Mesa (master): spirv: Implement SpvCapabilitySubgroupShuffleINTEL from SPV_INTEL_subgroups

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Nov 4 20:41:39 UTC 2020


Module: Mesa
Branch: master
Commit: b86ce274f9d189dbd2dac65ede5a2c14513787a0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b86ce274f9d189dbd2dac65ede5a2c14513787a0

Author: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
Date:   Thu Sep 17 21:00:42 2020 -0700

spirv: Implement SpvCapabilitySubgroupShuffleINTEL from SPV_INTEL_subgroups

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7448>

---

 src/compiler/shader_info.h        |  2 ++
 src/compiler/spirv/spirv_to_nir.c |  8 ++++++++
 src/compiler/spirv/vtn_subgroup.c | 43 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)

diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
index 59d95416877..7f655bb6ca5 100644
--- a/src/compiler/shader_info.h
+++ b/src/compiler/shader_info.h
@@ -93,6 +93,8 @@ struct spirv_supported_capabilities {
    bool amd_image_read_write_lod;
    bool amd_shader_explicit_vertex_parameter;
    bool amd_image_gather_bias_lod;
+
+   bool intel_subgroup_shuffle;
 };
 
 typedef struct shader_info {
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index f5d7fe4d160..6eb7b8f258d 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -4393,6 +4393,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
          spv_check_supported(float64_atomic_add, cap);
          break;
 
+      case SpvCapabilitySubgroupShuffleINTEL:
+         spv_check_supported(intel_subgroup_shuffle, cap);
+         break;
+
       default:
          vtn_fail("Unhandled capability: %s (%u)",
                   spirv_capability_to_string(cap), cap);
@@ -5327,6 +5331,10 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
    case SpvOpGroupFMaxNonUniformAMD:
    case SpvOpGroupUMaxNonUniformAMD:
    case SpvOpGroupSMaxNonUniformAMD:
+   case SpvOpSubgroupShuffleINTEL:
+   case SpvOpSubgroupShuffleDownINTEL:
+   case SpvOpSubgroupShuffleUpINTEL:
+   case SpvOpSubgroupShuffleXorINTEL:
       vtn_handle_subgroup(b, opcode, w, count);
       break;
 
diff --git a/src/compiler/spirv/vtn_subgroup.c b/src/compiler/spirv/vtn_subgroup.c
index 8e4c3f2ba92..b0256611308 100644
--- a/src/compiler/spirv/vtn_subgroup.c
+++ b/src/compiler/spirv/vtn_subgroup.c
@@ -299,6 +299,49 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode,
       break;
    }
 
+   case SpvOpSubgroupShuffleINTEL:
+   case SpvOpSubgroupShuffleXorINTEL: {
+      nir_intrinsic_op op = opcode == SpvOpSubgroupShuffleINTEL ?
+         nir_intrinsic_shuffle : nir_intrinsic_shuffle_xor;
+      vtn_push_ssa_value(b, w[2],
+         vtn_build_subgroup_instr(b, op, vtn_ssa_value(b, w[3]),
+                                  vtn_get_nir_ssa(b, w[4]), 0, 0));
+      break;
+   }
+
+   case SpvOpSubgroupShuffleUpINTEL:
+   case SpvOpSubgroupShuffleDownINTEL: {
+      /* TODO: Move this lower on the compiler stack, where we can move the
+       * current/other data to adjacent registers to avoid doing a shuffle
+       * twice.
+       */
+
+      nir_builder *nb = &b->nb;
+      nir_ssa_def *size = nir_load_subgroup_size(nb);
+      nir_ssa_def *delta = vtn_get_nir_ssa(b, w[5]);
+
+      /* Rewrite UP in terms of DOWN.
+       *
+       *   UP(a, b, delta) == DOWN(a, b, size - delta)
+       */
+      if (opcode == SpvOpSubgroupShuffleUpINTEL)
+         delta = nir_isub(nb, size, delta);
+
+      nir_ssa_def *index = nir_iadd(nb, nir_load_subgroup_invocation(nb), delta);
+      struct vtn_ssa_value *current =
+         vtn_build_subgroup_instr(b, nir_intrinsic_shuffle, vtn_ssa_value(b, w[3]),
+                                  index, 0, 0);
+
+      struct vtn_ssa_value *next =
+         vtn_build_subgroup_instr(b, nir_intrinsic_shuffle, vtn_ssa_value(b, w[4]),
+                                  nir_isub(nb, index, size), 0, 0);
+
+      nir_ssa_def *cond = nir_ilt(nb, index, size);
+      vtn_push_nir_ssa(b, w[2], nir_bcsel(nb, cond, current->def, next->def));
+
+      break;
+   }
+
    case SpvOpGroupNonUniformQuadBroadcast:
       vtn_push_ssa_value(b, w[2],
          vtn_build_subgroup_instr(b, nir_intrinsic_quad_broadcast,



More information about the mesa-commit mailing list