diff options
Diffstat (limited to 'chromium/third_party/glslang/src/gtests')
15 files changed, 1639 insertions, 0 deletions
diff --git a/chromium/third_party/glslang/src/gtests/AST.FromFile.cpp b/chromium/third_party/glslang/src/gtests/AST.FromFile.cpp new file mode 100644 index 00000000000..38d6d0ae570 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/AST.FromFile.cpp @@ -0,0 +1,195 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include <gtest/gtest.h> + +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +using CompileToAstTest = GlslangTest<::testing::TestWithParam<std::string>>; + +TEST_P(CompileToAstTest, FromFile) +{ + loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(), + Source::GLSL, Semantics::OpenGL, + Target::AST); +} + +// clang-format off +INSTANTIATE_TEST_CASE_P( + Glsl, CompileToAstTest, + ::testing::ValuesIn(std::vector<std::string>({ + "sample.frag", + "sample.vert", + "decls.frag", + "specExamples.frag", + "specExamples.vert", + "versionsClean.frag", + "versionsClean.vert", + "versionsErrors.frag", + "versionsErrors.vert", + "100.frag", + "120.vert", + "120.frag", + "130.vert", + "130.frag", + "140.vert", + "140.frag", + "150.vert", + "150.geom", + "150.frag", + "precision.frag", + "precision.vert", + "nonSquare.vert", + "matrixError.vert", + "cppSimple.vert", + "cppIndent.vert", + "cppNest.vert", + "cppComplexExpr.vert", + "badChars.frag", + "pointCoord.frag", + "array.frag", + "array100.frag", + "comment.frag", + "300.vert", + "300.frag", + "300BuiltIns.frag", + "300layout.vert", + "300layout.frag", + "300operations.frag", + "300block.frag", + "310.comp", + "310.vert", + "310.geom", + "310.frag", + "310.tesc", + "310.tese", + "310implicitSizeArrayError.vert", + "310AofA.vert", + "330.frag", + "330comp.frag", + "constErrors.frag", + "constFold.frag", + "errors.frag", + "forwardRef.frag", + "uint.frag", + "switch.frag", + "tokenLength.vert", + "100Limits.vert", + "100scope.vert", + "110scope.vert", + "300scope.vert", + "400.frag", + "400.vert", + "410.vert", + "420.comp", + "420.frag", + "420.vert", + "420.geom", + "420_size_gl_in.geom", + "430scope.vert", + "lineContinuation100.vert", + "lineContinuation.vert", + "numeral.frag", + "400.geom", + "400.tesc", + "400.tese", + "410.tesc", + "420.tesc", + "420.tese", + "410.geom", + "430.vert", + "430.comp", + "430AofA.frag", + "440.vert", + "440.frag", + "450.vert", + "450.geom", + "450.tesc", + "450.tese", + "450.frag", + "450.comp", + "dce.frag", + "atomic_uint.frag", + "aggOps.frag", + "always-discard.frag", + "always-discard2.frag", + "conditionalDiscard.frag", + "conversion.frag", + "dataOut.frag", + "dataOutIndirect.frag", + "deepRvalue.frag", + "depthOut.frag", + "discard-dce.frag", + "doWhileLoop.frag", + "earlyReturnDiscard.frag", + "flowControl.frag", + "forLoop.frag", + "functionCall.frag", + "functionSemantics.frag", + "length.frag", + "localAggregates.frag", + "loops.frag", + "loopsArtificial.frag", + "matrix.frag", + "matrix2.frag", + "newTexture.frag", + "Operations.frag", + "prepost.frag", + "simpleFunctionCall.frag", + "structAssignment.frag", + "structDeref.frag", + "structure.frag", + "swizzle.frag", + "syntaxError.frag", + "test.frag", + "texture.frag", + "types.frag", + "uniformArray.frag", + "variableArrayIndex.frag", + "varyingArray.frag", + "varyingArrayIndirect.frag", + "voidFunction.frag", + "whileLoop.frag", + "nonVulkan.frag", + "spv.atomic.comp", + })), + FileNameAsCustomTestSuffix +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/BuiltInResource.FromFile.cpp b/chromium/third_party/glslang/src/gtests/BuiltInResource.FromFile.cpp new file mode 100644 index 00000000000..4d68d873bbf --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/BuiltInResource.FromFile.cpp @@ -0,0 +1,57 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include <algorithm> + +#include <gtest/gtest.h> + +#include "StandAlone/ResourceLimits.h" +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +using DefaultResourceTest = GlslangTest<::testing::Test>; + +TEST_F(DefaultResourceTest, FromFile) +{ + const std::string path = GLSLANG_TEST_DIRECTORY "/baseResults/test.conf"; + std::string expectedConfig; + tryLoadFile(path, "expected resource limit", &expectedConfig); + const std::string realConfig = glslang::GetDefaultTBuiltInResourceString(); + ASSERT_EQ(expectedConfig, realConfig); +} + +} // anonymous namespace +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/CMakeLists.txt b/chromium/third_party/glslang/src/gtests/CMakeLists.txt new file mode 100644 index 00000000000..4aafd11f312 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/CMakeLists.txt @@ -0,0 +1,40 @@ +if (TARGET gmock) + message(STATUS "Google Mock found - building tests") + + set(TEST_SOURCES + # Framework related source files + ${CMAKE_CURRENT_SOURCE_DIR}/Initializer.h + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Settings.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Settings.h + ${CMAKE_CURRENT_SOURCE_DIR}/TestFixture.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestFixture.h + + # Test related source files + ${CMAKE_CURRENT_SOURCE_DIR}/AST.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/BuiltInResource.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Config.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Hlsl.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Link.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Pp.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Spv.FromFile.cpp + ) + + add_executable(glslangtests ${TEST_SOURCES}) + set_property(TARGET glslangtests PROPERTY FOLDER tests) + glslang_set_link_args(glslangtests) + install(TARGETS glslangtests + RUNTIME DESTINATION bin) + + target_compile_definitions(glslangtests + PRIVATE GLSLANG_TEST_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/../Test") + target_include_directories(glslangtests PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR} + ${gmock_SOURCE_DIR}/include + ${gtest_SOURCE_DIR}/include) + target_link_libraries(glslangtests PRIVATE + glslang OSDependent OGLCompiler HLSL glslang + SPIRV glslang-default-resource-limits gmock) + add_test(NAME glslang-gtests COMMAND glslangtests) +endif() diff --git a/chromium/third_party/glslang/src/gtests/Config.FromFile.cpp b/chromium/third_party/glslang/src/gtests/Config.FromFile.cpp new file mode 100644 index 00000000000..20c98be5584 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Config.FromFile.cpp @@ -0,0 +1,107 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include "StandAlone/ResourceLimits.h" +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +struct TestCaseSpec { + std::string input; + std::string config; + std::string output; + EShMessages controls; +}; + +using ConfigTest = GlslangTest<::testing::TestWithParam<TestCaseSpec>>; + +TEST_P(ConfigTest, FromFile) +{ + TestCaseSpec testCase = GetParam(); + GlslangResult result; + + // Get the contents for input shader and limit configurations. + std::string shaderContents, configContents; + tryLoadFile(GLSLANG_TEST_DIRECTORY "/" + testCase.input, "input", &shaderContents); + tryLoadFile(GLSLANG_TEST_DIRECTORY "/" + testCase.config, "limits config", &configContents); + + // Decode limit configurations. + TBuiltInResource resources = {}; + { + const size_t len = configContents.size(); + char* configChars = new char[len + 1]; + memcpy(configChars, configContents.data(), len); + configChars[len] = 0; + glslang::DecodeResourceLimits(&resources, configChars); + delete[] configChars; + } + + // Compile the shader. + glslang::TShader shader(GetShaderStage(GetSuffix(testCase.input))); + compile(&shader, shaderContents, "", testCase.controls, &resources); + result.shaderResults.push_back( + {testCase.input, shader.getInfoLog(), shader.getInfoDebugLog()}); + + // Link the shader. + glslang::TProgram program; + program.addShader(&shader); + program.link(testCase.controls); + result.linkingOutput = program.getInfoLog(); + result.linkingError = program.getInfoDebugLog(); + + std::ostringstream stream; + outputResultToStream(&stream, result, testCase.controls); + + // Check with expected results. + const std::string expectedOutputFname = + GLSLANG_TEST_DIRECTORY "/baseResults/" + testCase.output; + std::string expectedOutput; + tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); + + checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname); +} + +// clang-format off +INSTANTIATE_TEST_CASE_P( + Glsl, ConfigTest, + ::testing::ValuesIn(std::vector<TestCaseSpec>({ + {"specExamples.vert", "baseResults/test.conf", "specExamples.vert.out", EShMsgAST}, + {"100Limits.vert", "100.conf", "100LimitsConf.vert.out", EShMsgDefault}, + })), +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/Hlsl.FromFile.cpp b/chromium/third_party/glslang/src/gtests/Hlsl.FromFile.cpp new file mode 100644 index 00000000000..224250145f0 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Hlsl.FromFile.cpp @@ -0,0 +1,102 @@ +// +// Copyright (C) 2016 Google, Inc. +// Copyright (C) 2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include <gtest/gtest.h> + +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +struct FileNameEntryPointPair { + const char* fileName; + const char* entryPoint; +}; + +// We are using FileNameEntryPointPair objects as parameters for instantiating +// the template, so the global FileNameAsCustomTestSuffix() won't work since +// it assumes std::string as parameters. Thus, an overriding one here. +std::string FileNameAsCustomTestSuffix( + const ::testing::TestParamInfo<FileNameEntryPointPair>& info) { + std::string name = info.param.fileName; + // A valid test case suffix cannot have '.' and '-' inside. + std::replace(name.begin(), name.end(), '.', '_'); + std::replace(name.begin(), name.end(), '-', '_'); + return name; +} + +using HlslCompileTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>; + +// Compiling HLSL to SPIR-V under Vulkan semantics. Expected to successfully +// generate both AST and SPIR-V. +TEST_P(HlslCompileTest, FromFile) +{ + loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam().fileName, + Source::HLSL, Semantics::Vulkan, + Target::BothASTAndSpv, GetParam().entryPoint); +} + +// clang-format off +INSTANTIATE_TEST_CASE_P( + ToSpirv, HlslCompileTest, + ::testing::ValuesIn(std::vector<FileNameEntryPointPair>{ + {"hlsl.assoc.frag", "PixelShaderFunction"}, + {"hlsl.attribute.frag", "PixelShaderFunction"}, + {"hlsl.cast.frag", "PixelShaderFunction"}, + {"hlsl.doLoop.frag", "PixelShaderFunction"}, + {"hlsl.float1.frag", "PixelShaderFunction"}, + {"hlsl.float4.frag", "PixelShaderFunction"}, + {"hlsl.forLoop.frag", "PixelShaderFunction"}, + {"hlsl.if.frag", "PixelShaderFunction"}, + {"hlsl.intrinsics.frag", "PixelShaderFunction"}, + {"hlsl.intrinsics.negative.frag", "PixelShaderFunction"}, + {"hlsl.intrinsics.negative.vert", "VertexShaderFunction"}, + {"hlsl.intrinsics.vert", "VertexShaderFunction"}, + {"hlsl.matType.frag", "PixelShaderFunction"}, + {"hlsl.max.frag", "PixelShaderFunction"}, + {"hlsl.precedence.frag", "PixelShaderFunction"}, + {"hlsl.precedence2.frag", "PixelShaderFunction"}, + {"hlsl.scope.frag", "PixelShaderFunction"}, + {"hlsl.sin.frag", "PixelShaderFunction"}, + {"hlsl.struct.frag", "PixelShaderFunction"}, + {"hlsl.whileLoop.frag", "PixelShaderFunction"}, + {"hlsl.void.frag", "PixelShaderFunction"}, + }), + FileNameAsCustomTestSuffix +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/Initializer.h b/chromium/third_party/glslang/src/gtests/Initializer.h new file mode 100644 index 00000000000..3cafb52a067 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Initializer.h @@ -0,0 +1,87 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef GLSLANG_GTESTS_INITIALIZER_H +#define GLSLANG_GTESTS_INITIALIZER_H + +#include "glslang/Public/ShaderLang.h" + +namespace glslangtest { + +// Initializes glslang on creation, and destroys it on completion. +// And provides .Acquire() as a way to reinitialize glslang if semantics change. +// This object is expected to be a singleton, so that internal glslang state +// can be correctly handled. +// +// TODO(antiagainst): It's a known bug that some of the internal states need to +// be reset if semantics change: +// https://github.com/KhronosGroup/glslang/issues/166 +// Therefore, the following mechanism is needed. Remove this once the above bug +// gets fixed. +class GlslangInitializer { +public: + GlslangInitializer() : lastMessages(EShMsgDefault) + { + glslang::InitializeProcess(); + } + + ~GlslangInitializer() { glslang::FinalizeProcess(); } + + // A token indicates that the glslang is reinitialized (if necessary) to the + // required semantics. And that won't change until the token is destroyed. + class InitializationToken { + }; + + // Re-initializes glsl state iff the previous messages and the current + // messages are incompatible. We assume external synchronization, i.e. + // there is at most one acquired token at any one time. + InitializationToken acquire(EShMessages new_messages) + { + if ((lastMessages ^ new_messages) & + (EShMsgVulkanRules | EShMsgSpvRules | EShMsgReadHlsl)) { + glslang::FinalizeProcess(); + glslang::InitializeProcess(); + } + lastMessages = new_messages; + return InitializationToken(); + } + +private: + + EShMessages lastMessages; +}; + +} // namespace glslangtest + +#endif // GLSLANG_GTESTS_INITIALIZER_H diff --git a/chromium/third_party/glslang/src/gtests/Link.FromFile.cpp b/chromium/third_party/glslang/src/gtests/Link.FromFile.cpp new file mode 100644 index 00000000000..331c5b2710c --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Link.FromFile.cpp @@ -0,0 +1,108 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include <memory> + +#include <gtest/gtest.h> + +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +using LinkTest = GlslangTest< + ::testing::TestWithParam<std::vector<std::string>>>; + +TEST_P(LinkTest, FromFile) +{ + const auto& fileNames = GetParam(); + const size_t fileCount = fileNames.size(); + const EShMessages controls = DeriveOptions( + Source::GLSL, Semantics::OpenGL, Target::AST); + GlslangResult result; + + // Compile each input shader file. + std::vector<std::unique_ptr<glslang::TShader>> shaders; + for (size_t i = 0; i < fileCount; ++i) { + std::string contents; + tryLoadFile(GLSLANG_TEST_DIRECTORY "/" + fileNames[i], + "input", &contents); + shaders.emplace_back( + new glslang::TShader(GetShaderStage(GetSuffix(fileNames[i])))); + auto* shader = shaders.back().get(); + compile(shader, contents, "", controls); + result.shaderResults.push_back( + {fileNames[i], shader->getInfoLog(), shader->getInfoDebugLog()}); + } + + // Link all of them. + glslang::TProgram program; + for (const auto& shader : shaders) program.addShader(shader.get()); + program.link(controls); + result.linkingOutput = program.getInfoLog(); + result.linkingError = program.getInfoDebugLog(); + + std::ostringstream stream; + outputResultToStream(&stream, result, controls); + + // Check with expected results. + const std::string expectedOutputFname = + GLSLANG_TEST_DIRECTORY "/baseResults/" + fileNames.front() + ".out"; + std::string expectedOutput; + tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); + + checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname); +} + +// clang-format off +INSTANTIATE_TEST_CASE_P( + Glsl, LinkTest, + ::testing::ValuesIn(std::vector<std::vector<std::string>>({ + {"mains1.frag", "mains2.frag", "noMain1.geom", "noMain2.geom"}, + {"noMain.vert", "mains.frag"}, + {"link1.frag", "link2.frag", "link3.frag"}, + {"recurse1.vert", "recurse1.frag", "recurse2.frag"}, + {"300link.frag"}, + {"300link2.frag"}, + {"300link3.frag"}, + {"empty.frag", "empty2.frag", "empty3.frag"}, + {"150.tesc", "150.tese", "400.tesc", "400.tese", "410.tesc", "420.tesc", "420.tese"}, + {"max_vertices_0.geom"}, + {"es-link1.frag", "es-link2.frag"}, + })), +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/Pp.FromFile.cpp b/chromium/third_party/glslang/src/gtests/Pp.FromFile.cpp new file mode 100644 index 00000000000..01bdfc32711 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Pp.FromFile.cpp @@ -0,0 +1,74 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include <gtest/gtest.h> + +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +using PreprocessingTest = GlslangTest<::testing::TestWithParam<std::string>>; + +TEST_P(PreprocessingTest, FromFile) +{ + loadFilePreprocessAndCheck(GLSLANG_TEST_DIRECTORY, GetParam()); +} + +// clang-format off +INSTANTIATE_TEST_CASE_P( + Glsl, PreprocessingTest, + ::testing::ValuesIn(std::vector<std::string>({ + "preprocessor.cpp_style_line_directive.vert", + "preprocessor.cpp_style___FILE__.vert", + "preprocessor.edge_cases.vert", + "preprocessor.errors.vert", + "preprocessor.extensions.vert", + "preprocessor.function_macro.vert", + "preprocessor.include.enabled.vert", + "preprocessor.include.disabled.vert", + "preprocessor.line.vert", + "preprocessor.line.frag", + "preprocessor.pragma.vert", + "preprocessor.simple.vert", + "preprocessor.success_if_parse_would_fail.vert", + "preprocessor.defined.vert", + "preprocessor.many.endif.vert", + })), + FileNameAsCustomTestSuffix +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/README.md b/chromium/third_party/glslang/src/gtests/README.md new file mode 100644 index 00000000000..c8261cc46ae --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/README.md @@ -0,0 +1,26 @@ +Glslang Tests based on the Google Test Framework +================================================ + +This directory contains [Google Test][gtest] based test fixture and test +cases for glslang. + +Apart from typical unit tests, necessary utility methods are added into +the [`GlslangTests`](TestFixture.h) fixture to provide the ability to do +file-based integration tests. Various `*.FromFile.cpp` files lists names +of files containing input shader code in the `Test/` directory. Utility +methods will load the input shader source, compile them, and compare with +the corresponding expected output in the `Test/baseResults/` directory. + +How to run the tests +-------------------- + +Please make sure you have a copy of [Google Test][gtest] checked out under +the `External` directory before building. After building, just run the +`ctest` command or the `gtests/glslangtests` binary in your build directory. + +The `gtests/glslangtests` binary also provides an `--update-mode` command +line option, which, if supplied, will overwrite the golden files under +the `Test/baseResults/` directory with real output from that invocation. +This serves as an easy way to update golden files. + +[gtest]: https://github.com/google/googletest diff --git a/chromium/third_party/glslang/src/gtests/Settings.cpp b/chromium/third_party/glslang/src/gtests/Settings.cpp new file mode 100644 index 00000000000..4ba7989b4a3 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Settings.cpp @@ -0,0 +1,41 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include "Settings.h" + +namespace glslangtest { + +GTestSettings GlobalTestSettings = {nullptr, false}; + +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/Settings.h b/chromium/third_party/glslang/src/gtests/Settings.h new file mode 100644 index 00000000000..30056a7bacb --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Settings.h @@ -0,0 +1,54 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef GLSLANG_GTESTS_SETTINGS_H +#define GLSLANG_GTESTS_SETTINGS_H + +namespace glslangtest { + +class GlslangInitializer; + +struct GTestSettings { + // A handle to GlslangInitializer instance. + GlslangInitializer* initializer; + // An indicator of whether GTest should write real output to the file for + // the expected output. + bool updateMode; +}; + +extern GTestSettings GlobalTestSettings; + +} // namespace glslangtest + +#endif // GLSLANG_GTESTS_SETTINGS_H diff --git a/chromium/third_party/glslang/src/gtests/Spv.FromFile.cpp b/chromium/third_party/glslang/src/gtests/Spv.FromFile.cpp new file mode 100644 index 00000000000..054e293a6d4 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/Spv.FromFile.cpp @@ -0,0 +1,210 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include <algorithm> + +#include <gtest/gtest.h> + +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +using CompileToSpirvTest = GlslangTest<::testing::TestWithParam<std::string>>; +using VulkanSemantics = GlslangTest<::testing::TestWithParam<std::string>>; +using VulkanAstSemantics = GlslangTest<::testing::TestWithParam<std::string>>; + +// Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully +// generate SPIR-V. +TEST_P(CompileToSpirvTest, FromFile) +{ + loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(), + Source::GLSL, Semantics::Vulkan, + Target::Spv); +} + +// GLSL-level Vulkan semantics test. Expected to error out before generating +// SPIR-V. +TEST_P(VulkanSemantics, FromFile) +{ + loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(), + Source::GLSL, Semantics::Vulkan, + Target::Spv); +} + +// GLSL-level Vulkan semantics test that need to see the AST for validation. +TEST_P(VulkanAstSemantics, FromFile) +{ + loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(), + Source::GLSL, Semantics::Vulkan, + Target::AST); +} + +// clang-format off +INSTANTIATE_TEST_CASE_P( + Glsl, CompileToSpirvTest, + ::testing::ValuesIn(std::vector<std::string>({ + // Test looping constructs. + // No tests yet for making sure break and continue from a nested loop + // goes to the innermost target. + "spv.do-simple.vert", + "spv.do-while-continue-break.vert", + "spv.for-complex-condition.vert", + "spv.for-continue-break.vert", + "spv.for-simple.vert", + "spv.for-notest.vert", + "spv.for-nobody.vert", + "spv.while-continue-break.vert", + "spv.while-simple.vert", + // vulkan-specific tests + "spv.set.vert", + "spv.double.comp", + "spv.100ops.frag", + "spv.130.frag", + "spv.140.frag", + "spv.150.geom", + "spv.150.vert", + "spv.300BuiltIns.vert", + "spv.300layout.frag", + "spv.300layout.vert", + "spv.300layoutp.vert", + "spv.310.comp", + "spv.330.geom", + "spv.400.frag", + "spv.400.tesc", + "spv.400.tese", + "spv.420.geom", + "spv.430.vert", + "spv.accessChain.frag", + "spv.aggOps.frag", + "spv.always-discard.frag", + "spv.always-discard2.frag", + "spv.bitCast.frag", + "spv.bool.vert", + "spv.boolInBlock.frag", + "spv.branch-return.vert", + "spv.conditionalDiscard.frag", + "spv.conversion.frag", + "spv.dataOut.frag", + "spv.dataOutIndirect.frag", + "spv.dataOutIndirect.vert", + "spv.deepRvalue.frag", + "spv.depthOut.frag", + "spv.discard-dce.frag", + "spv.doWhileLoop.frag", + "spv.earlyReturnDiscard.frag", + "spv.flowControl.frag", + "spv.forLoop.frag", + "spv.forwardFun.frag", + "spv.functionCall.frag", + "spv.functionSemantics.frag", + "spv.interpOps.frag", + "spv.int64.frag", + "spv.layoutNested.vert", + "spv.length.frag", + "spv.localAggregates.frag", + "spv.loops.frag", + "spv.loopsArtificial.frag", + "spv.matFun.vert", + "spv.matrix.frag", + "spv.matrix2.frag", + "spv.memoryQualifier.frag", + "spv.merge-unreachable.frag", + "spv.newTexture.frag", + "spv.noDeadDecorations.vert", + "spv.nonSquare.vert", + "spv.Operations.frag", + "spv.intOps.vert", + "spv.precision.frag", + "spv.prepost.frag", + "spv.qualifiers.vert", + "spv.shaderBallot.comp", + "spv.shaderGroupVote.comp", + "spv.shiftOps.frag", + "spv.simpleFunctionCall.frag", + "spv.simpleMat.vert", + "spv.sparseTexture.frag", + "spv.sparseTextureClamp.frag", + "spv.structAssignment.frag", + "spv.structDeref.frag", + "spv.structure.frag", + "spv.switch.frag", + "spv.swizzle.frag", + "spv.test.frag", + "spv.test.vert", + "spv.texture.frag", + "spv.texture.vert", + "spv.image.frag", + "spv.types.frag", + "spv.uint.frag", + "spv.uniformArray.frag", + "spv.variableArrayIndex.frag", + "spv.varyingArray.frag", + "spv.varyingArrayIndirect.frag", + "spv.voidFunction.frag", + "spv.whileLoop.frag", + "spv.AofA.frag", + "spv.queryL.frag", + "spv.separate.frag", + "spv.shortCircuit.frag", + "spv.pushConstant.vert", + "spv.subpass.frag", + "spv.specConstant.vert", + "spv.specConstant.comp", + "spv.specConstantComposite.vert", + })), + FileNameAsCustomTestSuffix +); + +INSTANTIATE_TEST_CASE_P( + Glsl, VulkanSemantics, + ::testing::ValuesIn(std::vector<std::string>({ + "vulkan.frag", + "vulkan.vert", + "vulkan.comp", + })), + FileNameAsCustomTestSuffix +); + +INSTANTIATE_TEST_CASE_P( + Glsl, VulkanAstSemantics, + ::testing::ValuesIn(std::vector<std::string>({ + "vulkan.ast.vert", + })), + FileNameAsCustomTestSuffix +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/TestFixture.cpp b/chromium/third_party/glslang/src/gtests/TestFixture.cpp new file mode 100644 index 00000000000..2cf70707cbd --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/TestFixture.cpp @@ -0,0 +1,134 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include "TestFixture.h" + +namespace glslangtest { + +std::string FileNameAsCustomTestSuffix( + const ::testing::TestParamInfo<std::string>& info) +{ + std::string name = info.param; + // A valid test case suffix cannot have '.' and '-' inside. + std::replace(name.begin(), name.end(), '.', '_'); + std::replace(name.begin(), name.end(), '-', '_'); + return name; +} + +EShLanguage GetShaderStage(const std::string& stage) +{ + if (stage == "vert") { + return EShLangVertex; + } else if (stage == "tesc") { + return EShLangTessControl; + } else if (stage == "tese") { + return EShLangTessEvaluation; + } else if (stage == "geom") { + return EShLangGeometry; + } else if (stage == "frag") { + return EShLangFragment; + } else if (stage == "comp") { + return EShLangCompute; + } else { + assert(0 && "Unknown shader stage"); + return EShLangCount; + } +} + +EShMessages DeriveOptions(Source source, Semantics semantics, Target target) +{ + EShMessages result = EShMsgDefault; + + switch (source) { + case Source::GLSL: + break; + case Source::HLSL: + result = EShMsgReadHlsl; + break; + } + + switch (target) { + case Target::AST: + result = static_cast<EShMessages>(result | EShMsgAST); + break; + case Target::Spv: + result = static_cast<EShMessages>(result | EShMsgSpvRules); + break; + case Target::BothASTAndSpv: + result = static_cast<EShMessages>(result | EShMsgSpvRules | EShMsgAST); + break; + }; + + switch (semantics) { + case Semantics::OpenGL: + break; + case Semantics::Vulkan: + result = static_cast<EShMessages>(result | EShMsgVulkanRules | EShMsgSpvRules); + break; + } + + return result; +} + +std::pair<bool, std::string> ReadFile(const std::string& path) +{ + std::ifstream fstream(path, std::ios::in); + if (fstream) { + std::string contents; + fstream.seekg(0, std::ios::end); + contents.reserve(fstream.tellg()); + fstream.seekg(0, std::ios::beg); + contents.assign((std::istreambuf_iterator<char>(fstream)), + std::istreambuf_iterator<char>()); + return std::make_pair(true, contents); + } + return std::make_pair(false, ""); +} + +bool WriteFile(const std::string& path, const std::string& contents) +{ + std::ofstream fstream(path, std::ios::out); + if (!fstream) return false; + fstream << contents; + fstream.flush(); + return true; +} + +std::string GetSuffix(const std::string& name) +{ + const size_t pos = name.rfind('.'); + return (pos == std::string::npos) ? "" : name.substr(name.rfind('.') + 1); +} + +} // namespace glslangtest diff --git a/chromium/third_party/glslang/src/gtests/TestFixture.h b/chromium/third_party/glslang/src/gtests/TestFixture.h new file mode 100644 index 00000000000..e71bab1c4c2 --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/TestFixture.h @@ -0,0 +1,341 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef GLSLANG_GTESTS_TEST_FIXTURE_H +#define GLSLANG_GTESTS_TEST_FIXTURE_H + +#include <stdint.h> +#include <fstream> +#include <sstream> +#include <streambuf> +#include <tuple> + +#include <gtest/gtest.h> + +#include "SPIRV/GlslangToSpv.h" +#include "SPIRV/disassemble.h" +#include "SPIRV/doc.h" +#include "StandAlone/ResourceLimits.h" +#include "glslang/Public/ShaderLang.h" + +#include "Initializer.h" +#include "Settings.h" + +// We need CMake to provide us the absolute path to the directory containing +// test files, so we are certain to find those files no matter where the test +// harness binary is generated. This provides out-of-source build capability. +#ifndef GLSLANG_TEST_DIRECTORY +#error \ + "GLSLANG_TEST_DIRECTORY needs to be defined for gtest to locate test files." +#endif + +namespace glslangtest { + +// This function is used to provide custom test name suffixes based on the +// shader source file names. Otherwise, the test name suffixes will just be +// numbers, which are not quite obvious. +std::string FileNameAsCustomTestSuffix( + const ::testing::TestParamInfo<std::string>& info); + +enum class Source { + GLSL, + HLSL, +}; + +// Enum for shader compilation semantics. +enum class Semantics { + OpenGL, + Vulkan, +}; + +// Enum for compilation target. +enum class Target { + AST, + Spv, + BothASTAndSpv, +}; + +EShLanguage GetShaderStage(const std::string& stage); + +EShMessages DeriveOptions(Source, Semantics, Target); + +// Reads the content of the file at the given |path|. On success, returns true +// and the contents; otherwise, returns false and an empty string. +std::pair<bool, std::string> ReadFile(const std::string& path); + +// Writes the given |contents| into the file at the given |path|. Returns true +// on successful output. +bool WriteFile(const std::string& path, const std::string& contents); + +// Returns the suffix of the given |name|. +std::string GetSuffix(const std::string& name); + +// Base class for glslang integration tests. It contains many handy utility-like +// methods such as reading shader source files, compiling into AST/SPIR-V, and +// comparing with expected outputs. +// +// To write value-Parameterized tests: +// using ValueParamTest = GlslangTest<::testing::TestWithParam<std::string>>; +// To use as normal fixture: +// using FixtureTest = GlslangTest<::testing::Test>; +template <typename GT> +class GlslangTest : public GT { +public: + GlslangTest() + : defaultVersion(100), + defaultProfile(ENoProfile), + forceVersionProfile(false), + isForwardCompatible(false) {} + + // Tries to load the contents from the file at the given |path|. On success, + // writes the contents into |contents|. On failure, errors out. + void tryLoadFile(const std::string& path, const std::string& tag, + std::string* contents) + { + bool fileReadOk; + std::tie(fileReadOk, *contents) = ReadFile(path); + ASSERT_TRUE(fileReadOk) << "Cannot open " << tag << " file: " << path; + } + + // Checks the equality of |expected| and |real|. If they are not equal, + // write |real| to the given file named as |fname| if update mode is on. + void checkEqAndUpdateIfRequested(const std::string& expected, + const std::string& real, + const std::string& fname) + { + // In order to output the message we want under proper circumstances, + // we need the following operator<< stuff. + EXPECT_EQ(expected, real) + << (GlobalTestSettings.updateMode + ? ("Mismatch found and update mode turned on - " + "flushing expected result output.") + : ""); + + // Update the expected output file if requested. + // It looks weird to duplicate the comparison between expected_output + // and stream.str(). However, if creating a variable for the comparison + // result, we cannot have pretty print of the string diff in the above. + if (GlobalTestSettings.updateMode && expected != real) { + EXPECT_TRUE(WriteFile(fname, real)) << "Flushing failed"; + } + } + + struct ShaderResult { + std::string shaderName; + std::string output; + std::string error; + }; + + // A struct for holding all the information returned by glslang compilation + // and linking. + struct GlslangResult { + std::vector<ShaderResult> shaderResults; + std::string linkingOutput; + std::string linkingError; + std::string spirvWarningsErrors; + std::string spirv; // Optional SPIR-V disassembly text. + }; + + // Compiles and the given source |code| of the given shader |stage| into + // the target under the semantics conveyed via |controls|. Returns true + // and modifies |shader| on success. + bool compile(glslang::TShader* shader, const std::string& code, + const std::string& entryPointName, EShMessages controls, + const TBuiltInResource* resources=nullptr) + { + const char* shaderStrings = code.data(); + const int shaderLengths = static_cast<int>(code.size()); + + shader->setStringsWithLengths(&shaderStrings, &shaderLengths, 1); + if (!entryPointName.empty()) shader->setEntryPoint(entryPointName.c_str()); + // Reinitialize glslang if the semantics change. + GlslangInitializer::InitializationToken token = + GlobalTestSettings.initializer->acquire(controls); + return shader->parse( + (resources ? resources : &glslang::DefaultTBuiltInResource), + defaultVersion, isForwardCompatible, controls); + } + + // Compiles and links the given source |code| of the given shader + // |stage| into the target under the semantics specified via |controls|. + // Returns a GlslangResult instance containing all the information generated + // during the process. If the target includes SPIR-V, also disassembles + // the result and returns disassembly text. + GlslangResult compileAndLink( + const std::string shaderName, const std::string& code, + const std::string& entryPointName, EShMessages controls) + { + const EShLanguage kind = GetShaderStage(GetSuffix(shaderName)); + + glslang::TShader shader(kind); + bool success = compile(&shader, code, entryPointName, controls); + + glslang::TProgram program; + program.addShader(&shader); + success &= program.link(controls); + + spv::SpvBuildLogger logger; + + if (success && (controls & EShMsgSpvRules)) { + std::vector<uint32_t> spirv_binary; + glslang::GlslangToSpv(*program.getIntermediate(kind), + spirv_binary, &logger); + + std::ostringstream disassembly_stream; + spv::Parameterize(); + spv::Disassemble(disassembly_stream, spirv_binary); + return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, + program.getInfoLog(), program.getInfoDebugLog(), + logger.getAllMessages(), disassembly_stream.str()}; + } else { + return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, + program.getInfoLog(), program.getInfoDebugLog(), "", ""}; + } + } + + void outputResultToStream(std::ostringstream* stream, + const GlslangResult& result, + EShMessages controls) + { + const auto outputIfNotEmpty = [&stream](const std::string& str) { + if (!str.empty()) *stream << str << "\n"; + }; + + for (const auto& shaderResult : result.shaderResults) { + *stream << shaderResult.shaderName << "\n"; + outputIfNotEmpty(shaderResult.output); + outputIfNotEmpty(shaderResult.error); + } + outputIfNotEmpty(result.linkingOutput); + outputIfNotEmpty(result.linkingError); + *stream << result.spirvWarningsErrors; + + if (controls & EShMsgSpvRules) { + *stream + << (result.spirv.empty() + ? "SPIR-V is not generated for failed compile or link\n" + : result.spirv); + } + } + + void loadFileCompileAndCheck(const std::string& testDir, + const std::string& testName, + Source source, + Semantics semantics, + Target target, + const std::string& entryPointName="") + { + const std::string inputFname = testDir + "/" + testName; + const std::string expectedOutputFname = + testDir + "/baseResults/" + testName + ".out"; + std::string input, expectedOutput; + + tryLoadFile(inputFname, "input", &input); + tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); + + const EShMessages controls = DeriveOptions(source, semantics, target); + GlslangResult result = + compileAndLink(testName, input, entryPointName, controls); + + // Generate the hybrid output in the way of glslangValidator. + std::ostringstream stream; + outputResultToStream(&stream, result, controls); + + checkEqAndUpdateIfRequested(expectedOutput, stream.str(), + expectedOutputFname); + } + + // Preprocesses the given |source| code. On success, returns true, the + // preprocessed shader, and warning messages. Otherwise, returns false, an + // empty string, and error messages. + std::tuple<bool, std::string, std::string> preprocess( + const std::string& source) + { + const char* shaderStrings = source.data(); + const int shaderLengths = static_cast<int>(source.size()); + + glslang::TShader shader(EShLangVertex); + shader.setStringsWithLengths(&shaderStrings, &shaderLengths, 1); + std::string ppShader; + glslang::TShader::ForbidInclude includer; + const bool success = shader.preprocess( + &glslang::DefaultTBuiltInResource, defaultVersion, defaultProfile, + forceVersionProfile, isForwardCompatible, EShMsgOnlyPreprocessor, + &ppShader, includer); + + std::string log = shader.getInfoLog(); + log += shader.getInfoDebugLog(); + if (success) { + return std::make_tuple(true, ppShader, log); + } else { + return std::make_tuple(false, "", log); + } + } + + void loadFilePreprocessAndCheck(const std::string& testDir, + const std::string& testName) + { + const std::string inputFname = testDir + "/" + testName; + const std::string expectedOutputFname = + testDir + "/baseResults/" + testName + ".out"; + const std::string expectedErrorFname = + testDir + "/baseResults/" + testName + ".err"; + std::string input, expectedOutput, expectedError; + + tryLoadFile(inputFname, "input", &input); + tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); + tryLoadFile(expectedErrorFname, "expected error", &expectedError); + + bool ppOk; + std::string output, error; + std::tie(ppOk, output, error) = preprocess(input); + if (!output.empty()) output += '\n'; + if (!error.empty()) error += '\n'; + + checkEqAndUpdateIfRequested(expectedOutput, output, + expectedOutputFname); + checkEqAndUpdateIfRequested(expectedError, error, + expectedErrorFname); + } + +private: + const int defaultVersion; + const EProfile defaultProfile; + const bool forceVersionProfile; + const bool isForwardCompatible; +}; + +} // namespace glslangtest + +#endif // GLSLANG_GTESTS_TEST_FIXTURE_H diff --git a/chromium/third_party/glslang/src/gtests/main.cpp b/chromium/third_party/glslang/src/gtests/main.cpp new file mode 100644 index 00000000000..b9806aa255f --- /dev/null +++ b/chromium/third_party/glslang/src/gtests/main.cpp @@ -0,0 +1,63 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include <memory> + +#include <gtest/gtest.h> + +#include "Initializer.h" +#include "Settings.h" + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + std::unique_ptr<glslangtest::GlslangInitializer> initializer( + new glslangtest::GlslangInitializer); + + glslangtest::GlobalTestSettings.initializer = initializer.get(); + + for (int i = 1; i < argc; ++i) { + if (!strncmp("--update-mode", argv[i], 13)) { + glslangtest::GlobalTestSettings.updateMode = true; + break; + } + } + + const int result = RUN_ALL_TESTS(); + + glslangtest::GlobalTestSettings.initializer = nullptr; + + return result; +} |