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>
if(loop.isDeterministic())
{
deterministicVariables.insert(loop.index->getId());
-
- emit(sw::Shader::OPCODE_TEST);
}
if(node->getType() == ELoopDoWhile)
body->traverse(this);
}
- if(loop.isDeterministic())
- {
- emit(sw::Shader::OPCODE_TEST);
- }
+ emit(sw::Shader::OPCODE_TEST);
if(expression)
{
Int4 PixelProgram::enableMask(const Shader::Instruction *instruction)
{
- if(whileTest)
- {
- return Int4(0xFFFFFFFF);
- }
-
Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
if(shader->containsBreakInstruction() && instruction->analysisBreak)
void PixelProgram::TEST()
{
- whileTest = true;
+ enableContinue = restoreContinue.back();
+ restoreContinue.pop_back();
}
void PixelProgram::CALL(int labelIndex, int callSiteIndex)
Nucleus::setInsertBlock(endBlock);
enableIndex--;
- whileTest = false;
}
void PixelProgram::ENDSWITCH()
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);
Nucleus::setInsertBlock(loopBlock);
loopRepDepth++;
- whileTest = false;
}
void PixelProgram::SWITCH()
public:
PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :
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)
{
int ifDepth;
int loopRepDepth;
int currentLabel;
- bool whileTest;
BasicBlock *ifFalseBlock[24 + 24];
BasicBlock *loopRepTestBlock[4];
std::vector<BasicBlock*> callRetBlock[2048];
BasicBlock *returnBlock;
bool isConditionalIf[24 + 24];
+ std::vector<Int4> restoreContinue;
};
}
ifDepth = 0;
loopRepDepth = 0;
currentLabel = -1;
- whileTest = false;
for(int i = 0; i < 2048; i++)
{
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)
void VertexProgram::TEST()
{
- whileTest = true;
+ enableContinue = restoreContinue.back();
+ restoreContinue.pop_back();
}
void VertexProgram::CALL(int labelIndex, int callSiteIndex)
Nucleus::setInsertBlock(endBlock);
enableIndex--;
- whileTest = false;
}
void VertexProgram::ENDSWITCH()
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);
Nucleus::setInsertBlock(loopBlock);
loopRepDepth++;
- whileTest = false;
}
void VertexProgram::SWITCH()
int ifDepth;
int loopRepDepth;
int currentLabel;
- bool whileTest;
BasicBlock *ifFalseBlock[24 + 24];
BasicBlock *loopRepTestBlock[4];
std::vector<BasicBlock*> callRetBlock[2048];
BasicBlock *returnBlock;
bool isConditionalIf[24 + 24];
+ std::vector<Int4> restoreContinue;
};
}