diff --git a/renderdoc/driver/shaders/spirv/spirv_common.h b/renderdoc/driver/shaders/spirv/spirv_common.h index 24f5b5d14..101d59625 100644 --- a/renderdoc/driver/shaders/spirv/spirv_common.h +++ b/renderdoc/driver/shaders/spirv/spirv_common.h @@ -231,9 +231,28 @@ private: uint32_t value; }; +// need to do this in a separate struct because you can't specialise a member function in a +// templated class. Blech +struct OpExtInstHelper +{ + rdcarray params; + + template + T arg(uint32_t idx) + { + return T(params[idx]); + } +}; + +template <> +inline Id OpExtInstHelper::arg(uint32_t idx) +{ + return Id::fromWord(params[idx]); +} + // helper in the style of the auto-generated one for ext insts template -struct OpExtInstGeneric +struct OpExtInstGeneric : public OpExtInstHelper { OpExtInstGeneric(IdResultType resultType, IdResult result, Id set, InstType inst, const rdcarray ¶ms) @@ -279,7 +298,6 @@ struct OpExtInstGeneric IdResult result; Id set; InstType inst; - rdcarray params; }; struct OpExtInst : public OpExtInstGeneric diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index 902caee9f..8d919bf2c 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -2413,7 +2413,7 @@ void Debugger::RegisterOp(Iter it) { OpExtInst extinst(it); - if(extSets[extinst.set] == "GLSL.std.450") + if(knownExtSet[ExtSet_GLSL450] == extinst.set) { // all parameters to GLSL.std.450 are Ids, extend idDeathOffset appropriately for(const uint32_t param : extinst.params) @@ -2422,7 +2422,7 @@ void Debugger::RegisterOp(Iter it) idDeathOffset[id] = RDCMAX(it.offs() + 1, idDeathOffset[id]); } } - else if(extSets[extinst.set] == "NonSemantic.DebugPrintf") + else if(knownExtSet[ExtSet_Printf] == extinst.set) { // all parameters to NonSemantic.DebugPrintf are Ids, extend idDeathOffset appropriately for(const uint32_t param : extinst.params) diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index 22111a461..7e6f5c0ba 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -1534,44 +1534,74 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint, break; } - // need to handle this by hand anyway case Op::ExtInst: { - OpDecoder decoded(it); - ret += indent; - ret += StringFormat::Fmt("%s = ", declName(decoded.resultType, decoded.result).c_str()); + OpExtInst decoded(it); - rdcstr setname = extSets.find(Id::fromWord(it.word(3)))->second; + rdcstr setname = extSets.find(decoded.set)->second; uint32_t inst = it.word(4); - const bool IsGLSL450 = (setname == "GLSL.std.450"); - const bool IsDebugPrintf = (setname == "NonSemantic.DebugPrintf"); + const bool IsGLSL450 = knownExtSet[ExtSet_GLSL450] == decoded.set; + const bool IsDebugPrintf = knownExtSet[ExtSet_Printf] == decoded.set; + const bool IsShaderDbg = knownExtSet[ExtSet_ShaderDbg] == decoded.set; // GLSL.std.450 all parameters are Ids const bool idParams = IsGLSL450 || setname.beginsWith("NonSemantic."); - if(IsGLSL450) - ret += StringFormat::Fmt("%s::%s(", setname.c_str(), ToStr(GLSLstd450(inst)).c_str()); - else if(IsDebugPrintf) - ret += "DebugPrintf("; - else - ret += StringFormat::Fmt("%s::[%u](", setname.c_str(), inst); - - for(size_t i = 5; i < it.size(); i++) + // most vulkan debug info instructions don't get printed explicitly, and those that do + // have no return value that we print + if(IsShaderDbg) { - if(i == 5 && IsDebugPrintf) - ret += "\""; + OpShaderDbg dbg(it); - // TODO could generate this from the instruction set grammar. - ret += idParams ? idName(Id::fromWord(it.word(i))) : ToStr(it.word(i)); - - if(i == 5 && IsDebugPrintf) - ret += "\""; - - if(i + 1 < it.size()) + if(dbg.inst == ShaderDbg::Source) + { + dynamicNames[dbg.result] = idName(dbg.arg(0)); + continue; + } + else if(dbg.inst == ShaderDbg::CompilationUnit) + { + uint32_t lang = EvaluateConstant(dbg.arg(3), {}).value.u32v[0]; + ret += indent; + ret += "DebugCompilationUnit("; + ret += idName(dbg.arg(2)); ret += ", "; + ret += ToStr(rdcspv::SourceLanguage(lang)); + ret += ")"; + } + else + { + continue; + } } + else + { + ret += indent; + ret += StringFormat::Fmt("%s = ", declName(decoded.resultType, decoded.result).c_str()); - ret += ")"; + if(IsGLSL450) + ret += StringFormat::Fmt("%s::%s(", setname.c_str(), ToStr(GLSLstd450(inst)).c_str()); + else if(IsDebugPrintf) + ret += "DebugPrintf("; + else + ret += StringFormat::Fmt("%s::[%u](", setname.c_str(), inst); + + for(uint32_t i = 0; i < decoded.params.size(); i++) + { + if(i == 5 && IsDebugPrintf) + ret += "\""; + + // TODO could generate this from the instruction set grammar. + ret += idParams ? idName(decoded.arg(i)) : ToStr(decoded.arg(i)); + + if(i == 5 && IsDebugPrintf) + ret += "\""; + + if(i + 1 < decoded.params.size()) + ret += ", "; + } + + ret += ")"; + } break; } diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.cpp b/renderdoc/driver/shaders/spirv/spirv_processor.cpp index c3e394aa9..d38d596c3 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_processor.cpp @@ -526,6 +526,13 @@ void Processor::RegisterOp(Iter it) { OpExtInstImport decoded(it); extSets[decoded.result] = decoded.name; + + if(decoded.name == "GLSL.std.450") + knownExtSet[ExtSet_GLSL450] = decoded.result; + else if(decoded.name == "NonSemantic.DebugPrintf") + knownExtSet[ExtSet_Printf] = decoded.result; + else if(decoded.name == "NonSemantic.Shader.DebugInfo.100") + knownExtSet[ExtSet_ShaderDbg] = decoded.result; } else if(opdata.op == Op::EntryPoint) { diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.h b/renderdoc/driver/shaders/spirv/spirv_processor.h index 690ea7ebe..901351ced 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.h +++ b/renderdoc/driver/shaders/spirv/spirv_processor.h @@ -567,7 +567,16 @@ protected: SparseIdMap sampledImageTypes; SparseIdMap functionTypes; + enum ExtSet + { + ExtSet_GLSL450 = 0, + ExtSet_Printf = 1, + ExtSet_ShaderDbg = 2, + ExtSet_Count, + }; + std::map extSets; + Id knownExtSet[ExtSet_Count]; struct LogicalSection {