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);
+ } else if (vtn_pointer_uses_ssa_offset(b, ptr)) {
+ nir_ssa_def *offset, *index;
+ offset = vtn_pointer_to_offset(b, ptr, &index);
+
+ nir_intrinsic_op op;
+ if (ptr->mode == vtn_variable_mode_ssbo) {
+ op = get_ssbo_nir_atomic_op(b, opcode);
+ } else {
+ vtn_assert(ptr->mode == vtn_variable_mode_workgroup &&
+ b->options->lower_workgroup_access_to_offsets);
+ op = get_shared_nir_atomic_op(b, opcode);
+ }
+
atomic = nir_intrinsic_instr_create(b->nb.shader, op);
- atomic->src[0] = nir_src_for_ssa(&deref->dest.ssa);
+ int src = 0;
switch (opcode) {
case SpvOpAtomicLoad:
- atomic->num_components = glsl_get_vector_elements(deref_type);
+ atomic->num_components = glsl_get_vector_elements(ptr->type->type);
+ nir_intrinsic_set_align(atomic, 4, 0);
+ if (ptr->mode == vtn_variable_mode_ssbo)
+ atomic->src[src++] = nir_src_for_ssa(index);
+ atomic->src[src++] = nir_src_for_ssa(offset);
break;
case SpvOpAtomicStore:
- atomic->num_components = glsl_get_vector_elements(deref_type);
+ atomic->num_components = glsl_get_vector_elements(ptr->type->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);
+ nir_intrinsic_set_align(atomic, 4, 0);
+ atomic->src[src++] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
+ if (ptr->mode == vtn_variable_mode_ssbo)
+ atomic->src[src++] = nir_src_for_ssa(index);
+ atomic->src[src++] = nir_src_for_ssa(offset);
break;
case SpvOpAtomicExchange:
case SpvOpAtomicAnd:
case SpvOpAtomicOr:
case SpvOpAtomicXor:
- fill_common_atomic_sources(b, opcode, w, &atomic->src[1]);
+ if (ptr->mode == vtn_variable_mode_ssbo)
+ atomic->src[src++] = nir_src_for_ssa(index);
+ atomic->src[src++] = nir_src_for_ssa(offset);
+ fill_common_atomic_sources(b, opcode, w, &atomic->src[src]);
break;
default:
vtn_fail("Invalid SPIR-V atomic");
-
}
} else {
- nir_ssa_def *offset, *index;
- offset = vtn_pointer_to_offset(b, ptr, &index);
-
- nir_intrinsic_op op;
- if (ptr->mode == vtn_variable_mode_ssbo) {
- op = get_ssbo_nir_atomic_op(b, opcode);
- } else {
- vtn_assert(ptr->mode == vtn_variable_mode_workgroup &&
- b->options->lower_workgroup_access_to_offsets);
- op = get_shared_nir_atomic_op(b, opcode);
- }
-
+ 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);
- int src = 0;
switch (opcode) {
case SpvOpAtomicLoad:
- atomic->num_components = glsl_get_vector_elements(ptr->type->type);
- nir_intrinsic_set_align(atomic, 4, 0);
- if (ptr->mode == vtn_variable_mode_ssbo)
- atomic->src[src++] = nir_src_for_ssa(index);
- atomic->src[src++] = nir_src_for_ssa(offset);
+ atomic->num_components = glsl_get_vector_elements(deref_type);
break;
case SpvOpAtomicStore:
- atomic->num_components = glsl_get_vector_elements(ptr->type->type);
+ atomic->num_components = glsl_get_vector_elements(deref_type);
nir_intrinsic_set_write_mask(atomic, (1 << atomic->num_components) - 1);
- nir_intrinsic_set_align(atomic, 4, 0);
- atomic->src[src++] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
- if (ptr->mode == vtn_variable_mode_ssbo)
- atomic->src[src++] = nir_src_for_ssa(index);
- atomic->src[src++] = nir_src_for_ssa(offset);
+ atomic->src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
break;
case SpvOpAtomicExchange:
case SpvOpAtomicAnd:
case SpvOpAtomicOr:
case SpvOpAtomicXor:
- if (ptr->mode == vtn_variable_mode_ssbo)
- atomic->src[src++] = nir_src_for_ssa(index);
- atomic->src[src++] = nir_src_for_ssa(offset);
- fill_common_atomic_sources(b, opcode, w, &atomic->src[src]);
+ fill_common_atomic_sources(b, opcode, w, &atomic->src[1]);
break;
default: