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

Ian Romanick idr at freedesktop.org
Tue Oct 22 22:52:41 CEST 2013


On 09/15/2013 12:10 AM, Francisco Jerez wrote:
> 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.

A couple minor issues noted below.  With those fixed, this patch is

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

> ---
>  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;

The extension check should go first... here and in the cases below.

Also, it looks like you have some mixed tabs and spaces in (at least)
this file.

> +      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;

Extension check?

> +
>        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;
> +   }
>  }
> 



More information about the mesa-dev mailing list