From 49d8c791deb39a8912fa8b9d28c04296ad01c30a Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Thu, 13 Jun 2024 10:19:07 +0100 Subject: [PATCH] DXIL Disassembly rework resource handle display AnnotateHandle * Change the SSA result name to be "_typed_descriptor_" * Show the input handle SSA name instead of the resource alias name CreateHandleFromHeap * Change the SSA result name to be "_untyped_descriptor_" CBufferLoad, CBufferLoadLegacy * For SM6.6 use the handle alias instead of the cbuffer name Before: _dx.types.Handle _3 = ResourceDescriptorHeap[8]; _dx.types.Handle __heap_descriptor_0 = (StructuredBuffer)ResourceDescriptorHeap[8]; _dx.types.Handle _11 = SamplerDescriptorHeap[0]; _dx.types.Handle __heap_descriptor_1 = (SamplerState)SamplerDescriptorHeap[0]; _dx.types.Handle _15 = ResourceDescriptorHeap[12]; _dx.types.Handle __heap_descriptor_2 = (Texture2D<4xF32>)ResourceDescriptorHeap[12]; _dx.types.ResRet.f32 _19 = __heap_descriptor_2.Sample(__heap_descriptor_1, _.i05, _.i16, Offset = {0, 0}); After: _dx.types.Handle __untyped_descriptor_0 = ResourceDescriptorHeap[8]; _dx.types.Handle __typed_descriptor_0 = (StructuredBuffer)__untyped_descriptor_0; _dx.types.Handle __untyped_descriptor_1 = SamplerDescriptorHeap[0]; _dx.types.Handle __typed_descriptor_1 = (SamplerState)__untyped_descriptor_1; _dx.types.Handle __untyped_descriptor_2 = ResourceDescriptorHeap[12]; _dx.types.Handle __typed_descriptor_2 = (Texture2D)__untyped_descriptor_2; _dx.types.ResRet.f32 _19 = __typed_descriptor_2.Sample(__typed_descriptor_1, _.i05, _.i16, Offset = {0, 0}); --- renderdoc/driver/shaders/dxil/dxil_bytecode.h | 1 + .../driver/shaders/dxil/dxil_disassemble.cpp | 65 ++++++++++++------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index 5f1b9032d..062d2709d 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -1645,6 +1645,7 @@ protected: rdcarray m_EntryPointInterfaces; std::map m_ResourceHandles; std::map m_SsaAliases; + std::map m_ResourceAnnotateCounts; rdcarray m_ResourceReferences; rdcstr m_Disassembly; diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index bdf724766..dcc1e245e 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -2517,7 +2517,8 @@ static const DXBC::CBufferVariable *FindCBufferVar(const uint32_t minOffset, con } static rdcstr MakeCBufferRegisterStr(uint32_t reg, uint32_t bytesPerElement, - DXIL::EntryPointInterface::CBuffer cbuffer) + DXIL::EntryPointInterface::CBuffer cbuffer, + const rdcstr &handleStr) { rdcstr ret = "{"; uint32_t offset = 0; @@ -2535,7 +2536,7 @@ static rdcstr MakeCBufferRegisterStr(uint32_t reg, uint32_t bytesPerElement, FindCBufferVar(minOffset, maxOffset, cbuffer.cbufferRefl->variables, baseOffset, prefix); if(var) { - ret += cbuffer.name + "." + prefix + var->name; + ret += handleStr + "." + prefix + var->name; uint32_t varOffset = regOffset - baseOffset; // if it's an array, add the index based on the relative index to the base offset @@ -2578,7 +2579,7 @@ static rdcstr MakeCBufferRegisterStr(uint32_t reg, uint32_t bytesPerElement, if(offset > 16) break; ret += ", "; - ret += cbuffer.name + "." + prefix + var->name; + ret += handleStr + "." + prefix + var->name; ret += StringFormat::Fmt(".%c", swizzle[c & 0x3]); offset += elementSize; } @@ -3090,6 +3091,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) { // CreateHandleFromHeap(index,samplerHeap,nonUniformIndex) uint32_t samplerHeap; + resultIdStr = GetHandleAlias(resultIdStr); if(getival(inst.args[2], samplerHeap)) { lineStr += GetHandleAlias(resultIdStr); @@ -3262,11 +3264,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) lineStr += typeStr; lineStr += ")"; rdcstr ssaStr = GetArgId(inst, 1); - if(m_SsaAliases.count(ssaStr) == 0) - lineStr += ssaStr; - else - lineStr += m_SsaAliases[ssaStr]; - + lineStr += GetHandleAlias(ssaStr); resultIdStr = GetHandleAlias(resultIdStr); } else @@ -3287,11 +3285,13 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) // CBufferLoadLegacy(handle,regIndex) rdcstr handleStr = GetArgId(inst, 1); const ResourceReference *resRef = GetResourceReference(handleStr); + bool useFallback = true; if(entryPoint && resRef) { uint32_t regIndex; if(getival(inst.args[2], regIndex)) { + useFallback = false; if(dxOpCode == DXOp::CBufferLoad) { // TODO: handle non 16-byte aligned offsets @@ -3312,22 +3312,37 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) RDCASSERTEQUAL(baseType->type, Type::TypeKind::Scalar); bytesPerElement = baseType->bitWidth / 8; } - lineStr += MakeCBufferRegisterStr(regIndex, bytesPerElement, cbuffer); + lineStr += + MakeCBufferRegisterStr(regIndex, bytesPerElement, cbuffer, handleStr); commentStr += " cbuffer = " + cbuffer.name; commentStr += ", byte_offset = " + ToStr(regIndex * 16); } else { - lineStr += cbuffer.name; + lineStr += handleStr; lineStr += ".Load4("; lineStr += "byte_offset = " + ToStr(regIndex * 16); lineStr += ")"; } } } - else + if(useFallback) { - showDxFuncName = true; + lineStr += GetHandleAlias(handleStr); + lineStr += ".Load4("; + lineStr += "byte_offset = "; + uint32_t regIndex; + if(getival(inst.args[2], regIndex)) + { + lineStr += ToStr(regIndex * 16); + } + else + { + lineStr += GetArgId(inst, 2); + if(dxOpCode == DXOp::CBufferLoadLegacy) + lineStr += " * 16"; + } + lineStr += ")"; } break; } @@ -3818,10 +3833,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) lineStr += paramNameStr; rdcstr ssaStr = GetArgId(inst, a); - if(m_SsaAliases.count(ssaStr) == 0) - lineStr += ssaStr; - else - lineStr += m_SsaAliases[ssaStr]; + lineStr += GetHandleAlias(ssaStr); first = false; } } @@ -4577,7 +4589,6 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) void Program::ParseReferences(const DXBC::Reflection *reflection) { - uint32_t heapDescriptorResourceCount = 0; for(size_t i = 0; i < m_Functions.size(); i++) { const Function &func = *m_Functions[i]; @@ -4833,6 +4844,12 @@ void Program::ParseReferences(const DXBC::Reflection *reflection) case DXOp::CreateHandleFromHeap: { // CreateHandleFromHeap(index,samplerHeap,nonUniformIndex) + rdcstr resBaseName = "untyped_descriptor"; + uint32_t annotateHandleCount = m_ResourceAnnotateCounts[resBaseName]; + rdcstr resultAlias = "__" + resBaseName + "_" + ToStr(annotateHandleCount); + m_ResourceAnnotateCounts[resBaseName]++; + m_SsaAliases[resultIdStr] = resultAlias; + uint32_t samplerHeap; if(getival(inst.args[2], samplerHeap)) { @@ -4842,26 +4859,30 @@ void Program::ParseReferences(const DXBC::Reflection *reflection) resName += "["; resName += GetArgId(inst, 1); resName += "]"; - - m_SsaAliases[resultIdStr] = resName; + m_SsaAliases[resultAlias] = resName; } break; } case DXOp::AnnotateHandle: { // AnnotateHandle(res,props) - rdcstr resName = "__heap_descriptor_" + ToStr(heapDescriptorResourceCount); - heapDescriptorResourceCount += 1; - m_SsaAliases[resultIdStr] = resName; + // If the underlying handle points to a known resource then duplicate the resource // and register it as resultIdStr rdcstr baseResource = GetArgId(inst, 1); const ResourceReference *resRef = GetResourceReference(baseResource); + rdcstr resBaseName = "typed_descriptor"; if(resRef) { + resBaseName = resRef->resourceBase.name; m_ResourceHandles[resultIdStr] = m_ResourceHandles.size(); m_ResourceReferences.push_back(*resRef); } + uint32_t annotateHandleCount = m_ResourceAnnotateCounts[resBaseName]; + rdcstr resName = "__" + resBaseName + "_" + ToStr(annotateHandleCount); + m_SsaAliases[resultIdStr] = resName; + m_ResourceAnnotateCounts[resBaseName]++; + break; } default: break;