From 48f6014903454dcb0e8e05afb41cabf2dbac0585 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Fri, 23 Mar 2018 12:17:07 +1100 Subject: [PATCH] st/glsl_to_nir: correctly handle arrays packed across multiple vars MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fixes piglit test: tests/spec/arb_enhanced_layouts/execution/component-layout/vs-fs-array-interleave-range.shader_test Reviewed-by: Marek Olšák --- src/mesa/state_tracker/st_glsl_to_nir.cpp | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index acc8942bfeb..d80b8318c1d 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -133,6 +133,7 @@ st_nir_assign_var_locations(struct exec_list *var_list, unsigned *size, const int base = stage == MESA_SHADER_FRAGMENT ? (int) FRAG_RESULT_DATA0 : (int) VARYING_SLOT_VAR0; + int UNUSED last_loc = 0; nir_foreach_variable(var, var_list) { const struct glsl_type *type = var->type; @@ -164,8 +165,29 @@ st_nir_assign_var_locations(struct exec_list *var_list, unsigned *size, * we may have already have processed this location. */ if (processed) { - var->data.driver_location = assigned_locations[var->data.location]; + unsigned driver_location = assigned_locations[var->data.location]; + var->data.driver_location = driver_location; *size += type_size(type); + + /* An array may be packed such that is crosses multiple other arrays + * or variables, we need to make sure we have allocated the elements + * consecutively if the previously proccessed var was shorter than + * the current array we are processing. + * + * NOTE: The code below assumes the var list is ordered in ascending + * location order. + */ + assert(last_loc <= var->data.location); + last_loc = var->data.location; + unsigned last_slot_location = driver_location + var_size; + if (last_slot_location > location) { + unsigned num_unallocated_slots = last_slot_location - location; + unsigned first_unallocated_slot = var_size - num_unallocated_slots; + for (unsigned i = first_unallocated_slot; i < num_unallocated_slots; i++) { + assigned_locations[var->data.location + i] = location; + location++; + } + } continue; } -- 2.30.2