Don't disassemble most vulkan debug info SPIR-V opcodes

* These are metadata for us, not for general consumption in a user-facing
  disassembly
This commit is contained in:
baldurk
2022-02-04 16:45:14 +00:00
parent 4d0aba7725
commit 401e995748
5 changed files with 93 additions and 29 deletions
+20 -2
View File
@@ -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<uint32_t> params;
template <typename T>
T arg(uint32_t idx)
{
return T(params[idx]);
}
};
template <>
inline Id OpExtInstHelper::arg<Id>(uint32_t idx)
{
return Id::fromWord(params[idx]);
}
// helper in the style of the auto-generated one for ext insts
template <typename InstType>
struct OpExtInstGeneric
struct OpExtInstGeneric : public OpExtInstHelper
{
OpExtInstGeneric(IdResultType resultType, IdResult result, Id set, InstType inst,
const rdcarray<IdOrWord> &params)
@@ -279,7 +298,6 @@ struct OpExtInstGeneric
IdResult result;
Id set;
InstType inst;
rdcarray<uint32_t> params;
};
struct OpExtInst : public OpExtInstGeneric<uint32_t>
@@ -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)
@@ -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<Id>(0));
continue;
}
else if(dbg.inst == ShaderDbg::CompilationUnit)
{
uint32_t lang = EvaluateConstant(dbg.arg<Id>(3), {}).value.u32v[0];
ret += indent;
ret += "DebugCompilationUnit(";
ret += idName(dbg.arg<Id>(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<Id>(i)) : ToStr(decoded.arg<uint32_t>(i));
if(i == 5 && IsDebugPrintf)
ret += "\"";
if(i + 1 < decoded.params.size())
ret += ", ";
}
ret += ")";
}
break;
}
@@ -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)
{
@@ -567,7 +567,16 @@ protected:
SparseIdMap<SampledImage> sampledImageTypes;
SparseIdMap<FunctionType> functionTypes;
enum ExtSet
{
ExtSet_GLSL450 = 0,
ExtSet_Printf = 1,
ExtSet_ShaderDbg = 2,
ExtSet_Count,
};
std::map<Id, rdcstr> extSets;
Id knownExtSet[ExtSet_Count];
struct LogicalSection
{