glsl: add KHR_shader_subgroup_quad builtin functions

Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30610>
This commit is contained in:
Qiang Yu 2024-08-02 17:54:23 +08:00
parent 72517a8be9
commit 7538edf706
3 changed files with 108 additions and 1 deletions

View file

@ -1105,6 +1105,18 @@ subgroup_clustered_and_fp64(const _mesa_glsl_parse_state *state)
return subgroup_clustered(state) && fp64(state);
}
static bool
subgroup_quad(const _mesa_glsl_parse_state *state)
{
return state->KHR_shader_subgroup_quad_enable;
}
static bool
subgroup_quad_and_fp64(const _mesa_glsl_parse_state *state)
{
return subgroup_quad(state) && fp64(state);
}
/** @} */
/******************************************************************************/
@ -1543,6 +1555,12 @@ private:
ir_function_signature *_subgroup_clustered(const glsl_type *type,
const char *intrinsic_name);
ir_function_signature *_quad_broadcast_intrinsic(const glsl_type *type);
ir_function_signature *_quad_broadcast(const glsl_type *type);
ir_function_signature *_quad_swap_intrinsic(const glsl_type *type, enum ir_intrinsic_id id);
ir_function_signature *_quad_swap(const glsl_type *type, const char *intrinsic_name);
#undef B0
#undef B1
#undef B2
@ -2008,6 +2026,15 @@ builtin_builder::create_intrinsics()
SUBGROUP_ARITH_INTRINSICS(arithmetic, exclusive);
SUBGROUP_ARITH_INTRINSICS(clustered, clustered);
add_function("__intrinsic_quad_broadcast", FIUBD(_quad_broadcast_intrinsic), NULL);
add_function("__intrinsic_quad_swap_horizontal",
FIUBD(_quad_swap_intrinsic, ir_intrinsic_quad_swap_horizontal), NULL);
add_function("__intrinsic_quad_swap_vertical",
FIUBD(_quad_swap_intrinsic, ir_intrinsic_quad_swap_vertical), NULL);
add_function("__intrinsic_quad_swap_diagonal",
FIUBD(_quad_swap_intrinsic, ir_intrinsic_quad_swap_diagonal), NULL);
}
/**
@ -5947,6 +5974,15 @@ builtin_builder::create_builtins()
SUBGROUP_ARITH(clustered, Clustered, clustered);
add_function("subgroupQuadBroadcast", FIUBD(_quad_broadcast), NULL);
add_function("subgroupQuadSwapHorizontal",
FIUBD(_quad_swap, "__intrinsic_quad_swap_horizontal"), NULL);
add_function("subgroupQuadSwapVertical",
FIUBD(_quad_swap, "__intrinsic_quad_swap_vertical"), NULL);
add_function("subgroupQuadSwapDiagonal",
FIUBD(_quad_swap, "__intrinsic_quad_swap_diagonal"), NULL);
#undef F
#undef FI
#undef FIUDHF_VEC
@ -9400,6 +9436,56 @@ builtin_builder::_subgroup_clustered(const glsl_type *type, const char *intrinsi
return sig;
}
ir_function_signature *
builtin_builder::_quad_broadcast_intrinsic(const glsl_type *type)
{
ir_variable *value = in_var(type, "value");
ir_variable *id = in_var(&glsl_type_builtin_uint, "id");
MAKE_INTRINSIC(type, ir_intrinsic_quad_broadcast,
glsl_type_is_double(type) ? subgroup_quad_and_fp64 : subgroup_quad,
2, value, id);
return sig;
}
ir_function_signature *
builtin_builder::_quad_broadcast(const glsl_type *type)
{
ir_variable *value = in_var(type, "value");
ir_variable *id = in_var(&glsl_type_builtin_uint, "id");
MAKE_SIG(type, glsl_type_is_double(type) ? subgroup_quad_and_fp64 : subgroup_quad,
2, value, id);
ir_variable *retval = body.make_temp(type, "retval");
body.emit(call(shader->symbols->get_function("__intrinsic_quad_broadcast"),
retval, sig->parameters));
body.emit(ret(retval));
return sig;
}
ir_function_signature *
builtin_builder::_quad_swap_intrinsic(const glsl_type *type, enum ir_intrinsic_id id)
{
ir_variable *value = in_var(type, "value");
MAKE_INTRINSIC(type, id,
glsl_type_is_double(type) ? subgroup_quad_and_fp64 : subgroup_quad,
1, value);
return sig;
}
ir_function_signature *
builtin_builder::_quad_swap(const glsl_type *type, const char *intrinsic_name)
{
ir_variable *value = in_var(type, "value");
MAKE_SIG(type, glsl_type_is_double(type) ? subgroup_quad_and_fp64 : subgroup_quad,
1, value);
ir_variable *retval = body.make_temp(type, "retval");
body.emit(call(shader->symbols->get_function(intrinsic_name), retval, sig->parameters));
body.emit(ret(retval));
return sig;
}
/** @} */
/******************************************************************************/

View file

@ -1175,6 +1175,18 @@ nir_visitor::visit(ir_call *ir)
case ir_intrinsic_exclusive_xor:
op = nir_intrinsic_exclusive_scan;
break;
case ir_intrinsic_quad_broadcast:
op = nir_intrinsic_quad_broadcast;
break;
case ir_intrinsic_quad_swap_horizontal:
op = nir_intrinsic_quad_swap_horizontal;
break;
case ir_intrinsic_quad_swap_vertical:
op = nir_intrinsic_quad_swap_vertical;
break;
case ir_intrinsic_quad_swap_diagonal:
op = nir_intrinsic_quad_swap_diagonal;
break;
default:
unreachable("not reached");
}
@ -1598,7 +1610,11 @@ nir_visitor::visit(ir_call *ir)
case nir_intrinsic_shuffle:
case nir_intrinsic_shuffle_xor:
case nir_intrinsic_shuffle_up:
case nir_intrinsic_shuffle_down: {
case nir_intrinsic_shuffle_down:
case nir_intrinsic_quad_broadcast:
case nir_intrinsic_quad_swap_horizontal:
case nir_intrinsic_quad_swap_vertical:
case nir_intrinsic_quad_swap_diagonal: {
if (ir->return_deref) {
const glsl_type *type = ir->return_deref->type;
nir_def_init(&instr->instr, &instr->def, glsl_get_vector_elements(type),

View file

@ -1183,6 +1183,11 @@ enum ir_intrinsic_id {
ir_intrinsic_clustered_and,
ir_intrinsic_clustered_or,
ir_intrinsic_clustered_xor,
ir_intrinsic_quad_broadcast,
ir_intrinsic_quad_swap_horizontal,
ir_intrinsic_quad_swap_vertical,
ir_intrinsic_quad_swap_diagonal,
};
/*@{*/