glsl: Add helperInvocationEXT() builtin
From EXT_demote_to_helper_invocation, implemented with the existing nir_intrinsic_is_helper_invocation. Such builtin is necessary when using `demote` because we can't redefine the value of gl_HelperInvocation (since it is an input variable). Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -819,6 +819,13 @@ shader_atomic_float_minmax(const _mesa_glsl_parse_state *state)
|
||||
{
|
||||
return state->INTEL_shader_atomic_float_minmax_enable;
|
||||
}
|
||||
|
||||
static bool
|
||||
demote_to_helper_invocation(const _mesa_glsl_parse_state *state)
|
||||
{
|
||||
return state->EXT_demote_to_helper_invocation_enable;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1182,6 +1189,9 @@ private:
|
||||
ir_function_signature *_vote(const char *intrinsic_name,
|
||||
builtin_available_predicate avail);
|
||||
|
||||
ir_function_signature *_helper_invocation_intrinsic();
|
||||
ir_function_signature *_helper_invocation();
|
||||
|
||||
#undef B0
|
||||
#undef B1
|
||||
#undef B2
|
||||
@@ -1491,6 +1501,8 @@ builtin_builder::create_intrinsics()
|
||||
_read_first_invocation_intrinsic(glsl_type::uvec4_type),
|
||||
NULL);
|
||||
|
||||
add_function("__intrinsic_helper_invocation",
|
||||
_helper_invocation_intrinsic(), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4230,6 +4242,8 @@ builtin_builder::create_builtins()
|
||||
_vote("__intrinsic_vote_eq", v460_desktop),
|
||||
NULL);
|
||||
|
||||
add_function("helperInvocationEXT", _helper_invocation(), NULL);
|
||||
|
||||
add_function("__builtin_idiv64",
|
||||
generate_ir::idiv64(mem_ctx, integer_functions_supported),
|
||||
NULL);
|
||||
@@ -7274,6 +7288,28 @@ builtin_builder::_vote(const char *intrinsic_name,
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_helper_invocation_intrinsic()
|
||||
{
|
||||
MAKE_INTRINSIC(glsl_type::bool_type, ir_intrinsic_helper_invocation,
|
||||
demote_to_helper_invocation, 0);
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_helper_invocation()
|
||||
{
|
||||
MAKE_SIG(glsl_type::bool_type, demote_to_helper_invocation, 0);
|
||||
|
||||
ir_variable *retval = body.make_temp(glsl_type::bool_type, "retval");
|
||||
|
||||
body.emit(call(shader->symbols->get_function("__intrinsic_helper_invocation"),
|
||||
retval, sig->parameters));
|
||||
body.emit(ret(retval));
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/******************************************************************************/
|
||||
|
@@ -1166,6 +1166,9 @@ nir_visitor::visit(ir_call *ir)
|
||||
case ir_intrinsic_read_first_invocation:
|
||||
op = nir_intrinsic_read_first_invocation;
|
||||
break;
|
||||
case ir_intrinsic_helper_invocation:
|
||||
op = nir_intrinsic_is_helper_invocation;
|
||||
break;
|
||||
default:
|
||||
unreachable("not reached");
|
||||
}
|
||||
@@ -1641,6 +1644,12 @@ nir_visitor::visit(ir_call *ir)
|
||||
nir_builder_instr_insert(&b, &instr->instr);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_is_helper_invocation: {
|
||||
nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 1, NULL);
|
||||
instr->num_components = 1;
|
||||
nir_builder_instr_insert(&b, &instr->instr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
unreachable("not reached");
|
||||
}
|
||||
|
@@ -1138,6 +1138,8 @@ enum ir_intrinsic_id {
|
||||
ir_intrinsic_read_invocation,
|
||||
ir_intrinsic_read_first_invocation,
|
||||
|
||||
ir_intrinsic_helper_invocation,
|
||||
|
||||
ir_intrinsic_shared_load,
|
||||
ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),
|
||||
ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared),
|
||||
|
@@ -4120,6 +4120,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
|
||||
case ir_intrinsic_generic_atomic_comp_swap:
|
||||
case ir_intrinsic_begin_invocation_interlock:
|
||||
case ir_intrinsic_end_invocation_interlock:
|
||||
case ir_intrinsic_helper_invocation:
|
||||
unreachable("Invalid intrinsic");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user