glsl: Support transform feedback of varying structs.
[mesa.git] / src / glsl / opt_constant_variable.cpp
index 8068d0c1435fba86a2e09f2f48249a05285419d1..cbe6450c62f0b6b4cc8f68628ba5698bd444cf25 100644 (file)
@@ -37,6 +37,8 @@
 #include "ir_optimization.h"
 #include "glsl_types.h"
 
+namespace {
+
 struct assignment_entry {
    exec_node link;
    int assignment_count;
@@ -55,6 +57,8 @@ public:
    exec_list list;
 };
 
+} /* unnamed namespace */
+
 static struct assignment_entry *
 get_assignment_entry(ir_variable *var, exec_list *list)
 {
@@ -104,11 +108,8 @@ ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
    /* OK, now find if we actually have all the right conditions for
     * this to be a constant value assigned to the var.
     */
-   if (ir->condition) {
-      constval = ir->condition->constant_expression_value();
-      if (!constval || !constval->value.b[0])
-        return visit_continue;
-   }
+   if (ir->condition)
+      return visit_continue;
 
    ir_variable *var = ir->whole_variable_written();
    if (!var)
@@ -130,13 +131,14 @@ ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
 ir_visitor_status
 ir_constant_variable_visitor::visit_enter(ir_call *ir)
 {
-   exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
+   /* Mark any out parameters as assigned to */
+   exec_list_iterator sig_iter = ir->callee->parameters.iterator();
    foreach_iter(exec_list_iterator, iter, *ir) {
       ir_rvalue *param_rval = (ir_rvalue *)iter.get();
       ir_variable *param = (ir_variable *)sig_iter.get();
 
-      if (param->mode == ir_var_out ||
-         param->mode == ir_var_inout) {
+      if (param->mode == ir_var_function_out ||
+         param->mode == ir_var_function_inout) {
         ir_variable *var = param_rval->variable_referenced();
         struct assignment_entry *entry;
 
@@ -146,6 +148,17 @@ ir_constant_variable_visitor::visit_enter(ir_call *ir)
       }
       sig_iter.next();
    }
+
+   /* Mark the return storage as having been assigned to */
+   if (ir->return_deref != NULL) {
+      ir_variable *var = ir->return_deref->variable_referenced();
+      struct assignment_entry *entry;
+
+      assert(var);
+      entry = get_assignment_entry(var, &this->list);
+      entry->assignment_count++;
+   }
+
    return visit_continue;
 }