From eee3091e3e7293f6e1799ae6b3da44dc107bfc17 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 30 Jul 2024 16:04:04 +0800 Subject: [PATCH] glsl: add KHR_shader_subgroup_shuffle builtin functions Signed-off-by: Qiang Yu Part-of: --- src/compiler/glsl/builtin_functions.cpp | 81 +++++++++++++++++++++++++ src/compiler/glsl/glsl_to_nir.cpp | 10 ++- src/compiler/glsl/ir.h | 3 + 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index 005a13fceb7..e52d2a38306 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -1057,6 +1057,18 @@ compute_shader_and_subgroup_basic(const _mesa_glsl_parse_state *state) return state->stage == MESA_SHADER_COMPUTE && state->KHR_shader_subgroup_basic_enable; } +static bool +subgroup_shuffle(const _mesa_glsl_parse_state *state) +{ + return state->KHR_shader_subgroup_shuffle_enable; +} + +static bool +subgroup_shuffle_and_fp64(const _mesa_glsl_parse_state *state) +{ + return subgroup_shuffle(state) && fp64(state); +} + /** @} */ /******************************************************************************/ @@ -1473,6 +1485,12 @@ private: ir_function_signature *_elect_intrinsic(); ir_function_signature *_elect(); + ir_function_signature *_shuffle_intrinsic(const glsl_type *type); + ir_function_signature *_shuffle(const glsl_type *type); + + ir_function_signature *_shuffle_xor_intrinsic(const glsl_type *type); + ir_function_signature *_shuffle_xor(const glsl_type *type); + #undef B0 #undef B1 #undef B2 @@ -1887,6 +1905,10 @@ builtin_builder::create_intrinsics() NULL); add_function("__intrinsic_elect", _elect_intrinsic(), NULL); + + add_function("__intrinsic_shuffle", FIUBD(_shuffle_intrinsic), NULL); + + add_function("__intrinsic_shuffle_xor", FIUBD(_shuffle_xor_intrinsic), NULL); } /** @@ -5796,6 +5818,10 @@ builtin_builder::create_builtins() add_function("subgroupBallotFindLSB", _ballot_bit("__intrinsic_ballot_find_lsb"), NULL); add_function("subgroupBallotFindMSB", _ballot_bit("__intrinsic_ballot_find_msb"), NULL); + add_function("subgroupShuffle", FIUBD(_shuffle), NULL); + + add_function("subgroupShuffleXor", FIUBD(_shuffle_xor), NULL); + #undef F #undef FI #undef FIUDHF_VEC @@ -9088,6 +9114,61 @@ builtin_builder::_elect() return sig; } +ir_function_signature * +builtin_builder::_shuffle_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_shuffle, + glsl_type_is_double(type) ? subgroup_shuffle_and_fp64 : subgroup_shuffle, + 2, value, id); + return sig; +} + +ir_function_signature * +builtin_builder::_shuffle(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_shuffle_and_fp64 : subgroup_shuffle, + 2, value, id); + + ir_variable *retval = body.make_temp(type, "retval"); + + body.emit(call(shader->symbols->get_function("__intrinsic_shuffle"), retval, sig->parameters)); + body.emit(ret(retval)); + return sig; +} + +ir_function_signature * +builtin_builder::_shuffle_xor_intrinsic(const glsl_type *type) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *mask = in_var(&glsl_type_builtin_uint, "mask"); + MAKE_INTRINSIC(type, ir_intrinsic_shuffle_xor, + glsl_type_is_double(type) ? subgroup_shuffle_and_fp64 : subgroup_shuffle, + 2, value, mask); + return sig; +} + +ir_function_signature * +builtin_builder::_shuffle_xor(const glsl_type *type) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *mask = in_var(&glsl_type_builtin_uint, "mask"); + + MAKE_SIG(type, glsl_type_is_double(type) ? subgroup_shuffle_and_fp64 : subgroup_shuffle, + 2, value, mask); + + ir_variable *retval = body.make_temp(type, "retval"); + + body.emit(call(shader->symbols->get_function("__intrinsic_shuffle_xor"), + retval, sig->parameters)); + body.emit(ret(retval)); + return sig; +} + /** @} */ /******************************************************************************/ diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 4af694d3de2..31c0266951f 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -1086,6 +1086,12 @@ nir_visitor::visit(ir_call *ir) case ir_intrinsic_ballot_find_msb: op = nir_intrinsic_ballot_find_msb; break; + case ir_intrinsic_shuffle: + op = nir_intrinsic_shuffle; + break; + case ir_intrinsic_shuffle_xor: + op = nir_intrinsic_shuffle_xor; + break; default: unreachable("not reached"); } @@ -1480,7 +1486,9 @@ nir_visitor::visit(ir_call *ir) case nir_intrinsic_ballot_bit_count_inclusive: case nir_intrinsic_ballot_bit_count_exclusive: case nir_intrinsic_ballot_find_lsb: - case nir_intrinsic_ballot_find_msb: { + case nir_intrinsic_ballot_find_msb: + case nir_intrinsic_shuffle: + case nir_intrinsic_shuffle_xor: { if (ir->return_deref) { const glsl_type *type = ir->return_deref->type; nir_def_init(&instr->instr, &instr->def, glsl_get_vector_elements(type), diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index bd53e1d663a..c89f2277613 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -1146,6 +1146,9 @@ enum ir_intrinsic_id { ir_intrinsic_subgroup_memory_barrier_shared, ir_intrinsic_subgroup_memory_barrier_image, ir_intrinsic_elect, + + ir_intrinsic_shuffle, + ir_intrinsic_shuffle_xor, }; /*@{*/