From 045aad23ad98df54c7dc4f30e98f1c1990219ea6 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 1 Sep 2021 11:11:00 +0100 Subject: [PATCH] Write param attr blocks * We cheat slightly with the attributes - we combine these on load, so we lose information about multiple groups they may reference. So we save the groups that we read from and use that to write the attribute. --- .../driver/shaders/dxil/dxil_bytecode.cpp | 2 + renderdoc/driver/shaders/dxil/dxil_bytecode.h | 3 + .../shaders/dxil/dxil_bytecode_editor.cpp | 106 +++++++++++++++++- 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index 852971c18..1f615e689 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -524,6 +524,7 @@ Program::Program(const byte *bytes, size_t length) size_t id = (size_t)attrgroup.ops[0]; group.index = attrgroup.ops[1]; + group.valid = true; for(size_t i = 2; i < attrgroup.ops.size(); i++) { @@ -583,6 +584,7 @@ Program::Program(const byte *bytes, size_t length) Attributes attrs; attrs.index = m_Attributes.size(); + attrs.groups = paramattr.ops; for(uint64_t g : paramattr.ops) { diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index 141945f4b..0d2572fe9 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -221,8 +221,11 @@ BITMASK_OPERATORS(Attribute); struct Attributes { + bool valid = false; uint64_t index = 0; + rdcarray groups; + Attribute params = Attribute::None; uint64_t align = 0, stackAlign = 0, derefBytes = 0, derefOrNullBytes = 0; rdcarray> strs; diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp index 5e87f5fee..6b5380410 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode_editor.cpp @@ -50,7 +50,111 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const writer.Unabbrev((uint32_t)LLVMBC::ModuleRecord::VERSION, 1U); - writer.ModuleBlockInfo((uint32_t)m_Types.size()); + { + writer.ModuleBlockInfo((uint32_t)m_Types.size()); + } + + if(!m_AttributeGroups.empty()) + { + writer.BeginBlock(LLVMBC::KnownBlock::PARAMATTR_GROUP_BLOCK); + + rdcarray vals; + + for(size_t i = 0; i < m_AttributeGroups.size(); i++) + { + if(m_AttributeGroups[i].valid) + { + const Attributes &group = m_AttributeGroups[i]; + + vals.clear(); + vals.push_back(i); + vals.push_back(group.index); + + // decompose params bitfield into bits + if(group.params != Attribute::None) + { + uint64_t params = (uint64_t)group.params; + for(uint64_t p = 0; p < 64; p++) + { + if((params & (1ULL << p)) != 0) + { + switch(Attribute(1ULL << p)) + { + case Attribute::Alignment: + { + vals.push_back(1); + vals.push_back(p); + vals.push_back(group.align); + break; + } + case Attribute::StackAlignment: + { + vals.push_back(1); + vals.push_back(p); + vals.push_back(group.stackAlign); + break; + } + case Attribute::Dereferenceable: + { + vals.push_back(1); + vals.push_back(p); + vals.push_back(group.derefBytes); + break; + } + case Attribute::DereferenceableOrNull: + { + vals.push_back(1); + vals.push_back(p); + vals.push_back(group.derefOrNullBytes); + break; + } + default: + { + // this attribute just exists or doesn't + vals.push_back(0); + vals.push_back(p); + } + } + } + } + } + + if(!group.strs.empty()) + { + for(const rdcpair &strAttr : group.strs) + { + if(strAttr.second.empty()) + vals.push_back(3); + else + vals.push_back(4); + + // iterate including NULL terminator + for(size_t c = 0; c < strAttr.first.size() + 1; c++) + vals.push_back(uint64_t(strAttr.first[c])); + + for(size_t c = 0; !strAttr.second.empty() && c < strAttr.second.size() + 1; c++) + vals.push_back(uint64_t(strAttr.second[c])); + } + } + + writer.Unabbrev((uint32_t)LLVMBC::ParamAttrGroupRecord::ENTRY, vals); + } + } + + writer.EndBlock(); + } + + if(!m_Attributes.empty()) + { + writer.BeginBlock(LLVMBC::KnownBlock::PARAMATTR_BLOCK); + + for(size_t i = 0; i < m_Attributes.size(); i++) + { + writer.Unabbrev((uint32_t)LLVMBC::ParamAttrRecord::ENTRY, m_Attributes[i].groups); + } + + writer.EndBlock(); + } writer.EndBlock();