From 8b57989b3fba277605ed3219cf07b0e1a5c274cf Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 9 Jun 2020 14:10:31 +0100 Subject: [PATCH] Disassemble global variables with initialisers properly --- .../driver/shaders/dxil/dxil_bytecode.cpp | 20 +++++++-- renderdoc/driver/shaders/dxil/dxil_bytecode.h | 41 ++++++++++++------- .../driver/shaders/dxil/dxil_disassemble.cpp | 28 ++++++++++--- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index 5d30743be..e5981ebb1 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -419,7 +419,19 @@ Program::Program(const byte *bytes, size_t length) GlobalVar g; g.type = &m_Types[(size_t)rootchild.ops[0]]; - g.isconst = (rootchild.ops[1] & 0x1); + if(rootchild.ops[1] & 0x1) + g.flags |= GlobalFlags::IsConst; + + if(rootchild.ops.size() > 8) + { + if(rootchild.ops[8] == 1) + g.flags |= GlobalFlags::GlobalUnnamedAddr; + else if(rootchild.ops[8] == 2) + g.flags |= GlobalFlags::LocalUnnamedAddr; + } + + if(rootchild.ops[2]) + g.initialiser = Symbol(SymbolType::Constant, rootchild.ops[2] - 1); switch(rootchild.ops[3]) { @@ -427,8 +439,8 @@ Program::Program(const byte *bytes, size_t length) case 5: case 6: case 7: - case 15: g.external = true; break; - default: g.external = false; break; + case 15: g.flags |= GlobalFlags::IsExternal; break; + default: break; } g.align = (1U << rootchild.ops[4]) >> 1; @@ -454,6 +466,8 @@ Program::Program(const byte *bytes, size_t length) if(v.type == g.type) RDCERR("Expected to find pointer type for global variable"); + g.type = v.type; + m_Values.push_back(v); m_GlobalVars.push_back(g); } diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index 3fd0864c9..513da2526 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -78,20 +78,6 @@ struct Type rdcarray members; // the members for a struct, the parameters for functions }; -struct GlobalVar -{ - rdcstr name; - const Type *type = NULL; - bool isconst = false; - bool external = false; - uint64_t align = 0; -}; - -struct Alias -{ - rdcstr name; -}; - enum class SymbolType { Unknown, @@ -112,6 +98,31 @@ struct Symbol uint64_t idx; }; +enum class GlobalFlags : uint32_t +{ + NoFlags = 0, + IsConst = 0x1, + IsExternal = 0x2, + LocalUnnamedAddr = 0x4, + GlobalUnnamedAddr = 0x8, +}; + +BITMASK_OPERATORS(GlobalFlags); + +struct GlobalVar +{ + rdcstr name; + const Type *type = NULL; + uint64_t align = 0; + GlobalFlags flags = GlobalFlags::NoFlags; + Symbol initialiser; +}; + +struct Alias +{ + rdcstr name; +}; + // this enum is ordered to match the serialised order of these attributes enum class Attribute : uint64_t { @@ -183,7 +194,7 @@ struct Value ShaderValue val = {}; rdcarray members; rdcstr str; - bool undef = false, nullconst = true, symbol = false; + bool undef = false, nullconst = false, symbol = false; rdcstr toString(bool withType = false) const; }; diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index e76a067c0..79bc0196f 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -336,11 +336,21 @@ void Program::MakeDisassemblyString() const GlobalVar &g = m_GlobalVars[i]; m_Disassembly += StringFormat::Fmt("@%s = ", escapeStringIfNeeded(g.name).c_str()); - if(g.external) + if(g.flags & GlobalFlags::IsExternal) m_Disassembly += "external "; - if(g.isconst) + else + m_Disassembly += "internal "; + if(g.flags & GlobalFlags::LocalUnnamedAddr) + m_Disassembly += "local_unnamed_addr "; + else if(g.flags & GlobalFlags::GlobalUnnamedAddr) + m_Disassembly += "unnamed_addr "; + if(g.flags & GlobalFlags::IsConst) m_Disassembly += "constant "; - m_Disassembly += g.type->toString(); + + if(g.initialiser.type == SymbolType::Constant) + m_Disassembly += m_Values[g.initialiser.idx].toString(true); + else + m_Disassembly += g.type->inner->toString(); if(g.align > 0) m_Disassembly += StringFormat::Fmt(", align %u", g.align); @@ -395,6 +405,8 @@ void Program::MakeDisassemblyString() Metadata &m = m_Metadata[s.idx]; if(m.value && m.val && m.val->nullconst) ret += StringFormat::Fmt("%s zeroinitializer", m.val->type->toString()); + else if(m.value && m.val && m.val->symbol) + ret += m.val->toString(true); else ret += StringFormat::Fmt("!%u", GetOrAssignMetaID(&m)); } @@ -405,10 +417,16 @@ void Program::MakeDisassemblyString() break; case SymbolType::Function: ret = "@" + escapeStringIfNeeded(m_Functions[s.idx].name); break; case SymbolType::GlobalVar: - ret = "@" + escapeStringIfNeeded(m_GlobalVars[s.idx].name); + if(withTypes) + ret = m_GlobalVars[s.idx].type->toString() + " "; + ret += "@" + escapeStringIfNeeded(m_GlobalVars[s.idx].name); break; case SymbolType::Constant: ret = GetFunctionValue(func, s.idx)->toString(withTypes); break; - case SymbolType::Argument: ret = "%" + escapeStringIfNeeded(func.args[s.idx].name); break; + case SymbolType::Argument: + if(withTypes) + ret = func.args[s.idx].type->toString() + " "; + ret += "%" + escapeStringIfNeeded(func.args[s.idx].name); + break; case SymbolType::Instruction: { const Instruction &refinst = func.instructions[s.idx];