diff --git a/SPIRV/SPVRemapper.cpp b/SPIRV/SPVRemapper.cpp index 9b127050..e8031d02 100755 --- a/SPIRV/SPVRemapper.cpp +++ b/SPIRV/SPVRemapper.cpp @@ -464,8 +464,8 @@ namespace spv { { const auto instructionStart = word; const unsigned wordCount = asWordCount(instructionStart); - const spv::Op opCode = asOpCode(instructionStart); const int nextInst = word++ + wordCount; + spv::Op opCode = asOpCode(instructionStart); if (nextInst > int(spv.size())) error("spir instruction terminated too early"); @@ -506,6 +506,18 @@ namespace spv { // Store IDs from instruction in our map for (int op = 0; numOperands > 0; ++op, --numOperands) { + // SpecConstantOp is special: it includes the operands of another opcode which is + // given as a literal in the 3rd word. We will switch over to pretending that the + // opcode being processed is the literal opcode value of the SpecConstantOp. See the + // SPIRV spec for details. This way we will handle IDs and literals as appropriate for + // the embedded op. + if (opCode == spv::OpSpecConstantOp) { + if (op == 0) { + opCode = asOpCode(word++); // this is the opcode embedded in the SpecConstantOp. + --numOperands; + } + } + switch (spv::InstructionDesc[opCode].operands.getClass(op)) { case spv::OperandId: case spv::OperandScope: diff --git a/Test/baseResults/remap.specconst.comp.out b/Test/baseResults/remap.specconst.comp.out new file mode 100644 index 00000000..141c1a47 --- /dev/null +++ b/Test/baseResults/remap.specconst.comp.out @@ -0,0 +1,33 @@ +remap.specconst.comp +Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 16104 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint GLCompute 5663 "main" + ExecutionMode 5663 LocalSize 1 1 1 + Decorate 2 SpecId 0 + Decorate 3 SpecId 1 + Decorate 4 SpecId 2 + Decorate 5 BuiltIn WorkgroupSize + 8: TypeVoid + 1282: TypeFunction 8 + 11: TypeInt 32 0 + 2: 11(int) SpecConstant 1 + 3: 11(int) SpecConstant 1 + 4: 11(int) SpecConstant 1 + 20: TypeVector 11(int) 3 + 5: 20(ivec3) SpecConstantComposite 2 3 4 + 6: 11(int) SpecConstantOp 81 5 0 + 7: 11(int) SpecConstantOp 81 5 1(GLSL.std.450) + 9: 11(int) SpecConstantOp 81 5 2 + 10: 11(int) SpecConstantOp 132 7 9 + 12: 11(int) SpecConstantOp 128 6 10 + 5663: 8 Function None 1282 + 16103: Label + Return + FunctionEnd diff --git a/gtests/Remap.FromFile.cpp b/gtests/Remap.FromFile.cpp index 9f25a6f2..50bce8e3 100644 --- a/gtests/Remap.FromFile.cpp +++ b/gtests/Remap.FromFile.cpp @@ -89,6 +89,7 @@ INSTANTIATE_TEST_CASE_P( { "remap.basic.everything.frag", "main", Source::GLSL, spv::spirvbin_t::DO_EVERYTHING }, { "remap.basic.dcefunc.frag", "main", Source::GLSL, spv::spirvbin_t::DCE_FUNCS }, { "remap.basic.strip.frag", "main", Source::GLSL, spv::spirvbin_t::STRIP }, + { "remap.specconst.comp", "main", Source::GLSL, spv::spirvbin_t::DO_EVERYTHING }, { "remap.switch.none.frag", "main", Source::GLSL, spv::spirvbin_t::NONE }, { "remap.switch.everything.frag", "main", Source::GLSL, spv::spirvbin_t::DO_EVERYTHING }, { "remap.literal64.none.spv", "main", Source::GLSL, spv::spirvbin_t::NONE },