linker: Set sizes for non-global arrays as well
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 25 Jan 2011 20:04:08 +0000 (12:04 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Tue, 25 Jan 2011 21:41:26 +0000 (13:41 -0800)
Previously only global arrays with implicit sizes would be patched.
This causes all arrays that are actually accessed to be sized.

Fixes piglit test glsl-fs-implicit-array-size-02.

NOTE: This is a candidate for the 7.9 and 7.10 branches.

src/glsl/linker.cpp

index 5702ec0..58b0294 100644 (file)
@@ -890,30 +890,29 @@ link_intrastage_shaders(void *mem_ctx,
 
    free(linking_shaders);
 
-   /* Make a pass over all global variables to ensure that arrays with
+   /* Make a pass over all variable declarations to ensure that arrays with
     * unspecified sizes have a size specified.  The size is inferred from the
     * max_array_access field.
     */
    if (linked != NULL) {
-      foreach_list(node, linked->ir) {
-        ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
-        if (var == NULL)
-           continue;
-
-        if ((var->mode != ir_var_auto) && (var->mode != ir_var_temporary))
-           continue;
-
-        if (!var->type->is_array() || (var->type->length != 0))
-           continue;
+      class array_sizing_visitor : public ir_hierarchical_visitor {
+      public:
+        virtual ir_visitor_status visit(ir_variable *var)
+        {
+           if (var->type->is_array() && (var->type->length == 0)) {
+              const glsl_type *type =
+                 glsl_type::get_array_instance(var->type->fields.array,
+                                               var->max_array_access);
+
+              assert(type != NULL);
+              var->type = type;
+           }
 
-        const glsl_type *type =
-           glsl_type::get_array_instance(var->type->fields.array,
-                                         var->max_array_access);
+           return visit_continue;
+        }
+      } v;
 
-        assert(type != NULL);
-        var->type = type;
-      }
+      v.run(linked->ir);
    }
 
    return linked;