summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/glslang/src/StandAlone
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/glslang/src/StandAlone')
-rw-r--r--chromium/third_party/glslang/src/StandAlone/CMakeLists.txt48
-rw-r--r--chromium/third_party/glslang/src/StandAlone/ResourceLimits.cpp444
-rw-r--r--chromium/third_party/glslang/src/StandAlone/ResourceLimits.h57
-rw-r--r--chromium/third_party/glslang/src/StandAlone/StandAlone.cpp891
-rw-r--r--chromium/third_party/glslang/src/StandAlone/Worklist.h98
-rw-r--r--chromium/third_party/glslang/src/StandAlone/spirv-remap.cpp344
6 files changed, 1882 insertions, 0 deletions
diff --git a/chromium/third_party/glslang/src/StandAlone/CMakeLists.txt b/chromium/third_party/glslang/src/StandAlone/CMakeLists.txt
new file mode 100644
index 00000000000..d69351ef3c5
--- /dev/null
+++ b/chromium/third_party/glslang/src/StandAlone/CMakeLists.txt
@@ -0,0 +1,48 @@
+add_library(glslang-default-resource-limits
+ ${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp
+)
+set_property(TARGET glslang-default-resource-limits PROPERTY FOLDER glslang)
+
+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)
+
+add_executable(glslangValidator ${SOURCES})
+add_executable(spirv-remap ${REMAPPER_SOURCES})
+set_property(TARGET glslangValidator PROPERTY FOLDER tools)
+set_property(TARGET spirv-remap PROPERTY FOLDER tools)
+glslang_set_link_args(glslangValidator)
+glslang_set_link_args(spirv-remap)
+
+set(LIBRARIES
+ glslang
+ OGLCompiler
+ OSDependent
+ HLSL
+ SPIRV
+ glslang-default-resource-limits)
+
+if(WIN32)
+ set(LIBRARIES ${LIBRARIES} psapi)
+elseif(UNIX)
+ if(NOT ANDROID)
+ set(LIBRARIES ${LIBRARIES} pthread)
+ endif()
+endif(WIN32)
+
+target_link_libraries(glslangValidator ${LIBRARIES})
+target_link_libraries(spirv-remap ${LIBRARIES})
+
+if(WIN32)
+ source_group("Source" FILES ${SOURCES})
+endif(WIN32)
+
+install(TARGETS glslangValidator
+ RUNTIME DESTINATION bin)
+
+install(TARGETS spirv-remap
+ RUNTIME DESTINATION bin)
diff --git a/chromium/third_party/glslang/src/StandAlone/ResourceLimits.cpp b/chromium/third_party/glslang/src/StandAlone/ResourceLimits.cpp
new file mode 100644
index 00000000000..80491980503
--- /dev/null
+++ b/chromium/third_party/glslang/src/StandAlone/ResourceLimits.cpp
@@ -0,0 +1,444 @@
+//
+// 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 <cstdlib>
+#include <cstring>
+#include <sstream>
+
+#include "ResourceLimits.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();
+}
+
+void DecodeResourceLimits(TBuiltInResource* resources, char* config) {
+ const char* delims = " \t\n\r";
+ const char* token = strtok(config, delims);
+ while (token) {
+ const char* valueStr = strtok(0, delims);
+ if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
+ printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
+ return;
+ }
+ int value = atoi(valueStr);
+
+ if (strcmp(token, "MaxLights") == 0)
+ resources->maxLights = value;
+ else if (strcmp(token, "MaxClipPlanes") == 0)
+ resources->maxClipPlanes = value;
+ else if (strcmp(token, "MaxTextureUnits") == 0)
+ resources->maxTextureUnits = value;
+ else if (strcmp(token, "MaxTextureCoords") == 0)
+ resources->maxTextureCoords = value;
+ else if (strcmp(token, "MaxVertexAttribs") == 0)
+ resources->maxVertexAttribs = value;
+ else if (strcmp(token, "MaxVertexUniformComponents") == 0)
+ resources->maxVertexUniformComponents = value;
+ else if (strcmp(token, "MaxVaryingFloats") == 0)
+ resources->maxVaryingFloats = value;
+ else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
+ resources->maxVertexTextureImageUnits = value;
+ else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
+ resources->maxCombinedTextureImageUnits = value;
+ else if (strcmp(token, "MaxTextureImageUnits") == 0)
+ resources->maxTextureImageUnits = value;
+ else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
+ resources->maxFragmentUniformComponents = value;
+ else if (strcmp(token, "MaxDrawBuffers") == 0)
+ resources->maxDrawBuffers = value;
+ else if (strcmp(token, "MaxVertexUniformVectors") == 0)
+ resources->maxVertexUniformVectors = value;
+ else if (strcmp(token, "MaxVaryingVectors") == 0)
+ resources->maxVaryingVectors = value;
+ else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
+ resources->maxFragmentUniformVectors = value;
+ else if (strcmp(token, "MaxVertexOutputVectors") == 0)
+ resources->maxVertexOutputVectors = value;
+ else if (strcmp(token, "MaxFragmentInputVectors") == 0)
+ resources->maxFragmentInputVectors = value;
+ else if (strcmp(token, "MinProgramTexelOffset") == 0)
+ resources->minProgramTexelOffset = value;
+ else if (strcmp(token, "MaxProgramTexelOffset") == 0)
+ resources->maxProgramTexelOffset = value;
+ else if (strcmp(token, "MaxClipDistances") == 0)
+ resources->maxClipDistances = value;
+ else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
+ resources->maxComputeWorkGroupCountX = value;
+ else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
+ resources->maxComputeWorkGroupCountY = value;
+ else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
+ resources->maxComputeWorkGroupCountZ = value;
+ else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
+ resources->maxComputeWorkGroupSizeX = value;
+ else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
+ resources->maxComputeWorkGroupSizeY = value;
+ else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
+ resources->maxComputeWorkGroupSizeZ = value;
+ else if (strcmp(token, "MaxComputeUniformComponents") == 0)
+ resources->maxComputeUniformComponents = value;
+ else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
+ resources->maxComputeTextureImageUnits = value;
+ else if (strcmp(token, "MaxComputeImageUniforms") == 0)
+ resources->maxComputeImageUniforms = value;
+ else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
+ resources->maxComputeAtomicCounters = value;
+ else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
+ resources->maxComputeAtomicCounterBuffers = value;
+ else if (strcmp(token, "MaxVaryingComponents") == 0)
+ resources->maxVaryingComponents = value;
+ else if (strcmp(token, "MaxVertexOutputComponents") == 0)
+ resources->maxVertexOutputComponents = value;
+ else if (strcmp(token, "MaxGeometryInputComponents") == 0)
+ resources->maxGeometryInputComponents = value;
+ else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
+ resources->maxGeometryOutputComponents = value;
+ else if (strcmp(token, "MaxFragmentInputComponents") == 0)
+ resources->maxFragmentInputComponents = value;
+ else if (strcmp(token, "MaxImageUnits") == 0)
+ resources->maxImageUnits = value;
+ else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
+ resources->maxCombinedImageUnitsAndFragmentOutputs = value;
+ else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
+ resources->maxCombinedShaderOutputResources = value;
+ else if (strcmp(token, "MaxImageSamples") == 0)
+ resources->maxImageSamples = value;
+ else if (strcmp(token, "MaxVertexImageUniforms") == 0)
+ resources->maxVertexImageUniforms = value;
+ else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
+ resources->maxTessControlImageUniforms = value;
+ else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
+ resources->maxTessEvaluationImageUniforms = value;
+ else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
+ resources->maxGeometryImageUniforms = value;
+ else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
+ resources->maxFragmentImageUniforms = value;
+ else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
+ resources->maxCombinedImageUniforms = value;
+ else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
+ resources->maxGeometryTextureImageUnits = value;
+ else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
+ resources->maxGeometryOutputVertices = value;
+ else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
+ resources->maxGeometryTotalOutputComponents = value;
+ else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
+ resources->maxGeometryUniformComponents = value;
+ else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
+ resources->maxGeometryVaryingComponents = value;
+ else if (strcmp(token, "MaxTessControlInputComponents") == 0)
+ resources->maxTessControlInputComponents = value;
+ else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
+ resources->maxTessControlOutputComponents = value;
+ else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
+ resources->maxTessControlTextureImageUnits = value;
+ else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
+ resources->maxTessControlUniformComponents = value;
+ else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
+ resources->maxTessControlTotalOutputComponents = value;
+ else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
+ resources->maxTessEvaluationInputComponents = value;
+ else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
+ resources->maxTessEvaluationOutputComponents = value;
+ else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
+ resources->maxTessEvaluationTextureImageUnits = value;
+ else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
+ resources->maxTessEvaluationUniformComponents = value;
+ else if (strcmp(token, "MaxTessPatchComponents") == 0)
+ resources->maxTessPatchComponents = value;
+ else if (strcmp(token, "MaxPatchVertices") == 0)
+ resources->maxPatchVertices = value;
+ else if (strcmp(token, "MaxTessGenLevel") == 0)
+ resources->maxTessGenLevel = value;
+ else if (strcmp(token, "MaxViewports") == 0)
+ resources->maxViewports = value;
+ else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
+ resources->maxVertexAtomicCounters = value;
+ else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
+ resources->maxTessControlAtomicCounters = value;
+ else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
+ resources->maxTessEvaluationAtomicCounters = value;
+ else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
+ resources->maxGeometryAtomicCounters = value;
+ else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
+ resources->maxFragmentAtomicCounters = value;
+ else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
+ resources->maxCombinedAtomicCounters = value;
+ else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
+ resources->maxAtomicCounterBindings = value;
+ else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
+ resources->maxVertexAtomicCounterBuffers = value;
+ else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
+ resources->maxTessControlAtomicCounterBuffers = value;
+ else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
+ resources->maxTessEvaluationAtomicCounterBuffers = value;
+ else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
+ resources->maxGeometryAtomicCounterBuffers = value;
+ else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
+ resources->maxFragmentAtomicCounterBuffers = value;
+ else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
+ resources->maxCombinedAtomicCounterBuffers = value;
+ else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
+ resources->maxAtomicCounterBufferSize = value;
+ else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
+ resources->maxTransformFeedbackBuffers = value;
+ else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
+ resources->maxTransformFeedbackInterleavedComponents = value;
+ else if (strcmp(token, "MaxCullDistances") == 0)
+ resources->maxCullDistances = value;
+ else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
+ resources->maxCombinedClipAndCullDistances = value;
+ else if (strcmp(token, "MaxSamples") == 0)
+ resources->maxSamples = value;
+
+ else if (strcmp(token, "nonInductiveForLoops") == 0)
+ resources->limits.nonInductiveForLoops = (value != 0);
+ else if (strcmp(token, "whileLoops") == 0)
+ resources->limits.whileLoops = (value != 0);
+ else if (strcmp(token, "doWhileLoops") == 0)
+ resources->limits.doWhileLoops = (value != 0);
+ else if (strcmp(token, "generalUniformIndexing") == 0)
+ resources->limits.generalUniformIndexing = (value != 0);
+ else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
+ resources->limits.generalAttributeMatrixVectorIndexing = (value != 0);
+ else if (strcmp(token, "generalVaryingIndexing") == 0)
+ resources->limits.generalVaryingIndexing = (value != 0);
+ else if (strcmp(token, "generalSamplerIndexing") == 0)
+ resources->limits.generalSamplerIndexing = (value != 0);
+ else if (strcmp(token, "generalVariableIndexing") == 0)
+ resources->limits.generalVariableIndexing = (value != 0);
+ else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
+ resources->limits.generalConstantMatrixVectorIndexing = (value != 0);
+ else
+ printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
+
+ token = strtok(0, delims);
+ }
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/StandAlone/ResourceLimits.h b/chromium/third_party/glslang/src/StandAlone/ResourceLimits.h
new file mode 100644
index 00000000000..9c3eb3e9fb5
--- /dev/null
+++ b/chromium/third_party/glslang/src/StandAlone/ResourceLimits.h
@@ -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.
+
+#ifndef _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
+#define _STAND_ALONE_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();
+
+// Decodes the resource limits from |config| to |resources|.
+void DecodeResourceLimits(TBuiltInResource* resources, char* config);
+
+} // end namespace glslang
+
+#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
diff --git a/chromium/third_party/glslang/src/StandAlone/StandAlone.cpp b/chromium/third_party/glslang/src/StandAlone/StandAlone.cpp
new file mode 100644
index 00000000000..3fd7e7d2ada
--- /dev/null
+++ b/chromium/third_party/glslang/src/StandAlone/StandAlone.cpp
@@ -0,0 +1,891 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. 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.
+//
+
+// this only applies to the standalone wrapper, not the front end in general
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "ResourceLimits.h"
+#include "Worklist.h"
+#include "./../glslang/Include/ShHandle.h"
+#include "./../glslang/Include/revision.h"
+#include "./../glslang/Public/ShaderLang.h"
+#include "../SPIRV/GlslangToSpv.h"
+#include "../SPIRV/GLSL.std.450.h"
+#include "../SPIRV/doc.h"
+#include "../SPIRV/disassemble.h"
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "../glslang/OSDependent/osinclude.h"
+
+extern "C" {
+ SH_IMPORT_EXPORT void ShOutputHtml();
+}
+
+// Command-line options
+enum TOptions {
+ EOptionNone = 0x0000,
+ EOptionIntermediate = 0x0001,
+ EOptionSuppressInfolog = 0x0002,
+ EOptionMemoryLeakMode = 0x0004,
+ EOptionRelaxedErrors = 0x0008,
+ EOptionGiveWarnings = 0x0010,
+ EOptionLinkProgram = 0x0020,
+ EOptionMultiThreaded = 0x0040,
+ EOptionDumpConfig = 0x0080,
+ EOptionDumpReflection = 0x0100,
+ EOptionSuppressWarnings = 0x0200,
+ EOptionDumpVersions = 0x0400,
+ EOptionSpv = 0x0800,
+ EOptionHumanReadableSpv = 0x1000,
+ EOptionVulkanRules = 0x2000,
+ EOptionDefaultDesktop = 0x4000,
+ EOptionOutputPreprocessed = 0x8000,
+ EOptionReadHlsl = 0x10000,
+};
+
+//
+// Return codes from main/exit().
+//
+enum TFailCode {
+ ESuccess = 0,
+ EFailUsage,
+ EFailCompile,
+ EFailLink,
+ EFailCompilerCreate,
+ EFailThreadCreate,
+ EFailLinkerCreate
+};
+
+//
+// Forward declarations.
+//
+EShLanguage FindLanguage(const std::string& name);
+void CompileFile(const char* fileName, ShHandle);
+void usage();
+void FreeFileData(char** data);
+char** ReadFileData(const char* fileName);
+void InfoLogMsg(const char* msg, const char* name, const int num);
+
+// Globally track if any compile or link failure.
+bool CompileFailed = false;
+bool LinkFailed = false;
+
+// Use to test breaking up a single shader file into multiple strings.
+// Set in ReadFileData().
+int NumShaderStrings;
+
+TBuiltInResource Resources;
+std::string ConfigFile;
+
+//
+// Parse either a .conf file provided by the user or the default from glslang::DefaultTBuiltInResource
+//
+void ProcessConfigFile()
+{
+ char** configStrings = 0;
+ char* config = 0;
+ if (ConfigFile.size() > 0) {
+ configStrings = ReadFileData(ConfigFile.c_str());
+ if (configStrings)
+ config = *configStrings;
+ else {
+ printf("Error opening configuration file; will instead use the default configuration\n");
+ usage();
+ }
+ }
+
+ if (config == 0) {
+ Resources = glslang::DefaultTBuiltInResource;
+ return;
+ }
+
+ glslang::DecodeResourceLimits(&Resources, config);
+
+ if (configStrings)
+ FreeFileData(configStrings);
+ else
+ delete[] config;
+}
+
+// thread-safe list of shaders to asynchronously grab and compile
+glslang::TWorklist Worklist;
+
+// array of unique places to leave the shader names and infologs for the asynchronous compiles
+glslang::TWorkItem** Work = 0;
+int NumWorkItems = 0;
+
+int Options = 0;
+const char* ExecutableName = nullptr;
+const char* binaryFileName = nullptr;
+const char* entryPointName = nullptr;
+
+//
+// Create the default name for saving a binary if -o is not provided.
+//
+const char* GetBinaryName(EShLanguage stage)
+{
+ const char* name;
+ if (binaryFileName == nullptr) {
+ switch (stage) {
+ case EShLangVertex: name = "vert.spv"; break;
+ case EShLangTessControl: name = "tesc.spv"; break;
+ case EShLangTessEvaluation: name = "tese.spv"; break;
+ case EShLangGeometry: name = "geom.spv"; break;
+ case EShLangFragment: name = "frag.spv"; break;
+ case EShLangCompute: name = "comp.spv"; break;
+ default: name = "unknown"; break;
+ }
+ } else
+ name = binaryFileName;
+
+ return name;
+}
+
+//
+// *.conf => this is a config file that can set limits/resources
+//
+bool SetConfigFile(const std::string& name)
+{
+ if (name.size() < 5)
+ return false;
+
+ if (name.compare(name.size() - 5, 5, ".conf") == 0) {
+ ConfigFile = name;
+ return true;
+ }
+
+ return false;
+}
+
+//
+// Give error and exit with failure code.
+//
+void Error(const char* message)
+{
+ printf("%s: Error %s (use -h for usage)\n", ExecutableName, message);
+ exit(EFailUsage);
+}
+
+//
+// Do all command-line argument parsing. This includes building up the work-items
+// to be processed later, and saving all the command-line options.
+//
+// Does not return (it exits) if command-line is fatally flawed.
+//
+void ProcessArguments(int argc, char* argv[])
+{
+ ExecutableName = argv[0];
+ NumWorkItems = argc; // will include some empties where the '-' options were, but it doesn't matter, they'll be 0
+ Work = new glslang::TWorkItem*[NumWorkItems];
+ for (int w = 0; w < NumWorkItems; ++w)
+ Work[w] = 0;
+
+ argc--;
+ argv++;
+ for (; argc >= 1; argc--, argv++) {
+ if (argv[0][0] == '-') {
+ switch (argv[0][1]) {
+ case 'H':
+ Options |= EOptionHumanReadableSpv;
+ // fall through to -V
+ case 'V':
+ Options |= EOptionSpv;
+ Options |= EOptionVulkanRules;
+ Options |= EOptionLinkProgram;
+ break;
+ case 'G':
+ Options |= EOptionSpv;
+ Options |= EOptionLinkProgram;
+ break;
+ case 'E':
+ Options |= EOptionOutputPreprocessed;
+ break;
+ case 'c':
+ Options |= EOptionDumpConfig;
+ break;
+ case 'd':
+ Options |= EOptionDefaultDesktop;
+ break;
+ case 'D':
+ Options |= EOptionReadHlsl;
+ break;
+ case 'e':
+ // HLSL todo: entry point handle needs much more sophistication.
+ // This is okay for one compilation unit with one entry point.
+ entryPointName = argv[1];
+ if (argc > 0) {
+ argc--;
+ argv++;
+ } else
+ Error("no <entry-point> provided for -e");
+ break;
+ case 'h':
+ usage();
+ break;
+ case 'i':
+ Options |= EOptionIntermediate;
+ break;
+ case 'l':
+ Options |= EOptionLinkProgram;
+ break;
+ case 'm':
+ Options |= EOptionMemoryLeakMode;
+ break;
+ case 'o':
+ binaryFileName = argv[1];
+ if (argc > 0) {
+ argc--;
+ argv++;
+ } else
+ Error("no <file> provided for -o");
+ break;
+ case 'q':
+ Options |= EOptionDumpReflection;
+ break;
+ case 'r':
+ Options |= EOptionRelaxedErrors;
+ break;
+ case 's':
+ Options |= EOptionSuppressInfolog;
+ break;
+ case 't':
+ #ifdef _WIN32
+ Options |= EOptionMultiThreaded;
+ #endif
+ break;
+ case 'v':
+ Options |= EOptionDumpVersions;
+ break;
+ case 'w':
+ Options |= EOptionSuppressWarnings;
+ break;
+ default:
+ usage();
+ break;
+ }
+ } else {
+ std::string name(argv[0]);
+ if (! SetConfigFile(name)) {
+ Work[argc] = new glslang::TWorkItem(name);
+ Worklist.add(Work[argc]);
+ }
+ }
+ }
+
+ // Make sure that -E is not specified alongside linking (which includes SPV generation)
+ if ((Options & EOptionOutputPreprocessed) && (Options & EOptionLinkProgram))
+ Error("can't use -E when linking is selected");
+
+ // -o makes no sense if there is no target binary
+ if (binaryFileName && (Options & EOptionSpv) == 0)
+ Error("no binary generation requested (e.g., -V)");
+}
+
+//
+// Translate the meaningful subset of command-line options to parser-behavior options.
+//
+void SetMessageOptions(EShMessages& messages)
+{
+ if (Options & EOptionRelaxedErrors)
+ messages = (EShMessages)(messages | EShMsgRelaxedErrors);
+ if (Options & EOptionIntermediate)
+ messages = (EShMessages)(messages | EShMsgAST);
+ if (Options & EOptionSuppressWarnings)
+ messages = (EShMessages)(messages | EShMsgSuppressWarnings);
+ if (Options & EOptionSpv)
+ messages = (EShMessages)(messages | EShMsgSpvRules);
+ if (Options & EOptionVulkanRules)
+ messages = (EShMessages)(messages | EShMsgVulkanRules);
+ if (Options & EOptionOutputPreprocessed)
+ messages = (EShMessages)(messages | EShMsgOnlyPreprocessor);
+ if (Options & EOptionReadHlsl)
+ messages = (EShMessages)(messages | EShMsgReadHlsl);
+}
+
+//
+// Thread entry point, for non-linking asynchronous mode.
+//
+// Return 0 for failure, 1 for success.
+//
+unsigned int CompileShaders(void*)
+{
+ glslang::TWorkItem* workItem;
+ while (Worklist.remove(workItem)) {
+ ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), Options);
+ if (compiler == 0)
+ return 0;
+
+ CompileFile(workItem->name.c_str(), compiler);
+
+ if (! (Options & EOptionSuppressInfolog))
+ workItem->results = ShGetInfoLog(compiler);
+
+ ShDestruct(compiler);
+ }
+
+ return 0;
+}
+
+// Outputs the given string, but only if it is non-null and non-empty.
+// This prevents erroneous newlines from appearing.
+void PutsIfNonEmpty(const char* str)
+{
+ if (str && str[0]) {
+ puts(str);
+ }
+}
+
+// Outputs the given string to stderr, but only if it is non-null and non-empty.
+// This prevents erroneous newlines from appearing.
+void StderrIfNonEmpty(const char* str)
+{
+ if (str && str[0]) {
+ fprintf(stderr, "%s\n", str);
+ }
+}
+
+// Simple bundling of what makes a compilation unit for ease in passing around,
+// and separation of handling file IO versus API (programmatic) compilation.
+struct ShaderCompUnit {
+ EShLanguage stage;
+ std::string fileName;
+ char** text; // memory owned/managed externally
+};
+
+//
+// For linking mode: Will independently parse each compilation unit, but then put them
+// in the same program and link them together, making at most one linked module per
+// pipeline stage.
+//
+// Uses the new C++ interface instead of the old handle-based interface.
+//
+
+void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
+{
+ // keep track of what to free
+ std::list<glslang::TShader*> shaders;
+
+ EShMessages messages = EShMsgDefault;
+ SetMessageOptions(messages);
+
+ //
+ // Per-shader processing...
+ //
+
+ glslang::TProgram& program = *new glslang::TProgram;
+ for (auto it = compUnits.cbegin(); it != compUnits.cend(); ++it) {
+ const auto &compUnit = *it;
+ glslang::TShader* shader = new glslang::TShader(compUnit.stage);
+ shader->setStrings(compUnit.text, 1);
+ if (entryPointName) // HLSL todo: this needs to be tracked per compUnits
+ shader->setEntryPoint(entryPointName);
+ shaders.push_back(shader);
+
+ const int defaultVersion = Options & EOptionDefaultDesktop? 110: 100;
+
+ if (Options & EOptionOutputPreprocessed) {
+ std::string str;
+ glslang::TShader::ForbidInclude includer;
+ if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false,
+ messages, &str, includer)) {
+ PutsIfNonEmpty(str.c_str());
+ } else {
+ CompileFailed = true;
+ }
+ StderrIfNonEmpty(shader->getInfoLog());
+ StderrIfNonEmpty(shader->getInfoDebugLog());
+ continue;
+ }
+ if (! shader->parse(&Resources, defaultVersion, false, messages))
+ CompileFailed = true;
+
+ program.addShader(shader);
+
+ if (! (Options & EOptionSuppressInfolog) &&
+ ! (Options & EOptionMemoryLeakMode)) {
+ PutsIfNonEmpty(compUnit.fileName.c_str());
+ PutsIfNonEmpty(shader->getInfoLog());
+ PutsIfNonEmpty(shader->getInfoDebugLog());
+ }
+ }
+
+ //
+ // Program-level processing...
+ //
+
+ // Link
+ if (! (Options & EOptionOutputPreprocessed) && ! program.link(messages))
+ LinkFailed = true;
+
+ // Report
+ if (! (Options & EOptionSuppressInfolog) &&
+ ! (Options & EOptionMemoryLeakMode)) {
+ PutsIfNonEmpty(program.getInfoLog());
+ PutsIfNonEmpty(program.getInfoDebugLog());
+ }
+
+ // Reflect
+ if (Options & EOptionDumpReflection) {
+ program.buildReflection();
+ program.dumpReflection();
+ }
+
+ // Dump SPIR-V
+ if (Options & EOptionSpv) {
+ if (CompileFailed || LinkFailed)
+ printf("SPIR-V is not generated for failed compile or link\n");
+ else {
+ for (int stage = 0; stage < EShLangCount; ++stage) {
+ if (program.getIntermediate((EShLanguage)stage)) {
+ std::vector<unsigned int> spirv;
+ std::string warningsErrors;
+ spv::SpvBuildLogger logger;
+ glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger);
+
+ // Dump the spv to a file or stdout, etc., but only if not doing
+ // memory/perf testing, as it's not internal to programmatic use.
+ if (! (Options & EOptionMemoryLeakMode)) {
+ printf("%s", logger.getAllMessages().c_str());
+ glslang::OutputSpv(spirv, GetBinaryName((EShLanguage)stage));
+ if (Options & EOptionHumanReadableSpv) {
+ spv::Disassemble(std::cout, spirv);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Free everything up, program has to go before the shaders
+ // because it might have merged stuff from the shaders, and
+ // the stuff from the shaders has to have its destructors called
+ // before the pools holding the memory in the shaders is freed.
+ delete &program;
+ while (shaders.size() > 0) {
+ delete shaders.back();
+ shaders.pop_back();
+ }
+}
+
+//
+// Do file IO part of compile and link, handing off the pure
+// API/programmatic mode to CompileAndLinkShaderUnits(), which can
+// be put in a loop for testing memory footprint and performance.
+//
+// This is just for linking mode: meaning all the shaders will be put into the
+// the same program linked together.
+//
+// This means there are a limited number of work items (not multi-threading mode)
+// and that the point is testing at the linking level. Hence, to enable
+// performance and memory testing, the actual compile/link can be put in
+// a loop, independent of processing the work items and file IO.
+//
+void CompileAndLinkShaderFiles()
+{
+ std::vector<ShaderCompUnit> compUnits;
+
+ // Transfer all the work items from to a simple list of
+ // of compilation units. (We don't care about the thread
+ // work-item distribution properties in this path, which
+ // is okay due to the limited number of shaders, know since
+ // they are all getting linked together.)
+ glslang::TWorkItem* workItem;
+ while (Worklist.remove(workItem)) {
+ ShaderCompUnit compUnit = {
+ FindLanguage(workItem->name),
+ workItem->name,
+ ReadFileData(workItem->name.c_str())
+ };
+
+ if (! compUnit.text) {
+ usage();
+ return;
+ }
+
+ compUnits.push_back(compUnit);
+ }
+
+ // Actual call to programmatic processing of compile and link,
+ // in a loop for testing memory and performance. This part contains
+ // all the perf/memory that a programmatic consumer will care about.
+ for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
+ for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j)
+ CompileAndLinkShaderUnits(compUnits);
+
+ if (Options & EOptionMemoryLeakMode)
+ glslang::OS_DumpMemoryCounters();
+ }
+
+ for (auto it = compUnits.begin(); it != compUnits.end(); ++it)
+ FreeFileData(it->text);
+}
+
+int C_DECL main(int argc, char* argv[])
+{
+ ProcessArguments(argc, argv);
+
+ if (Options & EOptionDumpConfig) {
+ printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str());
+ if (Worklist.empty())
+ return ESuccess;
+ }
+
+ if (Options & EOptionDumpVersions) {
+ printf("Glslang Version: %s %s\n", GLSLANG_REVISION, GLSLANG_DATE);
+ printf("ESSL Version: %s\n", glslang::GetEsslVersionString());
+ printf("GLSL Version: %s\n", glslang::GetGlslVersionString());
+ std::string spirvVersion;
+ glslang::GetSpirvVersion(spirvVersion);
+ printf("SPIR-V Version %s\n", spirvVersion.c_str());
+ printf("GLSL.std.450 Version %d, Revision %d\n", GLSLstd450Version, GLSLstd450Revision);
+ printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId());
+ if (Worklist.empty())
+ return ESuccess;
+ }
+
+ if (Worklist.empty()) {
+ usage();
+ }
+
+ ProcessConfigFile();
+
+ //
+ // Two modes:
+ // 1) linking all arguments together, single-threaded, new C++ interface
+ // 2) independent arguments, can be tackled by multiple asynchronous threads, for testing thread safety, using the old handle interface
+ //
+ if (Options & EOptionLinkProgram ||
+ Options & EOptionOutputPreprocessed) {
+ glslang::InitializeProcess();
+ CompileAndLinkShaderFiles();
+ glslang::FinalizeProcess();
+ for (int w = 0; w < NumWorkItems; ++w) {
+ if (Work[w]) {
+ delete Work[w];
+ }
+ }
+ } else {
+ ShInitialize();
+
+ bool printShaderNames = Worklist.size() > 1;
+
+ if (Options & EOptionMultiThreaded) {
+ const int NumThreads = 16;
+ void* threads[NumThreads];
+ for (int t = 0; t < NumThreads; ++t) {
+ threads[t] = glslang::OS_CreateThread(&CompileShaders);
+ if (! threads[t]) {
+ printf("Failed to create thread\n");
+ return EFailThreadCreate;
+ }
+ }
+ glslang::OS_WaitForAllThreads(threads, NumThreads);
+ } else
+ CompileShaders(0);
+
+ // Print out all the resulting infologs
+ for (int w = 0; w < NumWorkItems; ++w) {
+ if (Work[w]) {
+ if (printShaderNames || Work[w]->results.size() > 0)
+ PutsIfNonEmpty(Work[w]->name.c_str());
+ PutsIfNonEmpty(Work[w]->results.c_str());
+ delete Work[w];
+ }
+ }
+
+ ShFinalize();
+ }
+
+ delete[] Work;
+
+ if (CompileFailed)
+ return EFailCompile;
+ if (LinkFailed)
+ return EFailLink;
+
+ return 0;
+}
+
+//
+// Deduce the language from the filename. Files must end in one of the
+// following extensions:
+//
+// .vert = vertex
+// .tesc = tessellation control
+// .tese = tessellation evaluation
+// .geom = geometry
+// .frag = fragment
+// .comp = compute
+//
+EShLanguage FindLanguage(const std::string& name)
+{
+ size_t ext = name.rfind('.');
+ if (ext == std::string::npos) {
+ usage();
+ return EShLangVertex;
+ }
+
+ std::string suffix = name.substr(ext + 1, std::string::npos);
+ if (suffix == "vert")
+ return EShLangVertex;
+ else if (suffix == "tesc")
+ return EShLangTessControl;
+ else if (suffix == "tese")
+ return EShLangTessEvaluation;
+ else if (suffix == "geom")
+ return EShLangGeometry;
+ else if (suffix == "frag")
+ return EShLangFragment;
+ else if (suffix == "comp")
+ return EShLangCompute;
+
+ usage();
+ return EShLangVertex;
+}
+
+//
+// Read a file's data into a string, and compile it using the old interface ShCompile,
+// for non-linkable results.
+//
+void CompileFile(const char* fileName, ShHandle compiler)
+{
+ int ret = 0;
+ char** shaderStrings = ReadFileData(fileName);
+ if (! shaderStrings) {
+ usage();
+ }
+
+ int* lengths = new int[NumShaderStrings];
+
+ // move to length-based strings, rather than null-terminated strings
+ for (int s = 0; s < NumShaderStrings; ++s)
+ lengths[s] = (int)strlen(shaderStrings[s]);
+
+ if (! shaderStrings) {
+ CompileFailed = true;
+ return;
+ }
+
+ EShMessages messages = EShMsgDefault;
+ SetMessageOptions(messages);
+
+ for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
+ for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
+ //ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
+ ret = ShCompile(compiler, shaderStrings, NumShaderStrings, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
+ //const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err",
+ // "or should be l", "ine 1", "string 5\n", "float glo", "bal",
+ // ";\n#error should be line 2\n void main() {", "global = 2.3;}" };
+ //const char* multi[7] = { "/", "/", "\\", "\n", "\n", "#", "version 300 es" };
+ //ret = ShCompile(compiler, multi, 7, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
+ }
+
+ if (Options & EOptionMemoryLeakMode)
+ glslang::OS_DumpMemoryCounters();
+ }
+
+ delete [] lengths;
+ FreeFileData(shaderStrings);
+
+ if (ret == 0)
+ CompileFailed = true;
+}
+
+//
+// print usage to stdout
+//
+void usage()
+{
+ printf("Usage: glslangValidator [option]... [file]...\n"
+ "\n"
+ "Where: each 'file' ends in .<stage>, where <stage> is one of\n"
+ " .conf to provide an optional config file that replaces the default configuration\n"
+ " (see -c option below for generating a template)\n"
+ " .vert for a vertex shader\n"
+ " .tesc for a tessellation control shader\n"
+ " .tese for a tessellation evaluation shader\n"
+ " .geom for a geometry shader\n"
+ " .frag for a fragment shader\n"
+ " .comp for a compute shader\n"
+ "\n"
+ "Compilation warnings and errors will be printed to stdout.\n"
+ "\n"
+ "To get other information, use one of the following options:\n"
+ "Each option must be specified separately.\n"
+ " -V create SPIR-V binary, under Vulkan semantics; turns on -l;\n"
+ " default file name is <stage>.spv (-o overrides this)\n"
+ " (unless -o is specified, which overrides the default file name)\n"
+ " -G create SPIR-V binary, under OpenGL semantics; turns on -l;\n"
+ " default file name is <stage>.spv (-o overrides this)\n"
+ " -H print human readable form of SPIR-V; turns on -V\n"
+ " -E print pre-processed GLSL; cannot be used with -l;\n"
+ " errors will appear on stderr.\n"
+ " -c configuration dump;\n"
+ " creates the default configuration file (redirect to a .conf file)\n"
+ " -d default to desktop (#version 110) when there is no shader #version\n"
+ " (default is ES version 100)\n"
+ " -D input is HLSL\n"
+ " -e specify entry-point name\n"
+ " -h print this usage message\n"
+ " -i intermediate tree (glslang AST) is printed out\n"
+ " -l link all input files together to form a single module\n"
+ " -m memory leak mode\n"
+ " -o <file> save binary into <file>, requires a binary option (e.g., -V)\n"
+ " -q dump reflection query database\n"
+ " -r relaxed semantic error-checking mode\n"
+ " -s silent mode\n"
+ " -t multi-threaded mode\n"
+ " -v print version strings\n"
+ " -w suppress warnings (except as required by #extension : warn)\n"
+ );
+
+ exit(EFailUsage);
+}
+
+#if !defined _MSC_VER && !defined MINGW_HAS_SECURE_API
+
+#include <errno.h>
+
+int fopen_s(
+ FILE** pFile,
+ const char* filename,
+ const char* mode
+)
+{
+ if (!pFile || !filename || !mode) {
+ return EINVAL;
+ }
+
+ FILE* f = fopen(filename, mode);
+ if (! f) {
+ if (errno != 0) {
+ return errno;
+ } else {
+ return ENOENT;
+ }
+ }
+ *pFile = f;
+
+ return 0;
+}
+
+#endif
+
+//
+// Malloc a string of sufficient size and read a string into it.
+//
+char** ReadFileData(const char* fileName)
+{
+ FILE *in = nullptr;
+ int errorCode = fopen_s(&in, fileName, "r");
+
+ int count = 0;
+ const int maxSourceStrings = 5; // for testing splitting shader/tokens across multiple strings
+ char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1)); // freed in FreeFileData()
+
+ if (errorCode || in == nullptr)
+ Error("unable to open input file");
+
+ while (fgetc(in) != EOF)
+ count++;
+
+ fseek(in, 0, SEEK_SET);
+
+ char *fdata = (char*)malloc(count+2); // freed before return of this function
+ if (! fdata)
+ Error("can't allocate memory");
+
+ if ((int)fread(fdata, 1, count, in) != count) {
+ free(fdata);
+ Error("can't read input file");
+ }
+
+ fdata[count] = '\0';
+ fclose(in);
+
+ if (count == 0) {
+ // recover from empty file
+ return_data[0] = (char*)malloc(count+2); // freed in FreeFileData()
+ return_data[0][0]='\0';
+ NumShaderStrings = 0;
+ free(fdata);
+
+ return return_data;
+ } else
+ NumShaderStrings = 1; // Set to larger than 1 for testing multiple strings
+
+ // compute how to split up the file into multiple strings, for testing multiple strings
+ int len = (int)(ceil)((float)count/(float)NumShaderStrings);
+ int ptr_len = 0;
+ int i = 0;
+ while (count > 0) {
+ return_data[i] = (char*)malloc(len + 2); // freed in FreeFileData()
+ memcpy(return_data[i], fdata + ptr_len, len);
+ return_data[i][len] = '\0';
+ count -= len;
+ ptr_len += len;
+ if (count < len) {
+ if (count == 0) {
+ NumShaderStrings = i + 1;
+ break;
+ }
+ len = count;
+ }
+ ++i;
+ }
+
+ free(fdata);
+
+ return return_data;
+}
+
+void FreeFileData(char** data)
+{
+ for(int i = 0; i < NumShaderStrings; i++)
+ free(data[i]);
+
+ free(data);
+}
+
+void InfoLogMsg(const char* msg, const char* name, const int num)
+{
+ if (num >= 0 )
+ printf("#### %s %s %d INFO LOG ####\n", msg, name, num);
+ else
+ printf("#### %s %s INFO LOG ####\n", msg, name);
+}
diff --git a/chromium/third_party/glslang/src/StandAlone/Worklist.h b/chromium/third_party/glslang/src/StandAlone/Worklist.h
new file mode 100644
index 00000000000..57dc0db7b29
--- /dev/null
+++ b/chromium/third_party/glslang/src/StandAlone/Worklist.h
@@ -0,0 +1,98 @@
+//
+//Copyright (C) 2013 LunarG, Inc.
+//
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. 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 WORKLIST_H_INCLUDED
+#define WORKLIST_H_INCLUDED
+
+#include "../glslang/OSDependent/osinclude.h"
+#include <string>
+#include <list>
+
+namespace glslang {
+
+ class TWorkItem {
+ public:
+ TWorkItem() { }
+ explicit TWorkItem(const std::string& s) :
+ name(s) { }
+ std::string name;
+ std::string results;
+ std::string resultsIndex;
+ };
+
+ class TWorklist {
+ public:
+ TWorklist() { }
+ virtual ~TWorklist() { }
+
+ void add(TWorkItem* item)
+ {
+ GetGlobalLock();
+
+ worklist.push_back(item);
+
+ ReleaseGlobalLock();
+ }
+
+ bool remove(TWorkItem*& item)
+ {
+ GetGlobalLock();
+
+ if (worklist.empty())
+ return false;
+ item = worklist.front();
+ worklist.pop_front();
+
+ ReleaseGlobalLock();
+
+ return true;
+ }
+
+ int size()
+ {
+ return (int)worklist.size();
+ }
+
+ bool empty()
+ {
+ return worklist.empty();
+ }
+
+ protected:
+ std::list<TWorkItem*> worklist;
+ };
+
+} // end namespace glslang
+
+#endif // WORKLIST_H_INCLUDED
diff --git a/chromium/third_party/glslang/src/StandAlone/spirv-remap.cpp b/chromium/third_party/glslang/src/StandAlone/spirv-remap.cpp
new file mode 100644
index 00000000000..f35b58eda99
--- /dev/null
+++ b/chromium/third_party/glslang/src/StandAlone/spirv-remap.cpp
@@ -0,0 +1,344 @@
+//
+//Copyright (C) 2015 LunarG, Inc.
+//
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. 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 <iostream>
+#include <fstream>
+#include <cstring>
+#include <stdexcept>
+
+#include "../SPIRV/SPVRemapper.h"
+
+namespace {
+
+ typedef unsigned int SpvWord;
+
+ // Poor man's basename: given a complete path, return file portion.
+ // E.g:
+ // Linux: /foo/bar/test -> test
+ // Win: c:\foo\bar\test -> test
+ // It's not very efficient, but that doesn't matter for our minimal-duty use.
+ // Using boost::filesystem would be better in many ways, but want to avoid that dependency.
+
+ // OS dependent path separator (avoiding boost::filesystem dependency)
+#if defined(_WIN32)
+ char path_sep_char() { return '\\'; }
+#else
+ char path_sep_char() { return '/'; }
+#endif
+
+ std::string basename(const std::string filename)
+ {
+ const size_t sepLoc = filename.find_last_of(path_sep_char());
+
+ return (sepLoc == filename.npos) ? filename : filename.substr(sepLoc+1);
+ }
+
+ void errHandler(const std::string& str) {
+ std::cout << str << std::endl;
+ exit(5);
+ }
+
+ void logHandler(const std::string& str) {
+ std::cout << str << std::endl;
+ }
+
+ // Read word stream from disk
+ void read(std::vector<SpvWord>& spv, const std::string& inFilename, int verbosity)
+ {
+ std::ifstream fp;
+
+ if (verbosity > 0)
+ logHandler(std::string(" reading: ") + inFilename);
+
+ spv.clear();
+ fp.open(inFilename, std::fstream::in | std::fstream::binary);
+
+ if (fp.fail())
+ errHandler("error opening file for read: ");
+
+ // Reserve space (for efficiency, not for correctness)
+ fp.seekg(0, fp.end);
+ spv.reserve(size_t(fp.tellg()) / sizeof(SpvWord));
+ fp.seekg(0, fp.beg);
+
+ while (!fp.eof()) {
+ SpvWord inWord;
+ fp.read((char *)&inWord, sizeof(inWord));
+
+ if (!fp.eof()) {
+ spv.push_back(inWord);
+ if (fp.fail())
+ errHandler(std::string("error reading file: ") + inFilename);
+ }
+ }
+ }
+
+ void write(std::vector<SpvWord>& spv, const std::string& outFile, int verbosity)
+ {
+ if (outFile.empty())
+ errHandler("missing output filename.");
+
+ std::ofstream fp;
+
+ if (verbosity > 0)
+ logHandler(std::string(" writing: ") + outFile);
+
+ fp.open(outFile, std::fstream::out | std::fstream::binary);
+
+ if (fp.fail())
+ errHandler(std::string("error opening file for write: ") + outFile);
+
+ for (auto it = spv.cbegin(); it != spv.cend(); ++it) {
+ SpvWord word = *it;
+ fp.write((char *)&word, sizeof(word));
+ if (fp.fail())
+ errHandler(std::string("error writing file: ") + outFile);
+ }
+
+ // file is closed by destructor
+ }
+
+ // Print helpful usage message to stdout, and exit
+ void usage(const char* const name, const char* const msg = 0)
+ {
+ if (msg)
+ std::cout << msg << std::endl << std::endl;
+
+ std::cout << "Usage: " << std::endl;
+
+ std::cout << " " << basename(name)
+ << " [-v[v[...]] | --verbose [int]]"
+ << " [--map (all|types|names|funcs)]"
+ << " [--dce (all|types|funcs)]"
+ << " [--opt (all|loadstore)]"
+ << " [--strip-all | --strip all | -s]"
+ << " [--do-everything]"
+ << " --input | -i file1 [file2...] --output|-o DESTDIR"
+ << std::endl;
+
+ std::cout << " " << basename(name) << " [--version | -V]" << std::endl;
+ std::cout << " " << basename(name) << " [--help | -?]" << std::endl;
+
+ exit(5);
+ }
+
+ // grind through each SPIR in turn
+ void execute(const std::vector<std::string>& inputFile, const std::string& outputDir,
+ int opts, int verbosity)
+ {
+ for (auto it = inputFile.cbegin(); it != inputFile.cend(); ++it) {
+ const std::string &filename = *it;
+ std::vector<SpvWord> spv;
+ read(spv, filename, verbosity);
+ spv::spirvbin_t(verbosity).remap(spv, opts);
+
+ const std::string outfile = outputDir + path_sep_char() + basename(filename);
+
+ write(spv, outfile, verbosity);
+ }
+
+ if (verbosity > 0)
+ std::cout << "Done: " << inputFile.size() << " file(s) processed" << std::endl;
+ }
+
+ // Parse command line options
+ void parseCmdLine(int argc, char** argv, std::vector<std::string>& inputFile,
+ std::string& outputDir,
+ int& options,
+ int& verbosity)
+ {
+ if (argc < 2)
+ usage(argv[0]);
+
+ verbosity = 0;
+ options = spv::spirvbin_t::NONE;
+
+ // Parse command line.
+ // boost::program_options would be quite a bit nicer, but we don't want to
+ // introduce a dependency on boost.
+ for (int a=1; a<argc; ) {
+ const std::string arg = argv[a];
+
+ if (arg == "--output" || arg == "-o") {
+ // Output directory
+ if (++a >= argc)
+ usage(argv[0], "--output requires an argument");
+ if (!outputDir.empty())
+ usage(argv[0], "--output can be provided only once");
+
+ outputDir = argv[a++];
+
+ // Remove trailing directory separator characters
+ while (!outputDir.empty() && outputDir.back() == path_sep_char())
+ outputDir.pop_back();
+
+ }
+ else if (arg == "-vv") { verbosity = 2; ++a; } // verbosity shortcuts
+ else if (arg == "-vvv") { verbosity = 3; ++a; } // ...
+ else if (arg == "-vvvv") { verbosity = 4; ++a; } // ...
+ else if (arg == "-vvvvv") { verbosity = 5; ++a; } // ...
+
+ else if (arg == "--verbose" || arg == "-v") {
+ ++a;
+ verbosity = 1;
+
+ if (a < argc) {
+ char* end_ptr = 0;
+ int verb = ::strtol(argv[a], &end_ptr, 10);
+ // If we have not read to the end of the string or
+ // the string contained no elements, then we do not want to
+ // store the value.
+ if (*end_ptr == '\0' && end_ptr != argv[a]) {
+ verbosity = verb;
+ ++a;
+ }
+ }
+ }
+ else if (arg == "--version" || arg == "-V") {
+ std::cout << basename(argv[0]) << " version 0.97 " << __DATE__ << " " << __TIME__ << std::endl;
+ exit(0);
+ } else if (arg == "--input" || arg == "-i") {
+ // Collect input files
+ for (++a; a < argc && argv[a][0] != '-'; ++a)
+ inputFile.push_back(argv[a]);
+ } else if (arg == "--do-everything") {
+ ++a;
+ options = options | spv::spirvbin_t::DO_EVERYTHING;
+ } else if (arg == "--strip-all" || arg == "-s") {
+ ++a;
+ options = options | spv::spirvbin_t::STRIP;
+ } else if (arg == "--strip") {
+ ++a;
+ if (strncmp(argv[a], "all", 3) == 0) {
+ options = options | spv::spirvbin_t::STRIP;
+ ++a;
+ }
+ } else if (arg == "--dce") {
+ // Parse comma (or colon, etc) separated list of things to dce
+ ++a;
+ for (const char* c = argv[a]; *c; ++c) {
+ if (strncmp(c, "all", 3) == 0) {
+ options = (options | spv::spirvbin_t::DCE_ALL);
+ c += 3;
+ } else if (strncmp(c, "*", 1) == 0) {
+ options = (options | spv::spirvbin_t::DCE_ALL);
+ c += 1;
+ } else if (strncmp(c, "funcs", 5) == 0) {
+ options = (options | spv::spirvbin_t::DCE_FUNCS);
+ c += 5;
+ } else if (strncmp(c, "types", 5) == 0) {
+ options = (options | spv::spirvbin_t::DCE_TYPES);
+ c += 5;
+ }
+ }
+ ++a;
+ } else if (arg == "--map") {
+ // Parse comma (or colon, etc) separated list of things to map
+ ++a;
+ for (const char* c = argv[a]; *c; ++c) {
+ if (strncmp(c, "all", 3) == 0) {
+ options = (options | spv::spirvbin_t::MAP_ALL);
+ c += 3;
+ } else if (strncmp(c, "*", 1) == 0) {
+ options = (options | spv::spirvbin_t::MAP_ALL);
+ c += 1;
+ } else if (strncmp(c, "types", 5) == 0) {
+ options = (options | spv::spirvbin_t::MAP_TYPES);
+ c += 5;
+ } else if (strncmp(c, "names", 5) == 0) {
+ options = (options | spv::spirvbin_t::MAP_NAMES);
+ c += 5;
+ } else if (strncmp(c, "funcs", 5) == 0) {
+ options = (options | spv::spirvbin_t::MAP_FUNCS);
+ c += 5;
+ }
+ }
+ ++a;
+ } else if (arg == "--opt") {
+ ++a;
+ for (const char* c = argv[a]; *c; ++c) {
+ if (strncmp(c, "all", 3) == 0) {
+ options = (options | spv::spirvbin_t::OPT_ALL);
+ c += 3;
+ } else if (strncmp(c, "*", 1) == 0) {
+ options = (options | spv::spirvbin_t::OPT_ALL);
+ c += 1;
+ } else if (strncmp(c, "loadstore", 9) == 0) {
+ options = (options | spv::spirvbin_t::OPT_LOADSTORE);
+ c += 9;
+ }
+ }
+ ++a;
+ } else if (arg == "--help" || arg == "-?") {
+ usage(argv[0]);
+ } else {
+ usage(argv[0], "Unknown command line option");
+ }
+ }
+ }
+
+} // namespace
+
+
+int main(int argc, char** argv)
+{
+ std::vector<std::string> inputFile;
+ std::string outputDir;
+ int opts;
+ int verbosity;
+
+#ifdef use_cpp11
+ // handle errors by exiting
+ spv::spirvbin_t::registerErrorHandler(errHandler);
+
+ // Log messages to std::cout
+ spv::spirvbin_t::registerLogHandler(logHandler);
+#endif
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ parseCmdLine(argc, argv, inputFile, outputDir, opts, verbosity);
+
+ if (outputDir.empty())
+ usage(argv[0], "Output directory required");
+
+ std::string errmsg;
+
+ // Main operations: read, remap, and write.
+ execute(inputFile, outputDir, opts, verbosity);
+
+ // If we get here, everything went OK! Nothing more to be done.
+}