From 30cf5412ba2c97fe927c6b565f2ed10151b98ea2 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Wed, 1 May 2024 13:34:23 +0100 Subject: [PATCH] RD DXIL Disassembly: decode "dx.op.bufferLoad" &"dx.op.rawBufferLoad" Example Output %31 = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle %bufOut_UAV_structbuf, i32 1, i32 0); Becomes _dx.types.ResRet.i32 _31 = bufOut[1]; --- .../driver/shaders/dxil/dxil_disassemble.cpp | 91 ++++++++++++++++--- 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index 6c46233a0..40770814f 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -75,6 +75,13 @@ rdcstr escapeStringIfNeeded(const rdcstr &name) return needsEscaping(name) ? escapeString(name) : name; } +bool isUndef(const Value *v) +{ + if(const Constant *c = cast(v)) + return c->isUndef(); + return false; +} + template bool getival(const Value *v, T &out) { @@ -2272,6 +2279,13 @@ static rdcstr MakeCBufferRegisterStr(uint32_t reg, DXIL::EntryPointInterface::CB return ret; } +struct ResourceHandle +{ + rdcstr name; + ResourceClass resourceClass; + uint32_t resourceIndex; +}; + void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) { DXIL::dxcStyleFormatting = false; @@ -2523,7 +2537,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) m_Disassembly += "{"; DisassemblyAddNewLine(); - std::map> resHandles; + std::map resHandles; size_t curBlock = 0; @@ -2570,7 +2584,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) { showDxFuncName = false; uint32_t dxopCode; - RDCASSERTEQUAL(getival(inst.args[0], dxopCode), true); + RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, 4); rdcstr name; rdcstr rowStr; @@ -2610,7 +2624,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) { showDxFuncName = false; uint32_t dxopCode; - RDCASSERTEQUAL(getival(inst.args[0], dxopCode), true); + RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, 5); rdcstr name; rdcstr rowStr; @@ -2651,7 +2665,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) { showDxFuncName = false; uint32_t dxopCode; - RDCASSERTEQUAL(getival(inst.args[0], dxopCode), true); + RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, 57); rdcstr handleStr = resultIdStr; ResourceClass resClass; @@ -2674,7 +2688,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) break; default: resName = "INVALID RESOURCE CLASS"; break; }; - resHandles[handleStr] = make_rdcpair(resClass, resIndex); + resHandles[handleStr] = {resName, resClass, resIndex}; uint32_t index; if(getival(inst.args[3], index)) { @@ -2715,7 +2729,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) { showDxFuncName = false; uint32_t dxopCode; - RDCASSERTEQUAL(getival(inst.args[0], dxopCode), true); + RDCASSERT(getival(inst.args[0], dxopCode)); RDCASSERTEQUAL(dxopCode, 59); rdcstr handleStr = ArgToString(inst.args[1], false); if(resHandles.count(handleStr) > 0) @@ -2730,7 +2744,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) regIndex = regIndex / 16; // uint32_t alignment = getival(inst.args[3]); } - uint32_t resourceIndex = resHandles[handleStr].second; + uint32_t resourceIndex = resHandles[handleStr].resourceIndex; lineStr += MakeCBufferRegisterStr(regIndex, entryPoint.cbuffers[resourceIndex]); } } @@ -2739,6 +2753,62 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) showDxFuncName = true; } } + else if(showDxFuncName && funcCallName.beginsWith("dx.op.bufferLoad")) + { + // handle, index, wot (unused) + showDxFuncName = false; + uint32_t dxopCode; + RDCASSERT(getival(inst.args[0], dxopCode)); + RDCASSERTEQUAL(dxopCode, 68); + rdcstr handleStr = ArgToString(inst.args[1], false); + if(resHandles.count(handleStr) > 0) + { + lineStr += resHandles[handleStr].name; + lineStr += "[" + ArgToString(inst.args[2], false) + "]"; + } + else + { + showDxFuncName = true; + } + } + else if(showDxFuncName && funcCallName.beginsWith("dx.op.rawBufferLoad")) + { + // handle, index, elementOffset, mask, alignment + showDxFuncName = false; + uint32_t dxopCode; + RDCASSERT(getival(inst.args[0], dxopCode)); + RDCASSERTEQUAL(dxopCode, 139); + rdcstr handleStr = ArgToString(inst.args[1], false); + if(resHandles.count(handleStr) > 0) + { + lineStr += resHandles[handleStr].name; + if(!isUndef(inst.args[2])) + { + lineStr += "[" + ArgToString(inst.args[2], false) + "]"; + if(!isUndef(inst.args[3])) + { + uint32_t elementOffset; + if(getival(inst.args[3], elementOffset)) + { + if(elementOffset > 0) + lineStr += " + " + ToStr(elementOffset) + " bytes"; + } + else + { + lineStr += " + " + ArgToString(inst.args[3], false) + " bytes"; + } + } + } + else + { + lineStr += "[" + ArgToString(inst.args[3], false) + "]"; + } + } + else + { + showDxFuncName = true; + } + } else if(funcCallName.beginsWith("llvm.dbg.")) { } @@ -2782,10 +2852,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) } } // Don't show "undef" parameters - bool isUndef = false; - if(const Constant *c = cast(inst.args[a])) - isUndef = c->isUndef(); - if(!isUndef) + if(!isUndef(inst.args[a])) { if(!first) lineStr += ", "; @@ -2997,7 +3064,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) // %3 = getelementptr [6 x float], [6 x float] addrspace(3)* // @"\01?s_x@@3@$$A.1dim", i32 0, i32 %9 - // RD: GroupShared float* _3 = s_x[0] + _9; + // RD: GroupShared float* _3 = s_x[_9]; fallbackOutput = false; rdcstr addrspaceStr(typeStr.substr(start, end - start));