diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index 1a49b975e..4fbce6cc7 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -837,6 +837,32 @@ Program::Program(const byte *bytes, size_t length) size_t v = (size_t)symtab.ops[0]; if(v < m_Values.size()) { + 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; + } + } + switch(m_Values[v].type) { case ValueType::Unknown: @@ -845,27 +871,31 @@ Program::Program(const byte *bytes, size_t length) 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 = symtab.getString(1); + global->name = str; break; } case ValueType::Function: { Function *function = (Function *)m_Values[v].function; - function->name = symtab.getString(1); + function->name = str; break; } case ValueType::Alias: { Alias *alias = (Alias *)m_Values[v].alias; - alias->name = symtab.getString(1); + alias->name = str; break; } } + + m_ValueSymtabOrder.push_back(v); } else { @@ -1103,28 +1133,53 @@ Program::Program(const byte *bytes, size_t length) } const Value &v = m_Values[idx]; + rdcstr str = symtab.getString(1); + + if(!f.valueSymtabOrder.empty()) + { + const Value &prevValue = m_Values[f.valueSymtabOrder.back()]; + 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; + } + } switch(v.type) { - case ValueType::Unknown: case ValueType::Constant: { Constant *constant = (Constant *)v.constant; - constant->str = symtab.getString(1); + constant->str = str; break; } case ValueType::Instruction: { Instruction *instruction = (Instruction *)v.instruction; - instruction->name = symtab.getString(1); + instruction->name = str; break; } case ValueType::BasicBlock: { Block *block = (Block *)v.block; - block->name = symtab.getString(1); + block->name = str; break; } + case ValueType::Unknown: case ValueType::GlobalVar: case ValueType::Function: case ValueType::Alias: @@ -1133,6 +1188,8 @@ Program::Program(const byte *bytes, size_t length) RDCERR("Unexpected local symbol referring to %d", v.type); break; } + + f.valueSymtabOrder.push_back(idx); } else if(IS_KNOWN(symtab.id, ValueSymtabRecord::BBENTRY)) { diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index c5e4d53e6..9c18dd9c6 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -600,6 +600,9 @@ struct Function rdcarray instructions; rdcarray values; + rdcarray valueSymtabOrder; + bool sortedSymtab = true; + rdcarray blocks; rdcarray constants; rdcarray metadata; @@ -676,6 +679,9 @@ protected: rdcarray m_Kinds; + rdcarray m_ValueSymtabOrder; + bool m_SortedSymtab = true; + rdcarray m_Types; const Type *m_VoidType = NULL; const Type *m_BoolType = NULL; diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp index 79750ad99..e96909670 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp @@ -482,12 +482,13 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const writer.EndBlock(); } + if(!m_ValueSymtabOrder.empty()) { writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK); rdcarray> entries; - for(size_t s = 0; s < m_Values.size(); s++) + for(size_t s : m_ValueSymtabOrder) { const rdcstr *str = NULL; switch(m_Values[s].type) @@ -502,11 +503,6 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const entries.push_back({s, str}); } - // sort the entries by string in order - std::sort(entries.begin(), entries.end(), - [](const rdcpair &a, - const rdcpair &b) { return *a.second < *b.second; }); - // 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) @@ -1062,6 +1058,36 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const debugLoc = inst.debugLoc; } + if(!f.valueSymtabOrder.empty()) + { + writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK); + + rdcarray> entries; + + for(size_t s : f.valueSymtabOrder) + { + const rdcstr *str = NULL; + 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; + } + + if(str) + entries.push_back({s, 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(); + } + if(needMetaAttach) { writer.BeginBlock(LLVMBC::KnownBlock::METADATA_ATTACHMENT);