diff options
author | Lionel Landwerlin <[email protected]> | 2016-09-06 22:51:23 +0100 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2016-09-07 17:37:37 +0100 |
commit | 0ad84b4366bd868a75146c3c2babdbbce8995b90 (patch) | |
tree | dbe89e51db9487afeb56b21505c85b9fa57de2f0 | |
parent | 37763bf44682ef3ec2e3772f997675d210b6033a (diff) |
spirv/nir: Implement OpAtomicLoad/Store for shared variables
Missing bits from 2afb950161f847d9b0a7be03dfb62cacc5ea51ba.
Signed-off-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r-- | src/compiler/spirv/spirv_to_nir.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index a675e4d436d..7e7a0263089 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -1919,11 +1919,44 @@ vtn_handle_ssbo_or_shared_atomic(struct vtn_builder *b, SpvOp opcode, */ if (chain->var->mode == vtn_variable_mode_workgroup) { + struct vtn_type *type = chain->var->type; nir_deref *deref = &vtn_access_chain_to_deref(b, chain)->deref; nir_intrinsic_op op = get_shared_nir_atomic_op(opcode); atomic = nir_intrinsic_instr_create(b->nb.shader, op); atomic->variables[0] = nir_deref_as_var(nir_copy_deref(atomic, deref)); - fill_common_atomic_sources(b, opcode, w, &atomic->src[0]); + + switch (opcode) { + case SpvOpAtomicLoad: + atomic->num_components = glsl_get_vector_elements(type->type); + break; + + case SpvOpAtomicStore: + atomic->num_components = glsl_get_vector_elements(type->type); + nir_intrinsic_set_write_mask(atomic, (1 << atomic->num_components) - 1); + atomic->src[0] = 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[0]); + break; + + default: + unreachable("Invalid SPIR-V atomic"); + + } } else { assert(chain->var->mode == vtn_variable_mode_ssbo); struct vtn_type *type; |