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:
Plamena Manolova
2018-04-27 14:12:30 +01:00
parent 53719f818c
commit 60e843c4d5
14 changed files with 197 additions and 1 deletions
+54
View File
@@ -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)