diff --git a/glslang/CInterface/glslang_c_interface.cpp b/glslang/CInterface/glslang_c_interface.cpp index d0b20b8a..9405c565 100644 --- a/glslang/CInterface/glslang_c_interface.cpp +++ b/glslang/CInterface/glslang_c_interface.cpp @@ -397,6 +397,10 @@ GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int opt shader->shader->setInvertY(true); } + if (options & GLSLANG_SHADER_MAP_UNUSED_UNIFORMS) { + shader->shader->setMapUnusedUniforms(); + } + #ifdef ENABLE_HLSL if (options & GLSLANG_SHADER_HLSL_IO_MAPPING) { shader->shader->setHlslIoMapping(true); diff --git a/glslang/Include/glslang_c_shader_types.h b/glslang/Include/glslang_c_shader_types.h index bc02fb1c..1bb86126 100644 --- a/glslang/Include/glslang_c_shader_types.h +++ b/glslang/Include/glslang_c_shader_types.h @@ -212,9 +212,10 @@ typedef enum { GLSLANG_SHADER_AUTO_MAP_LOCATIONS = (1 << 1), GLSLANG_SHADER_VULKAN_RULES_RELAXED = (1 << 2), GLSLANG_SHADER_INVERT_Y = (1 << 3), + GLSLANG_SHADER_MAP_UNUSED_UNIFORMS = (1 << 4), #ifdef ENABLE_HLSL - GLSLANG_SHADER_HLSL_IO_MAPPING = (1 << 4), - GLSLANG_SHADER_HLSL_FLATTEN_UNIFORM_ARRAYS = (1 << 5), + GLSLANG_SHADER_HLSL_IO_MAPPING = (1 << 5), + GLSLANG_SHADER_HLSL_FLATTEN_UNIFORM_ARRAYS = (1 << 6), #endif LAST_ELEMENT_MARKER(GLSLANG_SHADER_COUNT), } glslang_shader_options_t; diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 040b21da..493c9299 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1843,6 +1843,8 @@ void TShader::setShiftUavBinding(unsigned int base) { setShiftBinding(EResUa void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSsbo, base); } // Enables binding automapping using TIoMapper void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } +void TShader::setMapUnusedUniforms() { intermediate->setMapUnusedUniforms(); } + // Enables position.Y output negation in vertex shader // Fragile: currently within one stage: simple auto-assignment of location diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 3e7749d3..450bd9ed 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -885,6 +885,8 @@ bool TDefaultIoResolverBase::doAutoBindingMapping() const { return referenceInte bool TDefaultIoResolverBase::doAutoLocationMapping() const { return referenceIntermediate.getAutoMapLocations(); } +bool TDefaultIoResolverBase::doMapUnusedUniforms() const { return referenceIntermediate.getMapUnusedUniforms(); } + TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) { return std::lower_bound(slots[set].begin(), slots[set].end(), slot); } @@ -1230,7 +1232,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent ent.newBinding = iter->second; } } - if (!hasBinding && (ent.live && doAutoBindingMapping())) { + if (!hasBinding && ((ent.live || doMapUnusedUniforms()) && doAutoBindingMapping())) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one int binding = getFreeSlot(resourceKey, getBaseBinding(stage, resource, set), numBindings); @@ -1408,7 +1410,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase { if (type.getQualifier().hasBinding()) { return ent.newBinding = reserveSlot( set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings); - } else if (ent.live && doAutoBindingMapping()) { + } else if ((ent.live || doMapUnusedUniforms()) && doAutoBindingMapping()) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set), numBindings); @@ -1490,7 +1492,7 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase { if (resource < EResCount) { if (type.getQualifier().hasBinding()) { return ent.newBinding = reserveSlot(set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding); - } else if (ent.live && doAutoBindingMapping()) { + } else if ((ent.live || doMapUnusedUniforms()) && doAutoBindingMapping()) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set)); diff --git a/glslang/MachineIndependent/iomapper.h b/glslang/MachineIndependent/iomapper.h index ef513d9a..d56a4420 100644 --- a/glslang/MachineIndependent/iomapper.h +++ b/glslang/MachineIndependent/iomapper.h @@ -72,6 +72,7 @@ public: virtual TResourceType getResourceType(const glslang::TType& type) = 0; bool doAutoBindingMapping() const; bool doAutoLocationMapping() const; + bool doMapUnusedUniforms() const; TSlotSet::iterator findSlot(int set, int slot); bool checkEmpty(int set, int slot); bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index a2fb9514..0aa5c385 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -344,6 +344,7 @@ public: numTaskEXTPayloads(0), autoMapBindings(false), autoMapLocations(false), + mapUnusedUniforms(false), flattenUniformArrays(false), useUnknownFormat(false), hlslOffsets(false), @@ -1008,6 +1009,9 @@ public: else return pos->second; } + + void setMapUnusedUniforms() { mapUnusedUniforms = true; } + bool getMapUnusedUniforms() const { return mapUnusedUniforms; } #ifdef ENABLE_HLSL void setHlslFunctionality1() { hlslFunctionality1 = true; } bool getHlslFunctionality1() const { return hlslFunctionality1; } @@ -1237,6 +1241,7 @@ protected: std::vector resourceSetBinding; bool autoMapBindings; bool autoMapLocations; + bool mapUnusedUniforms; bool flattenUniformArrays; bool useUnknownFormat; bool hlslOffsets; diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 739d7f7b..cf7d832e 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -491,6 +491,7 @@ public: GLSLANG_EXPORT void setResourceSetBinding(const std::vector& base); GLSLANG_EXPORT void setAutoMapBindings(bool map); GLSLANG_EXPORT void setAutoMapLocations(bool map); + GLSLANG_EXPORT void setMapUnusedUniforms(); GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc); GLSLANG_EXPORT void setUniformLocationBase(int base); GLSLANG_EXPORT void setInvertY(bool invert);