From b2bbd978d0b1c85919c6f3b5f631b3c6cbaaaf8a Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 10 Sep 2018 21:59:31 +0200 Subject: [PATCH] nir: fix lowering arrays to elements for XFB outputs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If we have a transform feedback output like: float[2] x2_out (VARYING_SLOT_VAR1.x, 0, 0) which is lowered by nir_lower_io_arrays_to_elements to, float x2_out (VARYING_SLOT_VAR1.x, 0, 0) float x2_out@5 (VARYING_SLOT_VAR2.x, 0, 0) We have to update the destination offset to avoid overwriting the same value. v2 (Jason Ekstrand): - Compute the correct offsets for arrays of vectors and/or doubles Reviewed-by: Jason Ekstrand Reviewed-by: Alejandro Piñeiro --- src/compiler/nir/nir_lower_io_arrays_to_elements.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/compiler/nir/nir_lower_io_arrays_to_elements.c b/src/compiler/nir/nir_lower_io_arrays_to_elements.c index 9051d397fbc..73b6810b763 100644 --- a/src/compiler/nir/nir_lower_io_arrays_to_elements.c +++ b/src/compiler/nir/nir_lower_io_arrays_to_elements.c @@ -34,7 +34,8 @@ static unsigned get_io_offset(nir_builder *b, nir_deref_instr *deref, nir_variable *var, - unsigned *element_index, nir_ssa_def **vertex_index) + unsigned *element_index, unsigned *xfb_offset, + nir_ssa_def **vertex_index) { nir_deref_path path; nir_deref_path_init(&path, deref, NULL); @@ -51,6 +52,7 @@ get_io_offset(nir_builder *b, nir_deref_instr *deref, nir_variable *var, } unsigned offset = 0; + *xfb_offset = 0; for (; *p; p++) { if ((*p)->deref_type == nir_deref_type_array) { /* must not be indirect dereference */ @@ -59,6 +61,8 @@ get_io_offset(nir_builder *b, nir_deref_instr *deref, nir_variable *var, unsigned size = glsl_count_attribute_slots((*p)->type, false); offset += size * index; + xfb_offset += index * glsl_get_component_slots((*p)->type) * 4; + unsigned num_elements = glsl_type_is_array((*p)->type) ? glsl_get_aoa_size((*p)->type) : 1; @@ -116,14 +120,19 @@ lower_array(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var, nir_ssa_def *vertex_index = NULL; unsigned elements_index = 0; + unsigned xfb_offset = 0; unsigned io_offset = get_io_offset(b, nir_src_as_deref(intr->src[0]), - var, &elements_index, &vertex_index); + var, &elements_index, &xfb_offset, + &vertex_index); nir_variable *element = elements[elements_index]; if (!element) { element = nir_variable_clone(var, b->shader); element->data.location = var->data.location + io_offset; + if (var->data.explicit_offset) + element->data.offset = var->data.offset + xfb_offset; + const struct glsl_type *type = glsl_without_array(element->type); /* This pass also splits matrices so we need give them a new type. */ -- 2.30.2