From 49e9ba2ca7adf6926fdc0bc0172f4ed8601a4362 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 14:46:39 +0200 Subject: [PATCH] [d3d9] Move d3d9 bytecode into D3D9Shader This reduces the amount of times we copy the bytecode and actually frees it when the game frees the associated shader. --- src/d3d9/d3d9_device.cpp | 11 ++++++++--- src/d3d9/d3d9_device.h | 1 + src/d3d9/d3d9_shader.cpp | 4 ++-- src/d3d9/d3d9_shader.h | 39 ++++++++++++++++++++++----------------- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 4d445514..50741571 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2820,14 +2820,16 @@ namespace dxvk { moduleInfo.options = m_dxsoOptions; D3D9CommonShader module; + uint32_t bytecodeLength; if (FAILED(this->CreateShaderModule(&module, + &bytecodeLength, VK_SHADER_STAGE_VERTEX_BIT, pFunction, &moduleInfo))) return D3DERR_INVALIDCALL; - *ppShader = ref(new D3D9VertexShader(this, module)); + *ppShader = ref(new D3D9VertexShader(this, module, pFunction, bytecodeLength)); return D3D_OK; } @@ -3149,14 +3151,16 @@ namespace dxvk { moduleInfo.options = m_dxsoOptions; D3D9CommonShader module; + uint32_t bytecodeLength; if (FAILED(this->CreateShaderModule(&module, + &bytecodeLength, VK_SHADER_STAGE_FRAGMENT_BIT, pFunction, &moduleInfo))) return D3DERR_INVALIDCALL; - *ppShader = ref(new D3D9PixelShader(this, module)); + *ppShader = ref(new D3D9PixelShader(this, module, pFunction, bytecodeLength)); return D3D_OK; } @@ -6312,12 +6316,13 @@ namespace dxvk { HRESULT D3D9DeviceEx::CreateShaderModule( D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DWORD* pShaderBytecode, const DxsoModuleInfo* pModuleInfo) { try { m_shaderModules->GetShaderModule(this, pShaderModule, - ShaderStage, pModuleInfo, pShaderBytecode); + pLength, ShaderStage, pModuleInfo, pShaderBytecode); return D3D_OK; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index a815699e..40dcc955 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -981,6 +981,7 @@ namespace dxvk { HRESULT CreateShaderModule( D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DWORD* pShaderBytecode, const DxsoModuleInfo* pModuleInfo); diff --git a/src/d3d9/d3d9_shader.cpp b/src/d3d9/d3d9_shader.cpp index 2aa2f444..6b22a26e 100644 --- a/src/d3d9/d3d9_shader.cpp +++ b/src/d3d9/d3d9_shader.cpp @@ -17,8 +17,6 @@ namespace dxvk { const DxsoAnalysisInfo& AnalysisInfo, DxsoModule* pModule) { const uint32_t bytecodeLength = AnalysisInfo.bytecodeByteLength; - m_bytecode.resize(bytecodeLength); - std::memcpy(m_bytecode.data(), pShaderBytecode, bytecodeLength); const std::string name = Key.toString(); Logger::debug(str::format("Compiling shader ", name)); @@ -90,6 +88,7 @@ namespace dxvk { void D3D9ShaderModuleSet::GetShaderModule( D3D9DeviceEx* pDevice, D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DxsoModuleInfo* pDxbcModuleInfo, const void* pShaderBytecode) { @@ -105,6 +104,7 @@ namespace dxvk { throw DxvkError("GetShaderModule: Bytecode does not match shader stage"); DxsoAnalysisInfo info = module.analyze(); + *pLength = info.bytecodeByteLength; DxvkShaderKey lookupKey = DxvkShaderKey( ShaderStage, diff --git a/src/d3d9/d3d9_shader.h b/src/d3d9/d3d9_shader.h index fc281c50..c8705711 100644 --- a/src/d3d9/d3d9_shader.h +++ b/src/d3d9/d3d9_shader.h @@ -40,10 +40,6 @@ namespace dxvk { return m_shader->debugName(); } - const std::vector& GetBytecode() const { - return m_bytecode; - } - const DxsoIsgn& GetIsgn() const { return m_isgn; } @@ -70,8 +66,6 @@ namespace dxvk { Rc m_shader; - std::vector m_bytecode; - }; /** @@ -88,9 +82,15 @@ namespace dxvk { D3D9Shader( D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader) + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) : D3D9DeviceChild( pDevice ) - , m_shader ( CommonShader ) { } + , m_shader ( CommonShader ) { + + m_bytecode.resize(BytecodeLength); + std::memcpy(m_bytecode.data(), pShaderBytecode, BytecodeLength); + } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { if (ppvObject == nullptr) @@ -113,15 +113,13 @@ namespace dxvk { if (pSizeOfData == nullptr) return D3DERR_INVALIDCALL; - const auto& bytecode = m_shader.GetBytecode(); - if (pOut == nullptr) { - *pSizeOfData = bytecode.size(); + *pSizeOfData = m_bytecode.size(); return D3D_OK; } - size_t copyAmount = std::min(size_t(*pSizeOfData), bytecode.size()); - std::memcpy(pOut, bytecode.data(), copyAmount); + size_t copyAmount = std::min(size_t(*pSizeOfData), m_bytecode.size()); + std::memcpy(pOut, m_bytecode.data(), copyAmount); return D3D_OK; } @@ -134,6 +132,8 @@ namespace dxvk { D3D9CommonShader m_shader; + std::vector m_bytecode; + }; // Needs their own classes and not usings for forward decl. @@ -144,8 +144,10 @@ namespace dxvk { D3D9VertexShader( D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader) - : D3D9Shader( pDevice, CommonShader ) { } + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) + : D3D9Shader( pDevice, CommonShader, pShaderBytecode, BytecodeLength ) { } }; @@ -155,8 +157,10 @@ namespace dxvk { D3D9PixelShader( D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader) - : D3D9Shader( pDevice, CommonShader ) { } + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) + : D3D9Shader( pDevice, CommonShader, pShaderBytecode, BytecodeLength ) { } }; @@ -175,6 +179,7 @@ namespace dxvk { void GetShaderModule( D3D9DeviceEx* pDevice, D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DxsoModuleInfo* pDxbcModuleInfo, const void* pShaderBytecode);