Commit 0e976bca by Ben Clayton

SpirvShader: Fixes for complex loops.

Combine all the active lane masks for the merge block. Previously this was only using the lane mask of the last loop iteration. Loop phis were being overridden even for disabled lanes. Now fixed. Made EmitBranch() use addActiveLaneMaskEdge(). This is effectively a noop change, but keeps the code more consistent. dEQP-VK.glsl.switch.switch_in_do_while_loop_dynamic_vertex still seems broken, which I'm investigating. Tests: dEQP-VK.glsl.switch.* Bug: b/128527271 Change-Id: I49bafe5cdb49d6878dde98134f9cbb9a3ad4d384 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31268 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Presubmit-Ready: Ben Clayton <bclayton@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 40a6ed8d
......@@ -2076,6 +2076,14 @@ namespace sw
}
}
// mergeActiveLaneMasks contains edge lane masks for the merge block.
// This is the union of all edge masks across all iterations of the loop.
std::unordered_map<Block::ID, SIMD::Int> mergeActiveLaneMasks;
for (auto in : getBlock(block.mergeBlock).ins)
{
mergeActiveLaneMasks.emplace(in, SIMD::Int(0));
}
// Generate an alloca for each of the loop's phis.
// These will be primed with the incoming, non back edge Phi values
// before the loop, and then updated just before the loop jumps back to
......@@ -2192,6 +2200,17 @@ namespace sw
}
}
// Add active lanes to the merge lane mask.
for (auto in : getBlock(block.mergeBlock).ins)
{
auto edge = Block::Edge{in, block.mergeBlock};
auto it = state->edgeActiveLaneMasks.find(edge);
if (it != state->edgeActiveLaneMasks.end())
{
mergeActiveLaneMasks[in] |= it->second;
}
}
// Update loop phi values
for (auto &phi : phis)
{
......@@ -2201,7 +2220,7 @@ namespace sw
auto &type = getType(getObject(phi.phiId).type);
for (unsigned int i = 0u; i < type.sizeInComponents; i++)
{
phi.storage[i] = val.Int(i);
phi.storage[i] = (val.Int(i) & loopActiveLaneMask) | (phi.storage[i] & ~loopActiveLaneMask);
}
}
}
......@@ -2214,6 +2233,10 @@ namespace sw
// Continue emitting from the merge block.
Nucleus::setInsertBlock(mergeBasicBlock);
state->pending->emplace(block.mergeBlock);
for (auto it : mergeActiveLaneMasks)
{
state->addActiveLaneMaskEdge(it.first, block.mergeBlock, it.second);
}
}
SpirvShader::EmitResult SpirvShader::EmitInstruction(InsnIterator insn, EmitState *state) const
......@@ -4501,8 +4524,7 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitBranch(InsnIterator insn, EmitState *state) const
{
auto target = Block::ID(insn.word(1));
auto edge = Block::Edge{state->currentBlock, target};
state->edgeActiveLaneMasks.emplace(edge, state->activeLaneMask());
state->addActiveLaneMaskEdge(state->currentBlock, target, state->activeLaneMask());
return EmitResult::Terminator;
}
......
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