Remapper: handle embedded opcode in OpSpecConstantOp

OpSpecConstantOp contains an embedded opcode which is given as a literal
argument to the OpSpecConstantOp.  The subsequent arguments are as the
embedded op would expect, which may be a mixture of IDs and literals.  This
adds support for that to the remapper binary parser.  Upon seeing such an
embedded op, the parser flips over to parsing the argument list as
appropriate for that opcode.

Fixes #882.
This commit is contained in:
LoopDawg 2017-05-18 16:13:04 -06:00
parent 24e895b4a3
commit 65c2eed65d
3 changed files with 47 additions and 1 deletions

View File

@ -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:

View File

@ -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

View File

@ -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 },