To fix a regression in: dEQP-VK.spirv_assembly.instruction.graphics.variable_init.output.struct
v2: handle indirect array accesses (Dave) Fixes: f3275ca01c ("ac/nir: only enable used channels when exporting parameters") Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> --- src/amd/vulkan/radv_shader_info.c | 65 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c index 9c18791524..9934f779bd 100644 --- a/src/amd/vulkan/radv_shader_info.c +++ b/src/amd/vulkan/radv_shader_info.c @@ -47,6 +47,52 @@ static void mark_tess_output(struct radv_shader_info *info, info->tcs.outputs_written |= (mask << param); } +static void get_deref_offset(nir_deref_var *deref, unsigned *const_out, + bool *use_indirect_deref) +{ + nir_deref *tail = &deref->deref; + unsigned const_offset = 0; + + if (deref->var->data.compact) { + assert(tail->child->deref_type == nir_deref_type_array); + assert(glsl_type_is_scalar(glsl_without_array(deref->var->type))); + + nir_deref_array *deref_array = nir_deref_as_array(tail->child); + /* We always lower indirect dereferences for "compact" array vars. */ + assert(deref_array->deref_array_type == nir_deref_array_type_direct); + + *const_out = deref_array->base_offset; + return; + } + + while (tail->child != NULL) { + const struct glsl_type *parent_type = tail->type; + tail = tail->child; + + if (tail->deref_type == nir_deref_type_array) { + nir_deref_array *deref_array = nir_deref_as_array(tail); + unsigned size = glsl_count_attribute_slots(tail->type, false); + + const_offset += size * deref_array->base_offset; + if (deref_array->deref_array_type == nir_deref_array_type_direct) + continue; + + assert(deref_array->deref_array_type == nir_deref_array_type_indirect); + *use_indirect_deref = true; + } else if (tail->deref_type == nir_deref_type_struct) { + nir_deref_struct *deref_struct = nir_deref_as_struct(tail); + + for (unsigned i = 0; i < deref_struct->index; i++) { + const struct glsl_type *ft = glsl_get_struct_field(parent_type, i); + const_offset += glsl_count_attribute_slots(ft, false); + } + } else + unreachable("unsupported deref type"); + } + + *const_out = const_offset; +} + static void gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, struct radv_shader_info *info) @@ -176,13 +222,24 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, if (var->data.mode == nir_var_shader_out) { unsigned idx = var->data.location; unsigned comp = var->data.location_frac; + bool use_indirect_deref = false; + unsigned const_offset = 0; + unsigned writemask; + + get_deref_offset(dvar, &const_offset, &use_indirect_deref); + + writemask = instr->const_index[0] << comp; + if (use_indirect_deref) { + /* Make sure to enable all channels for + * indirect array accesses. + */ + writemask = 0xf; + } if (nir->info.stage == MESA_SHADER_VERTEX) { - info->vs.output_usage_mask[idx] |= - instr->const_index[0] << comp; + info->vs.output_usage_mask[idx + const_offset] |= writemask; } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) { - info->tes.output_usage_mask[idx] |= - instr->const_index[0] << comp; + info->tes.output_usage_mask[idx + const_offset] |= writemask; } else if (nir->info.stage == MESA_SHADER_TESS_CTRL) { unsigned param = shader_io_get_unique_index(idx); const struct glsl_type *type = var->type; -- 2.16.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev