Added GLSL version override interface and CLI

This change list allows a user to override the GLSL version from the
command line or through the C and C++ interfaces. This will override the
override happens in ProcessDeferred() before DeduceVersionProfile() so
the process should still error out if the version is insufficient for
the shader code.

- Added --glsl-version <version> to CLI.
- Added parameter to route glslVersion as override version to
  preprocessor and parse functions to C++ interface.
- Updated C interface with function to override GLSL version.
This commit is contained in:
Hai Nguyen 2022-01-01 04:18:41 -05:00
parent 9b20b25138
commit 9a98d32366
5 changed files with 83 additions and 17 deletions

View File

@ -191,6 +191,9 @@ glslang::EShTargetClientVersion ClientVersion; // not valid until Client i
glslang::EShTargetLanguage TargetLanguage = glslang::EShTargetNone; glslang::EShTargetLanguage TargetLanguage = glslang::EShTargetNone;
glslang::EShTargetLanguageVersion TargetVersion; // not valid until TargetLanguage is set glslang::EShTargetLanguageVersion TargetVersion; // not valid until TargetLanguage is set
// GLSL version
int GlslVersion = 0; // GLSL version specified on CLI, overrides #version in shader source
std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
// Per descriptor-set binding base data // Per descriptor-set binding base data
@ -653,6 +656,48 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
lowerword == "flatten-uniform-array" || lowerword == "flatten-uniform-array" ||
lowerword == "fua") { lowerword == "fua") {
Options |= EOptionFlattenUniformArrays; Options |= EOptionFlattenUniformArrays;
} else if (lowerword == "glsl-version") {
if (argc > 1) {
if (strcmp(argv[1], "100") == 0) {
GlslVersion = 100;
} else if (strcmp(argv[1], "110") == 0) {
GlslVersion = 110;
} else if (strcmp(argv[1], "120") == 0) {
GlslVersion = 120;
} else if (strcmp(argv[1], "130") == 0) {
GlslVersion = 130;
} else if (strcmp(argv[1], "140") == 0) {
GlslVersion = 140;
} else if (strcmp(argv[1], "150") == 0) {
GlslVersion = 150;
} else if (strcmp(argv[1], "300es") == 0) {
GlslVersion = 300;
} else if (strcmp(argv[1], "310es") == 0) {
GlslVersion = 310;
} else if (strcmp(argv[1], "320es") == 0) {
GlslVersion = 320;
} else if (strcmp(argv[1], "330") == 0) {
GlslVersion = 330;
} else if (strcmp(argv[1], "400") == 0) {
GlslVersion = 400;
} else if (strcmp(argv[1], "410") == 0) {
GlslVersion = 410;
} else if (strcmp(argv[1], "420") == 0) {
GlslVersion = 420;
} else if (strcmp(argv[1], "430") == 0) {
GlslVersion = 430;
} else if (strcmp(argv[1], "440") == 0) {
GlslVersion = 440;
} else if (strcmp(argv[1], "450") == 0) {
GlslVersion = 450;
} else if (strcmp(argv[1], "460") == 0) {
GlslVersion = 460;
} else
Error("--glsl-version expected one of: 100, 110, 120, 130, 140, 150,\n"
"300es, 310es, 320es, 330\n"
"400, 410, 420, 430, 440, 450, 460");
}
bumpArg();
} else if (lowerword == "hlsl-offsets") { } else if (lowerword == "hlsl-offsets") {
Options |= EOptionHlslOffsets; Options |= EOptionHlslOffsets;
} else if (lowerword == "hlsl-iomap" || } else if (lowerword == "hlsl-iomap" ||
@ -1317,7 +1362,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (Options & EOptionOutputPreprocessed) { if (Options & EOptionOutputPreprocessed) {
std::string str; std::string str;
if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false, messages, &str, includer)) { if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, GlslVersion, false, messages, &str, includer)) {
PutsIfNonEmpty(str.c_str()); PutsIfNonEmpty(str.c_str());
} else { } else {
CompileFailed = true; CompileFailed = true;
@ -1328,7 +1373,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
} }
#endif #endif
if (! shader->parse(&Resources, defaultVersion, false, messages, includer)) if (! shader->parse(&Resources, defaultVersion, GlslVersion, false, messages, includer))
CompileFailed = true; CompileFailed = true;
program.addShader(shader); program.addShader(shader);
@ -1850,6 +1895,11 @@ void usage()
" -dumpfullversion | -dumpversion print bare major.minor.patchlevel\n" " -dumpfullversion | -dumpversion print bare major.minor.patchlevel\n"
" --flatten-uniform-arrays | --fua flatten uniform texture/sampler arrays to\n" " --flatten-uniform-arrays | --fua flatten uniform texture/sampler arrays to\n"
" scalars\n" " scalars\n"
" --glsl-version {100 | 110 | 120 | 130 | 140 | 150 |\n"
" 300es | 310es | 320es | 330\n"
" 400 | 410 | 420 | 430 | 440 | 450 | 460}\n"
" set GLSL version, overrides #version\n"
" in shader sourcen\n"
" --hlsl-offsets allow block offsets to follow HLSL rules\n" " --hlsl-offsets allow block offsets to follow HLSL rules\n"
" works independently of source language\n" " works independently of source language\n"
" --hlsl-iomap perform IO mapping in HLSL register space\n" " --hlsl-iomap perform IO mapping in HLSL register space\n"

View File

@ -57,6 +57,7 @@ static_assert(sizeof(glslang_resource_t) == sizeof(TBuiltInResource), "");
typedef struct glslang_shader_s { typedef struct glslang_shader_s {
glslang::TShader* shader; glslang::TShader* shader;
std::string preprocessedGLSL; std::string preprocessedGLSL;
int glslVersion;
} glslang_shader_t; } glslang_shader_t;
typedef struct glslang_program_s { typedef struct glslang_program_s {
@ -373,7 +374,11 @@ GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int opt
if (options & GLSLANG_SHADER_VULKAN_RULES_RELAXED) { if (options & GLSLANG_SHADER_VULKAN_RULES_RELAXED) {
shader->shader->setEnvInputVulkanRulesRelaxed(); shader->shader->setEnvInputVulkanRulesRelaxed();
} }
}
GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version)
{
shader->glslVersion = version;
} }
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader) GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader)
@ -390,6 +395,7 @@ GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const gls
input->default_version, input->default_version,
c_shader_profile(input->default_profile), c_shader_profile(input->default_profile),
input->force_default_version_and_profile != 0, input->force_default_version_and_profile != 0,
shader->glslVersion,
input->forward_compatible != 0, input->forward_compatible != 0,
(EShMessages)c_shader_messages(input->messages), (EShMessages)c_shader_messages(input->messages),
&shader->preprocessedGLSL, &shader->preprocessedGLSL,
@ -405,6 +411,7 @@ GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_
return shader->shader->parse( return shader->shader->parse(
reinterpret_cast<const TBuiltInResource*>(input->resource), reinterpret_cast<const TBuiltInResource*>(input->resource),
input->default_version, input->default_version,
shader->glslVersion,
input->forward_compatible != 0, input->forward_compatible != 0,
(EShMessages)c_shader_messages(input->messages) (EShMessages)c_shader_messages(input->messages)
); );

View File

@ -227,6 +227,7 @@ GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader);
GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base); GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base);
GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set); GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set);
GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t
GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version);
GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input); GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input);
GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input); GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input);
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader); GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader);

View File

@ -813,6 +813,7 @@ bool ProcessDeferred(
// set version/profile to defaultVersion/defaultProfile regardless of the #version // set version/profile to defaultVersion/defaultProfile regardless of the #version
// directive in the source code // directive in the source code
bool forceDefaultVersionAndProfile, bool forceDefaultVersionAndProfile,
int overrideVersion, // overrides version specified by #verison or default version
bool forwardCompatible, // give errors for use of deprecated features bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out EShMessages messages, // warnings/errors/AST; things to print out
TIntermediate& intermediate, // returned tree, etc. TIntermediate& intermediate, // returned tree, etc.
@ -900,6 +901,9 @@ bool ProcessDeferred(
version = defaultVersion; version = defaultVersion;
profile = defaultProfile; profile = defaultProfile;
} }
if (source == EShSourceGlsl && overrideVersion != 0) {
version = overrideVersion;
}
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
versionNotFirst, defaultVersion, source, version, profile, spvVersion); versionNotFirst, defaultVersion, source, version, profile, spvVersion);
@ -1275,6 +1279,7 @@ bool PreprocessDeferred(
int defaultVersion, // use 100 for ES environment, 110 for desktop int defaultVersion, // use 100 for ES environment, 110 for desktop
EProfile defaultProfile, EProfile defaultProfile,
bool forceDefaultVersionAndProfile, bool forceDefaultVersionAndProfile,
int overrideVersion, // use 0 if not overriding GLSL version
bool forwardCompatible, // give errors for use of deprecated features bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out EShMessages messages, // warnings/errors/AST; things to print out
TShader::Includer& includer, TShader::Includer& includer,
@ -1285,7 +1290,7 @@ bool PreprocessDeferred(
DoPreprocessing parser(outputString); DoPreprocessing parser(outputString);
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
preamble, optLevel, resources, defaultVersion, preamble, optLevel, resources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile, defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, intermediate, parser, forwardCompatible, messages, intermediate, parser,
false, includer, "", environment); false, includer, "", environment);
} }
@ -1314,6 +1319,7 @@ bool CompileDeferred(
int defaultVersion, // use 100 for ES environment, 110 for desktop int defaultVersion, // use 100 for ES environment, 110 for desktop
EProfile defaultProfile, EProfile defaultProfile,
bool forceDefaultVersionAndProfile, bool forceDefaultVersionAndProfile,
int overrideVersion, // use 0 if not overriding GLSL version
bool forwardCompatible, // give errors for use of deprecated features bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out EShMessages messages, // warnings/errors/AST; things to print out
TIntermediate& intermediate,// returned tree, etc. TIntermediate& intermediate,// returned tree, etc.
@ -1324,7 +1330,7 @@ bool CompileDeferred(
DoFullParse parser; DoFullParse parser;
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
preamble, optLevel, resources, defaultVersion, preamble, optLevel, resources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile, defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, intermediate, parser, forwardCompatible, messages, intermediate, parser,
true, includer, sourceEntryPointName, environment); true, includer, sourceEntryPointName, environment);
} }
@ -1477,6 +1483,7 @@ int ShCompile(
const TBuiltInResource* resources, const TBuiltInResource* resources,
int /*debugOptions*/, int /*debugOptions*/,
int defaultVersion, // use 100 for ES environment, 110 for desktop int defaultVersion, // use 100 for ES environment, 110 for desktop
int overrideVersion, // use 0 if not overriding GLSL version
bool forwardCompatible, // give errors for use of deprecated features bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages // warnings/errors/AST; things to print out EShMessages messages // warnings/errors/AST; things to print out
) )
@ -1498,7 +1505,7 @@ int ShCompile(
TIntermediate intermediate(compiler->getLanguage()); TIntermediate intermediate(compiler->getLanguage());
TShader::ForbidIncluder includer; TShader::ForbidIncluder includer;
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr, bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
"", optLevel, resources, defaultVersion, ENoProfile, false, "", optLevel, resources, defaultVersion, ENoProfile, false, overrideVersion,
forwardCompatible, messages, intermediate, includer); forwardCompatible, messages, intermediate, includer);
// //
@ -1897,7 +1904,7 @@ void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlatt
// //
// Returns true for success. // Returns true for success.
// //
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, int overrideVersion,
bool forwardCompatible, EShMessages messages, Includer& includer) bool forwardCompatible, EShMessages messages, Includer& includer)
{ {
if (! InitThread()) if (! InitThread())
@ -1909,7 +1916,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
return CompileDeferred(compiler, strings, numStrings, lengths, stringNames, return CompileDeferred(compiler, strings, numStrings, lengths, stringNames,
preamble, EShOptNone, builtInResources, defaultVersion, preamble, EShOptNone, builtInResources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile, defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName, forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
&environment); &environment);
} }
@ -1922,7 +1929,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
// is not an officially supported or fully working path. // is not an officially supported or fully working path.
bool TShader::preprocess(const TBuiltInResource* builtInResources, bool TShader::preprocess(const TBuiltInResource* builtInResources,
int defaultVersion, EProfile defaultProfile, int defaultVersion, EProfile defaultProfile,
bool forceDefaultVersionAndProfile, bool forceDefaultVersionAndProfile, int overrideVersion,
bool forwardCompatible, EShMessages message, bool forwardCompatible, EShMessages message,
std::string* output_string, std::string* output_string,
Includer& includer) Includer& includer)
@ -1936,7 +1943,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
EShOptNone, builtInResources, defaultVersion, EShOptNone, builtInResources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile, defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, message, includer, *intermediate, output_string, forwardCompatible, message, includer, *intermediate, output_string,
&environment); &environment);
} }

View File

@ -334,6 +334,7 @@ GLSLANG_EXPORT int ShCompile(
const TBuiltInResource *resources, const TBuiltInResource *resources,
int debugOptions, int debugOptions,
int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader
int overrideVersion = 0, // overrides #version in GLSL shader, use 0 to disable
bool forwardCompatible = false, // give errors for use of deprecated features bool forwardCompatible = false, // give errors for use of deprecated features
EShMessages messages = EShMsgDefault // warnings and errors EShMessages messages = EShMsgDefault // warnings and errors
); );
@ -647,33 +648,33 @@ public:
GLSLANG_EXPORT bool parse( GLSLANG_EXPORT bool parse(
const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
bool forceDefaultVersionAndProfile, bool forwardCompatible, bool forceDefaultVersionAndProfile, int overrideVersion, bool forwardCompatible,
EShMessages, Includer&); EShMessages, Includer&);
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, int overrideVersion,
bool forwardCompatible, EShMessages messages) bool forwardCompatible, EShMessages messages)
{ {
TShader::ForbidIncluder includer; TShader::ForbidIncluder includer;
return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer); return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, overrideVersion, forwardCompatible, messages, includer);
} }
// Equivalent to parse() without a default profile and without forcing defaults. // Equivalent to parse() without a default profile and without forcing defaults.
bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages) bool parse(const TBuiltInResource* builtInResources, int defaultVersion, int overrideVersion, bool forwardCompatible, EShMessages messages)
{ {
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages); return parse(builtInResources, defaultVersion, ENoProfile, false, overrideVersion, forwardCompatible, messages);
} }
bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages, bool parse(const TBuiltInResource* builtInResources, int defaultVersion, int overrideVersion, bool forwardCompatible, EShMessages messages,
Includer& includer) Includer& includer)
{ {
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer); return parse(builtInResources, defaultVersion, ENoProfile, false, overrideVersion, forwardCompatible, messages, includer);
} }
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path. // is not an officially supported or fully working path.
GLSLANG_EXPORT bool preprocess( GLSLANG_EXPORT bool preprocess(
const TBuiltInResource* builtInResources, int defaultVersion, const TBuiltInResource* builtInResources, int defaultVersion,
EProfile defaultProfile, bool forceDefaultVersionAndProfile, EProfile defaultProfile, bool forceDefaultVersionAndProfile, int overrideVersion,
bool forwardCompatible, EShMessages message, std::string* outputString, bool forwardCompatible, EShMessages message, std::string* outputString,
Includer& includer); Includer& includer);