summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/compiler_tests/RemovePow_test.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/angle/src/tests/compiler_tests/RemovePow_test.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/angle/src/tests/compiler_tests/RemovePow_test.cpp')
-rwxr-xr-xgfx/angle/src/tests/compiler_tests/RemovePow_test.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/compiler_tests/RemovePow_test.cpp b/gfx/angle/src/tests/compiler_tests/RemovePow_test.cpp
new file mode 100755
index 000000000..8367ac745
--- /dev/null
+++ b/gfx/angle/src/tests/compiler_tests/RemovePow_test.cpp
@@ -0,0 +1,158 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemovePow_test.cpp:
+// Tests for removing pow() function calls from the AST.
+//
+
+#include "angle_gl.h"
+#include "gtest/gtest.h"
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/NodeSearch.h"
+#include "compiler/translator/TranslatorGLSL.h"
+
+using namespace sh;
+
+class RemovePowTest : public testing::Test
+{
+ public:
+ RemovePowTest() {}
+
+ protected:
+ void SetUp() override
+ {
+ allocator.push();
+ SetGlobalPoolAllocator(&allocator);
+ ShBuiltInResources resources;
+ sh::InitBuiltInResources(&resources);
+ mTranslatorGLSL =
+ new sh::TranslatorGLSL(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT);
+ ASSERT_TRUE(mTranslatorGLSL->Init(resources));
+ }
+
+ void TearDown() override
+ {
+ SafeDelete(mTranslatorGLSL);
+ SetGlobalPoolAllocator(nullptr);
+ allocator.pop();
+ }
+
+ void compile(const std::string& shaderString)
+ {
+ const char *shaderStrings[] = { shaderString.c_str() };
+ mASTRoot = mTranslatorGLSL->compileTreeForTesting(shaderStrings, 1,
+ SH_OBJECT_CODE | SH_REMOVE_POW_WITH_CONSTANT_EXPONENT);
+ if (!mASTRoot)
+ {
+ TInfoSink &infoSink = mTranslatorGLSL->getInfoSink();
+ FAIL() << "Shader compilation into ESSL failed " << infoSink.info.c_str();
+ }
+ }
+
+ template <class T>
+ bool foundInAST()
+ {
+ return T::search(mASTRoot);
+ }
+
+ private:
+ sh::TranslatorGLSL *mTranslatorGLSL;
+ TIntermNode *mASTRoot;
+
+ TPoolAllocator allocator;
+};
+
+// Check if there's a pow() node anywhere in the tree.
+class FindPow : public sh::NodeSearchTraverser<FindPow>
+{
+ public:
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ if (node->getOp() == EOpPow)
+ {
+ mFound = true;
+ }
+ return !mFound;
+ }
+};
+
+// Check if the tree starting at node corresponds to exp2(y * log2(x))
+// If the tree matches, set base to the node corresponding to x.
+bool IsPowWorkaround(TIntermNode *node, TIntermNode **base)
+{
+ TIntermUnary *exp = node->getAsUnaryNode();
+ if (exp != nullptr && exp->getOp() == EOpExp2)
+ {
+ TIntermBinary *mul = exp->getOperand()->getAsBinaryNode();
+ if (mul != nullptr && mul->isMultiplication())
+ {
+ TIntermUnary *log = mul->getRight()->getAsUnaryNode();
+ if (mul->getLeft()->getAsConstantUnion() && log != nullptr)
+ {
+ if (log->getOp() == EOpLog2)
+ {
+ if (base)
+ *base = log->getOperand();
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+// Check if there's a node with the correct workaround to pow anywhere in the tree.
+class FindPowWorkaround : public sh::NodeSearchTraverser<FindPowWorkaround>
+{
+ public:
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ mFound = IsPowWorkaround(node, nullptr);
+ return !mFound;
+ }
+};
+
+// Check if there's a node with the correct workaround to pow with another workaround to pow
+// nested within it anywhere in the tree.
+class FindNestedPowWorkaround : public sh::NodeSearchTraverser<FindNestedPowWorkaround>
+{
+ public:
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ TIntermNode *base = nullptr;
+ bool oneFound = IsPowWorkaround(node, &base);
+ if (oneFound && base)
+ mFound = IsPowWorkaround(base, nullptr);
+ return !mFound;
+ }
+};
+
+TEST_F(RemovePowTest, PowWithConstantExponent)
+{
+ const std::string &shaderString =
+ "precision mediump float;\n"
+ "uniform float u;\n"
+ "void main() {\n"
+ " gl_FragColor = pow(vec4(u), vec4(0.5));\n"
+ "}\n";
+ compile(shaderString);
+ ASSERT_FALSE(foundInAST<FindPow>());
+ ASSERT_TRUE(foundInAST<FindPowWorkaround>());
+ ASSERT_FALSE(foundInAST<FindNestedPowWorkaround>());
+}
+
+TEST_F(RemovePowTest, NestedPowWithConstantExponent)
+{
+ const std::string &shaderString =
+ "precision mediump float;\n"
+ "uniform float u;\n"
+ "void main() {\n"
+ " gl_FragColor = pow(pow(vec4(u), vec4(2.0)), vec4(0.5));\n"
+ "}\n";
+ compile(shaderString);
+ ASSERT_FALSE(foundInAST<FindPow>());
+ ASSERT_TRUE(foundInAST<FindNestedPowWorkaround>());
+}
+