]> git.tdb.fi Git - libs/gl.git/commitdiff
Handle redeclaration of variables in VariableResolver
authorMikko Rasa <tdb@tdb.fi>
Fri, 12 Mar 2021 21:58:14 +0000 (23:58 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 12 Mar 2021 22:07:42 +0000 (00:07 +0200)
source/glsl/compiler.cpp
source/glsl/generate.cpp
source/glsl/generate.h

index 3516048ca7e62ae9fa83dc52c0f14a7fb0329745..b4b63e27637c32231341a2631383c0b972be8019 100644 (file)
@@ -214,7 +214,6 @@ void Compiler::append_stage(Stage &stage)
                target->required_features.glsl_version = stage.required_features.glsl_version;
        for(NodeList<Statement>::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
                target->content.body.push_back(*i);
-       DeclarationCombiner().apply(*target);
 }
 
 void Compiler::import(DataFile::Collection *resources, const string &name)
index e5855e94cacb701c4ab96bec16324335fcccf910..a2fd3608220e836d268d2310ad1ec6c8915e4550 100644 (file)
@@ -12,57 +12,6 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-void DeclarationCombiner::apply(Stage &stage)
-{
-       stage.content.visit(*this);
-       NodeRemover().apply(stage, nodes_to_remove);
-}
-
-void DeclarationCombiner::visit(Block &block)
-{
-       if(current_block)
-               return;
-
-       TraversingVisitor::visit(block);
-}
-
-void DeclarationCombiner::visit(VariableDeclaration &var)
-{
-       VariableDeclaration *&ptr = variables[var.name];
-       if(ptr)
-       {
-               ptr->type = var.type;
-               if(var.init_expression)
-                       ptr->init_expression = var.init_expression;
-               if(var.layout)
-               {
-                       if(ptr->layout)
-                       {
-                               for(vector<Layout::Qualifier>::iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ++i)
-                               {
-                                       bool found = false;
-                                       for(vector<Layout::Qualifier>::iterator j=ptr->layout->qualifiers.begin(); (!found && j!=ptr->layout->qualifiers.end()); ++j)
-                                               if(j->name==i->name)
-                                               {
-                                                       j->has_value = i->value;
-                                                       j->value = i->value;
-                                                       found = true;
-                                               }
-
-                                       if(!found)
-                                               ptr->layout->qualifiers.push_back(*i);
-                               }
-                       }
-                       else
-                               ptr->layout = var.layout;
-               }
-               nodes_to_remove.insert(&var);
-       }
-       else
-               ptr = &var;
-}
-
-
 ConstantSpecializer::ConstantSpecializer():
        values(0)
 { }
@@ -270,6 +219,7 @@ bool VariableResolver::apply(Stage &s)
        s.interface_blocks.clear();
        r_any_resolved = false;
        s.content.visit(*this);
+       NodeRemover().apply(s, nodes_to_remove);
        return r_any_resolved;
 }
 
@@ -485,10 +435,45 @@ void VariableResolver::visit(Assignment &assign)
        assign.self_referencing = (r_self_referencing || assign.oper->token[0]!='=');
 }
 
+void VariableResolver::merge_layouts(Layout &to_layout, const Layout &from_layout)
+{
+       for(vector<Layout::Qualifier>::const_iterator i=from_layout.qualifiers.begin(); i!=from_layout.qualifiers.end(); ++i)
+       {
+               bool found = false;
+               for(vector<Layout::Qualifier>::iterator j=to_layout.qualifiers.begin(); (!found && j!=to_layout.qualifiers.end()); ++j)
+                       if(j->name==i->name)
+                       {
+                               j->has_value = i->value;
+                               j->value = i->value;
+                               found = true;
+                       }
+
+               if(!found)
+                       to_layout.qualifiers.push_back(*i);
+       }
+}
+
 void VariableResolver::visit(VariableDeclaration &var)
 {
        TraversingVisitor::visit(var);
-       current_block->variables.insert(make_pair(var.name, &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)
+       {
+               if(var.init_expression)
+                       ptr->init_expression = var.init_expression;
+               if(var.layout)
+               {
+                       if(ptr->layout)
+                               merge_layouts(*ptr->layout, *var.layout);
+                       else
+                               ptr->layout = var.layout;
+               }
+               nodes_to_remove.insert(&var);
+
+               r_any_resolved = true;
+       }
 }
 
 void VariableResolver::visit(InterfaceBlock &iface)
index 0a940cea5599a8f1381aadf6b9051989ac607a29..402f07f480b239e39f76dd7334656337955b2ff3 100644 (file)
@@ -11,23 +11,6 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-/** Combines multiple declarations of the same identifier into one. */
-class DeclarationCombiner: private TraversingVisitor
-{
-private:
-       std::map<std::string, std::vector<FunctionDeclaration *> > functions;
-       std::map<std::string, VariableDeclaration *> variables;
-       std::set<Node *> nodes_to_remove;
-
-public:
-       void apply(Stage &);
-
-private:
-       virtual void visit(Block &);
-       virtual void visit(VariableDeclaration &);
-       virtual void visit(FunctionDeclaration &) { }
-};
-
 /** Manipulates specialization constants.  If values are specified, turns
 specialization constants into normal constants.  Without values assigns
 automatic constant_ids to specialization constants. */
@@ -99,6 +82,7 @@ private:
        bool record_target;
        bool r_self_referencing;
        Assignment::Target r_assignment_target;
+       std::set<Node *> nodes_to_remove;
 
 public:
        VariableResolver();
@@ -116,6 +100,7 @@ private:
        virtual void visit(Swizzle &);
        virtual void visit(BinaryExpression &);
        virtual void visit(Assignment &);
+       void merge_layouts(Layout &, const Layout &);
        virtual void visit(VariableDeclaration &);
        virtual void visit(InterfaceBlock &);
 };