From be039cb467635c6e2a70e29a586de7a5e403c929 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 14 Dec 2018 18:20:00 -0600 Subject: [PATCH] spirv: Choose atomic deref type with pointer_uses_ssa_offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, we hard-coded the rule about workgroup variables and the builder lower_workgroup_access_to_offsets flag. Instead base it on the handy helper we have for exactly this sort of thing. Reviewed-by: Alejandro PiƱeiro Reviewed-by: Caio Marcelo de Oliveira Filho --- src/compiler/spirv/spirv_to_nir.c | 80 +++++++++++++++--------------- src/compiler/spirv/vtn_private.h | 3 ++ src/compiler/spirv/vtn_variables.c | 2 +- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 2968c735f32..a36cd7206fc 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -2801,47 +2801,7 @@ vtn_handle_atomics(struct vtn_builder *b, SpvOp opcode, unreachable("Invalid SPIR-V atomic"); } - } else if (ptr->mode == vtn_variable_mode_workgroup && - !b->options->lower_workgroup_access_to_offsets) { - nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr); - const struct glsl_type *deref_type = deref->type; - nir_intrinsic_op op = get_deref_nir_atomic_op(b, opcode); - atomic = nir_intrinsic_instr_create(b->nb.shader, op); - atomic->src[0] = nir_src_for_ssa(&deref->dest.ssa); - - switch (opcode) { - case SpvOpAtomicLoad: - atomic->num_components = glsl_get_vector_elements(deref_type); - break; - - case SpvOpAtomicStore: - atomic->num_components = glsl_get_vector_elements(deref_type); - nir_intrinsic_set_write_mask(atomic, (1 << atomic->num_components) - 1); - atomic->src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def); - break; - - case SpvOpAtomicExchange: - case SpvOpAtomicCompareExchange: - case SpvOpAtomicCompareExchangeWeak: - case SpvOpAtomicIIncrement: - case SpvOpAtomicIDecrement: - case SpvOpAtomicIAdd: - case SpvOpAtomicISub: - case SpvOpAtomicSMin: - case SpvOpAtomicUMin: - case SpvOpAtomicSMax: - case SpvOpAtomicUMax: - case SpvOpAtomicAnd: - case SpvOpAtomicOr: - case SpvOpAtomicXor: - fill_common_atomic_sources(b, opcode, w, &atomic->src[1]); - break; - - default: - vtn_fail("Invalid SPIR-V atomic"); - - } - } else { + } else if (vtn_pointer_uses_ssa_offset(b, ptr)) { nir_ssa_def *offset, *index; offset = vtn_pointer_to_offset(b, ptr, &index); @@ -2896,6 +2856,44 @@ vtn_handle_atomics(struct vtn_builder *b, SpvOp opcode, fill_common_atomic_sources(b, opcode, w, &atomic->src[src]); break; + default: + vtn_fail("Invalid SPIR-V atomic"); + } + } else { + nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr); + const struct glsl_type *deref_type = deref->type; + nir_intrinsic_op op = get_deref_nir_atomic_op(b, opcode); + atomic = nir_intrinsic_instr_create(b->nb.shader, op); + atomic->src[0] = nir_src_for_ssa(&deref->dest.ssa); + + switch (opcode) { + case SpvOpAtomicLoad: + atomic->num_components = glsl_get_vector_elements(deref_type); + break; + + case SpvOpAtomicStore: + atomic->num_components = glsl_get_vector_elements(deref_type); + nir_intrinsic_set_write_mask(atomic, (1 << atomic->num_components) - 1); + atomic->src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def); + break; + + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + fill_common_atomic_sources(b, opcode, w, &atomic->src[1]); + break; + default: vtn_fail("Invalid SPIR-V atomic"); } diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 342d4b74d71..8e3fa4af7f2 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -454,6 +454,9 @@ struct vtn_pointer { enum gl_access_qualifier access; }; +bool vtn_pointer_uses_ssa_offset(struct vtn_builder *b, + struct vtn_pointer *ptr); + struct vtn_variable { enum vtn_variable_mode mode; diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 7e80263abf3..97d3be75ea3 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -44,7 +44,7 @@ vtn_access_chain_create(struct vtn_builder *b, unsigned length) return chain; } -static bool +bool vtn_pointer_uses_ssa_offset(struct vtn_builder *b, struct vtn_pointer *ptr) {