Commit 5655b849 by Jamie Madill Committed by Commit Bot

D3D11: Fix integer pow workaround for nested pows.

For some nested pow expressions, queueing two node replacements in the same tree traversal would mangle tree, resulting in invalid code. Fix this by iterating over the tree until no replacements are found, and doing one replacement each iteration. BUG=angleproject:851 Change-Id: Ie08ab23f4bfe3d5f32726856afc61ff1f3d6c789 Reviewed-on: https://chromium-review.googlesource.com/365400Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 1e0ea4f5
...@@ -27,6 +27,9 @@ class Traverser : public TIntermTraverser ...@@ -27,6 +27,9 @@ class Traverser : public TIntermTraverser
private: private:
Traverser(); Traverser();
bool visitAggregate(Visit visit, TIntermAggregate *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override;
void nextIteration();
bool mFound = false;
}; };
// static // static
...@@ -34,16 +37,34 @@ void Traverser::Apply(TIntermNode *root, unsigned int *tempIndex) ...@@ -34,16 +37,34 @@ void Traverser::Apply(TIntermNode *root, unsigned int *tempIndex)
{ {
Traverser traverser; Traverser traverser;
traverser.useTemporaryIndex(tempIndex); traverser.useTemporaryIndex(tempIndex);
root->traverse(&traverser); do
traverser.updateTree(); {
traverser.nextIteration();
root->traverse(&traverser);
if (traverser.mFound)
{
traverser.updateTree();
}
} while (traverser.mFound);
} }
Traverser::Traverser() : TIntermTraverser(true, false, false) Traverser::Traverser() : TIntermTraverser(true, false, false)
{ {
} }
void Traverser::nextIteration()
{
mFound = false;
nextTemporaryIndex();
}
bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (mFound)
{
return false;
}
// Test 0: skip non-pow operators. // Test 0: skip non-pow operators.
if (node->getOp() != EOpPow) if (node->getOp() != EOpPow)
{ {
...@@ -123,7 +144,8 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -123,7 +144,8 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
} }
queueReplacement(node, current, OriginalNode::IS_DROPPED); queueReplacement(node, current, OriginalNode::IS_DROPPED);
return true; mFound = true;
return false;
} }
} // anonymous namespace } // anonymous namespace
......
...@@ -2158,6 +2158,33 @@ TEST_P(GLSLTest, RenderTrisWithPointCoord) ...@@ -2158,6 +2158,33 @@ TEST_P(GLSLTest, RenderTrisWithPointCoord)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// Convers a bug with the integer pow statement workaround.
TEST_P(GLSLTest, NestedPowStatements)
{
const std::string &vert =
"attribute vec2 position;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position, 0, 1);\n"
"}";
const std::string &frag =
"precision mediump float;\n"
"float func(float v)\n"
"{\n"
" float f1 = pow(v, 2.0);\n"
" return pow(f1 + v, 2.0);\n"
"}\n"
"void main()\n"
"{\n"
" float v = func(2.0);\n"
" gl_FragColor = abs(v - 36.0) < 0.001 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
"}";
ANGLE_GL_PROGRAM(prog, vert, frag);
drawQuad(prog.get(), "position", 0.5f);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// 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.
ANGLE_INSTANTIATE_TEST(GLSLTest, ANGLE_INSTANTIATE_TEST(GLSLTest,
ES2_D3D9(), ES2_D3D9(),
......
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