blob: fceaa4e99d406c7b7fc8b0d2df6a92f19273106b [file] [log] [blame]
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