mesa: Add GL/GLSL plumbing for INTEL_fragment_shader_ordering
[mesa.git] / src / compiler / glsl / builtin_functions.cpp
index 84833bdd7d5d637043a205df6f23659111574056..5650365d1d549ccfd5085d8515be47456f107dde 100644 (file)
@@ -75,7 +75,7 @@
 
 #include <stdarg.h>
 #include <stdio.h>
-#include "main/core.h" /* for struct gl_shader */
+#include "main/mtypes.h"
 #include "main/shaderobj.h"
 #include "ir_builder.h"
 #include "glsl_parser_extras.h"
@@ -104,7 +104,7 @@ static bool
 compatibility_vs_only(const _mesa_glsl_parse_state *state)
 {
    return state->stage == MESA_SHADER_VERTEX &&
-          state->language_version <= 130 &&
+          (state->compat_shader || state->ARB_compatibility_enable) &&
           !state->es_shader;
 }
 
@@ -150,6 +150,12 @@ v130_desktop(const _mesa_glsl_parse_state *state)
    return state->is_version(130, 0);
 }
 
+static bool
+v460_desktop(const _mesa_glsl_parse_state *state)
+{
+   return state->is_version(460, 0);
+}
+
 static bool
 v130_fs_only(const _mesa_glsl_parse_state *state)
 {
@@ -182,6 +188,14 @@ texture_external(const _mesa_glsl_parse_state *state)
    return state->OES_EGL_image_external_enable;
 }
 
+static bool
+texture_external_es3(const _mesa_glsl_parse_state *state)
+{
+   return state->OES_EGL_image_external_essl3_enable &&
+      state->es_shader &&
+      state->is_version(0, 300);
+}
+
 /** True if texturing functions with explicit LOD are allowed. */
 static bool
 lod_exists_in_stage(const _mesa_glsl_parse_state *state)
@@ -432,7 +446,8 @@ fs_oes_derivatives(const _mesa_glsl_parse_state *state)
 {
    return state->stage == MESA_SHADER_FRAGMENT &&
           (state->is_version(110, 300) ||
-           state->OES_standard_derivatives_enable);
+           state->OES_standard_derivatives_enable ||
+           state->ctx->Const.AllowGLSLRelaxedES);
 }
 
 static bool
@@ -486,12 +501,36 @@ shader_atomic_counter_ops(const _mesa_glsl_parse_state *state)
    return state->ARB_shader_atomic_counter_ops_enable;
 }
 
+static bool
+shader_atomic_counter_ops_or_v460_desktop(const _mesa_glsl_parse_state *state)
+{
+   return state->ARB_shader_atomic_counter_ops_enable || v460_desktop(state);
+}
+
 static bool
 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
+supports_nv_fragment_shader_interlock(const _mesa_glsl_parse_state *state)
+{
+   return state->NV_fragment_shader_interlock_enable;
+}
+
+static bool
+supports_intel_fragment_shader_ordering(const _mesa_glsl_parse_state *state)
+{
+   return state->INTEL_fragment_shader_ordering_enable;
+}
+
 static bool
 shader_clock(const _mesa_glsl_parse_state *state)
 {
@@ -502,7 +541,8 @@ static bool
 shader_clock_int64(const _mesa_glsl_parse_state *state)
 {
    return state->ARB_shader_clock_enable &&
-          state->ARB_gpu_shader_int64_enable;
+          (state->ARB_gpu_shader_int64_enable ||
+           state->AMD_gpu_shader_int64_enable);
 }
 
 static bool
@@ -537,7 +577,14 @@ shader_image_atomic_exchange_float(const _mesa_glsl_parse_state *state)
 {
    return (state->is_version(450, 320) ||
            state->ARB_ES3_1_compatibility_enable ||
-           state->OES_shader_image_atomic_enable);
+           state->OES_shader_image_atomic_enable ||
+           state->NV_shader_atomic_float_enable);
+}
+
+static bool
+shader_image_atomic_add_float(const _mesa_glsl_parse_state *state)
+{
+   return state->NV_shader_atomic_float_enable;
 }
 
 static bool
@@ -609,11 +656,48 @@ vote(const _mesa_glsl_parse_state *state)
    return state->ARB_shader_group_vote_enable;
 }
 
+static bool
+vote_or_v460_desktop(const _mesa_glsl_parse_state *state)
+{
+   return state->ARB_shader_group_vote_enable || v460_desktop(state);
+}
+
 static bool
 integer_functions_supported(const _mesa_glsl_parse_state *state)
 {
    return state->extensions->MESA_shader_integer_functions;
 }
+
+static bool
+NV_shader_atomic_float_supported(const _mesa_glsl_parse_state *state)
+{
+   return state->extensions->NV_shader_atomic_float;
+}
+
+static bool
+shader_atomic_float_add(const _mesa_glsl_parse_state *state)
+{
+   return state->NV_shader_atomic_float_enable;
+}
+
+static bool
+shader_atomic_float_exchange(const _mesa_glsl_parse_state *state)
+{
+   return state->NV_shader_atomic_float_enable ||
+          state->INTEL_shader_atomic_float_minmax_enable;
+}
+
+static bool
+INTEL_shader_atomic_float_minmax_supported(const _mesa_glsl_parse_state *state)
+{
+   return state->extensions->INTEL_shader_atomic_float_minmax;
+}
+
+static bool
+shader_atomic_float_minmax(const _mesa_glsl_parse_state *state)
+{
+   return state->INTEL_shader_atomic_float_minmax_enable;
+}
 /** @} */
 
 /******************************************************************************/
@@ -726,7 +810,8 @@ private:
                                 ir_expression_operation opcode,
                                 const glsl_type *return_type,
                                 const glsl_type *param0_type,
-                                const glsl_type *param1_type);
+                                const glsl_type *param1_type,
+                                bool swap_operands = false);
 
 #define B0(X) ir_function_signature *_##X();
 #define B1(X) ir_function_signature *_##X(const glsl_type *);
@@ -955,6 +1040,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,
@@ -962,7 +1055,8 @@ private:
 
    ir_function_signature *_vote_intrinsic(builtin_available_predicate avail,
                                           enum ir_intrinsic_id id);
-   ir_function_signature *_vote(const char *intrinsic_name);
+   ir_function_signature *_vote(const char *intrinsic_name,
+                                builtin_available_predicate avail);
 
 #undef B0
 #undef B1
@@ -982,7 +1076,8 @@ enum image_function_flags {
    IMAGE_FUNCTION_WRITE_ONLY = (1 << 5),
    IMAGE_FUNCTION_AVAIL_ATOMIC = (1 << 6),
    IMAGE_FUNCTION_MS_ONLY = (1 << 7),
-   IMAGE_FUNCTION_AVAIL_ATOMIC_EXCHANGE = (1 << 8)
+   IMAGE_FUNCTION_AVAIL_ATOMIC_EXCHANGE = (1 << 8),
+   IMAGE_FUNCTION_AVAIL_ATOMIC_ADD = (1 << 9),
 };
 
 } /* anonymous namespace */
@@ -1090,7 +1185,10 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_add),
-                _atomic_counter_intrinsic1(shader_atomic_counter_ops,
+                _atomic_intrinsic2(NV_shader_atomic_float_supported,
+                                   glsl_type::float_type,
+                                   ir_intrinsic_generic_atomic_add),
+                _atomic_counter_intrinsic1(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_add),
                 NULL);
    add_function("__intrinsic_atomic_min",
@@ -1100,7 +1198,10 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_min),
-                _atomic_counter_intrinsic1(shader_atomic_counter_ops,
+                _atomic_intrinsic2(INTEL_shader_atomic_float_minmax_supported,
+                                   glsl_type::float_type,
+                                   ir_intrinsic_generic_atomic_min),
+                _atomic_counter_intrinsic1(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_min),
                 NULL);
    add_function("__intrinsic_atomic_max",
@@ -1110,7 +1211,10 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_max),
-                _atomic_counter_intrinsic1(shader_atomic_counter_ops,
+                _atomic_intrinsic2(INTEL_shader_atomic_float_minmax_supported,
+                                   glsl_type::float_type,
+                                   ir_intrinsic_generic_atomic_max),
+                _atomic_counter_intrinsic1(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_max),
                 NULL);
    add_function("__intrinsic_atomic_and",
@@ -1120,7 +1224,7 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_and),
-                _atomic_counter_intrinsic1(shader_atomic_counter_ops,
+                _atomic_counter_intrinsic1(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_and),
                 NULL);
    add_function("__intrinsic_atomic_or",
@@ -1130,7 +1234,7 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_or),
-                _atomic_counter_intrinsic1(shader_atomic_counter_ops,
+                _atomic_counter_intrinsic1(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_or),
                 NULL);
    add_function("__intrinsic_atomic_xor",
@@ -1140,7 +1244,7 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_xor),
-                _atomic_counter_intrinsic1(shader_atomic_counter_ops,
+                _atomic_counter_intrinsic1(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_xor),
                 NULL);
    add_function("__intrinsic_atomic_exchange",
@@ -1150,7 +1254,10 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_exchange),
-                _atomic_counter_intrinsic1(shader_atomic_counter_ops,
+                _atomic_intrinsic2(NV_shader_atomic_float_supported,
+                                   glsl_type::float_type,
+                                   ir_intrinsic_generic_atomic_exchange),
+                _atomic_counter_intrinsic1(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_exchange),
                 NULL);
    add_function("__intrinsic_atomic_comp_swap",
@@ -1160,7 +1267,10 @@ builtin_builder::create_intrinsics()
                 _atomic_intrinsic3(buffer_atomics_supported,
                                    glsl_type::int_type,
                                    ir_intrinsic_generic_atomic_comp_swap),
-                _atomic_counter_intrinsic2(shader_atomic_counter_ops,
+                _atomic_intrinsic3(INTEL_shader_atomic_float_minmax_supported,
+                                   glsl_type::float_type,
+                                   ir_intrinsic_generic_atomic_comp_swap),
+                _atomic_counter_intrinsic2(shader_atomic_counter_ops_or_v460_desktop,
                                            ir_intrinsic_atomic_counter_comp_swap),
                 NULL);
 
@@ -1191,19 +1301,34 @@ 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_begin_fragment_shader_ordering",
+                _invocation_interlock_intrinsic(
+                   supports_intel_fragment_shader_ordering,
+                   ir_intrinsic_begin_fragment_shader_ordering), NULL);
+
    add_function("__intrinsic_shader_clock",
                 _shader_clock_intrinsic(shader_clock,
                                         glsl_type::uvec2_type),
                 NULL);
 
    add_function("__intrinsic_vote_all",
-                _vote_intrinsic(vote, ir_intrinsic_vote_all),
+                _vote_intrinsic(vote_or_v460_desktop, ir_intrinsic_vote_all),
                 NULL);
    add_function("__intrinsic_vote_any",
-                _vote_intrinsic(vote, ir_intrinsic_vote_any),
+                _vote_intrinsic(vote_or_v460_desktop, ir_intrinsic_vote_any),
                 NULL);
    add_function("__intrinsic_vote_eq",
-                _vote_intrinsic(vote, ir_intrinsic_vote_eq),
+                _vote_intrinsic(vote_or_v460_desktop, ir_intrinsic_vote_eq),
                 NULL);
 
    add_function("__intrinsic_ballot", _ballot_intrinsic(), NULL);
@@ -1899,6 +2024,8 @@ builtin_builder::create_builtins()
 
                 _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec3_type),
 
+                _texture(ir_tex, texture_external_es3, glsl_type::vec4_type,  glsl_type::samplerExternalOES_type, glsl_type::vec2_type),
+
                 _texture(ir_txb, v130_fs_only, glsl_type::vec4_type,  glsl_type::sampler1D_type,  glsl_type::float_type),
                 _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type),
                 _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type),
@@ -2058,6 +2185,9 @@ builtin_builder::create_builtins()
 
                 _texture(ir_tex, v130, glsl_type::vec4_type,  glsl_type::sampler2DRect_type,  glsl_type::vec3_type, TEX_PROJECT),
                 _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+                _texture(ir_tex, texture_external_es3, glsl_type::vec4_type,  glsl_type::samplerExternalOES_type, glsl_type::vec3_type, TEX_PROJECT),
+                _texture(ir_tex, texture_external_es3, glsl_type::vec4_type,  glsl_type::samplerExternalOES_type, glsl_type::vec4_type, TEX_PROJECT),
+
                 _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
                 _texture(ir_tex, v130, glsl_type::vec4_type,  glsl_type::sampler2DRect_type,  glsl_type::vec4_type, TEX_PROJECT),
                 _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
@@ -2123,8 +2253,12 @@ builtin_builder::create_builtins()
                 _texelFetch(texture_multisample_array, glsl_type::vec4_type,  glsl_type::sampler2DMSArray_type,  glsl_type::ivec3_type),
                 _texelFetch(texture_multisample_array, glsl_type::ivec4_type, glsl_type::isampler2DMSArray_type, glsl_type::ivec3_type),
                 _texelFetch(texture_multisample_array, glsl_type::uvec4_type, glsl_type::usampler2DMSArray_type, glsl_type::ivec3_type),
+
+                _texelFetch(texture_external_es3, glsl_type::vec4_type,  glsl_type::samplerExternalOES_type, glsl_type::ivec2_type),
+
                 NULL);
 
+
    add_function("texelFetchOffset",
                 _texelFetch(v130, glsl_type::vec4_type,  glsl_type::sampler1D_type,  glsl_type::int_type, glsl_type::int_type),
                 _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::int_type, glsl_type::int_type),
@@ -3031,6 +3165,43 @@ builtin_builder::create_builtins()
                                     shader_atomic_counter_ops),
                 NULL);
 
+   add_function("atomicCounterAdd",
+                _atomic_counter_op1("__intrinsic_atomic_add",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterSubtract",
+                _atomic_counter_op1("__intrinsic_atomic_sub",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterMin",
+                _atomic_counter_op1("__intrinsic_atomic_min",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterMax",
+                _atomic_counter_op1("__intrinsic_atomic_max",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterAnd",
+                _atomic_counter_op1("__intrinsic_atomic_and",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterOr",
+                _atomic_counter_op1("__intrinsic_atomic_or",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterXor",
+                _atomic_counter_op1("__intrinsic_atomic_xor",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterExchange",
+                _atomic_counter_op1("__intrinsic_atomic_exchange",
+                                    v460_desktop),
+                NULL);
+   add_function("atomicCounterCompSwap",
+                _atomic_counter_op2("__intrinsic_atomic_comp_swap",
+                                    v460_desktop),
+                NULL);
+
    add_function("atomicAdd",
                 _atomic_op2("__intrinsic_atomic_add",
                             buffer_atomics_supported,
@@ -3038,6 +3209,9 @@ builtin_builder::create_builtins()
                 _atomic_op2("__intrinsic_atomic_add",
                             buffer_atomics_supported,
                             glsl_type::int_type),
+                _atomic_op2("__intrinsic_atomic_add",
+                            shader_atomic_float_add,
+                            glsl_type::float_type),
                 NULL);
    add_function("atomicMin",
                 _atomic_op2("__intrinsic_atomic_min",
@@ -3046,6 +3220,9 @@ builtin_builder::create_builtins()
                 _atomic_op2("__intrinsic_atomic_min",
                             buffer_atomics_supported,
                             glsl_type::int_type),
+                _atomic_op2("__intrinsic_atomic_min",
+                            shader_atomic_float_minmax,
+                            glsl_type::float_type),
                 NULL);
    add_function("atomicMax",
                 _atomic_op2("__intrinsic_atomic_max",
@@ -3054,6 +3231,9 @@ builtin_builder::create_builtins()
                 _atomic_op2("__intrinsic_atomic_max",
                             buffer_atomics_supported,
                             glsl_type::int_type),
+                _atomic_op2("__intrinsic_atomic_max",
+                            shader_atomic_float_minmax,
+                            glsl_type::float_type),
                 NULL);
    add_function("atomicAnd",
                 _atomic_op2("__intrinsic_atomic_and",
@@ -3086,6 +3266,9 @@ builtin_builder::create_builtins()
                 _atomic_op2("__intrinsic_atomic_exchange",
                             buffer_atomics_supported,
                             glsl_type::int_type),
+                _atomic_op2("__intrinsic_atomic_exchange",
+                            shader_atomic_float_exchange,
+                            glsl_type::float_type),
                 NULL);
    add_function("atomicCompSwap",
                 _atomic_op3("__intrinsic_atomic_comp_swap",
@@ -3094,6 +3277,9 @@ builtin_builder::create_builtins()
                 _atomic_op3("__intrinsic_atomic_comp_swap",
                             buffer_atomics_supported,
                             glsl_type::int_type),
+                _atomic_op3("__intrinsic_atomic_comp_swap",
+                            shader_atomic_float_minmax,
+                            glsl_type::float_type),
                 NULL);
 
    add_function("min3",
@@ -3220,9 +3406,59 @@ builtin_builder::create_builtins()
                               glsl_type::uint64_t_type),
                 NULL);
 
-   add_function("anyInvocationARB", _vote("__intrinsic_vote_any"), NULL);
-   add_function("allInvocationsARB", _vote("__intrinsic_vote_all"), NULL);
-   add_function("allInvocationsEqualARB", _vote("__intrinsic_vote_eq"), 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("beginInvocationInterlockNV",
+                _invocation_interlock(
+                   "__intrinsic_begin_invocation_interlock",
+                   supports_nv_fragment_shader_interlock),
+                NULL);
+
+   add_function("endInvocationInterlockNV",
+                _invocation_interlock(
+                   "__intrinsic_end_invocation_interlock",
+                   supports_nv_fragment_shader_interlock),
+                NULL);
+
+   add_function("beginFragmentShaderOrderingINTEL",
+                _invocation_interlock(
+                   "__intrinsic_begin_fragment_shader_ordering",
+                   supports_intel_fragment_shader_ordering),
+                NULL);
+
+   add_function("anyInvocationARB",
+                _vote("__intrinsic_vote_any", vote),
+                NULL);
+
+   add_function("allInvocationsARB",
+                _vote("__intrinsic_vote_all", vote),
+                NULL);
+
+   add_function("allInvocationsEqualARB",
+                _vote("__intrinsic_vote_eq", vote),
+                NULL);
+
+   add_function("anyInvocation",
+                _vote("__intrinsic_vote_any", v460_desktop),
+                NULL);
+
+   add_function("allInvocations",
+                _vote("__intrinsic_vote_all", v460_desktop),
+                NULL);
+
+   add_function("allInvocationsEqual",
+                _vote("__intrinsic_vote_eq", v460_desktop),
+                NULL);
 
    add_function("__builtin_idiv64",
                 generate_ir::idiv64(mem_ctx, integer_functions_supported),
@@ -3365,7 +3601,9 @@ builtin_builder::add_image_functions(bool glsl)
 
    add_image_function(glsl ? "imageAtomicAdd" : "__intrinsic_image_atomic_add",
                       "__intrinsic_image_atomic_add",
-                      &builtin_builder::_image_prototype, 1, atom_flags,
+                      &builtin_builder::_image_prototype, 1,
+                      (flags | IMAGE_FUNCTION_AVAIL_ATOMIC_ADD |
+                       IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE),
                       ir_intrinsic_image_atomic_add);
 
    add_image_function(glsl ? "imageAtomicMin" : "__intrinsic_image_atomic_min",
@@ -3558,12 +3796,18 @@ builtin_builder::binop(builtin_available_predicate avail,
                        ir_expression_operation opcode,
                        const glsl_type *return_type,
                        const glsl_type *param0_type,
-                       const glsl_type *param1_type)
+                       const glsl_type *param1_type,
+                       bool swap_operands)
 {
    ir_variable *x = in_var(param0_type, "x");
    ir_variable *y = in_var(param1_type, "y");
    MAKE_SIG(return_type, avail, 2, x, y);
-   body.emit(ret(expr(opcode, x, y)));
+
+   if (swap_operands)
+      body.emit(ret(expr(opcode, y, x)));
+   else
+      body.emit(ret(expr(opcode, x, y)));
+
    return sig;
 }
 
@@ -4896,16 +5140,18 @@ ir_function_signature *
 builtin_builder::_lessThanEqual(builtin_available_predicate avail,
                                 const glsl_type *type)
 {
-   return binop(avail, ir_binop_lequal,
-                glsl_type::bvec(type->vector_elements), type, type);
+   return binop(avail, ir_binop_gequal,
+                glsl_type::bvec(type->vector_elements), type, type,
+                true);
 }
 
 ir_function_signature *
 builtin_builder::_greaterThan(builtin_available_predicate avail,
                               const glsl_type *type)
 {
-   return binop(avail, ir_binop_greater,
-                glsl_type::bvec(type->vector_elements), type, type);
+   return binop(avail, ir_binop_less,
+                glsl_type::bvec(type->vector_elements), type, type,
+                true);
 }
 
 ir_function_signature *
@@ -5882,7 +6128,12 @@ get_image_available_predicate(const glsl_type *type, unsigned flags)
        type->sampled_type == GLSL_TYPE_FLOAT)
       return shader_image_atomic_exchange_float;
 
+   if ((flags & IMAGE_FUNCTION_AVAIL_ATOMIC_ADD) &&
+       type->sampled_type == GLSL_TYPE_FLOAT)
+      return shader_image_atomic_add_float;
+
    else if (flags & (IMAGE_FUNCTION_AVAIL_ATOMIC_EXCHANGE |
+                     IMAGE_FUNCTION_AVAIL_ATOMIC_ADD |
                      IMAGE_FUNCTION_AVAIL_ATOMIC))
       return shader_image_atomic;
 
@@ -6125,6 +6376,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)
@@ -6163,11 +6432,12 @@ builtin_builder::_vote_intrinsic(builtin_available_predicate avail,
 }
 
 ir_function_signature *
-builtin_builder::_vote(const char *intrinsic_name)
+builtin_builder::_vote(const char *intrinsic_name,
+                       builtin_available_predicate avail)
 {
    ir_variable *value = in_var(glsl_type::bool_type, "value");
 
-   MAKE_SIG(glsl_type::bool_type, vote, 1, value);
+   MAKE_SIG(glsl_type::bool_type, avail, 1, value);
 
    ir_variable *retval = body.make_temp(glsl_type::bool_type, "retval");
 
@@ -6214,16 +6484,7 @@ _mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
    s = builtins.find(state, name, actual_parameters);
    mtx_unlock(&builtins_lock);
 
-   if (s == NULL)
-      return NULL;
-
-   struct hash_table *ht =
-      _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
-   void *mem_ctx = state;
-   ir_function *f = s->function()->clone(mem_ctx, ht);
-   _mesa_hash_table_destroy(ht, NULL);
-
-   return f->matching_signature(state, actual_parameters, true);
+   return s;
 }
 
 bool