[Mesa-dev] [PATCH v5 11/70] glsl: Add parser/compiler support for unsized array's length()

Samuel Iglesias Gonsálvez siglesias at igalia.com
Tue Sep 15 03:25:38 PDT 2015



On 15/09/15 11:38, Tapani Pälli wrote:
> 
> 
> On 09/10/2015 04:35 PM, Iago Toral Quiroga wrote:
>> From: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>>
>> The unsized array length is computed with the following formula:
>>
>> array.length() =
>>     max((buffer_object_size - offset_of_array) / stride_of_array, 0)
>>
>> Of these, only the buffer size needs to be provided by the backends, the
>> frontend already knows the values of the two other variables.
>>
>> This patch identifies the cases where we need to get the length of an
>> unsized array, injecting ir_unop_ssbo_unsized_array_length expressions
>> that will be lowered (in a later patch) to inject the formula mentioned
>> above.
>>
>> It also adds the ir_unop_get_buffer_size expression that drivers will
>> implement to provide the buffer length.
>>
>> v2:
>> - Do not define a triop that will force backends to implement the
>>    entire formula, they should only need to provide the buffer size
>>    since the other values are known by the frontend (Curro).
>>
>> Signed-off-by: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>> ---
>>   src/glsl/ast_function.cpp                             | 13
>> +++++++++----
>>   src/glsl/ir.cpp                                       |  7 +++++++
>>   src/glsl/ir.h                                         | 19
>> ++++++++++++++++++-
>>   src/glsl/ir_validate.cpp                              | 11 +++++++++++
>>   src/glsl/link_uniforms.cpp                            |  8 +++++++-
>>   .../drivers/dri/i965/brw_fs_channel_expressions.cpp   |  2 ++
>>   src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp        |  8 ++++++++
>>   src/mesa/program/ir_to_mesa.cpp                       |  2 ++
>>   src/mesa/state_tracker/st_glsl_to_tgsi.cpp            |  5 +++++
>>   9 files changed, 69 insertions(+), 6 deletions(-)
>>
>> diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
>> index 803edf5..0fb8928 100644
>> --- a/src/glsl/ast_function.cpp
>> +++ b/src/glsl/ast_function.cpp
>> @@ -1593,11 +1593,16 @@
>> ast_function_expression::handle_method(exec_list *instructions,
>>
>>         if (op->type->is_array()) {
>>            if (op->type->is_unsized_array()) {
>> -            _mesa_glsl_error(&loc, state, "length called on unsized
>> array");
>> -            goto fail;
>> +            if (!state->ARB_shader_storage_buffer_object_enable) {
> 
> this should be
> 
> if (!state->has_shader_storage_buffer_objects())
> 

Oh, nice catch!

Thanks,

Sam

>> +               _mesa_glsl_error(&loc, state, "length called on
>> unsized array"
>> +                                             " only available with "
>> +                                            
>> "ARB_shader_storage_buffer_object");
>> +            }
>> +            /* Calculate length of an unsized array in run-time */
>> +            result = new(ctx)
>> ir_expression(ir_unop_ssbo_unsized_array_length, op);
>> +         } else {
>> +            result = new(ctx) ir_constant(op->type->array_size());
>>            }
>> -
>> -         result = new(ctx) ir_constant(op->type->array_size());
>>         } else if (op->type->is_vector()) {
>>            if (state->ARB_shading_language_420pack_enable) {
>>               /* .length() returns int. */
>> diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
>> index 594fc33..60d8770 100644
>> --- a/src/glsl/ir.cpp
>> +++ b/src/glsl/ir.cpp
>> @@ -342,6 +342,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
>>                          op0->type->vector_elements, 1);
>>         break;
>>
>> +   case ir_unop_get_buffer_size:
>> +   case ir_unop_ssbo_unsized_array_length:
>> +      this->type = glsl_type::int_type;
>> +      break;
>> +
>>      default:
>>         assert(!"not reached: missing automatic type setup for
>> ir_expression");
>>         this->type = op0->type;
>> @@ -571,6 +576,8 @@ static const char *const operator_strs[] = {
>>      "noise",
>>      "subroutine_to_int",
>>      "interpolate_at_centroid",
>> +   "get_buffer_size",
>> +   "ssbo_unsized_array_length",
>>      "+",
>>      "-",
>>      "*",
>> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
>> index 9559dc4..ca6179c 100644
>> --- a/src/glsl/ir.h
>> +++ b/src/glsl/ir.h
>> @@ -1423,9 +1423,26 @@ enum ir_expression_operation {
>>      ir_unop_interpolate_at_centroid,
>>
>>      /**
>> +    * Ask the driver for the total size of a buffer block.
>> +    *
>> +    * operand0 is the ir_constant buffer block index in the linked
>> shader.
>> +    */
>> +   ir_unop_get_buffer_size,
>> +
>> +   /**
>> +    * Calculate length of an unsized array inside a buffer block.
>> +    * This opcode is going to be replaced in a lowering pass inside
>> +    * the linker.
>> +    *
>> +    * operand0 is the unsized array's ir_value for the calculation
>> +    * of its length.
>> +    */
>> +   ir_unop_ssbo_unsized_array_length,
>> +
>> +   /**
>>       * A sentinel marking the last of the unary operations.
>>       */
>> -   ir_last_unop = ir_unop_interpolate_at_centroid,
>> +   ir_last_unop = ir_unop_ssbo_unsized_array_length,
>>
>>      ir_binop_add,
>>      ir_binop_sub,
>> diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
>> index 3f0dea7..935571a 100644
>> --- a/src/glsl/ir_validate.cpp
>> +++ b/src/glsl/ir_validate.cpp
>> @@ -409,6 +409,17 @@ ir_validate::visit_leave(ir_expression *ir)
>>         assert(ir->operands[0]->type->is_float());
>>         break;
>>
>> +   case ir_unop_get_buffer_size:
>> +      assert(ir->type == glsl_type::int_type);
>> +      assert(ir->operands[0]->type == glsl_type::uint_type);
>> +      break;
>> +
>> +   case ir_unop_ssbo_unsized_array_length:
>> +      assert(ir->type == glsl_type::int_type);
>> +      assert(ir->operands[0]->type->is_array());
>> +      assert(ir->operands[0]->type->is_unsized_array());
>> +      break;
>> +
>>      case ir_unop_d2f:
>>         assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
>>         assert(ir->type->base_type == GLSL_TYPE_FLOAT);
>> diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
>> index a0cb618..fefc1ec 100644
>> --- a/src/glsl/link_uniforms.cpp
>> +++ b/src/glsl/link_uniforms.cpp
>> @@ -221,7 +221,13 @@ program_resource_visitor::recursion(const
>> glsl_type *t, char **name,
>>         if (record_type == NULL && t->fields.array->is_record())
>>            record_type = t->fields.array;
>>
>> -      for (unsigned i = 0; i < t->length; i++) {
>> +      unsigned length = t->length;
>> +      /* Shader storage block unsized arrays: add subscript [0] to
>> variable
>> +       * names */
>> +      if (t->is_unsized_array())
>> +         length = 1;
>> +
>> +      for (unsigned i = 0; i < length; i++) {
>>        size_t new_length = name_length;
>>
>>        /* Append the subscript to the current variable name */
>> diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
>> b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
>> index a8883a3..277b6cc 100644
>> --- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
>> +++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
>> @@ -379,6 +379,7 @@
>> ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
>>      }
>>
>>      case ir_binop_ubo_load:
>> +   case ir_unop_get_buffer_size:
>>         unreachable("not yet supported");
>>
>>      case ir_triop_fma:
>> @@ -430,6 +431,7 @@
>> ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
>>      case ir_triop_vector_insert:
>>      case ir_quadop_bitfield_insert:
>>      case ir_quadop_vector:
>> +   case ir_unop_ssbo_unsized_array_length:
>>         unreachable("should have been lowered");
>>
>>      case ir_unop_unpack_half_2x16_split_x:
>> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
>> b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
>> index ec41262..c186f48 100644
>> --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
>> +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
>> @@ -1583,6 +1583,10 @@ vec4_visitor::visit(ir_expression *ir)
>>         emit(MOV(result_dst, op[0]));
>>         break;
>>
>> +   case ir_unop_ssbo_unsized_array_length:
>> +      unreachable("not reached: should be handled by
>> lower_ubo_reference");
>> +      break;
>> +
>>      case ir_binop_add:
>>         emit(ADD(result_dst, op[0], op[1]));
>>         break;
>> @@ -1789,6 +1793,10 @@ vec4_visitor::visit(ir_expression *ir)
>>         emit(RNDE(result_dst, op[0]));
>>         break;
>>
>> +   case ir_unop_get_buffer_size:
>> +      unreachable("not reached: not implemented");
>> +      break;
>> +
>>      case ir_binop_min:
>>         emit_minmax(BRW_CONDITIONAL_L, result_dst, op[0], op[1]);
>>         break;
>> diff --git a/src/mesa/program/ir_to_mesa.cpp
>> b/src/mesa/program/ir_to_mesa.cpp
>> index 0defed8..d506485 100644
>> --- a/src/mesa/program/ir_to_mesa.cpp
>> +++ b/src/mesa/program/ir_to_mesa.cpp
>> @@ -1344,9 +1344,11 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
>>      case ir_unop_dFdy_coarse:
>>      case ir_unop_dFdy_fine:
>>      case ir_unop_subroutine_to_int:
>> +   case ir_unop_get_buffer_size:
>>         assert(!"not supported");
>>         break;
>>
>> +   case ir_unop_ssbo_unsized_array_length:
>>      case ir_quadop_vector:
>>         /* This operation should have already been handled.
>>          */
>> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> index 6c9f947..d1987a0 100644
>> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> @@ -2217,10 +2217,15 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
>>      case ir_triop_vector_insert:
>>      case ir_binop_carry:
>>      case ir_binop_borrow:
>> +   case ir_unop_ssbo_unsized_array_length:
>>         /* This operation is not supported, or should have already
>> been handled.
>>          */
>>         assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");
>>         break;
>> +
>> +   case ir_unop_get_buffer_size:
>> +      assert(!"Not implemented yet");
>> +      break;
>>      }
>>
>>      this->result = result_src;
>>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list