• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_vertex_array_range
4
5Name Strings
6
7    GL_NV_vertex_array_range
8
9Contact
10
11    Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)
12
13Notice
14
15    Copyright NVIDIA Corporation, 1999, 2000, 2001.
16
17IP Status
18
19    NVIDIA Proprietary.
20
21Status
22
23    Shipping (version 1.1)
24
25    Existing functionality is augmented by NV_vertex_array_range2.
26
27Version
28
29    NVIDIA Date: September 17, 2001 (version 1.1)
30
31Number
32
33    190
34
35Dependencies
36
37    None
38
39Overview
40
41    The goal of this extension is to permit extremely high vertex
42    processing rates via OpenGL vertex arrays even when the CPU lacks
43    the necessary data movement bandwidth to keep up with the rate
44    at which the vertex engine can consume vertices.  CPUs can keep
45    up if they can just pass vertex indices to the hardware and
46    let the hardware "pull" the actual vertex data via Direct Memory
47    Access (DMA).  Unfortunately, the current OpenGL 1.1 vertex array
48    functionality has semantic constraints that make such an approach
49    hard.  Hence, the vertex array range extension.
50
51    This extension provides a mechanism for deferring the pulling of
52    vertex array elements to facilitate DMAed pulling of vertices for
53    fast, efficient vertex array transfers.  The OpenGL client need only
54    pass vertex indices to the hardware which can DMA the actual index's
55    vertex data directly out of the client address space.
56
57    The OpenGL 1.1 vertex array functionality specifies a fairly strict
58    coherency model for when OpenGL extracts vertex data from a vertex
59    array and when the application can update the in memory
60    vertex array data.  The OpenGL 1.1 specification says "Changes
61    made to array data between the execution of Begin and the
62    corresponding execution of End may affect calls to ArrayElement
63    that are made within the same Begin/End period in non-sequential
64    ways.  That is, a call to ArrayElement that precedes a change to
65    array data may access the changed data, and a call that follows
66    a change to array data may access the original data."
67
68    This means that by the time End returns (and DrawArrays and
69    DrawElements return since they have implicit Ends), the actual vertex
70    array data must be transferred to OpenGL.  This strict coherency model
71    prevents us from simply passing vertex element indices to the hardware
72    and having the hardware "pull" the vertex data out (which is often
73    long after the End for the primitive has returned to the application).
74
75    Relaxing this coherency model and bounding the range from which
76    vertex array data can be pulled is key to making OpenGL vertex
77    array transfers faster and more efficient.
78
79    The first task of the vertex array range extension is to relax
80    the coherency model so that hardware can indeed "pull" vertex
81    data from the OpenGL client's address space long after the application
82    has completed sending the geometry primitives requiring the vertex
83    data.
84
85    The second problem with the OpenGL 1.1 vertex array functionality is
86    the lack of any guidance from the API about what region of memory
87    vertices can be pulled from.  There is no size limit for OpenGL 1.1
88    vertex arrays.  Any vertex index that points to valid data in all
89    enabled arrays is fair game.  This makes it hard for a vertex DMA
90    engine to pull vertices since they can be potentially pulled from
91    anywhere in the OpenGL client address space.
92
93    The vertex array range extension specifies a range of the OpenGL
94    client's address space where vertices can be pulled.  Vertex indices
95    that access any array elements outside the vertex array range
96    are specified to be undefined.  This permits hardware to DMA from
97    finite regions of OpenGL client address space, making DMA engine
98    implementation tractable.
99
100    The extension is specified such that an (error free) OpenGL client
101    using the vertex array range functionality could no-op its vertex
102    array range commands and operate equivalently to using (if slower
103    than) the vertex array range functionality.
104
105    Because different memory types (local graphics memory, AGP memory)
106    have different DMA bandwidths and caching behavior, this extension
107    includes a window system dependent memory allocator to allocate
108    cleanly the most appropriate memory for constructing a vertex array
109    range.  The memory allocator provided allows the application to
110    tradeoff the desired CPU read frequency, CPU write frequency, and
111    memory priority while still leaving it up to OpenGL implementation
112    the exact memory type to be allocated.
113
114Issues
115
116    How does this extension interact with the compiled_vertex_array
117    extension?
118
119       I think they should be independent and not interfere with
120       each other.  In practice, if you use NV_vertex_array_range,
121       you can surpass the performance of compiled_vertex_array
122
123    Should some explanation be added about what happens when an OpenGL
124    application updates its address space in regions overlapping with
125    the currently configured vertex array range?
126
127       RESOLUTION:  I think the right thing is to say that you get
128       non-sequential results.  In practice, you'll be using an old
129       context DMA pointing to the old pages.
130
131       If the application change's its address space within the
132       vertex array range, the application should call
133       glVertexArrayRangeNV again.  That will re-make a new vertex
134       array range context DMA for the application's current address
135       space.
136
137    If we are falling back to software transformation, do we still need to
138    abide by leaving "undefined" vertices outside the vertex array range?
139    For example, pointers that are not 32-bit aligned would likely cause
140    a fall back.
141
142       RESOLUTION:  No.  The fact that vertex is "undefined" means we
143       can do anything we want (as long as we send a vertex and do not
144       crash) so it is perfectly fine for the software puller to
145       grab vertex information not available to the hardware puller.
146
147    Should we give a programmer a sense of how big a vertex array
148    range they can specify?
149
150       RESOLUTION:  No.  Just document it if there are limitations.
151       Probably very hardware and operating system dependent.
152
153    Is it clear enough that language about ArrayElement
154    also applies to DrawArrays and DrawElements?
155
156       Maybe not, but OpenGL 1.1 spec is clear that DrawArrays and
157       DrawElements are defined in terms of ArrayElement.
158
159    Should glFlush be the same as glVertexArrayRangeFlush?
160
161       RESOLUTION:  No.  A glFlush is cheaper than a glVertexArrayRangeFlush
162       though a glVertexArrayRangeFlushNV should do a flush.
163
164    If any the data for any enabled array for a given array element index
165    falls outside of the vertex array range, what happens?
166
167       RESOLUTION:  An undefined vertex is generated.
168
169    What error is generated in this case?
170
171       I don't know yet.  We should make sure the hardware really does
172       let us know when vertices are undefined.
173
174       Note that this is a little weird for OpenGL since most errors
175       in OpenGL result in the command being ignored.  Not in this
176       case though.
177
178    Should this extension support an interface for allocating video
179    and AGP memory?
180
181       RESOLUTION:  YES.  It seems like we should be able to leave
182       the task of memory allocation to DirectDraw, but DirectDraw's
183       asynchronous unmapping behavior and having to hold locks to
184       update DirectDraw surfaces makes that mechanism to cumbersome.
185
186       Plus the API is a lot easier if we do it ourselves.
187
188    How do we decide what type of memory to allocate for the application?
189
190       RESOLUTION:  Usage hints.  The application rates the read
191       frequency (how often will they read the memory), the write
192       frequency (how often will they write the memory), and the
193       priority (how important is this memory relative to other
194       uses for the memory such as texturing) on a scale of 1.0
195       to 0.0.  Using these hints and the size of the memory requsted,
196       the OpenGL implementation decides where to allocate the memory.
197
198       We try to not directly expose particular types of memory
199       (AGP, local memory, cached/uncached, etc) so future memory
200       types can be supported by merely updating the OpenGL
201       implementation.
202
203    Should the memory allocator functionality be available be a part
204    of the GL or window system dependent (GLX or WGL) APIs?
205
206       RESOLUTION:  The window system dependent API.
207
208       The memory allocator should be considered a window system/
209       operating system dependent operation.  This also permits
210       memory to be allocated when no OpenGL rendering contexts
211       exist yet.
212
213New Procedures and Functions
214
215    void VertexArrayRangeNV(sizei length, void *pointer)
216    void FlushVertexArrayRangeNV(void)
217
218New Tokens
219
220    Accepted by the <cap> parameter of EnableClientState,
221    DisableClientState, and IsEnabled:
222
223        VERTEX_ARRAY_RANGE_NV              0x851D
224
225    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
226    GetFloatv, and GetDoublev:
227
228        VERTEX_ARRAY_RANGE_LENGTH_NV       0x851E
229        VERTEX_ARRAY_RANGE_VALID_NV        0x851F
230        MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV  0x8520
231
232    Accepted by the <pname> parameter of GetPointerv:
233
234        VERTEX_ARRAY_RANGE_POINTER_NV      0x8521
235
236Additions to Chapter 2 of the OpenGL 1.1 Specification (OpenGL Operation)
237
238    After the discussion of vertex arrays (Section 2.8) add a
239    description of the vertex array range:
240
241    "The command
242
243       void VertexArrayRangeNV(sizei length, void *pointer)
244
245    specifies the current vertex array range.  When the vertex array
246    range is enabled and valid, vertex array vertex transfers from within
247    the vertex array range are potentially faster.  The vertex array
248    range is a contiguous region of (virtual) address space for placing
249    vertex arrays.  The "pointer" parameter is a pointer to the base of
250    the vertex array range.  The "length" pointer is the length of the
251    vertex array range in basic machine units (typically unsigned bytes).
252
253    The vertex array range address space region extends from "pointer"
254    to "pointer + length - 1" inclusive.  When specified and enabled,
255    vertex array vertex transfers from within the vertex array range
256    are potentially faster.
257
258    There is some system burden associated with establishing a vertex
259    array range (typically, the memory range must be locked down).
260    If either the vertex array range pointer or size is set to zero,
261    the previously established vertex array range is released (typically,
262    unlocking the memory).
263
264    The vertex array range may not be established for operating system
265    dependent reasons, and therefore, not valid.  Reasons that a vertex
266    array range cannot be established include spanning different memory
267    types, the memory could not be locked down, alignment restrictions
268    are not met, etc.
269
270    The vertex array range is enabled or disabled by calling
271    EnableClientState or DisableClientState with the symbolic
272    constant VERTEX_ARRAY_RANGE_NV.
273
274    The vertex array range is either valid or invalid and this state can
275    be determined by querying VERTEX_ARRAY_RANGE_VALID_NV.  The vertex
276    array range is valid when the following conditions are met:
277
278      o  VERTEX_ARRAY_RANGE_NV is enabled.
279
280      o  VERTEX_ARRAY is enabled.
281
282      o  VertexArrayRangeNV has been called with a non-null pointer and
283         non-zero size.
284
285      o  The vertex array range has been established.
286
287      o  An implementation-dependent validity check based on the
288         pointer alignment, size, and underlying memory type of the
289         vertex array range region of memory.
290
291      o  An implementation-dependent validity check based on
292         the current vertex array state including the strides, sizes,
293         types, and pointer alignments (but not pointer value) for
294         currently enabled vertex arrays.
295
296      o  Other implementation-dependent validaity checks based on
297         other OpenGL rendering state.
298
299    Otherwise, the vertex array range is not valid.  If the vertex array
300    range is not valid, vertex array transfers will not be faster.
301
302    When the vertex array range is valid, ArrayElement commands may
303    generate undefined vertices if and only if any indexed elements of
304    the enabled arrays are not within the vertex array range or if the
305    index is negative or greater or equal to the implementation-dependent
306    value of MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV.  If an undefined vertex
307    is generated, an INVALID_OPERATION error may or may not be generated.
308
309    The vertex array cohenecy model specifies when vertex data must be
310    be extracted from the vertex array memory.  When the vertex array
311    range is not valid, (quoting the specification) `Changes made to
312    array data between the execution of Begin and the corresponding
313    execution of End may effect calls to ArrayElement that are made
314    within the same Begin/End period in non-sequential ways.  That is,
315    a call to ArrayElement that precedes a change to array data may
316    access the changed data, and a call that follows a change to array
317    data may access the original data.'
318
319    When the vertex array range is valid, the vertex array coherency
320    model is relaxed so that changes made to array data until the next
321    "vertex array range flush" may affects calls to ArrayElement in
322    non-sequential ways.  That is a call to ArrayElement that precedes
323    a change to array data (without an intervening "vertex array range
324    flush") may access the changed data, and a call that follows a change
325    (without an intervening "vertex array range flush") to array data
326    may access original data.
327
328    A 'vertex array range flush' occurs when one of the following
329    operations occur:
330
331       o  Finish returns.
332
333       o  FlushVertexArrayRangeNV returns.
334
335       o  VertexArrayRangeNV returns.
336
337       o  DisableClientState of VERTEX_ARRAY_RANGE_NV returns.
338
339       o  EnableClientState of VERTEX_ARRAY_RANGE_NV returns.
340
341       o  Another OpenGL context is made current.
342
343    The client state required to implement the vertex array range
344    consists of an enable bit, a memory pointer, an integer size,
345    and a valid bit.
346
347    If the memory mapping of pages within the vertex array range changes,
348    using the vertex array range may or may not result in undefined data
349    being fetched from the vertex arrays when the vertex array range is
350    enabled and valid.  To ensure that the vertex array range reflects
351    the address space's current state, the application is responsible
352    for calling VertexArrayRange again after any memory mapping changes
353    within the vertex array range."llo
354
355Additions to Chapter 5 of the OpenGL 1.1 Specification (Special Functions)
356
357    Add to the end of Section 5.4 "Display Lists"
358
359    "VertexArrayRangeNV and FlushVertexArrayRangeNV are not complied
360    into display lists but are executed immediately.
361
362    If a display list is compiled while VERTEX_ARRAY_RANGE_NV is
363    enabled, the commands ArrayElement, DrawArrays, DrawElements,
364    and DrawRangeElements are accumulated into a display list as
365    if VERTEX_ARRAY_RANGE_NV is disabled."
366
367Additions to the WGL interface:
368
369    "When establishing a vertex array range, certain types of memory
370    may be more efficient than other types of memory.  The commands
371
372       void *wglAllocateMemoryNV(sizei size,
373                                 float readFrequency,
374                                 float writeFrequency,
375                                 float priority)
376       void wglFreeMemoryNV(void *pointer)
377
378    allocate and free memory that may be more suitable for establishing
379    an efficient vertex array range than memory allocated by other means.
380    The wglAllocateMemoryNV command allocates <size> bytes of contiguous
381    memory.
382
383    The <readFrequency>, <writeFrequency>, and <priority> parameters are
384    usage hints that the OpenGL implementation can use to determine the
385    best type of memory to allocate.  These parameters range from 0.0
386    to 1.0.  A <readFrequency> of 1.0 indicates that the application
387    intends to frequently read the allocated memory; a <readFrequency>
388    of 0.0 indicates that the application will rarely or never read the
389    memory.  A <writeFrequency> of 1.0 indicates that the application
390    intends to frequently write the allocated memory; a <writeFrequency>
391    of 0.0 indicates that the application will rarely write the memory.
392    A <priority> parameter of 1.0 indicates that memory type should be
393    the most efficient available memory, even at the expense of (for
394    example) available texture memory; a <priority> of 0.0 indicates that
395    the vertex array range does not require an efficient memory type
396    (for example, so that more efficient memory is available for other
397    purposes such as texture memory).
398
399    The OpenGL implementation is free to use the <size>, <readFrequency>,
400    <writeFrequency>, and <priority> parameters to determine what memory
401    type should be allocated.  The memory types available and how the
402    memory type is determined is implementation dependent (and the
403    implementation is free to ignore any or all of the above parameters).
404
405    Possible memory types that could be allocated are uncached memory,
406    write-combined memory, graphics hardware memory, etc.  The intent
407    of the wglAllocateMemoryNV command is to permit the allocation of
408    memory for efficient vertex array range usage.  However, there is
409    no requirement that memory allocated by wglAllocateMemoryNV must be
410    used to allocate memory for vertex array ranges.
411
412    If the memory cannot be allocated, a NULL pointer is returned (and
413    no OpenGL error is generated).  An implementation that does not
414    support this extension's memory allocation interface is free to
415    never allocate memory (always return NULL).
416
417    The wglFreeMemoryNV command frees memory allocated with
418    wglAllocateMemoryNV.  The <pointer> should be a pointer returned by
419    wglAllocateMemoryNV and not previously freed.  If a pointer is passed
420    to wglFreeMemoryNV that was not allocated via wglAllocateMemoryNV
421    or was previously freed (without being reallocated), the free is
422    ignored with no error reported.
423
424    The memory allocated by wglAllocateMemoryNV should be available to
425    all other threads in the address space where the memory is allocated
426    (the memory is not private to a single thread).  Any thread in the
427    address space (not simply the thread that allocated the memory)
428    may use wglFreeMemoryNV to free memory allocated by itself or any
429    other thread.
430
431    Because wglAllocateMemoryNV and wglFreeMemoryNV are not OpenGL
432    rendering commands, these commands do not require a current context.
433    They operate normally even if called within a Begin/End or while
434    compiling a display list."
435
436Additions to the GLX Specification
437
438    Same language as the "Additions to the WGL Specification" section
439    except all references to wglAllocateMemoryNV and wglFreeMemoryNV
440    should be replaced with glXAllocateMemoryNV and glXFreeMemoryNV
441    respectively.
442
443    Additional language:
444
445    "OpenGL implementations using GLX indirect rendering should fail
446    to set up the vertex array range (failing to set the vertex array
447    valid bit so the vertex array range functionality is not usable).
448    Additionally, glXAllocateMemoryNV always fails to allocate memory
449    (returns NULL) when used with an indirect rendering context."
450
451GLX Protocol
452
453    None
454
455Errors
456
457    INVALID_OPERATION is generated if VertexArrayRange or
458    FlushVertexArrayRange is called between the execution of Begin
459    and the corresponding execution of End.
460
461    INVALID_OPERATION may be generated if an undefined vertex is
462    generated.
463
464New State
465
466                                                            Initial
467   Get Value                       Get Command     Type    Value    Attrib
468   ---------                       -----------     ----    -------  ------------
469   VERTEX_ARRAY_RANGE_NV           IsEnabled       B       False    vertex-array
470   VERTEX_ARRAY_RANGE_POINTER_NV   GetPointerv     Z+      0        vertex-array
471   VERTEX_ARRAY_RANGE_LENGTH_NV    GetIntegerv     Z+      0        vertex-array
472   VERTEX_ARRAY_RANGE_VALID_NV     GetBooleanv     B       False    vertex-array
473
474New Implementation Dependent State
475
476    Get Value                           Get Command     Type    Minimum Value
477    ---------                           -----------     -----   -------------
478    MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV   GetIntegerv     Z+      65535
479
480NV10 Implementation Details
481
482    This section describes implementation-defined limits for NV10:
483
484         The value of MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV is 65535.
485
486    This section describes bugs in the NV10 vertex array range.  These
487    bugs will be fixed in a future hardware release:
488
489         If VERTEX_ARRAY is enabled with a format of GL_SHORT and the
490         vertex array range is valid, a vertex array vertex with an X,
491         Y, Z, or W coordinate of -32768 is wrongly interpreted as zero.
492         Example: the X,Y coordinate (-32768,-32768) is incorrectly read
493         as (0,0) from the vertex array.
494
495         If TEXTURE_COORD_ARRAY is enabled with a format of GL_SHORT
496         and the vertex array range is valid, a vertex array texture
497         coord with an S, T, R, or Q coordinate of -32768 is wrongly
498         interpreted as zero.  Example: the S,T coordinate (-32768,-32768)
499         is incorrectly read as (0,0) from the texture coord array.
500
501    This section describes the implementation-dependent validity
502    checks for NV10.
503
504      o  For the NV10 implementation-dependent validity check for the
505         vertex array range region of memory to be true, all of the
506         following must be true:
507
508         1.  The <pointer> must be 32-byte aligned.
509
510         2.  The underlying memory types must all be the same (all
511             standard system memory -OR- all AGP memory -OR- all video
512             memory).
513
514     o  For the NV10 implementation-dependent validity check for the
515        vertex array state to be true, all of the following must be
516        true:
517
518        1.  ( VERTEX_ARRAY must be enabled -AND-
519              The vertex array stride must be less than 256 -AND-
520              ( ( The vertex array type must be FLOAT -AND-
521                  The vertex array stride must be a multiple of 4 bytes -AND-
522                  The vertex array pointer must be 4-byte aligned -AND-
523                  The vertex array size must be 2, 3, or 4 ) -OR-
524                ( The vertex array type must be SHORT -AND-
525                  The vertex array stride must be a multiple of 4 bytes -AND-
526                  The vertex array pointer must be 4-byte aligned. -AND-
527                  The vertex array size must be 2 ) -OR-
528                ( The vertex array type must be SHORT -AND-
529                  The vertex array stride must be a multiple of 8 bytes -AND-
530                  The vertex array pointer must be 8-byte aligned. -AND-
531                  The vertex array size must be 3 or 4 ) ) )
532
533        2.  ( NORMAL_ARRAY must be disabled. ) -OR -
534            ( NORMAL_ARRAY must be enabled -AND-
535              The normal array size must be 3 -AND-
536              The normal array stride must be less than 256 -AND-
537              ( ( The normal array type must be FLOAT -AND-
538                  The normal array stride must be a multiple of 4 bytes -AND-
539                  The normal array pointer must be 4-byte aligned. ) -OR-
540                ( The normal array type must be SHORT -AND-
541                  The normal array stride must be a multiple of 8 bytes -AND-
542                  The normal array pointer must be 8-byte aligned. ) ) )
543
544        3.  ( COLOR_ARRAY must be disabled. ) -OR -
545            ( COLOR_ARRAY must be enabled -AND-
546              The color array type must be FLOAT or UNSIGNED_BYTE -AND-
547              The color array stride must be a multiple of 4 bytes -AND-
548              The color array stride must be less than 256 -AND-
549              The color array pointer must be 4-byte aligned -AND-
550              The color array size must be 3 or 4 )
551
552        4.  ( SECONDARY_COLOR_ARRAY must be disabled. ) -OR -
553            ( SECONDARY_COLOR_ARRAY must be enabled -AND-
554              The secondary color array type must be FLOAT or UNSIGNED_BYTE -AND-
555              The secondary color array stride must be a multiple of 4 bytes -AND-
556              The secondary color array stride must be less than 256 -AND-
557              The secondary color array pointer must be 4-byte aligned -AND-
558              The secondary color array size must be 3 or 4 )
559
560        5.  For texture units zero and one:
561
562            ( TEXTURE_COORD_ARRAY must be disabled. ) -OR -
563            ( TEXTURE_COORD_ARRAY must be enabled -AND-
564              The texture coord array stride must be less than 256 -AND-
565              ( ( The texture coord array type must be FLOAT -AND-
566                  The texture coord array pointer must be 4-byte aligned. )
567                  The texture coord array stride must be a multiple of 4 bytes -AND-
568                  The texture coord array size must be 1, 2, 3, or 4 ) -OR-
569                ( The texture coord array type must be SHORT -AND-
570                  The texture coord array pointer must be 4-byte aligned. )
571                  The texture coord array stride must be a multiple of 4 bytes -AND-
572                  The texture coord array size must be 1 ) -OR-
573                ( The texture coord array type must be SHORT -AND-
574                  The texture coord array pointer must be 4-byte aligned. )
575                  The texture coord array stride must be a multiple of 4 bytes -AND-
576                  The texture coord array size must be 2 ) -OR-
577                ( The texture coord array type must be SHORT -AND-
578                  The texture coord array pointer must be 8-byte aligned. )
579                  The texture coord array stride must be a multiple of 8 bytes -AND-
580                  The texture coord array size must be 3 ) -OR-
581                ( The texture coord array type must be SHORT -AND-
582                  The texture coord array pointer must be 8-byte aligned. )
583                  The texture coord array stride must be a multiple of 8 bytes -AND-
584                  The texture coord array size must be 4 ) ) )
585
586        6.  ( EDGE_FLAG_ARRAY must be disabled. )
587
588        7.  ( VERTEX_WEIGHT_ARRAY_NV must be disabled. ) -OR -
589            ( VERTEX_WEIGHT_ARRAY_NV must be enabled. -AND -
590              The vertex weight array type must be FLOAT -AND-
591              The vertex weight array size must be 1 -AND-
592              The vertex weight array stride must be a multiple of 4 bytes -AND-
593              The vertex weight array stride must be less than 256 -AND-
594              The vertex weight array pointer must be 4-byte aligned )
595
596        8.  ( FOG_COORDINATE_ARRAY must be disabled. ) -OR -
597            ( FOG_COORDINATE_ARRAY must be enabled -AND-
598              The chip in use must be an NV11 or NV15, not NV10 -AND-
599              The fog coordinate array type must be FLOAT -AND-
600              The fog coordinate array size must be 1 -AND-
601              The fog coordinate array stride must be a multiple of 4 bytes -AND-
602              The fog coordinate array stride must be less than 256 -AND-
603              The fog coordinate array pointer must be 4-byte aligned )
604
605     o  For the NV10 the implementation-dependent validity check based on
606        other OpenGL rendering state is FALSE if any of the following are true:
607
608        1.  ( COLOR_LOGIC_OP is enabled -AND-
609              The logic op is not COPY ), except in the case of Quadro2
610            (Quadro2 Pro, Quadro2 MXR) products.
611
612        2.  ( LIGHT_MODEL_TWO_SIDE is true. )
613
614        3.  Either texture unit is enabled and active with a texture
615            with a non-zero border.
616
617        4.  VERTEX_PROGRAM_NV is enabled.
618
619        5.  Several other obscure unspecified reasons.
620
621NV20 Implementation Details
622
623    This section describes implementation-defined limits for NV20:
624
625         The value of MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV is 1048575.
626
627    This section describes the implementation-dependent validity
628    checks for NV20.
629
630      o  For the NV20 implementation-dependent validity check for the
631         vertex array range region of memory to be true, all of the
632         following must be true:
633
634         1.  The <pointer> must be 32-byte aligned.
635
636         2.  The underlying memory types must all be the same (all
637             standard system memory -OR- all AGP memory -OR- all video
638             memory).
639
640     o  To determine whether the NV20 implementation-dependent validity
641        check for the vertex array state is true, the following algorithm
642        is used:
643
644        The currently enabled arrays and their pointers, strides, and
645        types are first determined using the value of VERTEX_PROGRAM_NV.
646        If VERTEX_PROGRAM_NV is disabled, the standard GL vertex arrays
647        are used.  If VERTEX_PROGRAM_NV is enabled, the vertex attribute
648        arrays take precedence over the standard vertex arrays.  The
649        following table, taken from the NV_vertex_program specification,
650        shows the aliasing between the standard and attribute arrays:
651
652Vertex
653Attribute  Conventional                                           Conventional
654Register   Per-vertex        Conventional                         Component
655Number     Parameter         Per-vertex Parameter Command         Mapping
656---------  ---------------   -----------------------------------  ------------
657 0         vertex position   Vertex                               x,y,z,w
658 1         vertex weights    VertexWeightEXT                      w,0,0,1
659 2         normal            Normal                               x,y,z,1
660 3         primary color     Color                                r,g,b,a
661 4         secondary color   SecondaryColorEXT                    r,g,b,1
662 5         fog coordinate    FogCoordEXT                          fc,0,0,1
663 6         -                 -                                    -
664 7         -                 -                                    -
665 8         texture coord 0   MultiTexCoord(GL_TEXTURE0_ARB, ...)  s,t,r,q
666 9         texture coord 1   MultiTexCoord(GL_TEXTURE1_ARB, ...)  s,t,r,q
667 10        texture coord 2   MultiTexCoord(GL_TEXTURE2_ARB, ...)  s,t,r,q
668 11        texture coord 3   MultiTexCoord(GL_TEXTURE3_ARB, ...)  s,t,r,q
669 12        texture coord 4   MultiTexCoord(GL_TEXTURE4_ARB, ...)  s,t,r,q
670 13        texture coord 5   MultiTexCoord(GL_TEXTURE5_ARB, ...)  s,t,r,q
671 14        texture coord 6   MultiTexCoord(GL_TEXTURE6_ARB, ...)  s,t,r,q
672 15        texture coord 7   MultiTexCoord(GL_TEXTURE7_ARB, ...)  s,t,r,q
673
674        For the validity check to be TRUE, the following must all be
675        true:
676
677        1.  Vertex attribute 0's array must be enabled.
678        2.  EDGE_FLAG_ARRAY must be disabled.
679        3.  For all enabled arrays, all of the following must be true:
680            - the stride must be less than 256
681            - the type must be FLOAT, SHORT, or UNSIGNED_BYTE
682
683     o  For the NV20 the implementation-dependent validity check based on
684        other OpenGL rendering state is FALSE only for a few obscure and
685        unspecified reasons.
686
687Revision History
688
689    January 10, 2001 - Added NV20 implementation details.  Made several
690    corrections to the NV10 implementation details.  Specifically, noted
691    that on the NV11 and NV15 architectures, the fog coordinate array may
692    be used, and updated the section on other state that may cause the
693    vertex array range to be invalid.  Only drivers built after this date
694    will support fog coordinate arrays on NV11 and NV15.  Also fixed a
695    few typos in the spec.
696
697    September 17, 2001 - Modified NV20 implementation details to remove
698    all the pointer and stride restrictions, none of which are actually
699    required.  Only drivers built after this date will support arbitrary
700    pointer offsets and strides.  Also removed NV10 rules on non-zero
701    strides, which cannot be used in OpenGL anyhow, and fixed a few other
702    typos.
703