1Name 2 3 ARB_transform_feedback3 4 5Name Strings 6 7 GL_ARB_transform_feedback3 8 9Contact 10 11 Pat Brown (pbrown 'at' nvidia.com) 12 13Contributors 14 15 Barthold Lichtenbelt, NVIDIA 16 Bill Licea-Kane, AMD 17 Bruce Merry, ARM 18 Graham Sellers, AMD 19 Greg Roth, NVIDIA 20 Jeff Bolz, NVIDIA 21 Nick Haemel, AMD 22 Pierre Boudier, AMD 23 Piers Daniell, NVIDIA 24 25Notice 26 27 Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at 28 http://www.khronos.org/registry/speccopyright.html 29 30Specification Update Policy 31 32 Khronos-approved extension specifications are updated in response to 33 issues and bugs prioritized by the Khronos OpenGL Working Group. For 34 extensions which have been promoted to a core Specification, fixes will 35 first appear in the latest version of that core Specification, and will 36 eventually be backported to the extension document. This policy is 37 described in more detail at 38 https://www.khronos.org/registry/OpenGL/docs/update_policy.php 39 40Status 41 42 Complete. Approved by the ARB at the 2010/01/22 F2F meeting. 43 Approved by the Khronos Board of Promoters on March 10, 2010. 44 45Version 46 47 Last Modified Date: 03/23/2010 48 Revision: 12 49 50Number 51 52 ARB Extension #94 53 54Dependencies 55 56 EXT_transform_feedback, NV_transform_feedback, or OpenGL 3.0 is required. 57 58 OpenGL 2.0 is required. 59 60 This extension interacts with EXT_transform_feedback, 61 NV_transform_feedback, and NV_transform_feedback2. 62 63 This extension interacts with ARB_gpu_shader5 and NV_gpu_program5. 64 65 This extension is written against the OpenGL 3.2 specification (Core 66 Profile). 67 68 This extension builds up and is written against various language in the 69 EXT_transform_feedback and NV_transform_feedback specifications. 70 71Overview 72 73 This extension further extends the transform feedback capabilities 74 provided by the EXT_transform_feedback, NV_transform_feedback, and 75 NV_transform_feedback2 extensions. Those extensions provided a new 76 transform feedback mode, where selected vertex attributes can be recorded 77 to a buffer object for each primitive processed by the GL. 78 79 This extension provides increased flexibility in how vertex attributes can 80 be written to buffer objects. Previous extensions allowed applications to 81 record a set of attributes interleaved into a single buffer object 82 (interleaved mode) or to record into multiple objects, but with only a 83 single attribute per buffer (separate mode). This extension extends 84 interleaved mode to write into multiple buffers, with multiple attributes 85 per buffer. This capability is supported for all three styles of 86 transform feedback: 87 88 - "EXT"-style GLSL transform feedback (EXT_transform_feedback), where a 89 list of varyings is provided prior to linking a program object and is 90 used whenever that program object is used. 91 92 - "NV"-style GLSL transform feedback (NV_transform_feedback), where 93 "locations" of active varyings are queried after linking and are then 94 passed to a function that sets the active transform feedback varyings 95 for the program object. Unlike the "EXT"-style mode, the set of 96 varyings to capture can be changed without relinking. 97 98 - Transform feedback for fixed-function or assembly vertex/geometry 99 shaders (NV_transform_feedback), where applications specify a set of 100 canonical attribute enums/numbers to capture. 101 102 Additionally, this extension adds new support for multiple separate 103 vertex streams. New geometry shader functionality provided by the 104 ARB_gpu_shader5 and NV_gpu_program5 extensions allows geometry shaders 105 to direct each vertex arbitrarily at a specified vertex stream. For 106 example, a geometry program might write each "regular" vertex it emits 107 to one vertex stream while writing some per-primitive data it computes 108 to a second vertex stream. This extension allows applications to 109 choose a vertex stream for each buffer object it writes to, and allows 110 the vertices written to each vertex stream to be recorded in separate 111 buffer objects. Only one stream may be selected for rasterization, 112 and in the initial implementation, the geometry shader output topology 113 must be POINTS if multiple streams are used. When geometry shaders 114 are not used, or when an old geometry shader not writing multiple 115 streams is used, all vertices produced by the GL are directed at the 116 stream numbered zero. The set of transform feedback-related query 117 targets is extended to accommodate multiple vertex streams, so it is 118 possible to count the number of processed and recorded primitives for 119 each stream separately. 120 121IP Status 122 123 No known IP claims. 124 125New Procedures and Functions 126 127 void DrawTransformFeedbackStream(enum mode, uint id, uint stream); 128 void BeginQueryIndexed(enum target, uint index, uint id); 129 void EndQueryIndexed(enum target, uint index); 130 void GetQueryIndexediv(enum target, uint index, enum pname, int *params); 131 132New Tokens 133 134 Accepted by the <pname> parameter of GetBooleanv, GetDoublev, GetIntegerv, 135 and GetFloatv: 136 137 MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 138 MAX_VERTEX_STREAMS 0x8E71 139 140Additions to Chapter 2 of the OpenGL 3.2 Specification (OpenGL Operation) 141 142 (Modify the error behavior of transform feedback buffer binding APIs to 143 treat the new constant MAX_TRANSFORM_FEEDBACK_BUFFERS as the number of 144 binding points.) 145 146 Buffer objects are made to be targets of transform feedback by calling one 147 of the commands 148 149 void BindBufferRange(enum target, uint index, uint buffer, 150 intptr offset, sizeiptr size); 151 void BindBufferBase(enum target, uint index, uint buffer); 152 153 ... The error INVALID_VALUE is generated if <index> is greater than or 154 equal to the value of MAX_TRANSFORM_FEEDBACK_BUFFERS. 155 156 ... 157 158 Transform feedback can operate using one of two buffer modes. In 159 interleaved mode, the values of one or more varying variables written by a 160 vertex or geometry shader are written, interleaved, into the buffer 161 objects bound to one or more transform feedback binding points. The list 162 of varyings provided for capture in interleaved mode may include special 163 separator values, which can be used to direct subsequent varyings to the 164 next binding point. Each non-separator varying is written to the binding 165 point numbered <n>, where <n> is the number of separator values preceding 166 it in the list. If more than one varying variable is written to a buffer 167 object, they will be recorded in the order specified by 168 TransformFeedbackVaryings (section 2.11.6). In separate mode, the first 169 varying variable specified by TransformFeedbackVaryings is written to 170 the first transform feedback binding point; subsequent varying variables 171 are written to the subsequent transform feedback binding points. 172 173 When using a geometry shader or program that writes vertices to multiple 174 vertex streams, each vertex emitted may trigger a new primitive in the 175 vertex stream to which it was emitted. If transform feedback is active, 176 the varyings of the primitive are written to a transform feedback binding 177 point if and only if the varyings directed at that binding point belong to 178 the vertex stream in question. All varyings assigned to a given binding 179 point are required to come from a single vertex stream. 180 181 ... 182 183 184 (Modify Section 2.14, Asynchronous Queries) 185 186 After the description of BeginQuery, p.91: 187 188 Query targets also support multiple indexed queries. A query object may be 189 created and made active on an indexed query target by calling: 190 191 void BeginQueryIndexed(enum target, uint index, uint id); 192 193 <target> indicates the type of query to be performed as in BeginQuery. 194 <index> is the index of the query and must be between 0 and a <target>- 195 specific maximum. If <index> is outside of this range, BeginQueryIndexed will 196 generate the INVALID_VALUE error. The number of indexed queries supported by 197 specific targets is one, unless indicated otherwise in following sections. 198 Calling BeginQuery is equivalent to calling BeginQueryIndexed with <index> 199 set to zero. 200 201 After the description of EndQuery, p.91: 202 203 The command 204 205 void EndQueryIndexed(enum target, uint index); 206 207 may be used to mark the end of the query currently active at index <index> 208 of <target>, and must be between zero and the <target>-specific maximum. 209 If <index> is outside of this range, EndQuery will generated the INVALID_VALUE 210 error. Calling EndQuery is equivalent to calling EndQueryIndexed with 211 <index> set to zero. 212 213 (Modify Section 2.17, Primitive Queries. The only substantial change is 214 to modify language to reflect that we have primitive counters for each 215 vertex stream.) 216 217 Primitive queries use query objects to track the number of primitives in 218 each vertex stream that are generated by the GL and the number of 219 primitives in each vertex stream that are written to buffer objects in 220 transform feedback mode. 221 222 When BeginQueryIndexed is called with a <target> of PRIMITIVES_GENERATED, 223 the primitives generated count maintained by the GL for the vertex stream 224 <index> is set to zero. There is a separate query counter for each stream. 225 The number of vertex streams is given by the value of the implementation- 226 dependent constant MAX_VERTEX_STREAMS. If <index> is not an integer in the 227 range zero to the value of MAX_VERTEX_STREAMS minus one, the error 228 INVALID_VALUE is generated. When a generated primitive query for a vertex 229 stream is active, the primitives-generated count is incremented every time 230 a primitive emitted to that stream reaches the Discarding Rasterization 231 stage (see Section 3.x) right before rasterization. This counter is 232 incremented whether or not transform feedback is active. This counter counts 233 the number of primitives emitted by a geometry shader, if active, possibly 234 further tessellated into separate primitives during the transform feedback 235 stage, if active. 236 237 When BeginQueryIndexed is called with a <target> of 238 TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, the transform feedback primitives 239 written count maintained by the GL for vertex stream <index> is set to zero. 240 There is a separate query and counter for each vertex stream. If <index> is 241 not an integer in the range zero to the value of MAX_VERTEX_STREAMS minus 242 one, the error INVALID_VALUE is generated. When a transform feedback 243 primitives written query for a vertex stream is active, the counter for that 244 vertex stream is incremented every time the vertices of a primitive written 245 to that stream are recorded into one or more buffer objects. If transform 246 feedback is not active or if a primitive to be recorded does not fit in a 247 buffer object, the counter is not incremented. 248 249 These two types of queries can be used together to determine if all 250 primitives in a given vertex stream have been written to the bound 251 feedback buffers; if both queries are run simultaneously and the query 252 results are equal, all primitives have been written to the buffer(s). If 253 the number of primitives written is less than the number of primitives 254 generated, one or more buffers overflowed. 255 256 257 (Modify Section 2.11.6 "Varying Variables", p. 71.) 258 259 Each program object can specify a set of one or more vertex or geometry 260 shader output variables to be recorded in transform feedback mode (see 261 section 2.16). When a geometry shader is active (see section 2.12), 262 transform feedback records the values of the selected geometry shader 263 output variables from the emitted vertices. Otherwise, the values of the 264 selected vertex shader output variables are recorded. The values to record 265 are specified with the command 266 267 void TransformFeedbackVaryings(uint program, sizei count, 268 const char **varyings, 269 enum bufferMode) 270 271 <program> specifies the program object. <count> specifies the number of 272 varying variables used for transform feedback. <varyings> is an array of 273 <count> zero-terminated strings specifying the names of the varying 274 variables to use for transform feedback. Varying variables are written out 275 in the order they appear in the array varyings. <bufferMode> is either 276 INTERLEAVED_ATTRIBS or SEPARATE_ATTRIBS, and identifies the mode used to 277 capture the varying variables when transform feedback is active. The error 278 INVALID_VALUE is generated if program is not the name of a program object, 279 or if <bufferMode> is SEPARATE_ATTRIBS and <count> is greater than the 280 value of the implementation-dependent limit 281 MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS. 282 283 If a string in <varyings> is "gl_NextBuffer", it does not identify a 284 varying variable, but instead serves as a buffer separator value to 285 direct subsequent varyings at the next transform feedback binding point. 286 If a string in <varyings> is "gl_SkipComponents1", "gl_SkipComponents2", 287 "gl_SkipComponents3", or "gl_SkipComponents4", it also does not identify a 288 specific varying variable. Instead, such values are treated as requesting 289 that the GL skip the next one to four components of varying data. 290 Skipping components this way is equivalent to specifying a one- to four- 291 component varying with undefined values, except that the corresponding 292 memory in the buffer object is not modified. Such array entries are 293 counted as being written to the buffer object for the purposes of 294 determining whether the requested attributes exceed per-buffer component 295 count limits. Each component skipped is considered to occupy a single 296 float. 297 298 The error INVALID_OPERATION is generated if any pointer in <varyings> 299 identifies the special names "gl_NextBuffer", "gl_SkipComponents1", 300 "gl_SkipComponents2", "gl_SkipComponents3", or "gl_SkipComponents4" and 301 <bufferMode> is not INTERLEAVED_ATTRIBS, or if the number of 302 "gl_NextBuffer" pointers in <varyings> is greater than or equal to the 303 limit MAX_TRANSFORM_FEEDBACK_BUFFERS. 304 305 The state set by TransformFeedbackVaryings has no effect on the execution 306 of the program until <program> is subsequently linked. When LinkProgram is 307 called, the program is linked so that the values of the specified varying 308 variables for the vertices of each primitive generated by the GL are 309 written to a single buffer object (if the buffer mode is 310 INTERLEAVED_ATTRIBS) or multiple buffer objects (if the buffer mode is 311 SEPARATE_ATTRIBS). A program will fail to link if: 312 313 * the <count> specified by TransformFeedbackVaryings is non-zero, but 314 the program object has no vertex or geometry shader; 315 316 * any variable name specified in the <varyings> array is not one of 317 "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2", 318 "gl_SkipComponents3", or "gl_SkipComponents4", and is not declared as 319 an output in the geometry shader (if present) or the vertex shader (if 320 no geometry shader is present); 321 322 * any two entries in the <varyings> array specify the same varying 323 variable; 324 325 * the total number of components to capture in any varying variable in 326 <varyings> is greater than the constant 327 MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS and the buffer mode is 328 SEPARATE_ATTRIBS; 329 330 * the total number of components to capture is greater than the constant 331 MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS and the buffer 332 mode is INTERLEAVED_ATTRIBS; or 333 334 * the set of varyings to capture to any single binding point includes 335 varyings from more than one vertex stream. 336 337 (Add a new paragraph describing the interaction of separators and 338 GetTransformFeedbackVarying after the GetTransformFeedBackVarying 339 description.) 340 341 Special varying names (e.g., "gl_NextBuffer", "gl_SkipComponents1") passed 342 to TransformFeedbackVaryings in the <varyings> array are counted as 343 varyings to be recorded for the purposes of determining the value of 344 TRANSFORM_FEEDBACK_VARYINGS and for determining the variable selected 345 by <index> in GetTransformFeedbackVarying. If <index> identifies 346 "gl_NextBuffer", the values zero and NONE will be written to <size> and 347 <type>, respectively. If <index> is of the form "gl_SkipComponents<n>", 348 the value NONE, will be written to <type> and the number of components <n> 349 will be written to <size>. 350 351 (Modify Section 2.Y.3, Transform Feedback Draw Operations, added by the 352 NV_transform_feedback2 extension, to add a new DrawTransformFeedback API 353 to select the vertex count from an arbitrary vertex stream.) 354 355 ... The number of vertices captured from each vertex stream during 356 transform feedback are stored in the corresponding transform feedback 357 object and may be used in conjunction with the commands 358 359 void DrawTransformFeedback(enum mode, uint id); 360 void DrawTransformFeedbackStream(enum mode, uint id, uint stream); 361 362 to replay the captured vertices. DrawTransformFeedbackStream is 363 equivalent to calling DrawArrays with <mode> set to <mode>, <first> set to 364 zero, and <count> set to the number of vertices captured from the vertex 365 stream numbered <stream> the last time transform feedback was active on 366 the transform feedback object named by <id>. The error INVALID_VALUE 367 is generated if <stream> is greater than or equal to the value of 368 MAX_VERTEX_STREAMS. DrawTransformFeedback is equivalent to calling 369 DrawTransformFeedbackStream with a <stream> of zero. The error 370 INVALID_VALUE is generated if <id> is not the name of a transform feedback 371 object. The error INVALID_OPERATION is generated if 372 EndTransformFeedback has never been called while the object named by 373 <id> was bound. No error is generated if the transform feedback object 374 named by <id> is active; the vertex count used for the rendering operation 375 is set by the previous EndTransformFeedback command. Note that the 376 vertex count is from the number of vertices recorded to the selected 377 vertex stream during the transform feedback operation. If no varyings 378 belonging to the selected vertex stream are recorded, the corresponding 379 vertex count will be zero even if complete primitives were emitted to the 380 selected stream. 381 382 383Additions to Chapter 3 of the OpenGL 3.2 Specification (Rasterization) 384 385 (Modify Section 3.1, Discarding Primitives Before Rasterization. 386 State that only vertices sent to stream zero are processed further.) 387 388 (insert at the beginning of the section, prior to language explaining 389 RASTERIZER_DISCARD) 390 391 Primitives sent to the vertex stream zero are processed further; 392 primitives emitted to any other stream are discarded. When geometry 393 shaders are disabled, all vertices are considered to be emitted to stream 394 zero. 395 396Additions to Chapter 4 of the OpenGL 3.2 Specification (Per-Fragment 397Operations and the Frame Buffer) 398 399 None. 400 401 402Additions to Chapter 5 of the OpenGL 3.2 (Compatibility Profile) 403Specification (Special Functions) 404 405 Modify Section 5.2, Selection, p. 351 406 407 (modify the fourth paragraph, p. 234) In selection mode, if a point, line, 408 or polygon that would otherwise be sent to the rasterizer intersects with 409 the clip volume (section 2.12) then this primitive causes a selection hit. 410 Coordinates produced by a RasterPos command that intersect the clip volume 411 also cause a selection hit, as do the coordinates from a WindowPos 412 command. In case of polygons, no hit... 413 414 415Additions to Chapter 6 of the OpenGL 3.2 Specification (State and 416State Requests) 417 418 (Modify section 6.1.6, Asynchronous Queries) 419 420 Replace the description of GetQueryiv, p.256: 421 422 Information about an indexed query target may be queried with the commands 423 424 void GetQueryIndexediv(enum target, uint index, enum pname, int *params); 425 void GetQueryiv(enum taret, enum pname, int *params); 426 427 where <target> identifies the query target and must be SAMPLES_PASSED for 428 occlusion queries and PRIMITIVES_GENERATED or 429 TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN for primitive queries. <index> is the 430 index of the query target must be between zero and a <target>-specific 431 maximum. If <index> is outside of this range, GetQueryIndexediv will generate 432 the INVALID_VALUE error. Calling GetQueryiv is equivalent to calling 433 GetQueryIndexediv with <index> set to zero. 434 435 If <pname> is CURRENT_QUERY, the name of the currently active query for 436 index <index> of <target>, or zero if no query is active for that index 437 of <target>, will be placed in <params>. 438 439 If <pname> is QUERY_COUNTER_BITS, <index> is ignored and the implementation- 440 dependent number of bits used to hold the query result for target will be 441 placed in params. The number of query counter bits may be zero, in which 442 case the counter contains no useful information. 443 444 (Retain remainder of original language from description of GetQueryiv.) 445 446 (Minor change to the Section 6.1.8 language to change error behavior 447 of transform feedback query APIs to treat the new constant 448 MAX_TRANSFORM_FEEDBACK_BUFFERS as the number of binding points.) 449 450 To query which buffer objects are bound to the array of transform feedback 451 binding points and will be used when transform feedback is active, call 452 GetIntegeri_v() with <param> set to TRANSFORM_FEEDBACK_BUFFER_BINDING. 453 <index> must be in the range zero to the value of 454 MAX_TRANSFORM_FEEDBACK_BUFFERS - 1. The name of the buffer object bound 455 to <index> is returned in <values>. If no buffer object is bound for 456 <index>, zero is returned in <values>. The error INVALID_VALUE is 457 generated if <index> is greater than or equal to the value of 458 MAX_TRANSFORM_FEEDBACK_BUFFERS. 459 460 To query the starting offset or size of the range of each buffer object 461 binding used for transform feedback, call GetInteger64i_v() with param 462 set to TRANSFORM_FEEDBACK_BUFFER_START or TRANSFORM_FEEDBACK_BUFFER_SIZE 463 respectively. <index> must be in the range 0 to the value of 464 MAX_TRANSFORM_FEEDBACK_BUFFERS - 1. If the parameter (starting offset or 465 size) was not specified when the buffer object was bound, zero is 466 returned. If no buffer object is bound to index, -1 is returned. The 467 error INVALID_VALUE is generated if <index> is greater than or equal to 468 the limit MAX_TRANSFORM_FEEDBACK_BUFFERS. 469 470Additions to Appendix A of the OpenGL 3.2 Specification (Invariance) 471 472 None. 473 474Additions to the AGL/GLX/WGL Specifications 475 476 None. 477 478GLX Protocol 479 480 TBD 481 482Dependencies on NV_gpu_program5 and ARB_gpu_shader5 483 484 If support for multiple vertex streams is not provided (by 485 NV_gpu_program5, ARB_gpu_shader5, or a similar extension), the spec 486 language does not need to change. However, the value of the limit 487 MAX_VERTEX_STREAMS will be 1. In this case, the new query object 488 targets, language referring to multiple vertex streams, and the 489 TransformFeedbackStreamAttribsNV function (described immediately below in 490 the "NV_transform_feedback" dependencies section) would be unnecessary but 491 not otherwise harmful. 492 493 We expect that some extension providing multiple vertex streams will be 494 supported on all implementations of this extension. 495 496 497Dependencies on NV_transform_feedback and NV_transform_feedback2 498 499 If NV_transform_feedback or NV_transform_feedback2 is supported the 500 following additional edits are required: 501 502 New Procedures and Functions 503 504 void TransformFeedbackStreamAttribsNV(sizei count, 505 const int * attribs, 506 sizei nbuffers, 507 const int *bufstreams, 508 enum bufferMode); 509 510 New Tokens 511 512 Accepted in the <locations> array of TransformFeedbackVaryingsNV 513 when <bufferMode> is INTERLEAVED_ATTRIBS: 514 515 NEXT_BUFFER_NV -2 516 SKIP_COMPONENTS4_NV -3 517 SKIP_COMPONENTS3_NV -4 518 SKIP_COMPONENTS2_NV -5 519 SKIP_COMPONENTS1_NV -6 520 521 (Modify NV_transform_feedback section that adds to Section 2.Y, Transform 522 Feedback.) 523 524 (Modify the error behavior of transform feedback buffer binding APIs to 525 treat the new constant MAX_TRANSFORM_FEEDBACK_BUFFERS as the number of 526 binding points.) 527 528 Buffer objects are made to be targets of transform feedback by calling one 529 of 530 531 void BindBufferRange(enum target, uint index, uint buffer, 532 intptr offset, sizeiptr size) 533 void BindBufferOffsetNV(enum target, uint index, uint buffer, 534 intptr offset) 535 void BindBufferBase(enum target, uint index, uint buffer) 536 537 ... The error INVALID_VALUE is generated if <index> is greater than or 538 equal to the value of MAX_TRANSFORM_FEEDBACK_BUFFERS. 539 540 ... 541 542 (Modify the section that describes TransformFeedbackAttribsNV for 543 fixed-function vertex processing.) 544 545 When no vertex or geometry shader is active, transform feedback may be 546 used to record vertex attribute values written by fixed-function vertex 547 processing or by an assembly vertex or geometry program. Both buffer 548 modes described above are supported. The set of attributes recorded, and 549 their order, is specified by TransformFeedbackAttribsNV (section 2.Y). 550 551 (modify language from NV_transform_feedback describing 552 TransformFeedbackAttribsNV, used to capture outputs from fixed-function 553 and assembly programs) 554 555 The set of vertex attributes to capture when no vertex or geometry shader 556 is active is specified by the command 557 558 void TransformFeedbackAttribsNV(sizei count, const int *attribs, 559 enum bufferMode) 560 561 <bufferMode> is one of INTERLEAVED_ATTRIBS or SEPARATE_ATTRIBS, 562 and identifies the mode used to capture the attributes when transform 563 feedback is active. <attribs> is an array of 3*<count> values specifying 564 the set of vertex attribute vectors to record. For the <i>th attribute, 565 array element 3*<i>+0 specifies the type of attribute to capture, as 566 described in table X.1, or one of the special values described below. The 567 error INVALID_ENUM is generated if this value is not found in table X.1. 568 Array element 3*<i>+1 specifies the number of components to record from 569 the specified attribute. The error INVALID_VALUE is generated if this 570 value is not supported for the specified attribute type, as indicated in 571 Table X.1. Array element 3*<i>+2 identifies the attribute number used for 572 attribute types with more than one attribute vector (e.g., texture 573 coordinates, generic attributes). For attribute types with only a single 574 attribute, this element is ignored. Otherwise, it identifies the specific 575 attribute number. The error INVALID_VALUE is generated if this element is 576 greater than or equal to the number of attributes available for the 577 specified type. 578 579 Attribute type entries in <attribs> with the value NEXT_BUFFER_NV do not 580 identify a vertex attribute, but instead serve as buffer separator values 581 to direct subsequent attributes at the next transform feedback binding 582 point. Attribute type entries in <attribs> with the value 583 SKIP_COMPONENTS1_NV, SKIP_COMPONENTS2_NV, SKIP_COMPONENTS3_NV, or 584 SKIP_COMPONENTS4_NV also do not identify a specific vertex attribute type. 585 These values are treated as requesting that the GL skip the next one to 586 four components of attribute data. Skipping components this way is 587 equivalent to writing one to four components of undefined vertex attribute 588 data, except that the corresponding memory in the buffer object is not 589 modified. Such array entries are counted as being written to the buffer 590 object for the purposes of determining whether the requested attributes 591 exceed per-buffer component count limits. When an attribute type is 592 NEXT_BUFFER_NV or of the form SKIP_COMPONENTS<n>_NV, the next two values 593 in <attribs>, specifying component count and attribute number, are 594 ignored. 595 596 The error INVALID_OPERATION is generated if any such value is 597 NEXT_BUFFER_NV, SKIP_COMPONENTS1_NV, SKIP_COMPONENTS2_NV, 598 SKIP_COMPONENTS3_NV, or SKIP_COMPONENTS4_NV, and <bufferMode> is not 599 INTERLEAVED_ATTRIBS. 600 601 permitted GPU_program4 602 attrib sizes index? result name 603 --------------------- -------- -------- -------------- 604 POSITION 1,2,3,4 no position 605 PRIMARY_COLOR 1,2,3,4 no color.front.primary 606 SECONDARY_COLOR_NV 1,2,3,4 no color.front.secondary 607 BACK_PRIMARY_COLOR_NV 1,2,3,4 no color.back.primary 608 BACK_SECONDARY_COLOR_NV 1,2,3,4 no color.back.secondary 609 FOG_COORDINATE 1 no fogcoord 610 POINT_SIZE 1 no pointsize 611 TEXTURE_COORD_NV 1,2,3,4 yes texcoord[index] 612 CLIP_DISTANCE_NV 1 yes clip[index] 613 VERTEX_ID_NV 1 no vertexid 614 PRIMITIVE_ID_NV 1 no primid 615 GENERIC_ATTRIB_NV 1,2,3,4 yes attrib[index] 616 LAYER_NV 1 no layer 617 NEXT_BUFFER_NV 0 no ---- 618 SKIP_COMPONENTS1_NV 1 no ---- 619 SKIP_COMPONENTS2_NV 2 no ---- 620 SKIP_COMPONENTS3_NV 3 no ---- 621 SKIP_COMPONENTS4_NV 4 no ---- 622 623 Table X.1: Transform Feedback Attribute Specifiers. The "attrib" 624 column specifies the attribute types available to record. The 625 "permitted sizes" column indicate the legal component count values for 626 the attribute type. The "index" column indicates if the attribute type 627 has more than one attribute vector and requires an attribute number. 628 The "GPU_program4 result name" column shows the suffix of the result 629 variable binding recorded for each attribute type. 630 631 The attributes captured by TransformFeedbackAttribsNV always come from 632 primitives emitted to vertex stream zero. However, the command 633 634 void TransformFeedbackStreamAttribsNV(sizei count, const int * attribs, 635 sizei nbuffers, 636 const int *bufstreams, 637 enum bufferMode); 638 639 can capture vertex attributes from arbitrary vertex streams. <count>, 640 <attribs>, and <bufferMode> operate as above. <bufstreams> is an array of 641 <nbuffers> vertex stream numbers used for each transform feedback binding 642 point. When a new primitive is emitted to a given vertex stream, vertex 643 attributes are recorded only to those binding points whose corresponding 644 <bufstreams> value equals the vertex stream number. The error 645 INVALID_VALUE is generated if any value in <bufstreams> is greater than or 646 equal to the value of MAX_VERTEX_STREAMS. The error INVALID_OPERATION is 647 generated if the number of binding points specified by <attribs> is not 648 equal to <nbuffers>. If <bufferMode> is INTERLEAVED_ATTRIBS, the 649 number of binding points used is one plus the number of NEXT_BUFFER_NV 650 values in <attribs>. If <bufferMode> is SEPARATE_ATTRIBS, number of 651 binding points used is given by <count>. 652 653 The number of attributes or attribute components that may be recorded in 654 transform feedback mode is limited. The error INVALID_OPERATION is 655 generated by TransformFeedbackAttribsNV or 656 TransformFeedbackStreamAttribsNV if 657 658 * <bufferMode> is SEPARATE_ATTRIBS, and <count> is greater than the 659 limit MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV; 660 661 * <bufferMode> is INTERLEAVED_ATTRIBS, and the total number of 662 vertex components to record to any single binding point is greater 663 than the limit MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV; or 664 665 * <bufferMode> is INTERLEAVED_ATTRIBS, and the number of binding 666 points used (one plus the number of NEXT_BUFFER_NV values in 667 <attribs>) is greater than the limit 668 MAX_TRANSFORM_FEEDBACK_BUFFERS. 669 670 The set of attributes to record, set by TransformFeedbackAttribsNV or 671 TransformFeedbackStreamAttribsNV, has no effect if a vertex or geometry 672 shader is active. 673 674 The value for any attribute specified to be recorded to a buffer object 675 but not actually written by a vertex or geometry program is undefined. 676 The value of PRIMITIVE_ID_NV or LAYER_NV for a vertex is defined if and 677 only if a geometry program is active and that program writes to the result 678 variable "result.primid". The value of VERTEX_ID_NV is only defined if 679 and only if a vertex program is active, no geometry program is active, and 680 the vertex program writes to the output attribute "result.id". 681 682 683 (Fold in corresponding language from NV_transform_feedback providing 684 additional mechanisms for specifying the set of varyings or attributes to 685 capture in transform feedback. The only new functionality provided 686 by this extension is the ability to provide separator values to write to 687 multiple buffers in interleaved mode.) 688 689 Additionally, it is also possible to change the set of varying variables 690 to record in transform feedback mode immediately without relinking the 691 program object. The command 692 693 void TransformFeedbackVaryingsNV(uint program, sizei count, 694 const int *locations, 695 enum bufferMode) 696 697 sets the transform feedback state for <program> and specifies the set of 698 varying variables to record when transform feedback is active. 699 <bufferMode> is either INTERLEAVED_ATTRIBS or SEPARATE_ATTRIBS and 700 identifies the mode used to capture the varying variables when transform 701 feedback is active. The array <locations> contains <count> integers, each 702 of which must be either a location of an active varying variable in 703 <program> as queried with GetActiveVaryingNV() or one of the special 704 values described below. 705 706 If an entry in <locations> has the value NEXT_BUFFER_NV, it does not 707 identify a varying variable. Instead, it serves as a buffer separator 708 value to direct subsequent varyings at the next transform feedback binding 709 point. If any entry is SKIP_COMPONENTS1_NV, SKIP_COMPONENTS2_NV, 710 SKIP_COMPONENTS3_NV, or SKIP_COMPONENTS4_NV, it also does not identify a 711 specific varying variable. Instead, such values are treated as requesting 712 that the GL skip the next one to four components of varying data. 713 Skipping components this way is equivalent to specifying a one- to four- 714 component varying with undefined values, except that the corresponding 715 memory in the buffer object is not modified. Such array entries are 716 counted as being written to the buffer object for the purposes of 717 determining whether the requested attributes exceed per-buffer component 718 count limits. 719 720 The error INVALID_VALUE is generated if <program> is not the name of a 721 program object or if <bufferMode> is SEPARATE_ATTRIBS and <count> is 722 greater than the limit MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS. The 723 error INVALID_OPERATION is generated: 724 725 * if <program> has not been linked successfully; 726 727 * if <program> is being used by any active transform feedback object; 728 729 * if any value in <locations> is neither NEXT_BUFFER_NV nor the location 730 of an active varying variable in <program>; 731 732 * if any value in <locations> (other than NEXT_BUFFER_NV) appears more 733 than once in the array; 734 735 * if any value in <locations> is NEXT_BUFFER_NV, SKIP_COMPONENTS1_NV, 736 SKIP_COMPONENTS2_NV, SKIP_COMPONENTS3_NV, or SKIP_COMPONENTS4_NV, and 737 <bufferMode> is not INTERLEAVED_ATTRIBS; 738 739 * if the number of NEXT_BUFFER_NV values in <locations> is greater 740 than or equal to the value of MAX_TRANSFORM_FEEDBACK_BUFFERS; 741 742 * <bufferMode> is SEPARATE_ATTRIBS and the total number of 743 components to capture in any varying variable in <locations> is 744 greater than the limit MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS; 745 746 * <bufferMode> is INTERLEAVED_ATTRIBS, and the total number of 747 vertex components to capture to any single binding point is greater 748 than the limit MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; or 749 750 * the set of varyings to capture to any single binding point includes 751 varyings from more than one vertex stream. 752 753 The transform feedback state set by TransformFeedbackVaryingsNV 754 immediately replaces any transform feedback varying state of <program>, 755 whether the old state was set when <program> was last linked (using the 756 varying names provided by TransformFeedbackVaryings), or via a 757 post-link call to TransformFeedbackVaryingsNV. 758 759 (Additions to Chapter 6 of the OpenGL 3.2 Specification (State and State 760 Requests)) 761 762 (Clean up/replace the language added by NV_transform_feedback, which added 763 a new Section 6.1.14 "Transform Feedback" and renamed 6.1.14 to 6.1.15. 764 The only functional change here is to explicitly separator attributes 765 provided for interleaved mode.) 766 767 The set of vertex attributes to be recorded to a buffer object when 768 neither a vertex nor geometry shader is active may be queried. The buffer 769 mode and number of attributes specified is obtained by calling GetIntegerv 770 with <param> set to TRANSFORM_FEEDBACK_BUFFER_MODE_NV and 771 TRANSFORM_FEEDBACK_ATTRIBS_NV, respectively. Information on each 772 individual attribute to record may be obtained by calling 773 GetIntegerIndexedvEXT() with <param> set to TRANSFORM_FEEDBACK_RECORD_NV 774 and <index> specifying the position of the attribute in the array given to 775 TransformFeedbackAttribsNV. Three integers will be returned, containing 776 the three values passed to TransformFeedbackAttribsNV for the specified 777 attribute. The error INVALID_VALUE is generated if <index> is greater 778 than or equal to the value of TRANSFORM_FEEDBACK_ATTRIBS_NV. Any 779 separators (NEXT_BUFFER_NV) passed to TransformFeedbackAttribsNV are 780 counted as attributes for the purposes of these queries, and will be 781 returned by TRANSFORM_FEEDBACK_RECORD_NV queries. 782 783 (add to OpenGL 3.2 Section 6.1.10, Shader and Program Queries, p. 259) 784 785 (Clean up/replace the language added to this section by 786 NV_transform_feedback, and add language describing how separators are 787 handled.) 788 789 If <pname> is TRANSFORM_FEEDBACK_BUFFER_MODE, the buffer mode used when 790 transform feedback is active is returned. If <pname> is 791 TRANSFORM_FEEDBACK_VARYINGS, the number of varying variables to capture 792 in transform feedback mode for the program is returned. Any separators 793 (NEXT_BUFFER_NV) provided to TransformFeedbackVaryingsNV count. If 794 <pname> is TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, the length of the 795 longest varying name specified to be used for transform feedback, 796 including a null terminator character, is returned. If no varyings are 797 used for transform feedback, zero is returned. 798 799 The command 800 801 void GetTransformFeedbackVaryingNV(uint program, uint index, 802 int *location) 803 804 returns the location of a varying variable to stream to a buffer object in 805 <location>. The array element numbered <index> in the array <locations> 806 passed to TransformFeedbackVaryingsNV, is returned. The error 807 INVALID_VALUE is generated if <index> is greater than or equal to the 808 value of TRANSFORM_FEEDBACK_VARYINGS_NV. If <index> refers to a 809 separator, the value NEXT_BUFFER_NV is returned. The error 810 INVALID_OPERATION is generated if <program> is not the name of a program 811 object or if <program> has not been linked successfully. 812 813 Modify section 5.4, Display Lists, p. 237 814 815 On p. 358, add the following to the list of vertex buffer object commands 816 not compiled into a display list: TransformFeedbackStreamAttribsNV. 817 818 819Errors 820 821 The error INVALID_VALUE is generated by BindBufferRange, 822 BindBufferOffsetEXT, or BindBufferBase if <target> is 823 TRANSFORM_FEEDBACK_BUFFER and <index> is greater than or equal to the 824 value of MAX_TRANSFORM_FEEDBACK_BUFFERS. 825 826 The error INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed 827 or GetQueryIndexediv if <target> is TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 828 or PRIMITIVES_GENERATED and <index> is greater or equal to MAX_VERTEX_STREAMS. 829 830 The error INVALID_OPERATION is generated by EndQueryIndexed if the active 831 query object name at index <index> of target <target> is zero. 832 833 The error INVALID_VALUE is generated by TransformFeedbackAttribsNV or 834 TransformFeedbackStreamAttribsNV if the component count or attribute 835 numbers specified in the <attribs> array are not consistent with the 836 corresponding attribute type. 837 838 The error INVALID_VALUE is generated by TransformFeedbackStreamAttribsNV 839 if any value in <bufstreams> is greater than or equal to the value of 840 MAX_VERTEX_STREAMS. 841 842 The error INVALID_OPERATION is generated by TransformFeedbackStream- 843 AttribsNV if the number of binding points specified by <attribs> is not 844 equal to <nbuffers>. 845 846 The error INVALID_OPERATION is generated by TransformFeedbackAttribsNV or 847 TransformFeedbackStreamAttribsNV if 848 849 * <bufferMode> is SEPARATE_ATTRIBS, and <count> is greater than the 850 limit MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV; 851 852 * <bufferMode> is INTERLEAVED_ATTRIBS, and the total number of 853 vertex components to record to any single binding point is greater 854 than the limit MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV; 855 856 * <bufferMode> is INTERLEAVED_ATTRIBS, and the number of binding 857 points used (one plus the number of NEXT_BUFFER_NV values in 858 <attribs>) is greater than the limit 859 MAX_TRANSFORM_FEEDBACK_BUFFERS; or 860 861 * any attribute type value in <attribs> is NEXT_BUFFER_NV, 862 SKIP_COMPONENTS1_NV, SKIP_COMPONENTS2_NV, SKIP_COMPONENTS3_NV, or 863 SKIP_COMPONENTS4_NV, and <bufferMode> is not INTERLEAVED_ATTRIBS. 864 865 The error INVALID_VALUE is generated by DrawTransformFeedbackStream 866 if <stream> is greater than or equal to the value of 867 MAX_VERTEX_STREAMS. 868 869 The error INVALID_VALUE is generated by TransformFeedbackVaryings if 870 <program> is not the name of a program object, or if <bufferMode> is 871 SEPARATE_ATTRIBS and <count> is greater than the limit 872 MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS. 873 874 The error INVALID_OPERATION is generated by TransformFeedbackVaryings 875 if any pointer in <varyings> identifies the special names "gl_NextBuffer", 876 "gl_SkipComponents1", "gl_SkipComponents2", "gl_SkipComponents3", or 877 "gl_SkipComponents4" and <bufferMode> is not INTERLEAVED_ATTRIBS_NV, or if 878 the number of "gl_NextBuffer" pointers in <varyings> is greater than or 879 equal to the value of MAX_TRANSFORM_FEEDBACK_BUFFERS. 880 881 The error INVALID_VALUE is generated by TransformFeedbackVaryingsNV if 882 <program> is not the name of a program object, or if <bufferMode> is 883 SEPARATE_ATTRIBS and <count> is greater than the limit 884 MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS. 885 886 The error INVALID_OPERATION is generated by TransformFeedbackVaryingsNV: 887 888 * if <program> has not been linked successfully; 889 890 * if <program> is being used by any active transform feedback object; 891 892 * if any value in <locations> is neither NEXT_BUFFER_NV nor the location 893 of an active varying variable in <program>; 894 895 * if any value in <locations> (other than NEXT_BUFFER_NV) appears more 896 than once in the array; 897 898 * if any value in <locations> is NEXT_BUFFER_NV, SKIP_COMPONENTS1_NV, 899 SKIP_COMPONENTS2_NV, SKIP_COMPONENTS3_NV, or SKIP_COMPONENTS4_NV, and 900 <bufferMode> is not INTERLEAVED_ATTRIBS; 901 902 * if the number of NEXT_BUFFER_NV values in <locations> is greater 903 than or equal to the value of MAX_TRANSFORM_FEEDBACK_BUFFERS; 904 905 * <bufferMode> is SEPARATE_ATTRIBS and the total number of 906 components to capture in any varying variable in <locations> is 907 greater than the limit MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS; 908 909 * <bufferMode> is INTERLEAVED_ATTRIBS, and the total number of 910 vertex components to capture to any single binding point is greater 911 than the limit MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; or 912 913 * the set of varyings to capture to any single binding point includes 914 varyings from more than one vertex stream. 915 916 The error INVALID_VALUE is generated by GetIntegerIndexedvEXT if <param> 917 is TRANSFORM_FEEDBACK_RECORD_NV and <index> is greater than or equal to 918 the value of TRANSFORM_FEEDBACK_ATTRIBS_NV. 919 920 The error INVALID_VALUE is generated by GetIntegerIndexedvEXT() if <param> 921 is TRANSFORM_FEEDBACK_BUFFER_BINDING, 922 TRANSFORM_FEEDBACK_BUFFER_START, or TRANSFORM_FEEDBACK_BUFFER_SIZE and 923 <index> is greater than or equal to the value of 924 MAX_TRANSFORM_FEEDBACK_BUFFERS. 925 926 The error INVALID_VALUE is generated by GetTransformFeedbackVaryingNV if 927 <index> is greater than or equal to the value of 928 TRANSFORM_FEEDBACK_VARYINGS_NV. 929 930 The error INVALID_OPERATION is generated by GetTransformFeedbackVaryingNV 931 if <program> is not the name of a program object, or if <program> has not 932 been linked successfully. 933 934 The error INVALID_ENUM is generated by BeginQuery if the <target> is 935 PRIMITIVES_GENERATED<i>_NV or TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN<i>_NV 936 and <i> is greater than or equal to the value of MAX_VERTEX_STREAMS. 937 938New State 939 940 (Modify Table 6.37, p 298, adding a variable number of new transform 941 feedback query object binding points.) 942 943 Get Value Type Get Command Init. Value Description Sec Attribute 944 ---------------- ---- ---------------- ----------- ------------------------- ----- --------- 945 CURRENT_QUERY nxZ+ GetQueryiv 0 Active query object name 2.X - 946 (occlusion, timer, per- 947 stream xform feedback) 948 949New Implementation Dependent State 950 951 (Add to the new table, Table 6.X. Transform Feedback State, previously 952 added by EXT_transform_feedback.) 953 954 Minimum 955 Get Value Type Get Command Value Description Sec. Attrib 956 --------- ---- ----------- ------- --------------------------- ---- ------ 957 MAX_TRANSFORM_FEEDBACK_ Z+ GetIntegerv 4 Max number of buffer objs 2.Y - 958 BUFFERS to write with xform feedback 959 MAX_VERTEX_STREAMS Z+ GetIntegerv 1 Maximum number of vertex 2.Y - 960 streams supported 961 962Issues 963 964 (1) How should we provide the ability to record varyings/attributes to 965 multiple buffers with multiple varyings/attributes per buffer? 966 967 RESOLVED: The version supported in the spec extends the interleaved 968 mode provided by existing APIs to allow writing to multiple buffers. 969 Special separator values are provided to allow the caller to direct 970 subsequent varyings/attributes at the next buffer. For example, the 971 following code would capture the values of "batman" and "robin" 972 interleaved to the first buffer binding point, and "riddler", "joker", 973 and "manbearpig" interleaved to the second. This example specifies 974 attributes in the style used by EXT_transform_feedback (array of 975 variable names set prior to linking). 976 977 char *names[] = { "batman", "robin", "gl_NextBuffer", 978 "riddler", "joker", "manbearpig" }; 979 glTransformFeedbackVaryings(program, 6, names, 980 GL_INTERLEAVED_ATTRIBS); 981 982 The same example using the NV_transform_feedback-style API would 983 produce: 984 985 int locations[6] = { 986 glGetVaryingLocation(program, "batman"), 987 glGetVaryingLocation(program, "robin"), 988 NEXT_BUFFER_NV, 989 glGetVaryingLocation(program, "riddler"), 990 glGetVaryingLocation(program, "joker"), 991 glGetVaryingLocation(program, "manbearpig") 992 }; 993 glTransformFeedbackVaryingsNV(program, 6, locations, 994 GL_INTERLEAVED_ATTRIBS); 995 996 A similar example using assembly shaders might work like: 997 998 int attribs[] = { 999 GL_TEXTURE_COORD_NV, 3, 0, // vec3 batman @ result.texcoord[0] 1000 GL_TEXTURE_COORD_NV, 3, 1, // vec3 robin @ result.texcoord[1] 1001 NEXT_BUFFER_NV, 0, 0, 1002 GL_GENERIC_ATTRIB_NV, 4, 0, // vec4 riddler @ result.attrib[0] 1003 GL_GENERIC_ATTRIB_NV, 2, 0, // vec2 joker @ result.attrib[1] 1004 GL_GENERIC_ATTRIB_NV, 1, 0, // float manbearpig @ result.attrib[2] 1005 }; 1006 glTransformFeedbackAttribsNV(6, attribs, GL_INTERLEAVED_ATTRIBS); 1007 1008 Another approach considered was to create a separate "mixed" mode enum, 1009 but to use separators and existing APIs. That approach was close enough 1010 to the existing interleaved mode that we decided to use that instead. 1011 1012 One alternate approach would avoid separators by providing a new "mixed 1013 mode" API entry point taking an array of pointers, where each points to 1014 an array of varying/attribute descriptors. 1015 1016 char *heroes[] = { "batman", "robin" }; 1017 char *villains[] = { "riddler", "joker", "manbearpig" }; 1018 char **varyingLists[] = { heroes, villains }; 1019 int varyingListLengths[] = { 2, 3 }; 1020 glTransformFeedbackMixedVaryingsNV(program, 2, varyingListLengths, 1021 varyingLists); 1022 1023 (2) How do multiple vertex streams work, and how do they work in 1024 conjunction with transform feedback? 1025 1026 RESOLVED: The NV_gpu_program5 and ARB_gpu_shader5 extensions 1027 introduce the notion of multiple vertex streams emitted in geometry 1028 shaders. The following figure is a simplified picture of the vertex 1029 processing pipeline. 1030 1031 | 1032 | vertices in 1033 V 1034 vertex 1035 shader 1036 | 1037 V 1038 primitive 1039 assembly 1040 | 1041 +-----------+ 1042 | | 1043 | tessellation 1044 | | 1045 +<----------+ 1046 | 1047 +---------------+ 1048 | | 1049 |stream V 1050 |0 geometry 1051 | shader 1052 | | | | | 1053 | V V V V 1054 | primitive 1055 | assembly 1056 V | | | | 1057 +------------+ | | | 1058 | stream 0 | | | 1059 | | | | 1060 | +-----------+ | | 1061 | |stream 1 | | 1062 | | | | 1063 | | stream 2| |stream 3 1064 | | +----------+ | 1065 | | | +---------+ 1066 | | | | 1067 V V V V 1068 transform feedback ----+--------> binding point 0 ----> buffer 1069 | +--------> binding point 1 ----> buffer 1070 | stream 0 +--------> binding point 2 ----> buffer 1071 +---+ +--------> binding point 3 ----> buffer 1072 | 1073 V 1074 clipping, 1075 rasterization, 1076 etc... 1077 1078 Vertices are initially received via commands such as glDrawArrays, 1079 glDrawElements, glArrayElement, or glVertex. Vertices are first 1080 processed by the vertex shader and/or the fixed-function vertex pipeline 1081 and are assembled into primitives (points, lines, triangles, etc...). If 1082 tessellation shaders are enabled, these primitives are processed by the 1083 programmable shaders and associated fixed-function hardware and are 1084 assembled into primitives. Each primitive assembled after vertex 1085 shading and tessellation is said to belong to vertex stream 0, which is 1086 effectively the only vertex stream supported by the GL prior to this 1087 extension. 1088 1089 If a geometry shader is enabled, it is run on each input primitive in 1090 vertex stream 0. Such primitives are consumed by the geometry shader. 1091 However, the geometry shader can emit new vertices, and each vertex 1092 emitted is directed at a specified vertex stream. The geometry shader 1093 has an effective output primitive type for each vertex stream used to 1094 assemble the emitted vertices into primitives. In the initial 1095 implementation of this extension, four such streams are supported, and 1096 only the POINTS output primitive type is supported if more than one 1097 stream is used. When a sufficient number of vertices are emitted to a 1098 stream, the primitive assembly stage below the geometry shader sends the 1099 corresponding primitive down the appropriate primitive stream. If 1100 geometry shaders are disabled, all primitives assembled by previous 1101 stages remain on stream 0. 1102 1103 The primitives on all streams are seen by the transform feedback stage. 1104 As each primitive is received on any vertex stream, the transform 1105 feedback stage checks the set of varyings/attributes selected for each 1106 binding point. If they don't belong to the vertex stream the primitive 1107 came from, nothing is written to buffer attached to the binding point. 1108 Otherwise, transform feedbacks loops first over the vertices in the 1109 primitive and then the varyings/attributes used for the binding point, 1110 writing each selected value to the attached buffer object. The API 1111 doesn't allow a single binding point to store variables from more than 1112 one vertex stream, so each binding point effectively has an associated 1113 vertex stream it reads from. 1114 1115 After transform feedback, the primitives from stream zero are passed to 1116 subsequent primitive processing stages (flat shading/color selection, 1117 clipping, rasterization); primitives on all other streams are discarded. 1118 1119 (3) How might you use transform feedback with geometry shaders and 1120 multiple vertex streams? 1121 1122 RESOLVED: As a simple example, let's say you are processing triangles 1123 and capture both processed triangle vertices and some values that are 1124 computed per-primitive (e.g., facet normal). The geometry shader 1125 might declare its outputs like the following: 1126 1127 layout(stream = 0) out vec4 position; 1128 layout(stream = 0) out vec4 texcoord; 1129 layout(stream = 1) out vec4 normal; 1130 1131 "position" and "texcoord" would be per-vertex attributes written to 1132 vertex stream 0; "normal" would be a per-triangle facet normal. The 1133 geometry shader would emit three vertices to stream zero (the processed 1134 input vertices) and a single vertex to stream one (the per-triangle 1135 data). The transform feedback API usage for this case would be 1136 something like: 1137 1138 // Set up buffer objects 21 and 22 to capture data for per-vertex and 1139 // per primitive values. 1140 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 21); 1141 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, 22); 1142 1143 // Set up XFB to capture position and texcoord to buffer binding 1144 // point 0 (buffer 21 bound), and normal to binding point 1 (buffer 1145 // 22 bound). 1146 char *strings[] = { "position", "texcoord", "gl_NextBuffer", 1147 "normal" }; 1148 // create <program> 1149 glTransformFeedbackVaryings(program, 4, strings, 1150 GL_INTERLEAVED_ATTRIBS); 1151 // link <program> 1152 1153 A setup like: 1154 1155 char *strings[] = { "position", "gl_NextBuffer", 1156 "texcoord", "gl_NextBuffer", "normal" }; 1157 1158 would capture "position" to binding point 0, "normal" to binding point 1159 1, and "texcoord" to binding point 2. When a vertex is emitted to 1160 vertex stream 0, transform feedback would write to the first two binding 1161 points, but not the third. When per-primitive data is emitted to vertex 1162 stream 1, transform feedback would write to the third binding point, 1163 but not the first two. 1164 1165 A setup like: 1166 1167 char *strings[] = { "position", "normal", "gl_NextBuffer", 1168 "texcoord" }; 1169 1170 would be illegal (LinkProgram would fail) because the first binding 1171 point would want to capture varyings from both vertex streams. 1172 1173 (4) With multiple vertex streams supported by geometry shaders, the number 1174 of primitives generated and/or written by transform feedback is 1175 different for each stream. How should we expose the ability to query 1176 these counts? 1177 1178 RESOLVED: The set of primitive query object targets 1179 (PRIMITIVES_GENERATED and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) 1180 is extended to contain a target for each vertex stream. The new 1181 query targets PRIMITIVES_GENERATED<n> and 1182 TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN<n> are provided to select the 1183 stream number to use for a query object. To simultaneously determine 1184 the number of primitives written to multiple vertex streams, multiple 1185 query objects should be used. For example: 1186 1187 glBeginQuery(GL_PRIMITIVES_GENERATED0, 11); 1188 glBeginQuery(GL_PRIMITIVES_GENERATED1, 12); 1189 draw_some_stuff(); 1190 glEndQuery(GL_PRIMITIVES_GENERATED0); 1191 glEndQuery(GL_PRIMITIVES_GENERATED1); 1192 1193 will record the number of primitives generated on vertex stream zero by 1194 "draw_some_stuff()" to query object 11 and the number of primitives 1195 generated on vertex stream one to query object 12. 1196 1197 Two other API choices were considered but rejected. One choice was to 1198 define a query target to have multiple query object attachment points 1199 (one for each vertex stream). This would require adding 1200 BeginQueryIndexedNV, EndQueryIndexedNV, and GetQueryIndexedNV functions, 1201 and modifying all the existing query language to allow for this 1202 possibility. We chose instead to replicate enumerants to avoid adding 1203 the new API and spec language. We expect that 8 streams should be 1204 sufficient. 1205 1206 A second choice was to extend the result values of the existing 1207 primitive query objects from a single integer to an <n>-component 1208 vector, where <n> is the total number of vertex streams supported. New 1209 query object mechanisms could be provided to query an individual element 1210 in that vector. It might have been possible to define the existing 1211 query to return the entire vector integer at once, but that could be a 1212 problem for applications that used the old API on new hardware and 1213 allocated space for only a single integer in its return buffer. 1214 1215 (5) How do the EXT- and NV-style transform feedback APIs interact with 1216 each other? 1217 1218 RESOLVED: The EXT-style API requires that you provide a list of 1219 varyings prior to linking a program object, and does not provide the 1220 ability to change the set without re-linking. With the NV-style API, 1221 the set of varyings to record is cleared when the program is linked, 1222 but you can re-specify the set of varyings to record multiple times 1223 after linking without any re-link. 1224 1225 Fortunately, the two APIs fit together nicely. When both extensions are 1226 supported, the state set by EXT is defined to specify the values to 1227 capture when the program is next linked. If no variables are set using 1228 the EXT-style API, the transform feedback state is reset on a link, as 1229 called for by the NV-style API. After linking, the NV-style API can be 1230 used to change the variables to capture, and such changes don't collide 1231 with any EXT-style state changes, which would require a re-link to take 1232 effect. 1233 1234 (6) What value should we use when defining the separator token for 1235 NV-style transform feedback APIs? 1236 1237 RESOLVED: Unlike most existing GL defines, as we've chosen the value 1238 "-2". Both the GLSL and assembly NV-style APIs take arrays of signed 1239 integers. For the GLSL API, array entries are integers. By convention, 1240 the "location" an invalid variable name is "-1", with valid locations 1241 returned as non-negative integers. For the assembly-style API, the 1242 attribute types are just numbers, with nothing requiring that the number 1243 be positive or negative. The choice of "-2" can be used for both API 1244 styles, and guarantees that the separator separator will not collide 1245 with a valid GLSL varying location or the "invalid varying" marker of 1246 -1. 1247 1248 (7) How do multiple vertex streams interact with the 1249 DrawTransformFeedback() API added by the ARB_transform_feedback2 1250 extension? 1251 1252 RESOLVED: Prior to this extension, there was only one vertex stream, 1253 so the vertex count to be used by DrawTransformFeedback() was 1254 unambiguous. With multiple streams, there may be different vertex 1255 counts written to each buffer. We will add a new 1256 DrawTransformFeedbackStream command to draw using the number of 1257 vertices recorded to buffers for the specified vertex stream during the 1258 last transform feedback operation. The existing DrawTransformFeedback 1259 command is defined to use the number of vertices recorded to buffers for 1260 vertex stream zero. 1261 1262 We chose an API that makes the vertex counts for all streams used by a 1263 transform feedback object available for DrawTransformFeedback 1264 operations. We also considered an API that would have required the user 1265 to select a single stream prior to calling BeginTransformFeedback, 1266 where only the vertex count from that stream would be available for 1267 subsequent operations. We decided that there might be a usage case for 1268 an application that sorted its vertices into multiple streams, but still 1269 wanted to draw them all in a subsequent pass. To do this, all vertex 1270 counts would have to be made available. 1271 1272 (8) What happens with the DrawTransformFeedback() API if no complete 1273 primitives were emitted to the selected stream? What if complete 1274 primitives were emitted to the stream but no varyings from that stream 1275 were selected for transform feedback? 1276 1277 RESOLVED: The vertex count used by DrawTransformFeedbackNV() is the 1278 number of vertices recorded from the selected stream. If no primitives 1279 are emitted to that stream, the vertex count will be zero. If the set 1280 of varyings selected for transform feedback does not include any 1281 belonging to the specified stream, nothing will be recorded when 1282 primitives are emitted to that stream, and the corresponding vertex 1283 count will be zero. 1284 1285 (9) The new extension to interleaved mode provides increased flexibility 1286 on how varyings or attributes can be assigned to individual buffers 1287 for transform feedback. How can you query which varying/attribute is 1288 assigned to which buffer? 1289 1290 RESOLVED: The transform feedback attribute enumeration/query 1291 functions will return separator values in the positions where they were 1292 originally provided. An application can figure out the buffer a varying 1293 goes to by counting the number of separators prior to an attribute. It 1294 would be possible to provide a utility API that says "give me the <n>th 1295 varying recorded to binding point <m>", but simply returning separators 1296 seems usable enough. 1297 1298 (10) Previous transform feedback specs disallowed recording the same 1299 varying/attribute more than once. Should we continue that 1300 restriction? In particular, this may be problematic for assembly 1301 shaders using multiple vertex streams that wish to use the same 1302 attribute locations in multiple streams. 1303 1304 RESOLVED: We should probably allow recording the same attribute more 1305 than once in some form, if for no other reason than to handle the 1306 multi-stream assembly case described in the question. Resolved by 1307 allowing this for TransformFeedbackStreamAttribsNV. 1308 1309 (11) Should we provide the ability to leave holes in the data emitted by 1310 transform feedback? This would provide applications the ability to 1311 combine captured vertex attributes of multiple passes into a single 1312 buffer object. 1313 1314 RESOLVED: Yes. This spec extended the separator notion added to 1315 write to multiple buffers included in interleaved mode to include 1316 special "spacer" markers (e.g., "skip 4 components") as well. Consider 1317 the following example in the EXT_transform_feedback API: 1318 1319 char *names[] = { "batman", "gl_SkipComponents3", "robin", 1320 "gl_NextBuffer", "riddler", "gl_SkipComponents2", 1321 "joker", "manbearpig" }; 1322 glTransformFeedbackVaryings(program, 8, names, 1323 GL_INTERLEAVED_ATTRIBS); 1324 1325 "gl_SkipComponents<N>" is a special marker to indicate that <N> words 1326 should be skipped when recording values. In this case, each vertex 1327 written to the first binding point would start with the value of 1328 "batman", then leave 3 components worth of data unmodified, and then 1329 finish with the value of "robin". 1330 1331 For the NV_transform_feedback APIs, the special values 1332 GL_SKIP_COMPONENTS1_NV through GL_SKIP_COMPONENTS4_NV are provided. We 1333 chose to provide four tokens even for the assembly API, which could have 1334 used a GL_SKIP_COMPONENTS_NV token with a separate count value 1335 containing 1-4. However, the GLSL-based API needs separate tokens 1336 because there is no way to pass a component count separately. We 1337 decided to use the same tokens for both APIs to minimize confusion. 1338 1339 (12) Now that you can write to more than one buffer, what does 1340 MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS now mean? 1341 1342 RESOLVED: This query will return the number of components that may be 1343 written to a single buffer in interleaved mode. Since interleaved mode 1344 now supports multiple buffers, the total number of components that may 1345 be written in the single pass is the product of this per-buffer limit 1346 and the number of buffers that may be written at once. 1347 1348 The state table entry in the EXT_transform_feedback specification 1349 actually defined it this way, using the language "max number of 1350 components write to a single buffer in interleaved mode." 1351 1352 (13) How does rasterization work when vertices may be emitted to multiple 1353 streams? 1354 1355 RESOLVED: Primitives sent to stream zero are the only ones rasterized. 1356 When primitives are received on any other streams, they are discarded 1357 after any transform feedback operations involving that stream are 1358 completed. 1359 1360 When using GLSL geometry shaders, stream zero is the only one that 1361 makes sense for rasterization, because the geometry shader output 1362 "gl_Position" is associated with stream zero. 1363 1364 We considered building a mechanism for rasterization to select from any 1365 of the vertex streams, but decided not to include such a feature since 1366 it would require some way to designate a position for each stream or 1367 potentially assign "gl_Position" to all streams. 1368 1369 (15) How might you use transform feedback with assembly geometry programs 1370 and multiple vertex streams? 1371 1372 RESOLVED: As in issue (3), let's say you are processing triangles and 1373 capture both processed triangle vertices and some values that are 1374 computed per-primitive (e.g., facet normal). The geometry program might 1375 declare outputs like the following: 1376 1377 RESULT position = result.position; # used in stream 0 1378 RESULT texcoord = result.texcoord[0]; # used in stream 0 1379 RESULT normal = result.texcoord[0]; # used in stream 1 1380 1381 "position" and "texcoord" would be per-vertex attributes written to 1382 vertex stream 0; "normal" would be a per-triangle facet normal. The 1383 geometry program would emit three vertices to stream zero (the processed 1384 input vertices) and a single vertex to stream one (the per-triangle 1385 data). The transform feedback API usage for this case would be: 1386 1387 int attribs[] = { 1388 GL_TEXTURE_COORD_NV, 3, 0, // vec3 normal @ result.texcoord[0] 1389 NEXT_BUFFER_NV, 0, 0, 1390 GL_POSITION, 4, 0, // vec4 position @ result.position 1391 GL_TEXTURE_COORD_NV, 2, 0, // vec2 texcoord @ result.texcoord[0] 1392 }; 1393 int streams[] = { 1, 0 }; 1394 glTransformFeedbackStreamAttribsNV(3, attribs, 2, streams, 1395 GL_INTERLEAVED_ATTRIBS); 1396 1397 streams[0] is 1, which means that only the vertices emitted to stream 1398 one will be written to the first binding point (where "normal" goes). 1399 streams[1] is 0, which means that only the vertices emitted to stream 1400 zero will be written to the second binding point (where "position" and 1401 "texcoord" go). 1402 1403 (17) How does this extension interact with the old-school feedback and 1404 select modes set by glRenderMode? 1405 1406 RESOLVED: This spec provides multiple vertex streams, where only 1407 stream 0 is sent to the rasterizer. Feedback and select modes will 1408 only operate on primitives sent to the stream 0. Primitives sent to 1409 other streams are ignored, after they are optionally captured in 1410 transform feedback mode. 1411 1412 (18) How do transform feedback vertex streams interact with separate 1413 shader objects (EXT_separate_shader_objects)? 1414 1415 RESOLVED: The data captured in transform feedback are produced by the 1416 last active shader stage prior to the transform feedback stage. If 1417 there is an active program object for the geometry shader stage, and 1418 that program has a geometry shader that emits vertices to multiple 1419 streams, such a configuration behaves exactly like a similar 1420 configuration using a single program object. 1421 1422 1423Revision History 1424 1425 Rev. Date Author Changes 1426 ---- -------- -------- ----------------------------------------- 1427 12 03/23/2010 pbrown Update issue (13) and add issue (18) from 1428 issues left behind in the NV_gpu_shader5 when 1429 specs were refactored. 1430 1431 11 02/04/2010 gsellers Add indexed query entry points. 1432 Remove indexed enums. 1433 1434 10 02/02/2010 pbrown Clarify that "gl_SkipComponents*" is in 1435 units of "float" (bug 5863). 1436 1437 9 01/20/2010 pbrown Update extension interaction references 1438 to use ARB_gpu_shader5 (instead of "EXT"). 1439 1440 8 01/14/2010 Jon Leech Update errors for out of range vertex 1441 streams passed to 1442 DrawTransformFeedbackStream and 1443 BeginQuery to match core specification 1444 (Bug 5896). 1445 1446 7 12/07/2009 jbolz Rename EXT->ARB. 1447 1448 6 10/22/2009 jbolz Close unresolved issues, with no functional 1449 changes. 1450 1451 5 10/22/2009 jbolz Incorporated fixes from bmerry. Changed 1452 GetTransformFeedbackVarying to not return 1453 length=0 for separators. 1454 1455 4 09/30/2009 pbrown Removed tessellation shader dependencies, 1456 including language describing capture of 1457 patches. Capture of patches will only be 1458 supported via NV_gpu_shader5. 1459 1460 3 09/17/2009 pdaniell Move PATCHES_EXT into NV dependencies. 1461 Remove VertexDrawStreamEXT as only stream 0 1462 is output to the rasterizer. 1463 1464 2 09/14/2009 pdaniell EXTify. Move NV stuff into dependencies. 1465 1466 1 pbrown Internal revisions. 1467 1468