Test/localResults/
Test/multiThread.out
Test/singleThread.out
+External/googletest
cmake_minimum_required(VERSION 2.8)
+enable_testing()
+
set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "prefix")
project(glslang)
add_definitions(-std=c++11)
endif()
+# We depend on these for later projects, so they should come first.
+add_subdirectory(External)
+
add_subdirectory(glslang)
add_subdirectory(OGLCompilersDLL)
add_subdirectory(StandAlone)
add_subdirectory(SPIRV)
+
+add_subdirectory(gtests)
--- /dev/null
+# Suppress all warnings from external projects.
+set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS -w)
+
+if (TARGET gmock)
+ message(STATUS "Google Mock already configured - use it")
+elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
+ # We need to make sure Google Test does not mess up with the
+ # global CRT settings on Windows.
+ if(WIN32)
+ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+ endif(WIN32)
+ add_subdirectory(googletest)
+else()
+ message(STATUS
+ "Google Mock was not found - tests based on that will not build")
+endif()
-o MachineIndependent/glslang_tab.cpp
```
+Glslang is adding the ability to test with
+[Google Test](https://github.com/google/googletest) framework. If you want to
+build and run those tests, please make sure you have a copy of Google Tests
+checked out in the `External/` directory:
+`git clone https://github.com/google/googletest.git`.
+
Programmatic Interfaces
-----------------------
-------
Test results should always be included with a pull request that modifies
-functionality. There is a simple process for doing this, described here:
+functionality. And since glslang is adding the ability to test with
+[Google Test](https://github.com/google/googletest) framework,
+please write your new tests using Google Test.
+
+The old (deprecated) testing process is:
`Test` is an active test directory that contains test input and a
subdirectory `baseResults` that contains the expected results of the
cmake_minimum_required(VERSION 2.8)
+add_library(glslang-default-resource-limits
+ ${CMAKE_CURRENT_SOURCE_DIR}/DefaultResourceLimits.cpp
+)
+target_include_directories(glslang-default-resource-limits
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC ${PROJECT_SOURCE_DIR}
+)
+
set(SOURCES StandAlone.cpp)
set(REMAPPER_SOURCES spirv-remap.cpp)
glslang
OGLCompiler
OSDependent
- SPIRV)
+ SPIRV
+ glslang-default-resource-limits)
if(WIN32)
set(LIBRARIES ${LIBRARIES} psapi)
--- /dev/null
+//
+// 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 <sstream>
+
+#include "DefaultResourceLimits.h"
+
+namespace glslang {
+
+const TBuiltInResource DefaultTBuiltInResource = {
+ /* .MaxLights = */ 32,
+ /* .MaxClipPlanes = */ 6,
+ /* .MaxTextureUnits = */ 32,
+ /* .MaxTextureCoords = */ 32,
+ /* .MaxVertexAttribs = */ 64,
+ /* .MaxVertexUniformComponents = */ 4096,
+ /* .MaxVaryingFloats = */ 64,
+ /* .MaxVertexTextureImageUnits = */ 32,
+ /* .MaxCombinedTextureImageUnits = */ 80,
+ /* .MaxTextureImageUnits = */ 32,
+ /* .MaxFragmentUniformComponents = */ 4096,
+ /* .MaxDrawBuffers = */ 32,
+ /* .MaxVertexUniformVectors = */ 128,
+ /* .MaxVaryingVectors = */ 8,
+ /* .MaxFragmentUniformVectors = */ 16,
+ /* .MaxVertexOutputVectors = */ 16,
+ /* .MaxFragmentInputVectors = */ 15,
+ /* .MinProgramTexelOffset = */ -8,
+ /* .MaxProgramTexelOffset = */ 7,
+ /* .MaxClipDistances = */ 8,
+ /* .MaxComputeWorkGroupCountX = */ 65535,
+ /* .MaxComputeWorkGroupCountY = */ 65535,
+ /* .MaxComputeWorkGroupCountZ = */ 65535,
+ /* .MaxComputeWorkGroupSizeX = */ 1024,
+ /* .MaxComputeWorkGroupSizeY = */ 1024,
+ /* .MaxComputeWorkGroupSizeZ = */ 64,
+ /* .MaxComputeUniformComponents = */ 1024,
+ /* .MaxComputeTextureImageUnits = */ 16,
+ /* .MaxComputeImageUniforms = */ 8,
+ /* .MaxComputeAtomicCounters = */ 8,
+ /* .MaxComputeAtomicCounterBuffers = */ 1,
+ /* .MaxVaryingComponents = */ 60,
+ /* .MaxVertexOutputComponents = */ 64,
+ /* .MaxGeometryInputComponents = */ 64,
+ /* .MaxGeometryOutputComponents = */ 128,
+ /* .MaxFragmentInputComponents = */ 128,
+ /* .MaxImageUnits = */ 8,
+ /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
+ /* .MaxCombinedShaderOutputResources = */ 8,
+ /* .MaxImageSamples = */ 0,
+ /* .MaxVertexImageUniforms = */ 0,
+ /* .MaxTessControlImageUniforms = */ 0,
+ /* .MaxTessEvaluationImageUniforms = */ 0,
+ /* .MaxGeometryImageUniforms = */ 0,
+ /* .MaxFragmentImageUniforms = */ 8,
+ /* .MaxCombinedImageUniforms = */ 8,
+ /* .MaxGeometryTextureImageUnits = */ 16,
+ /* .MaxGeometryOutputVertices = */ 256,
+ /* .MaxGeometryTotalOutputComponents = */ 1024,
+ /* .MaxGeometryUniformComponents = */ 1024,
+ /* .MaxGeometryVaryingComponents = */ 64,
+ /* .MaxTessControlInputComponents = */ 128,
+ /* .MaxTessControlOutputComponents = */ 128,
+ /* .MaxTessControlTextureImageUnits = */ 16,
+ /* .MaxTessControlUniformComponents = */ 1024,
+ /* .MaxTessControlTotalOutputComponents = */ 4096,
+ /* .MaxTessEvaluationInputComponents = */ 128,
+ /* .MaxTessEvaluationOutputComponents = */ 128,
+ /* .MaxTessEvaluationTextureImageUnits = */ 16,
+ /* .MaxTessEvaluationUniformComponents = */ 1024,
+ /* .MaxTessPatchComponents = */ 120,
+ /* .MaxPatchVertices = */ 32,
+ /* .MaxTessGenLevel = */ 64,
+ /* .MaxViewports = */ 16,
+ /* .MaxVertexAtomicCounters = */ 0,
+ /* .MaxTessControlAtomicCounters = */ 0,
+ /* .MaxTessEvaluationAtomicCounters = */ 0,
+ /* .MaxGeometryAtomicCounters = */ 0,
+ /* .MaxFragmentAtomicCounters = */ 8,
+ /* .MaxCombinedAtomicCounters = */ 8,
+ /* .MaxAtomicCounterBindings = */ 1,
+ /* .MaxVertexAtomicCounterBuffers = */ 0,
+ /* .MaxTessControlAtomicCounterBuffers = */ 0,
+ /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
+ /* .MaxGeometryAtomicCounterBuffers = */ 0,
+ /* .MaxFragmentAtomicCounterBuffers = */ 1,
+ /* .MaxCombinedAtomicCounterBuffers = */ 1,
+ /* .MaxAtomicCounterBufferSize = */ 16384,
+ /* .MaxTransformFeedbackBuffers = */ 4,
+ /* .MaxTransformFeedbackInterleavedComponents = */ 64,
+ /* .MaxCullDistances = */ 8,
+ /* .MaxCombinedClipAndCullDistances = */ 8,
+ /* .MaxSamples = */ 4,
+ /* .limits = */ {
+ /* .nonInductiveForLoops = */ 1,
+ /* .whileLoops = */ 1,
+ /* .doWhileLoops = */ 1,
+ /* .generalUniformIndexing = */ 1,
+ /* .generalAttributeMatrixVectorIndexing = */ 1,
+ /* .generalVaryingIndexing = */ 1,
+ /* .generalSamplerIndexing = */ 1,
+ /* .generalVariableIndexing = */ 1,
+ /* .generalConstantMatrixVectorIndexing = */ 1,
+ }};
+
+std::string GetDefaultTBuiltInResourceString()
+{
+ std::ostringstream ostream;
+
+ ostream << "MaxLights " << DefaultTBuiltInResource.maxLights << "\n"
+ << "MaxClipPlanes " << DefaultTBuiltInResource.maxClipPlanes << "\n"
+ << "MaxTextureUnits " << DefaultTBuiltInResource.maxTextureUnits << "\n"
+ << "MaxTextureCoords " << DefaultTBuiltInResource.maxTextureCoords << "\n"
+ << "MaxVertexAttribs " << DefaultTBuiltInResource.maxVertexAttribs << "\n"
+ << "MaxVertexUniformComponents " << DefaultTBuiltInResource.maxVertexUniformComponents << "\n"
+ << "MaxVaryingFloats " << DefaultTBuiltInResource.maxVaryingFloats << "\n"
+ << "MaxVertexTextureImageUnits " << DefaultTBuiltInResource.maxVertexTextureImageUnits << "\n"
+ << "MaxCombinedTextureImageUnits " << DefaultTBuiltInResource.maxCombinedTextureImageUnits << "\n"
+ << "MaxTextureImageUnits " << DefaultTBuiltInResource.maxTextureImageUnits << "\n"
+ << "MaxFragmentUniformComponents " << DefaultTBuiltInResource.maxFragmentUniformComponents << "\n"
+ << "MaxDrawBuffers " << DefaultTBuiltInResource.maxDrawBuffers << "\n"
+ << "MaxVertexUniformVectors " << DefaultTBuiltInResource.maxVertexUniformVectors << "\n"
+ << "MaxVaryingVectors " << DefaultTBuiltInResource.maxVaryingVectors << "\n"
+ << "MaxFragmentUniformVectors " << DefaultTBuiltInResource.maxFragmentUniformVectors << "\n"
+ << "MaxVertexOutputVectors " << DefaultTBuiltInResource.maxVertexOutputVectors << "\n"
+ << "MaxFragmentInputVectors " << DefaultTBuiltInResource.maxFragmentInputVectors << "\n"
+ << "MinProgramTexelOffset " << DefaultTBuiltInResource.minProgramTexelOffset << "\n"
+ << "MaxProgramTexelOffset " << DefaultTBuiltInResource.maxProgramTexelOffset << "\n"
+ << "MaxClipDistances " << DefaultTBuiltInResource.maxClipDistances << "\n"
+ << "MaxComputeWorkGroupCountX " << DefaultTBuiltInResource.maxComputeWorkGroupCountX << "\n"
+ << "MaxComputeWorkGroupCountY " << DefaultTBuiltInResource.maxComputeWorkGroupCountY << "\n"
+ << "MaxComputeWorkGroupCountZ " << DefaultTBuiltInResource.maxComputeWorkGroupCountZ << "\n"
+ << "MaxComputeWorkGroupSizeX " << DefaultTBuiltInResource.maxComputeWorkGroupSizeX << "\n"
+ << "MaxComputeWorkGroupSizeY " << DefaultTBuiltInResource.maxComputeWorkGroupSizeY << "\n"
+ << "MaxComputeWorkGroupSizeZ " << DefaultTBuiltInResource.maxComputeWorkGroupSizeZ << "\n"
+ << "MaxComputeUniformComponents " << DefaultTBuiltInResource.maxComputeUniformComponents << "\n"
+ << "MaxComputeTextureImageUnits " << DefaultTBuiltInResource.maxComputeTextureImageUnits << "\n"
+ << "MaxComputeImageUniforms " << DefaultTBuiltInResource.maxComputeImageUniforms << "\n"
+ << "MaxComputeAtomicCounters " << DefaultTBuiltInResource.maxComputeAtomicCounters << "\n"
+ << "MaxComputeAtomicCounterBuffers " << DefaultTBuiltInResource.maxComputeAtomicCounterBuffers << "\n"
+ << "MaxVaryingComponents " << DefaultTBuiltInResource.maxVaryingComponents << "\n"
+ << "MaxVertexOutputComponents " << DefaultTBuiltInResource.maxVertexOutputComponents << "\n"
+ << "MaxGeometryInputComponents " << DefaultTBuiltInResource.maxGeometryInputComponents << "\n"
+ << "MaxGeometryOutputComponents " << DefaultTBuiltInResource.maxGeometryOutputComponents << "\n"
+ << "MaxFragmentInputComponents " << DefaultTBuiltInResource.maxFragmentInputComponents << "\n"
+ << "MaxImageUnits " << DefaultTBuiltInResource.maxImageUnits << "\n"
+ << "MaxCombinedImageUnitsAndFragmentOutputs " << DefaultTBuiltInResource.maxCombinedImageUnitsAndFragmentOutputs << "\n"
+ << "MaxCombinedShaderOutputResources " << DefaultTBuiltInResource.maxCombinedShaderOutputResources << "\n"
+ << "MaxImageSamples " << DefaultTBuiltInResource.maxImageSamples << "\n"
+ << "MaxVertexImageUniforms " << DefaultTBuiltInResource.maxVertexImageUniforms << "\n"
+ << "MaxTessControlImageUniforms " << DefaultTBuiltInResource.maxTessControlImageUniforms << "\n"
+ << "MaxTessEvaluationImageUniforms " << DefaultTBuiltInResource.maxTessEvaluationImageUniforms << "\n"
+ << "MaxGeometryImageUniforms " << DefaultTBuiltInResource.maxGeometryImageUniforms << "\n"
+ << "MaxFragmentImageUniforms " << DefaultTBuiltInResource.maxFragmentImageUniforms << "\n"
+ << "MaxCombinedImageUniforms " << DefaultTBuiltInResource.maxCombinedImageUniforms << "\n"
+ << "MaxGeometryTextureImageUnits " << DefaultTBuiltInResource.maxGeometryTextureImageUnits << "\n"
+ << "MaxGeometryOutputVertices " << DefaultTBuiltInResource.maxGeometryOutputVertices << "\n"
+ << "MaxGeometryTotalOutputComponents " << DefaultTBuiltInResource.maxGeometryTotalOutputComponents << "\n"
+ << "MaxGeometryUniformComponents " << DefaultTBuiltInResource.maxGeometryUniformComponents << "\n"
+ << "MaxGeometryVaryingComponents " << DefaultTBuiltInResource.maxGeometryVaryingComponents << "\n"
+ << "MaxTessControlInputComponents " << DefaultTBuiltInResource.maxTessControlInputComponents << "\n"
+ << "MaxTessControlOutputComponents " << DefaultTBuiltInResource.maxTessControlOutputComponents << "\n"
+ << "MaxTessControlTextureImageUnits " << DefaultTBuiltInResource.maxTessControlTextureImageUnits << "\n"
+ << "MaxTessControlUniformComponents " << DefaultTBuiltInResource.maxTessControlUniformComponents << "\n"
+ << "MaxTessControlTotalOutputComponents " << DefaultTBuiltInResource.maxTessControlTotalOutputComponents << "\n"
+ << "MaxTessEvaluationInputComponents " << DefaultTBuiltInResource.maxTessEvaluationInputComponents << "\n"
+ << "MaxTessEvaluationOutputComponents " << DefaultTBuiltInResource.maxTessEvaluationOutputComponents << "\n"
+ << "MaxTessEvaluationTextureImageUnits " << DefaultTBuiltInResource.maxTessEvaluationTextureImageUnits << "\n"
+ << "MaxTessEvaluationUniformComponents " << DefaultTBuiltInResource.maxTessEvaluationUniformComponents << "\n"
+ << "MaxTessPatchComponents " << DefaultTBuiltInResource.maxTessPatchComponents << "\n"
+ << "MaxPatchVertices " << DefaultTBuiltInResource.maxPatchVertices << "\n"
+ << "MaxTessGenLevel " << DefaultTBuiltInResource.maxTessGenLevel << "\n"
+ << "MaxViewports " << DefaultTBuiltInResource.maxViewports << "\n"
+ << "MaxVertexAtomicCounters " << DefaultTBuiltInResource.maxVertexAtomicCounters << "\n"
+ << "MaxTessControlAtomicCounters " << DefaultTBuiltInResource.maxTessControlAtomicCounters << "\n"
+ << "MaxTessEvaluationAtomicCounters " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounters << "\n"
+ << "MaxGeometryAtomicCounters " << DefaultTBuiltInResource.maxGeometryAtomicCounters << "\n"
+ << "MaxFragmentAtomicCounters " << DefaultTBuiltInResource.maxFragmentAtomicCounters << "\n"
+ << "MaxCombinedAtomicCounters " << DefaultTBuiltInResource.maxCombinedAtomicCounters << "\n"
+ << "MaxAtomicCounterBindings " << DefaultTBuiltInResource.maxAtomicCounterBindings << "\n"
+ << "MaxVertexAtomicCounterBuffers " << DefaultTBuiltInResource.maxVertexAtomicCounterBuffers << "\n"
+ << "MaxTessControlAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessControlAtomicCounterBuffers << "\n"
+ << "MaxTessEvaluationAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounterBuffers << "\n"
+ << "MaxGeometryAtomicCounterBuffers " << DefaultTBuiltInResource.maxGeometryAtomicCounterBuffers << "\n"
+ << "MaxFragmentAtomicCounterBuffers " << DefaultTBuiltInResource.maxFragmentAtomicCounterBuffers << "\n"
+ << "MaxCombinedAtomicCounterBuffers " << DefaultTBuiltInResource.maxCombinedAtomicCounterBuffers << "\n"
+ << "MaxAtomicCounterBufferSize " << DefaultTBuiltInResource.maxAtomicCounterBufferSize << "\n"
+ << "MaxTransformFeedbackBuffers " << DefaultTBuiltInResource.maxTransformFeedbackBuffers << "\n"
+ << "MaxTransformFeedbackInterleavedComponents " << DefaultTBuiltInResource.maxTransformFeedbackInterleavedComponents << "\n"
+ << "MaxCullDistances " << DefaultTBuiltInResource.maxCullDistances << "\n"
+ << "MaxCombinedClipAndCullDistances " << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n"
+ << "MaxSamples " << DefaultTBuiltInResource.maxSamples << "\n"
+
+ << "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n"
+ << "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n"
+ << "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n"
+ << "generalUniformIndexing " << DefaultTBuiltInResource.limits.generalUniformIndexing << "\n"
+ << "generalAttributeMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalAttributeMatrixVectorIndexing << "\n"
+ << "generalVaryingIndexing " << DefaultTBuiltInResource.limits.generalVaryingIndexing << "\n"
+ << "generalSamplerIndexing " << DefaultTBuiltInResource.limits.generalSamplerIndexing << "\n"
+ << "generalVariableIndexing " << DefaultTBuiltInResource.limits.generalVariableIndexing << "\n"
+ << "generalConstantMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalConstantMatrixVectorIndexing << "\n"
+ ;
+
+ return ostream.str();
+}
+
+} // end namespace glslang
--- /dev/null
+//
+// 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 _DEFAULT_RESOURCE_LIMITS_INCLUDED_
+#define _DEFAULT_RESOURCE_LIMITS_INCLUDED_
+
+#include <string>
+
+#include "glslang/Include/ResourceLimits.h"
+
+namespace glslang {
+
+// These are the default resources for TBuiltInResources, used for both
+// - parsing this string for the case where the user didn't supply one,
+// - dumping out a template for user construction of a config file.
+extern const TBuiltInResource DefaultTBuiltInResource;
+
+// Returns the DefaultTBuiltInResource as a human-readable string.
+std::string GetDefaultTBuiltInResourceString();
+
+} // end namespace glslang
+
+#endif // _DEFAULT_RESOURCE_LIMITS_INCLUDED_
// this only applies to the standalone wrapper, not the front end in general
#define _CRT_SECURE_NO_WARNINGS
+#include "DefaultResourceLimits.h"
#include "Worklist.h"
#include "./../glslang/Include/ShHandle.h"
#include "./../glslang/Include/revision.h"
std::string ConfigFile;
//
-// These are the default resources for TBuiltInResources, used for both
-// - parsing this string for the case where the user didn't supply one
-// - dumping out a template for user construction of a config file
-//
-const char* DefaultConfig =
- "MaxLights 32\n"
- "MaxClipPlanes 6\n"
- "MaxTextureUnits 32\n"
- "MaxTextureCoords 32\n"
- "MaxVertexAttribs 64\n"
- "MaxVertexUniformComponents 4096\n"
- "MaxVaryingFloats 64\n"
- "MaxVertexTextureImageUnits 32\n"
- "MaxCombinedTextureImageUnits 80\n"
- "MaxTextureImageUnits 32\n"
- "MaxFragmentUniformComponents 4096\n"
- "MaxDrawBuffers 32\n"
- "MaxVertexUniformVectors 128\n"
- "MaxVaryingVectors 8\n"
- "MaxFragmentUniformVectors 16\n"
- "MaxVertexOutputVectors 16\n"
- "MaxFragmentInputVectors 15\n"
- "MinProgramTexelOffset -8\n"
- "MaxProgramTexelOffset 7\n"
- "MaxClipDistances 8\n"
- "MaxComputeWorkGroupCountX 65535\n"
- "MaxComputeWorkGroupCountY 65535\n"
- "MaxComputeWorkGroupCountZ 65535\n"
- "MaxComputeWorkGroupSizeX 1024\n"
- "MaxComputeWorkGroupSizeY 1024\n"
- "MaxComputeWorkGroupSizeZ 64\n"
- "MaxComputeUniformComponents 1024\n"
- "MaxComputeTextureImageUnits 16\n"
- "MaxComputeImageUniforms 8\n"
- "MaxComputeAtomicCounters 8\n"
- "MaxComputeAtomicCounterBuffers 1\n"
- "MaxVaryingComponents 60\n"
- "MaxVertexOutputComponents 64\n"
- "MaxGeometryInputComponents 64\n"
- "MaxGeometryOutputComponents 128\n"
- "MaxFragmentInputComponents 128\n"
- "MaxImageUnits 8\n"
- "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
- "MaxCombinedShaderOutputResources 8\n"
- "MaxImageSamples 0\n"
- "MaxVertexImageUniforms 0\n"
- "MaxTessControlImageUniforms 0\n"
- "MaxTessEvaluationImageUniforms 0\n"
- "MaxGeometryImageUniforms 0\n"
- "MaxFragmentImageUniforms 8\n"
- "MaxCombinedImageUniforms 8\n"
- "MaxGeometryTextureImageUnits 16\n"
- "MaxGeometryOutputVertices 256\n"
- "MaxGeometryTotalOutputComponents 1024\n"
- "MaxGeometryUniformComponents 1024\n"
- "MaxGeometryVaryingComponents 64\n"
- "MaxTessControlInputComponents 128\n"
- "MaxTessControlOutputComponents 128\n"
- "MaxTessControlTextureImageUnits 16\n"
- "MaxTessControlUniformComponents 1024\n"
- "MaxTessControlTotalOutputComponents 4096\n"
- "MaxTessEvaluationInputComponents 128\n"
- "MaxTessEvaluationOutputComponents 128\n"
- "MaxTessEvaluationTextureImageUnits 16\n"
- "MaxTessEvaluationUniformComponents 1024\n"
- "MaxTessPatchComponents 120\n"
- "MaxPatchVertices 32\n"
- "MaxTessGenLevel 64\n"
- "MaxViewports 16\n"
- "MaxVertexAtomicCounters 0\n"
- "MaxTessControlAtomicCounters 0\n"
- "MaxTessEvaluationAtomicCounters 0\n"
- "MaxGeometryAtomicCounters 0\n"
- "MaxFragmentAtomicCounters 8\n"
- "MaxCombinedAtomicCounters 8\n"
- "MaxAtomicCounterBindings 1\n"
- "MaxVertexAtomicCounterBuffers 0\n"
- "MaxTessControlAtomicCounterBuffers 0\n"
- "MaxTessEvaluationAtomicCounterBuffers 0\n"
- "MaxGeometryAtomicCounterBuffers 0\n"
- "MaxFragmentAtomicCounterBuffers 1\n"
- "MaxCombinedAtomicCounterBuffers 1\n"
- "MaxAtomicCounterBufferSize 16384\n"
- "MaxTransformFeedbackBuffers 4\n"
- "MaxTransformFeedbackInterleavedComponents 64\n"
- "MaxCullDistances 8\n"
- "MaxCombinedClipAndCullDistances 8\n"
- "MaxSamples 4\n"
-
- "nonInductiveForLoops 1\n"
- "whileLoops 1\n"
- "doWhileLoops 1\n"
- "generalUniformIndexing 1\n"
- "generalAttributeMatrixVectorIndexing 1\n"
- "generalVaryingIndexing 1\n"
- "generalSamplerIndexing 1\n"
- "generalVariableIndexing 1\n"
- "generalConstantMatrixVectorIndexing 1\n"
- ;
-
-//
// Parse either a .conf file provided by the user or the default string above.
//
void ProcessConfigFile()
}
if (config == 0) {
- config = new char[strlen(DefaultConfig) + 1];
- strcpy(config, DefaultConfig);
+ Resources = glslang::DefaultTBuiltInResource;
+ return;
}
const char* delims = " \t\n\r";
ProcessArguments(argc, argv);
if (Options & EOptionDumpConfig) {
- printf("%s", DefaultConfig);
+ printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str());
if (Worklist.empty())
return ESuccess;
}
--- /dev/null
+//
+// 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(),
+ 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",
+ "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",
+ })),
+ FileNameAsCustomTestName
+);
+// clang-format on
+
+} // anonymous namespace
+} // namespace glslangtest
--- /dev/null
+//
+// 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/DefaultResourceLimits.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
--- /dev/null
+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}/Pp.FromFile.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/Spv.FromFile.cpp
+ )
+
+ add_executable(glslangtests ${TEST_SOURCES})
+ 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 glslang
+ SPIRV glslang-default-resource-limits gmock)
+ add_test(NAME glslang-gtests COMMAND glslangtests)
+endif()
--- /dev/null
+//
+// 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 <mutex>
+
+#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 {
+ public:
+ InitializationToken() : initializer(nullptr) {}
+ ~InitializationToken()
+ {
+ if (initializer) {
+ initializer->release();
+ }
+ }
+
+ InitializationToken(InitializationToken&& other)
+ : initializer(other.initializer)
+ {
+ other.initializer = nullptr;
+ }
+
+ InitializationToken(const InitializationToken&) = delete;
+
+ private:
+ InitializationToken(GlslangInitializer* initializer)
+ : initializer(initializer) {}
+
+ friend class GlslangInitializer;
+ GlslangInitializer* initializer;
+ };
+
+ // Obtains exclusive access to the glslang state. The state remains
+ // exclusive until the Initialization Token has been destroyed.
+ // Re-initializes glsl state iff the previous messages and the current
+ // messages are incompatible.
+ InitializationToken acquire(EShMessages new_messages)
+ {
+ stateLock.lock();
+
+ if ((lastMessages ^ new_messages) &
+ (EShMsgVulkanRules | EShMsgSpvRules)) {
+ glslang::FinalizeProcess();
+ glslang::InitializeProcess();
+ }
+ lastMessages = new_messages;
+ return InitializationToken(this);
+ }
+
+private:
+ void release() { stateLock.unlock(); }
+
+ friend class InitializationToken;
+
+ EShMessages lastMessages;
+ std::mutex stateLock;
+};
+
+} // namespace glslangtest
+
+#endif // GLSLANG_GTESTS_INITIALIZER_H
--- /dev/null
+//
+// 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",
+ })),
+ FileNameAsCustomTestName
+);
+// clang-format on
+
+} // anonymous namespace
+} // namespace glslangtest
--- /dev/null
+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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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>>;
+
+// Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
+// generate SPIR-V.
+TEST_P(CompileToSpirvTest, FromFile)
+{
+ loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(),
+ Semantics::Vulkan, Target::Spirv);
+}
+
+// GLSL-level Vulkan semantics test. Expected to error out before generating
+// SPIR-V.
+TEST_P(VulkanSemantics, FromFile)
+{
+ loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(),
+ Semantics::Vulkan, Target::Spirv);
+}
+
+// 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.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.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",
+ })),
+ FileNameAsCustomTestName
+);
+
+INSTANTIATE_TEST_CASE_P(
+ Glsl, VulkanSemantics,
+ ::testing::ValuesIn(std::vector<std::string>({
+ "vulkan.frag",
+ "vulkan.vert",
+ "vulkan.comp",
+ })),
+ FileNameAsCustomTestName
+);
+// clang-format on
+
+} // anonymous namespace
+} // namespace glslangtest
--- /dev/null
+//
+// 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 FileNameAsCustomTestName(
+ 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 GetGlslLanguageForStage(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 GetSpirvMessageOptionsForSemanticsAndTarget(Semantics semantics,
+ Target target)
+{
+ EShMessages result = EShMsgDefault;
+
+ switch (target) {
+ case Target::AST:
+ result = EShMsgAST;
+ break;
+ case Target::Spirv:
+ result = EShMsgSpvRules;
+ break;
+ };
+
+ switch (semantics) {
+ case Semantics::OpenGL:
+ break;
+ case Semantics::Vulkan:
+ result = static_cast<EShMessages>(result | EShMsgVulkanRules);
+ 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
--- /dev/null
+//
+// 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/DefaultResourceLimits.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 FileNameAsCustomTestName(
+ const ::testing::TestParamInfo<std::string>& info);
+
+// Enum for shader compilation semantics.
+enum class Semantics {
+ OpenGL,
+ Vulkan,
+};
+
+// Enum for compilation target.
+enum class Target {
+ AST,
+ Spirv,
+};
+
+EShLanguage GetGlslLanguageForStage(const std::string& stage);
+
+EShMessages GetSpirvMessageOptionsForSemanticsAndTarget(Semantics semantics,
+ Target 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";
+ }
+ }
+
+ // A struct for holding all the information returned by glslang compilation
+ // and linking.
+ struct GlslangResult {
+ const std::string compilationOutput;
+ const std::string compilationError;
+ const std::string linkingOutput;
+ const std::string linkingError;
+ const std::string spirv; // Optional SPIR-V disassembly text.
+ };
+
+ // Compiles and linkes the given GLSL |source| code of the given shader
+ // |stage| into the given |target| under the given |semantics|. Returns
+ // a GlslangResult instance containing all the information generated
+ // during the process. If |target| is Target::Spirv, also disassembles
+ // the result and returns disassembly text.
+ GlslangResult compileGlsl(const std::string& source,
+ const std::string& stage, Semantics semantics,
+ Target target)
+ {
+ const char* shaderStrings = source.data();
+ const int shaderLengths = static_cast<int>(source.size());
+ const EShLanguage language = GetGlslLanguageForStage(stage);
+
+ glslang::TShader shader(language);
+ shader.setStringsWithLengths(&shaderStrings, &shaderLengths, 1);
+ const EShMessages messages =
+ GetSpirvMessageOptionsForSemanticsAndTarget(semantics, target);
+ // Reinitialize glslang if the semantics change.
+ GlslangInitializer::InitializationToken token =
+ GlobalTestSettings.initializer->acquire(messages);
+ bool success =
+ shader.parse(&glslang::DefaultTBuiltInResource, defaultVersion,
+ isForwardCompatible, messages);
+
+ glslang::TProgram program;
+ program.addShader(&shader);
+ success &= program.link(messages);
+
+ if (success && target == Target::Spirv) {
+ std::vector<uint32_t> spirv_binary;
+ glslang::GlslangToSpv(*program.getIntermediate(language),
+ spirv_binary);
+
+ std::ostringstream disassembly_stream;
+ spv::Parameterize();
+ spv::Disassemble(disassembly_stream, spirv_binary);
+ return {shader.getInfoLog(), shader.getInfoDebugLog(),
+ program.getInfoLog(), program.getInfoDebugLog(),
+ disassembly_stream.str()};
+ } else {
+ return {shader.getInfoLog(), shader.getInfoDebugLog(),
+ program.getInfoLog(), program.getInfoDebugLog(), ""};
+ }
+ }
+
+ void loadFileCompileAndCheck(const std::string& testDir,
+ const std::string& testName,
+ Semantics semantics, Target target)
+ {
+ 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);
+
+ GlslangResult result =
+ compileGlsl(input, GetSuffix(testName), semantics, target);
+
+ // Generate the hybrid output in the way of glslangValidator.
+ std::ostringstream stream;
+
+ const auto outputIfNotEmpty = [&stream](const std::string& str) {
+ if (!str.empty()) stream << str << "\n";
+ };
+
+ stream << testName << "\n";
+ outputIfNotEmpty(result.compilationOutput);
+ outputIfNotEmpty(result.compilationError);
+ outputIfNotEmpty(result.linkingOutput);
+ outputIfNotEmpty(result.linkingError);
+ if (target == Target::Spirv) {
+ stream
+ << (result.spirv.empty()
+ ? "SPIR-V is not generated for failed compile or link\n"
+ : result.spirv);
+ }
+
+ checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
+ expectedOutputFname);
+ }
+
+ // Preprocesses the given GLSL |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> preprocessGlsl(
+ 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) = preprocessGlsl(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
--- /dev/null
+//
+// 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;
+}