diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index fd14476c..48fcb7fe 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -173,6 +173,9 @@ std::vector Processes; // what should be record // Per descriptor-set binding base data typedef std::map TPerSetBaseBinding; +std::vector> uniformLocationOverrides; +int uniformBase = 0; + std::array, glslang::EResCount> baseBinding; std::array, glslang::EResCount> baseBindingForSet; std::array, EShLangCount> baseResourceSetBinding; @@ -431,6 +434,22 @@ void ProcessArguments(std::vector>& workItem Options &= ~EOptionVulkanRules; }; + const auto getUniformOverride = [getStringOperand]() { + const char *arg = getStringOperand("-u:"); + 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]) { @@ -447,6 +466,12 @@ void ProcessArguments(std::vector>& workItem } else if (lowerword == "auto-map-locations" || // synonyms lowerword == "aml") { Options |= EOptionAutoMapLocations; + } else if (lowerword == "uniform-base") { + if (argc <= 1) + Error("no provided for --uniform-base"); + uniformBase = ::strtol(argv[1], NULL, 10); + bumpArg(); + break; } else if (lowerword == "client") { if (argc > 1) { if (strcmp(argv[1], "vulkan100") == 0) @@ -572,6 +597,9 @@ void ProcessArguments(std::vector>& workItem else UserPreamble.addDef(getStringOperand("-D macro name")); break; + case 'u': + uniformLocationOverrides.push_back(getUniformOverride()); + break; case 'E': Options |= EOptionOutputPreprocessed; break; @@ -898,6 +926,13 @@ void CompileAndLinkShaderUnits(std::vector compUnits) if (Options & EOptionInvertY) shader->setInvertY(true); + for (auto& uniOverride : uniformLocationOverrides) { + shader->addUniformLocationOverride(uniOverride.first.c_str(), + uniOverride.second); + } + + shader->setUniformLocationBase(uniformBase); + // Set up the environment, some subsettings take precedence over earlier // ways of setting things. if (Options & EOptionSpv) { @@ -1417,6 +1452,8 @@ 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: specify a uniform location override for --aml\n" + " --uniform-base set a base to use for generated uniform locations\n" " --auto-map-bindings | --amb automatically bind uniform variables\n" " without explicit bindings\n" " --auto-map-locations | --aml automatically locate input/output lacking\n" diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index d3340440..522ded16 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1759,6 +1759,14 @@ 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); +} +void TShader::setUniformLocationBase(int base) +{ + intermediate->setUniformLocationBase(base); +} // See comment above TDefaultHlslIoMapper in iomapper.cpp: void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 66f6f308..e68e32fb 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -359,7 +359,7 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver { TDefaultIoResolverBase(const TIntermediate &intermediate) : intermediate(intermediate), - nextUniformLocation(0), + nextUniformLocation(intermediate.getUniformLocationBase()), nextInputLocation(0), nextOutputLocation(0) { } @@ -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); diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 3fab9ce9..59fbaa98 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -252,7 +252,8 @@ public: hlslIoMapping(false), textureSamplerTransformMode(EShTexSampTransKeep), needToLegalize(false), - binaryDoubleOutput(false) + binaryDoubleOutput(false), + uniformLocationBase(0) { localSize[0] = 1; localSize[1] = 1; @@ -671,6 +672,23 @@ public: void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } const std::vector& 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 setUniformLocationBase(int base) { uniformLocationBase = base; } + int getUniformLocationBase() const { return uniformLocationBase; } + void setNeedsLegalization() { needToLegalize = true; } bool needsLegalization() const { return needToLegalize; } @@ -796,6 +814,9 @@ protected: bool needToLegalize; bool binaryDoubleOutput; + std::unordered_map uniformLocationOverrides; + int uniformLocationBase; + private: void operator=(TIntermediate&); // prevent assignments }; diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 4ba1976c..74ab3529 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -413,6 +413,8 @@ public: void setResourceSetBinding(const std::vector& base); void setAutoMapBindings(bool map); void setAutoMapLocations(bool map); + void addUniformLocationOverride(const char* name, int loc); + void setUniformLocationBase(int base); void setInvertY(bool invert); void setHlslIoMapping(bool hlslIoMap); void setFlattenUniformArrays(bool flatten);