[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