diff options
author | Yevhenii Kolesnikov <yevhenii.kolesnikov@globallogic.com> | 2021-07-14 20:39:45 +0300 |
---|---|---|
committer | Dylan Baker <dylan.c.baker@intel.com> | 2021-07-27 11:43:34 -0700 |
commit | 0028e826c5933fd2805439dac11868bd4e1410f0 (patch) | |
tree | 8790e4e5a655f3b628b9adea0c0483ae4009761e | |
parent | fc9650d1f398933dcf0ae1c1ca970b574b44bf17 (diff) | |
download | mesa-0028e826c5933fd2805439dac11868bd4e1410f0.tar.gz |
glsl: Add operator for .length() method on implicitly-sized arrays
ARB_shader_storage_buffer_object extension (promoted to core in 4.3) allows us
to call .length() method on arrays declared without an explicit size. The length is
determined at link time as a maximum array access.
Fixes: 273f61a0051a ("glsl: Add parser/compiler support for unsized array's length()")
Signed-off-by: Yevhenii Kolesnikov <yevhenii.kolesnikov@globallogic.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11952>
(cherry picked from commit 441826aaaac54e84629269c4622be2f17a465209)
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/compiler/glsl/ir.cpp | 1 | ||||
-rw-r--r-- | src/compiler/glsl/ir_expression_operation.py | 5 | ||||
-rw-r--r-- | src/compiler/glsl/ir_validate.cpp | 5 | ||||
-rw-r--r-- | src/compiler/glsl/linker.cpp | 39 | ||||
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 1 |
7 files changed, 53 insertions, 1 deletions
diff --git a/.pick_status.json b/.pick_status.json index e2e9c7f72d9..9e087012cce 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -103,7 +103,7 @@ "description": "glsl: Add operator for .length() method on implicitly-sized arrays", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "273f61a0051a794d1a39d70fb1dbf46a3ca3c63f" }, diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp index 97b302a744a..f9e9c321db4 100644 --- a/src/compiler/glsl/ir.cpp +++ b/src/compiler/glsl/ir.cpp @@ -438,6 +438,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_get_buffer_size: case ir_unop_ssbo_unsized_array_length: + case ir_unop_implicitly_sized_array_length: this->type = glsl_type::int_type; break; diff --git a/src/compiler/glsl/ir_expression_operation.py b/src/compiler/glsl/ir_expression_operation.py index 0d8d7a6f9ed..c9f9831c346 100644 --- a/src/compiler/glsl/ir_expression_operation.py +++ b/src/compiler/glsl/ir_expression_operation.py @@ -591,6 +591,11 @@ ir_expression_operation = [ # of its length. operation("ssbo_unsized_array_length", 1), + # Calculate length of an implicitly sized array. + # This opcode is going to be replaced with a constant expression at link + # time. + operation("implicitly_sized_array_length", 1), + # 64-bit integer packing ops. operation("pack_int_2x32", 1, printable_name="packInt2x32", source_types=(int_type,), dest_type=int64_type, c_expression="data.u64[0] = pack_2x32(op[0]->value.u[0], op[0]->value.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))), operation("pack_uint_2x32", 1, printable_name="packUint2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="data.u64[0] = pack_2x32(op[0]->value.u[0], op[0]->value.u[1])", flags=frozenset((horizontal_operation, non_assign_operation))), diff --git a/src/compiler/glsl/ir_validate.cpp b/src/compiler/glsl/ir_validate.cpp index c9d5ca1e356..c60c36cd260 100644 --- a/src/compiler/glsl/ir_validate.cpp +++ b/src/compiler/glsl/ir_validate.cpp @@ -633,6 +633,11 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[0]->type->is_unsized_array()); break; + case ir_unop_implicitly_sized_array_length: + assert(ir->type == glsl_type::int_type); + assert(ir->operands[0]->type->is_array()); + break; + case ir_unop_d2f: assert(ir->operands[0]->type->is_double()); assert(ir->type->is_float()); diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index a5ae7a30bf0..b598b63c09f 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -321,6 +321,39 @@ public: } }; +class array_length_to_const_visitor : public ir_rvalue_visitor { +public: + array_length_to_const_visitor() + { + this->progress = false; + } + + virtual ~array_length_to_const_visitor() + { + /* empty */ + } + + bool progress; + + virtual void handle_rvalue(ir_rvalue **rvalue) + { + if (*rvalue == NULL || (*rvalue)->ir_type != ir_type_expression) + return; + + ir_expression *expr = (*rvalue)->as_expression(); + if (expr) { + if (expr->operation == ir_unop_implicitly_sized_array_length) { + assert(!expr->operands[0]->type->is_unsized_array()); + ir_constant *constant = new(expr) + ir_constant(expr->operands[0]->type->array_size()); + if (constant) { + *rvalue = constant; + } + } + } + } +}; + /** * Visitor that determines the highest stream id to which a (geometry) shader * emits vertices. It also checks whether End{Stream}Primitive is ever called. @@ -2540,6 +2573,12 @@ link_intrastage_shaders(void *mem_ctx, v.run(linked->ir); v.fixup_unnamed_interface_types(); + /* Now that we know the sizes of all the arrays, we can replace .length() + * calls with a constant expression. + */ + array_length_to_const_visitor len_v; + len_v.run(linked->ir); + /* Link up uniform blocks defined within this stage. */ link_uniform_blocks(mem_ctx, ctx, prog, linked, &ubo_blocks, &num_ubo_blocks, &ssbo_blocks, &num_ssbo_blocks); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index eaaf8daab1c..96aa399aa63 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -1351,6 +1351,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir) break; case ir_unop_ssbo_unsized_array_length: + case ir_unop_implicitly_sized_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 4f62622ed16..3ecdb8374b0 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -2458,6 +2458,7 @@ glsl_to_tgsi_visitor::visit_expression(ir_expression* ir, st_src_reg *op) case ir_binop_carry: case ir_binop_borrow: case ir_unop_ssbo_unsized_array_length: + case ir_unop_implicitly_sized_array_length: case ir_unop_atan: case ir_binop_atan2: case ir_unop_clz: |