summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/test_utils/compiler_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/tests/test_utils/compiler_test.cpp')
-rwxr-xr-xgfx/angle/src/tests/test_utils/compiler_test.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/test_utils/compiler_test.cpp b/gfx/angle/src/tests/test_utils/compiler_test.cpp
new file mode 100755
index 000000000..873541ecd
--- /dev/null
+++ b/gfx/angle/src/tests/test_utils/compiler_test.cpp
@@ -0,0 +1,256 @@
+//
+// 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.
+//
+// compiler_test.cpp:
+// utilities for compiler unit tests.
+
+#include "tests/test_utils/compiler_test.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ShaderVariableFinder : public TIntermTraverser
+{
+ public:
+ ShaderVariableFinder(const TString &variableName, TBasicType basicType)
+ : TIntermTraverser(true, false, false),
+ mVariableName(variableName),
+ mNodeFound(nullptr),
+ mBasicType(basicType)
+ {
+ }
+
+ void visitSymbol(TIntermSymbol *node)
+ {
+ if (node->getBasicType() == mBasicType && node->getSymbol() == mVariableName)
+ {
+ mNodeFound = node;
+ }
+ }
+
+ bool isFound() const { return mNodeFound != nullptr; }
+ const TIntermSymbol *getNode() const { return mNodeFound; }
+
+ private:
+ TString mVariableName;
+ TIntermSymbol *mNodeFound;
+ TBasicType mBasicType;
+};
+
+class FunctionCallFinder : public TIntermTraverser
+{
+ public:
+ FunctionCallFinder(const TString &functionName)
+ : TIntermTraverser(true, false, false), mFunctionName(functionName), mNodeFound(nullptr)
+ {
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() == EOpFunctionCall &&
+ node->getFunctionSymbolInfo()->getName() == mFunctionName)
+ {
+ mNodeFound = node;
+ return false;
+ }
+ return true;
+ }
+
+ bool isFound() const { return mNodeFound != nullptr; }
+ const TIntermAggregate *getNode() const { return mNodeFound; }
+
+ private:
+ TString mFunctionName;
+ TIntermAggregate *mNodeFound;
+};
+
+} // anonymous namespace
+
+bool compileTestShader(GLenum type,
+ ShShaderSpec spec,
+ ShShaderOutput output,
+ const std::string &shaderString,
+ ShBuiltInResources *resources,
+ ShCompileOptions compileOptions,
+ std::string *translatedCode,
+ std::string *infoLog)
+{
+ sh::TCompiler *translator = sh::ConstructCompiler(type, spec, output);
+ if (!translator->Init(*resources))
+ {
+ SafeDelete(translator);
+ return false;
+ }
+
+ const char *shaderStrings[] = { shaderString.c_str() };
+
+ bool compilationSuccess = translator->compile(shaderStrings, 1, SH_OBJECT_CODE | compileOptions);
+ TInfoSink &infoSink = translator->getInfoSink();
+ if (translatedCode)
+ *translatedCode = infoSink.obj.c_str();
+ if (infoLog)
+ *infoLog = infoSink.info.c_str();
+ SafeDelete(translator);
+ return compilationSuccess;
+}
+
+bool compileTestShader(GLenum type,
+ ShShaderSpec spec,
+ ShShaderOutput output,
+ const std::string &shaderString,
+ ShCompileOptions compileOptions,
+ std::string *translatedCode,
+ std::string *infoLog)
+{
+ ShBuiltInResources resources;
+ sh::InitBuiltInResources(&resources);
+ return compileTestShader(type, spec, output, shaderString, &resources, compileOptions, translatedCode, infoLog);
+}
+
+MatchOutputCodeTest::MatchOutputCodeTest(GLenum shaderType,
+ ShCompileOptions defaultCompileOptions,
+ ShShaderOutput outputType)
+ : mShaderType(shaderType), mDefaultCompileOptions(defaultCompileOptions)
+{
+ sh::InitBuiltInResources(&mResources);
+ mOutputCode[outputType] = std::string();
+}
+
+void MatchOutputCodeTest::addOutputType(const ShShaderOutput outputType)
+{
+ mOutputCode[outputType] = std::string();
+}
+
+ShBuiltInResources *MatchOutputCodeTest::getResources()
+{
+ return &mResources;
+}
+
+void MatchOutputCodeTest::compile(const std::string &shaderString)
+{
+ compile(shaderString, mDefaultCompileOptions);
+}
+
+void MatchOutputCodeTest::compile(const std::string &shaderString,
+ const ShCompileOptions compileOptions)
+{
+ std::string infoLog;
+ for (auto &code : mOutputCode)
+ {
+ bool compilationSuccess =
+ compileWithSettings(code.first, shaderString, compileOptions, &code.second, &infoLog);
+ if (!compilationSuccess)
+ {
+ FAIL() << "Shader compilation failed:\n" << infoLog;
+ }
+ }
+}
+
+bool MatchOutputCodeTest::compileWithSettings(ShShaderOutput output,
+ const std::string &shaderString,
+ const ShCompileOptions compileOptions,
+ std::string *translatedCode,
+ std::string *infoLog)
+{
+ return compileTestShader(mShaderType, SH_GLES3_SPEC, output, shaderString, &mResources,
+ compileOptions, translatedCode, infoLog);
+}
+
+bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringToFind) const
+{
+ const auto code = mOutputCode.find(output);
+ EXPECT_NE(mOutputCode.end(), code);
+ if (code == mOutputCode.end())
+ {
+ return false;
+ }
+
+ return code->second.find(stringToFind) != std::string::npos;
+}
+
+bool MatchOutputCodeTest::foundInCode(ShShaderOutput output,
+ const char *stringToFind,
+ const int expectedOccurrences) const
+{
+ const auto code = mOutputCode.find(output);
+ EXPECT_NE(mOutputCode.end(), code);
+ if (code == mOutputCode.end())
+ {
+ return false;
+ }
+
+ size_t currentPos = 0;
+ int occurencesLeft = expectedOccurrences;
+ while (occurencesLeft-- > 0)
+ {
+ auto position = code->second.find(stringToFind, currentPos);
+ if (position == std::string::npos)
+ {
+ return false;
+ }
+ currentPos = position + 1;
+ }
+ return code->second.find(stringToFind, currentPos) == std::string::npos;
+}
+
+bool MatchOutputCodeTest::foundInCode(const char *stringToFind) const
+{
+ for (auto &code : mOutputCode)
+ {
+ if (!foundInCode(code.first, stringToFind))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool MatchOutputCodeTest::foundInCode(const char *stringToFind, const int expectedOccurrences) const
+{
+ for (auto &code : mOutputCode)
+ {
+ if (!foundInCode(code.first, stringToFind, expectedOccurrences))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool MatchOutputCodeTest::notFoundInCode(const char *stringToFind) const
+{
+ for (auto &code : mOutputCode)
+ {
+ if (foundInCode(code.first, stringToFind))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+const TIntermSymbol *FindSymbolNode(TIntermNode *root,
+ const TString &symbolName,
+ TBasicType basicType)
+{
+ ShaderVariableFinder finder(symbolName, basicType);
+ root->traverse(&finder);
+ return finder.getNode();
+}
+
+const TIntermAggregate *FindFunctionCallNode(TIntermNode *root, const TString &functionName)
+{
+ FunctionCallFinder finder(functionName);
+ root->traverse(&finder);
+ return finder.getNode();
+}
+
+} // namespace sh