diff options
| author | Stenzek <stenzek@gmail.com> | 2017-07-20 15:25:31 +1000 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2017-07-30 17:43:59 +1000 |
| commit | 4bf562589565636382b81313c2de0482e45743c0 (patch) | |
| tree | 16acc9338c56d0334d0e93bde7afdccf3052f64e /Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp | |
| parent | cd502990fa63e63c727d99ebf0defb3cf40583f9 (diff) | |
D3D: Uber shader support
Diffstat (limited to 'Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp | 83 |
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 |
