From f0c8520a90f4439e86bd076b1c36a4d691480c47 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 29 Jul 2024 17:24:12 +0800 Subject: [PATCH] glsl: add KHR_shader_subgroup_basic builtin functions Signed-off-by: Qiang Yu Part-of: --- src/compiler/glsl/builtin_functions.cpp | 96 +++++++++++++++++++++++++ src/compiler/glsl/glsl_to_nir.cpp | 37 +++++++++- src/compiler/glsl/ir.h | 7 ++ 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index c4ed2f73229..5f2a669cf49 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -1000,6 +1000,18 @@ derivatives_texture_cube_map_array_and_clamp(const _mesa_glsl_parse_state *state return derivatives_texture_cube_map_array(state) && state->ARB_sparse_texture_clamp_enable; } +static bool +subgroup_basic(const _mesa_glsl_parse_state *state) +{ + return state->KHR_shader_subgroup_basic_enable; +} + +static bool +compute_shader_and_subgroup_basic(const _mesa_glsl_parse_state *state) +{ + return state->stage == MESA_SHADER_COMPUTE && state->KHR_shader_subgroup_basic_enable; +} + /** @} */ /******************************************************************************/ @@ -1393,6 +1405,14 @@ private: ir_function_signature *_helper_invocation_intrinsic(); ir_function_signature *_helper_invocation(); + ir_function_signature *_subgroup_barrier_intrinsic(enum ir_intrinsic_id id, + builtin_available_predicate avail); + ir_function_signature *_subgroup_barrier(const char *intrinsic_name, + builtin_available_predicate avail); + + ir_function_signature *_elect_intrinsic(); + ir_function_signature *_elect(); + #undef B0 #undef B1 #undef B2 @@ -1759,6 +1779,28 @@ builtin_builder::create_intrinsics() add_function("__intrinsic_is_sparse_texels_resident", _is_sparse_texels_resident_intrinsic(), NULL); + + add_function("__intrinsic_subgroup_barrier", + _subgroup_barrier_intrinsic(ir_intrinsic_subgroup_barrier, subgroup_basic), + NULL); + add_function("__intrinsic_subgroup_memory_barrier", + _subgroup_barrier_intrinsic(ir_intrinsic_subgroup_memory_barrier, + subgroup_basic), + NULL); + add_function("__intrinsic_subgroup_memory_barrier_buffer", + _subgroup_barrier_intrinsic(ir_intrinsic_subgroup_memory_barrier_buffer, + subgroup_basic), + NULL); + add_function("__intrinsic_subgroup_memory_barrier_shared", + _subgroup_barrier_intrinsic(ir_intrinsic_subgroup_memory_barrier_shared, + compute_shader_and_subgroup_basic), + NULL); + add_function("__intrinsic_subgroup_memory_barrier_image", + _subgroup_barrier_intrinsic(ir_intrinsic_subgroup_memory_barrier_image, + subgroup_basic), + NULL); + + add_function("__intrinsic_elect", _elect_intrinsic(), NULL); } /** @@ -5650,6 +5692,23 @@ builtin_builder::create_builtins() &glsl_type_builtin_uvec4), NULL); + add_function("subgroupBarrier", + _subgroup_barrier("__intrinsic_subgroup_barrier", subgroup_basic), NULL); + add_function("subgroupMemoryBarrier", + _subgroup_barrier("__intrinsic_subgroup_memory_barrier", subgroup_basic), NULL); + add_function("subgroupMemoryBarrierBuffer", + _subgroup_barrier("__intrinsic_subgroup_memory_barrier_buffer", subgroup_basic), + NULL); + add_function("subgroupMemoryBarrierShared", + _subgroup_barrier("__intrinsic_subgroup_memory_barrier_shared", + compute_shader_and_subgroup_basic), + NULL); + add_function("subgroupMemoryBarrierImage", + _subgroup_barrier("__intrinsic_subgroup_memory_barrier_image", subgroup_basic), + NULL); + + add_function("subgroupElect", _elect(), NULL); + #undef F #undef FI #undef FIUDHF_VEC @@ -8833,6 +8892,43 @@ builtin_builder::_helper_invocation() return sig; } +ir_function_signature * +builtin_builder::_subgroup_barrier_intrinsic(enum ir_intrinsic_id id, + builtin_available_predicate avail) +{ + MAKE_INTRINSIC(&glsl_type_builtin_void, id, avail, 0); + return sig; +} + +ir_function_signature * +builtin_builder::_subgroup_barrier(const char *intrinsic_name, + builtin_available_predicate avail) +{ + MAKE_SIG(&glsl_type_builtin_void, avail, 0); + body.emit(call(shader->symbols->get_function(intrinsic_name), NULL, sig->parameters)); + return sig; +} + +ir_function_signature * +builtin_builder::_elect_intrinsic() +{ + MAKE_INTRINSIC(&glsl_type_builtin_bool, ir_intrinsic_elect, subgroup_basic, 0); + return sig; +} + +ir_function_signature * +builtin_builder::_elect() +{ + MAKE_SIG(&glsl_type_builtin_bool, subgroup_basic, 0); + + ir_variable *retval = body.make_temp(&glsl_type_builtin_bool, "retval"); + + body.emit(call(shader->symbols->get_function("__intrinsic_elect"), 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 65bbcd328a4..4aaee456833 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -1011,6 +1011,11 @@ nir_visitor::visit(ir_call *ir) case ir_intrinsic_memory_barrier_shared: case ir_intrinsic_memory_barrier_atomic_counter: case ir_intrinsic_group_memory_barrier: + case ir_intrinsic_subgroup_barrier: + case ir_intrinsic_subgroup_memory_barrier: + case ir_intrinsic_subgroup_memory_barrier_buffer: + case ir_intrinsic_subgroup_memory_barrier_shared: + case ir_intrinsic_subgroup_memory_barrier_image: op = nir_intrinsic_barrier; break; case ir_intrinsic_image_size: @@ -1055,6 +1060,9 @@ nir_visitor::visit(ir_call *ir) case ir_intrinsic_is_sparse_texels_resident: op = nir_intrinsic_is_sparse_texels_resident; break; + case ir_intrinsic_elect: + op = nir_intrinsic_elect; + break; default: unreachable("not reached"); } @@ -1274,6 +1282,12 @@ nir_visitor::visit(ir_call *ir) * * https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_gl_spirv.txt */ + if (ir->callee->intrinsic_id == ir_intrinsic_subgroup_barrier) { + nir_barrier(&b, SCOPE_SUBGROUP, SCOPE_SUBGROUP, NIR_MEMORY_ACQ_REL, + nir_var_image | nir_var_mem_ssbo | nir_var_mem_shared | nir_var_mem_global); + break; + } + mesa_scope scope; unsigned modes; switch (ir->callee->intrinsic_id) { @@ -1315,6 +1329,26 @@ nir_visitor::visit(ir_call *ir) scope = SCOPE_DEVICE; modes = nir_var_mem_ssbo; break; + case ir_intrinsic_subgroup_memory_barrier: + scope = SCOPE_SUBGROUP; + modes = nir_var_image | + nir_var_mem_ssbo | + nir_var_mem_shared | + nir_var_mem_global; + break; + case ir_intrinsic_subgroup_memory_barrier_buffer: + scope = SCOPE_SUBGROUP; + modes = nir_var_mem_ssbo | + nir_var_mem_global; + break; + case ir_intrinsic_subgroup_memory_barrier_shared: + scope = SCOPE_SUBGROUP; + modes = nir_var_mem_shared; + break; + case ir_intrinsic_subgroup_memory_barrier_image: + scope = SCOPE_SUBGROUP; + modes = nir_var_image; + break; default: unreachable("invalid intrinsic id for memory barrier"); } @@ -1414,7 +1448,8 @@ nir_visitor::visit(ir_call *ir) case nir_intrinsic_read_invocation: case nir_intrinsic_read_first_invocation: case nir_intrinsic_is_helper_invocation: - case nir_intrinsic_is_sparse_texels_resident: { + case nir_intrinsic_is_sparse_texels_resident: + case nir_intrinsic_elect: { 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 48a11b809e2..f9d8a784274 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -1132,6 +1132,13 @@ enum ir_intrinsic_id { ir_intrinsic_helper_invocation, ir_intrinsic_is_sparse_texels_resident, + + ir_intrinsic_subgroup_barrier, + ir_intrinsic_subgroup_memory_barrier, + ir_intrinsic_subgroup_memory_barrier_buffer, + ir_intrinsic_subgroup_memory_barrier_shared, + ir_intrinsic_subgroup_memory_barrier_image, + ir_intrinsic_elect, }; /*@{*/