glsl: Update call_link_visitor to update max_ifc_array_access.

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>
This commit is contained in:
Paul Berry 2013-09-24 11:52:50 -07:00
parent e226669eea
commit 45e46b2e37

View 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);
} 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->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;