diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h index 79b706f7aee..024ec73256d 100644 --- a/src/compiler/shader_enums.h +++ b/src/compiler/shader_enums.h @@ -1058,6 +1058,9 @@ enum gl_access_qualifier * This means that the memory scope is the current device. It indicates * that reads and writes are coherent with reads and writes from other * shader invocations and other workgroups. + * + * This is not necessary for shared access. It is always workgroup + * coherent. */ ACCESS_COHERENT = (1 << 0), diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 8746368089e..2bf92b0991e 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -3140,6 +3140,18 @@ vtn_translate_scope(struct vtn_builder *b, SpvScope scope) } } +static void +optimize_barrier(nir_memory_semantics *semantics, nir_variable_mode *modes) +{ + nir_memory_semantics vis_avail = NIR_MEMORY_MAKE_AVAILABLE | NIR_MEMORY_MAKE_VISIBLE; + + /* Shared access is always workgroup coherent in NIR. */ + if (*modes == nir_var_mem_shared) + *semantics &= ~vis_avail; + if ((*semantics & vis_avail) == *semantics) + *modes &= ~nir_var_mem_shared; +} + static void vtn_emit_scoped_control_barrier(struct vtn_builder *b, SpvScope exec_scope, SpvScope mem_scope, @@ -3150,6 +3162,8 @@ vtn_emit_scoped_control_barrier(struct vtn_builder *b, SpvScope exec_scope, nir_variable_mode modes = vtn_mem_semantics_to_nir_var_modes(b, semantics); mesa_scope nir_exec_scope = vtn_translate_scope(b, exec_scope); + optimize_barrier(&nir_semantics, &modes); + /* Memory semantics is optional for OpControlBarrier. */ mesa_scope nir_mem_scope; if (nir_semantics == 0 || modes == 0) @@ -3157,6 +3171,9 @@ vtn_emit_scoped_control_barrier(struct vtn_builder *b, SpvScope exec_scope, else nir_mem_scope = vtn_translate_scope(b, mem_scope); + if (nir_mem_scope <= SCOPE_INVOCATION && nir_exec_scope <= SCOPE_INVOCATION) + return; + nir_barrier(&b->nb, .execution_scope=nir_exec_scope, .memory_scope=nir_mem_scope, .memory_semantics=nir_semantics, .memory_modes=modes); } @@ -3169,6 +3186,8 @@ vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope, nir_memory_semantics nir_semantics = vtn_mem_semantics_to_nir_mem_semantics(b, semantics); + optimize_barrier(&nir_semantics, &modes); + /* No barrier to add. */ if (nir_semantics == 0 || modes == 0) return;