| Name |
| |
| NV_vertex_buffer_unified_memory |
| |
| Name Strings |
| |
| GL_NV_vertex_buffer_unified_memory |
| |
| Contact |
| |
| Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) |
| |
| Contributors |
| |
| Mark Kilgard, NVIDIA |
| Jason Sams, NVIDIA |
| Eric Werness, NVIDIA |
| Christoph Kubisch, NVIDIA |
| |
| Status |
| |
| Complete |
| |
| Version |
| |
| Last Modified Date: July 8, 2015 |
| Author Revision: 4 |
| |
| Number |
| |
| 380 |
| |
| Dependencies |
| |
| Written based on the wording of the OpenGL 3.0 specification. |
| |
| This extension interacts with NV_shader_buffer_load. |
| |
| This extension interacts with EXT_direct_state_access. |
| |
| This extension interacts with ARB_compatibility. |
| |
| This extension interacts with OpenGL 3.2 |
| |
| Overview |
| |
| This extension provides a mechanism to specify vertex attrib and |
| element array locations using GPU addresses. |
| |
| Binding vertex 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 vertex attrib state that alleviates |
| the overhead of object binds and driver memory management. |
| |
| New Procedures and Functions |
| |
| void BufferAddressRangeNV(enum pname, uint index, uint64EXT address, |
| sizeiptr length); |
| |
| void VertexFormatNV(int size, enum type, sizei stride); |
| void NormalFormatNV(enum type, sizei stride); |
| void ColorFormatNV(int size, enum type, sizei stride); |
| void IndexFormatNV(enum type, sizei stride); |
| void TexCoordFormatNV(int size, enum type, sizei stride); |
| void EdgeFlagFormatNV(sizei stride); |
| void SecondaryColorFormatNV(int size, enum type, sizei stride); |
| void FogCoordFormatNV(enum type, sizei stride); |
| void VertexAttribFormatNV(uint index, int size, enum type, |
| boolean normalized, sizei stride); |
| void VertexAttribIFormatNV(uint index, int size, enum type, |
| sizei stride); |
| |
| void GetIntegerui64i_vNV(enum value, uint index, uint64EXT result[]); |
| |
| New Tokens |
| |
| Accepted by the <cap> parameter of DisableClientState, |
| EnableClientState, IsEnabled: |
| |
| VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E |
| ELEMENT_ARRAY_UNIFIED_NV 0x8F1F |
| |
| Accepted by the <pname> parameter of BufferAddressRangeNV |
| and the <value> parameter of GetIntegerui64i_vNV: |
| |
| VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 |
| TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 |
| |
| Accepted by the <pname> parameter of BufferAddressRangeNV |
| and the <value> parameter of GetIntegerui64vNV: |
| |
| VERTEX_ARRAY_ADDRESS_NV 0x8F21 |
| NORMAL_ARRAY_ADDRESS_NV 0x8F22 |
| COLOR_ARRAY_ADDRESS_NV 0x8F23 |
| INDEX_ARRAY_ADDRESS_NV 0x8F24 |
| EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 |
| SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 |
| FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 |
| ELEMENT_ARRAY_ADDRESS_NV 0x8F29 |
| |
| Accepted by the <target> parameter of GetIntegeri_vNV or |
| GetIntegerui64i_vNV: |
| |
| VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A |
| TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F |
| |
| Accepted by the <value> parameter of GetIntegerv or |
| GetIntegerui64vNV: |
| |
| VERTEX_ARRAY_LENGTH_NV 0x8F2B |
| NORMAL_ARRAY_LENGTH_NV 0x8F2C |
| COLOR_ARRAY_LENGTH_NV 0x8F2D |
| INDEX_ARRAY_LENGTH_NV 0x8F2E |
| EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 |
| SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 |
| FOG_COORD_ARRAY_LENGTH_NV 0x8F32 |
| ELEMENT_ARRAY_LENGTH_NV 0x8F33 |
| |
| |
| Additions to Chapter 2 of the OpenGL 3.0 Specification (OpenGL Operation) |
| |
| Add to Section 2.9 (end of p. 29) |
| |
| The commands: |
| |
| void VertexFormatNV(int size, enum type, sizei stride); |
| void NormalFormatNV(enum type, sizei stride); |
| void ColorFormatNV(int size, enum type, sizei stride); |
| void IndexFormatNV(enum type, sizei stride); |
| void TexCoordFormatNV(int size, enum type, sizei stride); |
| void EdgeFlagFormatNV(sizei stride); |
| void SecondaryColorFormatNV(int size, enum type, sizei stride); |
| void FogCoordFormatNV(enum type, sizei stride); |
| void VertexAttribFormatNV(uint index, int size, enum type, boolean normalized, sizei stride); |
| void VertexAttribIFormatNV(uint index, int size, enum type, sizei stride); |
| |
| set the same vertex array format state as the corresponding command |
| where "Format" is changed to "Pointer" (and extension suffixes are |
| dropped or updated appropriately). They do not inspect the current |
| ARRAY_BUFFER binding for any error checks, nor do they modify the |
| pointer state or vertex attribute buffer bindings. The parameters are |
| interpreted as they are in the corresponding functions. |
| |
| Add to Section 2.9.1 (p. 46) |
| |
| While VERTEX_ATTRIB_ARRAY_UNIFIED_NV is enabled, the rendering |
| commands ArrayElement, DrawArrays, DrawElements, DrawRangeElements, |
| MultiDrawArrays, DrawArraysInstanced, and DrawElementsInstanced |
| operate as previously defined, except that data for enabled vertex and |
| attrib arrays are sourced from GPU addresses specified by the command: |
| |
| void BufferAddressRangeNV(enum pname, uint index, uint64EXT address, |
| sizeiptr length); |
| |
| where <pname> is VERTEX_ARRAY_ADDRESS_NV, NORMAL_ARRAY_ADDRESS_NV, |
| COLOR_ARRAY_ADDRESS_NV, INDEX_ARRAY_ADDRESS_NV, |
| EDGE_FLAG_ARRAY_ADDRESS_NV, SECONDARY_COLOR_ARRAY_ADDRESS_NV, |
| or FOG_COORD_ARRAY_ADDRESS_NV and <index> is ignored, or <pname> is |
| TEXTURE_COORD_ARRAY_ADDRESS_NV and <index> is the texture unit, |
| or <pname> is VERTEX_ATTRIB_ARRAY_ADDRESS_NV and <index> identifies |
| the generic vertex attribute 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 an enabled vertex attrib |
| does not belong to a buffer object that is resident at the time of |
| the Draw, undefined results, possibly including program termination, |
| may occur. |
| |
| It is not possible to mix vertex or attrib arrays sourced from GPU |
| addresses with either vertex or attrib arrays in client memory or |
| specified with classic VBO bindings. |
| |
| Add to Section 2.9.2 (p. 47) |
| |
| While ELEMENT_ARRAY_UNIFIED_NV is enabled, DrawElements, |
| DrawElementsRange, MultiDrawElements, and DrawElementsInstanced source |
| their indices from the address specified by the command |
| BufferAddressRange where <pname> is ELEMENT_ARRAY_ADDRESS_NV and |
| <index> is zero, added to the <indices> parameter. If a Draw command |
| sources indices beyond and including (<address> + <length>), the index |
| values will be undefined. If the element array address range does not |
| belong to a buffer object that is resident at the time of the Draw, |
| undefined results, possibly including program termination, may occur. |
| |
| Modify the language of NV_shader_buffer_load, replacing |
| "made (in)accessible to the GL via shader buffer loads" with "made |
| (in)accessible to the GL via shader buffer loads or via vertex attrib |
| and/or element array reads". |
| |
| Additions to Chapter 5 of the OpenGL 3.0 Specification (Special Functions) |
| |
| Add to Section 5.4, p. 310 (Display Lists) |
| |
| Add to the list of excluded Vertex Array commands: |
| BufferAddressRangeNV, and all VertexFormat* entry points added by |
| this extension. |
| |
| Additions to Chapter 6 of the OpenGL 3.0 Specification (State and State Requests) |
| |
| Add to Section 6.1.11, p. 314 (Pointer, String, and 64-bit Queries) |
| |
| Indexed 64-bit state variables are queried with the command: |
| |
| void GetIntegerui64i_vNV(enum value, uint index, uint64EXT *data); |
| |
| Legal values of <value> are only those that specify |
| GetIntegerui64i_vNV in the state tables in Chapter 6. |
| |
| 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 VERTEX_ATTRIB_ARRAY_ADDRESS_NV and <index> is greater than the |
| supported number of numbered vertex attribs, or if <pname> is |
| TEXTURE_COORD_ARRAY_ADDRESS_NV and <index> is greater than |
| MAX_TEXTURE_COORDS. |
| |
| New State |
| |
| Update Table 6.9, p. 347 (Vertex Array Object State) |
| |
| Get Value Type Get Command Initial Value Sec Attribute |
| --------- ---- ----------- ------------- --- --------- |
| VERTEX_ATTRIB_ARRAY_UNIFIED_NV B IsEnabled FALSE 2.9 none |
| ELEMENT_ARRAY_UNIFIED_NV B IsEnabled FALSE 2.9 none |
| VERTEX_ATTRIB_ARRAY_ADDRESS_NV 16*Z64+ GetIntegerui64i_vNV 0 2.9 none |
| VERTEX_ATTRIB_ARRAY_LENGTH_NV 16*Z64+ GetIntegeri_v 0 2.9 none |
| VERTEX_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| VERTEX_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| NORMAL_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| NORMAL_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| COLOR_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| COLOR_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| INDEX_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| INDEX_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| TEXTURE_COORD_ARRAY_ADDRESS_NV 8*Z64+ GetIntegerui64i_vNV 0 2.9 none |
| TEXTURE_COORD_ARRAY_LENGTH_NV 8*Z64+ GetIntegeri_v 0 2.9 none |
| EDGE_FLAG_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| EDGE_FLAG_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| SECONDARY_COLOR_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| SECONDARY_COLOR_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| FOG_COORD_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| FOG_COORD_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| ELEMENT_ARRAY_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| ELEMENT_ARRAY_LENGTH_NV Z64+ GetIntegerv 0 2.9 none |
| |
| Interactions with OpenGL 3.2 |
| |
| If the context version is greater or equal version 3.2, querying |
| all *_LENGTH_NV values can be done via GetInteger64v |
| as well as GetInteger64i_v. |
| |
| 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. |
| |
| Dependencies on ARB_compatibility |
| |
| If the context version is greater than 3.0 and does not include |
| ARB_compatibility functionality, then EnableClientState and |
| DisableClientState have been deprecated and removed. This extension |
| adds back those commands, but only requires that they accept the |
| VERTEX_ATTRIB_ARRAY_UNIFIED_NV and ELEMENT_ARRAY_UNIFIED_NV tokens. |
| |
| Examples |
| |
| Creating several interleaved vertex buffers of the same format and |
| switching between them efficiently. |
| |
| GenBuffers(N, vbos); |
| |
| // initialize buffers |
| GLuint64EXT gpuAddrs[N]; |
| for (i = 0; i < N; ++i) { |
| BindBuffer(target, vbos[i]); |
| BufferData(target, vboSizes[i], vboData[i], STATIC_DRAW); |
| |
| // get the address of this buffer and make it resident. |
| GetBufferParameterui64vNV(target, BUFFER_GPU_ADDRESS_NV, &gpuAddrs[i]); |
| MakeBufferResidentNV(target, READ_ONLY); |
| } |
| |
| // setup format - 4-ubyte color, 4-float position |
| EnableClientState(COLOR_ARRAY); |
| EnableClientState(VERTEX_ARRAY); |
| ColorFormatNV(4, UNSIGNED_BYTE, 20); |
| VertexFormatNV(4, FLOAT, 20); |
| // enable vertex address use |
| EnableClientState(VERTEX_ATTRIB_ARRAY_UNIFIED_NV); |
| |
| for (i = 0; i < N; ++i) { |
| // point at buffer i |
| BufferAddressRangeNV(COLOR_ARRAY_ADDRESS_NV, 0, gpuAddrs[i], vboSizes[i]); |
| BufferAddressRangeNV(VERTEX_ARRAY_ADDRESS_NV, 0, gpuAddrs[i]+4, vboSizes[i]-4); |
| |
| DrawArrays(POINTS, 0, vboSizes[i]/20); |
| } |
| |
| |
| Issues |
| |
| 1) Should any of the new commands be compiled into display lists? |
| |
| RESOLVED: NO. It should be straightforward to allow any of the vertex |
| format commands or BufferAddressRangeNV to be compiled, but as long |
| as DrawElements/DrawArrays are not compiled it's not clear that it's |
| useful. It's easier to relax the restriction later than to add a new |
| restriction later if deemed necessary, so they are not compiled. |
| |
| 2) What should be client state and what should be server state? |
| |
| RESOLVED: The new enables should be client state as the client needs |
| to know them to determine whether to read from client vertex arrays. |
| For all the other new state, it's not clear that there's any reason |
| to make them client state. Vertex and attrib array formats remain |
| client state. |
| |
| 3) What about other buffer object uses (PBO, XFB, etc)? |
| |
| RESOLVED: Deferred to separate extensions, if deemed necessary. |
| |
| 4) How should the use of GPU addresses be enabled and how should it |
| interact with classic VBO and client vertex arrays? |
| |
| RESOLVED: A single enable for all vertex attribs (both named and |
| generic), and an enable for element array. This precludes mixing with |
| classic VBO and client vertex arrays, which is not particularly |
| desirable in the first place. Requiring implementations to mix with |
| classic VBO may re-introduce a significant amount of the CPU overhead |
| that this extension is intended to remove. |
| |
| These enables are not problematic for middleware because the enables |
| are per-VAO and middleware libraries can/should use their own VAOs if |
| they need to avoid polluting the application's state. |
| |
| 5) Should ArrayElement be supported? |
| |
| RESOLVED: YES. ArrayElement updates the current vertex state in the |
| context which is not naturally a "GPU" operation, so this may be |
| inefficient, but we should support it anyway. |
| |
| 6) Should there be a separate BindBufferAddressNV and |
| BindBufferAddressIndexedNV? |
| |
| RESOLVED: NO. There's no particularly strong argument in either |
| direction. |
| |
| 7) What happens if an invalid address is fetched? |
| |
| UNRESOLVED: If <address> and <length> correctly specify a range of a |
| resident buffer object, then the implementation *might* support |
| replacing reads from beyond <address> + <length> with undefined |
| results. However, a genuinely invalid address may cause system errors |
| including program termination. A "debug context" could potentially |
| check on each draw call whether all the address ranges are within |
| a resident buffer object. |
| |
| 8) Should this be limited to generic vertex attribs? |
| |
| RESOLVED: NO. Named attribs are deprecated, and it would make the spec |
| and implementation shorter. But the interactions are clean and easy |
| to specify, and many legacy apps use the named attribs. The answer |
| may have to change to "yes" if this extension is ever promoted. |
| |
| 9) Should the <indices> parameter to DrawElements and friends be used? |
| |
| RESOLVED: YES. This is required for MultiDrawElements to be useful |
| and hence to provide an easy porting path for existing applications. |
| This is unfortunately inconsistent with ignoring the vertex attrib |
| pointer state, but the vertex attrib pointers are "latched" state and |
| <indices> is "immediate" state so they're already semantically |
| different. |
| |
| 10) Are there alignment requirements on vertex attrib and element |
| array addresses? |
| |
| RESOLVED: No more so than with existing VBO functionality. The spec has |
| the following vague language about using VBOs: |
| |
| "Clients must align data elements consistent with the requirements |
| of the client platform, with an additional base-level requirement |
| that an offset within a buffer to a datum comprising N basic machine |
| units be a multiple of N." |
| |
| However, the consequences of ignoring this advice aren't specified. |
| Since this extension still uses buffer objects, presumably it should |
| inherit the same restrictions. However, if we split out the Format API |
| from the Address API, then it becomes impossible to do an error check |
| to enforce this. But, our implementation has never had such an error |
| check in the first place... |
| |
| Follow the quoted advice from the core spec, and this extension adds |
| no new error checks to enforce it. The GL should ensure that the base |
| address of a buffer is at least 16-byte aligned (see issue 16 of |
| NV_shader_buffer_load). |
| |
| 11) Does MAX_SHADER_BUFFER_ADDRESS_NV imply any restriction on vertex |
| attrib or element array addresses? |
| |
| RESOLVED: No, it is only a restriction on shader loads. The entire |
| address space is available for vertex/element fetches. |
| |
| 12) How does the new vertex state interact with |
| EXT_direct_state_access's ClientAttribDefaultEXT? |
| |
| RESOLVED: All the new state is reset to the initial values. |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- -------- ----------------------------------------- |
| 1 jbolz Internal revisions. |
| 2 06/30/09 jbolz Defined interaction with deprecated |
| client state commands. |
| 3 09/09/09 mjk Assigned number + fixed typos |
| 4 07/08/15 ckubisch 64-bit Gets for *_LENGTH_NV, interaction with 3.2 |