[Mesa-dev] [PATCH 06/24] mesa: Add support for ARB_shader_atomic_counters.

Francisco Jerez currojerez at riseup.net
Sun Sep 15 00:10:32 PDT 2013


This patch implements the common support code required for the
ARB_shader_atomic_counters extension.  It defines the necessary data
structures for tracking atomic counter buffer objects (from now on
"ABOs") associated with some specific context or shader program, it
implements support for binding buffers to an ABO binding point and
querying the existing atomic counters and buffers declared by GLSL
shaders.
---
 src/glsl/ir_uniform.h            |  7 +++++
 src/glsl/link_uniforms.cpp       |  1 +
 src/mesa/main/bufferobj.c        | 58 +++++++++++++++++++++++++++++++++++++
 src/mesa/main/config.h           |  6 ++++
 src/mesa/main/context.c          |  9 ++++++
 src/mesa/main/extensions.c       |  1 +
 src/mesa/main/get.c              | 40 ++++++++++++++++++++++++++
 src/mesa/main/get_hash_params.py | 13 +++++++++
 src/mesa/main/mtypes.h           | 59 ++++++++++++++++++++++++++++++++++++++
 src/mesa/main/shaderapi.c        |  6 ++++
 src/mesa/main/uniform_query.cpp  |  4 +++
 src/mesa/main/uniforms.c         | 62 +++++++++++++++++++++++++++++++++++++++-
 12 files changed, 265 insertions(+), 1 deletion(-)

diff --git a/src/glsl/ir_uniform.h b/src/glsl/ir_uniform.h
index 8198c48..13faab7 100644
--- a/src/glsl/ir_uniform.h
+++ b/src/glsl/ir_uniform.h
@@ -166,6 +166,13 @@ struct gl_uniform_storage {
    bool row_major;
 
    /** @} */
+
+   /**
+    * Index within gl_shader_program::AtomicBuffers[] of the atomic
+    * counter buffer this uniform is stored in, or -1 if this is not
+    * an atomic counter.
+    */
+   int atomic_buffer_index;
 };
 
 #ifdef __cplusplus
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index fa77157..e877468 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -452,6 +452,7 @@ private:
       this->uniforms[id].num_driver_storage = 0;
       this->uniforms[id].driver_storage = NULL;
       this->uniforms[id].storage = this->values;
+      this->uniforms[id].atomic_buffer_index = -1;
       if (this->ubo_block_index != -1) {
 	 this->uniforms[id].block_index = this->ubo_block_index;
 
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index b22340f..8a5d617 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -102,6 +102,11 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
          return &ctx->UniformBuffer;
       }
       break;
+   case GL_ATOMIC_COUNTER_BUFFER:
+      if (ctx->Extensions.ARB_shader_atomic_counters) {
+         return &ctx->AtomicBuffer;
+      }
+      break;
    default:
       return NULL;
    }
@@ -2120,6 +2125,51 @@ bind_buffer_base_uniform_buffer(struct gl_context *ctx,
       set_ubo_binding(ctx, index, bufObj, 0, 0, GL_TRUE);
 }
 
+static void
+set_atomic_buffer_binding(struct gl_context *ctx,
+                          unsigned index,
+                          struct gl_buffer_object *bufObj,
+                          GLintptr offset,
+                          GLsizeiptr size,
+                          const char *name)
+{
+   struct gl_atomic_buffer_binding *binding;
+
+   if (index >= ctx->Const.MaxAtomicBufferBindings) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d)", name, index);
+      return;
+   }
+
+   if (offset & (ATOMIC_COUNTER_SIZE - 1)) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(offset misalgned %d/%d)", name, (int) offset,
+                  ATOMIC_COUNTER_SIZE);
+      return;
+   }
+
+   _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
+
+   binding = &ctx->AtomicBufferBindings[index];
+   if (binding->BufferObject == bufObj &&
+       binding->Offset == offset &&
+       binding->Size == size) {
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, 0);
+   ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
+
+   _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj);
+
+   if (bufObj == ctx->Shared->NullBufferObj) {
+      binding->Offset = -1;
+      binding->Size = -1;
+   } else {
+      binding->Offset = offset;
+      binding->Size = size;
+   }
+}
+
 void GLAPIENTRY
 _mesa_BindBufferRange(GLenum target, GLuint index,
                       GLuint buffer, GLintptr offset, GLsizeiptr size)
@@ -2157,6 +2207,10 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
    case GL_UNIFORM_BUFFER:
       bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
       return;
+   case GL_ATOMIC_COUNTER_BUFFER:
+      set_atomic_buffer_binding(ctx, index, bufObj, offset, size,
+                                "glBindBufferRange");
+      return;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)");
       return;
@@ -2216,6 +2270,10 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
    case GL_UNIFORM_BUFFER:
       bind_buffer_base_uniform_buffer(ctx, index, bufObj);
       return;
+   case GL_ATOMIC_COUNTER_BUFFER:
+      set_atomic_buffer_binding(ctx, index, bufObj, 0, 0,
+                                "glBindBufferBase");
+      return;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");
       return;
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 0bcf27c..91c60e8 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -170,6 +170,12 @@
 #define MAX_UNIFORM_BUFFERS            15 /* + 1 default uniform buffer */
 /* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */
 #define MAX_COMBINED_UNIFORM_BUFFERS   (MAX_UNIFORM_BUFFERS * 6)
+#define MAX_ATOMIC_COUNTERS            4096
+#define MAX_ATOMIC_BUFFERS             16
+/* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */
+#define MAX_COMBINED_ATOMIC_BUFFERS    (MAX_UNIFORM_BUFFERS * 6)
+/* Size of an atomic counter in bytes according to ARB_shader_atomic_counters */
+#define ATOMIC_COUNTER_SIZE            4
 /*@}*/
 
 /**
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index d726d11..a54038e 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -530,6 +530,9 @@ init_program_limits(struct gl_context *ctx, GLenum type,
    prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents +
                                          ctx->Const.MaxUniformBlockSize / 4 *
                                          prog->MaxUniformBlocks);
+
+   prog->MaxAtomicBuffers = 0;
+   prog->MaxAtomicCounters = 0;
 }
 
 
@@ -658,6 +661,12 @@ _mesa_init_constants(struct gl_context *ctx)
    ctx->Const.MaxColorTextureSamples = 1;
    ctx->Const.MaxDepthTextureSamples = 1;
    ctx->Const.MaxIntegerSamples = 1;
+
+   /* GL_ARB_shader_atomic_counters */
+   ctx->Const.MaxAtomicBufferBindings = MAX_COMBINED_ATOMIC_BUFFERS;
+   ctx->Const.MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE;
+   ctx->Const.MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS;
+   ctx->Const.MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS;
 }
 
 
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 34615e3..f2c1935 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -120,6 +120,7 @@ static const struct extension extension_table[] = {
    { "GL_ARB_robustness",                          o(dummy_true),                              GL,             2010 },
    { "GL_ARB_sampler_objects",                     o(dummy_true),                              GL,             2009 },
    { "GL_ARB_seamless_cube_map",                   o(ARB_seamless_cube_map),                   GL,             2009 },
+   { "GL_ARB_shader_atomic_counters",              o(ARB_shader_atomic_counters),              GL,             2011 },
    { "GL_ARB_shader_bit_encoding",                 o(ARB_shader_bit_encoding),                 GL,             2010 },
    { "GL_ARB_shader_objects",                      o(dummy_true),                              GL,             2002 },
    { "GL_ARB_shader_stencil_export",               o(ARB_shader_stencil_export),               GL,             2009 },
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 4f6f59a..9eff9c8 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -143,6 +143,7 @@ enum value_extra {
    EXTRA_FLUSH_CURRENT,
    EXTRA_GLSL_130,
    EXTRA_EXT_UBO_GS4,
+   EXTRA_EXT_ATOMICS_GS4,
 };
 
 #define NO_EXTRA NULL
@@ -331,6 +332,11 @@ static const int extra_MESA_texture_array_es3[] = {
    EXTRA_END
 };
 
+static const int extra_ARB_shader_atomic_counters_and_geometry_shader[] = {
+   EXTRA_EXT_ATOMICS_GS4,
+   EXTRA_END
+};
+
 EXTRA_EXT(ARB_texture_cube_map);
 EXTRA_EXT(MESA_texture_array);
 EXTRA_EXT(NV_fog_distance);
@@ -366,6 +372,7 @@ EXTRA_EXT(ARB_map_buffer_alignment);
 EXTRA_EXT(ARB_texture_cube_map_array);
 EXTRA_EXT(ARB_texture_buffer_range);
 EXTRA_EXT(ARB_texture_multisample);
+EXTRA_EXT(ARB_shader_atomic_counters);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
@@ -886,6 +893,10 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
          _mesa_problem(ctx, "driver doesn't implement GetTimestamp");
       }
       break;
+   /* GL_ARB_shader_atomic_counters */
+   case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+      v->value_int = ctx->AtomicBuffer->Name;
+      break;
    }
 }
 
@@ -991,6 +1002,11 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
          api_found = (ctx->Extensions.ARB_uniform_buffer_object &&
                       _mesa_has_geometry_shaders(ctx));
          break;
+      case EXTRA_EXT_ATOMICS_GS4:
+         api_check = GL_TRUE;
+         api_found = (ctx->Extensions.ARB_shader_atomic_counters &&
+                      _mesa_has_geometry_shaders(ctx));
+         break;
       case EXTRA_END:
 	 break;
       default: /* *e is a offset into the extension struct */
@@ -1684,6 +1700,30 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
          goto invalid_enum;
       v->value_int = ctx->Multisample.SampleMaskValue;
       return TYPE_INT;
+
+   case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+      if (index >= ctx->Const.MaxAtomicBufferBindings)
+	 goto invalid_value;
+      if (!ctx->Extensions.ARB_shader_atomic_counters)
+	 goto invalid_enum;
+      v->value_int = ctx->AtomicBufferBindings[index].BufferObject->Name;
+      return TYPE_INT;
+
+   case GL_ATOMIC_COUNTER_BUFFER_START:
+      if (index >= ctx->Const.MaxAtomicBufferBindings)
+	 goto invalid_value;
+      if (!ctx->Extensions.ARB_shader_atomic_counters)
+	 goto invalid_enum;
+      v->value_int64 = ctx->AtomicBufferBindings[index].Offset;
+      return TYPE_INT64;
+
+   case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+      if (index >= ctx->Const.MaxAtomicBufferBindings)
+	 goto invalid_value;
+      if (!ctx->Extensions.ARB_shader_atomic_counters)
+	 goto invalid_enum;
+      v->value_int64 = ctx->AtomicBufferBindings[index].Size;
+      return TYPE_INT64;
    }
 
  invalid_enum:
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 30855c3..4e77cea 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -718,6 +718,19 @@ descriptor=[
 
 # GL_ARB_texture_cube_map_array
   [ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT, TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
+
+# GL_ARB_shader_atomic_counters
+  [ "ATOMIC_COUNTER_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_atomic_counters" ],
+  [ "MAX_ATOMIC_COUNTER_BUFFER_BINDINGS", "CONTEXT_INT(Const.MaxAtomicBufferBindings), extra_ARB_shader_atomic_counters" ],
+  [ "MAX_ATOMIC_COUNTER_BUFFER_SIZE", "CONTEXT_INT(Const.MaxAtomicBufferSize), extra_ARB_shader_atomic_counters" ],
+  [ "MAX_VERTEX_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.VertexProgram.MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ],
+  [ "MAX_VERTEX_ATOMIC_COUNTERS", "CONTEXT_INT(Const.VertexProgram.MaxAtomicCounters), extra_ARB_shader_atomic_counters" ],
+  [ "MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.FragmentProgram.MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ],
+  [ "MAX_FRAGMENT_ATOMIC_COUNTERS", "CONTEXT_INT(Const.FragmentProgram.MaxAtomicCounters), extra_ARB_shader_atomic_counters" ],
+  [ "MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.GeometryProgram.MaxAtomicBuffers), extra_ARB_shader_atomic_counters_and_geometry_shader" ],
+  [ "MAX_GEOMETRY_ATOMIC_COUNTERS", "CONTEXT_INT(Const.GeometryProgram.MaxAtomicCounters), extra_ARB_shader_atomic_counters_and_geometry_shader" ],
+  [ "MAX_COMBINED_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.MaxCombinedAtomicBuffers), extra_ARB_shader_atomic_counters" ],
+  [ "MAX_COMBINED_ATOMIC_COUNTERS", "CONTEXT_INT(Const.MaxCombinedAtomicCounters), extra_ARB_shader_atomic_counters" ],
 ]},
 
 # Enums restricted to OpenGL Core profile
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 6d700ec..928ce93 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2284,6 +2284,25 @@ struct gl_uniform_block
    enum gl_uniform_block_packing _Packing;
 };
 
+/**
+ * Structure that represents a reference to an atomic buffer from some
+ * shader program.
+ */
+struct gl_active_atomic_buffer
+{
+   /** Uniform indices of the atomic counters declared within it. */
+   GLuint *Uniforms;
+   GLuint NumUniforms;
+
+   /** Binding point index associated with it. */
+   GLuint Binding;
+
+   /** Minimum reasonable size it is expected to have. */
+   GLuint MinimumSize;
+
+   /** Shader stages making use of it. */
+   GLboolean StageReferences[MESA_SHADER_TYPES];
+};
 
 /**
  * A GLSL program object.
@@ -2426,6 +2445,9 @@ struct gl_shader_program
     */
    struct string_to_uint_map *UniformHash;
 
+   struct gl_active_atomic_buffer *AtomicBuffers;
+   unsigned NumAtomicBuffers;
+
    GLboolean LinkStatus;   /**< GL_LINK_STATUS */
    GLboolean Validated;
    GLboolean _Used;        /**< Ever used for drawing? */
@@ -2839,6 +2861,9 @@ struct gl_program_constants
    GLuint MaxUniformBlocks;
    GLuint MaxCombinedUniformComponents;
    GLuint MaxTextureImageUnits;
+   /* GL_ARB_shader_atomic_counters */
+   GLuint MaxAtomicBuffers;
+   GLuint MaxAtomicCounters;
 };
 
 
@@ -3041,6 +3066,12 @@ struct gl_constants
    GLint MaxColorTextureSamples;
    GLint MaxDepthTextureSamples;
    GLint MaxIntegerSamples;
+
+   /** GL_ARB_shader_atomic_counters */
+   GLuint MaxAtomicBufferBindings;
+   GLuint MaxAtomicBufferSize;
+   GLuint MaxCombinedAtomicBuffers;
+   GLuint MaxCombinedAtomicCounters;
 };
 
 
@@ -3084,6 +3115,7 @@ struct gl_extensions
    GLboolean ARB_occlusion_query2;
    GLboolean ARB_point_sprite;
    GLboolean ARB_seamless_cube_map;
+   GLboolean ARB_shader_atomic_counters;
    GLboolean ARB_shader_bit_encoding;
    GLboolean ARB_shader_stencil_export;
    GLboolean ARB_shader_texture_lod;
@@ -3452,6 +3484,11 @@ struct gl_driver_flags
     * gl_shader_program::UniformBlocks
     */
    GLbitfield NewUniformBuffer;
+
+   /**
+    * gl_context::AtomicBufferBindings
+    */
+   GLbitfield NewAtomicBuffer;
 };
 
 struct gl_uniform_buffer_binding
@@ -3469,6 +3506,16 @@ struct gl_uniform_buffer_binding
 };
 
 /**
+ * Binding point for an atomic counter buffer object.
+ */
+struct gl_atomic_buffer_binding
+{
+   struct gl_buffer_object *BufferObject;
+   GLintptr Offset;
+   GLsizeiptr Size;
+};
+
+/**
  * Mesa rendering context.
  *
  * This is the central context data structure for Mesa.  Almost all
@@ -3636,6 +3683,18 @@ struct gl_context
    struct gl_uniform_buffer_binding
       UniformBufferBindings[MAX_COMBINED_UNIFORM_BUFFERS];
 
+   /**
+    * Object currently associated with the GL_ATOMIC_COUNTER_BUFFER
+    * target.
+    */
+   struct gl_buffer_object *AtomicBuffer;
+
+   /**
+    * Array of atomic counter buffer binding points.
+    */
+   struct gl_atomic_buffer_binding
+      AtomicBufferBindings[MAX_COMBINED_ATOMIC_BUFFERS];
+
    /*@}*/
 
    struct gl_meta_state *Meta;  /**< for "meta" operations */
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 4c0484a..2c67f62 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -619,6 +619,12 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
    case GL_PROGRAM_BINARY_LENGTH:
       *params = 0;
       return;
+   case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
+      if (!ctx->Extensions.ARB_shader_atomic_counters)
+         break;
+
+      *params = shProg->NumAtomicBuffers;
+      return;
    default:
       break;
    }
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 3c46004..f38738f 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -154,6 +154,10 @@ _mesa_GetActiveUniformsiv(GLuint program,
 	 params[i] = uni->row_major;
 	 break;
 
+      case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
+	 params[i] = uni->atomic_buffer_index;
+	 break;
+
       default:
 	 _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)");
 	 return;
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index 07e7ea3..d1cbad6 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -535,7 +535,8 @@ _mesa_GetUniformLocation(GLhandleARB programObj, const GLcharARB *name)
     *      with a named uniform block, or if <name> starts with the reserved
     *      prefix "gl_"."
     */
-   if (shProg->UniformStorage[index].block_index != -1)
+   if (shProg->UniformStorage[index].block_index != -1 ||
+       shProg->UniformStorage[index].atomic_buffer_index != -1)
       return -1;
 
    return _mesa_uniform_merge_location_offset(shProg, index, offset);
@@ -849,4 +850,63 @@ void GLAPIENTRY
 _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
                                      GLenum pname, GLint *params)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg;
+   struct gl_active_atomic_buffer *ab;
+   int i;
+
+   if (!ctx->Extensions.ARB_shader_atomic_counters) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetActiveAtomicCounterBufferiv");
+      return;
+   }
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program,
+                                            "glGetActiveAtomicCounterBufferiv");
+   if (!shProg)
+      return;
+
+   if (bufferIndex >= shProg->NumAtomicBuffers) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glGetActiveAtomicCounterBufferiv(bufferIndex)");
+      return;
+   }
+
+   ab = &shProg->AtomicBuffers[bufferIndex];
+
+   switch (pname) {
+   case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+      params[0] = ab->Binding;
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE:
+      params[0] = ab->MinimumSize;
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS:
+      params[0] = ab->NumUniforms;
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES:
+      for (i = 0; i < ab->NumUniforms; ++i)
+         params[i] = ab->Uniforms[i];
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER:
+      params[0] = ab->StageReferences[MESA_SHADER_VERTEX];
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER:
+      params[0] = ab->StageReferences[MESA_SHADER_GEOMETRY];
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER:
+      params[0] = ab->StageReferences[MESA_SHADER_FRAGMENT];
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
+      params[0] = GL_FALSE;
+      return;
+   case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
+      params[0] = GL_FALSE;
+      return;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetActiveAtomicCounterBufferiv(pname 0x%x (%s))",
+		  pname, _mesa_lookup_enum_by_nr(pname));
+      return;
+   }
 }
-- 
1.8.3.4



More information about the mesa-dev mailing list