diff options
Diffstat (limited to 'gfx/angle/src/tests/test_utils/compiler_test.cpp')
-rwxr-xr-x | gfx/angle/src/tests/test_utils/compiler_test.cpp | 256 |
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 |