mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-02 20:05:44 +00:00
Handle root signatures not being specified on pipeline create
* If the root signature is embedded in a shader somewhere we need to pull it out for access.
This commit is contained in:
@@ -490,6 +490,8 @@ bool WrappedID3D12Device::Serialise_CreateGraphicsPipelineState(
|
||||
|
||||
wrapped->graphics = new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(Descriptor);
|
||||
|
||||
wrapped->FetchRootSig(GetShaderCache());
|
||||
|
||||
D3D12_SHADER_BYTECODE *shaders[] = {
|
||||
&wrapped->graphics->VS, &wrapped->graphics->HS, &wrapped->graphics->DS,
|
||||
&wrapped->graphics->GS, &wrapped->graphics->PS,
|
||||
@@ -637,6 +639,8 @@ void WrappedID3D12Device::ProcessCreatedGraphicsPSO(ID3D12PipelineState *real,
|
||||
|
||||
wrapped->graphics = new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(*pDesc);
|
||||
|
||||
wrapped->FetchRootSig(GetShaderCache());
|
||||
|
||||
D3D12_SHADER_BYTECODE *shaders[] = {
|
||||
&wrapped->graphics->VS, &wrapped->graphics->HS, &wrapped->graphics->DS,
|
||||
&wrapped->graphics->GS, &wrapped->graphics->PS, &wrapped->graphics->AS,
|
||||
@@ -778,6 +782,8 @@ bool WrappedID3D12Device::Serialise_CreateComputePipelineState(
|
||||
|
||||
wrapped->compute = new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(Descriptor);
|
||||
|
||||
wrapped->FetchRootSig(GetShaderCache());
|
||||
|
||||
WrappedID3D12Shader *entry = WrappedID3D12Shader::AddShader(wrapped->compute->CS, this);
|
||||
entry->AddRef();
|
||||
|
||||
@@ -860,6 +866,8 @@ void WrappedID3D12Device::ProcessCreatedComputePSO(ID3D12PipelineState *real, ui
|
||||
|
||||
wrapped->compute = new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(*pDesc);
|
||||
|
||||
wrapped->FetchRootSig(GetShaderCache());
|
||||
|
||||
WrappedID3D12Shader *sh = WrappedID3D12Shader::AddShader(wrapped->compute->CS, this);
|
||||
sh->AddRef();
|
||||
wrapped->compute->CS.pShaderBytecode = sh;
|
||||
|
||||
@@ -190,6 +190,8 @@ bool WrappedID3D12Device::Serialise_CreatePipelineState(SerialiserType &ser,
|
||||
}
|
||||
}
|
||||
|
||||
wrapped->FetchRootSig(GetShaderCache());
|
||||
|
||||
// if this shader was initialised with nvidia's dynamic UAV, pull in that chunk as one of ours
|
||||
// and unset it (there will be one for each create that actually used vendor extensions)
|
||||
if(m_VendorEXT == GPUVendor::nVidia && m_GlobalEXTUAV != ~0U)
|
||||
@@ -382,6 +384,8 @@ HRESULT WrappedID3D12Device::CreatePipelineState(const D3D12_PIPELINE_STATE_STRE
|
||||
wrapped->graphics->ViewInstancing.pViewInstanceLocations = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wrapped->FetchRootSig(GetShaderCache());
|
||||
}
|
||||
|
||||
*ppPipelineState = (ID3D12PipelineState *)wrapped;
|
||||
|
||||
@@ -2049,10 +2049,6 @@ rdcarray<DescriptorLogicalLocation> D3D12Replay::GetDescriptorLocations(
|
||||
{
|
||||
WrappedID3D12PipelineState *pipe = (WrappedID3D12PipelineState *)res;
|
||||
|
||||
WrappedID3D12RootSignature *sig =
|
||||
(WrappedID3D12RootSignature *)(pipe->IsGraphics() ? pipe->graphics->pRootSignature
|
||||
: pipe->compute->pRootSignature);
|
||||
|
||||
// root constants
|
||||
size_t dst = 0;
|
||||
for(const DescriptorRange &r : ranges)
|
||||
@@ -2061,7 +2057,7 @@ rdcarray<DescriptorLogicalLocation> D3D12Replay::GetDescriptorLocations(
|
||||
|
||||
for(uint32_t i = 0; i < r.count; i++, rootIndex++, dst++)
|
||||
{
|
||||
const D3D12RootSignatureParameter ¶m = sig->sig.Parameters[rootIndex];
|
||||
const D3D12RootSignatureParameter ¶m = pipe->usedSig.Parameters[rootIndex];
|
||||
|
||||
DescriptorLogicalLocation &l = ret[dst];
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "driver/shaders/dxbc/dxbc_reflect.h"
|
||||
#include "d3d12_command_list.h"
|
||||
#include "d3d12_command_queue.h"
|
||||
#include "d3d12_shader_cache.h"
|
||||
|
||||
GPUAddressRangeTracker WrappedID3D12Resource::m_Addresses;
|
||||
std::map<WrappedID3D12PipelineState::DXBCKey, WrappedID3D12Shader *> WrappedID3D12Shader::m_Shaders;
|
||||
@@ -603,15 +604,15 @@ void WrappedID3D12PipelineState::ShaderEntry::BuildReflection()
|
||||
m_Details->resourceId = GetResourceID();
|
||||
}
|
||||
|
||||
rdcpair<uint32_t, uint32_t> FindMatchingRootParameter(const D3D12RootSignature *sig,
|
||||
rdcpair<uint32_t, uint32_t> FindMatchingRootParameter(const D3D12RootSignature &sig,
|
||||
D3D12_SHADER_VISIBILITY visibility,
|
||||
D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
|
||||
uint32_t space, uint32_t bind)
|
||||
{
|
||||
// search the root signature to find the matching entry and figure out the offset from the root binding
|
||||
for(uint32_t root = 0; root < sig->Parameters.size(); root++)
|
||||
for(uint32_t root = 0; root < sig.Parameters.size(); root++)
|
||||
{
|
||||
const D3D12RootSignatureParameter ¶m = sig->Parameters[root];
|
||||
const D3D12RootSignatureParameter ¶m = sig.Parameters[root];
|
||||
|
||||
if(param.ShaderVisibility != visibility && param.ShaderVisibility != D3D12_SHADER_VISIBILITY_ALL)
|
||||
continue;
|
||||
@@ -659,11 +660,11 @@ rdcpair<uint32_t, uint32_t> FindMatchingRootParameter(const D3D12RootSignature *
|
||||
if(rangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER)
|
||||
{
|
||||
// indicate that we're looking up static samplers
|
||||
uint32_t numRoots = (uint32_t)sig->Parameters.size();
|
||||
for(uint32_t samp = 0; samp < sig->StaticSamplers.size(); samp++)
|
||||
uint32_t numRoots = (uint32_t)sig.Parameters.size();
|
||||
for(uint32_t samp = 0; samp < sig.StaticSamplers.size(); samp++)
|
||||
{
|
||||
if(sig->StaticSamplers[samp].RegisterSpace == space &&
|
||||
sig->StaticSamplers[samp].ShaderRegister == bind)
|
||||
if(sig.StaticSamplers[samp].RegisterSpace == space &&
|
||||
sig.StaticSamplers[samp].ShaderRegister == bind)
|
||||
{
|
||||
return {numRoots, samp};
|
||||
}
|
||||
@@ -673,18 +674,61 @@ rdcpair<uint32_t, uint32_t> FindMatchingRootParameter(const D3D12RootSignature *
|
||||
return {~0U, 0};
|
||||
}
|
||||
|
||||
void WrappedID3D12PipelineState::FetchRootSig(D3D12ShaderCache *shaderCache)
|
||||
{
|
||||
if(compute)
|
||||
{
|
||||
if(compute->pRootSignature)
|
||||
{
|
||||
usedSig = ((WrappedID3D12RootSignature *)compute->pRootSignature)->sig;
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D12_SHADER_BYTECODE desc = CS()->GetDesc();
|
||||
if(DXBC::DXBCContainer::CheckForRootSig(desc.pShaderBytecode, desc.BytecodeLength))
|
||||
{
|
||||
usedSig = shaderCache->GetRootSig(desc.pShaderBytecode, desc.BytecodeLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("Couldn't find root signature in either desc or compute shader");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(graphics)
|
||||
{
|
||||
if(graphics->pRootSignature)
|
||||
{
|
||||
usedSig = ((WrappedID3D12RootSignature *)graphics->pRootSignature)->sig;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there is any root signature it must match in all shaders, so we just have to find the first one.
|
||||
for(ShaderEntry *shad : {PS(), VS(), HS(), DS(), GS(), AS(), MS()})
|
||||
{
|
||||
if(shad)
|
||||
{
|
||||
D3D12_SHADER_BYTECODE desc = shad->GetDesc();
|
||||
|
||||
if(DXBC::DXBCContainer::CheckForRootSig(desc.pShaderBytecode, desc.BytecodeLength))
|
||||
{
|
||||
usedSig = shaderCache->GetRootSig(desc.pShaderBytecode, desc.BytecodeLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RDCWARN("Couldn't find root signature in either desc or any bound shader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D12PipelineState::ProcessDescriptorAccess()
|
||||
{
|
||||
if(m_AccessProcessed)
|
||||
return;
|
||||
m_AccessProcessed = true;
|
||||
|
||||
const D3D12RootSignature *sig = NULL;
|
||||
if(graphics)
|
||||
sig = &((WrappedID3D12RootSignature *)graphics->pRootSignature)->sig;
|
||||
else if(compute)
|
||||
sig = &((WrappedID3D12RootSignature *)compute->pRootSignature)->sig;
|
||||
|
||||
for(ShaderEntry *shad : {VS(), HS(), DS(), GS(), PS(), AS(), MS(), CS()})
|
||||
{
|
||||
if(!shad)
|
||||
@@ -727,7 +771,7 @@ void WrappedID3D12PipelineState::ProcessDescriptorAccess()
|
||||
access.type = DescriptorType::ConstantBuffer;
|
||||
access.index = i;
|
||||
rdctie(access.byteSize, access.byteOffset) =
|
||||
FindMatchingRootParameter(sig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_CBV,
|
||||
FindMatchingRootParameter(usedSig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_CBV,
|
||||
bind.fixedBindSetOrSpace, bind.fixedBindNumber);
|
||||
|
||||
if(access.byteSize != ~0U)
|
||||
@@ -746,7 +790,7 @@ void WrappedID3D12PipelineState::ProcessDescriptorAccess()
|
||||
access.type = DescriptorType::Sampler;
|
||||
access.index = i;
|
||||
rdctie(access.byteSize, access.byteOffset) =
|
||||
FindMatchingRootParameter(sig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
|
||||
FindMatchingRootParameter(usedSig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
|
||||
bind.fixedBindSetOrSpace, bind.fixedBindNumber);
|
||||
|
||||
if(access.byteSize != ~0U)
|
||||
@@ -765,7 +809,7 @@ void WrappedID3D12PipelineState::ProcessDescriptorAccess()
|
||||
access.type = refl.readOnlyResources[i].descriptorType;
|
||||
access.index = i;
|
||||
rdctie(access.byteSize, access.byteOffset) =
|
||||
FindMatchingRootParameter(sig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
|
||||
FindMatchingRootParameter(usedSig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
|
||||
bind.fixedBindSetOrSpace, bind.fixedBindNumber);
|
||||
|
||||
if(access.byteSize != ~0U)
|
||||
@@ -784,7 +828,7 @@ void WrappedID3D12PipelineState::ProcessDescriptorAccess()
|
||||
access.type = refl.readWriteResources[i].descriptorType;
|
||||
access.index = i;
|
||||
rdctie(access.byteSize, access.byteOffset) =
|
||||
FindMatchingRootParameter(sig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
|
||||
FindMatchingRootParameter(usedSig, visibility, D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
|
||||
bind.fixedBindSetOrSpace, bind.fixedBindNumber);
|
||||
|
||||
if(access.byteSize != ~0U)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "d3d12_device.h"
|
||||
#include "d3d12_manager.h"
|
||||
|
||||
rdcpair<uint32_t, uint32_t> FindMatchingRootParameter(const D3D12RootSignature *sig,
|
||||
rdcpair<uint32_t, uint32_t> FindMatchingRootParameter(const D3D12RootSignature &sig,
|
||||
D3D12_SHADER_VISIBILITY visibility,
|
||||
D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
|
||||
uint32_t space, uint32_t bind);
|
||||
@@ -642,9 +642,15 @@ public:
|
||||
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC *graphics = NULL;
|
||||
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC *compute = NULL;
|
||||
|
||||
// either the signature from graphics/compute above, or else an extracted signature from the
|
||||
// shader blobs inside valid only on replay
|
||||
D3D12RootSignature usedSig;
|
||||
|
||||
rdcarray<DescriptorAccess> staticDescriptorAccess;
|
||||
bool m_AccessProcessed = false;
|
||||
|
||||
void FetchRootSig(D3D12ShaderCache *shaderCache);
|
||||
|
||||
void Fill(D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC &desc)
|
||||
{
|
||||
if(graphics)
|
||||
|
||||
@@ -1520,7 +1520,7 @@ bool D3D12Replay::FetchShaderFeedback(uint32_t eventId)
|
||||
{
|
||||
access.arrayElement = i;
|
||||
rdctie(access.byteSize, access.byteOffset) = FindMatchingRootParameter(
|
||||
&modsig, visibility, rangeType, it->first.space, it->first.bind);
|
||||
modsig, visibility, rangeType, it->first.space, it->first.bind);
|
||||
|
||||
access.byteOffset += access.arrayElement;
|
||||
|
||||
|
||||
@@ -1109,6 +1109,34 @@ bool DXBCContainer::CheckForDXIL(const void *ByteCode, size_t ByteCodeLength)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DXBCContainer::CheckForRootSig(const void *ByteCode, size_t ByteCodeLength)
|
||||
{
|
||||
FileHeader *header = (FileHeader *)ByteCode;
|
||||
|
||||
char *data = (char *)ByteCode; // just for convenience
|
||||
|
||||
if(ByteCode == NULL || ByteCodeLength == 0)
|
||||
return false;
|
||||
|
||||
if(header->fourcc != FOURCC_DXBC)
|
||||
return false;
|
||||
|
||||
if(header->fileLength != (uint32_t)ByteCodeLength)
|
||||
return false;
|
||||
|
||||
uint32_t *chunkOffsets = (uint32_t *)(header + 1); // right after the header
|
||||
|
||||
for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++)
|
||||
{
|
||||
uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]);
|
||||
|
||||
if(*fourcc == FOURCC_RTS0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
rdcstr DXBCContainer::GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLength)
|
||||
{
|
||||
rdcstr debugPath;
|
||||
|
||||
@@ -233,6 +233,7 @@ public:
|
||||
|
||||
static bool CheckForDebugInfo(const void *ByteCode, size_t ByteCodeLength);
|
||||
static bool CheckForDXIL(const void *ByteCode, size_t ByteCodeLength);
|
||||
static bool CheckForRootSig(const void *ByteCode, size_t ByteCodeLength);
|
||||
static rdcstr GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLength);
|
||||
static D3D_PRIMITIVE_TOPOLOGY GetOutputTopology(const void *ByteCode, size_t ByteCodeLength);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user