glsl: Update call_link_visitor to update max_ifc_array_access.
authorPaul Berry <stereotype441@gmail.com>
Tue, 24 Sep 2013 18:52:50 +0000 (11:52 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 9 Oct 2013 23:49:46 +0000 (16:49 -0700)
When multiple shaders of the same type access an interface block
containing an unsized array, we need to set the array size based on
the maximum array element accessed across all the shaders.  This is
similar to what we already do with unsized arrays occurring outside of
interface blocks.

Note: one corner case is not yet addressed by these patches: the case
where one compilation unit defines an interface block containing
unsized arrays and another compilation unit defines the same interface
block containing sized arrays.

Fixes piglit test:
- spec/glsl-1.50/execution/unsized-in-named-interface-block-multiple

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/glsl/link_functions.cpp

index b1a68fd55b04fe27f9d9a4943c5df8e76d64c66f..fd80099980266fa7d48fcfbe93f9faeed3d96795 100644 (file)
@@ -223,18 +223,31 @@ public:
            var = ir->var->clone(linked, NULL);
            linked->symbols->add_variable(var);
            linked->ir->push_head(var);
-        } else if (var->type->is_array()) {
-           /* It is possible to have a global array declared in multiple
-            * shaders without a size.  The array is implicitly sized by the
-            * maximal access to it in *any* shader.  Because of this, we
-            * need to track the maximal access to the array as linking pulls
-            * more functions in that access the array.
-            */
-           var->max_array_access =
-              MAX2(var->max_array_access, ir->var->max_array_access);
-
-           if (var->type->length == 0 && ir->var->type->length != 0)
-              var->type = ir->var->type;
+        } else {
+            if (var->type->is_array()) {
+               /* It is possible to have a global array declared in multiple
+                * shaders without a size.  The array is implicitly sized by
+                * the maximal access to it in *any* shader.  Because of this,
+                * we need to track the maximal access to the array as linking
+                * pulls more functions in that access the array.
+                */
+               var->max_array_access =
+                  MAX2(var->max_array_access, ir->var->max_array_access);
+
+               if (var->type->length == 0 && ir->var->type->length != 0)
+                  var->type = ir->var->type;
+            }
+            if (var->is_interface_instance()) {
+               /* Similarly, we need implicit sizes of arrays within interface
+                * blocks to be sized by the maximal access in *any* shader.
+                */
+               for (unsigned i = 0; i < var->get_interface_type()->length;
+                    i++) {
+                  var->max_ifc_array_access[i] =
+                     MAX2(var->max_ifc_array_access[i],
+                          ir->var->max_ifc_array_access[i]);
+               }
+            }
         }
 
         ir->var = var;