From d15f264c81f09056f9a85b0e382da761524ee91d Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 20 Sep 2021 17:57:09 +0100 Subject: [PATCH] Store values rather than indices for aliases/symtab to allow rebasing --- .../driver/shaders/dxil/dxil_bytecode.cpp | 163 +++++------------- renderdoc/driver/shaders/dxil/dxil_bytecode.h | 8 +- .../shaders/dxil/dxil_bytecode_editor.cpp | 56 ++---- 3 files changed, 66 insertions(+), 161 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index b6a45d416..95d6788af 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -145,6 +145,9 @@ void ParseConstant(const LLVMBC::BlockOrRecord &constant, const Type *&curType, c.type = curType; if(c.type->type == Type::Vector) { + // only handle 4-wide vectors right now + RDCASSERT(constant.ops.size() <= 4); + // inline vectors for(size_t m = 0; m < constant.ops.size(); m++) { @@ -491,7 +494,7 @@ Program::Program(const byte *bytes, size_t length) Alias a; a.type = &m_Types[(size_t)rootchild.ops[0]]; - a.valID = rootchild.ops[1]; + a.val = m_Values[(size_t)rootchild.ops[1]]; // ignore rest of properties, assert that if present they are 0 for(size_t p = 2; p < rootchild.ops.size(); p++) @@ -851,72 +854,22 @@ Program::Program(const byte *bytes, size_t length) continue; } - size_t v = (size_t)symtab.ops[0]; - if(v < m_Values.size()) + size_t vidx = (size_t)symtab.ops[0]; + if(vidx < m_Values.size()) { + const Value &v = m_Values[vidx]; rdcstr str = symtab.getString(1); - if(!m_ValueSymtabOrder.empty()) - { - const Value &prevValue = m_Values[m_ValueSymtabOrder.back()]; - switch(prevValue.type) - { - case ValueType::GlobalVar: - { - m_SortedSymtab &= prevValue.global->name < str; - break; - } - case ValueType::Function: - { - m_SortedSymtab &= prevValue.function->name < str; - break; - } - case ValueType::Alias: - { - m_SortedSymtab &= prevValue.alias->name < str; - break; - } - default: break; - } - } + GetValueSymtabString(v) = str; - switch(m_Values[v].type) - { - case ValueType::Unknown: - case ValueType::Constant: - case ValueType::Instruction: - case ValueType::Metadata: - case ValueType::Literal: - case ValueType::BasicBlock: - { - RDCERR("Unexpected global symbol referring to %d", m_Values[v].type); - break; - } - case ValueType::GlobalVar: - { - GlobalVar *global = (GlobalVar *)m_Values[v].global; - global->name = str; - break; - } - case ValueType::Function: - { - Function *function = (Function *)m_Values[v].function; - function->name = str; - break; - } - case ValueType::Alias: - { - Alias *alias = (Alias *)m_Values[v].alias; - alias->name = str; - break; - } - } + if(!m_ValueSymtabOrder.empty()) + m_SortedSymtab &= GetValueSymtabString(m_ValueSymtabOrder.back()) < str; m_ValueSymtabOrder.push_back(v); } else { - RDCERR("Value %llu referenced out of bounds", v); + RDCERR("Value %zu referenced out of bounds", vidx); } } } @@ -1152,75 +1105,24 @@ Program::Program(const byte *bytes, size_t length) const Value &v = m_Values[idx]; rdcstr str = symtab.getString(1); + GetValueSymtabString(v) = str; + if(!f.valueSymtabOrder.empty()) - { - size_t vidx = f.valueSymtabOrder.back(); - if(vidx & 0x80000000U) - { - f.sortedSymtab &= f.blocks[vidx & ~0x80000000U].name < str; - } - else - { - const Value &prevValue = m_Values[vidx]; - switch(prevValue.type) - { - case ValueType::Constant: - { - f.sortedSymtab &= prevValue.constant->str < str; - break; - } - case ValueType::Instruction: - { - f.sortedSymtab &= prevValue.instruction->name < str; - break; - } - case ValueType::BasicBlock: - { - f.sortedSymtab &= prevValue.block->name < str; - break; - } - default: break; - } - } - } + f.sortedSymtab &= GetValueSymtabString(f.valueSymtabOrder.back()) < str; - switch(v.type) - { - case ValueType::Constant: - { - Constant *constant = (Constant *)v.constant; - constant->str = str; - break; - } - case ValueType::Instruction: - { - Instruction *instruction = (Instruction *)v.instruction; - instruction->name = str; - break; - } - case ValueType::BasicBlock: - { - Block *block = (Block *)v.block; - block->name = str; - break; - } - case ValueType::Unknown: - case ValueType::GlobalVar: - case ValueType::Function: - case ValueType::Alias: - case ValueType::Metadata: - case ValueType::Literal: - RDCERR("Unexpected local symbol referring to %d", v.type); - break; - } - - f.valueSymtabOrder.push_back(idx); + f.valueSymtabOrder.push_back(v); } else if(IS_KNOWN(symtab.id, ValueSymtabRecord::BBENTRY)) { - f.blocks[(size_t)symtab.ops[0]].name = symtab.getString(1); + Value v(&f.blocks[(size_t)symtab.ops[0]]); + rdcstr str = symtab.getString(1); - f.valueSymtabOrder.push_back(0x80000000U | (size_t)symtab.ops[0]); + GetValueSymtabString(v) = str; + + if(!f.valueSymtabOrder.empty()) + f.sortedSymtab &= GetValueSymtabString(f.valueSymtabOrder.back()) < str; + + f.valueSymtabOrder.push_back(v); } else { @@ -2386,6 +2288,25 @@ Program::Program(const byte *bytes, size_t length) RDCASSERT(functionDecls.empty()); } +rdcstr &Program::GetValueSymtabString(const Value &v) +{ + static rdcstr err; + switch(v.type) + { + case ValueType::Constant: return (rdcstr &)v.constant->str; + case ValueType::Instruction: return (rdcstr &)v.instruction->name; + case ValueType::BasicBlock: return (rdcstr &)v.block->name; + case ValueType::GlobalVar: return (rdcstr &)v.global->name; + case ValueType::Function: return (rdcstr &)v.function->name; + case ValueType::Alias: return (rdcstr &)v.alias->name; + case ValueType::Unknown: + case ValueType::Metadata: + case ValueType::Literal: RDCERR("Unexpected value symtab entry referring to %d", v.type); break; + } + + return err; +} + uint32_t Program::GetOrAssignMetaID(Metadata *m) { if(m->id != ~0U) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index c563d333a..083d88515 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -208,7 +208,7 @@ struct Alias { rdcstr name; const Type *type = NULL; - uint64_t valID = 0; + Value val; }; // this enum is ordered to match the serialised order of these attributes @@ -617,7 +617,7 @@ struct Function rdcarray instructions; rdcarray values; - rdcarray valueSymtabOrder; + rdcarray valueSymtabOrder; bool sortedSymtab = true; rdcarray blocks; @@ -673,6 +673,8 @@ protected: bool ParseDebugMetaRecord(const LLVMBC::BlockOrRecord &metaRecord, Metadata &meta); rdcstr GetDebugVarName(const DIBase *d); + rdcstr &GetValueSymtabString(const Value &v); + uint32_t GetOrAssignMetaID(Metadata *m); uint32_t GetOrAssignMetaID(DebugLocation &l); const Type *GetVoidType(); @@ -696,7 +698,7 @@ protected: rdcarray m_Kinds; - rdcarray m_ValueSymtabOrder; + rdcarray m_ValueSymtabOrder; bool m_SortedSymtab = true; rdcarray m_Types; diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp index 6a2772376..6864f23f0 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp @@ -510,7 +510,7 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const uint64_t typeIndex = getTypeID(a.type); writer.Record(LLVMBC::ModuleRecord::ALIAS, { - typeIndex, a.valID, + typeIndex, getValueID(a.val), // linkage 0U, // visibility @@ -579,28 +579,21 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const { writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK); - rdcarray> entries; - - for(size_t s : m_ValueSymtabOrder) + for(Value v : m_ValueSymtabOrder) { const rdcstr *str = NULL; - switch(m_Values[s].type) + switch(v.type) { - case ValueType::GlobalVar: str = &m_Values[s].global->name; break; - case ValueType::Function: str = &m_Values[s].function->name; break; - case ValueType::Alias: str = &m_Values[s].alias->name; break; + case ValueType::GlobalVar: str = &v.global->name; break; + case ValueType::Function: str = &v.function->name; break; + case ValueType::Alias: str = &v.alias->name; break; default: break; } if(str) - entries.push_back({s, str}); + writer.RecordSymTabEntry(getValueID(v), *str); } - // we use a special function to record the entry so it can take the string as-is to check it for - // validity - for(const rdcpair &it : entries) - writer.RecordSymTabEntry(it.first, *it.second); - writer.EndBlock(); } @@ -1155,37 +1148,26 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const { writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK); - rdcarray> entries; - - for(size_t s : f.valueSymtabOrder) + for(Value v : f.valueSymtabOrder) { const rdcstr *str = NULL; - if(s & 0x80000000U) + switch(v.type) { - str = &f.blocks[s & ~0x80000000U].name; - } - else - { - switch(values[s].type) - { - case ValueType::Instruction: str = &values[s].instruction->name; break; - case ValueType::Constant: str = &values[s].constant->str; break; - case ValueType::BasicBlock: str = &values[s].block->name; break; - default: break; - } + case ValueType::Instruction: str = &v.instruction->name; break; + case ValueType::Constant: str = &v.constant->str; break; + case ValueType::BasicBlock: str = &v.block->name; break; + default: break; } if(str) - entries.push_back({s, str}); + { + if(v.type == ValueType::BasicBlock) + writer.RecordSymTabEntry(v.block - f.blocks.begin(), *str, true); + else + writer.RecordSymTabEntry(getValueID(v), *str); + } } - // we use a special function to record the entry so it can take the string as-is to check it - // for - // validity - for(const rdcpair &it : entries) - writer.RecordSymTabEntry(it.first & ~0x80000000U, *it.second, - it.first & 0x80000000U ? true : false); - writer.EndBlock(); }