[Mesa-dev] [PATCH v2 36/82] glsl: add support for unsized arrays in shader storage blocks

Samuel Iglesias Gonsálvez siglesias at igalia.com
Mon Jun 15 06:36:43 PDT 2015



On 15/06/15 13:25, Timothy Arceri wrote:
> On Wed, 2015-06-03 at 09:01 +0200, Iago Toral Quiroga wrote:
>> From: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>>
>> They only can be defined in the last position of the shader
>> storage blocks.
>>
>> When an unsized array is used in different shaders, it might be
>> converted in different sized arrays, avoid get a linker error
>> in that case.
>>
>> Signed-off-by: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>> ---
>>  src/glsl/ast_array_index.cpp |   6 +--
>>  src/glsl/ast_to_hir.cpp      |  32 +++++++++++++
>>  src/glsl/ir.cpp              |   1 +
>>  src/glsl/ir.h                |  14 ++++++
>>  src/glsl/linker.cpp          | 107 ++++++++++++++++++++++++++++---------------
>>  5 files changed, 121 insertions(+), 39 deletions(-)
>>
>> diff --git a/src/glsl/ast_array_index.cpp b/src/glsl/ast_array_index.cpp
>> index 752d86f..481efae 100644
>> --- a/src/glsl/ast_array_index.cpp
>> +++ b/src/glsl/ast_array_index.cpp
>> @@ -106,7 +106,6 @@ update_max_array_access(ir_rvalue *ir, int idx, YYLTYPE *loc,
>>     }
>>  }
>>  
>> -
>>  ir_rvalue *
>>  _mesa_ast_array_index_to_hir(void *mem_ctx,
>>  			     struct _mesa_glsl_parse_state *state,
>> @@ -182,8 +181,9 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
>>        if (array->type->is_array())
>>           update_max_array_access(array, idx, &loc, state);
>>     } else if (const_index == NULL && array->type->is_array()) {
>> -      if (array->type->is_unsized_array()) {
>> -	 _mesa_glsl_error(&loc, state, "unsized array index must be constant");
>> +      if (array->type->is_unsized_array() &&
>> +          array->variable_referenced()->data.mode != ir_var_shader_storage) {
>> +            _mesa_glsl_error(&loc, state, "unsized array index must be constant");
>>        } else if (array->type->fields.array->is_interface()
>>                   && array->variable_referenced()->data.mode == ir_var_uniform
>>                   && !state->is_version(400, 0) && !state->ARB_gpu_shader5_enable) {
>> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
>> index e1e5ca9..3ec28dd 100644
>> --- a/src/glsl/ast_to_hir.cpp
>> +++ b/src/glsl/ast_to_hir.cpp
>> @@ -5507,6 +5507,19 @@ private:
>>     bool found;
>>  };
>>  
>> +static bool
>> +is_unsized_array_last_element(ir_variable *v)
>> +{
>> +   const glsl_type *interface_type = v->get_interface_type();
>> +   int length = interface_type->length;
>> +
>> +   assert(v->type->is_unsized_array());
>> +
>> +   /* Check if it is the last element of the interface */
>> +   if (strcmp(interface_type->fields.structure[length-1].name, v->name) == 0)
>> +      return true;
>> +   return false;
>> +}
>>  
>>  ir_rvalue *
>>  ast_interface_block::hir(exec_list *instructions,
>> @@ -5828,6 +5841,15 @@ ast_interface_block::hir(exec_list *instructions,
>>           var->data.explicit_binding = this->layout.flags.q.explicit_binding;
>>           var->data.binding = this->layout.binding;
>>  
>> +         if (var->is_in_shader_storage_block() && var->type->is_unsized_array()) {
>> +            var->data.from_ssbo_unsized_array = true;
>> +            if (!is_unsized_array_last_element(var)) {
>> +               _mesa_glsl_error(&loc, state, "unsized array `%s' should be the"
>> +                                 " last member of a shader storage block",
>> +                                 var->name);
>> +            }
>> +         }
> 
> The existing comment above this is misleading I think its a copy and
> paste error from the non instance name block code below.
> 
> Anyway to get to the point here you are testing if the block itself is
> an unsized array not the member inside the block.
> 

Yes, you are right. I am going to modify it.

> Also when gles both this test and the test below should throw an error
> when there is an unsized array member but its not in a shader storage
> block.
> 
> "If an array is declared as the last member of a shader storage block
> and the size is not specified at compile-time, it is sized at run-time.
> In all other cases,  arrays are sized only at compile-time."
> 

Good catch! I am going to fix it too.

Thanks for the review!

Sam

> 
>> +
>>           state->symbols->add_variable(var);
>>           instructions->push_tail(var);
>>        }
>> @@ -5900,6 +5922,16 @@ ast_interface_block::hir(exec_list *instructions,
>>           var->data.explicit_binding = this->layout.flags.q.explicit_binding;
>>           var->data.binding = this->layout.binding;
>>  
>> +         if (var->data.mode == ir_var_shader_storage && var->type->is_unsized_array()) {
>> +            var->data.from_ssbo_unsized_array = true;
>> +            if (var->is_in_shader_storage_block() &&
>> +                !is_unsized_array_last_element(var)) {
>> +               _mesa_glsl_error(&loc, state, "unsized array `%s' should be the"
>> +                                 " last member of a shader storage block",
>> +                                 var->name);
>> +            }
>> +         }
>> +
>>           state->symbols->add_variable(var);
>>           instructions->push_tail(var);
>>        }
> 
> 
> 


More information about the mesa-dev mailing list