From dd81d8808d30459592a1fff2673e768951426364 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 14 May 2019 14:08:46 +0200 Subject: [PATCH] nir: Handle compact variables when assigning i/o locations These are used in Vulkan for clip/cull distances, instead of the GLSL lowering when the clip/cull arrays are shared. Reviewed-by: Bas Nieuwenhuizen --- src/compiler/nir/nir_linking_helpers.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c index d25b350a75e..b85690983d5 100644 --- a/src/compiler/nir/nir_linking_helpers.c +++ b/src/compiler/nir/nir_linking_helpers.c @@ -1011,15 +1011,35 @@ nir_assign_io_var_locations(struct exec_list *var_list, unsigned *size, (int) FRAG_RESULT_DATA0 : (int) VARYING_SLOT_VAR0; int UNUSED last_loc = 0; + bool last_partial = false; nir_foreach_variable(var, var_list) { - const struct glsl_type *type = var->type; if (nir_is_per_vertex_io(var, stage)) { assert(glsl_type_is_array(type)); type = glsl_get_array_element(type); } - unsigned var_size = glsl_count_attribute_slots(type, false); + unsigned var_size; + if (var->data.compact) { + /* compact variables must be arrays of scalars */ + assert(glsl_type_is_array(type)); + assert(glsl_type_is_scalar(glsl_get_array_element(type))); + unsigned start = 4 * location + var->data.location_frac; + unsigned end = start + glsl_get_length(type); + var_size = end / 4 - location; + last_partial = end % 4 != 0; + } else { + /* Compact variables bypass the normal varying compacting pass, + * which means they cannot be in the same vec4 slot as a normal + * variable. If part of the current slot is taken up by a compact + * variable, we need to go to the next one. + */ + if (last_partial) { + location++; + last_partial = false; + } + var_size = glsl_count_attribute_slots(type, false); + } /* Builtins don't allow component packing so we only need to worry about * user defined varyings sharing the same location. -- 2.30.2