From 5f62083c267401de50907c2c6b8ce65a366f8c20 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Fri, 2 Apr 2021 10:17:25 +0100 Subject: [PATCH] nir/gather_info: fix partial masking of compact I/O with location_frac!=0 nir_lower_clip_cull_distance_arrays() can create compact variables with location_frac!=0. Fixes: cc7a1874112 ("nir/gather_info: implement partial masking of struct and compact I/O") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4554 Signed-off-by: Rhys Perry Reviewed-by: Timothy Arceri Part-of: --- src/compiler/nir/nir_gather_info.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index b4123aa837d..5fbaecbf675 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -194,8 +194,15 @@ mark_whole_variable(nir_shader *shader, nir_variable *var, } static unsigned -get_io_offset(nir_deref_instr *deref, bool compact, bool per_vertex) +get_io_offset(nir_deref_instr *deref, nir_variable *var, bool per_vertex) { + if (var->data.compact) { + assert(deref->deref_type == nir_deref_type_array); + return nir_src_is_const(deref->arr.index) ? + (nir_src_as_uint(deref->arr.index) + var->data.location_frac) / 4u : + (unsigned)-1; + } + unsigned offset = 0; for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) { @@ -206,11 +213,8 @@ get_io_offset(nir_deref_instr *deref, bool compact, bool per_vertex) if (!nir_src_is_const(d->arr.index)) return -1; - if (compact) - offset += nir_src_as_uint(d->arr.index) / 4; - else - offset += glsl_count_attribute_slots(d->type, false) * - nir_src_as_uint(d->arr.index); + offset += glsl_count_attribute_slots(d->type, false) * + nir_src_as_uint(d->arr.index); } else if (d->deref_type == nir_deref_type_struct) { const struct glsl_type *parent_type = nir_deref_instr_parent(d)->type; for (unsigned i = 0; i < d->strct.index; i++) { @@ -246,7 +250,7 @@ try_mask_partial_io(nir_shader *shader, nir_variable *var, if (var->data.per_view) return false; - unsigned offset = get_io_offset(deref, var->data.compact, per_vertex); + unsigned offset = get_io_offset(deref, var, per_vertex); if (offset == -1) return false;