Commit 2f490f06 by Nicolas Capens Committed by Nicolas Capens

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/22248Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 42e8e54e
...@@ -1859,8 +1859,6 @@ namespace glsl ...@@ -1859,8 +1859,6 @@ namespace glsl
if(loop.isDeterministic()) if(loop.isDeterministic())
{ {
deterministicVariables.insert(loop.index->getId()); deterministicVariables.insert(loop.index->getId());
emit(sw::Shader::OPCODE_TEST);
} }
if(node->getType() == ELoopDoWhile) if(node->getType() == ELoopDoWhile)
...@@ -1926,10 +1924,7 @@ namespace glsl ...@@ -1926,10 +1924,7 @@ namespace glsl
body->traverse(this); body->traverse(this);
} }
if(loop.isDeterministic()) emit(sw::Shader::OPCODE_TEST);
{
emit(sw::Shader::OPCODE_TEST);
}
if(expression) if(expression)
{ {
......
...@@ -832,11 +832,6 @@ namespace sw ...@@ -832,11 +832,6 @@ namespace sw
Int4 PixelProgram::enableMask(const Shader::Instruction *instruction) Int4 PixelProgram::enableMask(const Shader::Instruction *instruction)
{ {
if(whileTest)
{
return Int4(0xFFFFFFFF);
}
Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF); Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
if(shader->containsBreakInstruction() && instruction->analysisBreak) if(shader->containsBreakInstruction() && instruction->analysisBreak)
...@@ -1397,7 +1392,8 @@ namespace sw ...@@ -1397,7 +1392,8 @@ namespace sw
void PixelProgram::TEST() void PixelProgram::TEST()
{ {
whileTest = true; enableContinue = restoreContinue.back();
restoreContinue.pop_back();
} }
void PixelProgram::CALL(int labelIndex, int callSiteIndex) void PixelProgram::CALL(int labelIndex, int callSiteIndex)
...@@ -1576,7 +1572,6 @@ namespace sw ...@@ -1576,7 +1572,6 @@ namespace sw
Nucleus::setInsertBlock(endBlock); Nucleus::setInsertBlock(endBlock);
enableIndex--; enableIndex--;
whileTest = false;
} }
void PixelProgram::ENDSWITCH() void PixelProgram::ENDSWITCH()
...@@ -1760,12 +1755,11 @@ namespace sw ...@@ -1760,12 +1755,11 @@ namespace sw
loopRepEndBlock[loopRepDepth] = endBlock; loopRepEndBlock[loopRepDepth] = endBlock;
Int4 restoreBreak = enableBreak; Int4 restoreBreak = enableBreak;
Int4 restoreContinue = enableContinue; restoreContinue.push_back(enableContinue);
// TODO: jump(testBlock) // TODO: jump(testBlock)
Nucleus::createBr(testBlock); Nucleus::createBr(testBlock);
Nucleus::setInsertBlock(testBlock); Nucleus::setInsertBlock(testBlock);
enableContinue = restoreContinue;
const Vector4f &src = fetchRegister(temporaryRegister); const Vector4f &src = fetchRegister(temporaryRegister);
Int4 condition = As<Int4>(src.x); Int4 condition = As<Int4>(src.x);
...@@ -1783,7 +1777,6 @@ namespace sw ...@@ -1783,7 +1777,6 @@ namespace sw
Nucleus::setInsertBlock(loopBlock); Nucleus::setInsertBlock(loopBlock);
loopRepDepth++; loopRepDepth++;
whileTest = false;
} }
void PixelProgram::SWITCH() void PixelProgram::SWITCH()
......
...@@ -25,7 +25,7 @@ namespace sw ...@@ -25,7 +25,7 @@ namespace sw
public: public:
PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) : PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :
PixelRoutine(state, shader), r(shader->indirectAddressableTemporaries), PixelRoutine(state, shader), r(shader->indirectAddressableTemporaries),
loopDepth(-1), ifDepth(0), loopRepDepth(0), currentLabel(-1), whileTest(false) loopDepth(-1), ifDepth(0), loopRepDepth(0), currentLabel(-1)
{ {
for(int i = 0; i < 2048; ++i) for(int i = 0; i < 2048; ++i)
{ {
...@@ -155,7 +155,6 @@ namespace sw ...@@ -155,7 +155,6 @@ namespace sw
int ifDepth; int ifDepth;
int loopRepDepth; int loopRepDepth;
int currentLabel; int currentLabel;
bool whileTest;
BasicBlock *ifFalseBlock[24 + 24]; BasicBlock *ifFalseBlock[24 + 24];
BasicBlock *loopRepTestBlock[4]; BasicBlock *loopRepTestBlock[4];
...@@ -164,6 +163,7 @@ namespace sw ...@@ -164,6 +163,7 @@ namespace sw
std::vector<BasicBlock*> callRetBlock[2048]; std::vector<BasicBlock*> callRetBlock[2048];
BasicBlock *returnBlock; BasicBlock *returnBlock;
bool isConditionalIf[24 + 24]; bool isConditionalIf[24 + 24];
std::vector<Int4> restoreContinue;
}; };
} }
......
...@@ -29,7 +29,6 @@ namespace sw ...@@ -29,7 +29,6 @@ namespace sw
ifDepth = 0; ifDepth = 0;
loopRepDepth = 0; loopRepDepth = 0;
currentLabel = -1; currentLabel = -1;
whileTest = false;
for(int i = 0; i < 2048; i++) for(int i = 0; i < 2048; i++)
{ {
...@@ -978,11 +977,6 @@ namespace sw ...@@ -978,11 +977,6 @@ namespace sw
Int4 VertexProgram::enableMask(const Shader::Instruction *instruction) Int4 VertexProgram::enableMask(const Shader::Instruction *instruction)
{ {
if(whileTest)
{
return Int4(0xFFFFFFFF);
}
Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF); Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
if(shader->containsBreakInstruction() && instruction->analysisBreak) if(shader->containsBreakInstruction() && instruction->analysisBreak)
...@@ -1110,7 +1104,8 @@ namespace sw ...@@ -1110,7 +1104,8 @@ namespace sw
void VertexProgram::TEST() void VertexProgram::TEST()
{ {
whileTest = true; enableContinue = restoreContinue.back();
restoreContinue.pop_back();
} }
void VertexProgram::CALL(int labelIndex, int callSiteIndex) void VertexProgram::CALL(int labelIndex, int callSiteIndex)
...@@ -1289,7 +1284,6 @@ namespace sw ...@@ -1289,7 +1284,6 @@ namespace sw
Nucleus::setInsertBlock(endBlock); Nucleus::setInsertBlock(endBlock);
enableIndex--; enableIndex--;
whileTest = false;
} }
void VertexProgram::ENDSWITCH() void VertexProgram::ENDSWITCH()
...@@ -1474,12 +1468,11 @@ namespace sw ...@@ -1474,12 +1468,11 @@ namespace sw
loopRepEndBlock[loopRepDepth] = endBlock; loopRepEndBlock[loopRepDepth] = endBlock;
Int4 restoreBreak = enableBreak; Int4 restoreBreak = enableBreak;
Int4 restoreContinue = enableContinue; restoreContinue.push_back(enableContinue);
// TODO: jump(testBlock) // TODO: jump(testBlock)
Nucleus::createBr(testBlock); Nucleus::createBr(testBlock);
Nucleus::setInsertBlock(testBlock); Nucleus::setInsertBlock(testBlock);
enableContinue = restoreContinue;
const Vector4f &src = fetchRegister(temporaryRegister); const Vector4f &src = fetchRegister(temporaryRegister);
Int4 condition = As<Int4>(src.x); Int4 condition = As<Int4>(src.x);
...@@ -1497,7 +1490,6 @@ namespace sw ...@@ -1497,7 +1490,6 @@ namespace sw
Nucleus::setInsertBlock(loopBlock); Nucleus::setInsertBlock(loopBlock);
loopRepDepth++; loopRepDepth++;
whileTest = false;
} }
void VertexProgram::SWITCH() void VertexProgram::SWITCH()
......
...@@ -124,7 +124,6 @@ namespace sw ...@@ -124,7 +124,6 @@ namespace sw
int ifDepth; int ifDepth;
int loopRepDepth; int loopRepDepth;
int currentLabel; int currentLabel;
bool whileTest;
BasicBlock *ifFalseBlock[24 + 24]; BasicBlock *ifFalseBlock[24 + 24];
BasicBlock *loopRepTestBlock[4]; BasicBlock *loopRepTestBlock[4];
...@@ -133,6 +132,7 @@ namespace sw ...@@ -133,6 +132,7 @@ namespace sw
std::vector<BasicBlock*> callRetBlock[2048]; std::vector<BasicBlock*> callRetBlock[2048];
BasicBlock *returnBlock; BasicBlock *returnBlock;
bool isConditionalIf[24 + 24]; bool isConditionalIf[24 + 24];
std::vector<Int4> restoreContinue;
}; };
} }
......
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