diff options
| author | Pierre Bourdon <delroth@gmail.com> | 2016-06-24 10:43:46 +0200 |
|---|---|---|
| committer | Pierre Bourdon <delroth@gmail.com> | 2016-06-24 10:43:46 +0200 |
| commit | 3570c7f03a2aa90aa634f96c0af1969af610f14d (patch) | |
| tree | 4252e03c0e853ba7cffe022937698c854ad0eaa9 /Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp | |
| parent | 2115e8a4a6814e32107b5205ff5c95bbd3c6e99c (diff) | |
Reformat all the things. Have fun with merge conflicts.
Diffstat (limited to 'Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp | 400 |
1 files changed, 204 insertions, 196 deletions
diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp index 65b8053810..f899f7f078 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp @@ -23,11 +23,10 @@ namespace DX11 { - GeometryShaderCache::GSCache GeometryShaderCache::GeometryShaders; const GeometryShaderCache::GSCacheEntry* GeometryShaderCache::last_entry; GeometryShaderUid GeometryShaderCache::last_uid; -UidChecker<GeometryShaderUid,ShaderCode> GeometryShaderCache::geometry_uid_checker; +UidChecker<GeometryShaderUid, ShaderCode> GeometryShaderCache::geometry_uid_checker; const GeometryShaderCache::GSCacheEntry GeometryShaderCache::pass_entry; ID3D11GeometryShader* ClearGeometryShader = nullptr; @@ -35,241 +34,250 @@ ID3D11GeometryShader* CopyGeometryShader = nullptr; LinearDiskCache<GeometryShaderUid, u8> g_gs_disk_cache; -ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader() { return (g_ActiveConfig.iStereoMode > 0) ? ClearGeometryShader: nullptr; } -ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader() { return (g_ActiveConfig.iStereoMode > 0) ? CopyGeometryShader : nullptr; } +ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader() +{ + return (g_ActiveConfig.iStereoMode > 0) ? ClearGeometryShader : nullptr; +} +ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader() +{ + return (g_ActiveConfig.iStereoMode > 0) ? CopyGeometryShader : nullptr; +} ID3D11Buffer* gscbuf = nullptr; -ID3D11Buffer* &GeometryShaderCache::GetConstantBuffer() +ID3D11Buffer*& GeometryShaderCache::GetConstantBuffer() { - // TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up - if (GeometryShaderManager::dirty) - { - D3D11_MAPPED_SUBRESOURCE map; - D3D::context->Map(gscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - memcpy(map.pData, &GeometryShaderManager::constants, sizeof(GeometryShaderConstants)); - D3D::context->Unmap(gscbuf, 0); - GeometryShaderManager::dirty = false; - - ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(GeometryShaderConstants)); - } - return gscbuf; + // TODO: divide the global variables of the generated shaders into about 5 constant buffers to + // speed this up + if (GeometryShaderManager::dirty) + { + D3D11_MAPPED_SUBRESOURCE map; + D3D::context->Map(gscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + memcpy(map.pData, &GeometryShaderManager::constants, sizeof(GeometryShaderConstants)); + D3D::context->Unmap(gscbuf, 0); + GeometryShaderManager::dirty = false; + + ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(GeometryShaderConstants)); + } + return gscbuf; } // this class will load the precompiled shaders into our cache class GeometryShaderCacheInserter : public LinearDiskCacheReader<GeometryShaderUid, u8> { public: - void Read(const GeometryShaderUid &key, const u8* value, u32 value_size) - { - GeometryShaderCache::InsertByteCode(key, value, value_size); - } + void Read(const GeometryShaderUid& key, const u8* value, u32 value_size) + { + GeometryShaderCache::InsertByteCode(key, value, value_size); + } }; const char clear_shader_code[] = { - "struct VSOUTPUT\n" - "{\n" - " float4 vPosition : POSITION;\n" - " float4 vColor0 : COLOR0;\n" - "};\n" - "struct GSOUTPUT\n" - "{\n" - " float4 vPosition : POSITION;\n" - " float4 vColor0 : COLOR0;\n" - " uint slice : SV_RenderTargetArrayIndex;\n" - "};\n" - "[maxvertexcount(6)]\n" - "void main(triangle VSOUTPUT o[3], inout TriangleStream<GSOUTPUT> Output)\n" - "{\n" - "for(int slice = 0; slice < 2; slice++)\n" - "{\n" - " for(int i = 0; i < 3; i++)\n" - " {\n" - " GSOUTPUT OUT;\n" - " OUT.vPosition = o[i].vPosition;\n" - " OUT.vColor0 = o[i].vColor0;\n" - " OUT.slice = slice;\n" - " Output.Append(OUT);\n" - " }\n" - " Output.RestartStrip();\n" - "}\n" - "}\n" -}; + "struct VSOUTPUT\n" + "{\n" + " float4 vPosition : POSITION;\n" + " float4 vColor0 : COLOR0;\n" + "};\n" + "struct GSOUTPUT\n" + "{\n" + " float4 vPosition : POSITION;\n" + " float4 vColor0 : COLOR0;\n" + " uint slice : SV_RenderTargetArrayIndex;\n" + "};\n" + "[maxvertexcount(6)]\n" + "void main(triangle VSOUTPUT o[3], inout TriangleStream<GSOUTPUT> Output)\n" + "{\n" + "for(int slice = 0; slice < 2; slice++)\n" + "{\n" + " for(int i = 0; i < 3; i++)\n" + " {\n" + " GSOUTPUT OUT;\n" + " OUT.vPosition = o[i].vPosition;\n" + " OUT.vColor0 = o[i].vColor0;\n" + " OUT.slice = slice;\n" + " Output.Append(OUT);\n" + " }\n" + " Output.RestartStrip();\n" + "}\n" + "}\n"}; const char copy_shader_code[] = { - "struct VSOUTPUT\n" - "{\n" - " float4 vPosition : POSITION;\n" - " float3 vTexCoord : TEXCOORD0;\n" - " float vTexCoord1 : TEXCOORD1;\n" - "};\n" - "struct GSOUTPUT\n" - "{\n" - " float4 vPosition : POSITION;\n" - " float3 vTexCoord : TEXCOORD0;\n" - " float vTexCoord1 : TEXCOORD1;\n" - " uint slice : SV_RenderTargetArrayIndex;\n" - "};\n" - "[maxvertexcount(6)]\n" - "void main(triangle VSOUTPUT o[3], inout TriangleStream<GSOUTPUT> Output)\n" - "{\n" - "for(int slice = 0; slice < 2; slice++)\n" - "{\n" - " for(int i = 0; i < 3; i++)\n" - " {\n" - " GSOUTPUT OUT;\n" - " OUT.vPosition = o[i].vPosition;\n" - " OUT.vTexCoord = o[i].vTexCoord;\n" - " OUT.vTexCoord.z = slice;\n" - " OUT.vTexCoord1 = o[i].vTexCoord1;\n" - " OUT.slice = slice;\n" - " Output.Append(OUT);\n" - " }\n" - " Output.RestartStrip();\n" - "}\n" - "}\n" -}; + "struct VSOUTPUT\n" + "{\n" + " float4 vPosition : POSITION;\n" + " float3 vTexCoord : TEXCOORD0;\n" + " float vTexCoord1 : TEXCOORD1;\n" + "};\n" + "struct GSOUTPUT\n" + "{\n" + " float4 vPosition : POSITION;\n" + " float3 vTexCoord : TEXCOORD0;\n" + " float vTexCoord1 : TEXCOORD1;\n" + " uint slice : SV_RenderTargetArrayIndex;\n" + "};\n" + "[maxvertexcount(6)]\n" + "void main(triangle VSOUTPUT o[3], inout TriangleStream<GSOUTPUT> Output)\n" + "{\n" + "for(int slice = 0; slice < 2; slice++)\n" + "{\n" + " for(int i = 0; i < 3; i++)\n" + " {\n" + " GSOUTPUT OUT;\n" + " OUT.vPosition = o[i].vPosition;\n" + " OUT.vTexCoord = o[i].vTexCoord;\n" + " OUT.vTexCoord.z = slice;\n" + " OUT.vTexCoord1 = o[i].vTexCoord1;\n" + " OUT.slice = slice;\n" + " Output.Append(OUT);\n" + " }\n" + " Output.RestartStrip();\n" + "}\n" + "}\n"}; void GeometryShaderCache::Init() { - unsigned int gbsize = ROUND_UP(sizeof(GeometryShaderConstants), 16); // must be a multiple of 16 - D3D11_BUFFER_DESC gbdesc = CD3D11_BUFFER_DESC(gbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - HRESULT hr = D3D::device->CreateBuffer(&gbdesc, nullptr, &gscbuf); - CHECK(hr == S_OK, "Create geometry shader constant buffer (size=%u)", gbsize); - D3D::SetDebugObjectName((ID3D11DeviceChild*)gscbuf, "geometry shader constant buffer used to emulate the GX pipeline"); - - // used when drawing clear quads - ClearGeometryShader = D3D::CompileAndCreateGeometryShader(clear_shader_code); - CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader"); - D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearGeometryShader, "clear geometry shader"); - - // used for buffer copy - CopyGeometryShader = D3D::CompileAndCreateGeometryShader(copy_shader_code); - CHECK(CopyGeometryShader != nullptr, "Create copy geometry shader"); - D3D::SetDebugObjectName((ID3D11DeviceChild*)CopyGeometryShader, "copy geometry shader"); - - Clear(); - - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); - - std::string cache_filename = StringFromFormat("%sdx11-%s-gs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_strUniqueID.c_str()); - GeometryShaderCacheInserter inserter; - g_gs_disk_cache.OpenAndRead(cache_filename, inserter); - - if (g_Config.bEnableShaderDebugging) - Clear(); - - last_entry = nullptr; + unsigned int gbsize = ROUND_UP(sizeof(GeometryShaderConstants), 16); // must be a multiple of 16 + D3D11_BUFFER_DESC gbdesc = CD3D11_BUFFER_DESC(gbsize, D3D11_BIND_CONSTANT_BUFFER, + D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); + HRESULT hr = D3D::device->CreateBuffer(&gbdesc, nullptr, &gscbuf); + CHECK(hr == S_OK, "Create geometry shader constant buffer (size=%u)", gbsize); + D3D::SetDebugObjectName((ID3D11DeviceChild*)gscbuf, + "geometry shader constant buffer used to emulate the GX pipeline"); + + // used when drawing clear quads + ClearGeometryShader = D3D::CompileAndCreateGeometryShader(clear_shader_code); + CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearGeometryShader, "clear geometry shader"); + + // used for buffer copy + CopyGeometryShader = D3D::CompileAndCreateGeometryShader(copy_shader_code); + CHECK(CopyGeometryShader != nullptr, "Create copy geometry shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)CopyGeometryShader, "copy geometry shader"); + + Clear(); + + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); + + std::string cache_filename = + StringFromFormat("%sdx11-%s-gs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().m_strUniqueID.c_str()); + GeometryShaderCacheInserter inserter; + g_gs_disk_cache.OpenAndRead(cache_filename, inserter); + + if (g_Config.bEnableShaderDebugging) + Clear(); + + last_entry = nullptr; } // ONLY to be used during shutdown. void GeometryShaderCache::Clear() { - for (auto& iter : GeometryShaders) - iter.second.Destroy(); - GeometryShaders.clear(); - geometry_uid_checker.Invalidate(); + for (auto& iter : GeometryShaders) + iter.second.Destroy(); + GeometryShaders.clear(); + geometry_uid_checker.Invalidate(); - last_entry = nullptr; + last_entry = nullptr; } void GeometryShaderCache::Shutdown() { - SAFE_RELEASE(gscbuf); + SAFE_RELEASE(gscbuf); - SAFE_RELEASE(ClearGeometryShader); - SAFE_RELEASE(CopyGeometryShader); + SAFE_RELEASE(ClearGeometryShader); + SAFE_RELEASE(CopyGeometryShader); - Clear(); - g_gs_disk_cache.Sync(); - g_gs_disk_cache.Close(); + Clear(); + g_gs_disk_cache.Sync(); + g_gs_disk_cache.Close(); } bool GeometryShaderCache::SetShader(u32 primitive_type) { - GeometryShaderUid uid = GetGeometryShaderUid(primitive_type, API_D3D); - if (g_ActiveConfig.bEnableShaderDebugging) - { - ShaderCode code = GenerateGeometryShaderCode(primitive_type, API_D3D); - geometry_uid_checker.AddToIndexAndCheck(code, uid, "Geometry", "g"); - } - - // Check if the shader is already set - if (last_entry) - { - if (uid == last_uid) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); - 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_entry = &pass_entry; - return true; - } - - // Check if the shader is already in the cache - GSCache::iterator iter; - iter = GeometryShaders.find(uid); - if (iter != GeometryShaders.end()) - { - const GSCacheEntry &entry = iter->second; - last_entry = &entry; - - return (entry.shader != nullptr); - } - - // Need to compile a new shader - ShaderCode code = GenerateGeometryShaderCode(primitive_type, API_D3D); - - D3DBlob* pbytecode; - if (!D3D::CompileGeometryShader(code.GetBuffer(), &pbytecode)) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); - 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(); - - if (g_ActiveConfig.bEnableShaderDebugging && success) - { - GeometryShaders[uid].code = code.GetBuffer(); - } - - return success; + GeometryShaderUid uid = GetGeometryShaderUid(primitive_type, API_D3D); + if (g_ActiveConfig.bEnableShaderDebugging) + { + ShaderCode code = GenerateGeometryShaderCode(primitive_type, API_D3D); + geometry_uid_checker.AddToIndexAndCheck(code, uid, "Geometry", "g"); + } + + // Check if the shader is already set + if (last_entry) + { + if (uid == last_uid) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); + 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_entry = &pass_entry; + return true; + } + + // Check if the shader is already in the cache + GSCache::iterator iter; + iter = GeometryShaders.find(uid); + if (iter != GeometryShaders.end()) + { + const GSCacheEntry& entry = iter->second; + last_entry = &entry; + + return (entry.shader != nullptr); + } + + // Need to compile a new shader + ShaderCode code = GenerateGeometryShaderCode(primitive_type, API_D3D); + + D3DBlob* pbytecode; + if (!D3D::CompileGeometryShader(code.GetBuffer(), &pbytecode)) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); + 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(); + + if (g_ActiveConfig.bEnableShaderDebugging && success) + { + GeometryShaders[uid].code = code.GetBuffer(); + } + + return success; } -bool GeometryShaderCache::InsertByteCode(const GeometryShaderUid &uid, const void* bytecode, unsigned int bytecodelen) +bool GeometryShaderCache::InsertByteCode(const GeometryShaderUid& uid, const void* bytecode, + unsigned int bytecodelen) { - ID3D11GeometryShader* shader = D3D::CreateGeometryShaderFromByteCode(bytecode, bytecodelen); - if (shader == nullptr) - return false; + 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"); + // 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]; + // Make an entry in the table + GSCacheEntry newentry; + newentry.shader = shader; + GeometryShaders[uid] = newentry; + last_entry = &GeometryShaders[uid]; - if (!shader) - return false; + if (!shader) + return false; - return true; + return true; } } // DX11 |
