diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 699809d9d..788281338 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -528,6 +528,16 @@ public: } } + size_t GetStageCount() { return 6; } + D3D12_SHADER_BYTECODE &GetStage(size_t i) + { + D3D12_SHADER_BYTECODE *stages[] = { + &m_GraphicsStreamData.VS, &m_GraphicsStreamData.HS, &m_GraphicsStreamData.DS, + &m_GraphicsStreamData.GS, &m_GraphicsStreamData.PS, &m_ComputeStreamData.CS, + }; + return *stages[i]; + } + private: struct { diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index c7b34310e..1fcb4b616 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -432,6 +432,25 @@ bool WrappedID3D12Device::Serialise_CreateGraphicsPipelineState( D3D12_GRAPHICS_PIPELINE_STATE_DESC unwrappedDesc = Descriptor; unwrappedDesc.pRootSignature = Unwrap(unwrappedDesc.pRootSignature); + { + D3D12_SHADER_BYTECODE *shaders[] = { + &Descriptor.VS, &Descriptor.HS, &Descriptor.DS, &Descriptor.GS, &Descriptor.PS, + }; + + for(size_t i = 0; i < ARRAY_COUNT(shaders); i++) + { + if(shaders[i]->BytecodeLength == 0 || shaders[i]->pShaderBytecode == NULL) + continue; + + // add any missing hashes ourselves. This probably comes from a capture with experimental + // enabled so it can load unhashed, but we want to be more proactive + if(!DXBC::DXBCContainer::IsHashedContainer(shaders[i]->pShaderBytecode, + shaders[i]->BytecodeLength)) + DXBC::DXBCContainer::HashContainer((void *)shaders[i]->pShaderBytecode, + shaders[i]->BytecodeLength); + } + } + ID3D12PipelineState *ret = NULL; HRESULT hr = m_pDevice->CreateGraphicsPipelineState(&unwrappedDesc, guid, (void **)&ret); @@ -712,6 +731,13 @@ bool WrappedID3D12Device::Serialise_CreateComputePipelineState( D3D12_COMPUTE_PIPELINE_STATE_DESC unwrappedDesc = Descriptor; unwrappedDesc.pRootSignature = Unwrap(unwrappedDesc.pRootSignature); + // add any missing hashes ourselves. This probably comes from a capture with experimental + // enabled so it can load unhashed, but we want to be more proactive + if(!DXBC::DXBCContainer::IsHashedContainer(Descriptor.CS.pShaderBytecode, + Descriptor.CS.BytecodeLength)) + DXBC::DXBCContainer::HashContainer((void *)Descriptor.CS.pShaderBytecode, + Descriptor.CS.BytecodeLength); + ID3D12PipelineState *ret = NULL; HRESULT hr = m_pDevice->CreateComputePipelineState(&unwrappedDesc, guid, (void **)&ret); diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap2.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap2.cpp index 6e5147d78..00ccb7565 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap2.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap2.cpp @@ -55,6 +55,17 @@ bool WrappedID3D12Device::Serialise_CreatePipelineState(SerialiserType &ser, ID3D12PipelineState *ret = NULL; HRESULT hr = E_NOINTERFACE; + for(size_t i = 0; i < unwrappedDesc.GetStageCount(); i++) + { + D3D12_SHADER_BYTECODE &sh = unwrappedDesc.GetStage(i); + + if(sh.BytecodeLength == 0 || sh.pShaderBytecode == NULL) + continue; + + if(!DXBC::DXBCContainer::IsHashedContainer(sh.pShaderBytecode, sh.BytecodeLength)) + DXBC::DXBCContainer::HashContainer((void *)sh.pShaderBytecode, sh.BytecodeLength); + } + if(m_pDevice2) hr = m_pDevice2->CreatePipelineState(unwrappedDesc.AsDescStream(), guid, (void **)&ret); else diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp index 10034a42a..be512d22b 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp @@ -754,12 +754,12 @@ void DXBCContainer::GetHash(uint32_t hash[4], const void *ByteCode, size_t Bytec } } -bool DXBCContainer::IsHashedContainer(void *ByteCode, size_t BytecodeLength) +bool DXBCContainer::IsHashedContainer(const void *ByteCode, size_t BytecodeLength) { if(BytecodeLength < sizeof(FileHeader)) return false; - FileHeader *header = (FileHeader *)ByteCode; + const FileHeader *header = (const FileHeader *)ByteCode; if(header->fourcc != FOURCC_DXBC) return false; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.h b/renderdoc/driver/shaders/dxbc/dxbc_container.h index f694fea36..7005661b5 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.h @@ -170,7 +170,7 @@ public: const DXIL::Program *GetDXILByteCode() { return m_DXILByteCode; } static void GetHash(uint32_t hash[4], const void *ByteCode, size_t BytecodeLength); - static bool IsHashedContainer(void *ByteCode, size_t BytecodeLength); + static bool IsHashedContainer(const void *ByteCode, size_t BytecodeLength); static bool HashContainer(void *ByteCode, size_t BytecodeLength); static bool UsesExtensionUAV(uint32_t slot, uint32_t space, const void *ByteCode,