Commit 8a587714 by Nicolas Capens Committed by Nicolas Capens

Fix deterministic loops within conditional blocks.

Deterministic loops use the first scalar of the SIMD register used as the loop index, for addressing arrays. This means that operations on the index register should not be masked (i.e. it should be treated as a scalar). Previously we were still masking it based on conditional statements, and we didn't disable the masking altogether (using the 'TEST' instruction) for the loop initialization and initial test. Also, non-deterministic loops should not have any execution masking disabled, so don't emit 'TEST' for them. Bug swiftshader:93 Bug b/118009174 Change-Id: I661de83df931d85f806d2ec5c9e1b2f20a9b5567 Reviewed-on: https://swiftshader-review.googlesource.com/c/21788Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 082dfec9
......@@ -15,7 +15,7 @@
#define MAJOR_VERSION 4
#define MINOR_VERSION 1
#define BUILD_VERSION 0
#define BUILD_REVISION 4
#define BUILD_REVISION 5
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -1848,11 +1848,6 @@ namespace glsl
return false;
}
if(loop.isDeterministic())
{
deterministicVariables.insert(loop.index->getId());
}
bool unroll = (loop.iterations <= 4);
TIntermNode *init = node->getInit();
......@@ -1861,6 +1856,13 @@ namespace glsl
TIntermNode *body = node->getBody();
Constant True(true);
if(loop.isDeterministic())
{
deterministicVariables.insert(loop.index->getId());
emit(sw::Shader::OPCODE_TEST);
}
if(node->getType() == ELoopDoWhile)
{
Temporary iterate(this);
......@@ -1924,7 +1926,10 @@ namespace glsl
body->traverse(this);
}
emit(sw::Shader::OPCODE_TEST);
if(loop.isDeterministic())
{
emit(sw::Shader::OPCODE_TEST);
}
if(expression)
{
......
......@@ -832,24 +832,26 @@ namespace sw
Int4 PixelProgram::enableMask(const Shader::Instruction *instruction)
{
if(whileTest)
{
return Int4(0xFFFFFFFF);
}
Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
if(!whileTest)
if(shader->containsBreakInstruction() && instruction->analysisBreak)
{
if(shader->containsBreakInstruction() && instruction->analysisBreak)
{
enable &= enableBreak;
}
enable &= enableBreak;
}
if(shader->containsContinueInstruction() && instruction->analysisContinue)
{
enable &= enableContinue;
}
if(shader->containsContinueInstruction() && instruction->analysisContinue)
{
enable &= enableContinue;
}
if(shader->containsLeaveInstruction() && instruction->analysisLeave)
{
enable &= enableLeave;
}
if(shader->containsLeaveInstruction() && instruction->analysisLeave)
{
enable &= enableLeave;
}
return enable;
......@@ -1781,6 +1783,7 @@ namespace sw
Nucleus::setInsertBlock(loopBlock);
loopRepDepth++;
whileTest = false;
}
void PixelProgram::SWITCH()
......
......@@ -978,24 +978,26 @@ namespace sw
Int4 VertexProgram::enableMask(const Shader::Instruction *instruction)
{
if(whileTest)
{
return Int4(0xFFFFFFFF);
}
Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
if(!whileTest)
if(shader->containsBreakInstruction() && instruction->analysisBreak)
{
if(shader->containsBreakInstruction() && instruction->analysisBreak)
{
enable &= enableBreak;
}
enable &= enableBreak;
}
if(shader->containsContinueInstruction() && instruction->analysisContinue)
{
enable &= enableContinue;
}
if(shader->containsContinueInstruction() && instruction->analysisContinue)
{
enable &= enableContinue;
}
if(shader->containsLeaveInstruction() && instruction->analysisLeave)
{
enable &= enableLeave;
}
if(shader->containsLeaveInstruction() && instruction->analysisLeave)
{
enable &= enableLeave;
}
return enable;
......@@ -1495,6 +1497,7 @@ namespace sw
Nucleus::setInsertBlock(loopBlock);
loopRepDepth++;
whileTest = false;
}
void VertexProgram::SWITCH()
......
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