Besides fixing the mentioned dEQP crashes, this patch also generally
fixes instance arrays with UBOs. The problem we have now is that each
element in the UBO instance array is a separate UBO mapped to a specific
binding point (and thus, a separate buffer), but we kill the instances
that are not being referenced in the shader code, so if we have
something like this:

layout(std140, binding=2) uniform Fragments {
   vec4 v0;
   vec4 v1;
} inst[3];

And then the shader code only references inst[1], for example:

vec4 tfOutput0 = inst[1].v0;

That UBO read for inst[1].v0 can fail as a consequence of the fact that
we we are killing UBOs for inst[0] and inst[2] and we shouldn't.

I hit this while developing SSBO, which is the same thing, and this
patch fixes the problem.

Iago

On Wed, 2015-03-11 at 10:01 +0100, Eduardo Lima Mitev wrote:
> From: Antia Puentes <apuen...@igalia.com>
> 
> Commmit 1ca25ab (glsl: Do not eliminate 'shared' or 'std140'
> blocks or block members) considers active 'shared' and 'std140'
> uniform blocks and uniform block arrays but did not include the
> block array elements. It was possible to have an active uniform
> block array without any elements marked as used, making the
> assertion ((b->num_array_elements > 0) == b->type->is_array())
> in link_uniform_blocks fail.
> 
> Fixes the following 5 dEQP tests:
> 
>  * dEQP-GLES3.functional.ubo.random.nested_structs_instance_arrays.18
>  * dEQP-GLES3.functional.ubo.random.nested_structs_instance_arrays.24
>  * dEQP-GLES3.functional.ubo.random.nested_structs_arrays_instance_arrays.19
>  * dEQP-GLES3.functional.ubo.random.all_per_block_buffers.49
>  * dEQP-GLES3.functional.ubo.random.all_shared_buffer.36
> ---
>  src/glsl/link_uniform_block_active_visitor.cpp | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/src/glsl/link_uniform_block_active_visitor.cpp 
> b/src/glsl/link_uniform_block_active_visitor.cpp
> index 292cde3..8379750 100644
> --- a/src/glsl/link_uniform_block_active_visitor.cpp
> +++ b/src/glsl/link_uniform_block_active_visitor.cpp
> @@ -105,6 +105,22 @@ link_uniform_block_active_visitor::visit(ir_variable 
> *var)
>     assert(b->num_array_elements == 0);
>     assert(b->array_elements == NULL);
>     assert(b->type != NULL);
> +   assert(!b->type->is_array() || b->has_instance_name);
> +
> +   /* For uniform block arrays declared with a shared or std140 layout
> +    * qualifier, mark all its instances as used.
> +    */
> +   if (b->type->is_array() && b->type->length > 0) {
> +      b->num_array_elements = b->type->length;
> +      b->array_elements = reralloc(this->mem_ctx,
> +                                   b->array_elements,
> +                                   unsigned,
> +                                   b->num_array_elements);
> +
> +      for (unsigned i = 0; i < b->num_array_elements; i++) {
> +         b->array_elements[i] = i;
> +      }
> +   }
>  
>     return visit_continue;
>  }
> @@ -146,6 +162,13 @@ 
> link_uniform_block_active_visitor::visit_enter(ir_dereference_array *ir)
>     assert((b->num_array_elements == 0) == (b->array_elements == NULL));
>     assert(b->type != NULL);
>  
> +   /* If the block array was declared with a shared or std140 layout 
> qualifier,
> +    * all its instances have been already marked as used (see
> +    * link_uniform_block_active_visitor::visit(ir_variable *) function).
> +    */
> +   if (var->type->interface_packing == GLSL_INTERFACE_PACKING_PACKED)
> +      return visit_continue;
> +
>     ir_constant *c = ir->array_index->as_constant();
>  
>     if (c) {


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to