]> git.tdb.fi Git - libs/gl.git/commitdiff
Support redeclaring builtins defined in an interface block
authorMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2021 11:49:59 +0000 (14:49 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2021 15:35:27 +0000 (18:35 +0300)
source/glsl/resolve.cpp
source/glsl/resolve.h

index c03ecae08c80d5bbe9be4c942a8379482b2bbe14..f72dedfd2aa006fe71409fad62c559908be118bd 100644 (file)
@@ -151,8 +151,8 @@ bool VariableResolver::apply(Stage &s)
        s.interface_blocks.clear();
        r_any_resolved = false;
        s.content.visit(*this);
-       for(VariableDeclaration *v: redeclared_builtins)
-               v->source = GENERATED_SOURCE;
+       for(Statement *b: redeclared_builtins)
+               b->source = GENERATED_SOURCE;
        NodeRemover().apply(s, nodes_to_remove);
        return r_any_resolved;
 }
@@ -393,31 +393,59 @@ void VariableResolver::merge_layouts(Layout &to_layout, const Layout &from_layou
 void VariableResolver::visit(VariableDeclaration &var)
 {
        TraversingVisitor::visit(var);
-       VariableDeclaration *&ptr = current_block->variables[var.name];
-       if(!ptr)
-               ptr = &var;
-       else if(!current_block->parent && ptr->interface==var.interface && ptr->type==var.type)
+
+       auto i = current_block->variables.find(var.name);
+       VariableDeclaration *existing = 0;
+       InterfaceBlock *block = 0;
+       if(i!=current_block->variables.end())
+               existing = i->second;
+       else if(!current_block->parent)
        {
-               if(ptr->source==BUILTIN_SOURCE)
-               {
-                       redeclared_builtins.push_back(ptr);
+               const map<string, InterfaceBlock *> &blocks = stage->interface_blocks;
+               for(auto j=blocks.begin(); j!=blocks.end(); ++j)
+                       if(j->second->instance_name.empty() && j->second->struct_declaration)
+                       {
+                               map<string, VariableDeclaration *> &block_vars = j->second->struct_declaration->members.variables;
+                               i = block_vars.find(var.name);
+                               if(i!=block_vars.end())
+                               {
+                                       existing = i->second;
+                                       block = j->second;
+                                       break;
+                               }
+                       }
+       }
 
+       if(!existing)
+               current_block->variables.insert(make_pair(var.name, &var));
+       else if(!current_block->parent && (block ? block->interface : existing->interface)==var.interface && existing->type==var.type && existing->array==var.array)
+       {
+               if(existing->source==BUILTIN_SOURCE)
+               {
                        if(var.layout)
                        {
-                               if(ptr->layout)
-                                       merge_layouts(*ptr->layout, *var.layout);
+                               if(existing->layout)
+                                       merge_layouts(*existing->layout, *var.layout);
                                else
-                                       ptr->layout = var.layout;
+                                       existing->layout = var.layout;
                        }
                        if(var.array_size)
-                               ptr->array_size = var.array_size;
+                               existing->array_size = var.array_size;
+
+                       redeclared_builtins.push_back(existing);
+                       if(block)
+                       {
+                               redeclared_builtins.push_back(block);
+                               for(const auto &kvp: block->struct_declaration->members.variables)
+                                       redeclared_builtins.push_back(kvp.second);
+                       }
 
                        nodes_to_remove.insert(&var);
                        r_any_resolved = true;
                }
-               else if(ptr->array && !ptr->array_size && !var.layout && !var.init_expression)
+               else if(existing->array && !existing->array_size && !var.layout && !var.init_expression)
                {
-                       ptr->array_size = var.array_size;
+                       existing->array_size = var.array_size;
                        nodes_to_remove.insert(&var);
                        r_any_resolved = true;
                }
index f32d0cd530fe03b289d04176da2535e43e86221a..856117272f892e9c5e60cd0a6f0ca53e34f6e567 100644 (file)
@@ -61,7 +61,7 @@ private:
        bool record_target = false;
        bool r_self_referencing = false;
        Assignment::Target r_assignment_target;
-       std::vector<VariableDeclaration *> redeclared_builtins;
+       std::vector<Statement *> redeclared_builtins;
        std::set<Node *> nodes_to_remove;
 
 public: