OSDN Git Service

Fix 'continue' in GLSL loops.
authorNicolas Capens <capn@google.com>
Thu, 1 Nov 2018 20:53:36 +0000 (16:53 -0400)
committerNicolas Capens <nicolascapens@google.com>
Fri, 2 Nov 2018 14:07:30 +0000 (14:07 +0000)
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>
src/OpenGL/compiler/OutputASM.cpp
src/Shader/PixelProgram.cpp
src/Shader/PixelProgram.hpp
src/Shader/VertexProgram.cpp
src/Shader/VertexProgram.hpp

index 5fa69f1..5a8bcdf 100644 (file)
@@ -1859,8 +1859,6 @@ namespace glsl
                if(loop.isDeterministic())
                {
                         deterministicVariables.insert(loop.index->getId());
-
-                        emit(sw::Shader::OPCODE_TEST);
                }
 
                if(node->getType() == ELoopDoWhile)
@@ -1926,10 +1924,7 @@ namespace glsl
                                        body->traverse(this);
                                }
 
-                               if(loop.isDeterministic())
-                               {
-                                       emit(sw::Shader::OPCODE_TEST);
-                               }
+                               emit(sw::Shader::OPCODE_TEST);
 
                                if(expression)
                                {
index f81596b..ec0bba0 100644 (file)
@@ -832,11 +832,6 @@ namespace sw
 
        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)
@@ -1397,7 +1392,8 @@ namespace sw
 
        void PixelProgram::TEST()
        {
-               whileTest = true;
+               enableContinue = restoreContinue.back();
+               restoreContinue.pop_back();
        }
 
        void PixelProgram::CALL(int labelIndex, int callSiteIndex)
@@ -1576,7 +1572,6 @@ namespace sw
                Nucleus::setInsertBlock(endBlock);
 
                enableIndex--;
-               whileTest = false;
        }
 
        void PixelProgram::ENDSWITCH()
@@ -1760,12 +1755,11 @@ namespace sw
                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);
@@ -1783,7 +1777,6 @@ namespace sw
                Nucleus::setInsertBlock(loopBlock);
 
                loopRepDepth++;
-               whileTest = false;
        }
 
        void PixelProgram::SWITCH()
index 240938d..0f628bc 100644 (file)
@@ -25,7 +25,7 @@ namespace sw
        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)
                        {
@@ -155,7 +155,6 @@ namespace sw
                int ifDepth;
                int loopRepDepth;
                int currentLabel;
-               bool whileTest;
 
                BasicBlock *ifFalseBlock[24 + 24];
                BasicBlock *loopRepTestBlock[4];
@@ -164,6 +163,7 @@ namespace sw
                std::vector<BasicBlock*> callRetBlock[2048];
                BasicBlock *returnBlock;
                bool isConditionalIf[24 + 24];
+               std::vector<Int4> restoreContinue;
        };
 }
 
index 0eb8441..d492c65 100644 (file)
@@ -29,7 +29,6 @@ namespace sw
                ifDepth = 0;
                loopRepDepth = 0;
                currentLabel = -1;
-               whileTest = false;
 
                for(int i = 0; i < 2048; i++)
                {
@@ -978,11 +977,6 @@ namespace sw
 
        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 @@ namespace sw
 
        void VertexProgram::TEST()
        {
-               whileTest = true;
+               enableContinue = restoreContinue.back();
+               restoreContinue.pop_back();
        }
 
        void VertexProgram::CALL(int labelIndex, int callSiteIndex)
@@ -1289,7 +1284,6 @@ namespace sw
                Nucleus::setInsertBlock(endBlock);
 
                enableIndex--;
-               whileTest = false;
        }
 
        void VertexProgram::ENDSWITCH()
@@ -1474,12 +1468,11 @@ namespace sw
                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 @@ namespace sw
                Nucleus::setInsertBlock(loopBlock);
 
                loopRepDepth++;
-               whileTest = false;
        }
 
        void VertexProgram::SWITCH()
index 3c4199c..437c881 100644 (file)
@@ -124,7 +124,6 @@ namespace sw
                int ifDepth;
                int loopRepDepth;
                int currentLabel;
-               bool whileTest;
 
                BasicBlock *ifFalseBlock[24 + 24];
                BasicBlock *loopRepTestBlock[4];
@@ -133,6 +132,7 @@ namespace sw
                std::vector<BasicBlock*> callRetBlock[2048];
                BasicBlock *returnBlock;
                bool isConditionalIf[24 + 24];
+               std::vector<Int4> restoreContinue;
        };
 }