glsl: add KHR_shader_subgroup_basic 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-07-29 17:24:12 +08:00
parent 6ae013a032
commit f0c8520a90
3 changed files with 139 additions and 1 deletions

View file

@ -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;
}
/** @} */
/******************************************************************************/

View file

@ -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),

View file

@ -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,
};
/*@{*/