diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index e52d2a38306..d68b7890fa4 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -1069,6 +1069,18 @@ subgroup_shuffle_and_fp64(const _mesa_glsl_parse_state *state) return subgroup_shuffle(state) && fp64(state); } +static bool +subgroup_shuffle_relative(const _mesa_glsl_parse_state *state) +{ + return state->KHR_shader_subgroup_shuffle_relative_enable; +} + +static bool +subgroup_shuffle_relative_and_fp64(const _mesa_glsl_parse_state *state) +{ + return subgroup_shuffle_relative(state) && fp64(state); +} + /** @} */ /******************************************************************************/ @@ -1491,6 +1503,12 @@ private: ir_function_signature *_shuffle_xor_intrinsic(const glsl_type *type); ir_function_signature *_shuffle_xor(const glsl_type *type); + ir_function_signature *_shuffle_up_intrinsic(const glsl_type *type); + ir_function_signature *_shuffle_up(const glsl_type *type); + + ir_function_signature *_shuffle_down_intrinsic(const glsl_type *type); + ir_function_signature *_shuffle_down(const glsl_type *type); + #undef B0 #undef B1 #undef B2 @@ -1909,6 +1927,10 @@ builtin_builder::create_intrinsics() add_function("__intrinsic_shuffle", FIUBD(_shuffle_intrinsic), NULL); add_function("__intrinsic_shuffle_xor", FIUBD(_shuffle_xor_intrinsic), NULL); + + add_function("__intrinsic_shuffle_up", FIUBD(_shuffle_up_intrinsic), NULL); + + add_function("__intrinsic_shuffle_down", FIUBD(_shuffle_down_intrinsic), NULL); } /** @@ -5822,6 +5844,10 @@ builtin_builder::create_builtins() add_function("subgroupShuffleXor", FIUBD(_shuffle_xor), NULL); + add_function("subgroupShuffleUp", FIUBD(_shuffle_up), NULL); + + add_function("subgroupShuffleDown", FIUBD(_shuffle_down), NULL); + #undef F #undef FI #undef FIUDHF_VEC @@ -9169,6 +9195,60 @@ builtin_builder::_shuffle_xor(const glsl_type *type) return sig; } +ir_function_signature * +builtin_builder::_shuffle_up_intrinsic(const glsl_type *type) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *delta = in_var(&glsl_type_builtin_uint, "delta"); + MAKE_INTRINSIC(type, ir_intrinsic_shuffle_up, + glsl_type_is_double(type) ? subgroup_shuffle_relative_and_fp64 : subgroup_shuffle_relative, + 2, value, delta); + return sig; +} + +ir_function_signature * +builtin_builder::_shuffle_up(const glsl_type *type) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *delta = in_var(&glsl_type_builtin_uint, "delta"); + + MAKE_SIG(type, glsl_type_is_double(type) ? subgroup_shuffle_relative_and_fp64 : subgroup_shuffle_relative, + 2, value, delta); + ir_variable *retval = body.make_temp(type, "retval"); + + body.emit(call(shader->symbols->get_function("__intrinsic_shuffle_up"), + retval, sig->parameters)); + body.emit(ret(retval)); + return sig; +} + +ir_function_signature * +builtin_builder::_shuffle_down_intrinsic(const glsl_type *type) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *delta = in_var(&glsl_type_builtin_uint, "delta"); + MAKE_INTRINSIC(type, ir_intrinsic_shuffle_down, + glsl_type_is_double(type) ? subgroup_shuffle_relative_and_fp64 : subgroup_shuffle_relative, + 2, value, delta); + return sig; +} + +ir_function_signature * +builtin_builder::_shuffle_down(const glsl_type *type) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *delta = in_var(&glsl_type_builtin_uint, "delta"); + + MAKE_SIG(type, glsl_type_is_double(type) ? subgroup_shuffle_relative_and_fp64 : subgroup_shuffle_relative, + 2, value, delta); + ir_variable *retval = body.make_temp(type, "retval"); + + body.emit(call(shader->symbols->get_function("__intrinsic_shuffle_down"), + 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 31c0266951f..c99a1e3975a 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -1092,6 +1092,12 @@ nir_visitor::visit(ir_call *ir) case ir_intrinsic_shuffle_xor: op = nir_intrinsic_shuffle_xor; break; + case ir_intrinsic_shuffle_up: + op = nir_intrinsic_shuffle_up; + break; + case ir_intrinsic_shuffle_down: + op = nir_intrinsic_shuffle_down; + break; default: unreachable("not reached"); } @@ -1488,7 +1494,9 @@ nir_visitor::visit(ir_call *ir) case nir_intrinsic_ballot_find_lsb: case nir_intrinsic_ballot_find_msb: case nir_intrinsic_shuffle: - case nir_intrinsic_shuffle_xor: { + case nir_intrinsic_shuffle_xor: + case nir_intrinsic_shuffle_up: + case nir_intrinsic_shuffle_down: { 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 c89f2277613..dec285c7f36 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -1149,6 +1149,8 @@ enum ir_intrinsic_id { ir_intrinsic_shuffle, ir_intrinsic_shuffle_xor, + ir_intrinsic_shuffle_up, + ir_intrinsic_shuffle_down, }; /*@{*/