glsl: Add built-in functions and constants required for ARB_shader_atomic_counters.
authorFrancisco Jerez <currojerez@riseup.net>
Sun, 20 Oct 2013 19:39:16 +0000 (12:39 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 29 Oct 2013 19:40:55 +0000 (12:40 -0700)
v2: Represent atomics as GLSL intrinsics.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/builtin_functions.cpp
src/glsl/builtin_variables.cpp
src/glsl/glcpp/glcpp-parse.y
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_parser_extras.h

index f122259e67dbc0b1f460c660f70190de4d6a678e..3fa0cb5ad4c17fe49e1c37c5df05979478d0488a 100644 (file)
@@ -326,6 +326,13 @@ tex3d_lod(const _mesa_glsl_parse_state *state)
 {
    return tex3d(state) && lod_exists_in_stage(state);
 }
+
+static bool
+shader_atomic_counters(const _mesa_glsl_parse_state *state)
+{
+   return state->ARB_shader_atomic_counters_enable;
+}
+
 /** @} */
 
 /******************************************************************************/
@@ -556,6 +563,11 @@ private:
    B1(uaddCarry)
    B1(usubBorrow)
    B1(mulExtended)
+
+   ir_function_signature *_atomic_intrinsic(builtin_available_predicate avail);
+   ir_function_signature *_atomic_op(const char *intrinsic,
+                                     builtin_available_predicate avail);
+
 #undef B0
 #undef B1
 #undef B2
@@ -662,6 +674,15 @@ builtin_builder::create_shader()
 void
 builtin_builder::create_intrinsics()
 {
+   add_function("__intrinsic_atomic_read",
+                _atomic_intrinsic(shader_atomic_counters),
+                NULL);
+   add_function("__intrinsic_atomic_increment",
+                _atomic_intrinsic(shader_atomic_counters),
+                NULL);
+   add_function("__intrinsic_atomic_predecrement",
+                _atomic_intrinsic(shader_atomic_counters),
+                NULL);
 }
 
 /**
@@ -2070,6 +2091,20 @@ builtin_builder::create_builtins()
                 _mulExtended(glsl_type::uvec3_type),
                 _mulExtended(glsl_type::uvec4_type),
                 NULL);
+
+   add_function("atomicCounter",
+                _atomic_op("__intrinsic_atomic_read",
+                           shader_atomic_counters),
+                NULL);
+   add_function("atomicCounterIncrement",
+                _atomic_op("__intrinsic_atomic_increment",
+                           shader_atomic_counters),
+                NULL);
+   add_function("atomicCounterDecrement",
+                _atomic_op("__intrinsic_atomic_predecrement",
+                           shader_atomic_counters),
+                NULL);
+
 #undef F
 #undef FI
 #undef FIU
@@ -3932,6 +3967,29 @@ builtin_builder::_mulExtended(const glsl_type *type)
 
    return sig;
 }
+
+ir_function_signature *
+builtin_builder::_atomic_intrinsic(builtin_available_predicate avail)
+{
+   ir_variable *counter = in_var(glsl_type::atomic_uint_type, "counter");
+   MAKE_INTRINSIC(glsl_type::uint_type, avail, 1, counter);
+   return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atomic_op(const char *intrinsic,
+                            builtin_available_predicate avail)
+{
+   ir_variable *counter = in_var(glsl_type::atomic_uint_type, "atomic_counter");
+   MAKE_SIG(glsl_type::uint_type, avail, 1, counter);
+
+   ir_variable *retval = body.make_temp(glsl_type::uint_type, "atomic_retval");
+   body.emit(call(shader->symbols->get_function(intrinsic), retval,
+                  sig->parameters));
+   body.emit(ret(retval));
+   return sig;
+}
+
 /** @} */
 
 /******************************************************************************/
index 018daf67fec16da5949df71b6b2058ba2ab25431..7a3505ace12c028645a098f100f3a9486fe1414d 100644 (file)
@@ -638,6 +638,21 @@ builtin_variable_generator::generate_constants()
        */
       add_const("gl_MaxTextureCoords", state->Const.MaxTextureCoords);
    }
+
+   if (state->ARB_shader_atomic_counters_enable) {
+      add_const("gl_MaxVertexAtomicCounters",
+                state->Const.MaxVertexAtomicCounters);
+      add_const("gl_MaxGeometryAtomicCounters",
+                state->Const.MaxGeometryAtomicCounters);
+      add_const("gl_MaxFragmentAtomicCounters",
+                state->Const.MaxFragmentAtomicCounters);
+      add_const("gl_MaxCombinedAtomicCounters",
+                state->Const.MaxCombinedAtomicCounters);
+      add_const("gl_MaxAtomicCounterBindings",
+                state->Const.MaxAtomicBufferBindings);
+      add_const("gl_MaxTessControlAtomicCounters", 0);
+      add_const("gl_MaxTessEvaluationAtomicCounters", 0);
+   }
 }
 
 
index 02100ab0cd19ddd062dfaae7b3efa030836e1c13..86f3cd5aa47d0c884c20210cda83437f428babc9 100644 (file)
@@ -1254,6 +1254,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
 
              if (extensions->ARB_texture_gather)
                 add_builtin_define(parser, "GL_ARB_texture_gather", 1);
+
+             if (extensions->ARB_shader_atomic_counters)
+                add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1);
           }
        }
 
index 6a69e22255722bb1dd9f3e547d95a1d23e1fd4d7..77e8816c489f454a8086a6e49d1d9a2079c2ebd4 100644 (file)
@@ -118,6 +118,12 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
    this->Const.MaxGeometryTotalOutputComponents = ctx->Const.MaxGeometryTotalOutputComponents;
    this->Const.MaxGeometryUniformComponents = ctx->Const.GeometryProgram.MaxUniformComponents;
 
+   this->Const.MaxVertexAtomicCounters = ctx->Const.VertexProgram.MaxAtomicCounters;
+   this->Const.MaxGeometryAtomicCounters = ctx->Const.GeometryProgram.MaxAtomicCounters;
+   this->Const.MaxFragmentAtomicCounters = ctx->Const.FragmentProgram.MaxAtomicCounters;
+   this->Const.MaxCombinedAtomicCounters = ctx->Const.MaxCombinedAtomicCounters;
+   this->Const.MaxAtomicBufferBindings = ctx->Const.MaxAtomicBufferBindings;
+
    this->current_function = NULL;
    this->toplevel_ir = NULL;
    this->found_return = false;
index 27a7a5c1d7f8900c482e172cff30ab52c25f4723..f3560c30a6aca1f27997d6ecf61d914234df33ee 100644 (file)
@@ -229,6 +229,13 @@ struct _mesa_glsl_parse_state {
       unsigned MaxGeometryOutputVertices;
       unsigned MaxGeometryTotalOutputComponents;
       unsigned MaxGeometryUniformComponents;
+
+      /* ARB_shader_atomic_counters */
+      unsigned MaxVertexAtomicCounters;
+      unsigned MaxGeometryAtomicCounters;
+      unsigned MaxFragmentAtomicCounters;
+      unsigned MaxCombinedAtomicCounters;
+      unsigned MaxAtomicBufferBindings;
    } Const;
 
    /**