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:

committed by
Jason Ekstrand

parent
5c3cb9c3ce
commit
be039cb467
@@ -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");
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user