Add thread safety to VkShaderCache
This commit is contained in:
parent
74e2e39e35
commit
4f1316b3fd
5 changed files with 76 additions and 42 deletions
|
|
@ -644,12 +644,12 @@ FString VkShaderManager::GetVersionBlock()
|
|||
|
||||
FString VkShaderManager::LoadPublicShaderLump(const char* lumpname)
|
||||
{
|
||||
return fb->GetShaderCache()->GetPublicFile(lumpname).Code;
|
||||
return fb->GetShaderCache()->GetPublicFileText(lumpname);
|
||||
}
|
||||
|
||||
FString VkShaderManager::LoadPrivateShaderLump(const char* lumpname)
|
||||
{
|
||||
return fb->GetShaderCache()->GetPrivateFile(lumpname).Code;
|
||||
return fb->GetShaderCache()->GetPrivateFileText(lumpname);
|
||||
}
|
||||
|
||||
VkPPShader* VkShaderManager::GetVkShader(PPShader* shader)
|
||||
|
|
|
|||
|
|
@ -26,42 +26,24 @@ VkShaderCache::~VkShaderCache()
|
|||
Save();
|
||||
}
|
||||
|
||||
FString VkShaderCache::GetPublicFileText(const FString& lumpname)
|
||||
{
|
||||
std::unique_lock lock(Mutex);
|
||||
return GetPublicFile(lumpname).Code;
|
||||
}
|
||||
|
||||
FString VkShaderCache::GetPrivateFileText(const FString& lumpname)
|
||||
{
|
||||
std::unique_lock lock(Mutex);
|
||||
return GetPrivateFile(lumpname).Code;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> VkShaderCache::Compile(ShaderType type, const TArrayView<VkShaderSource>& sources, const std::function<FString(FString)>& includeFilter)
|
||||
{
|
||||
// Is this something we already compiled before?
|
||||
|
||||
FString checksum = CalcSha1(type, sources);
|
||||
auto it = CodeCache.find(checksum);
|
||||
if (it != CodeCache.end())
|
||||
{
|
||||
// OK we found a match. Did any of the include files change?
|
||||
|
||||
try
|
||||
{
|
||||
VkCachedCompile& cacheinfo = it->second;
|
||||
|
||||
bool foundChanges = false;
|
||||
for (const VkCachedInclude& includeinfo : cacheinfo.Includes)
|
||||
{
|
||||
const VkCachedShaderLump& lumpinfo = includeinfo.PrivateLump ? GetPrivateFile(includeinfo.LumpName) : GetPublicFile(includeinfo.LumpName);
|
||||
if (lumpinfo.Checksum != includeinfo.Checksum)
|
||||
{
|
||||
foundChanges = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundChanges)
|
||||
{
|
||||
cacheinfo.LastUsed = LaunchTime;
|
||||
return cacheinfo.Code;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// If GetPrivateFile or GetPublicFile is unable to find the file anymore it must be out of date.
|
||||
}
|
||||
}
|
||||
FString key = CalcSha1(type, sources);
|
||||
std::vector<uint32_t> code = GetFromCache(key);
|
||||
if (!code.empty())
|
||||
return code;
|
||||
|
||||
// No match or out of date
|
||||
// Compile it and store the dependencies:
|
||||
|
|
@ -77,8 +59,50 @@ std::vector<uint32_t> VkShaderCache::Compile(ShaderType type, const TArrayView<V
|
|||
compiler.AddSource(source.Name, source.Code);
|
||||
cachedCompile.Code = compiler.Compile(fb->GetDevice());
|
||||
cachedCompile.LastUsed = LaunchTime;
|
||||
return AddToCache(key, std::move(cachedCompile));
|
||||
}
|
||||
|
||||
auto& c = CodeCache[checksum];
|
||||
std::vector<uint32_t> VkShaderCache::GetFromCache(const FString& key)
|
||||
{
|
||||
std::unique_lock lock(Mutex);
|
||||
|
||||
auto it = CodeCache.find(key);
|
||||
if (it == CodeCache.end())
|
||||
return {};
|
||||
|
||||
VkCachedCompile& cacheinfo = it->second;
|
||||
|
||||
try
|
||||
{
|
||||
// Did any of the include files change?
|
||||
bool foundChanges = false;
|
||||
for (const VkCachedInclude& includeinfo : cacheinfo.Includes)
|
||||
{
|
||||
const VkCachedShaderLump& lumpinfo = includeinfo.PrivateLump ? GetPrivateFile(includeinfo.LumpName) : GetPublicFile(includeinfo.LumpName);
|
||||
if (lumpinfo.Checksum != includeinfo.Checksum)
|
||||
{
|
||||
foundChanges = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundChanges)
|
||||
return {};
|
||||
|
||||
cacheinfo.LastUsed = LaunchTime;
|
||||
return cacheinfo.Code;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// If GetPrivateFile or GetPublicFile is unable to find the file anymore it must be out of date.
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint32_t> VkShaderCache::AddToCache(const FString& key, VkCachedCompile cachedCompile)
|
||||
{
|
||||
std::unique_lock lock(Mutex);
|
||||
auto& c = CodeCache[key];
|
||||
c = std::move(cachedCompile);
|
||||
return c.Code;
|
||||
}
|
||||
|
|
@ -88,6 +112,8 @@ ShaderIncludeResult VkShaderCache::OnInclude(VkCachedCompile& cachedCompile, FSt
|
|||
if (depth > 8)
|
||||
I_Error("Too much include recursion!");
|
||||
|
||||
std::unique_lock lock(Mutex);
|
||||
|
||||
const VkCachedShaderLump& file = system ? GetPrivateFile(headerName) : GetPublicFile(headerName);
|
||||
|
||||
VkCachedInclude cacheinfo;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <zvulkan/vulkanbuilders.h>
|
||||
|
||||
class VulkanRenderDevice;
|
||||
|
|
@ -50,18 +51,24 @@ public:
|
|||
|
||||
std::vector<uint32_t> Compile(ShaderType type, const TArrayView<VkShaderSource>& sources, const std::function<FString(FString)>& includeFilter = {});
|
||||
|
||||
const VkCachedShaderLump& GetPublicFile(const FString& lumpname);
|
||||
const VkCachedShaderLump& GetPrivateFile(const FString& lumpname);
|
||||
FString GetPublicFileText(const FString& lumpname);
|
||||
FString GetPrivateFileText(const FString& lumpname);
|
||||
|
||||
private:
|
||||
void Load();
|
||||
void Save();
|
||||
|
||||
std::vector<uint32_t> GetFromCache(const FString& key);
|
||||
std::vector<uint32_t> AddToCache(const FString& key, VkCachedCompile cachedCompile);
|
||||
|
||||
FString CalcSha1(ShaderType type, const TArrayView<VkShaderSource>& sources);
|
||||
FString CalcSha1(const FString& str);
|
||||
|
||||
ShaderIncludeResult OnInclude(VkCachedCompile& cachedCompile, FString headerName, FString includerName, size_t depth, bool system, const std::function<FString(FString)>& includeFilter);
|
||||
|
||||
const VkCachedShaderLump& GetPublicFile(const FString& lumpname);
|
||||
const VkCachedShaderLump& GetPrivateFile(const FString& lumpname);
|
||||
|
||||
static FString LoadPublicShaderLump(const char* lumpname);
|
||||
static FString LoadPrivateShaderLump(const char* lumpname);
|
||||
|
||||
|
|
@ -70,6 +77,7 @@ private:
|
|||
|
||||
VulkanRenderDevice* fb = nullptr;
|
||||
|
||||
std::mutex Mutex;
|
||||
std::map<FString, VkCachedShaderLump> PublicFiles;
|
||||
std::map<FString, VkCachedShaderLump> PrivateFiles;
|
||||
std::map<FString, VkCachedCompile> CodeCache;
|
||||
|
|
|
|||
|
|
@ -645,12 +645,12 @@ void VkLevelMesh::CreateViewerObjects()
|
|||
|
||||
FString VkLevelMesh::LoadPrivateShaderLump(const char* lumpname)
|
||||
{
|
||||
return fb->GetShaderCache()->GetPrivateFile(lumpname).Code;
|
||||
return fb->GetShaderCache()->GetPrivateFileText(lumpname);
|
||||
}
|
||||
|
||||
FString VkLevelMesh::LoadPublicShaderLump(const char* lumpname)
|
||||
{
|
||||
return fb->GetShaderCache()->GetPublicFile(lumpname).Code;
|
||||
return fb->GetShaderCache()->GetPublicFileText(lumpname);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -586,12 +586,12 @@ int VkLightmapper::GetRaytracePipelineIndex()
|
|||
|
||||
FString VkLightmapper::LoadPrivateShaderLump(const char* lumpname)
|
||||
{
|
||||
return fb->GetShaderCache()->GetPrivateFile(lumpname).Code;
|
||||
return fb->GetShaderCache()->GetPrivateFileText(lumpname);
|
||||
}
|
||||
|
||||
FString VkLightmapper::LoadPublicShaderLump(const char* lumpname)
|
||||
{
|
||||
return fb->GetShaderCache()->GetPublicFile(lumpname).Code;
|
||||
return fb->GetShaderCache()->GetPublicFileText(lumpname);
|
||||
}
|
||||
|
||||
void VkLightmapper::CreateRaytracePipeline()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue