spirv: Implement SPV_KHR_subgroup_rotate
authorCaio Oliveira <caio.oliveira@intel.com>
Thu, 17 Nov 2022 04:41:28 +0000 (20:41 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 24 Feb 2023 06:33:51 +0000 (06:33 +0000)
Map SpvOpGroupNonUniformRotateKHR to nir_intrinsic_rotate.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19797>

src/compiler/shader_info.h
src/compiler/spirv/spirv_to_nir.c
src/compiler/spirv/vtn_private.h
src/compiler/spirv/vtn_subgroup.c

index fd673d1..2e3caa0 100644 (file)
@@ -101,6 +101,7 @@ struct spirv_supported_capabilities {
    bool subgroup_basic;
    bool subgroup_dispatch;
    bool subgroup_quad;
+   bool subgroup_rotate;
    bool subgroup_shuffle;
    bool subgroup_uniform_control_flow;
    bool subgroup_vote;
index 2c9c75b..78fbc5f 100644 (file)
@@ -2484,7 +2484,7 @@ vtn_mem_semantics_to_nir_var_modes(struct vtn_builder *b,
    return modes;
 }
 
-static nir_scope
+nir_scope
 vtn_scope_to_nir_scope(struct vtn_builder *b, SpvScope scope)
 {
    nir_scope nir_scope;
@@ -4885,6 +4885,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
          spv_check_supported(shader_viewport_mask_nv, cap);
          break;
 
+      case SpvCapabilityGroupNonUniformRotateKHR:
+         spv_check_supported(subgroup_rotate, cap);
+         break;
+
       default:
          vtn_fail("Unhandled capability: %s (%u)",
                   spirv_capability_to_string(cap), cap);
@@ -6234,6 +6238,7 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
    case SpvOpSubgroupShuffleDownINTEL:
    case SpvOpSubgroupShuffleUpINTEL:
    case SpvOpSubgroupShuffleXorINTEL:
+   case SpvOpGroupNonUniformRotateKHR:
       vtn_handle_subgroup(b, opcode, w, count);
       break;
 
index fb4cd12..28ada26 100644 (file)
@@ -600,6 +600,9 @@ const struct glsl_type *
 vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type,
                       enum vtn_variable_mode mode);
 
+nir_scope
+vtn_scope_to_nir_scope(struct vtn_builder *b, SpvScope scope);
+
 struct vtn_image_pointer {
    nir_deref_instr *image;
    nir_ssa_def *coord;
index b025661..5fac2ae 100644 (file)
@@ -342,6 +342,20 @@ vtn_handle_subgroup(struct vtn_builder *b, SpvOp opcode,
       break;
    }
 
+   case SpvOpGroupNonUniformRotateKHR: {
+      const nir_scope scope = vtn_scope_to_nir_scope(b, vtn_constant_uint(b, w[3]));
+      const uint32_t cluster_size = count > 6 ? vtn_constant_uint(b, w[6]) : 0;
+      vtn_fail_if(cluster_size && !IS_POT(cluster_size),
+                  "Behavior is undefined unless ClusterSize is at least 1 and a power of 2.");
+
+      struct vtn_ssa_value *value = vtn_ssa_value(b, w[4]);
+      struct vtn_ssa_value *delta = vtn_ssa_value(b, w[5]);
+      vtn_push_nir_ssa(b, w[2],
+         vtn_build_subgroup_instr(b, nir_intrinsic_rotate,
+                                  value, delta->def, scope, cluster_size)->def);
+      break;
+   }
+
    case SpvOpGroupNonUniformQuadBroadcast:
       vtn_push_ssa_value(b, w[2],
          vtn_build_subgroup_instr(b, nir_intrinsic_quad_broadcast,