]> git.tdb.fi Git - libs/gl.git/commitdiff
Add legacy conversion for binding layout qualifiers
authorMikko Rasa <tdb@tdb.fi>
Sat, 3 Apr 2021 16:33:29 +0000 (19:33 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 3 Apr 2021 17:57:53 +0000 (20:57 +0300)
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
source/glsl/compiler.h
source/glsl/finalize.cpp
source/glsl/finalize.h
source/glsl/syntax.h

index 1948722a6c29b24fb3a36c92759a3dec592479d3..91a13f4398ed02af892f4f1db567b216fab5b5fa 100644 (file)
@@ -173,6 +173,20 @@ const map<string, unsigned> &Compiler::get_fragment_outputs() const
        throw invalid_operation("Compiler::get_fragment_outputs");
 }
 
+const map<string, unsigned> &Compiler::get_texture_bindings() const
+{
+       if(!compiled)
+               throw invalid_operation("Compiler::get_texture_bindings");
+       return module->shared.texture_bindings;
+}
+
+const map<string, unsigned> &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)
index e30bd709bb2aadef5cd585e114f6fdb6bc7f5ac8..a1ab51f254a771566c337f7b392484a3984a4157 100644 (file)
@@ -98,6 +98,15 @@ public:
        GLSL soucre). */
        const std::map<std::string, unsigned> &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<std::string, unsigned> &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<std::string, unsigned> &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;
index 0805a29e830eb45d626970a80faa1d10ae072c3b..1b300e72a872cd55aa19727cf284efba5607b26f 100644 (file)
@@ -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<const BasicTypeDeclaration *>(type))
+                                       type = basic->base_type;
+                               if(dynamic_cast<const ImageTypeDeclaration *>(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;
                }
index 36b349125f51eb236cff061d9c08c0ad49c2a542..28145aebd9e2837abedcb2b5ec54ae3b8f745414 100644 (file)
@@ -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;
index 597a48e4b39bf47f8e78c9b781006238a071a167..c8324c87460065a2a0d452d455600d017de8eabb 100644 (file)
@@ -532,6 +532,8 @@ struct Stage
        std::map<std::string, InterfaceBlock *> interface_blocks;
        std::map<std::string, FunctionDeclaration *> functions;
        std::map<std::string, unsigned> locations;
+       std::map<std::string, unsigned> texture_bindings;
+       std::map<std::string, unsigned> uniform_block_bindings;
        Features required_features;
        std::vector<Diagnostic> diagnostics;