From 17e80ae9cd1852acc539ebec5f18e449bf308813 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 20 Oct 2020 14:33:46 +0100 Subject: [PATCH] Fix forward references in LLVM constants block --- .../driver/shaders/dxil/dxil_bytecode.cpp | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index 8e3219faa..37494ffd9 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -375,14 +375,17 @@ void ParseConstant(const LLVMBC::BlockOrRecord &constant, const Type *&curType, { const Constant *member = getConstant(m); - if(member) + if(member && member->type) { v.members.push_back(*member); } else { - v.members.push_back(Constant()); - RDCERR("Index %llu out of bounds for constants array", m); + Constant c; + c.type = NULL; + c.val.u64v[0] = m; + v.members.push_back(c); + RDCWARN("Index %llu out of bounds for constants array, possible forward reference", m); } } } @@ -962,6 +965,37 @@ Program::Program(const byte *bytes, size_t length) m_Constants.push_back(v); }); } + + // post-patch up contants with members that are references to future constants (blech!) + for(Constant &c : m_Constants) + { + if(c.members.empty()) + continue; + + for(Constant &m : c.members) + { + if(m.type == NULL) + { + if(m.val.u64v[0] > 0) + { + size_t idx = (size_t)m.val.u64v[0]; + if(idx < m_Constants.size()) + { + m = m_Constants[idx]; + } + else + { + m = Constant(); + RDCERR("Couldn't resolve constant %zu", idx); + } + } + else + { + RDCERR("Unexpected member with no type but no forward-index constant value"); + } + } + } + } } else if(IS_KNOWN(rootchild.id, KnownBlocks::VALUE_SYMTAB_BLOCK)) { @@ -1145,6 +1179,29 @@ Program::Program(const byte *bytes, size_t length) }); } + // post-patch up contants with members that are references to future constants + // (blech!) + for(Constant &c : f.constants) + { + if(c.members.empty()) + continue; + + for(Constant &m : c.members) + { + if(m.type == NULL) + { + if(m.val.u64v[0] > 0) + { + m = *getConstant(m.val.u64v[0]); + } + else + { + RDCERR("Unexpected member with no type but no forward-index constant value"); + } + } + } + } + instrSymbolStart = m_Symbols.size(); } else if(IS_KNOWN(funcChild.id, KnownBlocks::METADATA_BLOCK))