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;
|
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,
|
ir_function_signature *_vote(const char *intrinsic_name,
|
||||||
builtin_available_predicate avail);
|
builtin_available_predicate avail);
|
||||||
|
|
||||||
|
ir_function_signature *_helper_invocation_intrinsic();
|
||||||
|
ir_function_signature *_helper_invocation();
|
||||||
|
|
||||||
#undef B0
|
#undef B0
|
||||||
#undef B1
|
#undef B1
|
||||||
#undef B2
|
#undef B2
|
||||||
@@ -1491,6 +1501,8 @@ builtin_builder::create_intrinsics()
|
|||||||
_read_first_invocation_intrinsic(glsl_type::uvec4_type),
|
_read_first_invocation_intrinsic(glsl_type::uvec4_type),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
add_function("__intrinsic_helper_invocation",
|
||||||
|
_helper_invocation_intrinsic(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4230,6 +4242,8 @@ builtin_builder::create_builtins()
|
|||||||
_vote("__intrinsic_vote_eq", v460_desktop),
|
_vote("__intrinsic_vote_eq", v460_desktop),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
add_function("helperInvocationEXT", _helper_invocation(), NULL);
|
||||||
|
|
||||||
add_function("__builtin_idiv64",
|
add_function("__builtin_idiv64",
|
||||||
generate_ir::idiv64(mem_ctx, integer_functions_supported),
|
generate_ir::idiv64(mem_ctx, integer_functions_supported),
|
||||||
NULL);
|
NULL);
|
||||||
@@ -7274,6 +7288,28 @@ builtin_builder::_vote(const char *intrinsic_name,
|
|||||||
return sig;
|
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:
|
case ir_intrinsic_read_first_invocation:
|
||||||
op = nir_intrinsic_read_first_invocation;
|
op = nir_intrinsic_read_first_invocation;
|
||||||
break;
|
break;
|
||||||
|
case ir_intrinsic_helper_invocation:
|
||||||
|
op = nir_intrinsic_is_helper_invocation;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
unreachable("not reached");
|
unreachable("not reached");
|
||||||
}
|
}
|
||||||
@@ -1641,6 +1644,12 @@ nir_visitor::visit(ir_call *ir)
|
|||||||
nir_builder_instr_insert(&b, &instr->instr);
|
nir_builder_instr_insert(&b, &instr->instr);
|
||||||
break;
|
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:
|
default:
|
||||||
unreachable("not reached");
|
unreachable("not reached");
|
||||||
}
|
}
|
||||||
|
@@ -1138,6 +1138,8 @@ enum ir_intrinsic_id {
|
|||||||
ir_intrinsic_read_invocation,
|
ir_intrinsic_read_invocation,
|
||||||
ir_intrinsic_read_first_invocation,
|
ir_intrinsic_read_first_invocation,
|
||||||
|
|
||||||
|
ir_intrinsic_helper_invocation,
|
||||||
|
|
||||||
ir_intrinsic_shared_load,
|
ir_intrinsic_shared_load,
|
||||||
ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),
|
ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),
|
||||||
ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, 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_generic_atomic_comp_swap:
|
||||||
case ir_intrinsic_begin_invocation_interlock:
|
case ir_intrinsic_begin_invocation_interlock:
|
||||||
case ir_intrinsic_end_invocation_interlock:
|
case ir_intrinsic_end_invocation_interlock:
|
||||||
|
case ir_intrinsic_helper_invocation:
|
||||||
unreachable("Invalid intrinsic");
|
unreachable("Invalid intrinsic");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user