[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.
This commit is contained in:
Robin Kertels 2022-08-08 14:46:39 +02:00 committed by Joshie
parent 1628b9e63a
commit 49e9ba2ca7
4 changed files with 33 additions and 22 deletions

View File

@ -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;
}

View File

@ -981,6 +981,7 @@ namespace dxvk {
HRESULT CreateShaderModule(
D3D9CommonShader* pShaderModule,
uint32_t* pLength,
VkShaderStageFlagBits ShaderStage,
const DWORD* pShaderBytecode,
const DxsoModuleInfo* pModuleInfo);

View File

@ -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,

View File

@ -40,10 +40,6 @@ namespace dxvk {
return m_shader->debugName();
}
const std::vector<uint8_t>& GetBytecode() const {
return m_bytecode;
}
const DxsoIsgn& GetIsgn() const {
return m_isgn;
}
@ -70,8 +66,6 @@ namespace dxvk {
Rc<DxvkShader> m_shader;
std::vector<uint8_t> m_bytecode;
};
/**
@ -88,9 +82,15 @@ namespace dxvk {
D3D9Shader(
D3D9DeviceEx* pDevice,
const D3D9CommonShader& CommonShader)
const D3D9CommonShader& CommonShader,
const void* pShaderBytecode,
uint32_t BytecodeLength)
: D3D9DeviceChild<Base>( 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<uint8_t> 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<IDirect3DVertexShader9>( pDevice, CommonShader ) { }
const D3D9CommonShader& CommonShader,
const void* pShaderBytecode,
uint32_t BytecodeLength)
: D3D9Shader<IDirect3DVertexShader9>( pDevice, CommonShader, pShaderBytecode, BytecodeLength ) { }
};
@ -155,8 +157,10 @@ namespace dxvk {
D3D9PixelShader(
D3D9DeviceEx* pDevice,
const D3D9CommonShader& CommonShader)
: D3D9Shader<IDirect3DPixelShader9>( pDevice, CommonShader ) { }
const D3D9CommonShader& CommonShader,
const void* pShaderBytecode,
uint32_t BytecodeLength)
: D3D9Shader<IDirect3DPixelShader9>( 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);