Module: Mesa
Branch: main
Commit: 9b09f244f071c67bceca40695ca72518fb370581
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=9b09f244f071c67bceca40695ca72518fb370581

Author: Gert Wollny <[email protected]>
Date:   Fri Mar  3 12:16:40 2023 +0100

r600/sfn: Fix atomic lowering

Fixes: 56dedf052f4af1903a0d312eb9c7721c69f36c69
  r600/sfn: add r600 specific lowering pass for atomics and use it

Signed-off-by: Gert Wollny <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21684>

---

 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 5f75a6fba18..773e70a7bc2 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<unsigned, unsigned> binding_offset;
+   std::map<unsigned, nir_variable *> 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,

Reply via email to