1Name 2 3 NV_primitive_restart 4 5Name Strings 6 7 GL_NV_primitive_restart 8 9Contact 10 11 Matt Craighead, NVIDIA Corporation (mcraighead 'at' nvidia.com) 12 13Notice 14 15 Copyright NVIDIA Corporation, 2002. 16 17IP Status 18 19 NVIDIA Proprietary. 20 21Status 22 23 Implemented in CineFX (NV30) Emulation driver, August 2002. 24 Shipping in Release 40 NVIDIA driver for CineFX hardware, January 2003. 25 26Version 27 28 NVIDIA Date: August 29, 2002 (version 0.1) 29 30Number 31 32 285 33 34Dependencies 35 36 Written based on the wording of the OpenGL 1.3 specification. 37 38Overview 39 40 This extension allows applications to easily and inexpensively 41 restart a primitive in its middle. A "primitive restart" is simply 42 the same as an End command, followed by another Begin command with 43 the same mode as the original. The typical expected use of this 44 feature is to draw a mesh with many triangle strips, though primitive 45 restarts are legal for all primitive types, even for points (where 46 they are not useful). 47 48 Although the EXT_multi_draw_arrays extension did reduce the overhead 49 of such drawing techniques, they still remain more expensive than one 50 would like. 51 52 This extension provides an extremely lightweight primitive restart, 53 which is accomplished by allowing the application to choose a special 54 index number that signals that a primitive restart should occur, 55 rather than a vertex being provoked. This index can be an arbitrary 56 32-bit integer for maximum application convenience. 57 58 In addition, for full orthogonality, a special OpenGL command is 59 provided to restart primitives when in immediate mode. This command 60 is not likely to increase performance in any significant fashion, but 61 providing it greatly simplifies the specification and implementation 62 of display list compilation and indirect rendering. 63 64Issues 65 66 * What should the default primitive restart index be? 67 68 RESOLVED: Zero. It's tough to pick another number that is 69 meaningful for all three element data types. In practice, apps 70 are likely to set it to 0xFFFF or 0xFFFFFFFF. 71 72 * Are primitives other than triangle strips supported? 73 74 RESOLVED: Yes. One example of how this can be useful is for 75 rendering a heightfield. The "standard" way to render a 76 heightfield uses a number of triangle strips, one for each row of 77 the grid. Another method, which can produce higher-quality 78 meshes, is to render a number of 8-triangle triangle fans. This 79 has the effect of alternating the direction of tessellation, as 80 shown in the diagram below. Primitive restarts enhance the 81 performance of both techniques. 82 83 ------------------------- ------------------------- 84 | /| /| /| /| /| /| /| /| |\ | /|\ | /|\ | /|\ | /| 85 |/ |/ |/ |/ |/ |/ |/ |/ | | \|/ | \|/ | \|/ | \|/ | 86 ------------------------- ---*-----*-----*-----*--- 87 | /| /| /| /| /| /| /| /| | /|\ | /|\ | /|\ | /|\ | 88 |/ |/ |/ |/ |/ |/ |/ |/ | |/ | \|/ | \|/ | \|/ | \| 89 ------------------------- ------------------------- 90 91 Two strips Four fans (centers marked '*') 92 93 * How is this feature turned on and off? 94 95 RESOLVED: Via a glEnable/DisableClientState setting. It is not 96 possible to select a restart index that is guaranteed to be 97 unused. 98 99 * Is the immediate mode PrimitiveRestartNV needed? 100 101 RESOLVED: Yes. It is difficult to make indirect rendering to 102 work without it, and it is near impossible to make display lists 103 work without it. It is a very clean way to resolve these issues. 104 105 * How is indirect rendering handled? 106 107 RESOLVED: Because of PrimitiveRestartNV, it works very easily. 108 PrimitiveRestartNV has a wire protocol and therefore it can 109 easily be inserted as needed. The server tracks the current 110 Begin mode, relieving the client of this burden. 111 112 Note that in practice, we expect that this feature is essentially 113 useless for indirect rendering. 114 115 * How does this extension interact with NV_element_array and 116 NV_vertex_array_range? 117 118 RESOLVED: It doesn't, not even for performance. It should be 119 fast on hardware that supports the feature with or without the 120 use of element arrays, with or without vertex array range. 121 122 XXXmjc Is it feasible to guarantee fast performance even in the 123 non-VAR, non-CVA, non-DRE case??? Possibly not. 124 125 * Does this extension affect ArrayElement and DrawArrays, or just 126 DrawElements? 127 128 RESOLVED: All of them. It applies to ArrayElement and to the 129 rest as a consequence. It is likely not useful with any other 130 than DrawElements, but nevertheless not prohibited. 131 132 * In the case of ArrayElement, what happens if the restart index is 133 used outside Begin/End? 134 135 RESOLVED: Since this is defined as being equivalent to a call to 136 PrimitiveRestartNV, and PrimitiveRestartNV is an 137 INVALID_OPERATION when not inside Begin/End, this is just an 138 error. 139 140 * For DrawRangeElements/LockArrays purposes, must the restart index 141 lie within the start/end range? 142 143 RESOLVED: No, this would to some extent defeat the point if the 144 restart index was, e.g., 0xFFFFFFFF. I don't believe any spec 145 language is required here, since hitting this index does not 146 cause a vertex to be dereferenced. 147 148 * Should this state push/pop? 149 150 RESOLVED: Yes, as vertex array client state. 151 152New Procedures and Functions 153 154 void PrimitiveRestartNV(void); 155 void PrimitiveRestartIndexNV(uint index); 156 157New Tokens 158 159 Accepted by the <array> parameter of EnableClientState and 160 DisableClientState, by the <cap> parameter of IsEnabled, and by 161 the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and 162 GetDoublev: 163 164 PRIMITIVE_RESTART_NV 0x8558 165 166 Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, 167 GetFloatv, and GetDoublev: 168 169 PRIMITIVE_RESTART_INDEX_NV 0x8559 170 171Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL Operation) 172 173 Add a section 2.6.X "Primitive Restarts", immediately after section 174 2.6.2 "Polygon Edges" (page 19): 175 176 "2.6.X Primitive Restarts 177 178 An OpenGL primitive may be restarted with the command 179 180 void PrimitiveRestartNV(void) 181 182 Between the execution of a Begin and its corresponding End, this 183 command is equivalent to a call to End, followed by a call to Begin 184 where the mode argument is the same mode as that used by the previous 185 Begin. Outside the execution of a Begin and its corresponding End, 186 this command generates the error INVALID_OPERATION." 187 188 189 Add PrimitiveRestartNV to the list of commands that are allowed 190 between Begin and End in section 2.6.3 "GL Commands within Begin/End" 191 (page 19). 192 193 194 Add to section 2.8 "Vertex Arrays", after the description of 195 ArrayElement (page 24): 196 197 "Primitive restarting is enabled or disabled by calling 198 EnableClientState or DisableClientState with parameter 199 PRIMITIVE_RESTART_NV. The command 200 201 void PrimitiveRestartIndexNV(uint index) 202 203 specifies the index of a vertex array element that is treated 204 specially when primitive restarting is enabled. When ArrayElement is 205 called between an execution of Begin and the corresponding execution 206 of End, if i is equal to PRIMITIVE_RESTART_INDEX_NV, then no vertex 207 data is derefererenced, and no current vertex state is modified. 208 Instead, it is as if PrimitiveRestartNV had been called." 209 210 211 Replace the last paragraph of section 2.8 "Vertex Arrays" (page 28) 212 with the following: 213 214 "If the number of supported texture units (the value of 215 MAX_TEXTURE_UNITS) is k, then the client state required to implement 216 vertex arrays consists of 7+k boolean values, 5+k memory pointers, 217 5+k integer stride values, 4+k symbolic constants representing array 218 types, 3+k integers representing values per element, and an unsigned 219 integer representing the restart index. In the initial state, the 220 boolean values are each disabled, the memory pointers are each null, 221 the strides are each zero, the array types are each FLOAT, the 222 integers representing values per element are each four, and the 223 restart index is zero." 224 225Additions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization) 226 227 None. 228 229Additions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment 230Operations and the Frame Buffer) 231 232 None. 233 234Additions to Chapter 5 of the OpenGL 1.3 Specification (Special Functions) 235 236 Add to the end of Section 5.4 "Display Lists": 237 238 "PrimitiveRestartIndexNV is not compiled into display lists, but is 239 executed immediately." 240 241Additions to Chapter 6 of the OpenGL 1.3 Specification (State and 242State Requests) 243 244 None. 245 246GLX Protocol 247 248 The following rendering commands are sent to the server as part of 249 glXRender requests: 250 251 PrimitiveRestartNV 252 2 4 rendering command length 253 2 364 rendering command opcode 254 255 PrimitiveRestartIndexNV 256 2 8 rendering command length 257 2 365 rendering command opcode 258 4 CARD32 index 259 260Errors 261 262 The error INVALID_OPERATION is generated if PrimitiveRestartNV is 263 called outside the execution of Begin and the corresponding execution 264 of End. 265 266 The error INVALID_OPERATION is generated if PrimitiveRestartIndexNV 267 is called between the execution of Begin and the corresponding 268 execution of End. 269 270New State 271 272 Initial 273 Get Value Get Command Type Value Sec Attrib 274 --------- ----------- ---- ------- ---- ------------ 275 PRIMITIVE_RESTART_NV IsEnabled B FALSE 2.8 vertex-array 276 PRIMITIVE_RESTART_INDEX_NV GetIntegerv Z+ 0 2.8 vertex-array 277 278Revision History 279 280 none yet 281