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.roman...@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; > + } > } > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev