Externals: Update glslang to upstream commit 32d3ec3

This commit is contained in:
Stenzek
2018-06-02 07:26:43 +00:00
parent 160d16f1b3
commit bc96557ec4
149 changed files with 47830 additions and 13886 deletions

View File

@ -35,31 +35,25 @@
#ifndef GLSLANG_GTESTS_TEST_FIXTURE_H
#define GLSLANG_GTESTS_TEST_FIXTURE_H
#include <stdint.h>
#include <cstdint>
#include <fstream>
#include <sstream>
#include <streambuf>
#include <tuple>
#include <string>
#include <gtest/gtest.h>
#include "SPIRV/GlslangToSpv.h"
#include "SPIRV/disassemble.h"
#include "SPIRV/doc.h"
#include "SPIRV/SPVRemapper.h"
#include "StandAlone/ResourceLimits.h"
#include "glslang/Public/ShaderLang.h"
#include "Initializer.h"
#include "Settings.h"
// We need CMake to provide us the absolute path to the directory containing
// test files, so we are certain to find those files no matter where the test
// harness binary is generated. This provides out-of-source build capability.
#ifndef GLSLANG_TEST_DIRECTORY
#error \
"GLSLANG_TEST_DIRECTORY needs to be defined for gtest to locate test files."
#endif
namespace glslangtest {
// This function is used to provide custom test name suffixes based on the
@ -76,7 +70,7 @@ enum class Source {
// Enum for shader compilation semantics.
enum class Semantics {
OpenGL,
Vulkan,
Vulkan
};
// Enum for compilation target.
@ -93,6 +87,7 @@ EShMessages DeriveOptions(Source, Semantics, Target);
// Reads the content of the file at the given |path|. On success, returns true
// and the contents; otherwise, returns false and an empty string.
std::pair<bool, std::string> ReadFile(const std::string& path);
std::pair<bool, std::vector<std::uint32_t> > ReadSpvBinaryFile(const std::string& path);
// Writes the given |contents| into the file at the given |path|. Returns true
// on successful output.
@ -128,6 +123,16 @@ public:
ASSERT_TRUE(fileReadOk) << "Cannot open " << tag << " file: " << path;
}
// Tries to load the contents from the file at the given |path|. On success,
// writes the contents into |contents|. On failure, errors out.
void tryLoadSpvFile(const std::string& path, const std::string& tag,
std::vector<uint32_t>& contents)
{
bool fileReadOk;
std::tie(fileReadOk, contents) = ReadSpvBinaryFile(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,
@ -179,8 +184,6 @@ public:
shader->setStringsWithLengths(&shaderStrings, &shaderLengths, 1);
if (!entryPointName.empty()) shader->setEntryPoint(entryPointName.c_str());
// Reinitialize glslang if the semantics change.
GlobalTestSettings.initializer->acquire(controls);
return shader->parse(
(resources ? resources : &glslang::DefaultTBuiltInResource),
defaultVersion, isForwardCompatible, controls);
@ -193,11 +196,41 @@ public:
// the result and returns disassembly text.
GlslangResult compileAndLink(
const std::string shaderName, const std::string& code,
const std::string& entryPointName, EShMessages controls)
const std::string& entryPointName, EShMessages controls,
glslang::EShTargetClientVersion clientTargetVersion,
bool flattenUniformArrays = false,
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep,
bool enableOptimizer = false,
bool automap = true)
{
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
const EShLanguage stage = GetShaderStage(GetSuffix(shaderName));
glslang::TShader shader(stage);
if (automap) {
shader.setAutoMapLocations(true);
shader.setAutoMapBindings(true);
}
shader.setTextureSamplerTransformMode(texSampTransMode);
shader.setFlattenUniformArrays(flattenUniformArrays);
if (controls & EShMsgSpvRules) {
if (controls & EShMsgVulkanRules) {
shader.setEnvInput((controls & EShMsgReadHlsl) ? glslang::EShSourceHlsl
: glslang::EShSourceGlsl,
stage, glslang::EShClientVulkan, 100);
shader.setEnvClient(glslang::EShClientVulkan, clientTargetVersion);
shader.setEnvTarget(glslang::EShTargetSpv,
clientTargetVersion == glslang::EShTargetVulkan_1_1 ? glslang::EShTargetSpv_1_3
: glslang::EShTargetSpv_1_0);
} else {
shader.setEnvInput((controls & EShMsgReadHlsl) ? glslang::EShSourceHlsl
: glslang::EShSourceGlsl,
stage, glslang::EShClientOpenGL, 100);
shader.setEnvClient(glslang::EShClientOpenGL, clientTargetVersion);
shader.setEnvTarget(glslang::EshTargetSpv, glslang::EShTargetSpv_1_0);
}
}
glslang::TShader shader(kind);
bool success = compile(&shader, code, entryPointName, controls);
glslang::TProgram program;
@ -208,7 +241,64 @@ public:
if (success && (controls & EShMsgSpvRules)) {
std::vector<uint32_t> spirv_binary;
glslang::GlslangToSpv(*program.getIntermediate(kind),
glslang::SpvOptions options;
options.disableOptimizer = !enableOptimizer;
glslang::GlslangToSpv(*program.getIntermediate(stage),
spirv_binary, &logger, &options);
std::ostringstream disassembly_stream;
spv::Parameterize();
spv::Disassemble(disassembly_stream, spirv_binary);
return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},},
program.getInfoLog(), program.getInfoDebugLog(),
logger.getAllMessages(), disassembly_stream.str()};
} else {
return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},},
program.getInfoLog(), program.getInfoDebugLog(), "", ""};
}
}
// Compiles and links the given source |code| of the given shader
// |stage| into the target under the semantics specified via |controls|.
// Returns a GlslangResult instance containing all the information generated
// during the process. If the target includes SPIR-V, also disassembles
// the result and returns disassembly text.
GlslangResult compileLinkIoMap(
const std::string shaderName, const std::string& code,
const std::string& entryPointName, EShMessages controls,
int baseSamplerBinding,
int baseTextureBinding,
int baseImageBinding,
int baseUboBinding,
int baseSsboBinding,
bool autoMapBindings,
bool flattenUniformArrays)
{
const EShLanguage stage = GetShaderStage(GetSuffix(shaderName));
glslang::TShader shader(stage);
shader.setShiftSamplerBinding(baseSamplerBinding);
shader.setShiftTextureBinding(baseTextureBinding);
shader.setShiftImageBinding(baseImageBinding);
shader.setShiftUboBinding(baseUboBinding);
shader.setShiftSsboBinding(baseSsboBinding);
shader.setAutoMapBindings(autoMapBindings);
shader.setAutoMapLocations(true);
shader.setFlattenUniformArrays(flattenUniformArrays);
bool success = compile(&shader, code, entryPointName, controls);
glslang::TProgram program;
program.addShader(&shader);
success &= program.link(controls);
success &= program.mapIO();
spv::SpvBuildLogger logger;
if (success && (controls & EShMsgSpvRules)) {
std::vector<uint32_t> spirv_binary;
glslang::GlslangToSpv(*program.getIntermediate(stage),
spirv_binary, &logger);
std::ostringstream disassembly_stream;
@ -223,6 +313,71 @@ public:
}
}
// This is like compileAndLink but with remapping of the SPV binary
// through spirvbin_t::remap(). While technically this could be merged
// with compileAndLink() above (with the remap step optionally being a no-op)
// it is given separately here for ease of future extraction.
GlslangResult compileLinkRemap(
const std::string shaderName, const std::string& code,
const std::string& entryPointName, EShMessages controls,
const unsigned int remapOptions = spv::spirvbin_t::NONE)
{
const EShLanguage stage = GetShaderStage(GetSuffix(shaderName));
glslang::TShader shader(stage);
shader.setAutoMapBindings(true);
shader.setAutoMapLocations(true);
bool success = compile(&shader, code, entryPointName, controls);
glslang::TProgram program;
program.addShader(&shader);
success &= program.link(controls);
spv::SpvBuildLogger logger;
if (success && (controls & EShMsgSpvRules)) {
std::vector<uint32_t> spirv_binary;
glslang::GlslangToSpv(*program.getIntermediate(stage),
spirv_binary, &logger);
spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, remapOptions);
std::ostringstream disassembly_stream;
spv::Parameterize();
spv::Disassemble(disassembly_stream, spirv_binary);
return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},},
program.getInfoLog(), program.getInfoDebugLog(),
logger.getAllMessages(), disassembly_stream.str()};
} else {
return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},},
program.getInfoLog(), program.getInfoDebugLog(), "", ""};
}
}
// remap the binary in 'code' with the options in remapOptions
GlslangResult remap(
const std::string shaderName, const std::vector<uint32_t>& code,
EShMessages controls,
const unsigned int remapOptions = spv::spirvbin_t::NONE)
{
if ((controls & EShMsgSpvRules)) {
std::vector<uint32_t> spirv_binary(code); // scratch copy
spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, remapOptions);
std::ostringstream disassembly_stream;
spv::Parameterize();
spv::Disassemble(disassembly_stream, spirv_binary);
return {{{shaderName, "", ""},},
"", "",
"", disassembly_stream.str()};
} else {
return {{{shaderName, "", ""},}, "", "", "", ""};
}
}
void outputResultToStream(std::ostringstream* stream,
const GlslangResult& result,
EShMessages controls)
@ -252,8 +407,41 @@ public:
const std::string& testName,
Source source,
Semantics semantics,
glslang::EShTargetClientVersion clientTargetVersion,
Target target,
const std::string& entryPointName="")
bool automap = true,
const std::string& entryPointName="",
const std::string& baseDir="/baseResults/",
const bool enableOptimizer = false)
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname =
testDir + baseDir + testName + ".out";
std::string input, expectedOutput;
tryLoadFile(inputFname, "input", &input);
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
EShMessages controls = DeriveOptions(source, semantics, target);
if (enableOptimizer)
controls = static_cast<EShMessages>(controls & ~EShMsgHlslLegalization);
GlslangResult result = compileAndLink(testName, input, entryPointName, controls, clientTargetVersion, false,
EShTexSampTransKeep, enableOptimizer, automap);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
outputResultToStream(&stream, result, controls);
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
expectedOutputFname);
}
void loadFileCompileFlattenUniformsAndCheck(const std::string& testDir,
const std::string& testName,
Source source,
Semantics semantics,
Target target,
const std::string& entryPointName="")
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname =
@ -264,7 +452,99 @@ public:
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = compileAndLink(testName, input, entryPointName, controls);
GlslangResult result = compileAndLink(testName, input, entryPointName, controls,
glslang::EShTargetVulkan_1_0, true);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
outputResultToStream(&stream, result, controls);
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
expectedOutputFname);
}
void loadFileCompileIoMapAndCheck(const std::string& testDir,
const std::string& testName,
Source source,
Semantics semantics,
Target target,
const std::string& entryPointName,
int baseSamplerBinding,
int baseTextureBinding,
int baseImageBinding,
int baseUboBinding,
int baseSsboBinding,
bool autoMapBindings,
bool flattenUniformArrays)
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname =
testDir + "/baseResults/" + testName + ".out";
std::string input, expectedOutput;
tryLoadFile(inputFname, "input", &input);
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = compileLinkIoMap(testName, input, entryPointName, controls,
baseSamplerBinding, baseTextureBinding, baseImageBinding,
baseUboBinding, baseSsboBinding,
autoMapBindings,
flattenUniformArrays);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
outputResultToStream(&stream, result, controls);
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
expectedOutputFname);
}
void loadFileCompileRemapAndCheck(const std::string& testDir,
const std::string& testName,
Source source,
Semantics semantics,
Target target,
const std::string& entryPointName="",
const unsigned int remapOptions = spv::spirvbin_t::NONE)
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname =
testDir + "/baseResults/" + testName + ".out";
std::string input, expectedOutput;
tryLoadFile(inputFname, "input", &input);
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = compileLinkRemap(testName, input, entryPointName, controls, remapOptions);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
outputResultToStream(&stream, result, controls);
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
expectedOutputFname);
}
void loadFileRemapAndCheck(const std::string& testDir,
const std::string& testName,
Source source,
Semantics semantics,
Target target,
const unsigned int remapOptions = spv::spirvbin_t::NONE)
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname =
testDir + "/baseResults/" + testName + ".out";
std::vector<std::uint32_t> input;
std::string expectedOutput;
tryLoadSpvFile(inputFname, "input", input);
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = remap(testName, input, controls, remapOptions);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
@ -286,7 +566,7 @@ public:
glslang::TShader shader(EShLangVertex);
shader.setStringsWithLengths(&shaderStrings, &shaderLengths, 1);
std::string ppShader;
glslang::TShader::ForbidInclude includer;
glslang::TShader::ForbidIncluder includer;
const bool success = shader.preprocess(
&glslang::DefaultTBuiltInResource, defaultVersion, defaultProfile,
forceVersionProfile, isForwardCompatible, (EShMessages)(EShMsgOnlyPreprocessor | EShMsgCascadingErrors),
@ -327,6 +607,33 @@ public:
expectedErrorFname);
}
void loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(const std::string& testDir,
const std::string& testName,
Source source,
Semantics semantics,
Target target,
const std::string& entryPointName = "")
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname = testDir + "/baseResults/" + testName + ".out";
std::string input, expectedOutput;
tryLoadFile(inputFname, "input", &input);
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = compileAndLink(testName, input, entryPointName, controls,
glslang::EShTargetVulkan_1_0, false,
EShTexSampTransUpgradeTextureRemoveSampler);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
outputResultToStream(&stream, result, controls);
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
expectedOutputFname);
}
private:
const int defaultVersion;
const EProfile defaultProfile;