From be674c012b883d51896259011ec6fd77a2067bca Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 22 Aug 2022 16:47:46 +0100 Subject: [PATCH] Handle variable length string in OpEntryPoint correctly. Closes #2697 --- .../driver/shaders/spirv/gen_spirv_code.py | 38 ++++++++++++++----- renderdoc/driver/shaders/spirv/spirv_gen.cpp | 6 ++- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/gen_spirv_code.py b/renderdoc/driver/shaders/spirv/gen_spirv_code.py index b1f0f71c1..2ed0dcfc7 100644 --- a/renderdoc/driver/shaders/spirv/gen_spirv_code.py +++ b/renderdoc/driver/shaders/spirv/gen_spirv_code.py @@ -946,6 +946,7 @@ for inst in spirv['instructions']: manual_init += ' this->wordCount = (uint16_t)it.size();\n' oper_cast = ' operator Operation() const\n {\n rdcarray words;\n' has_funcs = '' + used_ids_str = '' disassemble += ' Op{} decoded(it);\n'.format(inst['opname'][2:]) @@ -984,18 +985,32 @@ for inst in spirv['instructions']: manual_init += ' word = {};\n'.format(all_size) if kind['is_id']: - if quantifier == '*': - used_ids += ' for(size_t i=0; i < size-{0}; i++) callback(Id::fromWord(it.word({0}+i)), {1});\n'.format(all_size, 'true' if i+1==result else 'false') - elif quantifier == '?': - used_ids += ' if({0} < size) callback(Id::fromWord(it.word({0})), {1});\n'.format(all_size, 'true' if i+1==result else 'false') + if used_ids_str is None or used_ids_str != '': + if used_ids_str is not None: + used_ids += used_ids_str + if quantifier == '*': + used_ids += ' for(; word < size; word++) callback(Id::fromWord(it.word(word)), {0});\n'.format('true' if i+1==result else 'false') + elif quantifier == '?': + used_ids += ' if(word < size) callback(Id::fromWord(it.word(word)), {0});\n'.format('true' if i+1==result else 'false') + else: + used_ids += ' callback(Id::fromWord(it.word(word)), {});\n'.format('true' if i+1==result else 'false') else: - used_ids += ' callback(Id::fromWord(it.word({})), {});\n'.format(all_size, 'true' if i+1==result else 'false') + if quantifier == '*': + used_ids += ' for(size_t i=0; i < size-{0}; i++) callback(Id::fromWord(it.word({0}+i)), {1});\n'.format(all_size, 'true' if i+1==result else 'false') + elif quantifier == '?': + used_ids += ' if({0} < size) callback(Id::fromWord(it.word({0})), {1});\n'.format(all_size, 'true' if i+1==result else 'false') + else: + used_ids += ' callback(Id::fromWord(it.word({})), {});\n'.format(all_size, 'true' if i+1==result else 'false') if kind['size'] < 0: size_name = 'MinWordSize' construct_size = 'MinWordSize' complex_type = True manual_init += ' word = {};\n'.format(all_size) + # use DecodeParam to advance by the number of words when grabbing IDs + # Only used in OpEntryPoint which has a * qualifier after a string (itself already variable length) + used_ids_str += ' word = {};\n'.format(all_size) + used_ids_str += ' (void)DecodeParam(it, word);\n' opType,opName = (kind['type'], operand_name(operand['name'] if 'name' in operand else kind['def_name'])) @@ -1061,13 +1076,14 @@ for inst in spirv['instructions']: manual_init += ' this->{name} = {value};\n'.format(name = opName, type = opType, value = kind['from_words']('it.word({})'.format(all_size))) oper_cast += ' {push_words}\n'.format(push_words = kind['push_words'](opName)) - if kind['size'] >= 0: + if kind['size'] >= 0 and type(all_size) is int: all_size += kind['size'] + if quantifier == '': + size = all_size else: - all_size += 1 - - if quantifier == '': - size = all_size + if quantifier == '': + size += 1 + all_size = 'error: must not use all_size after variable length entry' else: assign = ' // no operands' member_decl = ' // no operands' @@ -1249,6 +1265,8 @@ rdcstr ParamToStr(const std::function &idName, const PairIdR void OpDecoder::ForEachID(const ConstIter &it, const std::function &callback) {{ size_t size = it.size(); + uint32_t word = 0; + (void)word; switch(it.opcode()) {{ {used_ids} diff --git a/renderdoc/driver/shaders/spirv/spirv_gen.cpp b/renderdoc/driver/shaders/spirv/spirv_gen.cpp index 6c85a561e..6764d021b 100644 --- a/renderdoc/driver/shaders/spirv/spirv_gen.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_gen.cpp @@ -2017,6 +2017,8 @@ rdcstr ParamToStr(const std::function &idName, const rdcspv: void OpDecoder::ForEachID(const ConstIter &it, const std::function &callback) { size_t size = it.size(); + uint32_t word = 0; + (void)word; switch(it.opcode()) { case rdcspv::Op::Nop: @@ -2055,7 +2057,9 @@ void OpDecoder::ForEachID(const ConstIter &it, const std::function(it, word); + for(; word < size; word++) callback(Id::fromWord(it.word(word)), false); break; case rdcspv::Op::ExecutionMode: callback(Id::fromWord(it.word(1)), false);