Commit 213a8ce6 by Ben Clayton

SpirvShader: Implement OpSwitch

Tests: dEQP-VK.spirv_assembly.instruction.compute.* Tests: dEQP-VK.spirv_assembly.instruction.graphics.* Bug: b/128527271 Change-Id: I7ba31ca504a582a4d36d25ef2747fb1c1607bade Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27775 Presubmit-Ready: Ben Clayton <bclayton@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 9fd02e0d
...@@ -1179,6 +1179,8 @@ namespace sw ...@@ -1179,6 +1179,8 @@ namespace sw
case Block::Simple: case Block::Simple:
case Block::StructuredBranchConditional: case Block::StructuredBranchConditional:
case Block::UnstructuredBranchConditional: case Block::UnstructuredBranchConditional:
case Block::StructuredSwitch:
case Block::UnstructuredSwitch:
if (id != mainBlockId) if (id != mainBlockId)
{ {
// Emit all preceeding blocks and set the activeLaneMask. // Emit all preceeding blocks and set the activeLaneMask.
...@@ -1404,6 +1406,9 @@ namespace sw ...@@ -1404,6 +1406,9 @@ namespace sw
case spv::OpBranchConditional: case spv::OpBranchConditional:
return EmitBranchConditional(insn, state); return EmitBranchConditional(insn, state);
case spv::OpSwitch:
return EmitSwitch(insn, state);
case spv::OpUnreachable: case spv::OpUnreachable:
return EmitUnreachable(insn, state); return EmitUnreachable(insn, state);
...@@ -2638,6 +2643,39 @@ namespace sw ...@@ -2638,6 +2643,39 @@ namespace sw
return EmitResult::Terminator; return EmitResult::Terminator;
} }
SpirvShader::EmitResult SpirvShader::EmitSwitch(InsnIterator insn, EmitState *state) const
{
auto block = getBlock(state->currentBlock);
ASSERT(block.branchInstruction == insn);
auto selId = Object::ID(block.branchInstruction.word(1));
auto sel = GenericValue(this, state->routine, selId);
ASSERT_MSG(getType(getObject(selId).type).sizeInComponents == 1, "Selector must be a scalar");
auto numCases = (block.branchInstruction.wordCount() - 3) / 2;
// TODO: Optimize for case where all lanes take same path.
SIMD::Int defaultLaneMask = state->activeLaneMask();
// Gather up the case label matches and calculate defaultLaneMask.
std::vector<RValue<SIMD::Int>> caseLabelMatches;
caseLabelMatches.reserve(numCases);
for (uint32_t i = 0; i < numCases; i++)
{
auto label = block.branchInstruction.word(i * 2 + 3);
auto caseBlockId = Block::ID(block.branchInstruction.word(i * 2 + 4));
auto caseLabelMatch = CmpEQ(sel.Int(0), SIMD::Int(label));
state->addOutputActiveLaneMaskEdge(caseBlockId, caseLabelMatch);
defaultLaneMask &= ~caseLabelMatch;
}
auto defaultBlockId = Block::ID(block.branchInstruction.word(2));
state->addOutputActiveLaneMaskEdge(defaultBlockId, defaultLaneMask);
return EmitResult::Terminator;
}
SpirvShader::EmitResult SpirvShader::EmitUnreachable(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitUnreachable(InsnIterator insn, EmitState *state) const
{ {
......
...@@ -602,6 +602,7 @@ namespace sw ...@@ -602,6 +602,7 @@ namespace sw
EmitResult EmitAll(InsnIterator insn, EmitState *state) const; EmitResult EmitAll(InsnIterator insn, EmitState *state) const;
EmitResult EmitBranch(InsnIterator insn, EmitState *state) const; EmitResult EmitBranch(InsnIterator insn, EmitState *state) const;
EmitResult EmitBranchConditional(InsnIterator insn, EmitState *state) const; EmitResult EmitBranchConditional(InsnIterator insn, EmitState *state) const;
EmitResult EmitSwitch(InsnIterator insn, EmitState *state) const;
EmitResult EmitUnreachable(InsnIterator insn, EmitState *state) const; EmitResult EmitUnreachable(InsnIterator insn, EmitState *state) const;
EmitResult EmitReturn(InsnIterator insn, EmitState *state) const; EmitResult EmitReturn(InsnIterator insn, EmitState *state) const;
EmitResult EmitPhi(InsnIterator insn, EmitState *state) const; EmitResult EmitPhi(InsnIterator insn, EmitState *state) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment