From 79101c7b1381fac6b505ada9858857f050097884 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 5 Jul 2017 20:35:50 +0100 Subject: [PATCH] Move DXBC shader friendly naming logic into C++ side code * This makes more sense and lets us share it between Qt and C# UIs. --- .../Code/Interface/PersistantConfig.cpp | 4 + renderdoc/driver/shaders/dxbc/dxbc_debug.cpp | 2 +- .../driver/shaders/dxbc/dxbc_disassemble.cpp | 239 +++++++++++++++--- .../driver/shaders/dxbc/dxbc_disassemble.h | 22 +- .../driver/shaders/dxbc/dxbc_inspect.cpp | 4 + renderdoc/driver/shaders/dxbc/dxbc_inspect.h | 24 +- renderdocui/Code/PersistantConfig.cs | 6 + renderdocui/Windows/ShaderViewer.cs | 143 +---------- 8 files changed, 264 insertions(+), 180 deletions(-) diff --git a/qrenderdoc/Code/Interface/PersistantConfig.cpp b/qrenderdoc/Code/Interface/PersistantConfig.cpp index d24a58182..79b8bc617 100644 --- a/qrenderdoc/Code/Interface/PersistantConfig.cpp +++ b/qrenderdoc/Code/Interface/PersistantConfig.cpp @@ -234,6 +234,8 @@ bool PersistantConfig::Load(const QString &filename) SetConfigSetting(key, ConfigSettings[key]); } + RENDERDOC_SetConfigSetting("Disassembly_FriendlyNaming", ShaderViewer_FriendlyNaming ? "1" : "0"); + // localhost should always be available as a remote host bool foundLocalhost = false; @@ -262,6 +264,8 @@ bool PersistantConfig::Save() for(RemoteHost *host : RemoteHosts) RemoteHostList.push_back(*host); + RENDERDOC_SetConfigSetting("Disassembly_FriendlyNaming", ShaderViewer_FriendlyNaming ? "1" : "0"); + return Serialize(m_Filename); } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 98abe4873..ccac64b47 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -680,7 +680,7 @@ void State::SetDst(const ASMOperand &dstoper, const ASMOperation &op, const Shad { RDCERR("Currently unsupported destination operand type %d!", dstoper.type); - string name = dstoper.toString(); + string name = dstoper.toString(dxbc, ToString::ShowSwizzle); for(int32_t i = 0; i < outputs.count; i++) { if(outputs[i].name.elems && !strcmp(name.c_str(), outputs[i].name.elems)) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp index 461eaed60..e4edd019d 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp @@ -26,6 +26,7 @@ #include "dxbc_disassemble.h" #include #include "common/common.h" +#include "core/core.h" #include "serialise/serialiser.h" #include "serialise/string_utils.h" #include "dxbc_inspect.h" @@ -347,6 +348,8 @@ void DXBCFile::DisassembleHexDump() m_Declarations.reserve(numDecls); + const bool friendly = RenderDoc::Inst().GetConfigSetting("Disassembly_FriendlyNaming") != "0"; + while(cur < end) { ASMOperation op; @@ -358,9 +361,9 @@ void DXBCFile::DisassembleHexDump() decl.offset = offset * sizeof(uint32_t); op.offset = offset * sizeof(uint32_t); - if(!ExtractOperation(cur, op)) + if(!ExtractOperation(cur, op, friendly)) { - if(!ExtractDecl(cur, decl)) + if(!ExtractDecl(cur, decl, friendly)) { RDCERR("Unexpected non-operation and non-decl in token stream at 0x%x", cur - begin); } @@ -733,7 +736,7 @@ bool DXBCFile::IsDeclaration(OpcodeType op) return isDecl; } -bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper) +bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ToString flags, ASMOperand &retOper) { uint32_t OperandToken0 = tokenStream[0]; @@ -851,12 +854,12 @@ bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper) // relative addressing retOper.indices[idx].relative = true; - bool ret = ExtractOperand(tokenStream, retOper.indices[idx].operand); + bool ret = ExtractOperand(tokenStream, flags, retOper.indices[idx].operand); RDCASSERT(ret); } if(retOper.indices[idx].relative) - retOper.indices[idx].str = "[" + retOper.indices[idx].operand.toString() + " + "; + retOper.indices[idx].str = "[" + retOper.indices[idx].operand.toString(this, flags) + " + "; if(retOper.indices[idx].absolute) { @@ -893,9 +896,43 @@ bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper) return true; } -string ASMOperand::toString(bool swizzle) const +const CBufferVariable *FindCBufferVar(const uint32_t minOffset, const uint32_t maxOffset, + const std::vector &variables, + uint32_t &byteOffset, std::string &prefix) { - string str = ""; + for(const CBufferVariable &v : variables) + { + // absolute byte offset of this variable in the cbuffer + const uint32_t voffs = byteOffset + v.descriptor.offset; + + // does minOffset-maxOffset reside in this variable? We don't handle the case where the range + // crosses a variable (and I don't think FXC emits that anyway). + if(voffs <= minOffset && voffs + v.type.descriptor.bytesize > maxOffset) + { + byteOffset = voffs; + + // if it is a struct with members, recurse to find a closer match + if(!v.type.members.empty()) + { + prefix += v.name + "."; + return FindCBufferVar(minOffset, maxOffset, v.type.members, byteOffset, prefix); + } + + // otherwise return this variable. + return &v; + } + } + + return NULL; +} + +string ASMOperand::toString(DXBCFile *dxbc, ToString flags) const +{ + string str, regstr; + + const bool decl = flags & ToString::IsDecl; + const bool swizzle = flags & ToString::ShowSwizzle; + const bool friendly = flags & ToString::FriendlyNameRegisters; char swiz[6] = {0, 0, 0, 0, 0, 0}; @@ -940,6 +977,26 @@ string ASMOperand::toString(bool swizzle) const str = "u"; str += indices[0].str; + + if(dxbc && friendly && !dxbc->m_GuessedResources && indices[0].absolute) + { + uint32_t idx = (uint32_t)indices[0].index; + + for(const ShaderInputBind &b : dxbc->m_Resources) + { + if(b.reg != idx || b.space != 0) + continue; + + if((type == TYPE_RESOURCE && b.IsROResource()) || (type == TYPE_SAMPLER && b.IsSampler()) || + (type == TYPE_UNORDERED_ACCESS_VIEW && b.IsUAV())) + { + if(decl) + regstr = str; + str = b.name; + break; + } + } + } } else if(indices.size() == 3) { @@ -1070,6 +1127,98 @@ string ASMOperand::toString(bool swizzle) const str = "cb"; str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[1].str.c_str()); + + if(dxbc && friendly && !dxbc->m_GuessedResources && indices[0].absolute) + { + const CBuffer *cbuffer = NULL; + + for(const CBuffer &cb : dxbc->m_CBuffers) + { + if(cb.space == 0 && cb.reg == uint32_t(indices[0].index)) + { + cbuffer = &cb; + break; + } + } + + if(cbuffer) + { + // if the second index is constant then this is easy enough, we just find the matching + // cbuffer variable and use its name, possibly rebasing the swizzle. + // Unfortunately for many cases it's something like cbX[r0.x + 0] then in the next + // instruction cbX[r0.x + 1] and so on, and it's obvious that it's indexing into the same + // array for subsequent entries. However without knowing r0 we have no way to look up the + // matching variable + if(indices[1].absolute && !indices[1].relative) + { + uint8_t minComp = comps[0]; + uint8_t maxComp = comps[0]; + for(int i = 1; i < 4; i++) + { + if(comps[i] < 4) + { + minComp = RDCMIN(minComp, comps[i]); + maxComp = RDCMAX(maxComp, comps[i]); + } + } + + uint32_t minOffset = uint32_t(indices[1].index) * 16 + minComp * 4; + uint32_t maxOffset = uint32_t(indices[1].index) * 16 + maxComp * 4; + + uint32_t baseOffset = 0; + + std::string prefix; + const CBufferVariable *var = + FindCBufferVar(minOffset, maxOffset, cbuffer->variables, baseOffset, prefix); + + if(var) + { + str = prefix + var->name; + + // for indices, look at just which register is selected + minOffset &= ~0xf; + uint32_t varOffset = minOffset - baseOffset; + + // if it's an array, add the index based on the relative index to the base offset + if(var->type.descriptor.elements > 1) + { + uint32_t byteSize = var->type.descriptor.bytesize; + + // round up the byte size to a the nearest vec4 in case it's not quite a multiple + byteSize = AlignUp16(byteSize); + + const uint32_t elementSize = byteSize / var->type.descriptor.elements; + + const uint32_t elementIndex = varOffset / elementSize; + + str += StringFormat::Fmt("[%u]", elementIndex); + + // subtract off so that if there's any further offset, it can be processed + varOffset -= elementIndex; + } + + // or if it's a matrix + if((var->type.descriptor.varClass == CLASS_MATRIX_ROWS && var->type.descriptor.cols > 1) || + (var->type.descriptor.varClass == CLASS_MATRIX_COLUMNS && + var->type.descriptor.rows > 1)) + { + str += StringFormat::Fmt("[%u]", varOffset / 16); + } + + // rebase swizzle if necessary + uint32_t vecOffset = (var->descriptor.offset & 0xf); + if(vecOffset > 0) + { + for(int i = 0; i < 4; i++) + { + if(swiz[i + 1]) + swiz[i + 1] = compchars[comps[i] - uint8_t(vecOffset / 4)]; + } + } + } + } + } + } } } else if(type == TYPE_TEMP || type == TYPE_OUTPUT || type == TYPE_STREAM || @@ -1206,14 +1355,20 @@ string ASMOperand::toString(bool swizzle) const if(modifier == OPERAND_MODIFIER_ABSNEG) str = "-abs(" + str + ")"; + if(decl && !regstr.empty()) + str += StringFormat::Fmt(" (%s)", regstr.c_str()); + return str; } -bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) +bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl, bool friendlyName) { uint32_t *begin = tokenStream; uint32_t OpcodeToken0 = tokenStream[0]; + ToString flags = friendlyName ? ToString::FriendlyNameRegisters : ToString::None; + flags = flags | ToString::IsDecl; + const bool sm51 = (m_Version.Major == 0x5 && m_Version.Minor == 0x1); OpcodeType op = Opcode::Type.Get(OpcodeToken0); @@ -1391,11 +1546,11 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) { CBufferAccessPattern accessPattern = Declaration::AccessPattern.Get(OpcodeToken0); - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.str += " "; - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); if(sm51) { uint32_t float4size = tokenStream[0]; @@ -1434,10 +1589,10 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) { retDecl.str += " "; - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); - retDecl.str += retDecl.operand.toString(); + retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle); } else if(op == OPCODE_DCL_TEMPS) { @@ -1473,10 +1628,10 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) { retDecl.str += " "; - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); - retDecl.str += retDecl.operand.toString(); + retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle); } else if(op == OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT) { @@ -1494,35 +1649,35 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) op == OPCODE_DCL_INPUT_PS_SIV || op == OPCODE_DCL_INPUT_PS_SGV || op == OPCODE_DCL_OUTPUT_SIV || op == OPCODE_DCL_OUTPUT_SGV) { - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.systemValue = (SVSemantic)tokenStream[0]; tokenStream++; retDecl.str += " "; - retDecl.str += retDecl.operand.toString(); + retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle); retDecl.str += ", "; retDecl.str += SystemValueToString(retDecl.systemValue); } else if(op == OPCODE_DCL_STREAM) { - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.str += " "; - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); } else if(op == OPCODE_DCL_SAMPLER) { retDecl.samplerMode = Declaration::SamplerMode.Get(OpcodeToken0); - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.str += " "; - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); retDecl.str += ", "; if(retDecl.samplerMode == SAMPLER_MODE_DEFAULT) @@ -1558,7 +1713,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) retDecl.sampleCount = Declaration::SampleCount.Get(OpcodeToken0); } - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); uint32_t ResourceReturnTypeToken = tokenStream[0]; @@ -1583,7 +1738,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) retDecl.str += toString(retDecl.resType[3]); retDecl.str += ")"; - retDecl.str += " " + retDecl.operand.toString(false); + retDecl.str += " " + retDecl.operand.toString(this, flags); retDecl.space = 0; @@ -1604,22 +1759,22 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) { retDecl.interpolation = Declaration::InterpolationMode.Get(OpcodeToken0); - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.str += " "; retDecl.str += toString(retDecl.interpolation); retDecl.str += " "; - retDecl.str += retDecl.operand.toString(); + retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle); } else if(op == OPCODE_DCL_INDEX_RANGE) { - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.str += " "; - retDecl.str += retDecl.operand.toString(); + retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle); retDecl.indexRange = tokenStream[0]; tokenStream++; @@ -1662,13 +1817,13 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) { retDecl.str += " "; - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.count = tokenStream[0]; tokenStream++; - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); retDecl.str += ", "; char buf[64] = {0}; @@ -1679,7 +1834,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) { retDecl.str += " "; - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.stride = tokenStream[0]; @@ -1688,7 +1843,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) retDecl.count = tokenStream[0]; tokenStream++; - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); retDecl.str += ", "; char buf[64] = {0}; @@ -1818,10 +1973,10 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) retDecl.str += " "; - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); if(retDecl.globallyCoherant) retDecl.str += ", globallyCoherant"; @@ -1857,13 +2012,13 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) retDecl.str += " "; - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.stride = tokenStream[0]; tokenStream++; - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); retDecl.str += ", "; char buf[64] = {0}; @@ -1908,7 +2063,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) if(retDecl.globallyCoherant) retDecl.str += "_glc"; - bool ret = ExtractOperand(tokenStream, retDecl.operand); + bool ret = ExtractOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); uint32_t ResourceReturnTypeToken = tokenStream[0]; @@ -1933,7 +2088,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) retDecl.str += " "; - retDecl.str += retDecl.operand.toString(false); + retDecl.str += retDecl.operand.toString(this, flags); if(retDecl.rov) retDecl.str += ", rasterizerOrderedAccess"; @@ -2068,11 +2223,13 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) return true; } -bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp) +bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp, bool friendlyName) { uint32_t *begin = tokenStream; uint32_t OpcodeToken0 = tokenStream[0]; + ToString flags = friendlyName ? ToString::FriendlyNameRegisters : ToString::None; + OpcodeType op = Opcode::Type.Get(OpcodeToken0); RDCASSERT(op < NUM_OPCODES); @@ -2118,7 +2275,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp) for(uint32_t i = 0; i < retOp.operands.size(); i++) { - bool ret = ExtractOperand(tokenStream, retOp.operands[i]); + bool ret = ExtractOperand(tokenStream, flags, retOp.operands[i]); RDCASSERT(ret); } @@ -2130,7 +2287,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp) for(uint32_t i = 0; i < retOp.operands.size(); i++) { retOp.str += ", "; - retOp.str += retOp.operands[i].toString(); + retOp.str += retOp.operands[i].toString(this, flags | ToString::ShowSwizzle); } tokenStream = end; @@ -2262,7 +2419,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp) for(size_t i = 0; i < retOp.operands.size(); i++) { - bool ret = ExtractOperand(tokenStream, retOp.operands[i]); + bool ret = ExtractOperand(tokenStream, flags, retOp.operands[i]); RDCASSERT(ret); } @@ -2286,7 +2443,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp) retOp.str += " "; else retOp.str += ", "; - retOp.str += retOp.operands[i].toString(); + retOp.str += retOp.operands[i].toString(this, flags | ToString::ShowSwizzle); } #if ENABLED(RDOC_DEVEL) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h index 0787df2a4..262952ad8 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h @@ -696,9 +696,29 @@ enum ComponentType // Main structures ///////////////////////////////////////////////////////////////////////// +class DXBCFile; + struct ASMIndex; struct ASMDecl; +enum class ToString +{ + None = 0x0, + IsDecl = 0x1, + ShowSwizzle = 0x2, + FriendlyNameRegisters = 0x4, +}; + +constexpr inline ToString operator|(ToString a, ToString b) +{ + return ToString(int(a) | int(b)); +} + +constexpr inline bool operator&(ToString a, ToString b) +{ + return (int(a) & int(b)) != 0; +} + struct ASMOperand { ASMOperand() @@ -715,7 +735,7 @@ struct ASMOperand bool operator==(const ASMOperand &o) const; - string toString(bool swizzle = true) const; + string toString(DXBCFile *dxbc, ToString flags) const; /////////////////////////////////////// diff --git a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp index 9972ce25b..8468eee53 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp @@ -809,6 +809,8 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength) // get type/version that's used regularly and cheap to fetch FetchTypeVersion(); + m_GuessedResources = false; + // didn't find an rdef means reflection information was stripped. // Attempt to reverse engineer basic info from declarations if(!rdefFound) @@ -817,6 +819,8 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength) DisassembleHexDump(); GuessResources(); + + m_GuessedResources = true; } for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_inspect.h b/renderdoc/driver/shaders/dxbc/dxbc_inspect.h index 2330243ad..0ff2daaf5 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_inspect.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_inspect.h @@ -131,6 +131,20 @@ struct ShaderInputBind TYPE_UAV_RWSTRUCTURED_WITH_COUNTER, } type; + constexpr bool IsCBuffer() const { return type == TYPE_CBUFFER; } + constexpr bool IsSampler() const { return type == TYPE_SAMPLER; } + constexpr bool IsROResource() const + { + return type == TYPE_TBUFFER || type == TYPE_TEXTURE || type == TYPE_STRUCTURED || + type == TYPE_BYTEADDRESS; + } + constexpr bool IsUAV() const + { + return type == TYPE_UAV_RWTYPED || type == TYPE_UAV_RWSTRUCTURED || + type == TYPE_UAV_RWBYTEADDRESS || type == TYPE_UAV_APPEND_STRUCTURED || + type == TYPE_UAV_CONSUME_STRUCTURED || type == TYPE_UAV_RWSTRUCTURED_WITH_COUNTER; + } + uint32_t space; uint32_t reg; uint32_t bindCount; @@ -344,6 +358,7 @@ public: vector m_Immediate; + bool m_GuessedResources; vector m_Resources; vector m_CBuffers; @@ -390,11 +405,10 @@ private: void GuessResources(); // these functions modify tokenStream pointer to point after the item - bool ExtractOperation( - uint32_t *&tokenStream, - ASMOperation &op); // returns false if not an operation (ie. it's a declaration) - bool ExtractDecl(uint32_t *&tokenStream, ASMDecl &decl); // as above - bool ExtractOperand(uint32_t *&tokenStream, ASMOperand &oper); + // ExtractOperation/ExtractDecl returns false if not an operation (ie. it's a declaration) + bool ExtractOperation(uint32_t *&tokenStream, ASMOperation &op, bool friendlyName); + bool ExtractDecl(uint32_t *&tokenStream, ASMDecl &decl, bool friendlyName); + bool ExtractOperand(uint32_t *&tokenStream, ToString flags, ASMOperand &oper); bool IsDeclaration(OpcodeType op); diff --git a/renderdocui/Code/PersistantConfig.cs b/renderdocui/Code/PersistantConfig.cs index 44dc04e95..25c2571bb 100644 --- a/renderdocui/Code/PersistantConfig.cs +++ b/renderdocui/Code/PersistantConfig.cs @@ -334,6 +334,9 @@ namespace renderdocui.Code { if (ReadOnly) return; + StaticExports.SetConfigSetting("Disassembly_FriendlyNaming", + ShaderViewer_FriendlyNaming ? "1" : "0"); + try { ConfigSettingsValues.Clear(); @@ -365,6 +368,9 @@ namespace renderdocui.Code PersistantConfig c = (PersistantConfig)xs.Deserialize(reader); reader.Close(); + StaticExports.SetConfigSetting("Disassembly_FriendlyNaming", + c.ShaderViewer_FriendlyNaming ? "1" : "0"); + foreach (var kv in c.ConfigSettingsValues) { if (kv.Key != null && kv.Key.Length > 0 && diff --git a/renderdocui/Windows/ShaderViewer.cs b/renderdocui/Windows/ShaderViewer.cs index 33872097e..1276efe2d 100644 --- a/renderdocui/Windows/ShaderViewer.cs +++ b/renderdocui/Windows/ShaderViewer.cs @@ -60,7 +60,6 @@ namespace renderdocui.Windows private D3D11PipelineState.ShaderStage m_Stage = null; private ShaderDebugTrace m_Trace = null; private ScintillaNET.Scintilla m_DisassemblyView = null; - private string m_DefaultDisasm = ""; private DockContent m_ErrorsDock = null; private DockContent m_ConstantsDock = null; @@ -154,70 +153,6 @@ namespace renderdocui.Windows } } - private string FriendlyName(string disasm, string stem, string prefix, ShaderConstant[] vars) - { - foreach (var v in vars) - { - if (v.type.descriptor.rows == 0 && v.type.descriptor.cols == 0 && v.type.members.Length > 0) - { - string subPrefix = prefix + v.name + "."; - - disasm = FriendlyName(disasm, stem, subPrefix, v.type.members); - } - else if (v.type.descriptor.rows > 0 && v.type.descriptor.cols > 0) - { - uint numRegs = v.type.descriptor.rows * Math.Max(1, v.type.descriptor.elements); - int regSize = (int)v.type.descriptor.cols; - - if (!v.type.descriptor.rowMajorStorage && v.type.descriptor.rows > 1 && v.type.descriptor.cols > 1) - { - numRegs = v.type.descriptor.cols; - regSize = (int)v.type.descriptor.rows; - } - - for (uint r = 0; r < numRegs; r++) - { - var reg = string.Format("{0}[{1}]", stem, v.reg.vec + r); - - int compStart = r == 0 ? (int)v.reg.comp : 0; - int compEnd = compStart + regSize; - - var comps = "xyzw".Substring(compStart, compEnd - compStart); - - var regexp = string.Format(", (-|abs\\()?{0}\\.([{1}]*)([^xyzw])", Regex.Escape(reg), comps); - - var match = Regex.Match(disasm, regexp); - - while (match.Success) - { - var swizzle = match.Groups[2].Value.ToCharArray(); - - for (int c = 0; c < swizzle.Length; c++) - { - int val = "xyzw".IndexOf(swizzle[c]); - swizzle[c] = "xyzw"[val - compStart]; - } - - var name = numRegs == 1 ? v.name : string.Format("{0}[{1}]", v.name, r); - - name = prefix + name; - - var replacement = string.Format(", {0}{1}.{2}{3}", - match.Groups[1].Value, name, new string(swizzle), match.Groups[3].Value); - - disasm = disasm.Remove(match.Index, match.Length); - - disasm = disasm.Insert(match.Index, replacement); - - match = Regex.Match(disasm, regexp); - } - } - } - } - - return disasm; - } - private List m_Scintillas = new List(); private SaveMethod m_SaveCallback = null; private CloseMethod m_CloseCallback = null; @@ -578,56 +513,10 @@ namespace renderdocui.Windows { var disasm = replay.DisassembleShader(m_ShaderDetails, ""); - if (m_Core.Config.ShaderViewer_FriendlyNaming && m_ShaderDetails != null && - m_Core.APIProps.pipelineType.IsD3D()) - { - for (int i = 0; i < m_ShaderDetails.ConstantBlocks.Length; i++) - { - var cbuf = m_ShaderDetails.ConstantBlocks[i]; - - var stem = string.Format("cb{0}", cbuf.bindPoint); - - if (cbuf.variables.Length == 0) - continue; - - disasm = FriendlyName(disasm, stem, "", cbuf.variables); - } - - foreach (var r in m_ShaderDetails.ReadOnlyResources) - { - if (r.IsSRV) - { - var needle = string.Format(", t{0}([^0-9])", r.bindPoint); - var replacement = string.Format(", {0}$1", r.name); - - Regex rgx = new Regex(needle); - disasm = rgx.Replace(disasm, replacement); - } - if (r.IsSampler) - { - var needle = string.Format(", s{0}([^0-9])", r.bindPoint); - var replacement = string.Format(", {0}$1", r.name); - - Regex rgx = new Regex(needle); - disasm = rgx.Replace(disasm, replacement); - } - } - foreach (var r in m_ShaderDetails.ReadWriteResources) - { - var needle = string.Format(", u{0}([^0-9])", r.bindPoint); - var replacement = string.Format(", {0}$1", r.name); - - Regex rgx = new Regex(needle); - disasm = rgx.Replace(disasm, replacement); - } - } - - m_DefaultDisasm = disasm; - this.BeginInvoke((MethodInvoker)delegate { m_DisassemblyView.IsReadOnly = false; - m_DisassemblyView.Text = m_DefaultDisasm; + m_DisassemblyView.Text = disasm; m_DisassemblyView.UndoRedo.EmptyUndoBuffer(); m_DisassemblyView.IsReadOnly = true; }); @@ -775,29 +664,19 @@ namespace renderdocui.Windows if (disasmType == null) return; - if (disasmType.SelectedIndex == 0 || m_ShaderDetails == null) + string target = disasmType.Items[disasmType.SelectedIndex].ToString(); + m_Core.Renderer.BeginInvoke((ReplayRenderer r) => { - m_DisassemblyView.IsReadOnly = false; - m_DisassemblyView.Text = m_DefaultDisasm; - m_DisassemblyView.UndoRedo.EmptyUndoBuffer(); - m_DisassemblyView.IsReadOnly = true; - } - else - { - string target = disasmType.Items[disasmType.SelectedIndex].ToString(); - m_Core.Renderer.BeginInvoke((ReplayRenderer r) => - { - string disasm = r.DisassembleShader(m_ShaderDetails, target); + string disasm = r.DisassembleShader(m_ShaderDetails, target); - this.BeginInvoke((MethodInvoker)delegate - { - m_DisassemblyView.IsReadOnly = false; - m_DisassemblyView.Text = disasm; - m_DisassemblyView.UndoRedo.EmptyUndoBuffer(); - m_DisassemblyView.IsReadOnly = true; - }); + this.BeginInvoke((MethodInvoker)delegate + { + m_DisassemblyView.IsReadOnly = false; + m_DisassemblyView.Text = disasm; + m_DisassemblyView.UndoRedo.EmptyUndoBuffer(); + m_DisassemblyView.IsReadOnly = true; }); - } + }); } private ListBox m_FileList = null;