Added GLSL version override interface and CLI
authorHai Nguyen <codingforlove@gmail.com>
Sat, 1 Jan 2022 09:18:41 +0000 (04:18 -0500)
committerHai Nguyen <codingforlove@gmail.com>
Sat, 1 Jan 2022 09:31:44 +0000 (04:31 -0500)
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.

StandAlone/StandAlone.cpp
glslang/CInterface/glslang_c_interface.cpp
glslang/Include/glslang_c_interface.h
glslang/MachineIndependent/ShaderLang.cpp
glslang/Public/ShaderLang.h

index f5ce631..fe33722 100644 (file)
@@ -191,6 +191,9 @@ glslang::EShTargetClientVersion ClientVersion;       // not valid until Client i
 glslang::EShTargetLanguage TargetLanguage = glslang::EShTargetNone;
 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
 
 // 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 == "fua") {
                         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") {
                         Options |= EOptionHlslOffsets;
                     } else if (lowerword == "hlsl-iomap" ||
@@ -1317,7 +1362,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
 #ifndef GLSLANG_WEB
         if (Options & EOptionOutputPreprocessed) {
             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());
             } else {
                 CompileFailed = true;
@@ -1328,7 +1373,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
         }
 #endif
 
-        if (! shader->parse(&Resources, defaultVersion, false, messages, includer))
+        if (! shader->parse(&Resources, defaultVersion, GlslVersion, false, messages, includer))
             CompileFailed = true;
 
         program.addShader(shader);
@@ -1850,6 +1895,11 @@ void usage()
            "  -dumpfullversion | -dumpversion   print bare major.minor.patchlevel\n"
            "  --flatten-uniform-arrays | --fua  flatten uniform texture/sampler arrays to\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"
            "                                    works independently of source language\n"
            "  --hlsl-iomap                      perform IO mapping in HLSL register space\n"
index da1cd14..8f2b9b3 100644 (file)
@@ -57,6 +57,7 @@ static_assert(sizeof(glslang_resource_t) == sizeof(TBuiltInResource), "");
 typedef struct glslang_shader_s {
     glslang::TShader* shader;
     std::string preprocessedGLSL;
+    int glslVersion;
 } glslang_shader_t;
 
 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) {
         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)
@@ -390,6 +395,7 @@ GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const gls
         input->default_version,
         c_shader_profile(input->default_profile),
         input->force_default_version_and_profile != 0,
+        shader->glslVersion,
         input->forward_compatible != 0,
         (EShMessages)c_shader_messages(input->messages),
         &shader->preprocessedGLSL,
@@ -405,6 +411,7 @@ GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_
     return shader->shader->parse(
         reinterpret_cast<const TBuiltInResource*>(input->resource),
         input->default_version,
+        shader->glslVersion,
         input->forward_compatible != 0,
         (EShMessages)c_shader_messages(input->messages)
     );
index 14ab6ac..a98a7e1 100644 (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_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_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_parse(glslang_shader_t* shader, const glslang_input_t* input);
 GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader);
index bcf2c33..434de01 100644 (file)
@@ -813,6 +813,7 @@ bool ProcessDeferred(
     // set version/profile to defaultVersion/defaultProfile regardless of the #version
     // directive in the source code
     bool forceDefaultVersionAndProfile,
+    int overrideVersion, // overrides version specified by #verison or default version
     bool forwardCompatible,     // give errors for use of deprecated features
     EShMessages messages,       // warnings/errors/AST; things to print out
     TIntermediate& intermediate, // returned tree, etc.
@@ -900,6 +901,9 @@ bool ProcessDeferred(
         version = defaultVersion;
         profile = defaultProfile;
     }
+    if (source == EShSourceGlsl && overrideVersion != 0) {
+        version = overrideVersion;
+    }
 
     bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
                                             versionNotFirst, defaultVersion, source, version, profile, spvVersion);
@@ -1275,6 +1279,7 @@ bool PreprocessDeferred(
     int defaultVersion,         // use 100 for ES environment, 110 for desktop
     EProfile defaultProfile,
     bool forceDefaultVersionAndProfile,
+    int overrideVersion,        // use 0 if not overriding GLSL version
     bool forwardCompatible,     // give errors for use of deprecated features
     EShMessages messages,       // warnings/errors/AST; things to print out
     TShader::Includer& includer,
@@ -1285,7 +1290,7 @@ bool PreprocessDeferred(
     DoPreprocessing parser(outputString);
     return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
                            preamble, optLevel, resources, defaultVersion,
-                           defaultProfile, forceDefaultVersionAndProfile,
+                           defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
                            forwardCompatible, messages, intermediate, parser,
                            false, includer, "", environment);
 }
@@ -1314,6 +1319,7 @@ bool CompileDeferred(
     int defaultVersion,         // use 100 for ES environment, 110 for desktop
     EProfile defaultProfile,
     bool forceDefaultVersionAndProfile,
+    int overrideVersion,        // use 0 if not overriding GLSL version
     bool forwardCompatible,     // give errors for use of deprecated features
     EShMessages messages,       // warnings/errors/AST; things to print out
     TIntermediate& intermediate,// returned tree, etc.
@@ -1324,7 +1330,7 @@ bool CompileDeferred(
     DoFullParse parser;
     return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
                            preamble, optLevel, resources, defaultVersion,
-                           defaultProfile, forceDefaultVersionAndProfile,
+                           defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
                            forwardCompatible, messages, intermediate, parser,
                            true, includer, sourceEntryPointName, environment);
 }
@@ -1477,6 +1483,7 @@ int ShCompile(
     const TBuiltInResource* resources,
     int /*debugOptions*/,
     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
     EShMessages messages       // warnings/errors/AST; things to print out
     )
@@ -1498,7 +1505,7 @@ int ShCompile(
     TIntermediate intermediate(compiler->getLanguage());
     TShader::ForbidIncluder includer;
     bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
-                                   "", optLevel, resources, defaultVersion, ENoProfile, false,
+                                   "", optLevel, resources, defaultVersion, ENoProfile, false, overrideVersion,
                                    forwardCompatible, messages, intermediate, includer);
 
     //
@@ -1897,7 +1904,7 @@ void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlatt
 //
 // 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)
 {
     if (! InitThread())
@@ -1909,7 +1916,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
 
     return CompileDeferred(compiler, strings, numStrings, lengths, stringNames,
                            preamble, EShOptNone, builtInResources, defaultVersion,
-                           defaultProfile, forceDefaultVersionAndProfile,
+                           defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
                            forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
                            &environment);
 }
@@ -1922,7 +1929,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
 // is not an officially supported or fully working path.
 bool TShader::preprocess(const TBuiltInResource* builtInResources,
                          int defaultVersion, EProfile defaultProfile,
-                         bool forceDefaultVersionAndProfile,
+                         bool forceDefaultVersionAndProfile, int overrideVersion,
                          bool forwardCompatible, EShMessages message,
                          std::string* output_string,
                          Includer& includer)
@@ -1936,7 +1943,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
 
     return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
                               EShOptNone, builtInResources, defaultVersion,
-                              defaultProfile, forceDefaultVersionAndProfile,
+                              defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
                               forwardCompatible, message, includer, *intermediate, output_string,
                               &environment);
 }
index 7e5d2cd..cdd321e 100644 (file)
@@ -334,6 +334,7 @@ GLSLANG_EXPORT int ShCompile(
     const TBuiltInResource *resources,
     int debugOptions,
     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
     EShMessages messages = EShMsgDefault // warnings and errors
     );
@@ -647,33 +648,33 @@ public:
 
     GLSLANG_EXPORT bool parse(
         const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
-        bool forceDefaultVersionAndProfile, bool forwardCompatible,
+        bool forceDefaultVersionAndProfile, int overrideVersion, bool forwardCompatible,
         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)
     {
         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.
-    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)
     {
-        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
     // is not an officially supported or fully working path.
     GLSLANG_EXPORT bool preprocess(
         const TBuiltInResource* builtInResources, int defaultVersion,
-        EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+        EProfile defaultProfile, bool forceDefaultVersionAndProfile, int overrideVersion,
         bool forwardCompatible, EShMessages message, std::string* outputString,
         Includer& includer);