// 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;
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]) {
else
UserPreamble.addDef(getStringOperand("-D<macro> macro name"));
break;
+ case 'u':
+ uniformLocationOverrides.push_back(getUniformOverride());
+ break;
case 'E':
Options |= EOptionOutputPreprocessed;
break;
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) {
" -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"
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); }
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())
return -1;
}
- int location = nextUniformLocation;
+ int location = intermediate.getUniformLocationOverride(name);
+ if (location != -1)
+ return location;
+
+ location = nextUniformLocation;
nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type);
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; }
bool needToLegalize;
bool binaryDoubleOutput;
+ std::unordered_map<TString, int> uniformLocationOverrides;
+
private:
void operator=(TIntermediate&); // prevent assignments
};