| Name |
| |
| ARB_shader_atomic_counters |
| |
| Name Strings |
| |
| GL_ARB_shader_atomic_counters |
| |
| Contact |
| |
| Bill Licea-Kane ( bill.licea-kane 'at' amd.com ) |
| |
| Contributors |
| |
| Barthold Lichtenbelt, NVIDIA |
| Chris Dodd, NVIDIA |
| Eric Werness, NVIDIA |
| Graham Sellers, AMD |
| Greg Roth, NVIDIA |
| Jeff Bolz, NVIDIA |
| Nick Haemel, AMD |
| Pat Brown, NVIDIA |
| Pierre Boudier, AMD |
| Piers Daniell, NVIDIA |
| |
| Notice |
| |
| Copyright (c) 2011-2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Specification Update Policy |
| |
| Khronos-approved extension specifications are updated in response to |
| issues and bugs prioritized by the Khronos OpenGL Working Group. For |
| extensions which have been promoted to a core Specification, fixes will |
| first appear in the latest version of that core Specification, and will |
| eventually be backported to the extension document. This policy is |
| described in more detail at |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php |
| |
| Status |
| |
| Complete. Approved by the ARB on 2011/06/20. |
| Approved by the Khronos Promoters on 2011/07/29. |
| |
| Version |
| |
| Last Modified Date: July 30, 2012 |
| Author Revision: 31 |
| |
| Number |
| |
| ARB Extension #114 |
| |
| Dependencies |
| |
| This extension is written against the OpenGL 4.1 (core) specification |
| and the GLSL 4.10.6 specification. |
| |
| OpenGL 3.0 is required. |
| |
| |
| Overview |
| |
| This extension provides a set of atomic counters. |
| |
| This extension provides GLSL built-in functions to |
| query and increment/decrement these atomic counters. |
| |
| This enables a shader to write to unique offsets |
| (append to a buffer object) or read from unique offsets |
| (consume from a buffer object). |
| |
| Opaque handles to atomic counters are declared |
| at global scope and are qualified with the uniform qualifier. |
| |
| Unlike other user-defined uniforms declared at global scope, |
| they take NO storage from the default partition, they have |
| NO location, and they may NOT be set with the Uniform* commands. |
| Atomic counters may also NOT be grouped into uniform blocks. |
| |
| Active atomic counters can be discovered by the commands |
| GetUniformIndices, GetActiveUniformName, GetActiveUniform |
| and GetActiveUniformsiv. |
| |
| Like samplers, the opaque handles of the atomic counters |
| and are ONLY used in some GLSL built-in functions. |
| |
| The atomic counters pointed to by the opaque handles |
| are bound to buffer binding points and buffer offsets |
| through the layout qualifiers in the shading language, |
| or they are implicitly assigned by the compiler. |
| |
| Through the OpenGL API, buffer objects may be |
| bound to these binding points with BindBufferBase |
| or BindBufferRange. |
| |
| The contents of the atomic counters are stored |
| in the buffer objects. The contents of atomic |
| counters may be set and queried with buffer object |
| manipulation functions (e.g. BufferData, |
| BufferSubData, MapBuffer or MapBufferRange). |
| |
| |
| IP Status |
| |
| No known IP claims. |
| |
| New Procedures and Functions |
| |
| void GetActiveAtomicCounterBufferiv |
| (uint program, uint bufferIndex, enum pname, int *params); |
| |
| New Types |
| |
| None. |
| |
| New Tokens |
| |
| Accepted by the <target> parameter of BindBufferBase and BindBufferRange: |
| |
| ATOMIC_COUNTER_BUFFER 0x92C0 |
| |
| Accepted by the <pname> parameter of GetBooleani_v, GetIntegeri_v, |
| GetFloati_v, GetDoublei_v, GetInteger64i_v, GetBooleanv, GetIntegerv, |
| GetInteger64v, GetFloatv, GetDoublev, and GetActiveAtomicCounterBufferiv: |
| |
| ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 |
| |
| Accepted by the <pname> parameter of GetIntegeri_64v: |
| |
| ATOMIC_COUNTER_BUFFER_START 0x92C2 |
| ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 |
| |
| Accepted by the <pname> parameter of GetActiveAtomicCounterBufferiv: |
| |
| ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 |
| ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 |
| ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB |
| |
| Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, |
| GetInteger64v, GetFloatv, and GetDoublev: |
| |
| MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC |
| MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD |
| MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE |
| MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF |
| MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 |
| MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 |
| |
| MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 |
| MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 |
| MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 |
| MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 |
| MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 |
| MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 |
| |
| MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 |
| MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC |
| |
| Accepted by the <pname> parameter of GetProgramiv: |
| |
| ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 |
| |
| Accepted by the <pname> parameter of GetActiveUniformsiv: |
| |
| UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA |
| |
| Returned in <params> by GetActiveUniform and GetActiveUniformsiv: |
| |
| UNSIGNED_INT_ATOMIC_COUNTER 0x92DB |
| |
| |
| Additions to Chapter 2 of the OpenGL 4.1 (Core Profile) Specification |
| (OpenGL Operation) |
| |
| Changes to Section 2.9 Buffer Objects |
| |
| Add to table 2.8 (p. 41) |
| |
| Target Name Purpose Described in section(s) |
| --------------------- ---------------------- ----------------------- |
| ATOMIC_COUNTER_BUFFER Atomic counter storage 2.11.8 |
| |
| Changes to Section Binding Buffer Objects to Indexed Targets |
| |
| Change end of first sentence in section, p. 42 |
| |
| ...target must be ATOMIC_COUNTER_BUFFER, TRANSFORM_FEEDBACK_BUFFER |
| or UNIFORM_BUFFER. |
| |
| 2.11.7 Uniform Variables |
| |
| Replace third sentence of paragraph one in the section, p. 72 |
| beginning with "Uniforms are program..." |
| |
| Uniforms, except for subroutine uniforms, are program... |
| |
| Replace first sentence of paragraph two in the section, p. 72 |
| beginning with "Sets of uniforms can be..." |
| |
| Sets of uniforms, except for samplers, subroutine uniforms and |
| atomic counters, can be grouped into <uniform blocks>. |
| |
| Modify first sentence of first paragraph, p. 73 |
| beginning with "The amount of storage..." |
| |
| The amount of storage available for uniform variables, |
| except for subroutine uniforms and atomic counters, |
| in the default uniform block... |
| |
| Modify first sentence of second paragraph, p. 73 |
| beginning with "When a program..." |
| |
| When a program is successfully linked, all active |
| uniforms, except for atomic counters, ... |
| |
| Insert a pragraph prior to third paragraph, p. 73 |
| beginning with "Similary, when a program..." |
| |
| Similarly, when a program is successfully linked, |
| all active atomic counters are assigned bindings, |
| offsets (and strides for arrays of atomic counters) |
| according to layout rules described below. Atomic |
| counter uniform buffer objects provide the storage for |
| atomic counters, so the values of atomic counters |
| may be changed by modifying the contents of the |
| buffer object using commands such as BufferData, |
| BufferSubData, MapBuffer, and UnmapBuffer. Atomic |
| counters are not assigned a location and may not be |
| modified using the Uniform* commands. The bindings, |
| offsets, and strides belonging to atomic counters |
| of a program object are invalidated and new ones |
| assigned after each successful re-link. |
| |
| |
| Modify the final line on paragraph continuing on p. 74 |
| ending "or if <name> is associated with a named uniform block." |
| |
| ... if <name> is associated with an atomic counter, |
| or if <name> is associated with a named uniform block. |
| |
| Insert section prior to the last paragraph on p. 76, |
| begining with "Each active uniform, whether in a named..." |
| |
| In programs with active atomic counter uniforms, each buffer object |
| binding point associated with one or more active atomic counters is |
| considered an active atomic counter buffer. Information about the set of |
| active atomic counter buffers for a program can be obtained by calling |
| |
| void GetActiveAtomicCounterBufferiv |
| ( uint program, uint bufferIndex, enum pname, int *params ); |
| |
| <program> is the name of a program object for which the |
| command LinkProgram has been issued in the past. It is |
| not necessary for <program> to have been linked successfully. |
| The link could have failed because the number of active |
| active atomic counters exceeded implementation-dependent limits. |
| |
| <bufferIndex> specifies the index of an active atomic counter buffer and |
| must be in the range zero to the value of ACTIVE_ATOMIC_COUNTER_BUFFERS-1. |
| The value of ACTIVE_ATOMIC_COUNTER_BUFFERS for <program> indicates the |
| number of active atomic counter buffers and can be queried with |
| GetProgramiv (see section 6.1.12). If <bufferIndex> is greater than or |
| equal to the value of ACTIVE_ATOMIC_COUNTER_BUFFERS, the error |
| INVALID_VALUE is generated. |
| |
| If no error occurs, the parameter(s) specified by <pname> are |
| returned in <params>. Otherwise, nothing will be written to |
| <params>. |
| |
| If <pname> is ATOMIC_COUNTER_BUFFER_BINDING, then the index of the atomic |
| counter buffer binding point associated with the active atomic counter |
| buffer <bufferIndex> for <program> is returned. |
| |
| If <pname> is ATOMIC_COUNTER_BUFFER_DATA_SIZE, then the |
| implementation-dependent minimum total buffer object size, in |
| basic machine units, required to hold all active atomic counters |
| in the atomic counter buffer identified by |
| <bufferIndex> is returned. |
| |
| The total amount of buffer object storage accessible in any |
| given atomic counter buffer is subject to an implementation-dependent |
| limit. The maximum amount of storage accessible to atomic counters, |
| in basic machine units, can be queried by calling GetIntegerv with the constant |
| MAX_ATOMIC_COUNTER_BUFFER_SIZE. If the amount of storage required for a |
| atomic counter buffer exceeds this limit, a program may fail |
| to link. |
| |
| If <pname> is ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS, then the |
| number of active atomic counter variables associated with the atomic |
| counter buffer identified by <bufferIndex> is returned. |
| |
| If <pname> is ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES, |
| then a list of the active atomic counter indices for the atomic counter |
| buffer identified by <bufferIndex> is returned. The number of |
| elements that will be written to <params> is the value of |
| ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS for <bufferIndex>. |
| |
| If <pname> is ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER, |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER, |
| UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER, |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER, or |
| ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER, then a boolean |
| value indicating whether the atomic counter buffer identified by |
| <bufferIndex> is referenced by the vertex, tessellation control, |
| tessellation evaluation, geometry, or fragment programming stages of |
| <program>, respectively, is returned." |
| |
| Modify first sentence of last paragraph on p. 76, |
| beginning with "Each active uniform, whether in a named..." |
| |
| Each active uniform, except for subroutine uniforms, |
| whether in a the default block, in a named uniform block, or |
| an atomic counter... |
| |
| Modify first sentence of the fourth paragraph on p. 77 |
| beginning with "The name of an active..." |
| |
| The name of an active uniform, except for subroutine |
| uniforms, may be querried... |
| |
| |
| Replace the last paragraph on p. 77 |
| beginning with "Each uniform variable..." |
| |
| Each active uniform variable, except subroutine uniforms, |
| is broken down into one or more strings using the "." (dot) |
| and "[]" operators, if necessary, to the point that it is |
| legal to pass each string back into GetUniformIndices. |
| |
| Modify first sentence of first paragraph on p. 78 |
| beginning with "Information about active uniforms..." |
| |
| Information about active uniforms, except for |
| subroutine uniforms, can be... |
| |
| Replace the fourth paragraph on p. 78 |
| beginning with "Each uniform variable..." |
| |
| Each active uniform variable, except subroutine uniforms, |
| is broken down into one or more strings using the "." (dot) |
| and "[]" operators, if necessary, to the point that it is |
| legal to pass each string back into GetUniformIndices. |
| |
| Modify the last paragraph |
| |
| Add to Table 2.13, p. 81 |
| |
| Type Name Token Keyword Attrib Xfb |
| --------------------------- ----------- ------ --- |
| UNSIGNED_INT_ATOMIC_COUNTER atomic_uint |
| |
| Modify description of UNIFORM_OFFSET query in GetActiveUniformsiv, p. 82 |
| |
| If <pname> is UNIFORM_OFFSET, then an array of buffer offsets is returned. |
| For uniforms in a named uniform block, the returned value will be its |
| offset, in basic machine units, relative to the beginning of the uniform |
| block in the buffer object data store. For atomic counter uniforms, the |
| returned value will be its offset relative to the beginning of its active |
| atomic counter buffer. For all other uniforms, an offset of -1 will be |
| returned. |
| |
| If <pname> is UNIFORM_ARRAY_STRIDE, then an array of strides between array |
| elements in buffer object storage is returned. For uniforms in named |
| uniform blocks and for uniforms declared as atomic counters, the stride is |
| the difference, in basic machine units, of the offsets of consecutive |
| elements in an array, or zero for uniforms not declared as an array. For |
| all other uniforms, a stride of -1 will be returned. |
| |
| Add prior to "Loading Uniform Values In The Default Uniform Block", p. 83 |
| |
| If <pname> is UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX, then an array |
| identifying the active atomic counter buffer index of each of the uniforms |
| specified by the corresponding array of <uniformIndices> is returned. For |
| uniforms other than atomic counters, the returned buffer index is -1. The |
| returned indices can be passed to GetActiveAtomicCounterBufferiv to query |
| properties of the associated buffer, and not necessarily the binding point |
| specified in the uniform declaration. |
| |
| Modify first sentence of first new paragraph on p. 83 |
| beginning with "To load values into the uniform variables..." |
| |
| To load values into the uniform variables of the default uniform block |
| of the active program object, except for subroutine uniforms and atomic |
| counters, ..." |
| |
| Modify first sentence of the fifth paragraph on p. 84 |
| beginning with "For all other uniform types..." |
| |
| For all other uniform types, except for subroutine |
| uniforms and atomic counters, ... |
| |
| |
| Add new unnumbered subsections at the end of the section, p. 90 |
| |
| Atomic Counter Buffers |
| |
| The values of atomic counters are backed by buffer object storage. |
| The mechanisms for accessing individual atomic counters in a buffer object |
| and connecting to an atomic counter are described in this section. |
| |
| There is a set of implementation-dependent maximums for the number |
| of active atomic counter buffers referenced by each shader. If the |
| number of atomic counter buffers referenced by any shader in the program |
| exceeds its corresponding limit, the program will fail to link. The limits |
| for vertex, tessellation control, tessellation evaluation, geometry, and |
| fragment shaders can be obtained by calling GetIntegerv with pname values |
| of MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS, |
| MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS, MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, |
| or MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, respectively. |
| |
| Additionally, there is an implementation-dependent limit on the sum of the |
| number of active atomic counter buffers used by each shader of a |
| program. If an atomic counter buffer is used by multiple shaders, |
| each such use counts separately against this combined limit. The combined |
| atomic counter buffer use limit can be obtained by calling |
| GetIntegerv with a <pname> of MAX_COMBINED_ATOMIC_COUNTER_BUFFERS. |
| |
| Atomic Counter Buffer Object Storage |
| |
| Atomic counters stored in buffer objects are represented in memory |
| as follows: |
| |
| * Members of type atomic_uint are extracted from a buffer object by |
| reading a single uint-typed value at the specified offset. |
| |
| * Arrays of type atomic_uint are stored in memory by element order, |
| with array element member zero at the lowest offset. The difference |
| in offsets between each pair of elements in the array in basic machine |
| units is referred to as the array stride, and is constant across the |
| entire array. The stride can be queried by calling GetIntegerv with |
| a <pname> of UNIFORM_ARRAY_STRIDE after a program is linked. |
| |
| Atomic Counter Buffer Bindings |
| |
| The value of an active atomic counter is extracted from or written to the |
| data store of a buffer object bound to one of an array of atomic counter |
| buffer binding points. The number of binding points can be queried by |
| calling GetIntegerv with a <pname> of MAX_ATOMIC_COUNTER_BUFFER_BINDINGS. |
| |
| Regions of buffer objects are bound as storage for atomic counters by calling |
| one of the commands BindBufferRange or BindBufferBase (see section 2.9.1) |
| with <target> set to ATOMIC_COUNTER_BUFFER. In addition to the general errors |
| described in section 2.9.1, BindBufferBase and BindBufferRange will generate an INVALID_VALUE |
| error if <index> is greater than or equal to the value of MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, |
| and BindBufferRange will generate an INVALID_VALUE error if <offset> is |
| not a multiple of four. |
| |
| Each of a program's active atomic counter buffer bindings has a corresponding |
| atomic counter buffer binding point. This binding point is established |
| with the layout qualifier in the shader text, either explicitly or implicitly, |
| as described in the Shading Language specification. |
| |
| When executing shaders that access atomic counters, each active atomic |
| counter buffer must be populated with a buffer object with a size no |
| smaller than the minimum required size for that buffer (the value of |
| ATOMIC_COUNTER_BUFFER_DATA_SIZE). For binding points populated by |
| BindBufferRange, the size in question is the value of the <size> |
| parameter. If any active atomic counter buffer is not backed by a |
| sufficiently large buffer object, the results of shader execution are |
| undefined, and may result in GL interruption or termination. |
| |
| |
| Add to Section 2.11.11 Shader Execution, p. 102, inserting before Shader Inputs |
| |
| Atomic Counter Access |
| |
| Shaders have the ability to set and get atomic counters. The maximum number |
| of atomic counters available to shaders are the values of the implementation |
| dependent constants |
| |
| * MAX_VERTEX_ATOMIC_COUNTERS (for vertex shaders), |
| * MAX_TESS_CONTROL_ATOMIC_COUNTERS (for tessellation control shaders), |
| * MAX_TESS_EVALUATION_ATOMIC_COUNTERS (for tessellation evaluation shaders), |
| * MAX_GEOMETRY_ATOMIC_COUNTERS (for geometry shaders), and |
| * MAX_FRAGMENT_ATOMIC_COUNTERS (for fragment shaders). |
| |
| All active shaders combined cannot use more than the value of |
| MAX_COMBINED_ATOMIC_COUNTERS atomic counters. If more than one |
| pipeline stage accesses the same atomic counter, each such |
| access counts separately against the MAX_COMBINED_ATOMIC_COUNTERS limit. |
| |
| |
| Additions to Chapter 6 of the OpenGL 4.1 (Core Profile) Specification |
| (State and State Requests) |
| |
| Add to the end of section 6.1.8 (Buffer Object Queries) |
| |
| To query which buffer objects are bound to the array of transform |
| feedback binding points and will be used when transform feedback is |
| active, call GetIntegeri\_v with <param> set to |
| TRANSFORM_FEEDBACK_BUFFER_BINDING. <index> must be in the range zero to |
| the value of MAX_TRANSFORM_FEEDBACK_BUFFERS minus one. The name of the |
| buffer object bound to <index> is returned in <values>. If no buffer |
| object is bound for <index>, zero is returned in <values>. The error |
| INVALID_VALUE is generated if <index> is greater than or equal to the |
| value of MAX_TRANSFORM_FEEDBACK_BUFFERS. |
| |
| To query the starting offset or size of the range of each buffer object |
| binding used for transform feedback, call GetInteger64i_v with <param> |
| set to TRANSFORM_FEEDBACK_BUFFER_START or TRANSFORM_FEEDBACK_BUFFER_SIZE |
| respectively. <index> must be in the range 0 to the value of |
| MAX_TRANSFORM_FEEDBACK_BUFFERS minus one. If the parameter (starting |
| offset or size) was not specified when the buffer object was bound (e.g. |
| if bound with BindBufferBase), or if no buffer object is bound to |
| <index>, zero is returned. The error INVALID_VALUE is generated if |
| <index> is greater than or equal to the value of |
| MAX_TRANSFORM_FEEDBACK_BUFFERS}. |
| |
| Add to Section 6.1.12, immediately before the description of IsProgramPipeline |
| (p. 335) |
| |
| If <pname> is ACTIVE_ATOMIC_COUNTER_BUFFERS, the number of active atomic |
| counter buffers used by <program> is returned. |
| |
| Additions to Appendix A (Invariance) |
| |
| Add additional sentence to A.3 Invariance Rules, Rule 4 (p. 399) |
| |
| Invariance is relaxed for shaders with side effects (such |
| as accessing atomic counters), see A.5, Atomic Counter Invariance. |
| |
| Add A.5 Atomic Counter Invariance |
| |
| When using a program containing atomic counters, the following |
| invariance rules are intended to provide repeatability guarantees |
| but within certain constraints. |
| |
| Rule 1 When a single shader type within a program accesses |
| an atomic counter with only atomicCounterIncrement, any individual |
| shader invocation is guaranteed to get a unique value returned. |
| |
| Corollary 1 - Also holds true with atomicCounterDecrement. |
| |
| Corollary 2 - This does not hold true for atomicCounter |
| |
| Corollary 3 - Repeatability is relaxed. While a unique |
| value is returned to the shader, even given the same |
| initial state vector and buffer contents, it is not guaranteed |
| that the *SAME* unique value will be returned for each individual |
| invocation of a shader (For example, on any single vertex, or |
| any single fragment). It is wholly the shader writer's |
| responsibility to respect this constraint. |
| |
| Rule 2 When two or more shader types within a program |
| access an atomic counter with only atomicCounterIncrement, |
| there is no repeatability of the ordering of operations between |
| stages. For example, some number of vertices may be processed, |
| then some number of fragments may be processed. |
| |
| Corollary 4 - This also holds true with atomicCounterDecrement |
| and atomicCounter. |
| |
| Additions to Appendix D (Shared Objects and Multiple Contexts) |
| |
| Modify D.3 (Propagating State Changes) |
| |
| (add to list of bullets at the end of the section, p. 467) |
| |
| * Rendering commands that trigger shader invocations, where |
| the shader performs built-in atomic counter functions. |
| |
| New State |
| |
| Add new table, labeled "Program Object State (cont.)" after Table 6.36, p. 377 |
| |
| Initial |
| Get Value Type Get Command Value Description Sec. |
| ----------------------- ---- ----------- ------- ------------------------ ----- |
| ACTIVE_ATOMIC_COUNTER_BUFFERS Z+ GetProgramiv 0 Number of active atomic 2.11.7 |
| counter buffers used |
| by a program |
| ATOMIC_COUNTER_BUFFER_BINDING nxZ+ GetActiveAtomic- - Binding point associated 2.11.7 |
| CounterBufferiv with an active atomic |
| counter buffer |
| ATOMIC_COUNTER_BUFFER_DATA_SIZE nxZ+ GetActiveAtomic- - Minimum size required by 2.11.7 |
| CounterBufferiv an active atomic counter |
| buffer |
| ATOMIC_COUNTER_BUFFER_ACTIVE_ nxZ+ GetActiveAtomic- - Number of active atomic 2.11.7 |
| ATOMIC_COUNTERS CounterBufferiv counters in an active |
| atomic counter buffer |
| ATOMIC_COUNTER_BUFFER_ACTIVE_ mxnxZ+ GetActiveAtomic- - List of active atomic 2.11.7 |
| ATOMIC_COUNTER_INDICES CounterBufferiv counters in an active |
| atomic counter buffer |
| ATOMIC_COUNTER_BUFFER_ nxB GetActiveAtomic- FALSE Active atomic counter 2.11.7 |
| REFERENCED_BY_VERTEX CounterBufferiv buffer has a counter used |
| SHADER by vertex shaders |
| ATOMIC_COUNTER_BUFFER_ nxB GetActiveAtomic- FALSE Active atomic counter 2.11.7 |
| REFERENCED_BY_TESS_CONTROL CounterBufferiv buffer has a counter used |
| SHADER by tess. control shaders |
| ATOMIC_COUNTER_BUFFER_ nxB GetActiveAtomic- FALSE Active atomic counter 2.11.7 |
| REFERENCED_BY_TESS_EVALUTION CounterBufferiv buffer has a counter used |
| SHADER by tess. evaluation shaders |
| ATOMIC_COUNTER_BUFFER_ nxB GetActiveAtomic- FALSE Active atomic counter 2.11.7 |
| REFERENCED_BY_GEOMETRY CounterBufferiv buffer has a counter used |
| SHADER by geometry shaders |
| ATOMIC_COUNTER_BUFFER_ nxB GetActiveAtomic- FALSE Active atomic counter 2.11.7 |
| REFERENCED_BY_FRAGMENT CounterBufferiv buffer has a counter used |
| SHADER by fragment shaders |
| UNIFORM_ATOMIC_COUNTER_BUFFER_ nxZ+ GetActive- - Active atomic counter 2.11.7 |
| INDEX Uniformsiv buffer associated with an |
| active uniform |
| |
| Add new table, labeled "Atomic Counter State", after Table 6.39, p. 380 |
| |
| Initial |
| Get Value Type Get Command Value Description Sec. |
| ----------------------- ---- ----------- ------- ------------------------ ----- |
| ATOMIC_COUNTER_BUFFER_BINDING Z+ GetIntegerv 0 Current value of generic 2.9.9 |
| atomic counter buffer |
| binding |
| ATOMIC_COUNTER_BUFFER_BINDING n*Z+ GetIntegeri_v 0 Buffer object bound 2.9.9 |
| to each atomic counter |
| buffer binding point |
| ATOMIC_COUNTER_BUFFER_START n*Z+ GetInteger64i_v 0 Start offset of 2.9.9 |
| binding range for each |
| atomic counter buffer |
| ATOMIC_COUNTER_BUFFER_SIZE n*Z+ GetInteger64i_v 0 Size of binding range for 2.9.9 |
| each atomic counter buffer |
| |
| New Implementation Dependent State |
| |
| |
| Add to Table 6.46, Implementation Dependent Vertex Shader Limits, p. 387: |
| |
| Get Value Type Get Command Minimum Value Description Sec. |
| ----------------------- ---- ----------- ------------- ------------------------- ----- |
| MAX_VERTEX_ATOMIC_COUNTER_BUFFERS Z+ GetIntegerv 0 Number of atomic counter 2.11.7 |
| buffers accessed by a |
| vertex shader |
| MAX_VERTEX_ATOMIC_COUNTERS Z+ GetIntegerv 0 Number of atomic counters 2.11.11 |
| accessed by a vertex |
| shader |
| Add to Table 6.47, Implementation Dependent Tesselation Shader Limits, p. 388: |
| |
| Get Value Type Get Command Minimum Value Description Sec. |
| ----------------------- ---- ----------- ------------- ------------------------- ----- |
| MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS Z+ GetIntegerv 0 Number of atomic counter 2.11.7 |
| buffers accessed by a |
| tesselation control shader |
| MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS Z+ GetIntegerv 0 Number of atomic counter 2.11.7 |
| buffers accessed by a |
| tesselation evaluation shader |
| MAX_TESS_CONTROL_ATOMIC_COUNTERS Z+ GetIntegerv 0 Number of atomic counters 2.11.11 |
| accessed by a tesselation |
| control shader |
| MAX_TESS_EVALUATION_ATOMIC_COUNTERS Z+ GetIntegerv 0 Number of atomic counters 2.11.11 |
| accessed by a tesselation |
| evaluation shader |
| Add to Table 6.48, Implementation Dependent Geometry Shader Limits, p. 389: |
| |
| Get Value Type Get Command Minimum Value Description Sec. |
| ----------------------- ---- ----------- ------------- ------------------------- ----- |
| MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS Z+ GetIntegerv 0 Number of atomic counter 2.11.7 |
| buffers accessed by a |
| geometry shader |
| MAX_GEOMETRY_ATOMIC_COUNTERS Z+ GetIntegerv 0 Number of atomic counters 2.11.11 |
| accessed by a geometry |
| shader |
| Add to Table 6.49, Implementation Dependent Fragment Shader Limits, p. 390: |
| |
| Get Value Type Get Command Minimum Value Description Sec. |
| ----------------------- ---- ----------- ------------- ------------------------- ----- |
| MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS Z+ GetIntegerv 1 Number of atomic counter 2.11.7 |
| buffers accessed by a |
| fragment shader |
| MAX_FRAGMENT_ATOMIC_COUNTERS Z+ GetIntegerv 8 Number of atomic counters 2.11.11 |
| accessed by a fragment |
| shader |
| Add to Table 6.50 Implementation Dependent Aggregate Shader Limits, p. 391: |
| |
| Get Value Type Get Command Minimum Value Description Sec. |
| ----------------------- ---- ----------- ------------- ------------------------- ----- |
| MAX_ATOMIC_COUNTER_BUFFER_BINDINGS Z+ GetIntegerv 1 Max. number of atomic 2.9.9 |
| counter buffer bindings |
| MAX_ATOMIC_COUNTER_BUFFER_SIZE Z+ GetIntegerv 32 |
| machine units of an |
| atomic counter buffer |
| MAX_COMBINED_ATOMIC_COUNTER_BUFFERS Z+ GetIntegerv 1 Max. number of atomic 2.11.7 |
| counter buffers per |
| program |
| MAX_COMBINED_ATOMIC_COUNTERS Z+ GetIntegerv 8 Max. number of atomic 2.11.11 |
| counter uniforms per |
| program |
| |
| |
| |
| Additions to the OpenGL Shading Langauge 4.10.6 Specification |
| |
| Including the following line in a shader can be used to control the |
| language features described in the extension: |
| |
| #extension GL_ARB_shader_atomic_counters : <behavior> |
| |
| where <behavior> is as specified in section 3.3. |
| |
| A new preprocessor #define is added to the OpenGL Shading Language: |
| |
| #define GL_ARB_shader_atomic_counters 1 |
| |
| Additions to Chapter 3 of the OpenGL Shading Language 4.10.6 Specification |
| |
| Add to 3.6 Keywords (pp. 13-15) |
| |
| atomic_uint |
| |
| Additions to Chapter 4 of the OpenGL Shading Language 4.10.6 Specification |
| |
| Add to Section 4.1 Basic Types |
| |
| Unsigned Integer Counter Types (opaque) |
| |
| Type Meaning |
| atomic_uint a handle for accessing an unsigned integer atomic counter |
| |
| Insert Section 4.1.8 Atomic Counters (existing 4.1.8 becomes 4.1.9, and so on) |
| |
| 4.1.8 Atomic Counters |
| |
| Atomic Counter types (e.g. atomic_uint) are effectively opaque handles to counters. |
| They are used with the built-in atomic counter functions (described in section 8.10 |
| "Atomic Counter Functions") to specify which counter to access. They can only be |
| declared as function parameters or uniform-qualified global variables. |
| |
| Except for array indexing, structure field selection, and parenthesis, |
| counters are not allowed to be operands in expressions. Counters aggregated into |
| arrays within a shader (using square brackets []) can only be indexed with dynamically |
| uniform integral expressions, otherwise results are undefined. Counters cannot be |
| treated as l-values; hence cannot be used as out or inout function parameters, nor |
| can they be assigned into. |
| |
| |
| Modify last sentence of first paragraph of section 4.3.5, p. 36 |
| beginning with "Sampler types cannot..." |
| |
| Sampler types and atomic counter types cannot..." |
| |
| Insert Section 4.3.6 Atomic Counters. (Existing 4.3.6 becomes 4.3.7, and so on) |
| |
| 4.3.6 Uniform |
| |
| The uniform qualifier is used to declare global opaque handles (to counters) |
| where the handles are the same across the entire primitive being processed. |
| All uniform variables are read-only and are initialized at link time. |
| |
| It is an error to write to a uniform-qualified variable. |
| |
| For example, |
| |
| layout( binding=2, offset=0 ) uniform atomic_uint a; |
| |
| will establish that the opaque handle to the atomic counter "a" |
| will be bound to atomic counter buffer binding 2 at offset 0. |
| |
| There is an implementation dependent limit to the number of uniforms that |
| can be used for each type of shader and if this is exceeded it will cause a |
| compile-time or link-time error. Uniform variables that are declared but |
| not used may or may not count against this limit. |
| |
| If multiple shaders are linked together, then they will share a single |
| global uniform name space, including within the language as well as across |
| languages. Hence, the type of uniform variables with the |
| same name must match across all shaders that are linked into a single program. |
| |
| It is legal for some shaders to provide a layout qualifier for a uniform |
| variable of the same name, while another shader does not provide |
| a layout qualifier for a uniform variable of the same name, but if provided, |
| all provided layout qualifiers must be equal for a uniform variable of the |
| same name, and if not provided, all implicitly provided layout qualifiers must |
| be equal for a uniform variable of the same name. |
| |
| |
| Add Section 4.3.8.4 Uniform Layout Qualifiers |
| |
| Layout qualifiers can be used on uniform declarations. The uniform qualifier |
| identifiers for uniforms are |
| |
| layout-qualifier-id |
| binding = integer-constant |
| offset = integer-constant |
| |
| For example, |
| |
| layout(binding = 2, offset = 4) uniform atomic_uint foo; |
| |
| will establish that the atomic counter foo has a binding to |
| buffer binding point 2 and an offset of 4 basic machine units |
| in that buffer. The offset will be post-incremented by the |
| size of the uniform (for atomic_uint, 4 basic machine units). |
| |
| A subsequent uniform declaration will inherit the binding, |
| and offset (perhaps post-incremented). For example, a |
| subsequent declaration of, |
| |
| uniform atomic_uint bar; |
| |
| will establish that the atomic counter bar has a binding to |
| buffer binding point 2 and an offset of 8 basic machine units |
| in that buffer. The offset will be post-incremented by |
| the size of the uniform (again, for atomic_uint, 4 basic |
| machine units). |
| |
| If the limit on the maximum number of bindings is exceeded, |
| or if the limit of the maximum number of counters (either |
| per shader type or combined) is exceeded, it will be a link |
| error. |
| |
| It is a compile error to bind an atomic counter with |
| a value greater than or equal to gl_MaxAtomicCounterBindings. |
| |
| Add Section 4.3.8.3 Uniform Layout Qualifiers prior to |
| existing 4.3.8.3 Uniform Block Layout Qualifiers, and renumber |
| subsequent sections |
| |
| Layout qualifiers can be used on uniform declarations. The layout |
| qualifiers identifiers for uniforms are |
| |
| layout-qualifier-id |
| binding = integer-constant |
| offset = integer-constant |
| |
| Uniform layout qualifiers can be declared for global scope or on a single |
| uniform declaration. |
| |
| Default layouts are established at global scope for uniforms as |
| |
| layout (layout-qualifier-id-list) uniform; |
| |
| When this is done, the previous default qualification is first inherited and |
| then overridden as per the override rules listed below. The result becomes |
| the new default qualification scoped to subsequent uniform block definitions. |
| |
| The initial state of compiliation is as if the following were declared: |
| |
| layout(binding=0, offset=0) uniform; |
| |
| Explicitly declaring this in a shader will return defaults back to their |
| initial state. |
| |
| Uniforms can be declared with optional layout qualifiers. As with global |
| layout declarations, uniform layout qualification first inherits from the |
| current default qualification and then overrides it. |
| |
| When multiple arguments are listed in a layout declaration, the affect will |
| be the same as if they were declared one at a time, in order from left to |
| right, each in turn inheriting from and overriding the result from the |
| previous qualification. |
| |
| For each uniform element, the then current default layout qualifiers will |
| be applied, together with any prior post-increments of offset, if applicable, |
| then the offset will be post-incremented by the size of the uniform, in |
| basic machine units. |
| |
| Uniforms may share the same binding, but if a binding is shared, each |
| offset must be explicitly or implicitly unique. |
| |
| For example a valid uniform declarations: |
| |
| layout(binding=3, offset=4) uniform; |
| |
| uniform atomic_uint thunderhead; // offset = 4 |
| uniform atomic_uint stratogirl; // offset = 8 |
| layout(binding=3) uniform atomic_uint metalman; // binding matches, |
| // offset = 12 |
| layout(offset=20) uniform atomic_uint dynaguy; // offset = 20 |
| uniform atomic_uint splashdown; // offset = 24 |
| |
| |
| Example of an invalid uniform declarations; |
| |
| layout(binding=1, offset=0) batman; // OK |
| layout(binding=2, offset=0) robin; // OK |
| layout(binding=1, offset=0) catwoman; // error, offsets |
| // must not be shared |
| // between batman and |
| // catwoman |
| |
| Additions to Chapter 7 of the OpenGL Shading Language 4.10.6 Specification |
| (Built-in Variables) |
| |
| Add to Section 7.4, Built-In Constants |
| |
| const int gl_MaxVertexAtomicCounters = 0; // minimum maximum |
| const int gl_MaxTessControlAtomicCounters = 0; // minimum maximum |
| const int gl_MaxTessEvaluationAtomicCounters = 0; // minimum maximum |
| const int gl_MaxGeometryAtomicCounters = 0; // minimum maximum |
| const int gl_MaxFragmentAtomicCounters = 8; // minimum maximum |
| const int gl_MaxCombinedAtomicCounters = 8; // minimum maximum |
| const int gl_MaxAtomicCounterBindings = 1; // minimum maximum |
| |
| Additions to Chapter 8 of the OpenGL Shading Language 1.50 Specification |
| (Built-in Functions) |
| |
| Add Section 8.10 Atomic Counter Functions (existing 8.10 becomes 8.11, and so on) |
| |
| 8.10 Atomic Counter Functions |
| |
| Atomic counter functions have exclusive access to any single counter, perform |
| an atomic operation, then release exclusive access to that counter, |
| as-if a single step. |
| Any other atomic counter function may access that single counter only after any |
| earlier atomic operation is completed. |
| |
| The value returned by an atomic counter function is the value of |
| an atomic counter, which may be: |
| returned and incremented in an atomic operation, |
| or decremented and returned in an atomic operation, |
| or simply returned. |
| |
| The underlying counter is a 32-bit unsigned integer. Increments and decrements |
| at the limit of the range will wrap to [0, 2^32-1]. |
| |
| |
| Syntax Description |
| uint atomicCounterIncrement Increments <counter> atomically, returning |
| ( atomic_uint counter ); the value prior to the increment operation. |
| |
| uint atomicCounterDecrement Decrements <counter> atomically, returning |
| ( atomic_uint counter ); the value after the decrement operation. |
| |
| uint atomicCounter Returns the value of <counter>. |
| ( atomic_uint counter ); |
| |
| |
| Sample Code |
| |
| layout( binding=2) uniform atomic_uint a; |
| layout( binding=2, offset=4 ) uniform atomic_uint b; |
| layout( binding=5, offset=0 ) uniform atomic_uint c; |
| |
| // ... |
| |
| uint foo = atomicCounterIncrement( a ); // get the counter value, then increment the counter |
| // atomic operation |
| uint bar = atomicCounterDecrement( b ); // decrement the counter value, then get the counter |
| // atomic operation |
| uint baz = atomicCounter( c ); // get the counter value |
| // atomic operation |
| |
| Issues |
| |
| 1 - Do we need an indirection table between the counters and the shaders? |
| (Similar to Samplers? VertexAttribBinding? Uniform blocks?) |
| |
| Yes. This draft introduces opaque counters similar to samplers. |
| However, there is no Uniform-like API means of setting them to a |
| texture unit or attribute-like API of binding them to a location. |
| Instead, we have uniforms, which are a storage qualifier at |
| global scope, and which use layout qualifiers to bind them |
| to buffer binding points. A GetActiveUniforms API is |
| used to retrieve the names of the counters, and their |
| bindings, and other useful information. |
| |
| 2 - What shader stages are these available in? |
| |
| Resolved. All stages. |
| |
| 3 - Can the counters be operated on in the shading language? |
| |
| Resolved: Not directly. But indirectly, probably not in |
| any meaningful way. But there are no restrictions placed on the |
| values once they are returned to the shader. |
| |
| 4 - Where's issue 4? |
| |
| Resolved. It's here. |
| |
| 5 - Can a single shader both increment and decrement an individual atomic |
| counter? |
| |
| Resolved: Yes, with caveats. In order to provide a global unique |
| offset, a counter must *either* be incremented or decremented by a |
| shader. The best way to think of this is that these are UNORDERED |
| increments and decrements. However, there may be uses for these |
| atomic counters other than providing unique offsets. |
| |
| We provide mechanism, not policy. Shader coding conventions can |
| provide policy - there's little reason for the compiler to be involved |
| in enforcing. |
| |
| 6 - Can multiple shaders in a program both increment and decrement an |
| individual atomic counter? |
| |
| Resolved. Yes, with the same caveats as above. |
| |
| 7 - Is there a maximum maximum number of counters? |
| |
| Resolved. No, implementations are free to support arbitrarily many |
| counters. Implementations may set their own limits, though there are |
| specified minimum limits. |
| |
| 8 - Can a counter be queried, but not incremented/decremented in the shader? |
| |
| Resolved: Yes. (It's an increment of zero. Or a decrement of zero.) |
| Note that using a get without an increment or decrement will return |
| a value that is *not* unique. |
| |
| Again, we provide mechanism, not policy. |
| |
| 9 - Can a counter be incremented/decremented by an arbitrary amount? |
| |
| Resolved: No. Only by 1. (Or 0.) |
| |
| 10 - Should append counters wrap on zero and overflow? |
| |
| Resolved: Wrap. [0,2^32-1] |
| |
| 11 - What piece of state owns the atomic counters? |
| |
| Resolved: There is no context state, they must be backed |
| by buffer objects. |
| |
| 12 - Can the atomic counters be shared between contexts? |
| |
| Resolved: Not directly, but they may be shared indirectly by sharing the |
| buffer objects that back them. |
| |
| 13 - Should we be able to write atomic counters to a buffer object? |
| |
| Resolved. Yes. (Note that buffer objects can be shared. |
| The result of updating atomic counters in multiple contexts |
| backed with the same buffer object is undefined.) |
| |
| 14 - If indexing an array of atomic_uints, can the index used diverge |
| in a SIMD implementation? |
| |
| Resolved. No. They must be dynamically uniform, similar |
| to samplers. |
| |
| 15 - Should we provide "append buffer" functionality? |
| |
| Resolved: Yes, but by providing access to atomic counters. |
| This provides the mechanism to do "append buffer" functionality, |
| and more. |
| |
| 16 - What should this extension be called? |
| |
| Resolved: ARB_shader_atomic_counters. It's primarily a shader |
| extension, and it provides atomic_counters. |
| |
| 17 - What happens to shared buffer objects that are updated in |
| more than one context by data-setting commands, including |
| the built-in atomic counter functions? |
| |
| Resolved: They should follow the same rules as other shared |
| buffer objects. (That is, care must be taken when updating |
| atomic counters in one context and using them in another |
| context.) Further, the atomic built-in functions are |
| atomic in a single context, but there is no guarantee that |
| they are atomic across contexts. |
| |
| 18 - Should there be one buffer binding for all counters, or a |
| buffer binding per counter. |
| |
| Resolved. There should be a buffer binding (and offset) |
| per counter. Shaders may store multiple atomic counters in |
| a single buffer binding. |
| |
| 19 - What about simultaneous use of buffer object at two |
| binding points, where one is an atomic counter binding point? |
| |
| Resolved. We are going to be conservative and make |
| such use undefined. |
| |
| 20 - Does atomic_uint type add any value? |
| |
| Resolved. Yes. For a single program text, the opaque |
| atomic_uint is just syntactic sugar. |
| However, for multiple shaders bound to a shader target, |
| only one shader must contain the locations. This would |
| permit an implementation to do fast relinking if |
| a single shader is attached to an existing shader. |
| (And display lists are just fine for optimizing |
| texture loads. [insert silly smiley face]) |
| |
| Also, when we do add api (not yet added) to query active |
| atomic_uints in a shader, this provides additional benefits. |
| |
| 21 - Do we need api to query the atomic counter? |
| |
| Resolved. Earlier drafts had a traditional indexed get, |
| which would be useful for debugging but not high performance. |
| An alternative would be to add a query object to do asynchronos |
| queries. But note, that when these counters are backed by |
| buffer objects, all the GetBufferSubData and/or MapBuffer |
| just works. |
| |
| This draft simply nukes the get. (It is trivial to put it |
| back in with a caveat.) The existing buffer api should |
| be used for high performance client side (cpu) access |
| to atomic counters. |
| |
| 22 - Does AtomicCounter reset to zero: |
| The context default counter state? |
| The value in a buffer object bound to a counter? |
| Both? |
| |
| Resolved. THERE IS NO DEFAULT CONTEXT STATE, only the |
| buffer object bound, if any, is set. |
| |
| 23 - Does a BufferData to a buffer bound to counter set the value of: |
| The buffer object? (Obviously) |
| The context default counter state bound that that buffer? |
| |
| Resolved. THERE IS NO DEFAULT CONTEXT STATE. |
| |
| 24 - Do we want an error (or undefined behavior) that says you |
| can't draw while a mapped buffer is bound to one of these |
| counters? |
| |
| Resolved. Undefined. |
| |
| 25 - Is a atomic_uint an "in" or a "uniform"? |
| |
| Resolved. "atomic_uint" variables are declared as uniforms at global |
| scope. |
| |
| 26 - Can the active atomic counters for one program be stored in more than one |
| buffer object? |
| |
| Resolved. Yes. |
| |
| 27 - Can atomic counters be grouped into blocks similar to uniform blocks? |
| |
| Resolved. No. However, layout qualifiers can be used in individual |
| declarations to identify a specific buffer binding point and offset to |
| use for the counter. |
| |
| 28 - What API should be used to query information about atomic counters? |
| |
| Resolved. GetActiveUniformsiv. Apart from the common type and count |
| queries, UNIFORM_OFFSET can be used to query the offset of an atomic |
| counter, UNIFORM_ARRAY_STRIDE can be used to query the stride in memory |
| of an array of atomic counters (even though it's always four bytes), and |
| UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX can be used to query the index of the |
| active atomic counter buffer associated with the uniform. |
| |
| No GetActiveUniformsiv query is provided to retrieve the binding point |
| associated with an atomic counter uniform. It may be obtained indirectly |
| by UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX and then using |
| GetAtomicCounterBufferiv to query the ATOMIC_COUNTER_BUFFER_BINDING for |
| the returned index. |
| |
| 29 - What API should we provide to query information about buffer object |
| storage needed to back atomic counters? |
| |
| Unresolved. We will provide an API for querying information about |
| "active atomic counter buffers" similar to the API we provide for |
| querying active uniform blocks. Each set of active atomic counter |
| uniforms sharing a single binding point corresponds to an active atomic |
| counter buffer. An application can query the number of active atomic |
| counter buffers via GetProgram. If there are <N> active atomic counter |
| buffers, it can pass the values 0..<N>-1 to the command |
| GetAtomicCounterBufferiv to query properties of each buffer. |
| |
| Consider the following set of active atomic counter uniform declarations |
| in three different shader types in a program: |
| |
| [in vertex] |
| layout(binding = 0, offset = 0) uniform atomic_uint batman; |
| layout(binding = 3, offset = 4) uniform atomic_uint robin; |
| [in geometry] |
| layout(binding = 0, offset = 4) uniform atomic_uint joker; |
| layout(binding = 6, offset = 124) uniform atomic_uint riddler; |
| [in fragment] |
| layout(binding = 7, offset = 0) uniform atomic_uint penguin; |
| |
| In this example, there are four active atomic counter buffers. For the |
| purposes of the GetActiveAtomicCounterBufferiv query, these will be |
| assigned indices 0, 1, 2, 3. If the active atomic counter buffers are |
| sorted by binding point, the atomic counter buffer binding point numbers |
| returned by calling GetActiveAtomicCounterBufferiv with a <pname> of |
| ATOMIC_COUNTER_BUFFER_BINDING, will be 0, 3, 6, and 7, respectively. |
| |
| 30 - The function atomicCounterIncrement() returns the value of the counter |
| prior to incrementing while atomicCounterDecrement() returns the value |
| of the counter *after* decrementing. Is this intentional? |
| |
| Resolved. Yes. One of the intended uses of this programming model is to |
| be able to atomically add or remove records to an array stored in a |
| buffer (via ARB_shader_image_load_store). In this model, we use the |
| atomic counter to indicate the number of records stored in the buffer and |
| expect the value to be initialized to zero. When the first record is |
| added, it gets an index of zero and increments the counter to one. If a |
| later operation wants to remove a record from the end of a buffer with an |
| associated counter value <N>, we would want to decrement to counter to |
| <N>-1, but also return the decremented index of <N>-1, which was the |
| index of the last record in the buffer prior to the decrement. |
| |
| 31 - What alignment requirements apply to the <offset> and <size> parameters |
| of BindBufferRange when binding atomic counter buffers? |
| |
| Resolved. <offset> must be a multiple of four. <size> has no required |
| alignment. However, if <size> is not four-byte aligned, it will not |
| possible to store an atomic counter in the last few bytes of the bound |
| range since the offset of all atomic counters must also be a multiple of |
| four. |
| |
| Revision History |
| |
| Revision 1, wwlk, 2009-09-08 |
| - Working Draft |
| Revision 2, wwlk, 2009-09-08 |
| - updates from feedback |
| Revision 3, wwlk, 2009-09-09 |
| - (9/9/9, yeah yeah yeah) |
| - updates from feedback |
| Revision 4, wwlk, 2009-09-15 |
| - updates from walkthrough |
| - minor typo update (2.9.10 should be 2.9.9) |
| - add extension enables and defines to shader spec |
| - correct function names (add EXT suffix) |
| - rename extension |
| Revision 5, wwlk, 2009-09-15 |
| - Clarify buffer objects |
| - Clarify undersized buffer objects |
| Revision 6, wwlk, 2009-09-16 |
| - Clarify alignment restrictions for buffer object |
| - Update built-in function names and descriptions |
| - Add issue about number of binding points |
| Revision 7, wwlk, 2010-10-17 |
| - Add opaque ucounter |
| - add buffer binding and offset per counter |
| Revision 8, wwlk, 2010-10-28 |
| - make it clear that these use the indexed binding api |
| (ala transform feedback) |
| - remove get |
| (bug 5839, issue 2 in bug, issue 21 in this extension) |
| - remove fragment restriction |
| (bug 5839, issue 5 in bug, issue 2 in this extension) |
| - add issue 4 |
| - add other issues from bug 5839 |
| - Some clarifications from bug 6975 |
| Revision 9, wwlk, 2010-11-30 |
| - added new global qualifier, uniform |
| - clarified no default context state |
| - clarified the action of BindBufferRange |
| - corrected alignment and sizing restrictions |
| - Still to be done - GetActiveUniforms API! |
| Revision 10, wwlk, 2010-12-02 |
| - GetActiveUniforms API |
| - change ucounter -> atomic_uint |
| Revision 11, wwlk, 2010-12-02 |
| - Removed unnecessary AtomicCounterEXT API. |
| (use buffer API) |
| Revision 12, wwlk, 2010-12-03 |
| - Trivial typos |
| Revision 13, wwlk, 2010-12-03 |
| - More trivial typos |
| Revision 14, wwlk, 2010-12-03 |
| - Still more trivial typos |
| Revision 15, wwlk, 2010-12-09 |
| - Still more trivial typos |
| - Clarifications |
| - Additional uniform API - next revision |
| (the obvious additions, but unfortunately |
| extensive. Proofing now.) |
| Revision 16, johnk, 2010-12-17 |
| - Change MAX_ATOMIC_COUNTERS to gl_MaxAtomicCounterBindingsEXT (is that correct?) |
| - Move that statement from the uniform section to the qualifier section. |
| - added integer constants to the layout qualifier grammar |
| - minor grammar and consistency changes going into 4.2 core. |
| Revision 17, Jon Leech, 2010-12-19 |
| - Change extension name to ARB instead of EXT. Remove _EXT |
| suffixes on API since this extension is backwards-compatibility |
| for a core GL 4.2 feature. Probably should remove suffixes on |
| GLSL interface as well. |
| - Fix version number for API spec in section headings. |
| Revision 18, Jon Leech, 2011-01-05 |
| - Fix typos from Bug 7202 |
| Revision 19, wwlk, 2011-04-05 |
| - Uniform API - large rework |
| - Clarify limits |
| - Clarify layouts, binding rules, offset rules |
| - Clarify named uniform blocks |
| - Clarify unnamed uniform blocks |
| Revision 20, wwlk, 2011-04-08 |
| - Clarify named uniform blocks with examples |
| - Make explicit the matching rules for layout (explicit or implicit layout must match) |
| - Added issue 29, do we need both un-named uniform blocks and uniform blocks? |
| - Added issue 30, should the un-named uniform blocks be un-named "", or should |
| they be implicitly named (example, uniform3 for binding to 3) |
| Revision 21, wwlk, 2011-04-08 |
| - Minor change to invalid uniform block example |
| Revision 22, wwlk, 2011-05-05 |
| - Major change |
| uniforms (immutable) |
| Revision 23, wwlk, 2011-05-05 |
| - Fixed hellacious paragraph, related to bug 7458 |
| "Each active uniform variable ... "." (dot) and "[]" ..." |
| Revision 24, Jon Leech, 2011-05-08 |
| - Minor formatting/typo cleanup. Fix name of query in state tables. |
| Remove EXT suffixes from shader constant and function names. |
| Revision 25, pbrown, 2011-06-18 |
| - Add missing entries in the lists of new functions and tokens. |
| - Assigned enumerant values for new tokens. |
| - Minor language clarifications and typo fixes. |
| - Clarify the two different numbering spaces for buffers used for atomic |
| counters. The set of binding points actively referenced by a |
| particular program are called "active atomic counter buffers"; the set |
| of binding points in the context to which buffers are attached query |
| are called "atomic counter bindings" or "binding points". Related |
| APIs and tokens use "buffer" for the former and "binding" for the |
| latter (bug 7723). |
| - Add GetActiveUniformsiv support for atomic counters, allowing the use |
| of UNIFORM_OFFSET and UNIFORM_ARRAY_STRIDE, and adding the query |
| UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX to query the associated active |
| atomic counter buffer. |
| - Restructure the atomic counter buffer binding section to more closely |
| match existing uniform block language; clarify alignment and buffer |
| size requirements (bug 7722). |
| - Remove explicit language about a minimum of 8 atomic counter buffers; |
| already covered by existing queries and state table entries (bug 7722). |
| - Add GetProgram language for ACTIVE_ATOMIC_COUNTER_BUFFERS. |
| - Add missing state table entries for program object state and |
| implementation limits on atomic counter buffer sizes and the combined |
| active buffer count (bug 7722). |
| - Clarify that we intended the non-orthogonality where the increment |
| function returns a value prior to incrementing while the decrement |
| function returns a value after decrementing (bug 7722). |
| - Add a few issues and clarify/update some existing ones. |
| Revision 26, pbrown, 2011-06-20 |
| - Add missing enum assignment for MAX_ATOMIC_COUNTER_BUFFER_BINDINGS. |
| Revision 27, pbrown, 2011-06-23 |
| - Set a minimum value for MAX_ATOMIC_COUNTER_BUFFER_SIZE (bug 7743). |
| - Fix typo in state table. |
| Revision 28, pbrown, 2011-07-27 |
| - Clarify that ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS queries the |
| number of atomic counter variables (bug 7834). |
| - Fix tokens MAX_*_ATOMIC_COUNTER_BUFFERS in the state table (bug 7834). |
| - Fix a couple typos. |
| Revision 29, Jon Leech, 2011-08-05 |
| - Change minimum MAX_ATOMIC_COUNTER_BUFFER_SIZE value to 32 (bug |
| 7855). |
| Revision 30, Jon Leech, 2012-04-12 |
| - Add description of atomic buffer object binding queries in section |
| 6.1.8. Correct typo for GetAtomicCounterBufferiv in state table |
| entries. |
| Revision 31, Jon Leech, 2012-07-30 |
| - Correct typo ATOMIC_COUNTER_ARRAY_STRIDE -> UNIFORM_ARRAY_STRIDE |
| (bug 9346). |