mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 15:36:33 +00:00
Fix constant buffer lookups with SM5.1 shader debugging
Constant buffers store some additional state when parsed from DXBC to make it easier to fix the match and know the correct size. The debug trace still stores a simple array of CBuffers, but the shader debug code provides a BindingSlot and uses the ShaderBindpointMapping to find the logical identifier that shader instructions will use to reference the constant buffer.
This commit is contained in:
committed by
Baldur Karlsson
parent
d377c4e0cf
commit
1c764ca518
@@ -1699,6 +1699,25 @@ bool D3D11DebugAPIWrapper::CalculateMathIntrinsic(DXBCBytecode::OpcodeType opcod
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddCBuffersToDebugTrace(const DXBCBytecode::Program &program, D3D11DebugManager &debugManager,
|
||||
ShaderDebugTrace &trace, const D3D11RenderState::Shader &shader,
|
||||
const ShaderReflection &refl, const ShaderBindpointMapping &mapping)
|
||||
{
|
||||
bytebuf cbufData;
|
||||
for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
|
||||
{
|
||||
if(shader.ConstantBuffers[i])
|
||||
{
|
||||
ShaderDebug::BindingSlot slot(i, 0);
|
||||
cbufData.clear();
|
||||
debugManager.GetBufferData(shader.ConstantBuffers[i], shader.CBOffsets[i] * sizeof(Vec4f),
|
||||
shader.CBCounts[i] * sizeof(Vec4f), cbufData);
|
||||
|
||||
AddCBufferToDebugTrace(program, trace, refl, mapping, slot, cbufData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventId, uint32_t vertid, uint32_t instid,
|
||||
uint32_t idx, uint32_t instOffset, uint32_t vertOffset)
|
||||
{
|
||||
@@ -1793,19 +1812,15 @@ ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventId, uint32_t vertid, uin
|
||||
}
|
||||
}
|
||||
|
||||
bytebuf cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
|
||||
if(rs->VS.ConstantBuffers[i])
|
||||
GetDebugManager()->GetBufferData(rs->VS.ConstantBuffers[i],
|
||||
rs->VS.CBOffsets[i] * sizeof(Vec4f), 0, cbufData[i]);
|
||||
|
||||
ShaderDebugTrace ret;
|
||||
|
||||
GlobalState global;
|
||||
global.PopulateGroupshared(dxbc->GetDXBCByteCode());
|
||||
State initialState;
|
||||
CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl, cbufData);
|
||||
CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl);
|
||||
|
||||
AddCBuffersToDebugTrace(*dxbc->GetDXBCByteCode(), *GetDebugManager(), ret, rs->VS, refl,
|
||||
vs->GetMapping());
|
||||
|
||||
for(size_t i = 0; i < ret.inputs.size(); i++)
|
||||
{
|
||||
@@ -2640,13 +2655,6 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim
|
||||
// get the index of our desired pixel
|
||||
int destIdx = (x - xTL) + 2 * (y - yTL);
|
||||
|
||||
bytebuf cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
|
||||
if(rs->PS.ConstantBuffers[i])
|
||||
GetDebugManager()->GetBufferData(rs->PS.ConstantBuffers[i],
|
||||
rs->PS.CBOffsets[i] * sizeof(Vec4f), 0, cbufData[i]);
|
||||
|
||||
D3D11_COMPARISON_FUNC depthFunc = D3D11_COMPARISON_LESS;
|
||||
|
||||
if(rs->OM.DepthStencilState)
|
||||
@@ -2719,15 +2727,17 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim
|
||||
|
||||
GlobalState global;
|
||||
global.PopulateGroupshared(dxbc->GetDXBCByteCode());
|
||||
|
||||
global.sampleEvalRegisterMask = sampleEvalRegisterMask;
|
||||
|
||||
State initialState;
|
||||
CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl);
|
||||
|
||||
AddCBuffersToDebugTrace(*dxbc->GetDXBCByteCode(), *GetDebugManager(), traces[destIdx], rs->PS,
|
||||
refl, ps->GetMapping());
|
||||
|
||||
{
|
||||
DebugHit *hit = winner;
|
||||
|
||||
State initialState;
|
||||
CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl, cbufData);
|
||||
|
||||
rdcarray<ShaderVariable> &ins = traces[destIdx].inputs;
|
||||
if(!ins.empty() && ins.back().name == "vCoverage")
|
||||
ins.back().value.u.x = hit->coverage;
|
||||
@@ -3015,19 +3025,15 @@ ShaderDebugTrace D3D11Replay::DebugThread(uint32_t eventId, const uint32_t group
|
||||
|
||||
D3D11RenderState *rs = m_pImmediateContext->GetCurrentPipelineState();
|
||||
|
||||
bytebuf cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
|
||||
if(rs->CS.ConstantBuffers[i])
|
||||
GetDebugManager()->GetBufferData(rs->CS.ConstantBuffers[i],
|
||||
rs->CS.CBOffsets[i] * sizeof(Vec4f), 0, cbufData[i]);
|
||||
|
||||
ShaderDebugTrace ret;
|
||||
|
||||
GlobalState global;
|
||||
global.PopulateGroupshared(dxbc->GetDXBCByteCode());
|
||||
State initialState;
|
||||
CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl, cbufData);
|
||||
CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl);
|
||||
|
||||
AddCBuffersToDebugTrace(*dxbc->GetDXBCByteCode(), *GetDebugManager(), ret, rs->CS, refl,
|
||||
cs->GetMapping());
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
|
||||
@@ -1035,9 +1035,10 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
return true;
|
||||
}
|
||||
|
||||
void GatherConstantBuffers(WrappedID3D12Device *pDevice, DXBC::ShaderType shaderType,
|
||||
void GatherConstantBuffers(WrappedID3D12Device *pDevice, const DXBCBytecode::Program &program,
|
||||
const D3D12RenderState::RootSignature &rootsig,
|
||||
bytebuf cbufData[D3D12_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT])
|
||||
const ShaderReflection &refl, const ShaderBindpointMapping &mapping,
|
||||
ShaderDebugTrace &debugTrace)
|
||||
{
|
||||
WrappedID3D12RootSignature *pD3D12RootSig =
|
||||
pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12RootSignature>(rootsig.rootsig);
|
||||
@@ -1047,21 +1048,26 @@ void GatherConstantBuffers(WrappedID3D12Device *pDevice, DXBC::ShaderType shader
|
||||
{
|
||||
const D3D12RootSignatureParameter &rootSigParam = pD3D12RootSig->sig.Parameters[i];
|
||||
const D3D12RenderState::SignatureElement &element = rootsig.sigelems[i];
|
||||
if(IsShaderParameterVisible(shaderType, rootSigParam.ShaderVisibility))
|
||||
if(IsShaderParameterVisible(program.GetShaderType(), rootSigParam.ShaderVisibility))
|
||||
{
|
||||
if(rootSigParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS &&
|
||||
element.type == eRootConst)
|
||||
{
|
||||
UINT cbufIndex = rootSigParam.Constants.ShaderRegister;
|
||||
ShaderDebug::BindingSlot slot(rootSigParam.Constants.ShaderRegister,
|
||||
rootSigParam.Constants.RegisterSpace);
|
||||
UINT sizeBytes = sizeof(uint32_t) * RDCMIN(rootSigParam.Constants.Num32BitValues,
|
||||
(UINT)element.constants.size());
|
||||
cbufData[cbufIndex].assign((const byte *)element.constants.data(), sizeBytes);
|
||||
bytebuf cbufData((const byte *)element.constants.data(), sizeBytes);
|
||||
AddCBufferToDebugTrace(program, debugTrace, refl, mapping, slot, cbufData);
|
||||
}
|
||||
else if(rootSigParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV && element.type == eRootCBV)
|
||||
{
|
||||
UINT cbufIndex = rootSigParam.Descriptor.ShaderRegister;
|
||||
ShaderDebug::BindingSlot slot(rootSigParam.Descriptor.ShaderRegister,
|
||||
rootSigParam.Descriptor.RegisterSpace);
|
||||
ID3D12Resource *cbv = pDevice->GetResourceManager()->GetCurrentAs<ID3D12Resource>(element.id);
|
||||
pDevice->GetDebugManager()->GetBufferData(cbv, element.offset, 0, cbufData[cbufIndex]);
|
||||
bytebuf cbufData;
|
||||
pDevice->GetDebugManager()->GetBufferData(cbv, element.offset, 0, cbufData);
|
||||
AddCBufferToDebugTrace(program, debugTrace, refl, mapping, slot, cbufData);
|
||||
}
|
||||
else if(rootSigParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE &&
|
||||
element.type == eRootTable)
|
||||
@@ -1073,10 +1079,10 @@ void GatherConstantBuffers(WrappedID3D12Device *pDevice, DXBC::ShaderType shader
|
||||
size_t numRanges = rootSigParam.ranges.size();
|
||||
for(size_t r = 0; r < numRanges; r++)
|
||||
{
|
||||
// For this traversal we only care about CBV descriptor ranges
|
||||
// For this traversal we only care about CBV descriptor ranges, but we still need to
|
||||
// calculate the table offsets in case a descriptor table has a combination of
|
||||
// different range types
|
||||
const D3D12_DESCRIPTOR_RANGE1 &range = rootSigParam.ranges[r];
|
||||
if(range.RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_CBV)
|
||||
continue;
|
||||
|
||||
UINT offset = range.OffsetInDescriptorsFromTableStart;
|
||||
if(range.OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
|
||||
@@ -1098,9 +1104,13 @@ void GatherConstantBuffers(WrappedID3D12Device *pDevice, DXBC::ShaderType shader
|
||||
|
||||
prevTableOffset = offset + numDescriptors;
|
||||
|
||||
UINT cbufIndex = range.BaseShaderRegister;
|
||||
if(range.RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_CBV)
|
||||
continue;
|
||||
|
||||
for(UINT n = 0; n < numDescriptors; ++n, ++cbufIndex)
|
||||
ShaderDebug::BindingSlot slot(range.BaseShaderRegister, range.RegisterSpace);
|
||||
|
||||
bytebuf cbufData;
|
||||
for(UINT n = 0; n < numDescriptors; ++n, ++slot.shaderRegister)
|
||||
{
|
||||
if(desc)
|
||||
{
|
||||
@@ -1110,8 +1120,9 @@ void GatherConstantBuffers(WrappedID3D12Device *pDevice, DXBC::ShaderType shader
|
||||
WrappedID3D12Resource1::GetResIDFromAddr(cbv.BufferLocation, resId, byteOffset);
|
||||
ID3D12Resource *pCbvResource =
|
||||
pDevice->GetResourceManager()->GetCurrentAs<ID3D12Resource>(resId);
|
||||
pDevice->GetDebugManager()->GetBufferData(pCbvResource, element.offset, 0,
|
||||
cbufData[cbufIndex]);
|
||||
cbufData.clear();
|
||||
pDevice->GetDebugManager()->GetBufferData(pCbvResource, element.offset, 0, cbufData);
|
||||
AddCBufferToDebugTrace(program, debugTrace, refl, mapping, slot, cbufData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1509,10 +1520,6 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim
|
||||
// get the index of our desired pixel
|
||||
int destIdx = (x - xTL) + 2 * (y - yTL);
|
||||
|
||||
// Fetch constant buffer data from root signature
|
||||
bytebuf cbufData[D3D12_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
|
||||
GatherConstantBuffers(m_pDevice, dxbc->m_Type, rs.graphics, cbufData);
|
||||
|
||||
// Get depth func and determine "winner" pixel
|
||||
D3D12_COMPARISON_FUNC depthFunc = pipeDesc.DepthStencilState.DepthFunc;
|
||||
DebugHit *pWinnerHit = NULL;
|
||||
@@ -1571,10 +1578,15 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim
|
||||
GlobalState global;
|
||||
global.PopulateGroupshared(dxbc->GetDXBCByteCode());
|
||||
|
||||
State initialState;
|
||||
CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl);
|
||||
|
||||
// Fetch constant buffer data from root signature
|
||||
GatherConstantBuffers(m_pDevice, *dxbc->GetDXBCByteCode(), rs.graphics, refl,
|
||||
origPSO->PS()->GetMapping(), traces[destIdx]);
|
||||
|
||||
{
|
||||
DebugHit *pHit = pWinnerHit;
|
||||
State initialState;
|
||||
CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl, cbufData);
|
||||
|
||||
rdcarray<ShaderVariable> &ins = traces[destIdx].inputs;
|
||||
if(!ins.empty() && ins.back().name == "vCoverage")
|
||||
@@ -1849,15 +1861,17 @@ ShaderDebugTrace D3D12Replay::DebugThread(uint32_t eventId, const uint32_t group
|
||||
|
||||
D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState;
|
||||
|
||||
bytebuf cbufData[D3D12_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
|
||||
GatherConstantBuffers(m_pDevice, dxbc->m_Type, rs.compute, cbufData);
|
||||
|
||||
ShaderDebugTrace ret;
|
||||
|
||||
GlobalState global;
|
||||
global.PopulateGroupshared(dxbc->GetDXBCByteCode());
|
||||
State initialState;
|
||||
CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl, cbufData);
|
||||
CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl);
|
||||
|
||||
WrappedID3D12PipelineState *pso =
|
||||
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12PipelineState>(rs.pipe);
|
||||
GatherConstantBuffers(m_pDevice, *dxbc->GetDXBCByteCode(), rs.compute, refl,
|
||||
pso->CS()->GetMapping(), ret);
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
|
||||
@@ -329,13 +329,19 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
RDCASSERT(dcl.operand.indices.size() == 2 || dcl.operand.indices.size() == 3);
|
||||
RDCASSERT(dcl.operand.indices[0].absolute && dcl.operand.indices[1].absolute);
|
||||
|
||||
// Constant buffer declarations differ between SM5 and SM5.1. For SM5.1, the indices are
|
||||
// logical identifier, start shader register, and end shader register. Register space and
|
||||
// buffer size are stored elsewhere in the declaration. For SM5 and earlier, the indices
|
||||
// are the shader register and buffer size (measured in float4's)
|
||||
bool isShaderModel51 = IsShaderModel51();
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
uint32_t numVecs = (uint32_t)dcl.operand.indices[1].index;
|
||||
uint32_t reg = isShaderModel51 ? (uint32_t)dcl.operand.indices[1].index : idx;
|
||||
uint32_t numVecs = isShaderModel51 ? dcl.float4size : (uint32_t)dcl.operand.indices[1].index;
|
||||
|
||||
desc.name = StringFormat::Fmt("cbuffer%u", idx);
|
||||
desc.type = DXBC::ShaderInputBind::TYPE_CBUFFER;
|
||||
desc.space = dcl.space;
|
||||
desc.reg = idx;
|
||||
desc.reg = reg;
|
||||
desc.bindCount = 1;
|
||||
desc.flags = 1;
|
||||
desc.retType = DXBC::RETURN_TYPE_UNKNOWN;
|
||||
@@ -353,8 +359,12 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
|
||||
cb.name = desc.name;
|
||||
|
||||
// In addition to the register, store the identifier that we'll use to lookup during
|
||||
// debugging. For SM5.1, this is the logical identifier that correlates to the CB order in
|
||||
// the bytecode. For SM5 and earlier, it's the CB register.
|
||||
cb.identifier = idx;
|
||||
cb.space = dcl.space;
|
||||
cb.reg = idx;
|
||||
cb.reg = reg;
|
||||
cb.bindCount = desc.bindCount;
|
||||
|
||||
cb.descriptor.name = cb.name;
|
||||
|
||||
@@ -754,6 +754,7 @@ struct Declaration
|
||||
resType[0] = resType[1] = resType[2] = resType[3] = DXBC::NUM_RETURN_TYPES;
|
||||
dim = RESOURCE_DIMENSION_UNKNOWN;
|
||||
sampleCount = 0;
|
||||
float4size = 0;
|
||||
interpolation = INTERPOLATION_UNDEFINED;
|
||||
systemValue = DXBC::SVNAME_UNDEFINED;
|
||||
maxOut = 0;
|
||||
@@ -828,6 +829,9 @@ struct Declaration
|
||||
ResourceDimension dim;
|
||||
uint32_t sampleCount;
|
||||
|
||||
// OPCODE_DCL_CONSTANT_BUFFER
|
||||
uint32_t float4size;
|
||||
|
||||
// OPCODE_DCL_INPUT_PS
|
||||
InterpolationMode interpolation;
|
||||
|
||||
|
||||
@@ -319,6 +319,7 @@ struct CBuffer
|
||||
{
|
||||
rdcstr name;
|
||||
|
||||
uint32_t identifier;
|
||||
uint32_t space;
|
||||
uint32_t reg;
|
||||
uint32_t bindCount;
|
||||
|
||||
@@ -880,6 +880,10 @@ DXBCContainer::DXBCContainer(const void *ByteCode, size_t ByteCodeLength)
|
||||
|
||||
cbuffernames.insert(cname);
|
||||
|
||||
// In addition to the register, store the identifier that we'll use to lookup during
|
||||
// debugging. For SM5.1, this is the logical identifier that correlates to the CB order in
|
||||
// the bytecode. For SM5 and earlier, it's the CB register.
|
||||
cb.identifier = (h->targetVersion < 0x501) ? cbufferbinds[cname].reg : i;
|
||||
cb.space = cbufferbinds[cname].space;
|
||||
cb.reg = cbufferbinds[cname].reg;
|
||||
cb.bindCount = cbufferbinds[cname].bindCount;
|
||||
|
||||
@@ -1564,9 +1564,14 @@ ShaderVariable State::GetSrc(const Operand &oper, const Operation &op, bool allo
|
||||
{
|
||||
int cb = -1;
|
||||
|
||||
// For this operand, index 0 is always the logical identifier that we can use to
|
||||
// lookup the correct cbuffer. The location of the access entry differs for SM5.1,
|
||||
// as index 1 stores the shader register.
|
||||
uint32_t cbIdentifier = indices[0];
|
||||
uint32_t cbLookup = program->IsShaderModel51() ? indices[2] : indices[1];
|
||||
for(size_t i = 0; i < reflection->CBuffers.size(); i++)
|
||||
{
|
||||
if(reflection->CBuffers[i].reg == indices[0])
|
||||
if(reflection->CBuffers[i].identifier == cbIdentifier)
|
||||
{
|
||||
cb = (int)i;
|
||||
break;
|
||||
@@ -1579,11 +1584,11 @@ ShaderVariable State::GetSrc(const Operand &oper, const Operation &op, bool allo
|
||||
if(cb >= 0 && cb < trace->constantBlocks.count())
|
||||
{
|
||||
RDCASSERTMSG("Out of bounds cbuffer lookup",
|
||||
indices[1] < (uint32_t)trace->constantBlocks[cb].members.count(), indices[1],
|
||||
cbLookup < (uint32_t)trace->constantBlocks[cb].members.count(), cbLookup,
|
||||
trace->constantBlocks[cb].members.count());
|
||||
|
||||
if(indices[1] < (uint32_t)trace->constantBlocks[cb].members.count())
|
||||
v = s = trace->constantBlocks[cb].members[indices[1]];
|
||||
if(cbLookup < (uint32_t)trace->constantBlocks[cb].members.count())
|
||||
v = s = trace->constantBlocks[cb].members[cbLookup];
|
||||
else
|
||||
v = s = ShaderVariable("", 0U, 0U, 0U, 0U);
|
||||
}
|
||||
@@ -4128,7 +4133,7 @@ void GlobalState::PopulateGroupshared(const DXBCBytecode::Program *pBytecode)
|
||||
|
||||
void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebugTrace &trace,
|
||||
int quadIdx, DXBC::DXBCContainer *dxbc,
|
||||
const ShaderReflection &refl, bytebuf *cbufData)
|
||||
const ShaderReflection &refl)
|
||||
{
|
||||
initialState = ShaderDebug::State(quadIdx, &trace, dxbc->GetReflection(), dxbc->GetDXBCByteCode());
|
||||
|
||||
@@ -4268,28 +4273,43 @@ void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebu
|
||||
}
|
||||
}
|
||||
|
||||
// Fill constant buffers and add them to the trace
|
||||
// Set the number of constant buffers in the trace, but assignment happens later
|
||||
size_t numCBuffers = dxbc->GetReflection()->CBuffers.size();
|
||||
trace.constantBlocks.resize(numCBuffers);
|
||||
for(size_t i = 0; i < numCBuffers; i++)
|
||||
|
||||
initialState.Init();
|
||||
}
|
||||
|
||||
void AddCBufferToDebugTrace(const DXBCBytecode::Program &program, ShaderDebugTrace &trace,
|
||||
const ShaderReflection &refl, const ShaderBindpointMapping &mapping,
|
||||
const ShaderDebug::BindingSlot &slot, bytebuf &cbufData)
|
||||
{
|
||||
// Find the identifier
|
||||
size_t numCBs = mapping.constantBlocks.size();
|
||||
for(size_t i = 0; i < numCBs; ++i)
|
||||
{
|
||||
rdcarray<ShaderVariable> vars;
|
||||
|
||||
// Fetch cbuffers into vars, which will be 'natural': structs with members, non merged vectors
|
||||
StandardFillCBufferVariables(refl.resourceId, refl.constantBlocks[i].variables, vars,
|
||||
cbufData[dxbc->GetReflection()->CBuffers[i].reg]);
|
||||
|
||||
FlattenVariables(refl.constantBlocks[i].variables, vars, trace.constantBlocks[i].members);
|
||||
|
||||
for(size_t c = 0; c < trace.constantBlocks[i].members.size(); c++)
|
||||
if((uint32_t)mapping.constantBlocks[i].bindset == slot.registerSpace &&
|
||||
(uint32_t)mapping.constantBlocks[i].bind == slot.shaderRegister)
|
||||
{
|
||||
trace.constantBlocks[i].members[c].name =
|
||||
StringFormat::Fmt("cb%u[%u] (%s)", dxbc->GetReflection()->CBuffers[i].reg, (uint32_t)c,
|
||||
trace.constantBlocks[i].members[c].name.c_str());
|
||||
RDCASSERTMSG("Reassigning previously filled cbuffer", trace.constantBlocks[i].members.empty());
|
||||
|
||||
rdcarray<ShaderVariable> vars;
|
||||
StandardFillCBufferVariables(refl.resourceId, refl.constantBlocks[i].variables, vars, cbufData);
|
||||
FlattenVariables(refl.constantBlocks[i].variables, vars, trace.constantBlocks[i].members);
|
||||
|
||||
const char *format = program.IsShaderModel51() ? "CB%u[%u] (%s)" : "cb%u[%u] (%s)";
|
||||
uint32_t regSlot = program.IsShaderModel51() ? (uint32_t)i : slot.shaderRegister;
|
||||
for(size_t c = 0; c < trace.constantBlocks[i].members.size(); c++)
|
||||
{
|
||||
trace.constantBlocks[i].members[c].name = StringFormat::Fmt(
|
||||
format, regSlot, (uint32_t)c, trace.constantBlocks[i].members[c].name.c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
initialState.Init();
|
||||
RDCERR("Cannot find cbuffer (b%u, space%u) in shader mapping", slot.shaderRegister,
|
||||
slot.registerSpace);
|
||||
}
|
||||
|
||||
bool PromptDebugTimeout(uint32_t cycleCounter)
|
||||
|
||||
@@ -365,6 +365,9 @@ private:
|
||||
|
||||
void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebugTrace &trace,
|
||||
int quadIdx, DXBC::DXBCContainer *dxbc,
|
||||
const ShaderReflection &refl, bytebuf *cbufData);
|
||||
const ShaderReflection &refl);
|
||||
void AddCBufferToDebugTrace(const DXBCBytecode::Program &program, ShaderDebugTrace &trace,
|
||||
const ShaderReflection &refl, const ShaderBindpointMapping &mapping,
|
||||
const ShaderDebug::BindingSlot &slot, bytebuf &cbufData);
|
||||
|
||||
}; // namespace ShaderDebug
|
||||
|
||||
@@ -1447,10 +1447,12 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
retDecl.str += retDecl.operand.toString(m_Reflection, flags);
|
||||
if(sm51)
|
||||
{
|
||||
uint32_t float4size = tokenStream[0];
|
||||
// Store the size provided. If there's no reflection data, this will be
|
||||
// necessary to guess the buffer size properly
|
||||
retDecl.float4size = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += StringFormat::Fmt("[%u]", float4size);
|
||||
retDecl.str += StringFormat::Fmt("[%u]", retDecl.float4size);
|
||||
}
|
||||
|
||||
retDecl.str += ", ";
|
||||
|
||||
Reference in New Issue
Block a user