Name

    ARB_shader_storage_buffer_object

Name Strings

    GL_ARB_shader_storage_buffer_object

Contact

    Pat Brown, NVIDIA (pbrown 'at' nvidia.com)

Contributors

    Jeff Bolz, NVIDIA
    Piers Daniell, NVIDIA
    Christophe Riccio, AMD
    Graham Sellers, AMD
    Bruce Merry
    John Kessenich

Notice

    Copyright (c) 2012-2014 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 2012/06/12.

Version

    Last Modified Date:         April 28, 2014
    Revision:                   16

Number

    ARB Extension #137

Dependencies

    OpenGL 4.0 (either core or compatibility profile) is required.

    OpenGL 4.3 or ARB_program_interface_query is required.

    This extension is written against the OpenGL 4.2 (Compatibility Profile)
    Specification.

    This extension interacts with OpenGL 4.3 and ARB_compute_shader.

    This extension interacts with OpenGL 4.3 and ARB_program_interface_query.

    This extension interacts with NV_bindless_texture.

Overview

    This extension provides the ability for OpenGL shaders to perform random
    access reads, writes, and atomic memory operations on variables stored in
    a buffer object.  Application shader code can declare sets of variables
    (referred to as "buffer variables") arranged into interface blocks in a
    manner similar to that done with uniform blocks in OpenGL 3.1.  In both
    cases, the values of the variables declared in a given interface block are
    taken from a buffer object bound to a binding point associated with the
    block.  Buffer objects used in this extension are referred to as "shader
    storage buffers".  

    While the capability provided by this extension is similar to that
    provided by OpenGL 3.1 and ARB_uniform_buffer_object, there are several
    significant differences.  Most importantly, shader code is allowed to
    write to shader storage buffers, while uniform buffers are always
    read-only.  Shader storage buffers have a separate set of binding points,
    with different counts and size limits.  The maximum usable size for shader
    storage buffers is implementation-dependent, but its minimum value is
    substantially larger than the minimum for uniform buffers.  

    The ability to write to buffer objects creates the potential for multiple
    independent shader invocations to read and write the same underlying
    memory.  The same issue exists with the ARB_shader_image_load_store
    extension provided in OpenGL 4.2, which can write to texture objects and
    buffers.  In both cases, the specification makes few guarantees related to
    the relative order of memory reads and writes performed by the shader
    invocations.  For ARB_shader_image_load_store, the OpenGL API and shading
    language do provide some control over memory transactions; those
    mechanisms also affect reads and writes of shader storage buffers.  In the
    OpenGL API, the glMemoryBarrier() call can be used to ensure that certain
    memory operations related to commands issued prior the barrier complete
    before other operations related to commands issued after the barrier.
    Additionally, the shading language provides the memoryBarrier() function
    to control the relative order of memory accesses within individual shader
    invocations and provides various memory qualifiers controlling how the
    memory corresponding to individual variables is accessed.


New Procedures and Functions

    void ShaderStorageBlockBinding(uint program, uint storageBlockIndex, 
                                   uint storageBlockBinding);

New Tokens

    Accepted by the <target> parameters of BindBuffer, BufferData,
    BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, and
    GetBufferPointerv:

        SHADER_STORAGE_BUFFER                           0x90D2

    Accepted by the <pname> parameter of GetIntegerv, GetIntegeri_v,
    GetBooleanv, GetInteger64v, GetFloatv, GetDoublev, GetBooleani_v,
    GetIntegeri_v, GetFloati_v, GetDoublei_v, and GetInteger64i_v:

        SHADER_STORAGE_BUFFER_BINDING                   0x90D3

    Accepted by the <pname> parameter of GetIntegeri_v, GetBooleani_v,
    GetIntegeri_v, GetFloati_v, GetDoublei_v, and GetInteger64i_v:

        SHADER_STORAGE_BUFFER_START                     0x90D4
        SHADER_STORAGE_BUFFER_SIZE                      0x90D5

    Accepted by the <pname> parameter of GetIntegerv, GetBooleanv,
    GetInteger64v, GetFloatv, and GetDoublev:

        MAX_VERTEX_SHADER_STORAGE_BLOCKS                0x90D6
        MAX_GEOMETRY_SHADER_STORAGE_BLOCKS              0x90D7
        MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS          0x90D8
        MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS       0x90D9
        MAX_FRAGMENT_SHADER_STORAGE_BLOCKS              0x90DA
        MAX_COMPUTE_SHADER_STORAGE_BLOCKS               0x90DB
        MAX_COMBINED_SHADER_STORAGE_BLOCKS              0x90DC
        MAX_SHADER_STORAGE_BUFFER_BINDINGS              0x90DD
        MAX_SHADER_STORAGE_BLOCK_SIZE                   0x90DE
        SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT          0x90DF

    Accepted in the <barriers> bitfield in glMemoryBarrier:

        SHADER_STORAGE_BARRIER_BIT                      0x2000        

    Also, add a new alias for the existing token
    MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS:

        MAX_COMBINED_SHADER_OUTPUT_RESOURCES            0x8F39 (alias)

Additions to Chapter 2 of the OpenGL 4.2 (Compatibility Profile) Specification
(OpenGL Operation)

    Modify Section 2.9, Buffer Objects, p. 56

    (Add to Table 2.9, p. 57)

        Target Name             Purpose                 Described in section(s)
        ---------------------   --------------------    ----------------------
        SHADER_STORAGE_BUFFER   read-write storage      2.14.X
                                for shaders

    (modify next-to-last paragraph, p. 58) target must be one of
    ATOMIC_COUNTER_BUFFER, SHADER_STORAGE_BUFFER, TRANSFORM_FEEDBACK_BUFFER,
    UNIFORM_BUFFER. ...


    Modify Section 2.14.7, Uniform Variables, p. 113

    (modify Table 2.16, pp. 122-125)

    Add a new column labeled "Buffer".  Include dots for all the types on
    p. 122 (including BOOL types not supported for "Attrib" and "Xfb").  Add
    dots for the "DOUBLE_MAT*" rows on p. 123.  Add no dots for any image or
    sampler types.  

    In the description of the table (p. 125), add a new sentence:  Types whose
    "Buffer" column are marked may be declared as buffer variables (see
    section 2.14.X).


    Modify unnumbered "Standard Uniform Block Layout" section, p. 132

    (insert a new paragraph at the end of the section, at the bottom of
    p. 133) Shader storage blocks (section 2.14.X) also support the "std140"
    layout qualifier, as well as a "std430" layout qualifier not supported for
    uniform blocks.  When using the "std430" storage layout, shader storage
    blocks will be laid out in buffer storage identically to uniform and
    shader storage blocks using the "std140" layout, except that the base
    alignment of arrays of scalars and vectors in rule (4) and of structures
    in rule (9) are not rounded up a multiple of the base alignment of a vec4.


    Add new section immediately before Section 2.14.8, Subroutine Uniform
    Variables (p. 135)

    2.14.X, Shader Buffer Variables

    Shaders can declare named /buffer variables/, as described in the OpenGL
    Shading Language Specification.  Sets of buffer variables are grouped into
    interface blocks called /shader storage blocks/.  The values of each
    buffer variable in a shader storage block are read from or written to the
    data store of a buffer object bound to the binding point associated with
    the block.  The values of active buffer variables may be changed by
    executing shaders that assign values to them or perform atomic memory
    operations on them, by modifying the contents of the bound buffer object's
    data store with commands such as BufferSubData, by binding a new buffer
    object to the binding point associated with the block, or by changing the
    binding point associated with the block.

    Buffer variables in shader storage blocks are represented in memory in the
    same way as uniforms stored in uniform blocks, as described in the
    "Uniform Buffer Object Storage" subsection of Section 2.14.7.  When a
    program is linked successfully, each active buffer variable is assigned an
    offset relative to the base of the buffer object binding associated with
    its shader storage block.  For buffer variables declared as arrays and
    matrices, strides between array elements or matrix columns or rows will
    also be assigned.  Offsets and strides of buffer variables will be
    assigned in an implementation-dependent manner unless the shader storage
    block is declared using the "std140" or "std430" storage layout
    qualifiers.  For "std140" and "std430" shader storage blocks, offsets will
    be assigned using the method described in the "Standard Uniform Block
    Layout" subsection of Section 2.14.7.  If a program is re-linked, existing
    buffer variable offsets and strides are invalidated, and a new set of
    active variables, offsets, and strides will be generated.

    The total amount of buffer object storage that can be accessed in any
    shader storage block is subject to an implementation-dependent limit. The
    maximum amount of available space, in basic machine units, can be queried
    by calling GetIntegerv with the constant MAX_SHADER_STORAGE_BLOCK_SIZE.
    If the amount of storage required for any shader storage block exceeds
    this limit, a program will fail to link.

    If the number of active shader storage blocks referenced by the shaders in
    a program exceeds implementation-dependent limits, the program will fail
    to link.  The limits for vertex, tessellation control, tessellation
    evaluation, geometry, fragment, and compute shaders can be obtained by
    calling GetIntegerv with pname values of MAX_VERTEX_SHADER_STORAGE_BLOCKS,
    MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,
    MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,
    MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, MAX_FRAGMENT_SHADER_STORAGE_BLOCKS,
    and MAX_COMPUTE_SHADER_STORAGE_BLOCKS, respectively.  Additionally, a
    program will fail to link if the sum of the number of active shader
    storage blocks referenced by each shader stage in a program exceeds the
    value of the implementation-dependent limit
    MAX_COMBINED_SHADER_STORAGE_BLOCKS.  If a shader storage block in a
    program is referenced by multiple shaders, each such reference counts
    separately against this combined limit.

    When a named shader storage block is declared by multiple shaders in a
    program, it must be declared identically in each shader. The buffer
    variables within the block must be declared with the same names, types,
    qualification, and declaration order.  If a program contains multiple
    shaders with different declarations for the same named shader storage
    block, the program will fail to link.

    Regions of buffer objects are bound as storage for shader storage blocks
    by calling one of the commands BindBufferRange or BindBufferBase (see
    section 2.9.1) with target set to SHADER_STORAGE_BUFFER.  In addition to
    the general errors described in section 2.9.1, BindBufferRange will
    generate an INVALID_VALUE error if index is greater than or equal to the
    value of MAX_SHADER_STORAGE_BUFFER_BINDINGS, or if <offset> is not a
    multiple of the implementation-dependent alignment requirement (the value
    of SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT).

    Each of a program's active shader storage blocks has a corresponding
    shader storage buffer object binding point.  When a program object is
    linked, the shader storage buffer object binding point assigned to each of
    its active shader storage blocks is reset to the value specified by the
    corresponding "binding" layout qualifier, if present, or zero otherwise.
    After a program is linked, the command 

      void ShaderStorageBlockBinding(uint program, uint storageBlockIndex, 
                                     uint storageBlockBinding);

    changes the active shader storage block with an assigned index of
    <storageBlockIndex> in program object <program>.  The error INVALID_VALUE
    is generated if <storageBlockIndex> is not an active shader storage block
    index in <program>, or if <storageBlockBinding> is greater than or equal
    to the value of MAX_SHADER_STORAGE_BUFFER_BINDINGS. If successful,
    ShaderStorageBlockBinding specifies that <program> will use the data
    store of the buffer object bound to the binding point
    <storageBlockBinding> to read and write the values of the buffer
    variables in the shader storage block identified by <storageBlockIndex>.

    When executing shaders that access shader storage blocks, the binding
    point corresponding to each active shader storage block must be populated
    with a buffer object with a size no smaller than the minimum required size
    of the shader storage block (the value of BUFFER_SIZE for the appropriate
    SHADER_STORAGE_BUFFER resource).  For binding points populated by
    BindBufferRange, the size in question is the value of the <size> parameter
    or the size of the buffer minus the value of the <offset> parameter,
    whichever is smaller.  If any active shader storage block is not backed by
    a sufficiently large buffer object, the results of shader execution are
    undefined, and may result in GL interruption or termination. Shaders may
    be executed to process the primitives and vertices specified between Begin
    and End, or by vertex array commands (see section 2.8). Shaders may also
    be executed as a result of DrawPixels, Bitmap, or RasterPos* commands.


    Modify Section 2.14.12, Shader Execution (p. 145)

    (add new sub-section before "Shader Inputs", p. 151)

    Shader Storage Buffer Access

    Shaders have the ability to read and write to buffer memory via buffer
    variables in shader storage blocks. The maximum number of shader storage
    blocks available to shaders are the values of the implementation dependent
    constants

    * MAX_VERTEX_SHADER_STORAGE_BLOCKS (for vertex shaders),

    * MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS (for tessellation control
      shaders),

    * MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS (for tessellation evaluation
      shaders),

    * MAX_GEOMETRY_SHADER_STORAGE_BLOCKS (for geometry shaders),

    * MAX_FRAGMENT_SHADER_STORAGE_BLOCKS (for fragment shaders), and 

    * MAX_COMPUTE_SHADER_STORAGE_BLOCKS (for compute shaders).
    
    All active shaders combined cannot use more than the value of
    MAX_COMBINED_SHADER_STORAGE_BLOCKS shader storage blocks. If more than one
    pipeline stage accesses the same shader storage block, each such access
    counts separately against this combined limit.


    (add to the list of bullets in the "Validation" section on p. 153)

    * The sum of the number of active shader storage blocks used by the
      current program objects exceeds the combined limit on the number of
      active shader storage blocks (MAX_COMBINED_SHADER_STORAGE_BLOCKS).
    

    Modify Section 2.14.13, Shader Memory Access (p. 153)

    (modify last paragraph, p. 153) Shaders may perform random-access reads
    and writes to texture or buffer object memory by using built-in image
    load, store, and atomic functions operating on shader image variables, or
    by reading from, assigning to, or performing atomic memory operation on
    shader buffer variables, as described in the OpenGL Shading Language
    Specification. The ability to perform such random-access reads and writes
    in systems that may be highly pipelined results in ordering and
    synchronization issues discussed in the sections below.

    (add to list of MemoryBarrier <barriers> bullets, p. 158)

      * SHADER_STORAGE_BARRIER_BIT:  Memory accesses using shader buffer
        variables issued after the barrier will reflect data written by
        shaders prior to the barrier.  Additionally, assignments to and atomic
        operations performed on shader buffer variables after the barrier will
        not execute until all memory accesses (e.g., loads, stores, texture
        fetches, vertex fetches) initiated prior to the barrier complete.


Additions to Chapter 3 of the OpenGL 4.2 (Compatibility Profile) Specification
(Rasterization)

    Modify Section 3.10.22, Texture Image Loads and Stores (p. 358)

    (modify first paragraph, p. 367) Implementations may support a limited
    combined number of image units, shader storage blocks, and active fragment
    shader outputs (see section 4.2.1).  A link error will be generated if the
    sum of the number of active image uniforms used in all shaders, the number
    of active shader storage blocks, and the number of active fragment shader
    outputs exceeds the implementation-dependent value of
    MAX_COMBINED_SHADER_OUTPUT_RESOURCES.


Additions to Chapter 4 of the OpenGL 4.2 (Compatibility Profile) Specification
(Per-Fragment Operations and the Frame Buffer)

    None.

Additions to Chapter 5 of the OpenGL 4.2 (Compatibility Profile) Specification
(Special Functions)

    None.

Additions to Chapter 6 of the OpenGL 4.2 (Compatibility Profile) Specification
(State and State Requests)

    Modify Secction 6.1.15, Buffer Object Queries (p. 490)

    (add to end of section)

    To query which buffer objects are bound to the array of shader storage
    buffer binding points and will be used as the storage for active shader
    storage blocks, call GetIntegeri_v with <param> set to
    SHADER_STORAGE_BUFFER_BINDING.  <index> must be in the range zero to the
    value of MAX_SHADER_STORAGE_BUFFER_BINDINGS-1.  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>.

    To query the starting offset or size of the range of each buffer object
    binding used for shader storage buffers, call GetInteger64i_v with <param>
    set to SHADER_STORAGE_BUFFER_START or SHADER_STORAGE_BUFFER_SIZE
    respectively.  <index> must be in the range zero to the value of
    MAX_SHADER_STORAGE_BUFFER_BINDINGS-1.  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.


Additions to Appendix A of the OpenGL 4.2 (Compatibility Profile) Specification
(Invariance)

    Modify Section A.1, Repeatability (p. 583)

    (modify last sentence of the first paragraph, p. 583) ...  This
    repeatability requirement doesn't apply when using shaders containing side
    effects (image stores, image atomic operations, atomic counter operations,
    buffer variable stores, buffer variable atomic operations), because these
    memory operations are not guaranteed to be processed in a defined order.

    Modify Section A.3, Invariance (p. 584)

    (modify first sentence of the paragraph after Rule 5, p. 586) If a
    sequence of GL commands specifies primitives to be rendered with shaders
    containing side effects (image stores, image atomic operations, atomic
    counter operations, buffer variable stores, buffer variable atomic
    operations), invariance rules are relaxed.  ...

    (modify first paragraph, p. 587) When any sequence of GL commands triggers
    shader invocations that perform image stores, image atomic operations,
    atomic counter operations, buffer variable stores, or buffer variable
    atomic operations and subsequent GL commands read the memory written by
    those shader invocations, these operations must be explicitly
    synchronized.  For more details, see Section 2.14.X, Shader Memory Access.


Additions to Appendix D of the OpenGL 4.2 (Compatibility Profile) Specification
(Shared Objects and Multiple Contexts)

    Modify Section D.3, Propagating State Changes, p. 611

    (modify second bullet, p. 612)

    * Rendering commands that trigger shader invocations, where the shader
      performs image stores, image atomic operations, atomic counter
      operations, buffer variable stores, or buffer variable atomic
      operations.

Additions to the OpenGL Shading Language 4.20 Specification

    Including the following line in a shader can be used to control the
    language features described in this extension:

      #extension GL_ARB_shader_storage_buffer_object : <behavior>

    where <behavior> is as specified in section 3.3.

    New preprocessor #defines are added to the OpenGL Shading Language:

      #define GL_ARB_shader_storage_buffer_object       1


    Modify Section 3.6, Keywords (p. 15)

    (add to list of keywords)

    buffer


    Modify Section 4.1.9, Arrays (p. 29)

    (modify first paragraph of the section, p. 29, adding an exception
     allowing general indexing of the last array of a shader storage block)
     ... Except for the last declared member of a shader storage block
     (section 4.3.X), the size of an array must be declared before it is
     indexed with anything other than an integral constant expression.  The
     size of an array must be declared before passing it as an argument to a
     function. ...

    (modify last paragraph, p. 30) ...  This returns a type int.  If an array
    has been explicitly sized, the value returned by the length method is
    a constant expression.  If an array has not been explicitly
    sized and is not the last declared member of a shader storage block, the
    value returned by the length method is not a constant
    expression and will be determined when a program is linked.  If an array
    has not been explicitly sized and is the last declared member of a shader
    storage block, the value returned will not be constant expression and
    will be determined at run time based on
    the size of the buffer object providing storage for the block.  For such
    arrays, the value returned by the length method will be undefined if the
    array is contained in an array of shader storage blocks that is indexed
    with a non-constant expression less than zero or greater than or equal 
    to the number of blocks in the array.

    (add a new paragraph to end of the section, at the bottom of p. 30) In a
    shader storage block, the last member may be declared without an explicit
    size.  In this case, the effective array size is inferred at run-time from
    the size of the data store backing the interface block.  Such unsized
    arrays may be indexed with general integer expressions, but may not be
    passed as an argument to a function or indexed with a negative constant
    expression.


    Modify Section 4.3, Storage Qualifiers (p. 36)

      Storage
      Qualifier   Meaning
      ----------  ---------------------------------------------------
      buffer      value is stored in a buffer object, and can be read
                  or written by shader invocations and the OpenGL API


    Modify Section 4.3.3, Constant Expressions (p. 38)

    (modify first bullet, p. 39, clarifying that the length() method only
     produces constant expressions on explicitly sized objects, since we now
     allow it on implicitly sized or unsized arrays)

    * valid use of the length() method on an explicitly sized object, whether
      or not the object itself is constant (implicitly sized or unsized arrays
      do not return a constant expression)


    Insert after Section 4.3.5, Uniform (p. 40)

    4.3.X, Buffer Variables

    The <buffer> qualifier is used to declare global variables whose values
    are stored in the data store of a buffer object bound through the OpenGL
    API.  Buffer variables can be read and written, with the underlying
    storage shared among all active shader invocations.  Buffer variable
    memory reads and writes within a single shader invocation are processed in
    order.  However, the order of reads and writes performed in one invocation
    relative to those performed by another invocation is largely undefined.
    Buffer variables may be qualified with memory qualifiers affecting how the
    underlying memory is accessed, as described in Section 4.10.

    The "buffer" qualifier can be used with any of the basic data types, or
    when declaring a variable whose type is a structure, or an array of any of
    these.

    Buffer variables may only be declared inside interface blocks (Section
    4.3.7), which are referred to as shader storage blocks.  It is illegal to
    declare buffer variables at global scope (outside a block).  Buffer 
    variables cannot have initializers.

    There are implementation-dependent limits on the number of the shader
    storage blocks used for each type of shader, the combined number of shader
    storage blocks used for a program, and the amount of storage required by
    each individual shader storage block.  If any of these limits are
    exceeded, it will cause a compile-time or link-time error.

    If multiple shaders are linked together, then they will share a single
    global buffer variable name space, including within a language as well as
    across languages.  Hence, the types of buffer variables with the same name
    must match across all shaders that are linked into a single program.
  

    Modify Section 4.3.7, Interface Blocks (p. 43)

    (modify first paragraph) Input, output, uniform, and buffer variable
    declarations can be grouped into named interface blocks ...  A uniform
    block is backed by the application with a buffer object.  A block of
    buffer variables, called a shader storage block, is also backed by the
    application with a buffer object. ...

    (modify second paragraph) An interface block is started by an in, out,
    uniform, or buffer keyword, followed by ...

    (add "buffer" to the grammar rules)

      interface-qualifier:
        in
        out
        uniform
        buffer

    (modify first paragraph, p. 44) Types and declarators are the same as for
    other input, output, uniform, and buffer variable declarations...

    (modify third paragraph, p. 44) If no optional qualifier is used in a
    member-declaration, the qualification of the variable is just in, out,
    uniform, or buffer as determined by <interface-qualifier>.  ...  Input
    variables, output variables, uniform variables, and buffer variables can
    only be in in blocks, out blocks, uniform blocks, and shader storage
    blocks, respectively.  Repeating the "in", "out", "uniform", or "buffer"
    interface qualifier for a member's storage qualifier is optional. ...

    (modify fourth paragraph, p. 44) For this section, define an interface to
    be one of these:

      * All the uniforms of a program. This spans all compilation units linked
        together within one program.

      * All the buffer variables of a program.

      * The boundary between adjacent programmable pipeline stages: ...

    (modify next-to-last paragraph, p. 45) For uniform or shader storage
    blocks declared as an array, each individual array element corresponds to
    a separate buffer object bind range, backing one instance of the block. As
    the array size indicates the number of buffer objects needed, uniform and
    shader storage block array declarations must specify an array size.  A
    uniform or shader storage block array can only be indexed with a
    dynamically uniform integral expression, otherwise results are undefined.

    (modify last paragraph of the section, p. 46) There are
    implementation-dependent limits on the number of uniform blocks and the
    number of shader storage blocks that can be used per stage.  If either
    limit is exceeded, it will cause a link error.


    Modify Section 4.4.1.2, Geometry Shader Inputs (p. 49)

    (modify example at the top of p. 51, since it's now legal to take the
     length of implicitly sized arrays)

      // code sequence within one shader...
      in vec4 Color1[];  // legal, size still unknown
      in vec4 Color2[2]; // legal, size is 2
      in vec4 Color3[3]; // illegal, input sizes are inconsistent
      layout(lines) in;  // legal for Color2, input size is 2, matching Color2
      in vec4 Color4[3]; // illegal, contradicts layout of lines
      layout(lines) in;  // legal, matches other layout() declaration
      layout(triangles) in; // illegal, does not match earlier layout() 
                            // declaration  


    Modify Section 4.4.3, Uniform Block Layout Qualifiers (p. 57).  Rename
    section title to "Uniform and Shader Storage Block Layout Qualifiers".

    (modify first paragraph) Layout qualifiers can be used for uniform and
    shader storage blocks, but not for non-block uniform declarations. The
    layout qualifier identifiers for uniform and shader storage blocks are

      layout-qualifier-id
        shared
        packed
        std140
        std430
        row_major
        column_major
        binding = integer-constant

    (modify last paragraph, p. 57) Uniform and shader storage block layout
    qualifiers can be declared for global scope, on a single uniform or shader
    storage block, or on a single block member declaration.

    (modify first paragraph, p. 58) Default layouts are established (except
    for binding) at global scope for uniform blocks as

      layout(layout-qualifier-id-list) uniform;

    and for shader storage blocks as

      layout(layout-qualifier-id-list) buffer;

    ... The result becomes the new default qualification scoped to subsequent 
    uniform or shader storage block definitions.

    (modify third paragraph, p. 58) The initial state of compilation is as if
    the following were declared:  

      layout(shared, column_major) uniform;
      layout(shared, column_major) buffer;

    (modify fourth paragraph, p. 58) Uniform and shader storage blocks can be
    declared with optional layout qualifiers, and so can their individual
    member declarations. Such block layout qualification is scoped only to the
    content of the block. As with global layout declarations, block layout
    qualification first inherits from the current default qualification and
    then overrides it. Similarly, individual member layout qualification is
    scoped just to the member declaration, and inherits from and overrides the
    block's qualification.

    (modify the fifth paragraph, p. 58) The shared qualifier overrides only
    the std140, std430, and packed qualifiers; other qualifiers are
    inherited. The compiler/linker will ensure that multiple programs and
    programmable stages containing this definition will share the same memory
    layout for this block, as long as all arrays are declared with explicit
    sizes and all matrices have matching row_major and/or column_major
    qualifications (which may come from a declaration outside the block
    definition). ...

    (modify sixth paragraph, p. 58) The packed qualfier overrides only std140,
    std430, and shared; other qualifiers are inherited.  ... Attempts to share
    a packed uniform or shader storage block across programs or stages will
    generally fail. ...

    (modify seventh paragraph, p. 58) The std140 and std430 qualifiers
    override only the packed, shared, std140, and std430 qualifiers; other
    qualifiers are inherited.  The std430 qualifier is supported only for
    shader storage blocks; a shader using the std430 qualifier on a uniform
    block will fail to compile.  ...

    (modify eight paragraph, p. 58)  Layout qualifiers on member declarations
    cannot use the shared, packed, std140, or std430 qualifiers. ...

    (modify last paragraph, p. 58) The <binding> identifier specifies the
    buffer binding point corresponding to the uniform or shader storage block,
    which will be used to obtain the values of the member variables of the
    block. It is an error to specify the binding identifier for the global
    scope or for block member declarations. Any uniform or shader storage
    block declared without a binding identifier is initially assigned to block
    binding point zero.  After a program is linked, the binding points used
    for uniform and shader storage blocks declared with or without a binding
    identifier can be updated by the OpenGL API.

    (modify second paragraph, p. 59) If the <binding> identifier is used with
    a uniform or shader storage block instanced as an array then the first
    element of the array takes the specified block binding and each subsequent
    element takes the next consecutive block binding point.

    (modify third paragraph, p. 59) If the binding point for any uniform or
    shader storage block instance is less than zero or greater than or equal
    to the implementation-dependent maximum number of bindings for the block
    type (uniform or shader storage), a compilation error will occur.  When
    the binding identifier is used with a uniform or shader storage block
    instanced as an array of size <N>, all elements of the array from
    <binding> through <binding>+<N>-1 must be within this range.


    Modify Section 4.10, Memory Qualifiers (p. 71)

    (modify first paragraph of section, p. 71, removing the "Only" from "Only
    variables") Variables declared as image types (the basic opaque types with
    "image" in their keyword) can be qualified with a memory qualifier.

    (add to the end of the third paragraph, p. 73) ...  It is an error to
    qualify an image variable with both "readonly" and "writeonly".

    (insert after third paragraph, p. 73) The memory qualifiers "coherent",
    "volatile", "restrict", "readonly", and "writeonly" may be used in the
    declaration of buffer variables (i.e., members of shader storage blocks).
    When a buffer variable is declared with a memory qualifier, the behavior
    specified for memory accesses involving image variables described above
    applies identically to memory accesses involving that buffer variable.  It
    is an error to assign to a buffer variable qualified with "readonly" or to
    read from a buffer variable qualified with "writeonly".

    Additionally, memory qualifiers may also be used in the declaration of
    shader storage blocks.  When a block declaration is qualified with a
    memory qualifier, it is as if all of its members were declared with the
    same memory qualifier.  For example, the block declaration

      coherent buffer Block {
        readonly vec4 member1;
        vec4 member2;
      };

    is equivalent to

      buffer Block {
        coherent readonly vec4 member1;
        coherent vec4 member2;
      };

    Memory qualifiers are only supported in the declarations of image
    variables, buffer variables, and shader storage blocks; it is an error to
    use such qualifiers in any other declaration.


    Modify Section 5.5, Vector and Scalar Components and Length, p. 79

    (modify last paragraph of section, p. 81)  ... The type returned by
    .length() on a vector is int, and the value returned is considered a
    constant expression.


    Modify Section 5.6, Matrix Components, p. 81

    (modify last paragraph of section, p. 81) ... The type returned by
    .length() on a matrix is int, and the value returned is considered a
    constant expression.


    Modify Section 5.9, Expressions, p. 83

    (insert after 4th bullet of section, p. 83, correcting the oversight that
     .length() can also be used on vectors and matrices)

      * an expression of vector or matrix type with the length method applied


    Insert new section after Section 8.10, Atomic Counter Functions (p. 149)

    8.X  Atomic Memory Functions

    Atomic memory functions perform atomic operations on an individual signed
    or unsigned integer found in buffer object or shared variable storage.
    All of the atomic memory operations read a value from memory, compute a
    new value using one of the operations described below, write the new value
    to memory, and return the original value read.  The contents of the memory
    being updated by the atomic operation are guaranteed not to be modified by
    any other assignment or atomic memory function in any shader invocation
    between the time the original value is read and the time the new value is
    written.

    Atomic memory functions are supported only for a limited set of variables.
    A shader will fail to compile if the value passed to the <mem> argument of
    an atomic memory function does not correspond to a buffer or shared
    variable.  It is acceptable to pass an element of an array or a single
    component of a vector to the <mem> argument of an atomic memory function,
    as long as the underlying array or vector is a buffer or shared variable.

    Functions:

        uint atomicAdd(inout uint mem, uint data);
        int atomicAdd(inout int mem, int data);

          Computes a new value by adding the value of <data> to the contents
          of <mem>.

        uint atomicMin(inout uint mem, uint data);
        int atomicMin(inout int mem, int data);

          Computes a new value by taking the minimum of the value of <data>
          and the contents of <mem>.

        uint atomicMax(inout uint mem, uint data);
        int atomicMax(inout int mem, int data);

          Computes a new value by taking the maximum of the value of <data>
          and the contents of <mem>.

        uint atomicAnd(inout uint mem, uint data);
        int atomicAnd(inout int mem, int data);

          Computes a new value by performing a bit-wise and of the value of
          <data> and the contents of <mem>.

        uint atomicOr(inout uint mem, uint data);
        int atomicOr(inout int mem, int data);

          Computes a new value by performing a bit-wise or of the value of
          <data> and the contents of <mem>.

        uint atomicXor(inout uint mem, uint data);
        int atomicXor(inout int mem, int data);

          Computes a new value by performing a bit-wise exclusive or of the
          value of <data> and the contents of <mem>.

        uint atomicExchange(inout uint mem, uint data);
        int atomicExchange(inout int mem, int data);

          Computes a new value by simply copying the value of <data>.

        uint atomicCompSwap(inout uint mem, uint compare, uint data);
        int atomicCompSwap(inout int mem, int compare, int data);

          Compares the value of <compare> and the contents of <mem>.  If the
          values are equal, the new value is given by <data>; otherwise, it is
          taken from the original contents of <mem>.

Additions to the AGL/EGL/GLX/WGL Specifications

    None

GLX Protocol

    TBD

Dependencies on OpenGL 4.3 and ARB_compute_shader:

    If OpenGL 4.3 and ARB_compute_shader are not supported, any references to
    uses of shader storage blocks in compute shaders, as well as the enumerant
    MAX_COMPUTE_SHADER_STORAGE_BLOCKS, should be removed.  Additionally, this
    extension provides GLSL atomic memory functions that can be used with
    buffer variables (from this extension) and shared variables (from
    ARB_compute_shader).  If ARB_compute_shader is not supported, references
    to shared variables should be removed from the language describing these
    functions.

    Note that no "#extension" directive is necessary to use atomic memory
    functions on shared variables in compute shaders.

Dependencies on OpenGL 4.3 and ARB_program_interface_query

    If OpenGL 4.3 and ARB_program_interface_query are not supported, it
    wouldn't be possible to use GLSL query APIs to enumerate active buffer
    variables and shader storage blocks used by a program.  We require that
    OpenGL 4.3 or ARB_program_interface_query be supported; this shouldn't be
    a problem for any implementations of this extension.

Dependencies on NV_bindless_texture

    If NV_bindless_texture is supported (and enabled via the #extension
    directive), the restriction that image and sampler variables must be
    uniform variables not in blocks is lifted.  In this case, image and
    sampler variables may be members in shader storage blocks.

    If an image variable is declared as a member of a shader storage block,
    the memory qualifiers on such variable declarations apply to the memory
    holding the block member and *not* the memory referenced by the image.  If
    it is necessary to apply a memory qualifier to the memory referenced by an
    image variable found inside a shader storage block, it's possible to embed
    the image variable declaration in a sturcture and then embed the structure
    in a block.  In the following example:

      struct S {
        readonly image2D x;
      };
      buffer Block {
        S m;
      };

    "readonly" is considered to apply to the memory pointed to by the image
    variable <x>.  In this example:

      buffer Block {
        readonly image2D m;
      }

     "readonly" is considered to apply to the memory holding the image handle.
     It would be illegal to write to <m>, but it would be legal to write to
     the texture memory pointed to by <m> (i.e., you can pass <m> to
     imageStore).

Errors

    INVALID_VALUE is generated by BindBufferRange if <target> is
    SHADER_STORAGE_BUFFER and <index> is greater than or equal to the value of
    MAX_SHADER_STORAGE_BUFFER_BINDINGS.

    INVALID_VALUE is generated by BindBufferRange if <target> is
    SHADER_STORAGE_BUFFER and <offset> is not a multiple of the value of
    SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT.

    INVALID_VALUE is generated by ShaderStorageBlockBinding if
    <storageBlockIndex> is not an active shader storage block index of
    <program>.

    INVALID_VALUE is generated by ShaderStorageBlockBinding if
    <storageBlockBinding> is is greater than or equal to the value of
    MAX_SHADER_STORAGE_BUFFER_BINDINGS.

New State

    Add new table, labeled "Shader Storage Buffer State", after Table 6.58
    (Atomic Counter State), p. 562:

                                                             Initial
    Get Value                         Type  Get Command      Value    Description                Sec.
    -----------------------           ----  -----------      -------  ------------------------   -----
    SHADER_STORAGE_BUFFER_BINDING     Z+    GetIntegerv      0        Current value of generic   2.14.X
                                                                      shader storage buffer
                                                                      binding
    SHADER_STORAGE_BUFFER_BINDING     n*Z+  GetIntegeri_v    0        Buffer object bound        2.14.X
                                                                      to each shader storage
                                                                      buffer binding point
    SHADER_STORAGE_BUFFER_START       n*Z+  GetInteger64i_v  0        Start offset of            2.14.X
                                                                      binding range for each
                                                                      shader storage buffer
    SHADER_STORAGE_BUFFER_SIZE        n*Z+  GetInteger64i_v  0        Size of binding range for  2.14.X
                                                                      each shader storage buffer

New Implementation Dependent State

    Add to Table 6.66, Implementation Dependent Vertex Shader Limits, p. 570

    Get Value                         Type  Get Command    Minimum Value  Description                Sec. 
    -----------------------           ----  -----------    -------------  -------------------------  -----
    MAX_VERTEX_SHADER_STORAGE_BLOCKS  Z+    GetIntegerv    0              Number of shader storage   2.14.X
                                                                          blocks accessed by a
                                                                          vertex shader

    Add to Table 6.67, Implementation Dependent Tessellation Shader Limits, p. 571

    Get Value                         Type  Get Command    Minimum Value  Description                Sec. 
    -----------------------           ----  -----------    -------------  -------------------------  -----
    MAX_TESS_CONTROL_SHADER_          Z+    GetIntegerv    0              Number of shader storage   2.14.X
      STORAGE_BLOCKS                                                      blocks accessed by a
                                                                          tess. control shader
    MAX_TESS_EVALUATION_SHADER_       Z+    GetIntegerv    0              Number of shader storage   2.14.X
      STORAGE_BLOCKS                                                      blocks accessed by a
                                                                          tess. evaluation shader

    Add to Table 6.68, Implementation Dependent Geometry Shader Limits, p. 572

    Get Value                         Type  Get Command    Minimum Value  Description                Sec. 
    -----------------------           ----  -----------    -------------  -------------------------  -----
    MAX_GEOMETRY_SHADER_STORAGE_      Z+    GetIntegerv    0              Number of shader storage   2.14.X
      BLOCKS                                                              blocks accessed by a
                                                                          geometry shader

    Add to Table 6.69, Implementation Dependent Fragment Shader Limits, p. 573

    Get Value                         Type  Get Command    Minimum Value  Description                Sec. 
    -----------------------           ----  -----------    -------------  -------------------------  -----
    MAX_FRAGMENT_SHADER_STORAGE_      Z+    GetIntegerv    8              Number of shader storage   2.14.X
      BLOCKS                                                              blocks accessed by a
                                                                          fragment shader

    Add to new table in ARB_compute_shader, Implementation Dependent Compute Shader Limits

    Get Value                         Type  Get Command    Minimum Value  Description                Sec. 
    -----------------------           ----  -----------    -------------  -------------------------  -----
    MAX_COMPUTE_SHADER_STORAGE_       Z+    GetIntegerv    8              Number of shader storage   2.14.X
      BLOCKS                                                              blocks accessed by a
                                                                          compute shader

    Add to Table 6.70, Implementation Dependent Aggregate Shader Limits, p. 574

    Get Value                         Type  Get Command    Minimum Value  Description                Sec. 
    -----------------------           ----  -----------    -------------  -------------------------  -----
    MAX_COMBINED_SHADER_STORAGE_      Z+    GetIntegerv    8              Number of shader storage   2.14.X
      BLOCKS                                                              blocks accessed by a
                                                                          program
    MAX_SHADER_STORAGE_BLOCK_SIZE     Z+    GetInteger-    2^24           Maximum size in basic      2.14.X
                                              64v                         machine units of a shader
                                                                          storage block
    SHADER_STORAGE_BUFFER_OFFSET_     Z+    GetIntegerv    256            Minimum required alignment 2.14.X
      ALIGNMENT                                                           for shader storage buffer
                                                                          binding offsets
    MAX_SHADER_STORAGE_BUFFER_        Z+    GetIntegerv    8              Maximum number of shader   2.14.X
      BINDINGS                                                            storage buffer bindings
                                                                          in the context

    Modify Table 6.71, Implementation Dependent Aggregate Shader Limits (cont.), p. 575

    Get Value                         Type  Get Command    Minimum Value  Description                Sec. 
    -----------------------           ----  -----------    -------------  -------------------------  -----
    MAX_COMBINED_SHADER_OUTPUT_       Z+    GetIntegerv    8              limit on active image      3.10.22
      RESOURCES                                                           units, shader storage
                                                                          blocks, and fragment outputs

    (The only change here is a rename of the token formerly called
     MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS.)

Sample Code

    The following example code records a list of fragment (x,y) coordinates
    and colors in rasterized primitives into a buffer object.  Fragment shader
    code would incude:

      #extension GL_ARB_shader_storage_buffer_object : require

      // Use an atomic counter to keep a running count of the number of
      // fragments recorded in the shader storage buffer.
      layout(binding=0, offset=0) uniform atomic_uint fragmentCounter;

      // Keep a uniform with the number of fragments that can be recorded in
      // the buffer.
      uniform uint maxFragmentCount;

      // Structure with the per-fragment information to record.
      struct FragmentData {
        ivec2 position;
        vec4 color;
      };

      // Shader storage block holding an array <fragments> declared without
      // a fixed size.  Application code should determine how many fragments
      // it wants to record and allocate a buffer appropriately.  With the 
      // "std140" layout, each FragmentData record will take 32B.  With other
      // layouts, the stride of the array is implementation-dependent.  The
      // "binding=2" layout qualifier says that the block <Fragments> should
      // be associated with shader storage buffer binding point #2.
      layout(std140, binding=2) buffer Fragments {
        FragmentData fragments[];
      };

      in vec4 color;

      void main()
      {
        uint fragmentNumber = atomicCounterIncrement(fragmentCounter);
        if (fragmentNumber < maxFragmentCount) {
          fragments[fragmentNumber].position = ivec2(gl_FragCoord.xy);
          fragments[fragmentNumber].color    = color;
        }
      }

    In application code

      #define NFRAGMENTS        100000
      #define FRAGMENT_SIZE     32  // known due to "std140" usage

      GLuint fragmentBuffer, counterBuffer;

      // Generate, bind, and specify the data store to hold fragments.  The
      // NULL pointer in BufferData says that the intial buffer contents are
      // undefined.  They will be filled in by the fragment shader code.
      glGenBuffers(1, &fragmentBuffer);
      glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, fragmentBuffer);
      glBufferData(GL_SHADER_STORAGE_BUFFER, NFRAGMENTS*FRAGMENT_SIZE,
                   NULL, GL_DYNAMIC_DRAW);

      // Generate, bind, and specify the data store for the atomic counter.
      glGenBuffers(1, &counterBuffer);
      glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, counterBuffer);
      glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, 
                   GL_DYNAMIC_DRAW);

      // Reset the atomic counter to zero, then draw stuff.  This will record
      // values into the shader storage buffer as fragments are generated.
      GLuint zero = 0;
      glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &zero);
      glUseProgram(program);
      glDrawElements(GL_TRIANGLES, ...);

      // You could inspect the contents with a call such as:
      void *ptr = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
      ...
      glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

      // You could also use the storage buffer contents for vertex pulling.
      // The glMemoryBarrier() command ensures that the data writes to the
      // storage buffer complete prior to vertex pulling.
      glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
      glBindBuffer(GL_ARRAY_BUFFER, fragmentBuffer);
      glVertexAttribIPointer(0, 2, GL_INT, GL_FALSE, FRAGMENT_SIZE, 
                             (void*)0);
      glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, FRAGMENT_SIZE,
                            (void*)16);
      glEnableVertexAttribArray(0);
      glEnableVertexAttribArray(1);
      glDrawArrays(GL_POINTS, ...);

Conformance Tests

    TBD

Issues

    (1) The main goal of this extension is to allow C-style GLSL shader code
        to write to buffer objects without using roundabout hacks like
        creating buffer textures and using shader image loads and stores.
        What other approaches could we take to achieving the same thing?

      RESOLVED:  We are using "shader storage blocks" as an abstraction
      similar to uniform blocks, except that we allow shaders to write to
      "shader storage blocks".  Other options considered include:

      - Use uniform blocks, but with a special layout qualifier (e.g.,
        "writeonly" or "readwrite") that implies different semantics and
        implementation-dependent limits.  This would avoid the need for a new
        storage qualifier in the shading language, and could also avoid adding
        new GL APIs to enumerate active buffer variables and shader storage
        blocks.  However, it would have the disadvantage of shoehorning two
        features, which might be implemented very differently in hardware,
        into a single abstraction.

      - Use C-style pointer syntax as in NV_shader_buffer_store, but treat the
        pointers as referring to a buffer binding rather than a specific GPU
        address.  In this approach, pointers might be required to be uniform.
        (In NV_shader_buffer_store, pointers are just data.  They can be
        passed as uniforms, uniform block members, shader inputs/outputs,
        reconstructed from texture data, or however the application wants to
        pass them.)

    (2) When using shader storage blocks to append records to a buffer, the
        storage is provided by a buffer object.  There doesn't seem to be any
        reason why the shader really needs to know the "length" of the buffer.
        It might therefore want to declare global storage blocks containing
        unsized arrays.  Should we allow this?  If so, how does that interact
        with bounds checking?  What does it mean for the ".length()" method in
        GLSL?  What would happen if you tried to pass such an array as a
        function parameter?  What does it mean for a possible introspection
        API allowing applications to query how big the block needs to be?

      RESOLVED:  We will support shader storage blocks whose last member is an
      unsized array.  For this unsized array, the effective size will be
      determined at run-time from the size of the data store.  Such unsized
      arrays can be indexed with general integer expressions (other than
      negative constant expressions, which are generally forbidden for array
      indexing in GLSL).  The ".length()" method is not supported, nor is
      passing the array as a function argument.

      When using the ARB_program_interface_query extension to enumerate the
      set of active buffer variables, only the first element of arrays (sized
      or unsized) will be enumerated; the array size and offsets for array
      elements other than the first can be determined by querying the
      TOP_LEVEL_ARRAY_SIZE and TOP_LEVEL_ARRAY_STRIDE properties of the buffer
      variable.

      The bounds checking rules for unsized arrays at the end of shader
      storage blocks are the same as for uniform blocks.  If the array is
      accessed using an index pointing at memory beyond the end of the buffer
      object associated with the shader storage blocks, the results are
      undefined and can lead to program termination; see also issue (7).

      Other options considered here included having the shader declare an
      array with a dummy size that's either unrealistically small (1 or 2) or
      unrealistically large, and providing guarantees like:

        - (small) if the last element of the storage block is an array, we
          have defined behavior for indexed accesses off the end of the array,
          as long as the effective offset is contained within the buffer; or

        - (large) if the buffer is too small for the large declared array,
          we have defined behavior for accesses to array elements as long as
          the effective offset is contained within the buffer.

      Note that it wouldn't be possible for the application to determine the
      stride of an array of structures if it were declared with a size of 1.
      For a size of 2 or larger, you could use

            offset(array[1].member) - offset(array[0].member)

      for "shared" layouts at least, but that's not possible if there is no
      "array[1].member".

    (3) Do we allow arrays of shader storage blocks?

      RESOLVED:  Yes; we already allow arrays of uniform blocks, where each
      block instance has an identical layout but is backed by a separate
      buffer object.  It seems like we should do this here for consistency.

      If we had overloaded the existing uniform block APIs (e.g., by applying
      a "readwrite" layout qualifier to uniform blocks), it would be really
      weird if we disallowed arrays of writeable uniform blocks since we
      already allow it for regular (read-only) uniform blocks.

    (4) We have typically provided some sort of "introspection" API where
        application code written with no explicit knowledge of the shaders
        used can discover properties of active variables.  Should we provide
        some here?  If so, any pitfalls?

      RESOLVED:  Yes, we will provide an introspection API, but not as part of
      this extension.  Instead, we require support for the
      ARB_program_interface_query extension, which provides a generic
      mechanism for enumerating the set of active resources for a number of
      "interfaces".  This API includes interfaces for all active shader
      storage blocks as well as all active buffer variables.  Supporting
      enumeration of these new resources was one of the primary motivations
      for the generic ARB_program_interface_query extension; however, that
      extension also added enumeration support for other resources that
      previously had no enumeration API.

      The enumeration of buffer variables follows slightly different rules
      than other variables; in particular, only the first element of members
      declared as arrays are enumerated.  The previous enumeration rules would
      have awful consequences when applied to large arrays of structures in
      shader storage blocks.  For example, the following declaration would
      report 80K active uniforms, starting with "records[0].position" and
      ending with "records[39999].texcoord".  Ouch!

        struct FragmentData {
          vec4 position;
          vec2 texcoord;
        };
        buffer FragmentInfo {
          FragmentData records[40000];
        };

      Regular uniforms and UBOs also have exactly the same problem; the
      primary difference is that current implementation limits on uniform
      storage provide a bounds on how bad this could get.  Even those limits
      might not actually bound the GetActiveUniform* badness, as the spec
      doesn't require a program to link successfully for GetActiveUniform* to
      enumerate uniforms.

    (5) Uniform blocks already have a well-established usage model, for which
        implementations may have dedicated support as well as limits that
        reflect this usage model.  If we were to overload uniform blocks, some
        new uses might not meet this limit and usage model.  Is that a
        problem?

      RESOLVED:  Yes, it could have been a problem if we had overloaded
      uniform blocks.  Implementations may be able to distinguish between
      different types of uniform blocks, which might be implemented
      differently.  One might be able to distinguish based on the size of the
      block as well as the layout qualifier (i.e., "readwrite" might be
      "different" than "readonly").

      Note that if an implementation wants to use the size of the block as a
      factor for determining how the block is accessed, this would introduce a
      new wrinkle into the unsized array use case above.  That might not be a
      huge deal; implementations could make a worst-case assumption and treat
      the effective size of an unsized array as resulting in a maximum-size
      buffer object.

      Note that this consideration applies equally to purely read-only uniform
      storage.  For example, implementations might have a limit on the size of
      uniform blocks that can be accessed by shaders with accelerated hardware
      support.  However, applications might well want to store large data sets
      in buffer objects and access them using random-access reads in shader
      code.  OpenGL 4.2's mechanisms allow data to be pulled from buffer
      objects for vertex shaders using vertex buffers (but only using the
      vertex/instance number as an index).  Data can also be read from a
      texture buffer object via texelFetch(), but that doesn't allow for more
      complex data structures (as noted above in the "write" example above).
      It would be desirable to have a mechanism to allow random access reads
      to "large" buffer objects, even if the implementation and performance
      characterstics are different from regular UBO usage.

      NVIDIA's NV_shader_buffer_load extension fills this need by allowing the
      use of read-only pointers.  That extension has been supported for a
      longer time and is supported on more platforms than the
      NV_shader_buffer_store mentioned above.

    (6) The size of uniform blocks on typical OpenGL 3/4 implementations is
        64KB.  Is this good enough for shader storage buffers, or do we need a
        higher limit?

      RESOLVED:  64K is not good enough; a higher limit is required.  The
      current specification requires implementations to support shader storage
      blocks of at least 2^24 bytes (16MB).  Implementations may support
      larger sizes; the maximum size can be determined by querying
      MAX_SHADER_STORAGE_BLOCK_SIZE.  Because implementations may choose to
      support block sizes >= 2^31 bytes, applications should query the maximum
      size with GetInteger64v().

    (7) How are write accesses to shader storage blocks bounds-checked?

      RESOLVED:  For shader storage blocks, we use the same language found in
      the current OpenGL 4.2 specification for uniform blocks, which
      guarantees no bounds-checking:

        | If any active uniform block is not backed by a sufficiently 
        | large buffer object, the results of shader execution are
        | undefined, and may result in GL interruption or termination.

      It would be desirable for to have a "robustness" feature that provides
      more solid guarantees when accessing outside the bounds of a buffer
      object range.  However, such a feature is not present in the existing
      ARB_robustness specification and is considered orthogonal to the
      functionality being added here.

      If we were to add bounds-checking here or in the future, there may still
      be issues of how bounds-checking would be performed, with multiple use
      cases.  For example, some existing UBO hardware might include hardware
      bounds checking (e.g., return zeroes if accessing off the end of a
      buffer object), but that support might not be extended to cover writes
      or even some other read-only use cases.

      If shader-based bounds checking is required, using code inserted by the
      compiler, we'd have to figure out how to specify it.  In particular,
      we'd have to figure out what granularity the check be done at.  At the
      byte/word level?  Using the first index of the array?

        struct FragmentData {
          vec4 position;
          vec2 texcoord;
        };
        layout(writeonly,binding=2) uniform FragmentInfo {
          FragmentData records[40000];
        };

      In the example above, let's assume that the structure was tightly
      packed, where each element of <records> requires exactly 24 bytes -- 16
      for <position> and 8 for <texcoord>.  If we bound a 32-byte buffer, what
      would happen to reads/writes of records[1].position?  Are reads/writes
      of the x/y components guaranteed to work, with "out-of-bounds" behavior
      on z/w?  What about a 31-byte buffer -- do you read/write partial data
      for records[1].position.y?  What about a 40-byte buffer, which contains
      sufficient storage for all of records[1].position?  Is it guaranteed to
      work, or should we allow implementations to treat accesses to array
      elements out of bounds unless the buffer storage for the entire element
      (including records[1].texcoord in this case).

    (8) Should we provide new "packing" layout qualifiers to augment the
        existing vec4-centric "std140" rule for uniform blocks?

      RESOLVED:  Yes, add a new "std430" layout that provided for tighter
      packing of arrays and structures.  With "std140", the base alignment of
      arrays of scalars and vectors and of structures is always a multiple of
      the base alignment of a vec4 (16B), which means that the stride of an
      array of type "float", "int", or "uint" is 16B instead of 4B.  With
      "std430", such arrays will now be tightly packed.

      Note that in the "std430" packing, arrays of vec3s are still not tightly
      packed; vec3 types still require a 16B alignment as in "std140".

      Note that the "std430" layout is supported only for shader storage
      blocks, and not for uniform blocks.

    (9) Should we allow memory qualifiers ("coherent", "volatile", "restrict",
        "readonly", and "writeonly") to apply to entire shader storage blocks?
        To individual shader storage block members.

      RESOLVED:  We allow memory qualifiers to apply to both shader storage
      blocks and block members (buffer variables).  When a memory qualifier is
      applied to a block declaration, it is considered to apply to all block
      members.

      Note that the extension NV_bindless_texture allows image variables
      (which accept memory qualifiers) to be declared as members of shader
      storage blocks (which also accept memory qualifiers).  This spec adds an
      interaction that says that if this case occurs, the qualifier is
      considered to apply to the image handle, stored in the block, and not
      the memory referenced by the image.

    (10) Should we allow mutable assignments of storage blocks to binding
         points?

      RESOLVED:  Yes, allow them in a manner similar to uniform blocks, since
      OpenGL 4.2's atomic counter buffer feature requires the "binding=N"
      layout in atomic counter declarations and doesn't let you change the
      binding used post-link.  However, we decided to use the same behavior as
      uniform blocks, since the functionality seems so similar.

    (11) Is this extension/feature really needed?  Isn't it possible to do
         something similar in unextended OpenGL 4.2?

      RESOLVED:  Yes, it's possible to achieve similar functionality in
      unextended OpenGL 4.2, but something cleaner is clearly desirable.

      One of the intended uses of OpenGL 4.2's atomic counter feature
      (ARB_shader_atomic_counters) is to allow shader invocations to write
      values generated by shaders into a buffer object, using the atomic
      counters to reserve a unique slot number in an array of outputs.  The
      array itself is accessed by associating the buffer object with a buffer
      texture (ARB_texture_buffer_object) and writing to that texture using
      shader image stores (ARB_shader_image_load_store).  There are a number
      of unfortunate limitations of this approach:

        * Buffers written to using image stores must have a 1- to 4-component
          texture format associated with them.  It's not possible to write out
          an array of structures, though one can use multiple buffers with
          each buffer holding a separate member.

        * The image store function takes a canonical vec4/ivec4/uvec4 value to
          write, regardless of the value stored.  If you're only storing a
          float or a vec2, you need to use a constructor (or a swizzle hack)
          to generate a vec4 in which the extra components are ignored.

        * The image store function takes signed integer coordinates (like the
          texelFetch built-ins).  However, the atomic counter returns an
          unsigned value, and GLSL doesn't support implicit conversions from
          unsigned to signed.

        * Image stores to buffers require the use of a buffer texture, even
          though we don't ever use it as a texture.

      The solution offered here is far more direct -- shader code simply
      declares the format of the buffer object as an interface block and can
      read and write the buffer using normal shader code.

    (12) Are there other extensions providing similar functionality?

      RESOLVED:  Yes.  The NVIDIA extension NV_shader_buffer_store also
      provides a mechanism where buffer objects can be written to with regular
      shader code.  Using that extension, an application is able to query a
      GPU address of a buffer, make that buffer resident, and then access the
      buffer in GLSL code using the queried GPU address as a pointer.
      Applications using NV_shader_buffer_store are required to ensure that
      pointers are valid and no automatic bounds checking is provided.

      This proposed extension is intended to provide GLSL functionality
      similar to what you can get with NV_shader_buffer_store, but without
      general pointers.  Instead, this extension uses bindings, with shader
      code effectively extracting a pointer from the bound buffer.

    (13) Do we need some sort of limit on the combined sum of actively used
         shader storage blocks and other resources, similar to what we had for
         image units in OpenGL 4.2 (MAX_COMBINED_IMAGE_UNITS_
         AND_FRAGMENT_OUTPUTS)?

      RESOLVED:  Yes.  For this extension, we just add shader storage blocks
      to the set of resources that have a combined limit and also create a new
      general token name (MAX_COMBINED_SHADER_OUTPUT_RESOURCES) that is a new
      alias of the old combined limit token.

      Some OpenGL 4.2 and 4.3 implementations need to share a single set of
      internal hardware resources to handle fragment shader outputs, image
      loads and stores (from OpenGL 4.3 and ARB_shader_image_load_store), as
      well as shader storage buffers.  We specify that a link error will occur
      if a program requires more of these internal resources than are
      available.  It is expected that implementations without a need for a
      combined limit will expose a limit greater than or equal to the sum of
      the individual limits for each shader stage and resource type.

      This link error have interaction problems with the
      ARB_separate_shader_objects extension and OpenGL 4.1.  When linking a
      separable program, the linker will not know anything about the usage of
      fragment shader outputs, image units, and shader storage blocks from
      other programs that could be in use at the same time as the program
      being linked.  This makes it seemingly impossible to enforce a combined
      limit.  In practice, this is unlikely to be a problem because the
      implementations needing to enforce this combined limit will support the
      use of image uniforms and shader storage blocks only in fragment and
      compute shaders, and those two stages can't run concurrently.

    (14) Are accesses to shader storage buffers coherent with other accesses
         to the same underlying resource (e.g., image loads/stores, texture
         fetches)?  In the same shader invocation?  In different shader
         invocations?

      RESOLVED:  No; we don't guarantee coherent accesses between shader
      resources of different types.  Spec language corresponding to this issue
      will be proposed outside this extension.

    (15) Do we really need to have a combined limit on the sum of the number
         of active shader storage blocks for each program stage
         (MAX_COMBINED_SHADER_STORAGE_BLOCKS)?

      RESOLVED:  We include such a limit, following the precedent of providing
      a combined limit for each new resource with per-stage limits.  It's not
      clear that this combined limit is needed by any current implementation,
      though we envision an implementation that could have a set of physical
      resources shared between shader stages without providing a full set of
      resources for every stage.

      Some implementations do need a combined limit on the number of fragment
      shader outputs, image uniforms, and shader storage blocks, which is
      handled by the separate MAX_COMBINED_SHADER_OUTPUT_RESOURCES limit
      discussed in issue (13).

    (16) How does an application determine the required buffer object size for
         a shader storage block whose last member is an unsized array?

      RESOLVED:  The ARB_program_interface_query extension includes a property
      BUFFER_SIZE that can be queried for active shader storage blocks.  For
      blocks where all members have known storage requirements, the value of
      this property gives the minimum buffer size required to back the shader
      storage block.

      For shader storage blocks ending in an unsized array, the BUFFER_SIZE
      property returns the minimum buffer size needed to store a single
      element in the unsized array.  The actual storage requirements are a
      function of the number of elements the application wants to store in the
      buffer object.  If an application needs to store N elements in the
      unsized array, the required size can be derived by 

        minimum_size = buffer_size + (N-1) * top_level_stride

      where <buffer_size> is the value of the BUFFER_SIZE property of the
      shader storage block, and <top_level_stride> is the value of the
      TOP_LEVEL_STRIDE property for the unsized array.

      Note that when using the "std140" layout qualifier, applications can
      determine the layout of shader storage blocks without any queries by
      following the layout rules documented in the API specification.

    (17) Should we provide GLSL constants for the implementation-dependent
         limits in this specification (e.g., gl_MaxVertexShaderStorageBlocks)?

      RESOLVED:  No.  It's not clear that these constants are of any real
      value, and they've been specified inconsistently.  In particular, we
      have a bunch of constants for atomic counters, atomic counter buffers,
      and image units/uniforms, but we don't have any limits for uniform
      blocks (ARB_uniform_buffer_object).

    (18) Other than the last member of a shader storage block, should we allow
         block members declared without an explicit size?

      RESOLVED:  Yes, for consistency with the rest of GLSL.  GLSL in general
      allows for arrays declared without a size.  Such arrays are implicitly
      sized by the compiler based on usage.  For example, if a shader includes
      code such as:

         uniform int array[];  // no explicit size
         ...
         expression = array[2] * array[9];  // only references to <array>

      the array is likely to be implicitly sized to 10 elements, since it
      needs to provide storage for array[9].  These implicitly sized arrays
      are also permitted in interface blocks, such as uniform blocks.

      When an array is declared in shader code, there are limitations on how
      the array can be used.  Such arrays may not be passed to functions in
      their entirety or used by the ".length()" method.  Additionally, the
      array may only be indexed with integer constant expressions.

      If the last member of a shader storage block is declared as an array
      without an explicit size, it will be considered to be an explicitly
      unsized array whose size will be inferred at run-time based on the
      provided buffer object.  Such arrays can be indexed with arbitrary
      expressions, but can not be passed as function arguments or be used by
      the ".length()" method.

      Note that when using uniform or shader storage blocks using the "shared"
      or "std140" layout qualifier, shaders should avoid using implicitly
      sized arrays.  In this case, the size will be inferred by the compiler
      based on shader code and might not be computed identically for multiple
      programs using the same block.

    (19) Should the ".length()" method be supported for unsized arrays at the
         end of a shader storage block?  If not, how can shader code determine
         the effective size of an unsized array?

      RESOLVED:  In previous versions of GLSL, the ".length()" method is not
      supported for arrays without a declared size, which means that its value
      is known at compile time.  As a result, the value returned by
      ".length()" is considered a constant expression.

      In this expression, we allow unsized arrays at the end of shader storage
      blocks, and allow the ".length()" method to be used to determine the
      size of such arrays based on the size of the provided buffer object.
      The derived array size can be derived by reversing the process described
      in issue (16):

        array.length() =
          max((buffer_object_size - offset_of_array) / stride_of_array, 0)

      Given that we will support the ".length()" method on unsized arrays, we
      will also support on implicitly sized arrays for consistency.  For such
      arrays, the array size will be determined at link time but will not be
      considered a constant expression.


Revision History

    Revision 16, April 28, 2014 (pbrown)
      - Fix typo in description of MAX_COMBINED_SHADER_STORAGE_BLOCKS.

    Revision 15, September 23, 2013 (Jon Leech)
      - Fix typo ShaderStorageBinding -> ShaderStorageBlockBinding in the
        description of that command (Bug 10715).

    Revision 14, September 6, 2013 (Jon Leech)
      - Fix typo SHADER_STORAGE_BLOCK -> SHADER_STORAGE_BUFFER in the
        description of ShaderStorageBlockBinding (Bug 10795).

    Revision 13, June 1, 2012 (pbrown)
      - Mark issues (8) and (9) as resolved.

    Revision 12, May 31, 2012 (pbrown)
      - Modify spec to allow the "std430" layout qualifier only on shader
        storage blocks, not uniform blocks (bug 8992).

    Revision 11, May 14, 2012 (pbrown)
      - Further clarify the interaction with ARB_compute_shader on atomic
        memory functions; add a clarification that no #extension directive is
        needed to use these functions on shared memory variables in compute
        shaders.

    Revision 10, May 8, 2012 (pbrown)
      - Add explicit language specifying that the value returned by the
       .length() method for unsized arrays is undefined when the array is in
       an array of blocks dereferenced with an out-of-bounds index.

    Revision 9, May 7, 2012 (pbrown)
      - Allow the use of the .length() method on unsized and implicitly sized 
        arrays.  For unsized arrays in shader storage blocks, .length() will
        be computed from the size of the associated buffer object.  For
        implicitly sized arrays, .length() will be determined at link time.

    Revision 8, May 3, 2012 (pbrown)
      - Add a "std430" layout qualifier supporting more tightly packed arrays
        and structures relative to "std140" for issue (8).
      - Add support for memory qualifiers on shader storage block declarations
        for issue (9), also add more explicit language on how these qualifiers
        work on buffer variables.
      - Add spec language making it illegal to use "readonly" and "writeonly"
        memory qualifiers on the same declaration.
      - Remove built-in constants for shader storage block implementation
        limits, as described in issue (17).
      - Mark various spec issues as resolved per the Khronos F2F.
      - Add interaction with NV_bindless_texture, describing the behavior of
        memory qualifiers on image variables inside shader storage blocks.

    Revision 7, April 25, 2012 (pbrown)
      - Remove the GLSL spec language generally disallowing unsized arrays in
        interface blocks (bug 8837).  We have supported implicitly sized
        arrays in blocks in previous versions of GLSL and decided to retain
        backward compatibility.
      - Added a warning in the descript the "shared" layout qualifier
        indicating that such blocks might not be shareable between programs if
        they contain implicitly-sized array members.
      - Minor typo/wording fixes.
      - Fixed token table to describe all the general query functions 
        (e.g., GetIntegerv, GetInteger64) where certain tokens can be used.
      - Update the spec to require dynamically uniform indexing on arrays of
        shader storage blocks.
      - Added issues (18) and (19).

    Revision 6, April 16, 2012 (pbrown)
      - Tentatively add built-in constants for implementation limits on shader
        storage blocks, as well as new issue (17) on the topic.

    Revision 5, April 13, 2012 (pbrown)
      - Add missing #extension and #define built-in documentation for the GLSL
        part of the extension.
      - Add GLSL spec language documenting support for unsized arrays at the
        end of shader storage blocks.
      - Add GLSL spec language generally disallowing unsized arrays in
        interface blocks, including input/output blocks, uniform blocks, and
        shader storage buffers (bug 8837).  This borrows from similar language
        where unsized arrays are not permitted in structures.
      - Extend the tables describing API tokens enumerating GLSL types to
        indicate the set of types that can be used for buffer variables.
      - Add sample code.
      - Update language for several issues, and mark them as resolved.
      - Add an issue indicating how an application can determine the required
        size of a shader storage buffer when using unsized arrays.

    Revision 4, April 12, 2012 (pbrown)
      - Remove the enumeration APIs for buffer variables and shader storage
        blocks; these resources can only be enumerated using the new APIs
        provided by the ARB_program_interface_query extension.
      - Add an interaction with ARB_program_interface_query, and have this
        spec require that extension to ensure that the queries are available.
      - Add a new interaction with ARB_compute_shader; the atomic memory
        functions provided in this extension for buffer variables can also be
        used for shared variables in compute shaders.  Also add new compute 
        shader limit for active storage blocks.
      - Add values for new enumerants in this extension.
      - Fix up the "New Procedures and Functions" and "New Tokens" sections.
      - Assign enumerant values for all tokens.
      - Add a new token MAX_COMBINED_SHADER_OUTPUT_RESOURCES that's an alias
        for MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS.  That combined
        limit now needs to apply to fragment outputs, image units, and shader
        storage blocks.
      - General cleanup of API specification language for shader storage
        blocks.
      - Add documentation of per-stage and combined limits in "Shader Execution"
        spec langauge, and a validation error for exceeding combined limits with
        separate program objects.
      - Add new edits to Appendix A and Appendix D.
      - Add appropriate text to the Dependencies, New Errors, New State, and
        New Implementation-Dependent State sections.
      - Add some new issues; update issue (13).

    Revision 3, January 23, 2012 (pbrown)
      - Add actual spec language in place of the previous "here's our options"
        overview.  Clean up the overview and issues section to reflect the
        general approach chosen in the initial feature discussion.
      - Note:  Lists of new enumerants, functions, state, and errors have not
        been built yet.

    Revision 2, January 3, 2012 (pbrown)
      - Move issues from overview to separate section in preparation for
        further edits; no other changes.

    Revision 1, October 26, 2011 (pbrown)
      - Initial sketch/proposal, containing only an introduction and issues
        list.
