Commit 36fd100d by Corentin Wallez Committed by Commit Bot

GLSLTest: test interaction of declaration splitting with other passes

In TranslatorHLSL a number of AST simplifications are done, that must happen in a precise order for things to be correct: - First for-loops must be split - Then multideclarations must be split - Finally comma operators must be split This adds tests for interaction between this passes to make sure they are done in the right order. BUG=668028 Change-Id: I306915b51011bb5467d117352becfd60cbe77be4 Reviewed-on: https://chromium-review.googlesource.com/417989 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 327411e8
...@@ -479,6 +479,17 @@ TIntermTyped *TIntermTyped::CreateZero(const TType &type) ...@@ -479,6 +479,17 @@ TIntermTyped *TIntermTyped::CreateZero(const TType &type)
return constructor; return constructor;
} }
// static
TIntermTyped *TIntermTyped::CreateBool(bool value)
{
TConstantUnion *u = new TConstantUnion[1];
u[0].setBConst(value);
TType type(EbtBool, EbpUndefined, EvqConst, 1);
TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
return node;
}
TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node) TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
{ {
mUnionArrayPointer = node.mUnionArrayPointer; mUnionArrayPointer = node.mUnionArrayPointer;
......
...@@ -176,6 +176,7 @@ class TIntermTyped : public TIntermNode ...@@ -176,6 +176,7 @@ class TIntermTyped : public TIntermNode
static TIntermTyped *CreateIndexNode(int index); static TIntermTyped *CreateIndexNode(int index);
static TIntermTyped *CreateZero(const TType &type); static TIntermTyped *CreateZero(const TType &type);
static TIntermTyped *CreateBool(bool value);
protected: protected:
TType mType; TType mType;
......
...@@ -224,29 +224,54 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node) ...@@ -224,29 +224,54 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
// { // {
// init; // init;
// bool s0 = expr; // bool s0 = expr;
// while (s0) { { body; } exprB; s0 = expr; } // while (s0) {
// { body; }
// exprB;
// s0 = expr;
// }
// } // }
TIntermBlock *loopScope = new TIntermBlock(); TIntermBlock *loopScope = new TIntermBlock();
TIntermSequence *loopScopeSequence = loopScope->getSequence();
// Insert "init;"
if (node->getInit()) if (node->getInit())
{ {
loopScope->getSequence()->push_back(node->getInit()); loopScopeSequence->push_back(node->getInit());
}
// Insert "bool s0 = expr;" if applicable, "bool s0 = true;" otherwise
TIntermTyped *conditionInitializer = nullptr;
if (node->getCondition())
{
conditionInitializer = node->getCondition()->deepCopy();
}
else
{
conditionInitializer = TIntermTyped::CreateBool(true);
} }
loopScope->getSequence()->push_back( loopScopeSequence->push_back(createTempInitDeclaration(conditionInitializer));
createTempInitDeclaration(node->getCondition()->deepCopy()));
// Insert "{ body; }" in the while loop
TIntermBlock *whileLoopBody = new TIntermBlock(); TIntermBlock *whileLoopBody = new TIntermBlock();
if (node->getBody()) if (node->getBody())
{ {
whileLoopBody->getSequence()->push_back(node->getBody()); whileLoopBody->getSequence()->push_back(node->getBody());
} }
// Insert "exprB;" in the while loop
if (node->getExpression()) if (node->getExpression())
{ {
whileLoopBody->getSequence()->push_back(node->getExpression()); whileLoopBody->getSequence()->push_back(node->getExpression());
} }
whileLoopBody->getSequence()->push_back( // Insert "s0 = expr;" in the while loop
createTempAssignment(node->getCondition()->deepCopy())); if (node->getCondition())
{
whileLoopBody->getSequence()->push_back(
createTempAssignment(node->getCondition()->deepCopy()));
}
// Create "while(s0) { whileLoopBody }"
TIntermLoop *whileLoop = new TIntermLoop( TIntermLoop *whileLoop = new TIntermLoop(
ELoopWhile, nullptr, createTempSymbol(node->getCondition()->getType()), nullptr, ELoopWhile, nullptr, createTempSymbol(conditionInitializer->getType()), nullptr,
whileLoopBody); whileLoopBody);
loopScope->getSequence()->push_back(whileLoop); loopScope->getSequence()->push_back(whileLoop);
queueReplacementWithParent(getAncestorNode(1), node, loopScope, queueReplacementWithParent(getAncestorNode(1), node, loopScope,
......
...@@ -2426,6 +2426,87 @@ TEST_P(GLSLTest_ES3, LiteralNegativeInfinityOutput) ...@@ -2426,6 +2426,87 @@ TEST_P(GLSLTest_ES3, LiteralNegativeInfinityOutput)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// The following MultipleDeclaration* tests are testing TranslatorHLSL specific simplification
// passes. Because the interaction of multiple passes must be tested, it is difficult to write
// a unittest for them. Instead we add the tests as end2end so will in particular test
// TranslatorHLSL when run on Windows.
// Test that passes splitting multiple declarations and comma operators are correctly ordered.
TEST_P(GLSLTest_ES3, MultipleDeclarationWithCommaOperator)
{
const std::string &fragmentShader =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : 0.0), 1.0);\n"
" color = vec4(b);\n"
"}\n";
ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
}
// Test that passes splitting multiple declarations and comma operators and for loops are
// correctly ordered.
TEST_P(GLSLTest_ES3, MultipleDeclarationWithCommaOperatorInForLoop)
{
const std::string &fragmentShader =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" for(float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : 0.0), 1.0); a < 10.0; a++)\n"
" {\n"
" b += 1.0;\n"
" color = vec4(b);\n"
" }\n"
"}\n";
ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
}
// Test that splitting multiple declaration in for loops works with no loop condition
TEST_P(GLSLTest_ES3, MultipleDeclarationInForLoopEmptyCondition)
{
const std::string &fragmentShader =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" for(float a = 0.0, b = 1.0;; a++)\n"
" {\n"
" b += 1.0;\n"
" if (a > 10.0) {break;}\n"
" color = vec4(b);\n"
" }\n"
"}\n";
ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
}
// Test that splitting multiple declaration in for loops works with no loop expression
TEST_P(GLSLTest_ES3, MultipleDeclarationInForLoopEmptyExpression)
{
const std::string &fragmentShader =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" for(float a = 0.0, b = 1.0; a < 10.0;)\n"
" {\n"
" b += 1.0;\n"
" a += 1.0;\n"
" color = vec4(b);\n"
" }\n"
"}\n";
ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
}
} // anonymous namespace } // anonymous namespace
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
......
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