blob: ca6c0dc5849b73a3e0b0e703e80c187281008d35 [file] [log] [blame]
Name
NV_vertex_array_range
Name Strings
GL_NV_vertex_array_range
Contact
Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)
Notice
Copyright NVIDIA Corporation, 1999, 2000, 2001.
IP Status
NVIDIA Proprietary.
Status
Shipping (version 1.1)
Existing functionality is augmented by NV_vertex_array_range2.
Version
NVIDIA Date: September 17, 2001 (version 1.1)
Number
190
Dependencies
None
Overview
The goal of this extension is to permit extremely high vertex
processing rates via OpenGL vertex arrays even when the CPU lacks
the necessary data movement bandwidth to keep up with the rate
at which the vertex engine can consume vertices. CPUs can keep
up if they can just pass vertex indices to the hardware and
let the hardware "pull" the actual vertex data via Direct Memory
Access (DMA). Unfortunately, the current OpenGL 1.1 vertex array
functionality has semantic constraints that make such an approach
hard. Hence, the vertex array range extension.
This extension provides a mechanism for deferring the pulling of
vertex array elements to facilitate DMAed pulling of vertices for
fast, efficient vertex array transfers. The OpenGL client need only
pass vertex indices to the hardware which can DMA the actual index's
vertex data directly out of the client address space.
The OpenGL 1.1 vertex array functionality specifies a fairly strict
coherency model for when OpenGL extracts vertex data from a vertex
array and when the application can update the in memory
vertex array data. The OpenGL 1.1 specification says "Changes
made to array data between the execution of Begin and the
corresponding execution of End may affect calls to ArrayElement
that are made within the same Begin/End period in non-sequential
ways. That is, a call to ArrayElement that precedes a change to
array data may access the changed data, and a call that follows
a change to array data may access the original data."
This means that by the time End returns (and DrawArrays and
DrawElements return since they have implicit Ends), the actual vertex
array data must be transferred to OpenGL. This strict coherency model
prevents us from simply passing vertex element indices to the hardware
and having the hardware "pull" the vertex data out (which is often
long after the End for the primitive has returned to the application).
Relaxing this coherency model and bounding the range from which
vertex array data can be pulled is key to making OpenGL vertex
array transfers faster and more efficient.
The first task of the vertex array range extension is to relax
the coherency model so that hardware can indeed "pull" vertex
data from the OpenGL client's address space long after the application
has completed sending the geometry primitives requiring the vertex
data.
The second problem with the OpenGL 1.1 vertex array functionality is
the lack of any guidance from the API about what region of memory
vertices can be pulled from. There is no size limit for OpenGL 1.1
vertex arrays. Any vertex index that points to valid data in all
enabled arrays is fair game. This makes it hard for a vertex DMA
engine to pull vertices since they can be potentially pulled from
anywhere in the OpenGL client address space.
The vertex array range extension specifies a range of the OpenGL
client's address space where vertices can be pulled. Vertex indices
that access any array elements outside the vertex array range
are specified to be undefined. This permits hardware to DMA from
finite regions of OpenGL client address space, making DMA engine
implementation tractable.
The extension is specified such that an (error free) OpenGL client
using the vertex array range functionality could no-op its vertex
array range commands and operate equivalently to using (if slower
than) the vertex array range functionality.
Because different memory types (local graphics memory, AGP memory)
have different DMA bandwidths and caching behavior, this extension
includes a window system dependent memory allocator to allocate
cleanly the most appropriate memory for constructing a vertex array
range. The memory allocator provided allows the application to
tradeoff the desired CPU read frequency, CPU write frequency, and
memory priority while still leaving it up to OpenGL implementation
the exact memory type to be allocated.
Issues
How does this extension interact with the compiled_vertex_array
extension?
I think they should be independent and not interfere with
each other. In practice, if you use NV_vertex_array_range,
you can surpass the performance of compiled_vertex_array
Should some explanation be added about what happens when an OpenGL
application updates its address space in regions overlapping with
the currently configured vertex array range?
RESOLUTION: I think the right thing is to say that you get
non-sequential results. In practice, you'll be using an old
context DMA pointing to the old pages.
If the application change's its address space within the
vertex array range, the application should call
glVertexArrayRangeNV again. That will re-make a new vertex
array range context DMA for the application's current address
space.
If we are falling back to software transformation, do we still need to
abide by leaving "undefined" vertices outside the vertex array range?
For example, pointers that are not 32-bit aligned would likely cause
a fall back.
RESOLUTION: No. The fact that vertex is "undefined" means we
can do anything we want (as long as we send a vertex and do not
crash) so it is perfectly fine for the software puller to
grab vertex information not available to the hardware puller.
Should we give a programmer a sense of how big a vertex array
range they can specify?
RESOLUTION: No. Just document it if there are limitations.
Probably very hardware and operating system dependent.
Is it clear enough that language about ArrayElement
also applies to DrawArrays and DrawElements?
Maybe not, but OpenGL 1.1 spec is clear that DrawArrays and
DrawElements are defined in terms of ArrayElement.
Should glFlush be the same as glVertexArrayRangeFlush?
RESOLUTION: No. A glFlush is cheaper than a glVertexArrayRangeFlush
though a glVertexArrayRangeFlushNV should do a flush.
If any the data for any enabled array for a given array element index
falls outside of the vertex array range, what happens?
RESOLUTION: An undefined vertex is generated.
What error is generated in this case?
I don't know yet. We should make sure the hardware really does
let us know when vertices are undefined.
Note that this is a little weird for OpenGL since most errors
in OpenGL result in the command being ignored. Not in this
case though.
Should this extension support an interface for allocating video
and AGP memory?
RESOLUTION: YES. It seems like we should be able to leave
the task of memory allocation to DirectDraw, but DirectDraw's
asynchronous unmapping behavior and having to hold locks to
update DirectDraw surfaces makes that mechanism to cumbersome.
Plus the API is a lot easier if we do it ourselves.
How do we decide what type of memory to allocate for the application?
RESOLUTION: Usage hints. The application rates the read
frequency (how often will they read the memory), the write
frequency (how often will they write the memory), and the
priority (how important is this memory relative to other
uses for the memory such as texturing) on a scale of 1.0
to 0.0. Using these hints and the size of the memory requsted,
the OpenGL implementation decides where to allocate the memory.
We try to not directly expose particular types of memory
(AGP, local memory, cached/uncached, etc) so future memory
types can be supported by merely updating the OpenGL
implementation.
Should the memory allocator functionality be available be a part
of the GL or window system dependent (GLX or WGL) APIs?
RESOLUTION: The window system dependent API.
The memory allocator should be considered a window system/
operating system dependent operation. This also permits
memory to be allocated when no OpenGL rendering contexts
exist yet.
New Procedures and Functions
void VertexArrayRangeNV(sizei length, void *pointer)
void FlushVertexArrayRangeNV(void)
New Tokens
Accepted by the <cap> parameter of EnableClientState,
DisableClientState, and IsEnabled:
VERTEX_ARRAY_RANGE_NV 0x851D
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
VERTEX_ARRAY_RANGE_VALID_NV 0x851F
MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
Accepted by the <pname> parameter of GetPointerv:
VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
Additions to Chapter 2 of the OpenGL 1.1 Specification (OpenGL Operation)
After the discussion of vertex arrays (Section 2.8) add a
description of the vertex array range:
"The command
void VertexArrayRangeNV(sizei length, void *pointer)
specifies the current vertex array range. When the vertex array
range is enabled and valid, vertex array vertex transfers from within
the vertex array range are potentially faster. The vertex array
range is a contiguous region of (virtual) address space for placing
vertex arrays. The "pointer" parameter is a pointer to the base of
the vertex array range. The "length" pointer is the length of the
vertex array range in basic machine units (typically unsigned bytes).
The vertex array range address space region extends from "pointer"
to "pointer + length - 1" inclusive. When specified and enabled,
vertex array vertex transfers from within the vertex array range
are potentially faster.
There is some system burden associated with establishing a vertex
array range (typically, the memory range must be locked down).
If either the vertex array range pointer or size is set to zero,
the previously established vertex array range is released (typically,
unlocking the memory).
The vertex array range may not be established for operating system
dependent reasons, and therefore, not valid. Reasons that a vertex
array range cannot be established include spanning different memory
types, the memory could not be locked down, alignment restrictions
are not met, etc.
The vertex array range is enabled or disabled by calling
EnableClientState or DisableClientState with the symbolic
constant VERTEX_ARRAY_RANGE_NV.
The vertex array range is either valid or invalid and this state can
be determined by querying VERTEX_ARRAY_RANGE_VALID_NV. The vertex
array range is valid when the following conditions are met:
o VERTEX_ARRAY_RANGE_NV is enabled.
o VERTEX_ARRAY is enabled.
o VertexArrayRangeNV has been called with a non-null pointer and
non-zero size.
o The vertex array range has been established.
o An implementation-dependent validity check based on the
pointer alignment, size, and underlying memory type of the
vertex array range region of memory.
o An implementation-dependent validity check based on
the current vertex array state including the strides, sizes,
types, and pointer alignments (but not pointer value) for
currently enabled vertex arrays.
o Other implementation-dependent validaity checks based on
other OpenGL rendering state.
Otherwise, the vertex array range is not valid. If the vertex array
range is not valid, vertex array transfers will not be faster.
When the vertex array range is valid, ArrayElement commands may
generate undefined vertices if and only if any indexed elements of
the enabled arrays are not within the vertex array range or if the
index is negative or greater or equal to the implementation-dependent
value of MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV. If an undefined vertex
is generated, an INVALID_OPERATION error may or may not be generated.
The vertex array cohenecy model specifies when vertex data must be
be extracted from the vertex array memory. When the vertex array
range is not valid, (quoting the specification) `Changes made to
array data between the execution of Begin and the corresponding
execution of End may effect calls to ArrayElement that are made
within the same Begin/End period in non-sequential ways. That is,
a call to ArrayElement that precedes a change to array data may
access the changed data, and a call that follows a change to array
data may access the original data.'
When the vertex array range is valid, the vertex array coherency
model is relaxed so that changes made to array data until the next
"vertex array range flush" may affects calls to ArrayElement in
non-sequential ways. That is a call to ArrayElement that precedes
a change to array data (without an intervening "vertex array range
flush") may access the changed data, and a call that follows a change
(without an intervening "vertex array range flush") to array data
may access original data.
A 'vertex array range flush' occurs when one of the following
operations occur:
o Finish returns.
o FlushVertexArrayRangeNV returns.
o VertexArrayRangeNV returns.
o DisableClientState of VERTEX_ARRAY_RANGE_NV returns.
o EnableClientState of VERTEX_ARRAY_RANGE_NV returns.
o Another OpenGL context is made current.
The client state required to implement the vertex array range
consists of an enable bit, a memory pointer, an integer size,
and a valid bit.
If the memory mapping of pages within the vertex array range changes,
using the vertex array range may or may not result in undefined data
being fetched from the vertex arrays when the vertex array range is
enabled and valid. To ensure that the vertex array range reflects
the address space's current state, the application is responsible
for calling VertexArrayRange again after any memory mapping changes
within the vertex array range."llo
Additions to Chapter 5 of the OpenGL 1.1 Specification (Special Functions)
Add to the end of Section 5.4 "Display Lists"
"VertexArrayRangeNV and FlushVertexArrayRangeNV are not complied
into display lists but are executed immediately.
If a display list is compiled while VERTEX_ARRAY_RANGE_NV is
enabled, the commands ArrayElement, DrawArrays, DrawElements,
and DrawRangeElements are accumulated into a display list as
if VERTEX_ARRAY_RANGE_NV is disabled."
Additions to the WGL interface:
"When establishing a vertex array range, certain types of memory
may be more efficient than other types of memory. The commands
void *wglAllocateMemoryNV(sizei size,
float readFrequency,
float writeFrequency,
float priority)
void wglFreeMemoryNV(void *pointer)
allocate and free memory that may be more suitable for establishing
an efficient vertex array range than memory allocated by other means.
The wglAllocateMemoryNV command allocates <size> bytes of contiguous
memory.
The <readFrequency>, <writeFrequency>, and <priority> parameters are
usage hints that the OpenGL implementation can use to determine the
best type of memory to allocate. These parameters range from 0.0
to 1.0. A <readFrequency> of 1.0 indicates that the application
intends to frequently read the allocated memory; a <readFrequency>
of 0.0 indicates that the application will rarely or never read the
memory. A <writeFrequency> of 1.0 indicates that the application
intends to frequently write the allocated memory; a <writeFrequency>
of 0.0 indicates that the application will rarely write the memory.
A <priority> parameter of 1.0 indicates that memory type should be
the most efficient available memory, even at the expense of (for
example) available texture memory; a <priority> of 0.0 indicates that
the vertex array range does not require an efficient memory type
(for example, so that more efficient memory is available for other
purposes such as texture memory).
The OpenGL implementation is free to use the <size>, <readFrequency>,
<writeFrequency>, and <priority> parameters to determine what memory
type should be allocated. The memory types available and how the
memory type is determined is implementation dependent (and the
implementation is free to ignore any or all of the above parameters).
Possible memory types that could be allocated are uncached memory,
write-combined memory, graphics hardware memory, etc. The intent
of the wglAllocateMemoryNV command is to permit the allocation of
memory for efficient vertex array range usage. However, there is
no requirement that memory allocated by wglAllocateMemoryNV must be
used to allocate memory for vertex array ranges.
If the memory cannot be allocated, a NULL pointer is returned (and
no OpenGL error is generated). An implementation that does not
support this extension's memory allocation interface is free to
never allocate memory (always return NULL).
The wglFreeMemoryNV command frees memory allocated with
wglAllocateMemoryNV. The <pointer> should be a pointer returned by
wglAllocateMemoryNV and not previously freed. If a pointer is passed
to wglFreeMemoryNV that was not allocated via wglAllocateMemoryNV
or was previously freed (without being reallocated), the free is
ignored with no error reported.
The memory allocated by wglAllocateMemoryNV should be available to
all other threads in the address space where the memory is allocated
(the memory is not private to a single thread). Any thread in the
address space (not simply the thread that allocated the memory)
may use wglFreeMemoryNV to free memory allocated by itself or any
other thread.
Because wglAllocateMemoryNV and wglFreeMemoryNV are not OpenGL
rendering commands, these commands do not require a current context.
They operate normally even if called within a Begin/End or while
compiling a display list."
Additions to the GLX Specification
Same language as the "Additions to the WGL Specification" section
except all references to wglAllocateMemoryNV and wglFreeMemoryNV
should be replaced with glXAllocateMemoryNV and glXFreeMemoryNV
respectively.
Additional language:
"OpenGL implementations using GLX indirect rendering should fail
to set up the vertex array range (failing to set the vertex array
valid bit so the vertex array range functionality is not usable).
Additionally, glXAllocateMemoryNV always fails to allocate memory
(returns NULL) when used with an indirect rendering context."
GLX Protocol
None
Errors
INVALID_OPERATION is generated if VertexArrayRange or
FlushVertexArrayRange is called between the execution of Begin
and the corresponding execution of End.
INVALID_OPERATION may be generated if an undefined vertex is
generated.
New State
Initial
Get Value Get Command Type Value Attrib
--------- ----------- ---- ------- ------------
VERTEX_ARRAY_RANGE_NV IsEnabled B False vertex-array
VERTEX_ARRAY_RANGE_POINTER_NV GetPointerv Z+ 0 vertex-array
VERTEX_ARRAY_RANGE_LENGTH_NV GetIntegerv Z+ 0 vertex-array
VERTEX_ARRAY_RANGE_VALID_NV GetBooleanv B False vertex-array
New Implementation Dependent State
Get Value Get Command Type Minimum Value
--------- ----------- ----- -------------
MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV GetIntegerv Z+ 65535
NV10 Implementation Details
This section describes implementation-defined limits for NV10:
The value of MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV is 65535.
This section describes bugs in the NV10 vertex array range. These
bugs will be fixed in a future hardware release:
If VERTEX_ARRAY is enabled with a format of GL_SHORT and the
vertex array range is valid, a vertex array vertex with an X,
Y, Z, or W coordinate of -32768 is wrongly interpreted as zero.
Example: the X,Y coordinate (-32768,-32768) is incorrectly read
as (0,0) from the vertex array.
If TEXTURE_COORD_ARRAY is enabled with a format of GL_SHORT
and the vertex array range is valid, a vertex array texture
coord with an S, T, R, or Q coordinate of -32768 is wrongly
interpreted as zero. Example: the S,T coordinate (-32768,-32768)
is incorrectly read as (0,0) from the texture coord array.
This section describes the implementation-dependent validity
checks for NV10.
o For the NV10 implementation-dependent validity check for the
vertex array range region of memory to be true, all of the
following must be true:
1. The <pointer> must be 32-byte aligned.
2. The underlying memory types must all be the same (all
standard system memory -OR- all AGP memory -OR- all video
memory).
o For the NV10 implementation-dependent validity check for the
vertex array state to be true, all of the following must be
true:
1. ( VERTEX_ARRAY must be enabled -AND-
The vertex array stride must be less than 256 -AND-
( ( The vertex array type must be FLOAT -AND-
The vertex array stride must be a multiple of 4 bytes -AND-
The vertex array pointer must be 4-byte aligned -AND-
The vertex array size must be 2, 3, or 4 ) -OR-
( The vertex array type must be SHORT -AND-
The vertex array stride must be a multiple of 4 bytes -AND-
The vertex array pointer must be 4-byte aligned. -AND-
The vertex array size must be 2 ) -OR-
( The vertex array type must be SHORT -AND-
The vertex array stride must be a multiple of 8 bytes -AND-
The vertex array pointer must be 8-byte aligned. -AND-
The vertex array size must be 3 or 4 ) ) )
2. ( NORMAL_ARRAY must be disabled. ) -OR -
( NORMAL_ARRAY must be enabled -AND-
The normal array size must be 3 -AND-
The normal array stride must be less than 256 -AND-
( ( The normal array type must be FLOAT -AND-
The normal array stride must be a multiple of 4 bytes -AND-
The normal array pointer must be 4-byte aligned. ) -OR-
( The normal array type must be SHORT -AND-
The normal array stride must be a multiple of 8 bytes -AND-
The normal array pointer must be 8-byte aligned. ) ) )
3. ( COLOR_ARRAY must be disabled. ) -OR -
( COLOR_ARRAY must be enabled -AND-
The color array type must be FLOAT or UNSIGNED_BYTE -AND-
The color array stride must be a multiple of 4 bytes -AND-
The color array stride must be less than 256 -AND-
The color array pointer must be 4-byte aligned -AND-
The color array size must be 3 or 4 )
4. ( SECONDARY_COLOR_ARRAY must be disabled. ) -OR -
( SECONDARY_COLOR_ARRAY must be enabled -AND-
The secondary color array type must be FLOAT or UNSIGNED_BYTE -AND-
The secondary color array stride must be a multiple of 4 bytes -AND-
The secondary color array stride must be less than 256 -AND-
The secondary color array pointer must be 4-byte aligned -AND-
The secondary color array size must be 3 or 4 )
5. For texture units zero and one:
( TEXTURE_COORD_ARRAY must be disabled. ) -OR -
( TEXTURE_COORD_ARRAY must be enabled -AND-
The texture coord array stride must be less than 256 -AND-
( ( The texture coord array type must be FLOAT -AND-
The texture coord array pointer must be 4-byte aligned. )
The texture coord array stride must be a multiple of 4 bytes -AND-
The texture coord array size must be 1, 2, 3, or 4 ) -OR-
( The texture coord array type must be SHORT -AND-
The texture coord array pointer must be 4-byte aligned. )
The texture coord array stride must be a multiple of 4 bytes -AND-
The texture coord array size must be 1 ) -OR-
( The texture coord array type must be SHORT -AND-
The texture coord array pointer must be 4-byte aligned. )
The texture coord array stride must be a multiple of 4 bytes -AND-
The texture coord array size must be 2 ) -OR-
( The texture coord array type must be SHORT -AND-
The texture coord array pointer must be 8-byte aligned. )
The texture coord array stride must be a multiple of 8 bytes -AND-
The texture coord array size must be 3 ) -OR-
( The texture coord array type must be SHORT -AND-
The texture coord array pointer must be 8-byte aligned. )
The texture coord array stride must be a multiple of 8 bytes -AND-
The texture coord array size must be 4 ) ) )
6. ( EDGE_FLAG_ARRAY must be disabled. )
7. ( VERTEX_WEIGHT_ARRAY_NV must be disabled. ) -OR -
( VERTEX_WEIGHT_ARRAY_NV must be enabled. -AND -
The vertex weight array type must be FLOAT -AND-
The vertex weight array size must be 1 -AND-
The vertex weight array stride must be a multiple of 4 bytes -AND-
The vertex weight array stride must be less than 256 -AND-
The vertex weight array pointer must be 4-byte aligned )
8. ( FOG_COORDINATE_ARRAY must be disabled. ) -OR -
( FOG_COORDINATE_ARRAY must be enabled -AND-
The chip in use must be an NV11 or NV15, not NV10 -AND-
The fog coordinate array type must be FLOAT -AND-
The fog coordinate array size must be 1 -AND-
The fog coordinate array stride must be a multiple of 4 bytes -AND-
The fog coordinate array stride must be less than 256 -AND-
The fog coordinate array pointer must be 4-byte aligned )
o For the NV10 the implementation-dependent validity check based on
other OpenGL rendering state is FALSE if any of the following are true:
1. ( COLOR_LOGIC_OP is enabled -AND-
The logic op is not COPY ), except in the case of Quadro2
(Quadro2 Pro, Quadro2 MXR) products.
2. ( LIGHT_MODEL_TWO_SIDE is true. )
3. Either texture unit is enabled and active with a texture
with a non-zero border.
4. VERTEX_PROGRAM_NV is enabled.
5. Several other obscure unspecified reasons.
NV20 Implementation Details
This section describes implementation-defined limits for NV20:
The value of MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV is 1048575.
This section describes the implementation-dependent validity
checks for NV20.
o For the NV20 implementation-dependent validity check for the
vertex array range region of memory to be true, all of the
following must be true:
1. The <pointer> must be 32-byte aligned.
2. The underlying memory types must all be the same (all
standard system memory -OR- all AGP memory -OR- all video
memory).
o To determine whether the NV20 implementation-dependent validity
check for the vertex array state is true, the following algorithm
is used:
The currently enabled arrays and their pointers, strides, and
types are first determined using the value of VERTEX_PROGRAM_NV.
If VERTEX_PROGRAM_NV is disabled, the standard GL vertex arrays
are used. If VERTEX_PROGRAM_NV is enabled, the vertex attribute
arrays take precedence over the standard vertex arrays. The
following table, taken from the NV_vertex_program specification,
shows the aliasing between the standard and attribute arrays:
Vertex
Attribute Conventional Conventional
Register Per-vertex Conventional Component
Number Parameter Per-vertex Parameter Command Mapping
--------- --------------- ----------------------------------- ------------
0 vertex position Vertex x,y,z,w
1 vertex weights VertexWeightEXT w,0,0,1
2 normal Normal x,y,z,1
3 primary color Color r,g,b,a
4 secondary color SecondaryColorEXT r,g,b,1
5 fog coordinate FogCoordEXT fc,0,0,1
6 - - -
7 - - -
8 texture coord 0 MultiTexCoord(GL_TEXTURE0_ARB, ...) s,t,r,q
9 texture coord 1 MultiTexCoord(GL_TEXTURE1_ARB, ...) s,t,r,q
10 texture coord 2 MultiTexCoord(GL_TEXTURE2_ARB, ...) s,t,r,q
11 texture coord 3 MultiTexCoord(GL_TEXTURE3_ARB, ...) s,t,r,q
12 texture coord 4 MultiTexCoord(GL_TEXTURE4_ARB, ...) s,t,r,q
13 texture coord 5 MultiTexCoord(GL_TEXTURE5_ARB, ...) s,t,r,q
14 texture coord 6 MultiTexCoord(GL_TEXTURE6_ARB, ...) s,t,r,q
15 texture coord 7 MultiTexCoord(GL_TEXTURE7_ARB, ...) s,t,r,q
For the validity check to be TRUE, the following must all be
true:
1. Vertex attribute 0's array must be enabled.
2. EDGE_FLAG_ARRAY must be disabled.
3. For all enabled arrays, all of the following must be true:
- the stride must be less than 256
- the type must be FLOAT, SHORT, or UNSIGNED_BYTE
o For the NV20 the implementation-dependent validity check based on
other OpenGL rendering state is FALSE only for a few obscure and
unspecified reasons.
Revision History
January 10, 2001 - Added NV20 implementation details. Made several
corrections to the NV10 implementation details. Specifically, noted
that on the NV11 and NV15 architectures, the fog coordinate array may
be used, and updated the section on other state that may cause the
vertex array range to be invalid. Only drivers built after this date
will support fog coordinate arrays on NV11 and NV15. Also fixed a
few typos in the spec.
September 17, 2001 - Modified NV20 implementation details to remove
all the pointer and stride restrictions, none of which are actually
required. Only drivers built after this date will support arbitrary
pointer offsets and strides. Also removed NV10 rules on non-zero
strides, which cannot be used in OpenGL anyhow, and fixed a few other
typos.