nir: fix lowering arrays to elements for XFB outputs
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 <jason@jlekstrand.net> Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
This commit is contained in:
parent
9f4e0aa7c1
commit
b2bbd978d0
|
@ -34,7 +34,8 @@
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
get_io_offset(nir_builder *b, nir_deref_instr *deref, nir_variable *var,
|
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 path;
|
||||||
nir_deref_path_init(&path, deref, NULL);
|
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;
|
unsigned offset = 0;
|
||||||
|
*xfb_offset = 0;
|
||||||
for (; *p; p++) {
|
for (; *p; p++) {
|
||||||
if ((*p)->deref_type == nir_deref_type_array) {
|
if ((*p)->deref_type == nir_deref_type_array) {
|
||||||
/* must not be indirect dereference */
|
/* 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);
|
unsigned size = glsl_count_attribute_slots((*p)->type, false);
|
||||||
offset += size * index;
|
offset += size * index;
|
||||||
|
|
||||||
|
xfb_offset += index * glsl_get_component_slots((*p)->type) * 4;
|
||||||
|
|
||||||
unsigned num_elements = glsl_type_is_array((*p)->type) ?
|
unsigned num_elements = glsl_type_is_array((*p)->type) ?
|
||||||
glsl_get_aoa_size((*p)->type) : 1;
|
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;
|
nir_ssa_def *vertex_index = NULL;
|
||||||
unsigned elements_index = 0;
|
unsigned elements_index = 0;
|
||||||
|
unsigned xfb_offset = 0;
|
||||||
unsigned io_offset = get_io_offset(b, nir_src_as_deref(intr->src[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];
|
nir_variable *element = elements[elements_index];
|
||||||
if (!element) {
|
if (!element) {
|
||||||
element = nir_variable_clone(var, b->shader);
|
element = nir_variable_clone(var, b->shader);
|
||||||
element->data.location = var->data.location + io_offset;
|
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);
|
const struct glsl_type *type = glsl_without_array(element->type);
|
||||||
|
|
||||||
/* This pass also splits matrices so we need give them a new type. */
|
/* This pass also splits matrices so we need give them a new type. */
|
||||||
|
|
Loading…
Reference in New Issue