From c6b29fbf9927467b21dca65539a1fa2c98f96e0e Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 3 Apr 2021 19:33:29 +0300 Subject: [PATCH] Add legacy conversion for binding layout qualifiers These are not yet used by Program because there's no good way to detect which uniforms had bindings in case the implementation does support the qualifiers. Anything missing a binding gets assigned binding 0, which is also a valid manually specified binding. Upcoming commits will move bindings entirely to GLSL side. --- source/glsl/compiler.cpp | 18 ++++++++++++++++++ source/glsl/compiler.h | 9 +++++++++ source/glsl/finalize.cpp | 23 +++++++++++++++++++++++ source/glsl/finalize.h | 1 + source/glsl/syntax.h | 2 ++ 5 files changed, 53 insertions(+) diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 1948722a..91a13f43 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -173,6 +173,20 @@ const map &Compiler::get_fragment_outputs() const throw invalid_operation("Compiler::get_fragment_outputs"); } +const map &Compiler::get_texture_bindings() const +{ + if(!compiled) + throw invalid_operation("Compiler::get_texture_bindings"); + return module->shared.texture_bindings; +} + +const map &Compiler::get_uniform_block_bindings() const +{ + if(!compiled) + throw invalid_operation("Compiler::get_uniform_block_bindings"); + return module->shared.uniform_block_bindings; +} + const SourceMap &Compiler::get_source_map() const { return module->source_map; @@ -373,6 +387,10 @@ void Compiler::finalize(Stage &stage, Mode mode) resolve(stage, RESOLVE_VARIABLES|RESOLVE_FUNCTIONS); PrecisionConverter().apply(stage); } + + // Collect bindings from all stages into the shared stage's maps + module->shared.texture_bindings.insert(stage.texture_bindings.begin(), stage.texture_bindings.end()); + module->shared.uniform_block_bindings.insert(stage.uniform_block_bindings.begin(), stage.uniform_block_bindings.end()); } void Compiler::inject_block(Block &target, const Block &source) diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index e30bd709..a1ab51f2 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -98,6 +98,15 @@ public: GLSL soucre). */ const std::map &get_fragment_outputs() const; + /** Returns a map of texture bindings. If the target GLSL version supports + bindings, the map is empty (bindings are included in the GLSL source). */ + const std::map &get_texture_bindings() const; + + /** Returns a map of uniform block bindings. If the target GLSL version + supports bindings, the map is empty (bindings are included in the GLSL + source). */ + const std::map &get_uniform_block_bindings() const; + /** Returns the mapping of source indices to filenames. Can be used to translate error messages. */ const SourceMap &get_source_map() const; diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 0805a29e..1b300e72 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -382,6 +382,14 @@ bool LegacyConverter::supports_uniform_location() const return check_extension(&Features::arb_explicit_uniform_location); } +bool LegacyConverter::supports_binding() const +{ + if(features.gl_api==OPENGL_ES2) + return check_version(Version(3, 10)); + else + return check_version(Version(4, 20)); +} + void LegacyConverter::visit(VariableDeclaration &var) { if(var.layout) @@ -420,6 +428,16 @@ void LegacyConverter::visit(VariableDeclaration &var) else ++i; } + else if(i->name=="binding" && !supports_binding()) + { + const TypeDeclaration *type = var.type_declaration; + while(const BasicTypeDeclaration *basic = dynamic_cast(type)) + type = basic->base_type; + if(dynamic_cast(type)) + stage->texture_bindings[var.name] = i->value; + + i = var.layout->qualifiers.erase(i); + } else ++i; } @@ -486,6 +504,11 @@ void LegacyConverter::visit(InterfaceBlock &iface) { if(i->name=="location" && !supports_interface_block_location()) i = iface.layout->qualifiers.erase(i); + else if(i->name=="binding" && !supports_binding()) + { + stage->uniform_block_bindings[iface.block_name] = i->value; + i = iface.layout->qualifiers.erase(i); + } else ++i; } diff --git a/source/glsl/finalize.h b/source/glsl/finalize.h index 36b34912..28145aeb 100644 --- a/source/glsl/finalize.h +++ b/source/glsl/finalize.h @@ -82,6 +82,7 @@ private: bool supports_centroid_sampling() const; bool supports_sample_sampling() const; bool supports_uniform_location() const; + bool supports_binding() const; virtual void visit(VariableDeclaration &); bool supports_interface_blocks(const std::string &) const; bool supports_interface_block_location() const; diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index 597a48e4..c8324c87 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -532,6 +532,8 @@ struct Stage std::map interface_blocks; std::map functions; std::map locations; + std::map texture_bindings; + std::map uniform_block_bindings; Features required_features; std::vector diagnostics; -- 2.43.0