[Mesa-dev] [PATCH] glsl: Update deref types when resizing implicitly sized arrays.
Timothy Arceri
timothy.arceri at collabora.com
Thu Nov 3 00:20:27 UTC 2016
On Wed, 2016-11-02 at 14:28 -0700, Kenneth Graunke wrote:
> At link time, we resolve the size of implicitly sized arrays.
> When doing so, we update the type of the ir_variables. However,
> we neglected to update the type of ir_dereference nodes which
> reference those variables.
>
> It turns out array_resize_visitor (for GS/TCS/TES interface array
> handling) already did 2/3 of the cases for this, so we can simply
> refactor the code and reuse it.
>
> This fixes:
> GL45-CTS.shader_storage_buffer_object.basic-syntax
> GL45-CTS.shader_storage_buffer_object.basic-syntaxSSO
>
> which have an SSBO containing an implicitly sized array, followed
> by some other members. setup_buffer_access uses the dereference
> types to compute offsets to fields, and it had a stale type where
> the implicitly sized array's length was still 0 instead of the
> actual length.
>
> While we're here, we can also fix update_array_sizes to properly
> update deref types as well, fixing a FINISHME from 2010.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> src/compiler/glsl/linker.cpp | 70 +++++++++++++++++++++++++++++-----
> ----------
> 1 file changed, 47 insertions(+), 23 deletions(-)
>
> diff --git a/src/compiler/glsl/linker.cpp
> b/src/compiler/glsl/linker.cpp
> index 03b866f..bd650a6 100644
> --- a/src/compiler/glsl/linker.cpp
> +++ b/src/compiler/glsl/linker.cpp
> @@ -181,7 +181,43 @@ private:
> };
>
>
> -class array_resize_visitor : public ir_hierarchical_visitor {
> +/**
> + * A visitor helper that provides methods for updating the types of
> + * ir_dereferences. Classes that update variable types (say,
> updating
> + * array sizes) will want to use this so that dereference types stay
> in sync.
> + */
> +class deref_type_updater : public ir_hierarchical_visitor {
> +public:
> + virtual ir_visitor_status visit(ir_dereference_variable *ir)
> + {
> + ir->type = ir->var->type;
> + return visit_continue;
> + }
> +
> + virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
> + {
> + const glsl_type *const vt = ir->array->type;
> + if (vt->is_array())
> + ir->type = vt->fields.array;
> + return visit_continue;
> + }
> +
> + virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
> + {
> + for (unsigned i = 0; i < ir->record->type->length; i++) {
> + const struct glsl_struct_field *field =
> + &ir->record->type->fields.structure[i];
> + if (strcmp(field->name, ir->field) == 0) {
> + ir->type = field->type;
> + break;
> + }
> + }
> + return visit_continue;
> + }
> +};
> +
> +
> +class array_resize_visitor : public deref_type_updater {
> public:
> unsigned num_vertices;
> gl_shader_program *prog;
> @@ -240,24 +276,6 @@ public:
>
> return visit_continue;
> }
> -
> - /* Dereferences of input variables need to be updated so that
> their type
> - * matches the newly assigned type of the variable they are
> accessing. */
> - virtual ir_visitor_status visit(ir_dereference_variable *ir)
> - {
> - ir->type = ir->var->type;
> - return visit_continue;
> - }
> -
> - /* Dereferences of 2D input arrays need to be updated so that
> their type
> - * matches the newly assigned type of the array they are
> accessing. */
> - virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
> - {
> - const glsl_type *const vt = ir->array->type;
> - if (vt->is_array())
> - ir->type = vt->fields.array;
> - return visit_continue;
> - }
> };
>
> /**
> @@ -1361,7 +1379,7 @@ move_non_declarations(exec_list *instructions,
> exec_node *last,
> * it inside that function leads to compiler warnings with some
> versions of
> * gcc.
> */
> -class array_sizing_visitor : public ir_hierarchical_visitor {
> +class array_sizing_visitor : public deref_type_updater {
> public:
> array_sizing_visitor()
> : mem_ctx(ralloc_context(NULL)),
> @@ -2283,6 +2301,8 @@ update_array_sizes(struct gl_shader_program
> *prog)
> if (prog->_LinkedShaders[i] == NULL)
> continue;
>
> + bool updated_any_types = false;
I'm probably being picky but IMO it would read better just as
types_updated.
With or without the change:
Reviewed-by: Timothy Arceri <timothy.arceri at collabora.com>
> +
> foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]-
> >ir) {
> ir_variable *const var = node->as_variable();
>
> @@ -2338,11 +2358,15 @@ update_array_sizes(struct gl_shader_program
> *prog)
>
> var->type = glsl_type::get_array_instance(var->type-
> >fields.array,
> size + 1);
> - /* FINISHME: We should update the types of array
> - * dereferences of this variable now.
> - */
> + updated_any_types = true;
> }
> }
> +
> + /* Update the types of dereferences in case we changed any. */
> + if (updated_any_types) {
> + deref_type_updater v;
> + v.run(prog->_LinkedShaders[i]->ir);
> + }
> }
> }
>
More information about the mesa-dev
mailing list