blob: 7b2a751375acd9e883e3b8f6957174ef7a722eef [file] [log] [blame]
Name
NV_primitive_restart
Name Strings
GL_NV_primitive_restart
Contact
Matt Craighead, NVIDIA Corporation (mcraighead 'at' nvidia.com)
Notice
Copyright NVIDIA Corporation, 2002.
IP Status
NVIDIA Proprietary.
Status
Implemented in CineFX (NV30) Emulation driver, August 2002.
Shipping in Release 40 NVIDIA driver for CineFX hardware, January 2003.
Version
NVIDIA Date: August 29, 2002 (version 0.1)
Number
285
Dependencies
Written based on the wording of the OpenGL 1.3 specification.
Overview
This extension allows applications to easily and inexpensively
restart a primitive in its middle. A "primitive restart" is simply
the same as an End command, followed by another Begin command with
the same mode as the original. The typical expected use of this
feature is to draw a mesh with many triangle strips, though primitive
restarts are legal for all primitive types, even for points (where
they are not useful).
Although the EXT_multi_draw_arrays extension did reduce the overhead
of such drawing techniques, they still remain more expensive than one
would like.
This extension provides an extremely lightweight primitive restart,
which is accomplished by allowing the application to choose a special
index number that signals that a primitive restart should occur,
rather than a vertex being provoked. This index can be an arbitrary
32-bit integer for maximum application convenience.
In addition, for full orthogonality, a special OpenGL command is
provided to restart primitives when in immediate mode. This command
is not likely to increase performance in any significant fashion, but
providing it greatly simplifies the specification and implementation
of display list compilation and indirect rendering.
Issues
* What should the default primitive restart index be?
RESOLVED: Zero. It's tough to pick another number that is
meaningful for all three element data types. In practice, apps
are likely to set it to 0xFFFF or 0xFFFFFFFF.
* Are primitives other than triangle strips supported?
RESOLVED: Yes. One example of how this can be useful is for
rendering a heightfield. The "standard" way to render a
heightfield uses a number of triangle strips, one for each row of
the grid. Another method, which can produce higher-quality
meshes, is to render a number of 8-triangle triangle fans. This
has the effect of alternating the direction of tessellation, as
shown in the diagram below. Primitive restarts enhance the
performance of both techniques.
------------------------- -------------------------
| /| /| /| /| /| /| /| /| |\ | /|\ | /|\ | /|\ | /|
|/ |/ |/ |/ |/ |/ |/ |/ | | \|/ | \|/ | \|/ | \|/ |
------------------------- ---*-----*-----*-----*---
| /| /| /| /| /| /| /| /| | /|\ | /|\ | /|\ | /|\ |
|/ |/ |/ |/ |/ |/ |/ |/ | |/ | \|/ | \|/ | \|/ | \|
------------------------- -------------------------
Two strips Four fans (centers marked '*')
* How is this feature turned on and off?
RESOLVED: Via a glEnable/DisableClientState setting. It is not
possible to select a restart index that is guaranteed to be
unused.
* Is the immediate mode PrimitiveRestartNV needed?
RESOLVED: Yes. It is difficult to make indirect rendering to
work without it, and it is near impossible to make display lists
work without it. It is a very clean way to resolve these issues.
* How is indirect rendering handled?
RESOLVED: Because of PrimitiveRestartNV, it works very easily.
PrimitiveRestartNV has a wire protocol and therefore it can
easily be inserted as needed. The server tracks the current
Begin mode, relieving the client of this burden.
Note that in practice, we expect that this feature is essentially
useless for indirect rendering.
* How does this extension interact with NV_element_array and
NV_vertex_array_range?
RESOLVED: It doesn't, not even for performance. It should be
fast on hardware that supports the feature with or without the
use of element arrays, with or without vertex array range.
XXXmjc Is it feasible to guarantee fast performance even in the
non-VAR, non-CVA, non-DRE case??? Possibly not.
* Does this extension affect ArrayElement and DrawArrays, or just
DrawElements?
RESOLVED: All of them. It applies to ArrayElement and to the
rest as a consequence. It is likely not useful with any other
than DrawElements, but nevertheless not prohibited.
* In the case of ArrayElement, what happens if the restart index is
used outside Begin/End?
RESOLVED: Since this is defined as being equivalent to a call to
PrimitiveRestartNV, and PrimitiveRestartNV is an
INVALID_OPERATION when not inside Begin/End, this is just an
error.
* For DrawRangeElements/LockArrays purposes, must the restart index
lie within the start/end range?
RESOLVED: No, this would to some extent defeat the point if the
restart index was, e.g., 0xFFFFFFFF. I don't believe any spec
language is required here, since hitting this index does not
cause a vertex to be dereferenced.
* Should this state push/pop?
RESOLVED: Yes, as vertex array client state.
New Procedures and Functions
void PrimitiveRestartNV(void);
void PrimitiveRestartIndexNV(uint index);
New Tokens
Accepted by the <array> parameter of EnableClientState and
DisableClientState, by the <cap> parameter of IsEnabled, and by
the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and
GetDoublev:
PRIMITIVE_RESTART_NV 0x8558
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
PRIMITIVE_RESTART_INDEX_NV 0x8559
Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL Operation)
Add a section 2.6.X "Primitive Restarts", immediately after section
2.6.2 "Polygon Edges" (page 19):
"2.6.X Primitive Restarts
An OpenGL primitive may be restarted with the command
void PrimitiveRestartNV(void)
Between the execution of a Begin and its corresponding End, this
command is equivalent to a call to End, followed by a call to Begin
where the mode argument is the same mode as that used by the previous
Begin. Outside the execution of a Begin and its corresponding End,
this command generates the error INVALID_OPERATION."
Add PrimitiveRestartNV to the list of commands that are allowed
between Begin and End in section 2.6.3 "GL Commands within Begin/End"
(page 19).
Add to section 2.8 "Vertex Arrays", after the description of
ArrayElement (page 24):
"Primitive restarting is enabled or disabled by calling
EnableClientState or DisableClientState with parameter
PRIMITIVE_RESTART_NV. The command
void PrimitiveRestartIndexNV(uint index)
specifies the index of a vertex array element that is treated
specially when primitive restarting is enabled. When ArrayElement is
called between an execution of Begin and the corresponding execution
of End, if i is equal to PRIMITIVE_RESTART_INDEX_NV, then no vertex
data is derefererenced, and no current vertex state is modified.
Instead, it is as if PrimitiveRestartNV had been called."
Replace the last paragraph of section 2.8 "Vertex Arrays" (page 28)
with the following:
"If the number of supported texture units (the value of
MAX_TEXTURE_UNITS) is k, then the client state required to implement
vertex arrays consists of 7+k boolean values, 5+k memory pointers,
5+k integer stride values, 4+k symbolic constants representing array
types, 3+k integers representing values per element, and an unsigned
integer representing the restart index. In the initial state, the
boolean values are each disabled, the memory pointers are each null,
the strides are each zero, the array types are each FLOAT, the
integers representing values per element are each four, and the
restart index is zero."
Additions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization)
None.
Additions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment
Operations and the Frame Buffer)
None.
Additions to Chapter 5 of the OpenGL 1.3 Specification (Special Functions)
Add to the end of Section 5.4 "Display Lists":
"PrimitiveRestartIndexNV is not compiled into display lists, but is
executed immediately."
Additions to Chapter 6 of the OpenGL 1.3 Specification (State and
State Requests)
None.
GLX Protocol
The following rendering commands are sent to the server as part of
glXRender requests:
PrimitiveRestartNV
2 4 rendering command length
2 364 rendering command opcode
PrimitiveRestartIndexNV
2 8 rendering command length
2 365 rendering command opcode
4 CARD32 index
Errors
The error INVALID_OPERATION is generated if PrimitiveRestartNV is
called outside the execution of Begin and the corresponding execution
of End.
The error INVALID_OPERATION is generated if PrimitiveRestartIndexNV
is called between the execution of Begin and the corresponding
execution of End.
New State
Initial
Get Value Get Command Type Value Sec Attrib
--------- ----------- ---- ------- ---- ------------
PRIMITIVE_RESTART_NV IsEnabled B FALSE 2.8 vertex-array
PRIMITIVE_RESTART_INDEX_NV GetIntegerv Z+ 0 2.8 vertex-array
Revision History
none yet