diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 688f9e26..2d9793f4 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -318,16 +318,37 @@ namespace dxvk { } } - // Remove location declarations - for (auto ins : code) { - if (ins.opCode() == spv::OpDecorate - && ins.arg(2) == spv::DecorationLocation - && ins.arg(1) == inputVarId) { - code.beginInsertion(ins.offset()); - code.erase(4); - code.endInsertion(); - break; + // Remove location and other declarations + for (auto iter = code.begin(); iter != code.end(); ) { + auto ins = *(iter++); + + if (ins.opCode() == spv::OpDecorate && ins.arg(1) == inputVarId) { + uint32_t numWords; + + switch (ins.arg(2)) { + case spv::DecorationLocation: + case spv::DecorationFlat: + case spv::DecorationNoPerspective: + case spv::DecorationCentroid: + case spv::DecorationPatch: + case spv::DecorationSample: + numWords = ins.length(); + break; + + default: + numWords = 0; + } + + if (numWords) { + code.beginInsertion(ins.offset()); + code.erase(numWords); + + iter = SpirvInstructionIterator(code.data(), code.endInsertion(), code.dwords()); + } } + + if (ins.opCode() == spv::OpFunction) + break; } // Fix up pointer types used in access chain instructions diff --git a/src/spirv/spirv_code_buffer.h b/src/spirv/spirv_code_buffer.h index a06b594c..6bee2c9b 100644 --- a/src/spirv/spirv_code_buffer.h +++ b/src/spirv/spirv_code_buffer.h @@ -208,9 +208,10 @@ namespace dxvk { * After this call, new instructions will be * appended to the stream. In other words, * this will restore default behaviour. + * \returns Previous instruction pointer */ - void endInsertion() { - m_ptr = m_code.size(); + size_t endInsertion() { + return std::exchange(m_ptr, m_code.size()); } private: diff --git a/src/spirv/spirv_instruction.h b/src/spirv/spirv_instruction.h index 061d5ab7..ada816e7 100644 --- a/src/spirv/spirv_instruction.h +++ b/src/spirv/spirv_instruction.h @@ -109,7 +109,7 @@ namespace dxvk { : m_code (length != 0 ? code : nullptr), m_offset(length != 0 ? offset : 0), m_length(length) { - if ((length >= 5) && (m_code[0] == spv::MagicNumber)) + if ((length >= 5) && (offset == 0) && (m_code[0] == spv::MagicNumber)) this->advance(5); } @@ -118,6 +118,12 @@ namespace dxvk { return *this; } + SpirvInstructionIterator operator ++ (int) { + SpirvInstructionIterator result = *this; + this->advance(SpirvInstruction(m_code, m_offset, m_length).length()); + return result; + } + SpirvInstruction operator * () const { return SpirvInstruction(m_code, m_offset, m_length); }