summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2017-07-20 15:25:31 +1000
committerStenzek <stenzek@gmail.com>2017-07-30 17:43:59 +1000
commit4bf562589565636382b81313c2de0482e45743c0 (patch)
tree16acc9338c56d0334d0e93bde7afdccf3052f64e /Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
parentcd502990fa63e63c727d99ebf0defb3cf40583f9 (diff)
D3D: Uber shader support
Diffstat (limited to 'Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp')
-rw-r--r--Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp83
1 files changed, 43 insertions, 40 deletions
diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
index f6fd869b8c..f6d0599ac3 100644
--- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
+++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
@@ -13,6 +13,7 @@
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DShader.h"
+#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/FramebufferManager.h"
#include "VideoBackends/D3D/GeometryShaderCache.h"
@@ -159,6 +160,9 @@ void GeometryShaderCache::Init()
if (g_ActiveConfig.bShaderCache)
LoadShaderCache();
+
+ if (g_ActiveConfig.CanPrecompileUberShaders())
+ PrecompileShaders();
}
void GeometryShaderCache::LoadShaderCache()
@@ -175,6 +179,9 @@ void GeometryShaderCache::Reload()
if (g_ActiveConfig.bShaderCache)
LoadShaderCache();
+
+ if (g_ActiveConfig.CanPrecompileUberShaders())
+ PrecompileShaders();
}
// ONLY to be used during shutdown.
@@ -203,78 +210,74 @@ void GeometryShaderCache::Shutdown()
bool GeometryShaderCache::SetShader(u32 primitive_type)
{
GeometryShaderUid uid = GetGeometryShaderUid(primitive_type);
-
- // Check if the shader is already set
- if (last_entry)
+ if (last_entry && uid == last_uid)
{
- if (uid == last_uid)
- {
- GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- return true;
- }
+ GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
+ D3D::stateman->SetGeometryShader(last_entry->shader);
+ return true;
}
- last_uid = uid;
-
// Check if the shader is a pass-through shader
if (uid.GetUidData()->IsPassthrough())
{
// Return the default pass-through shader
+ last_uid = uid;
last_entry = &pass_entry;
+ D3D::stateman->SetGeometryShader(last_entry->shader);
return true;
}
// Check if the shader is already in the cache
- GSCache::iterator iter;
- iter = GeometryShaders.find(uid);
+ auto iter = GeometryShaders.find(uid);
if (iter != GeometryShaders.end())
{
const GSCacheEntry& entry = iter->second;
+ last_uid = uid;
last_entry = &entry;
-
+ D3D::stateman->SetGeometryShader(last_entry->shader);
return (entry.shader != nullptr);
}
// Need to compile a new shader
+ if (CompileShader(uid))
+ return SetShader(primitive_type);
+ else
+ return false;
+}
+
+bool GeometryShaderCache::CompileShader(const GeometryShaderUid& uid)
+{
+ D3DBlob* bytecode;
ShaderCode code =
GenerateGeometryShaderCode(APIType::D3D, ShaderHostConfig::GetCurrent(), uid.GetUidData());
-
- D3DBlob* pbytecode;
- if (!D3D::CompileGeometryShader(code.GetBuffer(), &pbytecode))
+ if (!D3D::CompileGeometryShader(code.GetBuffer(), &bytecode) ||
+ !InsertByteCode(uid, bytecode->Data(), bytecode->Size()))
{
- GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
+ SAFE_RELEASE(bytecode);
return false;
}
// Insert the bytecode into the caches
- g_gs_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
-
- bool success = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
- pbytecode->Release();
-
- return success;
+ g_gs_disk_cache.Append(uid, bytecode->Data(), bytecode->Size());
+ return true;
}
-bool GeometryShaderCache::InsertByteCode(const GeometryShaderUid& uid, const void* bytecode,
- unsigned int bytecodelen)
+bool GeometryShaderCache::InsertByteCode(const GeometryShaderUid& uid, const u8* bytecode,
+ size_t len)
{
- ID3D11GeometryShader* shader = D3D::CreateGeometryShaderFromByteCode(bytecode, bytecodelen);
- if (shader == nullptr)
- return false;
-
- // TODO: Somehow make the debug name a bit more specific
- D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of GeometryShaderCache");
-
- // Make an entry in the table
- GSCacheEntry newentry;
- newentry.shader = shader;
- GeometryShaders[uid] = newentry;
- last_entry = &GeometryShaders[uid];
+ GSCacheEntry& newentry = GeometryShaders[uid];
+ newentry.shader = bytecode ? D3D::CreateGeometryShaderFromByteCode(bytecode, len) : nullptr;
+ return newentry.shader != nullptr;
+}
- if (!shader)
- return false;
+void GeometryShaderCache::PrecompileShaders()
+{
+ EnumerateGeometryShaderUids([](const GeometryShaderUid& uid) {
+ if (GeometryShaders.find(uid) != GeometryShaders.end())
+ return;
- return true;
+ CompileShader(uid);
+ });
}
} // DX11