Merge pull request #190 from antiagainst/gtest

Add Google Test as the new test framework
This commit is contained in:
John Kessenich 2016-03-31 12:31:45 -06:00
commit a42533eca1
23 changed files with 1618 additions and 106 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ build/
Test/localResults/ Test/localResults/
Test/multiThread.out Test/multiThread.out
Test/singleThread.out Test/singleThread.out
External/googletest

View File

@ -1,5 +1,7 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
enable_testing()
set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "prefix") set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "prefix")
project(glslang) project(glslang)
@ -20,7 +22,12 @@ elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
add_definitions(-std=c++11) add_definitions(-std=c++11)
endif() endif()
# We depend on these for later projects, so they should come first.
add_subdirectory(External)
add_subdirectory(glslang) add_subdirectory(glslang)
add_subdirectory(OGLCompilersDLL) add_subdirectory(OGLCompilersDLL)
add_subdirectory(StandAlone) add_subdirectory(StandAlone)
add_subdirectory(SPIRV) add_subdirectory(SPIRV)
add_subdirectory(gtests)

16
External/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,16 @@
# 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()

View File

@ -61,6 +61,12 @@ bison --defines=MachineIndependent/glslang_tab.cpp.h
-o MachineIndependent/glslang_tab.cpp -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 Programmatic Interfaces
----------------------- -----------------------
@ -118,7 +124,11 @@ Testing
------- -------
Test results should always be included with a pull request that modifies 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 `Test` is an active test directory that contains test input and a
subdirectory `baseResults` that contains the expected results of the subdirectory `baseResults` that contains the expected results of the

View File

@ -1,5 +1,13 @@
cmake_minimum_required(VERSION 2.8) 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(SOURCES StandAlone.cpp)
set(REMAPPER_SOURCES spirv-remap.cpp) set(REMAPPER_SOURCES spirv-remap.cpp)
@ -10,7 +18,8 @@ set(LIBRARIES
glslang glslang
OGLCompiler OGLCompiler
OSDependent OSDependent
SPIRV) SPIRV
glslang-default-resource-limits)
if(WIN32) if(WIN32)
set(LIBRARIES ${LIBRARIES} psapi) set(LIBRARIES ${LIBRARIES} psapi)

View File

@ -0,0 +1,239 @@
//
// 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

View File

@ -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 _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_

View File

@ -37,6 +37,7 @@
// this only applies to the standalone wrapper, not the front end in general // this only applies to the standalone wrapper, not the front end in general
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#include "DefaultResourceLimits.h"
#include "Worklist.h" #include "Worklist.h"
#include "./../glslang/Include/ShHandle.h" #include "./../glslang/Include/ShHandle.h"
#include "./../glslang/Include/revision.h" #include "./../glslang/Include/revision.h"
@ -110,107 +111,6 @@ int NumShaderStrings;
TBuiltInResource Resources; TBuiltInResource Resources;
std::string ConfigFile; 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. // Parse either a .conf file provided by the user or the default string above.
// //
@ -229,8 +129,8 @@ void ProcessConfigFile()
} }
if (config == 0) { if (config == 0) {
config = new char[strlen(DefaultConfig) + 1]; Resources = glslang::DefaultTBuiltInResource;
strcpy(config, DefaultConfig); return;
} }
const char* delims = " \t\n\r"; const char* delims = " \t\n\r";
@ -832,7 +732,7 @@ int C_DECL main(int argc, char* argv[])
ProcessArguments(argc, argv); ProcessArguments(argc, argv);
if (Options & EOptionDumpConfig) { if (Options & EOptionDumpConfig) {
printf("%s", DefaultConfig); printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str());
if (Worklist.empty()) if (Worklist.empty())
return ESuccess; return ESuccess;
} }

0
Test/baseResults/spv.330.geom.out Executable file → Normal file
View File

0
Test/baseResults/spv.test.frag.out Executable file → Normal file
View File

0
Test/baseResults/spv.test.vert.out Executable file → Normal file
View File

191
gtests/AST.FromFile.cpp Normal file
View File

@ -0,0 +1,191 @@
//
// 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

View File

@ -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/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

32
gtests/CMakeLists.txt Normal file
View File

@ -0,0 +1,32 @@
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()

119
gtests/Initializer.h Normal file
View File

@ -0,0 +1,119 @@
//
// 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

74
gtests/Pp.FromFile.cpp Normal file
View File

@ -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",
})),
FileNameAsCustomTestName
);
// clang-format on
} // anonymous namespace
} // namespace glslangtest

26
gtests/README.md Normal file
View File

@ -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

41
gtests/Settings.cpp Normal file
View File

@ -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

54
gtests/Settings.h Normal file
View File

@ -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

188
gtests/Spv.FromFile.cpp Normal file
View File

@ -0,0 +1,188 @@
//
// 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

124
gtests/TestFixture.cpp Normal file
View File

@ -0,0 +1,124 @@
//
// 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

307
gtests/TestFixture.h Normal file
View File

@ -0,0 +1,307 @@
//
// 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

63
gtests/main.cpp Normal file
View File

@ -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;
}