Name

    NV_uniform_buffer_unified_memory

Name Strings

    GL_NV_uniform_buffer_unified_memory

Contact

    Markus Tavenrath, NVIDIA Corporation (matavenrath 'at' nvidia.com)

Contributors

    Markus Tavenrath, NVIDIA
    Christoph Kubisch, NVIDIA

Status

    SHIPPING 

Version

    Last Modified Date: August 28, 2014
    Revision: 1

Number

    OpenGL Extension #459

Dependencies

    Written based on the wording of the OpenGL 4.4 Specification, Core Profile.
    
    This extension interacts with ARB_uniform_buffer_object. 
    
    This extension interacts with NV_vertex_buffer_unified_memory. 

    This extension interacts with NV_shader_buffer_load. 

Overview

    This extension provides a mechanism to specify uniform buffers
    using GPU addresses.

    Binding uniform buffers is one of the most frequent and expensive
    operations in many GL applications, due to the cost of chasing 
    pointers and binding objects described in the overview of 
    NV_shader_buffer_load. The intent of this extension is to enable a 
    way for the application to specify uniform buffer state that alleviates
    the overhead of object binds and driver memory management.

New Procedures and Functions

New Tokens

    Accepted by the <cap> parameter of DisableClientState, 
    EnableClientState, IsEnabled:

        UNIFORM_BUFFER_UNIFIED_NV                      0x936E

    Accepted by the <pname> parameter of BufferAddressRangeNV 
    and the <value> parameter of GetIntegerui64i_vNV: 

        UNIFORM_BUFFER_ADDRESS_NV                      0x936F

    Accepted by the <target> parameter of GetIntegeri_vNV:    

        UNIFORM_BUFFER_LENGTH_NV                       0x9370


Additions to Chapter 7 of the OpenGL 4.4 (Core) Specification (Programs and Shaders)

    Section 7.6.3 Uniform Buffer Object Bindings (p. 132)
    
    Add to second paragraph:
    
    If UNIFORM_BUFFER_UNIFIED_NV is enabled these bindings are overridden
    by the bindings specified by the command 

    void BufferAddressRangeNV(enum pname, uint index, uint64EXT address,
                                   sizeiptr length);

    where <pname> is UNIFORM_BUFFER_ADDRESS_NV and <index> identifies 
    the uniform buffer binding whose address is being specified. 
    
    <address> specifies the GPU address from which arrays will be sourced,
    and addresses beyond and including (<address> + <length>) will return 
    undefined values. If the address range of the used uniform buffer
    does not belong to a buffer object that is resident at the time of 
    the Draw or Dispatch, undefined results, possibly 
    including program termination, may occur.


Additions to the AGL/EGL/GLX/WGL Specifications

    None.

Errors

    The error INVALID_VALUE is generated by BufferAddressRange if <length>
    is negative.

    The error INVALID_VALUE is generated by BufferAddressRange if <pname>
    is UNIFORM_BUFFER_UNIFIED_NV and <index> is equal or greater than
    MAX_UNIFORM_BUFFER_BINDINGS.

    The error INVALID_VALUE is generated by BufferAddressRange if <address>
    is not aligned to UNIFORM_BUFFER_OFFSET_ALIGNMENT.

    New State

    Add to Table 23.49  p. 574 (Uniform Buffer Binding State)

    Get Value                            Type    Get Command     Initial Value   Sec     Attribute
    ---------                            ----    -----------     -------------   ---     ---------
    UNIFORM_BUFFER_UNIFIED_NV             B      IsEnabled           FALSE       7.6.3   none
    UNIFORM_BUFFER_ADDRESS_NV      MAX_UBO*Z64+  GetIntegerui64i_vNV   0         7.6.3   none
    UNIFORM_BUFFER_LENGTH_NV       MAX_UBO*Z+    GetIntegeri_v         0         7.6.3   none

Dependencies on ARB_uniform_buffer_object:

    This extension relies on the availability of uniform buffer objects.

Dependencies on NV_vertex_buffer_unified_memory:

    This extension relies on the mechanisms to provide buffer addresses
    that NV_vertex_buffer_unified_memory provides, but does not
    rely on other changes.
    
Dependencies on NV_shader_buffer_load:

    This extension relies on the mechanisms to get addresses and make
    buffers resident that NV_shader_buffer_load provides, but does not
    rely on either the LOAD instruction or the changes to the Shading 
    Language.

Examples

    In a bindless driven pipeline, high frequency bindings such
    as vertex buffers and uniform buffers can now be achieved
    efficiently.
    
    // initialization of UBOs
    
    GenBuffers(3, ubos);
    GLuint64 uboAddrs[3];

    for (i = 0; i < 3; ++i) {
        BindBuffer(UNIFORM_BUFFER, ubos[i]);
        BufferStorage(UNIFORM_BUFFER, uboSizes[i], uboData[i], DYNAMIC_STORAGE_BIT);
    }
    
    // example rendering loop
    // vertex format / attrib binding setup, data transfers...
    
    
    // enable buffer unified memory usage,
    // which globally overrides all bindings via BufferAddressRange
    
    // for this extension
    EnableClientState(UNIFORM_BUFFER_UNIFIED_NV);
    // for NV_vertex_buffer_unified_memory
    EnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV);
    
    // unextended: 
    // BindBufferRange(UNIFORM_BUFFER, 0, ubos[0], 0, sizeof(View));
        
    BufferAddressRangeNV(UNIFORM_BUFFER_ADDRESS_NV, 0, uboAddrs[0], sizeof(View));
    
    for (object in scene) {
    
      if (object.vbo != lastvbo){
        // unextended: 
        // BindVertexBuffer(0, object.vbo, 0, sizeof(Vertex));
        
        // from NV_vertex_buffer_unified_memory
        BufferAddressRangeNV(VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, object.vboAddr, object.numVertices * sizeof(Vertex));
      }
      
      if (object.material != lastmaterial){
        // unextended: BindBufferRange(UNIFORM_BUFFER, 1, ubos[1], sizeof(Material) * object.material, sizeof(Material));
        
        BufferAddressRangeNV(UNIFORM_BUFFER_ADDRESS_NV, 1, uboAddrs[1] + sizeof(Material) * object.material, sizeof(Material));
      }
      
      if (object.node != lastnode){
        // unextended: BindBufferRange(UNIFORM_BUFFER, 2, ubos[2], sizeof(Node) * object.node, sizeof(Node));
        
        BufferAddressRangeNV(UNIFORM_BUFFER_ADDRESS_NV, 2, uboAddrs[2] + sizeof(Node) * object.node, sizeof(Node));
      }
      
      MultiDrawArrays(..)
    }
    
    
Issues


Revision History

    Rev.    Date    Author      Changes
    ----  --------  --------    -----------------------------------------
     1              ckubisch    Internal revisions.

