[Mesa-dev] [PATCH 09/10] glsl: Update call_link_visitor to update max_ifc_array_access.

Paul Berry stereotype441 at gmail.com
Fri Sep 27 12:05:35 PDT 2013


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
---
 src/glsl/link_functions.cpp | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp
index b1a68fd..fd80099 100644
--- a/src/glsl/link_functions.cpp
+++ b/src/glsl/link_functions.cpp
@@ -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;
-- 
1.8.4



More information about the mesa-dev mailing list