nir/glsl: Emit memory barriers as part of barrier()
authorJason Ekstrand <jason@jlekstrand.net>
Tue, 7 Jan 2020 20:40:53 +0000 (14:40 -0600)
committerMarge Bot <eric+marge@anholt.net>
Mon, 13 Jan 2020 17:23:47 +0000 (17:23 +0000)
The GLSL barrier() intrinsic does an implicit shared memory barrier in
compute shaders and an implicit TCS patch output barrier in tessellation
control shaders.  We'd like NIR's barrier intrinsic to just be a control
flow barrier and not have memory implications.  To satisfy this, we need
to add an extra memory barrier in front of each nir_intrinsic_barrier.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3307>

src/compiler/glsl/glsl_to_nir.cpp

index 479832b5ab0a56f5acdf3d97cee6ef5595f6ee15..4ab620142b07ca9efb710aeaa7ba31382b296c5f 100644 (file)
@@ -2701,6 +2701,18 @@ nir_visitor::visit(ir_dereference_array *ir)
 void
 nir_visitor::visit(ir_barrier *)
 {
+   if (shader->info.stage == MESA_SHADER_COMPUTE) {
+      nir_intrinsic_instr *shared_barrier =
+         nir_intrinsic_instr_create(this->shader,
+                                    nir_intrinsic_memory_barrier_shared);
+      nir_builder_instr_insert(&b, &shared_barrier->instr);
+   } else if (shader->info.stage == MESA_SHADER_TESS_CTRL) {
+      nir_intrinsic_instr *patch_barrier =
+         nir_intrinsic_instr_create(this->shader,
+                                    nir_intrinsic_memory_barrier_tcs_patch);
+      nir_builder_instr_insert(&b, &patch_barrier->instr);
+   }
+
    nir_intrinsic_instr *instr =
       nir_intrinsic_instr_create(this->shader, nir_intrinsic_barrier);
    nir_builder_instr_insert(&b, &instr->instr);