DXIL Disassembly rework resource handle display

AnnotateHandle
* Change the SSA result name to be "_typed_descriptor_<N>"
* Show the input handle SSA name instead of the resource alias name

CreateHandleFromHeap
* Change the SSA result name to be "_untyped_descriptor_<N>"

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<stride=8>)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<stride=8>)__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<float4>)__untyped_descriptor_2;
  _dx.types.ResRet.f32 _19 = __typed_descriptor_2.Sample(__typed_descriptor_1, _.i05, _.i16, Offset = {0, 0});
This commit is contained in:
Jake Turner
2024-06-13 10:19:07 +01:00
parent fc1e5bb1ad
commit 49d8c791de
2 changed files with 44 additions and 22 deletions
@@ -1645,6 +1645,7 @@ protected:
rdcarray<EntryPointInterface> m_EntryPointInterfaces;
std::map<rdcstr, size_t> m_ResourceHandles;
std::map<rdcstr, rdcstr> m_SsaAliases;
std::map<rdcstr, uint32_t> m_ResourceAnnotateCounts;
rdcarray<ResourceReference> m_ResourceReferences;
rdcstr m_Disassembly;
@@ -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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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;