spirv: Implement SPV_KHR_subgroup_rotate

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>
This commit is contained in:
Caio Oliveira
2022-11-16 20:41:28 -08:00
committed by Marge Bot
parent 3328714295
commit 070f042e10
4 changed files with 24 additions and 1 deletions

View 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;

View 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;

View 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;

View 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,