[Mesa-dev] [PATCH] spirv/nir: Implement OpAtomicLoad/Store for shared variables

Lionel Landwerlin llandwerlin at gmail.com
Wed Sep 7 10:10:17 UTC 2016


Missing bits from 2afb950161f847d9b0a7be03dfb62cacc5ea51ba.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: Jason Ekstrand <jason.ekstrand at intel.com>
---
 src/compiler/spirv/spirv_to_nir.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 4d88fdb..f1cd4be 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1920,11 +1920,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;
-- 
2.9.3



More information about the mesa-dev mailing list