[Mesa-dev] [PATCH v5 11/70] glsl: Add parser/compiler support for unsized array's length()
Tapani Pälli
tapani.palli at intel.com
Tue Sep 15 02:38:32 PDT 2015
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())
> + _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;
>
More information about the mesa-dev
mailing list