Fix 'continue' in GLSL loops.
The test expression of a loop is placed between the TEST and ENDWHILE
shader assembly instructions, and should no longer be affected by the
cleared execution mask of a continue statement. Thus TEST should always
be emitted, even for non-deterministic loops.
Other masks should still apply, and work recursively, so the
'whileTest' boolean to disable all masks during the test expression
evaluation has been replaced with a stack to restore the continue mask
at the TEST instruction.
Bug swiftshader:93
Bug b/118009174
Change-Id: I505c48f0344e61a6c31f81d26e93bc1217a105a2
Reviewed-on: https://swiftshader-review.googlesource.com/c/22248
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp
index 0eb8441..d492c65 100644
--- a/src/Shader/VertexProgram.cpp
+++ b/src/Shader/VertexProgram.cpp
@@ -29,7 +29,6 @@
ifDepth = 0;
loopRepDepth = 0;
currentLabel = -1;
- whileTest = false;
for(int i = 0; i < 2048; i++)
{
@@ -978,11 +977,6 @@
Int4 VertexProgram::enableMask(const Shader::Instruction *instruction)
{
- if(whileTest)
- {
- return Int4(0xFFFFFFFF);
- }
-
Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
if(shader->containsBreakInstruction() && instruction->analysisBreak)
@@ -1110,7 +1104,8 @@
void VertexProgram::TEST()
{
- whileTest = true;
+ enableContinue = restoreContinue.back();
+ restoreContinue.pop_back();
}
void VertexProgram::CALL(int labelIndex, int callSiteIndex)
@@ -1289,7 +1284,6 @@
Nucleus::setInsertBlock(endBlock);
enableIndex--;
- whileTest = false;
}
void VertexProgram::ENDSWITCH()
@@ -1474,12 +1468,11 @@
loopRepEndBlock[loopRepDepth] = endBlock;
Int4 restoreBreak = enableBreak;
- Int4 restoreContinue = enableContinue;
+ restoreContinue.push_back(enableContinue);
// TODO: jump(testBlock)
Nucleus::createBr(testBlock);
Nucleus::setInsertBlock(testBlock);
- enableContinue = restoreContinue;
const Vector4f &src = fetchRegister(temporaryRegister);
Int4 condition = As<Int4>(src.x);
@@ -1497,7 +1490,6 @@
Nucleus::setInsertBlock(loopBlock);
loopRepDepth++;
- whileTest = false;
}
void VertexProgram::SWITCH()