spirv: Choose atomic deref type with pointer_uses_ssa_offset

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 <apinheiro@igalia.com>
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
This commit is contained in:
Jason Ekstrand
2018-12-14 18:20:00 -06:00
committed by Jason Ekstrand
parent 5c3cb9c3ce
commit be039cb467
3 changed files with 43 additions and 42 deletions

View File

@@ -2801,47 +2801,7 @@ vtn_handle_atomics(struct vtn_builder *b, SpvOp opcode,
unreachable("Invalid SPIR-V atomic"); unreachable("Invalid SPIR-V atomic");
} }
} else if (ptr->mode == vtn_variable_mode_workgroup && } else if (vtn_pointer_uses_ssa_offset(b, ptr)) {
!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 {
nir_ssa_def *offset, *index; nir_ssa_def *offset, *index;
offset = vtn_pointer_to_offset(b, ptr, &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]); fill_common_atomic_sources(b, opcode, w, &atomic->src[src]);
break; 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: default:
vtn_fail("Invalid SPIR-V atomic"); vtn_fail("Invalid SPIR-V atomic");
} }

View File

@@ -454,6 +454,9 @@ struct vtn_pointer {
enum gl_access_qualifier access; enum gl_access_qualifier access;
}; };
bool vtn_pointer_uses_ssa_offset(struct vtn_builder *b,
struct vtn_pointer *ptr);
struct vtn_variable { struct vtn_variable {
enum vtn_variable_mode mode; enum vtn_variable_mode mode;

View File

@@ -44,7 +44,7 @@ vtn_access_chain_create(struct vtn_builder *b, unsigned length)
return chain; return chain;
} }
static bool bool
vtn_pointer_uses_ssa_offset(struct vtn_builder *b, vtn_pointer_uses_ssa_offset(struct vtn_builder *b,
struct vtn_pointer *ptr) struct vtn_pointer *ptr)
{ {