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

Author: Caio Oliveira <[email protected]>
Date:   Fri Feb 24 02:25:44 2023 -0800

glsl: Implement use_scoped_barrier option for lowering memory barriers

When the option is enabled, lower memory barriers to the
unified nir_intrinsic_scoped_barrier.

The translation of the following is based on
https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_gl_spirv.txt

- memoryBarrier()
- memoryBarrierBuffer()
- memoryBarrierImage()
- memoryBarrierShared()
- groupMemoryBarrier()

Also use scoped barrier for the memory counterparts of the GLSL
(control) barrier() when the option is enabled.  The execution
part of a (control) barrier() remains using the old intrinsic.

For memoryBarrierAtomicCounter() there's no corresponding
nir_var_atomic_counter mode. Since atomic counters are lowered
to SSBOs, use the nir_var_mem_ssbo mode in the scoped barrier
instead.

Reviewed-by: Faith Ekstrand <[email protected]>
Acked-by: Rob Clark <[email protected]>
Reviewed-by: Alyssa Rosenzweig <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3339>

---

 src/compiler/glsl/glsl_to_nir.cpp | 98 +++++++++++++++++++++++++++++++++++----
 1 file changed, 88 insertions(+), 10 deletions(-)

diff --git a/src/compiler/glsl/glsl_to_nir.cpp 
b/src/compiler/glsl/glsl_to_nir.cpp
index 492caa0d854..7a8f4d751ac 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -1085,7 +1085,9 @@ nir_visitor::visit(ir_call *ir)
          op = nir_intrinsic_image_deref_atomic_dec_wrap;
          break;
       case ir_intrinsic_memory_barrier:
-         op = nir_intrinsic_memory_barrier;
+         op = shader->options->use_scoped_barrier
+            ? nir_intrinsic_scoped_barrier
+            : nir_intrinsic_memory_barrier;
          break;
       case ir_intrinsic_image_size:
          op = nir_intrinsic_image_deref_size;
@@ -1106,19 +1108,29 @@ nir_visitor::visit(ir_call *ir)
          op = nir_intrinsic_end_invocation_interlock;
          break;
       case ir_intrinsic_group_memory_barrier:
-         op = nir_intrinsic_group_memory_barrier;
+         op = shader->options->use_scoped_barrier
+            ? nir_intrinsic_scoped_barrier
+            : nir_intrinsic_group_memory_barrier;
          break;
       case ir_intrinsic_memory_barrier_atomic_counter:
-         op = nir_intrinsic_memory_barrier_atomic_counter;
+         op = shader->options->use_scoped_barrier
+            ? nir_intrinsic_scoped_barrier
+            : nir_intrinsic_memory_barrier_atomic_counter;
          break;
       case ir_intrinsic_memory_barrier_buffer:
-         op = nir_intrinsic_memory_barrier_buffer;
+         op = shader->options->use_scoped_barrier
+            ? nir_intrinsic_scoped_barrier
+            : nir_intrinsic_memory_barrier_buffer;
          break;
       case ir_intrinsic_memory_barrier_image:
-         op = nir_intrinsic_memory_barrier_image;
+         op = shader->options->use_scoped_barrier
+            ? nir_intrinsic_scoped_barrier
+            : nir_intrinsic_memory_barrier_image;
          break;
       case ir_intrinsic_memory_barrier_shared:
-         op = nir_intrinsic_memory_barrier_shared;
+         op = shader->options->use_scoped_barrier
+            ? nir_intrinsic_scoped_barrier
+            : nir_intrinsic_memory_barrier_shared;
          break;
       case ir_intrinsic_shared_load:
          op = nir_intrinsic_load_shared;
@@ -1437,6 +1449,62 @@ nir_visitor::visit(ir_call *ir)
       case nir_intrinsic_memory_barrier_shared:
          nir_builder_instr_insert(&b, &instr->instr);
          break;
+      case nir_intrinsic_scoped_barrier: {
+         /* The nir_intrinsic_scoped_barrier follows the general
+          * semantics of SPIR-V memory barriers, so this and other memory
+          * barriers use the mapping based on GLSL->SPIR-V from
+          *
+          *   
https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_gl_spirv.txt
+          */
+         nir_scope scope;
+         unsigned modes;
+         switch (ir->callee->intrinsic_id) {
+         case ir_intrinsic_memory_barrier:
+            scope = NIR_SCOPE_DEVICE;
+            modes = nir_var_image |
+                    nir_var_mem_ssbo |
+                    nir_var_mem_shared |
+                    nir_var_mem_global;
+            break;
+         case ir_intrinsic_memory_barrier_buffer:
+            scope = NIR_SCOPE_DEVICE;
+            modes = nir_var_mem_ssbo |
+                    nir_var_mem_global;
+            break;
+         case ir_intrinsic_memory_barrier_image:
+            scope = NIR_SCOPE_DEVICE;
+            modes = nir_var_image;
+            break;
+         case ir_intrinsic_memory_barrier_shared:
+            /* Both ARB_gl_spirv and glslang lower this to Device scope, so
+             * follow their lead.  Note GL_KHR_vulkan_glsl also does
+             * something similar.
+             */
+            scope = NIR_SCOPE_DEVICE;
+            modes = nir_var_mem_shared;
+            break;
+         case ir_intrinsic_group_memory_barrier:
+            scope = NIR_SCOPE_WORKGROUP;
+            modes = nir_var_image |
+                    nir_var_mem_ssbo |
+                    nir_var_mem_shared |
+                    nir_var_mem_global;
+            break;
+         case ir_intrinsic_memory_barrier_atomic_counter:
+            /* There's no nir_var_atomic_counter, but since atomic counters 
are lowered
+             * to SSBOs, we use nir_var_mem_ssbo instead.
+             */
+            scope = NIR_SCOPE_DEVICE;
+            modes = nir_var_mem_ssbo;
+            break;
+         default:
+               unreachable("invalid intrinsic id for memory barrier");
+         }
+
+         nir_scoped_memory_barrier(&b, scope, NIR_MEMORY_ACQ_REL,
+                                   (nir_variable_mode)modes);
+         break;
+      }
       case nir_intrinsic_shader_clock:
          nir_ssa_dest_init(&instr->instr, &instr->dest, 2, 32, NULL);
          nir_intrinsic_set_memory_scope(instr, NIR_SCOPE_SUBGROUP);
@@ -2693,10 +2761,20 @@ nir_visitor::visit(ir_dereference_array *ir)
 void
 nir_visitor::visit(ir_barrier *)
 {
-   if (shader->info.stage == MESA_SHADER_COMPUTE)
-      nir_memory_barrier_shared(&b);
-   else if (shader->info.stage == MESA_SHADER_TESS_CTRL)
-      nir_memory_barrier_tcs_patch(&b);
+   if (shader->options->use_scoped_barrier) {
+      if (shader->info.stage == MESA_SHADER_COMPUTE) {
+         nir_scoped_memory_barrier(&b, NIR_SCOPE_WORKGROUP, NIR_MEMORY_ACQ_REL,
+                                   nir_var_mem_shared);
+      } else if (shader->info.stage == MESA_SHADER_TESS_CTRL) {
+         nir_scoped_memory_barrier(&b, NIR_SCOPE_WORKGROUP, NIR_MEMORY_ACQ_REL,
+                                   nir_var_shader_out);
+      }
+   } else {
+      if (shader->info.stage == MESA_SHADER_COMPUTE)
+         nir_memory_barrier_shared(&b);
+      else if (shader->info.stage == MESA_SHADER_TESS_CTRL)
+         nir_memory_barrier_tcs_patch(&b);
+   }
 
    nir_control_barrier(&b);
 }

Reply via email to