Add a command-line option to override uniform locations
authorNeil Roberts <nroberts@igalia.com>
Tue, 20 Mar 2018 16:30:53 +0000 (17:30 +0100)
committerAlejandro Piñeiro <apinheiro@igalia.com>
Tue, 2 Oct 2018 10:15:22 +0000 (12:15 +0200)
StandAlone/StandAlone.cpp
glslang/MachineIndependent/ShaderLang.cpp
glslang/MachineIndependent/iomapper.cpp
glslang/MachineIndependent/localintermediate.h
glslang/Public/ShaderLang.h

index fd14476..e15994b 100644 (file)
@@ -173,6 +173,8 @@ std::vector<std::string> Processes;                     // what should be record
 // Per descriptor-set binding base data
 typedef std::map<unsigned int, unsigned int> TPerSetBaseBinding;
 
+std::vector<std::pair<std::string, int>> uniformLocationOverrides;
+
 std::array<std::array<unsigned int, EShLangCount>, glslang::EResCount> baseBinding;
 std::array<std::array<TPerSetBaseBinding, EShLangCount>, glslang::EResCount> baseBindingForSet;
 std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;
@@ -431,6 +433,22 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
         Options &= ~EOptionVulkanRules;
     };
 
+    const auto getUniformOverride = [getStringOperand]() {
+        const char *arg = getStringOperand("-u<name>:<location>");
+        const char *split = strchr(arg, ':');
+        if (split == NULL) {
+            printf("%s: missing location\n", arg);
+            exit(EFailUsage);
+        }
+        errno = 0;
+        int location = ::strtol(split + 1, NULL, 10);
+        if (errno) {
+            printf("%s: invalid location\n", arg);
+            exit(EFailUsage);
+        }
+        return std::make_pair(std::string(arg, split - arg), location);
+    };
+
     for (bumpArg(); argc >= 1; bumpArg()) {
         if (argv[0][0] == '-') {
             switch (argv[0][1]) {
@@ -572,6 +590,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                 else
                     UserPreamble.addDef(getStringOperand("-D<macro> macro name"));
                 break;
+            case 'u':
+                uniformLocationOverrides.push_back(getUniformOverride());
+                break;
             case 'E':
                 Options |= EOptionOutputPreprocessed;
                 break;
@@ -898,6 +919,11 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
         if (Options & EOptionInvertY)
             shader->setInvertY(true);
 
+        for (auto& uniOverride : uniformLocationOverrides) {
+            shader->addUniformLocationOverride(uniOverride.first.c_str(),
+                                               uniOverride.second);
+        }
+
         // Set up the environment, some subsettings take precedence over earlier
         // ways of setting things.
         if (Options & EOptionSpv) {
@@ -1417,6 +1443,7 @@ void usage()
            "  -w | --suppress-warnings\n"
            "              suppress GLSL warnings, except as required by \"#extension : warn\"\n"
            "  -x          save binary output as text-based 32-bit hexadecimal numbers\n"
+           "  -u<name>:<loc> specify a uniform location override for --aml\n"
            "  --auto-map-bindings | --amb       automatically bind uniform variables\n"
            "                                    without explicit bindings\n"
            "  --auto-map-locations | --aml      automatically locate input/output lacking\n"
index d334044..1a30fd3 100755 (executable)
@@ -1759,6 +1759,10 @@ void TShader::setAutoMapBindings(bool map)              { intermediate->setAutoM
 void TShader::setInvertY(bool invert)                   { intermediate->setInvertY(invert); }
 // Fragile: currently within one stage: simple auto-assignment of location
 void TShader::setAutoMapLocations(bool map)             { intermediate->setAutoMapLocations(map); }
+void TShader::addUniformLocationOverride(const char* name, int loc)
+{
+    intermediate->addUniformLocationOverride(name, loc);
+}
 // See comment above TDefaultHlslIoMapper in iomapper.cpp:
 void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslIoMapping(hlslIoMap); }
 void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlattenUniformArrays(flatten); }
index 66f6f30..73ea801 100644 (file)
@@ -434,7 +434,7 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
 
         return 0;
     }
-    int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
+    int resolveUniformLocation(EShLanguage /*stage*/, const char* name, const glslang::TType& type, bool /*is_live*/) override
     {
         // kick out of not doing this
         if (!doAutoLocationMapping())
@@ -455,7 +455,11 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
                 return -1;
         }
 
-        int location = nextUniformLocation;
+        int location = intermediate.getUniformLocationOverride(name);
+        if (location != -1)
+                return location;
+
+        location = nextUniformLocation;
 
         nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type);
 
index 3fab9ce..a95e26f 100644 (file)
@@ -671,6 +671,20 @@ public:
     void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
     const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
 
+    void addUniformLocationOverride(const TString& name, int location)
+    {
+            uniformLocationOverrides[name] = location;
+    }
+
+    int getUniformLocationOverride(const TString& name) const
+    {
+            auto pos = uniformLocationOverrides.find(name);
+            if (pos == uniformLocationOverrides.end())
+                    return -1;
+            else
+                    return pos->second;
+    }
+
     void setNeedsLegalization() { needToLegalize = true; }
     bool needsLegalization() const { return needToLegalize; }
 
@@ -796,6 +810,8 @@ protected:
     bool needToLegalize;
     bool binaryDoubleOutput;
 
+    std::unordered_map<TString, int> uniformLocationOverrides;
+
 private:
     void operator=(TIntermediate&); // prevent assignments
 };
index 4ba1976..cd9f25e 100644 (file)
@@ -413,6 +413,7 @@ public:
     void setResourceSetBinding(const std::vector<std::string>& base);
     void setAutoMapBindings(bool map);
     void setAutoMapLocations(bool map);
+    void addUniformLocationOverride(const char* name, int loc);
     void setInvertY(bool invert);
     void setHlslIoMapping(bool hlslIoMap);
     void setFlattenUniformArrays(bool flatten);