mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
This extension provides new GLSL built-in functions beginInvocationInterlockARB() and endInvocationInterlockARB() that delimit a critical section of fragment shader code. For pairs of shader invocations with "overlapping" coverage in a given pixel, the OpenGL implementation will guarantee that the critical section of the fragment shader will be executed for only one fragment at a time. Signed-off-by: Plamena Manolova <plamena.manolova@intel.com> Reviewed-by: Francisco Jerez <currojerez@riseup.net>
This commit is contained in:
@@ -512,6 +512,12 @@ shader_ballot(const _mesa_glsl_parse_state *state)
|
||||
return state->ARB_shader_ballot_enable;
|
||||
}
|
||||
|
||||
static bool
|
||||
supports_arb_fragment_shader_interlock(const _mesa_glsl_parse_state *state)
|
||||
{
|
||||
return state->ARB_fragment_shader_interlock_enable;
|
||||
}
|
||||
|
||||
static bool
|
||||
shader_clock(const _mesa_glsl_parse_state *state)
|
||||
{
|
||||
@@ -982,6 +988,14 @@ private:
|
||||
ir_function_signature *_read_invocation_intrinsic(const glsl_type *type);
|
||||
ir_function_signature *_read_invocation(const glsl_type *type);
|
||||
|
||||
|
||||
ir_function_signature *_invocation_interlock_intrinsic(
|
||||
builtin_available_predicate avail,
|
||||
enum ir_intrinsic_id id);
|
||||
ir_function_signature *_invocation_interlock(
|
||||
const char *intrinsic_name,
|
||||
builtin_available_predicate avail);
|
||||
|
||||
ir_function_signature *_shader_clock_intrinsic(builtin_available_predicate avail,
|
||||
const glsl_type *type);
|
||||
ir_function_signature *_shader_clock(builtin_available_predicate avail,
|
||||
@@ -1219,6 +1233,16 @@ builtin_builder::create_intrinsics()
|
||||
ir_intrinsic_memory_barrier_shared),
|
||||
NULL);
|
||||
|
||||
add_function("__intrinsic_begin_invocation_interlock",
|
||||
_invocation_interlock_intrinsic(
|
||||
supports_arb_fragment_shader_interlock,
|
||||
ir_intrinsic_begin_invocation_interlock), NULL);
|
||||
|
||||
add_function("__intrinsic_end_invocation_interlock",
|
||||
_invocation_interlock_intrinsic(
|
||||
supports_arb_fragment_shader_interlock,
|
||||
ir_intrinsic_end_invocation_interlock), NULL);
|
||||
|
||||
add_function("__intrinsic_shader_clock",
|
||||
_shader_clock_intrinsic(shader_clock,
|
||||
glsl_type::uvec2_type),
|
||||
@@ -3294,6 +3318,18 @@ builtin_builder::create_builtins()
|
||||
glsl_type::uint64_t_type),
|
||||
NULL);
|
||||
|
||||
add_function("beginInvocationInterlockARB",
|
||||
_invocation_interlock(
|
||||
"__intrinsic_begin_invocation_interlock",
|
||||
supports_arb_fragment_shader_interlock),
|
||||
NULL);
|
||||
|
||||
add_function("endInvocationInterlockARB",
|
||||
_invocation_interlock(
|
||||
"__intrinsic_end_invocation_interlock",
|
||||
supports_arb_fragment_shader_interlock),
|
||||
NULL);
|
||||
|
||||
add_function("anyInvocationARB",
|
||||
_vote("__intrinsic_vote_any", vote),
|
||||
NULL);
|
||||
@@ -6227,6 +6263,24 @@ builtin_builder::_read_invocation(const glsl_type *type)
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_invocation_interlock_intrinsic(builtin_available_predicate avail,
|
||||
enum ir_intrinsic_id id)
|
||||
{
|
||||
MAKE_INTRINSIC(glsl_type::void_type, id, avail, 0);
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_invocation_interlock(const char *intrinsic_name,
|
||||
builtin_available_predicate avail)
|
||||
{
|
||||
MAKE_SIG(glsl_type::void_type, avail, 0);
|
||||
body.emit(call(shader->symbols->get_function(intrinsic_name),
|
||||
NULL, sig->parameters));
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_shader_clock_intrinsic(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
|
||||
Reference in New Issue
Block a user