diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index 80de51c4bdf..30aec4b7161 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -1093,6 +1093,18 @@ subgroup_arithmetic_and_fp64(const _mesa_glsl_parse_state *state) return subgroup_arithmetic(state) && fp64(state); } +static bool +subgroup_clustered(const _mesa_glsl_parse_state *state) +{ + return state->KHR_shader_subgroup_clustered_enable; +} + +static bool +subgroup_clustered_and_fp64(const _mesa_glsl_parse_state *state) +{ + return subgroup_clustered(state) && fp64(state); +} + /** @} */ /******************************************************************************/ @@ -1526,6 +1538,11 @@ private: ir_function_signature *_subgroup_arithmetic(const glsl_type *type, const char *intrinsic_name); + ir_function_signature *_subgroup_clustered_intrinsic(const glsl_type *type, + enum ir_intrinsic_id id); + ir_function_signature *_subgroup_clustered(const glsl_type *type, + const char *intrinsic_name); + #undef B0 #undef B1 #undef B2 @@ -1989,6 +2006,8 @@ builtin_builder::create_intrinsics() SUBGROUP_ARITH_INTRINSICS(arithmetic, reduce); SUBGROUP_ARITH_INTRINSICS(arithmetic, inclusive); SUBGROUP_ARITH_INTRINSICS(arithmetic, exclusive); + + SUBGROUP_ARITH_INTRINSICS(clustered, clustered); } /** @@ -5926,6 +5945,8 @@ builtin_builder::create_builtins() SUBGROUP_ARITH(arithmetic, Inclusive, inclusive); SUBGROUP_ARITH(arithmetic, Exclusive, exclusive); + SUBGROUP_ARITH(clustered, Clustered, clustered); + #undef F #undef FI #undef FIUDHF_VEC @@ -9350,6 +9371,35 @@ builtin_builder::_subgroup_arithmetic(const glsl_type *type, const char *intrins return sig; } +ir_function_signature * +builtin_builder::_subgroup_clustered_intrinsic(const glsl_type *type, enum ir_intrinsic_id id) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *size = + new(mem_ctx) ir_variable(&glsl_type_builtin_uint, "clusterSize", ir_var_const_in); + + MAKE_INTRINSIC(type, id, + glsl_type_is_double(type) ? subgroup_clustered_and_fp64 : subgroup_clustered, + 2, value, size); + return sig; +} + +ir_function_signature * +builtin_builder::_subgroup_clustered(const glsl_type *type, const char *intrinsic_name) +{ + ir_variable *value = in_var(type, "value"); + ir_variable *size = + new(mem_ctx) ir_variable(&glsl_type_builtin_uint, "clusterSize", ir_var_const_in); + + MAKE_SIG(type, glsl_type_is_double(type) ? subgroup_clustered_and_fp64 : subgroup_clustered, + 2, value, size); + + 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; +} + /** @} */ /******************************************************************************/ diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index ec2443aa7c1..f006e8b4406 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -856,6 +856,7 @@ get_reduction_op(enum ir_intrinsic_id id, const glsl_type *type) case ir_intrinsic_reduce_##op: \ case ir_intrinsic_inclusive_##op: \ case ir_intrinsic_exclusive_##op: \ + case ir_intrinsic_clustered_##op: \ return CONV_OP(op); switch (id) { @@ -1147,6 +1148,13 @@ nir_visitor::visit(ir_call *ir) case ir_intrinsic_reduce_and: case ir_intrinsic_reduce_or: case ir_intrinsic_reduce_xor: + case ir_intrinsic_clustered_add: + case ir_intrinsic_clustered_mul: + case ir_intrinsic_clustered_min: + case ir_intrinsic_clustered_max: + case ir_intrinsic_clustered_and: + case ir_intrinsic_clustered_or: + case ir_intrinsic_clustered_xor: op = nir_intrinsic_reduce; break; case ir_intrinsic_inclusive_add: @@ -1548,9 +1556,18 @@ nir_visitor::visit(ir_call *ir) glsl_get_bit_size(type)); instr->num_components = instr->def.num_components; - ir_rvalue *value = (ir_rvalue *)ir->actual_parameters.get_head(); + exec_node *param = ir->actual_parameters.get_head(); + ir_rvalue *value = ((ir_instruction *)param)->as_rvalue(); instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); + param = param->get_next(); + if (!param->is_tail_sentinel()) { + ir_constant *size = ((ir_instruction *)param)->as_constant(); + assert(size); + + nir_intrinsic_set_cluster_size(instr, size->get_uint_component(0)); + } + nir_intrinsic_set_reduction_op(instr, get_reduction_op(ir->callee->intrinsic_id, type)); nir_builder_instr_insert(&b, &instr->instr); diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index 5fa4c116605..298e4cf9029 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -1175,6 +1175,14 @@ enum ir_intrinsic_id { ir_intrinsic_exclusive_and, ir_intrinsic_exclusive_or, ir_intrinsic_exclusive_xor, + + ir_intrinsic_clustered_add, + ir_intrinsic_clustered_mul, + ir_intrinsic_clustered_min, + ir_intrinsic_clustered_max, + ir_intrinsic_clustered_and, + ir_intrinsic_clustered_or, + ir_intrinsic_clustered_xor, }; /*@{*/