From fdb6617cb18aaf50f2f793fa26c03127e45c985c Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 29 Jan 2020 16:04:51 +0000 Subject: [PATCH] Pass back 'registers' for resource bindings in debug trace --- qrenderdoc/Windows/ShaderViewer.cpp | 176 +++++++++++++------ qrenderdoc/Windows/ShaderViewer.h | 4 +- renderdoc/api/replay/replay_enums.h | 14 ++ renderdoc/api/replay/shader_types.h | 16 ++ renderdoc/driver/d3d11/d3d11_shaderdebug.cpp | 7 +- renderdoc/driver/d3d12/d3d12_shaderdebug.cpp | 10 +- renderdoc/driver/shaders/dxbc/dxbc_debug.cpp | 147 +++++++++++----- renderdoc/driver/shaders/dxbc/dxbc_debug.h | 3 +- renderdoc/replay/renderdoc_serialise.inl | 4 +- 9 files changed, 276 insertions(+), 105 deletions(-) diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index 307869cdc..f9bec0786 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -1889,89 +1889,103 @@ void ShaderViewer::updateDebugging() } } - rdcarray rw = m_Ctx.CurPipelineState().GetReadWriteResources(m_Stage); - rdcarray ro = m_Ctx.CurPipelineState().GetReadOnlyResources(m_Stage); + rdcarray roBinds = m_Ctx.CurPipelineState().GetReadOnlyResources(m_Stage); - bool tree = false; - - for(int i = 0; - i < m_Mapping->readWriteResources.count() && i < m_ShaderDetails->readWriteResources.count(); - i++) + for(int i = 0; i < m_Trace->readOnlyResources.count(); i++) { - Bindpoint bind = m_Mapping->readWriteResources[i]; + const ShaderVariable &ro = m_Trace->readOnlyResources[i]; + + if(varsMapped.contains(ro.name)) + continue; + + uint32_t idx = ro.value.u.x; + + if(idx >= m_Mapping->readOnlyResources.size()) + continue; + + Bindpoint bind = m_Mapping->readOnlyResources[idx]; if(!bind.used) continue; - int idx = rw.indexOf(bind); + int32_t bindIdx = roBinds.indexOf(bind); - if(idx < 0 || rw[idx].resources.isEmpty()) + if(bindIdx < 0) continue; - QString bindname = makeBindName(bind, false); + BoundResourceArray roBind = roBinds[bindIdx]; if(bind.arraySize == 1) { RDTreeWidgetItem *node = - new RDTreeWidgetItem({bindname, m_ShaderDetails->readWriteResources[i].name, - lit("RW Resource"), ToQStr(rw[idx].resources[0].resourceId)}); + new RDTreeWidgetItem({m_ShaderDetails->readOnlyResources[i].name, ro.name, + lit("Resource"), ToQStr(roBind.resources[0].resourceId)}); if(node) ui->constants->addTopLevelItem(node); } else { RDTreeWidgetItem *node = - new RDTreeWidgetItem({bindname, m_ShaderDetails->readWriteResources[i].name, + new RDTreeWidgetItem({m_ShaderDetails->readOnlyResources[i].name, QString(), QFormatStr("[%1]").arg(bind.arraySize), QString()}); for(uint32_t a = 0; a < bind.arraySize; a++) - node->addChild(new RDTreeWidgetItem( - {QFormatStr("%1[%2]").arg(bindname).arg(a), m_ShaderDetails->readWriteResources[i].name, - lit("Resource"), ToQStr(rw[idx].resources[a].resourceId)})); - - tree = true; + node->addChild(new RDTreeWidgetItem({ + QFormatStr("%1[%2]").arg(m_ShaderDetails->readOnlyResources[i].name).arg(a), + QFormatStr("%1[%2]").arg(ro.name).arg(a), lit("Resource"), + ToQStr(roBind.resources[a].resourceId), + })); ui->constants->addTopLevelItem(node); } } - for(int i = 0; - i < m_Mapping->readOnlyResources.count() && i < m_ShaderDetails->readOnlyResources.count(); - i++) + rdcarray rwBinds = m_Ctx.CurPipelineState().GetReadWriteResources(m_Stage); + + for(int i = 0; i < m_Trace->readWriteResources.count(); i++) { - Bindpoint bind = m_Mapping->readOnlyResources[i]; + const ShaderVariable &rw = m_Trace->readWriteResources[i]; + + if(varsMapped.contains(rw.name)) + continue; + + uint32_t idx = rw.value.u.x; + + if(idx >= m_Mapping->readWriteResources.size()) + continue; + + Bindpoint bind = m_Mapping->readWriteResources[idx]; if(!bind.used) continue; - int idx = ro.indexOf(bind); + int32_t bindIdx = rwBinds.indexOf(bind); - if(idx < 0 || ro[idx].resources.isEmpty()) + if(bindIdx < 0) continue; - QString bindname = makeBindName(bind, true); + BoundResourceArray rwBind = rwBinds[bindIdx]; if(bind.arraySize == 1) { RDTreeWidgetItem *node = - new RDTreeWidgetItem({bindname, m_ShaderDetails->readOnlyResources[i].name, - lit("Resource"), ToQStr(ro[idx].resources[0].resourceId)}); + new RDTreeWidgetItem({m_ShaderDetails->readWriteResources[i].name, rw.name, + lit("Resource"), ToQStr(rwBind.resources[0].resourceId)}); if(node) ui->constants->addTopLevelItem(node); } else { RDTreeWidgetItem *node = - new RDTreeWidgetItem({bindname, m_ShaderDetails->readOnlyResources[i].name, - m_ShaderDetails->readOnlyResources[i].name, + new RDTreeWidgetItem({m_ShaderDetails->readWriteResources[i].name, QString(), QFormatStr("[%1]").arg(bind.arraySize), QString()}); for(uint32_t a = 0; a < bind.arraySize; a++) - node->addChild(new RDTreeWidgetItem( - {QFormatStr("%1[%2]").arg(bindname).arg(a), m_ShaderDetails->readOnlyResources[i].name, - lit("Resource"), ToQStr(ro[idx].resources[a].resourceId)})); - - tree = true; + node->addChild(new RDTreeWidgetItem({ + QFormatStr("%1[%2]").arg(m_ShaderDetails->readWriteResources[i].name).arg(a), + QFormatStr("%1[%2]").arg(rw.name).arg(a), lit("RW Resource"), + ToQStr(rwBind.resources[a].resourceId), + })); ui->constants->addTopLevelItem(node); } @@ -2306,19 +2320,6 @@ void ShaderViewer::updateDebugging() updateVariableTooltip(); } -QString ShaderViewer::makeBindName(Bindpoint &bind, bool readOnly) -{ - QChar regChar(QLatin1Char('u')); - - if(readOnly) - regChar = QLatin1Char('t'); - - if(m_Ctx.APIProps().pipelineType == GraphicsAPI::D3D12) - return QFormatStr("%1%2:%3").arg(regChar).arg(bind.bindset).arg(bind.bind); - else - return QFormatStr("%1%2").arg(regChar).arg(bind.bind); -} - RDTreeWidgetItem *ShaderViewer::makeSourceVariableNode(const SourceVariableMapping &l) { const ShaderDebugState &state = m_Trace->states[m_CurrentStep]; @@ -2367,6 +2368,54 @@ RDTreeWidgetItem *ShaderViewer::makeSourceVariableNode(const SourceVariableMappi regNames += lit("-"); value += lit("?"); } + else if(r.type == DebugVariableType::ReadOnlyResource || + r.type == DebugVariableType::ReadWriteResource) + { + const bool isReadOnlyResource = r.type == DebugVariableType::ReadOnlyResource; + + const ShaderVariable *reg = GetRegisterVariable(r); + + regNames = GetRegisterVariable(r)->name; + typeName = isReadOnlyResource ? lit("Resource") : lit("RW Resource"); + + rdcarray resList = + isReadOnlyResource ? m_Ctx.CurPipelineState().GetReadOnlyResources(m_Stage) + : m_Ctx.CurPipelineState().GetReadWriteResources(m_Stage); + + uint32_t idx = reg->value.u.x; + + if(isReadOnlyResource && idx >= m_Mapping->readOnlyResources.size()) + continue; + if(!isReadOnlyResource && idx >= m_Mapping->readWriteResources.size()) + continue; + + Bindpoint bind = isReadOnlyResource ? m_Mapping->readOnlyResources[idx] + : m_Mapping->readWriteResources[idx]; + + int32_t bindIdx = resList.indexOf(bind); + + if(bindIdx < 0) + continue; + + BoundResourceArray res = resList[bindIdx]; + + if(bind.arraySize == 1) + { + value = ToQStr(res.resources[0].resourceId); + } + else + { + for(uint32_t a = 0; a < bind.arraySize; a++) + children.push_back(new RDTreeWidgetItem({ + QFormatStr("%1[%2]").arg(localName).arg(a), QFormatStr("%1[%2]").arg(regNames).arg(a), + typeName, ToQStr(res.resources[a].resourceId), + })); + + regNames = QString(); + typeName = QFormatStr("[%1]").arg(bind.arraySize); + value = QString(); + } + } else { const ShaderVariable *reg = GetRegisterVariable(r); @@ -2406,9 +2455,14 @@ RDTreeWidgetItem *ShaderViewer::makeSourceVariableNode(const SourceVariableMappi { if(((i + 1) % l.columns) == 0) { + QString localBaseName = localName; + int dot = localBaseName.lastIndexOf(QLatin1Char('.')); + if(dot >= 0) + localBaseName = localBaseName.mid(dot + 1); + uint32_t row = (uint32_t)i / l.columns; children.push_back(new RDTreeWidgetItem( - {QFormatStr("%1.row%2").arg(localName).arg(row), regNames, typeName, value})); + {QFormatStr("%1.row%2").arg(localBaseName).arg(row), regNames, typeName, value})); regNames = QString(); value = QString(); } @@ -2436,6 +2490,22 @@ const ShaderVariable *ShaderViewer::GetRegisterVariable(const DebugVariableRefer return NULL; } + else if(r.type == DebugVariableType::ReadOnlyResource) + { + for(int i = 0; i < m_Trace->readOnlyResources.count(); i++) + if(m_Trace->readOnlyResources[i].name == r.name) + return GetRegisterVariable(VariableCategory::ReadOnlyResource, i, 0); + + return NULL; + } + else if(r.type == DebugVariableType::ReadWriteResource) + { + for(int i = 0; i < m_Trace->readWriteResources.count(); i++) + if(m_Trace->readWriteResources[i].name == r.name) + return GetRegisterVariable(VariableCategory::ReadWriteResource, i, 0); + + return NULL; + } else if(r.type == DebugVariableType::Constant) { for(int i = 0; i < m_Trace->constantBlocks.count(); i++) @@ -2491,6 +2561,14 @@ const ShaderVariable *ShaderViewer::GetRegisterVariable(VariableCategory categor if(index >= 0 && index < state.variables.count()) var = &state.variables[index]; break; + case VariableCategory::ReadOnlyResource: + if(index >= 0 && index < m_Trace->readOnlyResources.count()) + var = &m_Trace->readOnlyResources[index]; + break; + case VariableCategory::ReadWriteResource: + if(index >= 0 && index < m_Trace->readWriteResources.count()) + var = &m_Trace->readWriteResources[index]; + break; default: break; } diff --git a/qrenderdoc/Windows/ShaderViewer.h b/qrenderdoc/Windows/ShaderViewer.h index e1aa4a901..1fb253003 100644 --- a/qrenderdoc/Windows/ShaderViewer.h +++ b/qrenderdoc/Windows/ShaderViewer.h @@ -50,6 +50,8 @@ enum class VariableCategory Unknown, Inputs, Constants, + ReadOnlyResource, + ReadWriteResource, Variables, ByString, }; @@ -266,8 +268,6 @@ private: void updateDebugging(); - QString makeBindName(Bindpoint &bind, bool readOnly); - RDTreeWidgetItem *makeSourceVariableNode(const SourceVariableMapping &l); const ShaderVariable *GetRegisterVariable(const DebugVariableReference &r); diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index c016dd344..4bc504214 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -120,6 +120,18 @@ DOCUMENT(R"(Represents the category of debugging variable that a source variable A constant buffer value, stored globally. +.. data:: ReadOnlyResource + + A read-only resource, stored globally. + +.. data:: ReadWriteResource + + A read-write resource, stored globally. + +.. data:: Constant + + A constant buffer value, stored globally. + .. data:: Variable A mutable variable, stored per state. @@ -129,6 +141,8 @@ enum class DebugVariableType : uint8_t Undefined, Input, Constant, + ReadOnlyResource, + ReadWriteResource, Variable, }; diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index 4f9a99a34..12a8a97ba 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -575,6 +575,22 @@ it may have been vectorised and flattened. )"); rdcarray constantBlocks; + DOCUMENT(R"(The read-only resource variables for this shader as a list of :class:`ShaderVariable`. + +The 'value' of the variable is always a single unsigned integer, which is the bindpoint - an index +into the :data:`ShaderBindpointMapping.readOnlyResources` list, which can be used to look up the +other metadata as well as find the binding from the pipeline state. +)"); + rdcarray readOnlyResources; + + DOCUMENT(R"(The read-write resource variables for this shader as a list of :class:`ShaderVariable`. + +The 'value' of the variable is always a single unsigned integer, which is the bindpoint - an index +into the :data:`ShaderBindpointMapping.readWriteResources` list, which can be used to look up the +other metadata as well as find the binding from the pipeline state. +)"); + rdcarray readWriteResources; + DOCUMENT(R"(An optional list of :class:`SourceVariableMapping` indicating which high-level source variables map to which debug variables and includes extra type information. diff --git a/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp b/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp index e28fde42b..b99144b08 100644 --- a/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp +++ b/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp @@ -1817,7 +1817,7 @@ ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventId, uint32_t vertid, uin GlobalState global; global.PopulateGroupshared(dxbc->GetDXBCByteCode()); State initialState; - CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl); + CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl, vs->GetMapping()); AddCBuffersToDebugTrace(*dxbc->GetDXBCByteCode(), *GetDebugManager(), ret, rs->VS, refl, vs->GetMapping()); @@ -2718,7 +2718,8 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim global.sampleEvalRegisterMask = sampleEvalRegisterMask; State initialState; - CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl); + CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl, + ps->GetMapping()); AddCBuffersToDebugTrace(*dxbc->GetDXBCByteCode(), *GetDebugManager(), traces[destIdx], rs->PS, refl, ps->GetMapping()); @@ -3007,7 +3008,7 @@ ShaderDebugTrace D3D11Replay::DebugThread(uint32_t eventId, const uint32_t group GlobalState global; global.PopulateGroupshared(dxbc->GetDXBCByteCode()); State initialState; - CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl); + CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl, cs->GetMapping()); AddCBuffersToDebugTrace(*dxbc->GetDXBCByteCode(), *GetDebugManager(), ret, rs->CS, refl, cs->GetMapping()); diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index e8c5eacd3..6b22912a2 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -1579,7 +1579,8 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim global.PopulateGroupshared(dxbc->GetDXBCByteCode()); State initialState; - CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl); + CreateShaderDebugStateAndTrace(initialState, traces[destIdx], destIdx, dxbc, refl, + origPSO->PS()->GetMapping()); // Fetch constant buffer data from root signature GatherConstantBuffers(m_pDevice, *dxbc->GetDXBCByteCode(), rs.graphics, refl, @@ -1850,13 +1851,14 @@ ShaderDebugTrace D3D12Replay::DebugThread(uint32_t eventId, const uint32_t group ShaderDebugTrace ret; + WrappedID3D12PipelineState *pso = + m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); + GlobalState global; global.PopulateGroupshared(dxbc->GetDXBCByteCode()); State initialState; - CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl); + CreateShaderDebugStateAndTrace(initialState, ret, -1, dxbc, refl, pso->CS()->GetMapping()); - WrappedID3D12PipelineState *pso = - m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); GatherConstantBuffers(m_pDevice, *dxbc->GetDXBCByteCode(), rs.compute, refl, pso->CS()->GetMapping(), ret); diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index ad1b35fb2..3363e71e8 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -4165,7 +4165,8 @@ void GlobalState::PopulateGroupshared(const DXBCBytecode::Program *pBytecode) void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebugTrace &trace, int quadIdx, DXBC::DXBCContainer *dxbc, - const ShaderReflection &refl) + const ShaderReflection &refl, + const ShaderBindpointMapping &mapping) { initialState = ShaderDebug::State(quadIdx, &trace, dxbc->GetReflection(), dxbc->GetDXBCByteCode()); @@ -4217,14 +4218,14 @@ void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebu dst.columns = RDCMAX(dst.columns, v.columns); { - SourceVariableMapping mapping; - mapping.name = sig.semanticIdxName; - if(mapping.name.empty() && sig.systemValue != ShaderBuiltin::Undefined) - mapping.name = ToStr(sig.systemValue); - mapping.type = v.type; - mapping.rows = 1; - mapping.columns = sig.compCount; - mapping.variables.reserve(sig.compCount); + SourceVariableMapping sourcemap; + sourcemap.name = sig.semanticIdxName; + if(sourcemap.name.empty() && sig.systemValue != ShaderBuiltin::Undefined) + sourcemap.name = ToStr(sig.systemValue); + sourcemap.type = v.type; + sourcemap.rows = 1; + sourcemap.columns = sig.compCount; + sourcemap.variables.reserve(sig.compCount); for(uint16_t c = 0; c < 4; c++) { @@ -4234,11 +4235,11 @@ void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebu ref.name = v.name; ref.type = DebugVariableType::Input; ref.component = c; - mapping.variables.push_back(ref); + sourcemap.variables.push_back(ref); } } - trace.sourceVars.push_back(mapping); + trace.sourceVars.push_back(sourcemap); } } @@ -4251,17 +4252,17 @@ void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebu trace.inputs.back().columns = 1; { - SourceVariableMapping mapping; - mapping.name = "SV_Coverage"; - mapping.type = VarType::UInt; - mapping.rows = 1; - mapping.columns = 1; + SourceVariableMapping sourcemap; + sourcemap.name = "SV_Coverage"; + sourcemap.type = VarType::UInt; + sourcemap.rows = 1; + sourcemap.columns = 1; DebugVariableReference ref; ref.type = DebugVariableType::Input; ref.name = trace.inputs.back().name; - mapping.variables.push_back(ref); + sourcemap.variables.push_back(ref); - trace.sourceVars.push_back(mapping); + trace.sourceVars.push_back(sourcemap); } } } @@ -4327,14 +4328,14 @@ void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebu { if(type == DXBCBytecode::TYPE_OUTPUT) { - SourceVariableMapping mapping; - mapping.name = sig.semanticIdxName; - if(mapping.name.empty() && sig.systemValue != ShaderBuiltin::Undefined) - mapping.name = ToStr(sig.systemValue); - mapping.type = v.type; - mapping.rows = 1; - mapping.columns = sig.compCount; - mapping.variables.reserve(sig.compCount); + SourceVariableMapping sourcemap; + sourcemap.name = sig.semanticIdxName; + if(sourcemap.name.empty() && sig.systemValue != ShaderBuiltin::Undefined) + sourcemap.name = ToStr(sig.systemValue); + sourcemap.type = v.type; + sourcemap.rows = 1; + sourcemap.columns = sig.compCount; + sourcemap.variables.reserve(sig.compCount); for(uint16_t c = 0; c < 4; c++) { @@ -4344,58 +4345,114 @@ void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebu ref.type = DebugVariableType::Variable; ref.name = v.name; ref.component = c; - mapping.variables.push_back(ref); + sourcemap.variables.push_back(ref); } } - trace.sourceVars.push_back(mapping); + trace.sourceVars.push_back(sourcemap); } else { - SourceVariableMapping mapping; + SourceVariableMapping sourcemap; if(sig.systemValue == ShaderBuiltin::DepthOutput) { - mapping.name = "SV_Depth"; - mapping.type = VarType::Float; + sourcemap.name = "SV_Depth"; + sourcemap.type = VarType::Float; } else if(sig.systemValue == ShaderBuiltin::DepthOutputLessEqual) { - mapping.name = "SV_DepthLessEqual"; - mapping.type = VarType::Float; + sourcemap.name = "SV_DepthLessEqual"; + sourcemap.type = VarType::Float; } else if(sig.systemValue == ShaderBuiltin::DepthOutputGreaterEqual) { - mapping.name = "SV_DepthGreaterEqual"; - mapping.type = VarType::Float; + sourcemap.name = "SV_DepthGreaterEqual"; + sourcemap.type = VarType::Float; } else if(sig.systemValue == ShaderBuiltin::MSAACoverage) { - mapping.name = "SV_Coverage"; - mapping.type = VarType::UInt; + sourcemap.name = "SV_Coverage"; + sourcemap.type = VarType::UInt; } else if(sig.systemValue == ShaderBuiltin::StencilReference) { - mapping.name = "SV_StencilRef"; - mapping.type = VarType::UInt; + sourcemap.name = "SV_StencilRef"; + sourcemap.type = VarType::UInt; } // all these variables are 1 scalar component - mapping.rows = 1; - mapping.columns = 1; + sourcemap.rows = 1; + sourcemap.columns = 1; DebugVariableReference ref; ref.type = DebugVariableType::Variable; ref.name = v.name; - mapping.variables.push_back(ref); + sourcemap.variables.push_back(ref); - trace.sourceVars.push_back(mapping); + trace.sourceVars.push_back(sourcemap); } } } // Set the number of constant buffers in the trace, but assignment happens later - size_t numCBuffers = dxbc->GetReflection()->CBuffers.size(); - trace.constantBlocks.resize(numCBuffers); + trace.constantBlocks.resize(refl.constantBlocks.size()); + + struct ResList + { + DebugVariableType varType; + const rdcarray &binds; + const rdcarray &resources; + const char *regChars; + rdcarray &dst; + }; + + ResList lists[2] = { + { + DebugVariableType::ReadOnlyResource, mapping.readOnlyResources, refl.readOnlyResources, + "tT", trace.readOnlyResources, + }, + { + DebugVariableType::ReadWriteResource, mapping.readWriteResources, refl.readWriteResources, + "uU", trace.readWriteResources, + }, + }; + + for(ResList &list : lists) + { + // add the registers for the resources that are used + list.dst.reserve(list.binds.size()); + for(size_t i = 0; i < list.binds.size(); i++) + { + const Bindpoint &b = list.binds[i]; + const ShaderResource &r = list.resources[i]; + + if(!b.used) + continue; + + rdcstr identifier; + + if(dxbc->GetDXBCByteCode()->IsShaderModel51()) + identifier = StringFormat::Fmt("%c%zu", list.regChars[1], i); + else + identifier = StringFormat::Fmt("%c%u", list.regChars[0], b.bind); + + ShaderVariable reg(identifier, (uint32_t)i, 0U, 0U, 0U); + reg.columns = 1; + + SourceVariableMapping sourcemap; + sourcemap.name = r.name; + sourcemap.type = r.variableType.descriptor.type; + sourcemap.rows = r.variableType.descriptor.rows; + sourcemap.columns = r.variableType.descriptor.columns; + DebugVariableReference ref; + ref.type = list.varType; + ref.name = reg.name; + sourcemap.variables.push_back(ref); + + trace.sourceVars.push_back(sourcemap); + list.dst.push_back(reg); + } + } } void AddCBufferToDebugTrace(const DXBCBytecode::Program &program, ShaderDebugTrace &trace, diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.h b/renderdoc/driver/shaders/dxbc/dxbc_debug.h index aca76e47b..aeadc5142 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.h @@ -359,7 +359,8 @@ private: void CreateShaderDebugStateAndTrace(ShaderDebug::State &initialState, ShaderDebugTrace &trace, int quadIdx, DXBC::DXBCContainer *dxbc, - const ShaderReflection &refl); + const ShaderReflection &refl, + const ShaderBindpointMapping &mapping); void AddCBufferToDebugTrace(const DXBCBytecode::Program &program, ShaderDebugTrace &trace, const ShaderReflection &refl, const ShaderBindpointMapping &mapping, const ShaderDebug::BindingSlot &slot, bytebuf &cbufData); diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index e1dd1ff95..bae0e6aff 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -393,12 +393,14 @@ void DoSerialise(SerialiserType &ser, ShaderDebugTrace &el) { SERIALISE_MEMBER(inputs); SERIALISE_MEMBER(constantBlocks); + SERIALISE_MEMBER(readOnlyResources); + SERIALISE_MEMBER(readWriteResources); SERIALISE_MEMBER(sourceVars); SERIALISE_MEMBER(states); SERIALISE_MEMBER(hasSourceMapping); SERIALISE_MEMBER(lineInfo); - SIZE_CHECK(128); + SIZE_CHECK(176); } template