From ddf010479d9c715386bc1f7d770c13ac834ae9a2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 21 Oct 2019 12:09:53 +0200 Subject: [PATCH] [d3d11] Refactor shader module creation --- src/d3d11/d3d11_device.cpp | 112 +++++++++++++++++++++---------------- src/d3d11/d3d11_shader.cpp | 39 ++++++++----- src/d3d11/d3d11_shader.h | 13 +++-- 3 files changed, 98 insertions(+), 66 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 92b0173ca..61aaca29e 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -721,13 +721,15 @@ namespace dxvk { Sha1Hash hash = Sha1Hash::compute( pShaderBytecode, BytecodeLength); - if (FAILED(this->CreateShaderModule(&module, - DxvkShaderKey(VK_SHADER_STAGE_VERTEX_BIT, hash), - pShaderBytecode, BytecodeLength, pClassLinkage, - &moduleInfo))) - return E_INVALIDARG; + HRESULT hr = CreateShaderModule(&module, + DxvkShaderKey(VK_SHADER_STAGE_VERTEX_BIT, hash), + pShaderBytecode, BytecodeLength, pClassLinkage, + &moduleInfo); - if (ppVertexShader == nullptr) + if (FAILED(hr)) + return hr; + + if (!ppVertexShader) return S_FALSE; *ppVertexShader = ref(new D3D11VertexShader(this, module)); @@ -751,13 +753,15 @@ namespace dxvk { Sha1Hash hash = Sha1Hash::compute( pShaderBytecode, BytecodeLength); - if (FAILED(this->CreateShaderModule(&module, - DxvkShaderKey(VK_SHADER_STAGE_GEOMETRY_BIT, hash), - pShaderBytecode, BytecodeLength, pClassLinkage, - &moduleInfo))) - return E_INVALIDARG; + HRESULT hr = CreateShaderModule(&module, + DxvkShaderKey(VK_SHADER_STAGE_GEOMETRY_BIT, hash), + pShaderBytecode, BytecodeLength, pClassLinkage, + &moduleInfo); + + if (FAILED(hr)) + return hr; - if (ppGeometryShader == nullptr) + if (!ppGeometryShader) return S_FALSE; *ppGeometryShader = ref(new D3D11GeometryShader(this, module)); @@ -851,13 +855,15 @@ namespace dxvk { moduleInfo.tess = nullptr; moduleInfo.xfb = &xfb; - if (FAILED(this->CreateShaderModule(&module, - DxvkShaderKey(VK_SHADER_STAGE_GEOMETRY_BIT, hash), - pShaderBytecode, BytecodeLength, pClassLinkage, - &moduleInfo))) + HRESULT hr = CreateShaderModule(&module, + DxvkShaderKey(VK_SHADER_STAGE_GEOMETRY_BIT, hash), + pShaderBytecode, BytecodeLength, pClassLinkage, + &moduleInfo); + + if (FAILED(hr)) return E_INVALIDARG; - if (ppGeometryShader == nullptr) + if (!ppGeometryShader) return S_FALSE; *ppGeometryShader = ref(new D3D11GeometryShader(this, module)); @@ -881,13 +887,16 @@ namespace dxvk { Sha1Hash hash = Sha1Hash::compute( pShaderBytecode, BytecodeLength); - if (FAILED(this->CreateShaderModule(&module, - DxvkShaderKey(VK_SHADER_STAGE_FRAGMENT_BIT, hash), - pShaderBytecode, BytecodeLength, pClassLinkage, - &moduleInfo))) - return E_INVALIDARG; + + HRESULT hr = CreateShaderModule(&module, + DxvkShaderKey(VK_SHADER_STAGE_FRAGMENT_BIT, hash), + pShaderBytecode, BytecodeLength, pClassLinkage, + &moduleInfo); + + if (FAILED(hr)) + return hr; - if (ppPixelShader == nullptr) + if (!ppPixelShader) return S_FALSE; *ppPixelShader = ref(new D3D11PixelShader(this, module)); @@ -917,12 +926,14 @@ namespace dxvk { Sha1Hash hash = Sha1Hash::compute( pShaderBytecode, BytecodeLength); - if (FAILED(this->CreateShaderModule(&module, - DxvkShaderKey(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, hash), - pShaderBytecode, BytecodeLength, pClassLinkage, &moduleInfo))) - return E_INVALIDARG; + HRESULT hr = CreateShaderModule(&module, + DxvkShaderKey(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, hash), + pShaderBytecode, BytecodeLength, pClassLinkage, &moduleInfo); + + if (FAILED(hr)) + return hr; - if (ppHullShader == nullptr) + if (!ppHullShader) return S_FALSE; *ppHullShader = ref(new D3D11HullShader(this, module)); @@ -946,10 +957,12 @@ namespace dxvk { Sha1Hash hash = Sha1Hash::compute( pShaderBytecode, BytecodeLength); - if (FAILED(this->CreateShaderModule(&module, - DxvkShaderKey(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, hash), - pShaderBytecode, BytecodeLength, pClassLinkage, &moduleInfo))) - return E_INVALIDARG; + HRESULT hr = CreateShaderModule(&module, + DxvkShaderKey(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, hash), + pShaderBytecode, BytecodeLength, pClassLinkage, &moduleInfo); + + if (FAILED(hr)) + return hr; if (ppDomainShader == nullptr) return S_FALSE; @@ -975,13 +988,15 @@ namespace dxvk { Sha1Hash hash = Sha1Hash::compute( pShaderBytecode, BytecodeLength); - if (FAILED(this->CreateShaderModule(&module, - DxvkShaderKey(VK_SHADER_STAGE_COMPUTE_BIT, hash), - pShaderBytecode, BytecodeLength, pClassLinkage, - &moduleInfo))) - return E_INVALIDARG; + HRESULT hr = CreateShaderModule(&module, + DxvkShaderKey(VK_SHADER_STAGE_COMPUTE_BIT, hash), + pShaderBytecode, BytecodeLength, pClassLinkage, + &moduleInfo); + + if (FAILED(hr)) + return hr; - if (ppComputeShader == nullptr) + if (!ppComputeShader) return S_FALSE; *ppComputeShader = ref(new D3D11ComputeShader(this, module)); @@ -2024,15 +2039,18 @@ namespace dxvk { const DxbcModuleInfo* pModuleInfo) { if (pClassLinkage != nullptr) Logger::warn("D3D11Device::CreateShaderModule: Class linkage not supported"); - - try { - *pShaderModule = m_shaderModules.GetShaderModule(this, - &ShaderKey, pModuleInfo, pShaderBytecode, BytecodeLength); - return S_OK; - } catch (const DxvkError& e) { - Logger::err(e.message()); - return E_INVALIDARG; - } + + D3D11CommonShader commonShader; + + HRESULT hr = m_shaderModules.GetShaderModule(this, + &ShaderKey, pModuleInfo, pShaderBytecode, BytecodeLength, + &commonShader); + + if (FAILED(hr)) + return hr; + + *pShaderModule = std::move(commonShader); + return S_OK; } diff --git a/src/d3d11/d3d11_shader.cpp b/src/d3d11/d3d11_shader.cpp index bf3c87418..ddb3d62e3 100644 --- a/src/d3d11/d3d11_shader.cpp +++ b/src/d3d11/d3d11_shader.cpp @@ -79,24 +79,34 @@ namespace dxvk { D3D11ShaderModuleSet::~D3D11ShaderModuleSet() { } - D3D11CommonShader D3D11ShaderModuleSet::GetShaderModule( - D3D11Device* pDevice, - const DxvkShaderKey* pShaderKey, - const DxbcModuleInfo* pDxbcModuleInfo, - const void* pShaderBytecode, - size_t BytecodeLength) { + HRESULT D3D11ShaderModuleSet::GetShaderModule( + D3D11Device* pDevice, + const DxvkShaderKey* pShaderKey, + const DxbcModuleInfo* pDxbcModuleInfo, + const void* pShaderBytecode, + size_t BytecodeLength, + D3D11CommonShader* pShader) { // Use the shader's unique key for the lookup { std::unique_lock lock(m_mutex); auto entry = m_modules.find(*pShaderKey); - if (entry != m_modules.end()) - return entry->second; + if (entry != m_modules.end()) { + *pShader = entry->second; + return S_OK; + } } // This shader has not been compiled yet, so we have to create a // new module. This takes a while, so we won't lock the structure. - D3D11CommonShader module(pDevice, pShaderKey, - pDxbcModuleInfo, pShaderBytecode, BytecodeLength); + D3D11CommonShader module; + + try { + module = D3D11CommonShader(pDevice, pShaderKey, + pDxbcModuleInfo, pShaderBytecode, BytecodeLength); + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_INVALIDARG; + } // Insert the new module into the lookup table. If another thread // has compiled the same shader in the meantime, we should return @@ -104,11 +114,14 @@ namespace dxvk { { std::unique_lock lock(m_mutex); auto status = m_modules.insert({ *pShaderKey, module }); - if (!status.second) - return status.first->second; + if (!status.second) { + *pShader = status.first->second; + return S_OK; + } } - return module; + *pShader = std::move(module); + return S_OK; } } diff --git a/src/d3d11/d3d11_shader.h b/src/d3d11/d3d11_shader.h index 6c3c5ebab..3a26a46c6 100644 --- a/src/d3d11/d3d11_shader.h +++ b/src/d3d11/d3d11_shader.h @@ -140,12 +140,13 @@ namespace dxvk { D3D11ShaderModuleSet(); ~D3D11ShaderModuleSet(); - D3D11CommonShader GetShaderModule( - D3D11Device* pDevice, - const DxvkShaderKey* pShaderKey, - const DxbcModuleInfo* pDxbcModuleInfo, - const void* pShaderBytecode, - size_t BytecodeLength); + HRESULT GetShaderModule( + D3D11Device* pDevice, + const DxvkShaderKey* pShaderKey, + const DxbcModuleInfo* pDxbcModuleInfo, + const void* pShaderBytecode, + size_t BytecodeLength, + D3D11CommonShader* pShader); private: