From 2329e68f26dcc775ceb63a737acc2249dcb0569f Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Tue, 14 May 2024 10:00:58 +0100 Subject: [PATCH] RD DXIL Disassembly refactoring to support DXIL Debugging Added: void Parse(const DXBC::Reflection *reflection); void ParseReferences(const DXBC::Reflection *reflection); const ResourceReference *GetResourceReference(const rdcstr &handleStr) const; rdcstr GetResourceReferenceName(ResourceClass resClass, const BindingSlot &slot) const; Changed: void FetchEntryPointInterfaces(rdcarray &entryPointInterfaces); to void FillEntryPointInterfaces(); and store the entry point interface data in new member variable "m_EntryPointInterfaces" To get the SSA names for handles that are referenced by createHandle calls Added DoStringise() for DXIL::ResourceClass --- renderdoc/driver/shaders/dxil/dxil_bytecode.h | 25 +- renderdoc/driver/shaders/dxil/dxil_common.cpp | 14 + renderdoc/driver/shaders/dxil/dxil_common.h | 13 + .../driver/shaders/dxil/dxil_disassemble.cpp | 346 ++++++++++-------- .../driver/shaders/dxil/dxil_reflect.cpp | 56 ++- 5 files changed, 299 insertions(+), 155 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index 2ccdee694..4f6759d69 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -1196,13 +1196,14 @@ struct EntryPointInterface struct ResourceBase { - ResourceBase(const Metadata *resourceBase); + ResourceBase(ResourceClass resourceClass, const Metadata *resourceBase); uint32_t id; const Type *type; rdcstr name; uint32_t space; uint32_t regBase; uint32_t regCount; + const ResourceClass resClass; }; struct SRV : ResourceBase @@ -1252,6 +1253,16 @@ struct EntryPointInterface rdcarray samplers; }; +struct ResourceReference +{ + ResourceReference(rdcstr handleStr, const EntryPointInterface::ResourceBase &resBase, uint32_t idx) + : handleID(handleStr), resourceBase(resBase), resourceIndex(idx){}; + + rdcstr handleID; + EntryPointInterface::ResourceBase resourceBase; + uint32_t resourceIndex; +}; + class Program : public DXBC::IDebugInfo { public: @@ -1267,6 +1278,8 @@ public: DXBC::Reflection *GetReflection(); rdcstr GetDebugStatus(); rdcarray GetEntryPoints(); + void FillEntryPointInterfaces(); + rdcstr GetResourceReferenceName(ResourceClass resClass, const BindingSlot &slot) const; void FillRayPayloads( Program *executable, rdcflatmap> @@ -1294,7 +1307,9 @@ public: const Metadata *GetMetadataByName(const rdcstr &name) const; uint32_t GetDirectHeapAcessCount() const { return m_directHeapAccessCount; } protected: + void Parse(const DXBC::Reflection *reflection); void SettleIDs(); + void ParseReferences(const DXBC::Reflection *reflection); void MakeDXCDisassemblyString(); void MakeRDDisassemblyString(const DXBC::Reflection *reflection); @@ -1312,7 +1327,8 @@ protected: uint32_t GetMetaSlot(const DebugLocation *l) const; void AssignMetaSlot(rdcarray &metaSlots, uint32_t &nextMetaSlot, DebugLocation &l); - void FetchEntryPointInterfaces(rdcarray &entryPointInterfaces); + const ResourceReference *GetResourceReference(const rdcstr &handleStr) const; + const Metadata *FindMetadata(uint32_t slot) const; rdcstr ArgToString(const Value *v, bool withTypes, const rdcstr &attrString = "") const; rdcstr DisassembleComDats(int &instructionLine) const; @@ -1376,10 +1392,13 @@ protected: bool m_Uselists = false; bool m_DXCStyle = false; - bool m_SettledIDs = false; + bool m_Parsed = false; rdcstr m_Triple, m_Datalayout; + rdcarray m_EntryPointInterfaces; + std::map m_ResourceHandles; + rdcarray m_ResourceReferences; rdcstr m_Disassembly; int m_DisassemblyInstructionLine; diff --git a/renderdoc/driver/shaders/dxil/dxil_common.cpp b/renderdoc/driver/shaders/dxil/dxil_common.cpp index ec1ab0f48..eb32703f5 100644 --- a/renderdoc/driver/shaders/dxil/dxil_common.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_common.cpp @@ -49,3 +49,17 @@ rdcstr DoStringise(const DXIL::ComponentType &el) } END_ENUM_STRINGISE(); } + +template <> +rdcstr DoStringise(const DXIL::ResourceClass &el) +{ + BEGIN_ENUM_STRINGISE(DXIL::ResourceClass); + { + STRINGISE_ENUM_CLASS(SRV); + STRINGISE_ENUM_CLASS(UAV); + STRINGISE_ENUM_CLASS(CBuffer); + STRINGISE_ENUM_CLASS(Sampler); + STRINGISE_ENUM_CLASS_NAMED(Invalid, ""); + } + END_ENUM_STRINGISE(); +} diff --git a/renderdoc/driver/shaders/dxil/dxil_common.h b/renderdoc/driver/shaders/dxil/dxil_common.h index f412e02a6..799667b3b 100644 --- a/renderdoc/driver/shaders/dxil/dxil_common.h +++ b/renderdoc/driver/shaders/dxil/dxil_common.h @@ -147,6 +147,19 @@ enum class SamplerFeedbackType : uint8_t LastEntry = 2 }; +struct BindingSlot +{ + BindingSlot() : shaderRegister(UINT32_MAX), registerSpace(UINT32_MAX) {} + BindingSlot(uint32_t shaderReg, uint32_t regSpace) + : shaderRegister(shaderReg), registerSpace(regSpace) + { + } + + uint32_t shaderRegister; + uint32_t registerSpace; +}; + }; // namespace DXIL DECLARE_STRINGISE_TYPE(DXIL::ComponentType); +DECLARE_STRINGISE_TYPE(DXIL::ResourceClass); diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index 104f772b1..4dde0889b 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -474,11 +474,22 @@ rdcstr GetCBufferVariableTypeName(const DXBC::CBufferVariableType &type) return ret; } -void Program::SettleIDs() +void Program::Parse(const DXBC::Reflection *reflection) { - if(m_SettledIDs) + if(m_Parsed) return; + SettleIDs(); + + m_EntryPointInterfaces.clear(); + FillEntryPointInterfaces(); + ParseReferences(reflection); + + m_Parsed = true; +} + +void Program::SettleIDs() +{ RDCASSERTEQUAL(m_NextMetaSlot, 0); RDCASSERT(m_MetaSlots.isEmpty()); @@ -689,8 +700,6 @@ void Program::SettleIDs() m_FuncAttrGroups.push_back(m_AttributeGroups[i]); } - - m_SettledIDs = true; } const Metadata *Program::FindMetadata(uint32_t slot) const @@ -1008,7 +1017,19 @@ const rdcstr &Program::GetDisassembly(bool dxcStyle, const DXBC::Reflection *ref if(m_Disassembly.empty() || (dxcStyle != m_DXCStyle)) { m_DXCStyle = dxcStyle; - SettleIDs(); + // Need to set the style formatting before Parse() to get consistent SSA identifiers + if(m_DXCStyle) + { + DXIL::dxcStyleFormatting = true; + DXIL::dxilIdentifier = '%'; + } + else + { + DXIL::dxcStyleFormatting = false; + DXIL::dxilIdentifier = '_'; + } + + Parse(reflection); if(dxcStyle) MakeDXCDisassemblyString(); @@ -1020,9 +1041,6 @@ const rdcstr &Program::GetDisassembly(bool dxcStyle, const DXBC::Reflection *ref void Program::MakeDXCDisassemblyString() { - DXIL::dxcStyleFormatting = true; - DXIL::dxilIdentifier = '%'; - m_Disassembly.clear(); #if DISABLED(DXC_COMPATIBLE_DISASM) m_Disassembly += StringFormat::Fmt("; %s Shader, compiled under SM%u.%u\n\n", @@ -2034,25 +2052,8 @@ static rdcstr MakeCBufferRegisterStr(uint32_t reg, DXIL::EntryPointInterface::CB return ret; } -struct ResourceHandle -{ - rdcstr name; - ResourceClass resourceClass; - uint32_t resourceIndex = 0; - union - { - const DXIL::EntryPointInterface::UAV *uav; - const DXIL::EntryPointInterface::SRV *srv; - const DXIL::EntryPointInterface::CBuffer *cbuffer; - const DXIL::EntryPointInterface::Sampler *sampler; - }; -}; - void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) { - DXIL::dxcStyleFormatting = false; - DXIL::dxilIdentifier = '_'; - m_Disassembly.clear(); m_DisassemblyInstructionLine = 1; @@ -2066,9 +2067,6 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) const char *swizzle = "xyzw"; - rdcarray entryPoints; - FetchEntryPointInterfaces(entryPoints); - for(size_t i = 0; i < m_Functions.size(); i++) { const Function &func = *m_Functions[i]; @@ -2081,11 +2079,11 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) if(!func.external) { EntryPointInterface *entryPoint = NULL; - for(size_t e = 0; e < entryPoints.size(); ++e) + for(size_t e = 0; e < m_EntryPointInterfaces.size(); ++e) { - if(func.name == entryPoints[e].name) + if(func.name == m_EntryPointInterfaces[e].name) { - entryPoint = &entryPoints[e]; + entryPoint = &m_EntryPointInterfaces[e]; break; } } @@ -2172,15 +2170,6 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) if(needBlankLine) DisassemblyAddNewLine(); EntryPointInterface::SRV &srv = entryPoint->srvs[j]; - if(srv.name.empty() && reflection) - { - for(DXBC::ShaderInputBind bind : reflection->SRVs) - { - if((bind.space == srv.space) && (bind.reg == srv.regBase) && - (bind.bindCount == srv.regCount)) - srv.name = bind.name; - } - } m_Disassembly += GetResourceShapeName(srv.shape, false); m_Disassembly += "<" + GetResourceTypeName(srv.type) + ">"; m_Disassembly += " " + srv.name; @@ -2206,15 +2195,6 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) if(needBlankLine) DisassemblyAddNewLine(); EntryPointInterface::UAV &uav = entryPoint->uavs[j]; - if(uav.name.empty() && reflection) - { - for(DXBC::ShaderInputBind bind : reflection->UAVs) - { - if((bind.space == uav.space) && (bind.reg == uav.regBase) && - (bind.bindCount == uav.regCount)) - uav.name = bind.name; - } - } m_Disassembly += GetResourceShapeName(uav.shape, true); m_Disassembly += "<" + GetResourceTypeName(uav.type) + ">"; m_Disassembly += " " + uav.name; @@ -2248,8 +2228,6 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) if((cb.space == cbuffer.space) && (cb.reg == cbuffer.regBase) && (cb.bindCount == cbuffer.regCount)) { - if(cbuffer.name.empty()) - cbuffer.name = cb.name; if(!cbuffer.cbufferRefl) cbuffer.cbufferRefl = &reflection->CBuffers[cbIdx]; } @@ -2299,15 +2277,6 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) if(needBlankLine) DisassemblyAddNewLine(); EntryPointInterface::Sampler &sampler = entryPoint->samplers[j]; - if(sampler.name.empty() && reflection) - { - for(DXBC::ShaderInputBind s : reflection->Samplers) - { - if((s.space == sampler.space) && (s.reg == sampler.regBase) && - (s.bindCount == sampler.regCount)) - sampler.name = s.name; - } - } m_Disassembly += GetSamplerTypeName(sampler.type); m_Disassembly += " " + sampler.name; if(sampler.regCount > 1) @@ -2349,7 +2318,6 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) m_Disassembly += "{"; DisassemblyAddNewLine(); - std::map resHandles; std::map ssaAliases; size_t curBlock = 0; @@ -2483,77 +2451,28 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) uint32_t dxopCode; RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, (uint32_t)DXOp::createHandle); - rdcstr handleStr = resultIdStr; - ResourceClass resClass; - rdcstr resName; - uint32_t resIndex; - bool hasResIndex = getival(inst.args[2], resIndex); - if(getival(inst.args[1], resClass)) - { - if(hasResIndex) - { - ResourceHandle resHandle; - bool validRes = true; - switch(resClass) - { - case ResourceClass::SRV: - resName = entryPoint->srvs[resIndex].name; - resHandle.srv = &entryPoint->srvs[resIndex]; - break; - case ResourceClass::UAV: - resName = entryPoint->uavs[resIndex].name; - resHandle.uav = &entryPoint->uavs[resIndex]; - break; - case ResourceClass::CBuffer: - resName = entryPoint->cbuffers[resIndex].name; - resHandle.cbuffer = &entryPoint->cbuffers[resIndex]; - break; - case ResourceClass::Sampler: - resName = entryPoint->samplers[resIndex].name; - resHandle.sampler = &entryPoint->samplers[resIndex]; - break; - default: - validRes = false; - resName = "INVALID RESOURCE CLASS"; - break; - }; - if(validRes) - { - resHandle.name = resName; - resHandle.resourceClass = resClass; - resHandle.resourceIndex = resIndex; - resHandles[handleStr] = resHandle; - ssaAliases[handleStr] = resName; - } - uint32_t index; - if(getival(inst.args[3], index)) - { - if(index != resIndex) - commentStr += " index = " + ToStr(index); - } - } - else + rdcstr handleStr(resultIdStr); + rdcstr resName; + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) + { + resName = resRef->resourceBase.name; + + uint32_t index; + if(getival(inst.args[3], index)) { - switch(resClass) - { - case ResourceClass::SRV: resName = "SRV"; break; - case ResourceClass::UAV: resName = "UAV"; break; - case ResourceClass::CBuffer: resName = "CBuffer"; break; - case ResourceClass::Sampler: resName = "Sampler"; break; - default: resName = "INVALID RESOURCE CLASS"; break; - }; + if(index != resRef->resourceIndex) + commentStr += " index = " + ToStr(index); } } else { resName = "ResourceClass:" + ArgToString(inst.args[1], false); - } - if(!hasResIndex) - { resName += "[" + ArgToString(inst.args[2], false) + "]"; commentStr += " index = " + ArgToString(inst.args[3], false); } + ssaAliases[handleStr] = resName; uint32_t value; if(getival(inst.args[4], value)) { @@ -2575,7 +2494,8 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) else RDCASSERTEQUAL(dxopCode, (uint32_t)DXOp::cbufferLoad); rdcstr handleStr = ArgToString(inst.args[1], false); - if(resHandles.count(handleStr) > 0) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) { uint32_t regIndex; if(getival(inst.args[2], regIndex)) @@ -2587,8 +2507,8 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) regIndex = regIndex / 16; // uint32_t alignment = getival(inst.args[3]); } - uint32_t resourceIndex = resHandles[handleStr].resourceIndex; - lineStr += MakeCBufferRegisterStr(regIndex, entryPoint->cbuffers[resourceIndex]); + lineStr += + MakeCBufferRegisterStr(regIndex, entryPoint->cbuffers[resRef->resourceIndex]); } } else @@ -2605,9 +2525,10 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, (uint32_t)DXOp::bufferLoad); rdcstr handleStr = ArgToString(inst.args[1], false); - if(resHandles.count(handleStr) > 0) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) { - lineStr += resHandles[handleStr].name; + lineStr += resRef->resourceBase.name; lineStr += "[" + ArgToString(inst.args[2], false) + "]"; } else @@ -2623,9 +2544,10 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, (uint32_t)DXOp::rawBufferLoad); rdcstr handleStr = ArgToString(inst.args[1], false); - if(resHandles.count(handleStr) > 0) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) { - lineStr += resHandles[handleStr].name; + lineStr += resRef->resourceBase.name; if(!isUndef(inst.args[2])) { lineStr += "[" + ArgToString(inst.args[2], false) + "]"; @@ -2674,13 +2596,14 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) } rdcstr handleStr = ArgToString(inst.args[1], false); - if(resHandles.count(handleStr) > 0) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) { uint32_t offset = 0; bool validElementOffset = !isUndef(inst.args[3]); bool constantElementOffset = validElementOffset && getival(inst.args[3], offset); - lineStr += resHandles[handleStr].name; + lineStr += resRef->resourceBase.name; uint32_t index; if(getival(inst.args[2], index)) { @@ -2731,12 +2654,16 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, (uint32_t)DXOp::textureLoad); rdcstr handleStr = ArgToString(inst.args[1], false); - if(resHandles.count(handleStr) > 0) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) { - lineStr += resHandles[handleStr].name; + lineStr += resRef->resourceBase.name; lineStr += ".Load("; bool needComma = false; - const EntryPointInterface::SRV *texture = resHandles[handleStr].srv; + uint32_t resourceIndex = resRef->resourceIndex; + const EntryPointInterface::SRV *texture = resourceIndex < entryPoint->srvs.size() + ? &entryPoint->srvs[resourceIndex] + : NULL; for(uint32_t a = 3; a < 6; ++a) { if(!isUndef(inst.args[a])) @@ -2803,9 +2730,10 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, (uint32_t)DXOp::textureStore); rdcstr handleStr = ArgToString(inst.args[1], false); - if(resHandles.count(handleStr) > 0) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) { - lineStr += resHandles[handleStr].name; + lineStr += resRef->resourceBase.name; lineStr += "["; bool needComma = false; for(uint32_t a = 2; a < 5; ++a) @@ -2864,9 +2792,10 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) (dxopCode == (uint32_t)DXOp::sampleCmpBias)); showDxFuncName = false; rdcstr handleStr = ArgToString(inst.args[1], false); - if(resHandles.count(handleStr) > 0) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef) { - lineStr += resHandles[handleStr].name; + lineStr += resRef->resourceBase.name; lineStr += "."; rdcstr dxFuncSig = funcNameSigs[dxopCode]; int paramStart = dxFuncSig.find('(') + 1; @@ -2877,8 +2806,9 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) // sampler is 2 rdcstr samplerStr = ArgToString(inst.args[2], false); - if(resHandles.count(samplerStr) > 0) - samplerStr = resHandles[samplerStr].name; + const ResourceReference *samplerRef = GetResourceReference(samplerStr); + if(samplerRef) + samplerStr = samplerRef->resourceBase.name; lineStr += samplerStr; for(uint32_t a = 3; a < 7; ++a) @@ -2957,10 +2887,10 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) RDCASSERTEQUAL(dxopCode, (uint32_t)DXOp::atomicBinOp); rdcstr handleStr = ArgToString(inst.args[1], false); AtomicBinOpCode atomicBinOpCode; - if((resHandles.count(handleStr) > 0) && - getival(inst.args[2], atomicBinOpCode)) + const ResourceReference *resRef = GetResourceReference(handleStr); + if(resRef && getival(inst.args[2], atomicBinOpCode)) { - lineStr += resHandles[handleStr].name; + lineStr += resRef->resourceBase.name; lineStr += "."; lineStr += "Interlocked"; lineStr += ToStr(atomicBinOpCode); @@ -4016,6 +3946,134 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) m_Disassembly += "\n"; } +void Program::ParseReferences(const DXBC::Reflection *reflection) +{ + for(size_t i = 0; i < m_Functions.size(); i++) + { + const Function &func = *m_Functions[i]; + + m_Accum.processFunction(m_Functions[i]); + + if(func.external) + continue; + + EntryPointInterface *entryPoint = NULL; + for(size_t e = 0; e < m_EntryPointInterfaces.size(); ++e) + { + if(func.name == m_EntryPointInterfaces[e].name) + { + entryPoint = &m_EntryPointInterfaces[e]; + break; + } + } + RDCASSERT(entryPoint); + + // Use resource names from the reflection data if the resource name data is empty + if(reflection) + { + for(EntryPointInterface::CBuffer &cbuffer : entryPoint->cbuffers) + { + if(cbuffer.name.empty()) + { + for(DXBC::CBuffer reflCB : reflection->CBuffers) + { + if((reflCB.space == cbuffer.space) && (reflCB.reg == cbuffer.regBase) && + (reflCB.bindCount == cbuffer.regCount)) + cbuffer.name = reflCB.name; + } + } + } + + for(EntryPointInterface::SRV &srv : entryPoint->srvs) + { + if(srv.name.empty()) + { + for(DXBC::ShaderInputBind bind : reflection->SRVs) + { + if((bind.space == srv.space) && (bind.reg == srv.regBase) && + (bind.bindCount == srv.regCount)) + srv.name = bind.name; + } + } + } + + for(EntryPointInterface::UAV &uav : entryPoint->uavs) + { + if(uav.name.empty()) + { + for(DXBC::ShaderInputBind bind : reflection->UAVs) + { + if((bind.space == uav.space) && (bind.reg == uav.regBase) && + (bind.bindCount == uav.regCount)) + uav.name = bind.name; + } + } + } + + for(size_t j = 0; j < entryPoint->samplers.size(); ++j) + { + EntryPointInterface::Sampler &sampler = entryPoint->samplers[j]; + if(sampler.name.empty()) + { + for(DXBC::ShaderInputBind bind : reflection->Samplers) + { + if((bind.space == sampler.space) && (bind.reg == sampler.regBase) && + (bind.bindCount == sampler.regCount)) + sampler.name = bind.name; + } + } + } + } + // Find all the resource handle references and store them in + // rdcarray m_ResourceReferences; + for(size_t funcIdx = 0; funcIdx < func.instructions.size(); funcIdx++) + { + Instruction &inst = *func.instructions[funcIdx]; + rdcstr resultIdStr; + if(!inst.getName().empty()) + resultIdStr = StringFormat::Fmt("%c%s", DXIL::dxilIdentifier, + escapeStringIfNeeded(inst.getName()).c_str()); + else if(inst.slot != ~0U) + resultIdStr = StringFormat::Fmt("%c%s", DXIL::dxilIdentifier, ToStr(inst.slot).c_str()); + + switch(inst.op) + { + case Operation::Call: + { + rdcstr funcCallName = inst.getFuncCall()->name; + if(funcCallName.beginsWith("dx.op.createHandle")) + { + ResourceClass resClass; + uint32_t resIndex; + if(getival(inst.args[1], resClass) && + getival(inst.args[2], resIndex)) + { + EntryPointInterface::ResourceBase *resourceBase = NULL; + switch(resClass) + { + case ResourceClass::SRV: resourceBase = &entryPoint->srvs[resIndex]; break; + case ResourceClass::UAV: resourceBase = &entryPoint->uavs[resIndex]; break; + case ResourceClass::CBuffer: resourceBase = &entryPoint->cbuffers[resIndex]; break; + case ResourceClass::Sampler: resourceBase = &entryPoint->samplers[resIndex]; break; + default: break; + }; + if(resourceBase) + { + const rdcstr &handleStr = resultIdStr; + RDCASSERT(!GetResourceReference(handleStr)); + ResourceReference resRef(handleStr, *resourceBase, resIndex); + m_ResourceHandles[handleStr] = m_ResourceHandles.size(); + m_ResourceReferences.push_back(resRef); + } + } + } + } + default: break; + } + } + } +} + rdcstr Type::toString() const { if(!name.empty()) @@ -4760,7 +4818,7 @@ rdcstr DoStringise(const DXIL::AtomicBinOpCode &el) STRINGISE_ENUM_CLASS(UMin) STRINGISE_ENUM_CLASS(UMax) STRINGISE_ENUM_CLASS(Exchange) - STRINGISE_ENUM_CLASS(Invalid) + STRINGISE_ENUM_CLASS_NAMED(Invalid, ""); } END_ENUM_STRINGISE(); } diff --git a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp index ca228561f..71d9eb36b 100644 --- a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp @@ -287,7 +287,9 @@ EntryPointInterface::Signature::Signature(const Metadata *signature) startCol = getival(signature->children[SignatureElement::StartCol]); } -EntryPointInterface::ResourceBase::ResourceBase(const Metadata *resourceBase) +EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, + const Metadata *resourceBase) + : resClass(resourceClass) { id = getival(resourceBase->children[(size_t)ResField::ID]); type = resourceBase->children[(size_t)ResField::VarDecl]->type; @@ -297,7 +299,7 @@ EntryPointInterface::ResourceBase::ResourceBase(const Metadata *resourceBase) regCount = getival(resourceBase->children[(size_t)ResField::RegCount]); } -EntryPointInterface::SRV::SRV(const Metadata *srv) : ResourceBase(srv) +EntryPointInterface::SRV::SRV(const Metadata *srv) : ResourceBase(ResourceClass::SRV, srv) { shape = getival(srv->children[(size_t)ResField::SRVShape]); sampleCount = getival(srv->children[(size_t)ResField::SRVSampleCount]); @@ -319,7 +321,7 @@ EntryPointInterface::SRV::SRV(const Metadata *srv) : ResourceBase(srv) } } -EntryPointInterface::UAV::UAV(const Metadata *uav) : ResourceBase(uav) +EntryPointInterface::UAV::UAV(const Metadata *uav) : ResourceBase(ResourceClass::UAV, uav) { shape = getival(uav->children[(size_t)ResField::UAVShape]); globallCoherent = (getival(uav->children[(size_t)ResField::UAVGloballyCoherent]) == 1); @@ -349,7 +351,8 @@ EntryPointInterface::UAV::UAV(const Metadata *uav) : ResourceBase(uav) } } -EntryPointInterface::CBuffer::CBuffer(const Metadata *cbuffer) : ResourceBase(cbuffer) +EntryPointInterface::CBuffer::CBuffer(const Metadata *cbuffer) + : ResourceBase(ResourceClass::CBuffer, cbuffer) { sizeInBytes = getival(cbuffer->children[(size_t)ResField::CBufferByteSize]); const Metadata *tags = cbuffer->children[(size_t)ResField::CBufferTags]; @@ -363,7 +366,8 @@ EntryPointInterface::CBuffer::CBuffer(const Metadata *cbuffer) : ResourceBase(cb cbufferRefl = NULL; } -EntryPointInterface::Sampler::Sampler(const Metadata *sampler) : ResourceBase(sampler) +EntryPointInterface::Sampler::Sampler(const Metadata *sampler) + : ResourceBase(ResourceClass::Sampler, sampler) { samplerType = getival(sampler->children[(size_t)ResField::SamplerType]); } @@ -544,16 +548,19 @@ static DXBC::CBufferVariableType MakePayloadType(const TypeInfo &typeInfo, const return ret; } -void Program::FetchEntryPointInterfaces(rdcarray &entryPointInterfaces) +void Program::FillEntryPointInterfaces() { + if(!m_EntryPointInterfaces.isEmpty()) + return; + DXMeta dx(m_NamedMeta); - entryPointInterfaces.clear(); + m_EntryPointInterfaces.clear(); if(!dx.entryPoints) return; for(size_t c = 0; c < dx.entryPoints->children.size(); ++c) - entryPointInterfaces.emplace_back(dx.entryPoints->children[c]); + m_EntryPointInterfaces.emplace_back(dx.entryPoints->children[c]); } void Program::FetchComputeProperties(DXBC::Reflection *reflection) @@ -1718,4 +1725,37 @@ void Program::GetLocals(const DXBC::DXBCContainer *dxbc, size_t instruction, uin locals.clear(); } +rdcstr Program::GetResourceReferenceName(ResourceClass resClass, const BindingSlot &slot) const +{ + for(const ResourceReference &resRef : m_ResourceReferences) + { + if(resRef.resourceBase.resClass != resClass) + continue; + if(resRef.resourceBase.space != slot.registerSpace) + continue; + if(resRef.resourceBase.regBase > slot.shaderRegister) + continue; + if(resRef.resourceBase.regBase + resRef.resourceBase.regCount < slot.shaderRegister) + continue; + + return resRef.handleID; + } + RDCERR("Failed to find DXIL %s Resource Space %d Register %d", ToStr(resClass).c_str(), + slot.registerSpace, slot.shaderRegister); + return "UNKNOWN_RESOURCE_HANDLE"; +} + +const ResourceReference *Program::GetResourceReference(const rdcstr &handleStr) const +{ + if(m_ResourceHandles.count(handleStr) > 0) + { + size_t resRefIndex = m_ResourceHandles.find(handleStr)->second; + if(resRefIndex < m_ResourceHandles.size()) + { + return &m_ResourceReferences[resRefIndex]; + } + } + return NULL; +} + }; // namespace DXIL