From 9b09f244f071c67bceca40695ca72518fb370581 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Fri, 3 Mar 2023 12:16:40 +0100 Subject: [PATCH] r600/sfn: Fix atomic lowering Fixes: 56dedf052f4af1903a0d312eb9c7721c69f36c69 r600/sfn: add r600 specific lowering pass for atomics and use it Signed-off-by: Gert Wollny Part-of: --- src/gallium/drivers/r600/sfn/sfn_nir.cpp | 35 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.cpp b/src/gallium/drivers/r600/sfn/sfn_nir.cpp index 5f75a6f..773e70a 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_nir.cpp @@ -444,23 +444,30 @@ r600_lower_clipvertex_to_clipdist(nir_shader *sh, pipe_stream_output_info& so_in static bool r600_nir_lower_atomics(nir_shader *shader) { - /* First re-do the offsets, in Hardware we start at zero for each new - * binding, and we use an offset of one per counter */ - int current_binding = -1; - int current_offset = 0; - nir_foreach_variable_with_modes(var, shader, nir_var_uniform) - { - if (!var->type->contains_atomic()) - continue; + /* In Hardware we start at a zero index for each new + * binding, and we use an offset of one per counter. We also + * need to sort the atomics according to binding and offset. */ + std::map binding_offset; + std::map sorted_var; + + nir_foreach_variable_with_modes_safe(var, shader, nir_var_uniform) { + if (var->type->contains_atomic()) { + sorted_var[(var->data.binding << 16) | var->data.offset] = var; + exec_node_remove(&var->node); + } + } - if (current_binding == (int)var->data.binding) { - var->data.index = current_offset; - current_offset += var->type->atomic_size() / ATOMIC_COUNTER_SIZE; - } else { - current_binding = var->data.binding; + for (auto& [dummy, var] : sorted_var) { + auto iindex = binding_offset.find(var->data.binding); + unsigned offset_update = var->type->atomic_size() / ATOMIC_COUNTER_SIZE; + if (iindex == binding_offset.end()) { var->data.index = 0; - current_offset = var->type->atomic_size() / ATOMIC_COUNTER_SIZE; + binding_offset[var->data.binding] = offset_update; + } else { + var->data.index = iindex->second; + iindex->second += offset_update; } + shader->variables.push_tail(&var->node); } return nir_shader_instructions_pass(shader, -- 2.7.4