]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/optimize.cpp
Transform interface block contents into structs
[libs/gl.git] / source / glsl / optimize.cpp
index 88a323992636b0642d05d4134ee81d68bdebce9c..c1431f2b6e9d9e33ed522cd853bcd326bbb3414a 100644 (file)
@@ -202,6 +202,7 @@ void FunctionInliner::visit_and_inline(RefPtr<Expression> &ptr)
                ptr = r_inline_result;
                r_any_inlined = true;
        }
+       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(Block &block)
@@ -218,20 +219,17 @@ void FunctionInliner::visit(Block &block)
 void FunctionInliner::visit(UnaryExpression &unary)
 {
        visit_and_inline(unary.expression);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(BinaryExpression &binary)
 {
        visit_and_inline(binary.left);
        visit_and_inline(binary.right);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(MemberAccess &memacc)
 {
        visit_and_inline(memacc.left);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(FunctionCall &call)
@@ -259,8 +257,6 @@ void FunctionInliner::visit(FunctionCall &call)
                inlined further. */
                inlineable.erase(current_function);
        }
-       else
-               r_inline_result = 0;
 }
 
 void FunctionInliner::visit(ExpressionStatement &expr)
@@ -272,7 +268,6 @@ void FunctionInliner::visit(VariableDeclaration &var)
 {
        if(var.init_expression)
                visit_and_inline(var.init_expression);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(FunctionDeclaration &func)
@@ -364,6 +359,7 @@ void ExpressionInliner::visit_and_record(RefPtr<Expression> &ptr, const Operator
                        r_ref_info->inline_on_rhs = on_rhs;
                }
        }
+       r_ref_info = 0;
 }
 
 void ExpressionInliner::inline_expression(Expression &expr, RefPtr<Expression> &ptr, const Operator *outer_oper, const Operator *inner_oper, bool on_rhs)
@@ -439,7 +435,6 @@ void ExpressionInliner::visit(VariableReference &var)
 void ExpressionInliner::visit(MemberAccess &memacc)
 {
        visit_and_record(memacc.left, memacc.oper, false);
-       r_ref_info = 0;
        r_oper = memacc.oper;
        r_trivial = false;
 }
@@ -448,7 +443,6 @@ void ExpressionInliner::visit(UnaryExpression &unary)
 {
        SetFlag set_target(mutating, mutating || unary.oper->token[1]=='+' || unary.oper->token[1]=='-');
        visit_and_record(unary.expression, unary.oper, false);
-       r_ref_info = 0;
        r_oper = unary.oper;
        r_trivial = false;
 }
@@ -460,7 +454,6 @@ void ExpressionInliner::visit(BinaryExpression &binary)
                SetFlag clear_target(mutating, false);
                visit_and_record(binary.right, binary.oper, true);
        }
-       r_ref_info = 0;
        r_oper = binary.oper;
        r_trivial = false;
 }
@@ -489,7 +482,6 @@ void ExpressionInliner::visit(Assignment &assign)
                }
        }
 
-       r_ref_info = 0;
        r_oper = assign.oper;
        r_trivial = false;
 }
@@ -498,7 +490,6 @@ void ExpressionInliner::visit(FunctionCall &call)
 {
        for(NodeArray<Expression>::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
                visit_and_record(*i, 0, false);
-       r_ref_info = 0;
        r_oper = 0;
        r_trivial = false;
 }
@@ -629,6 +620,29 @@ bool UnusedTypeRemover::apply(Stage &stage)
        return !unused_nodes.empty();
 }
 
+void UnusedTypeRemover::visit(Literal &literal)
+{
+       unused_nodes.erase(literal.type);
+}
+
+void UnusedTypeRemover::visit(UnaryExpression &unary)
+{
+       unused_nodes.erase(unary.type);
+       TraversingVisitor::visit(unary);
+}
+
+void UnusedTypeRemover::visit(BinaryExpression &binary)
+{
+       unused_nodes.erase(binary.type);
+       TraversingVisitor::visit(binary);
+}
+
+void UnusedTypeRemover::visit(FunctionCall &call)
+{
+       unused_nodes.erase(call.type);
+       TraversingVisitor::visit(call);
+}
+
 void UnusedTypeRemover::visit(BasicTypeDeclaration &type)
 {
        if(type.base_type)
@@ -646,6 +660,7 @@ void UnusedTypeRemover::visit(ImageTypeDeclaration &type)
 void UnusedTypeRemover::visit(StructDeclaration &strct)
 {
        unused_nodes.insert(&strct);
+       TraversingVisitor::visit(strct);
 }
 
 void UnusedTypeRemover::visit(VariableDeclaration &var)
@@ -653,6 +668,17 @@ void UnusedTypeRemover::visit(VariableDeclaration &var)
        unused_nodes.erase(var.type_declaration);
 }
 
+void UnusedTypeRemover::visit(InterfaceBlock &iface)
+{
+       unused_nodes.erase(iface.type_declaration);
+}
+
+void UnusedTypeRemover::visit(FunctionDeclaration &func)
+{
+       unused_nodes.erase(func.return_type_declaration);
+       TraversingVisitor::visit(func);
+}
+
 
 UnusedVariableRemover::UnusedVariableRemover():
        aggregate(0),
@@ -669,9 +695,19 @@ bool UnusedVariableRemover::apply(Stage &stage)
        BlockVariableMap &global_variables = variables.back();
        for(BlockVariableMap::iterator i=global_variables.begin(); i!=global_variables.end(); ++i)
        {
+               string interface = i->first->interface;
+               bool linked = i->first->linked_declaration;
+               map<VariableDeclaration *, Node *>::iterator j = aggregates.find(i->first);
+               if(j!=aggregates.end())
+                       if(InterfaceBlock *iface = dynamic_cast<InterfaceBlock *>(j->second))
+                       {
+                               interface = iface->interface;
+                               linked = iface->linked_block;
+                       }
+
                /* Don't remove output variables which are used by the next stage or the
                graphics API. */
-               if(i->first->interface=="out" && (stage.type==Stage::FRAGMENT || i->first->linked_declaration || !i->first->name.compare(0, 3, "gl_")))
+               if(interface=="out" && (stage.type==Stage::FRAGMENT || linked || !i->first->name.compare(0, 3, "gl_")))
                        continue;
 
                // Mark other unreferenced global variables as unused.
@@ -812,7 +848,7 @@ void UnusedVariableRemover::visit(InterfaceBlock &iface)
 {
        SetForScope<Node *> set(aggregate, &iface);
        unused_nodes.insert(&iface);
-       TraversingVisitor::visit(iface);
+       iface.struct_declaration->members.visit(*this);
 }
 
 void UnusedVariableRemover::visit(FunctionDeclaration &func)