1Name 2 3 EXT_transform_feedback2 4 5Name Strings 6 7 GL_EXT_transform_feedback2 8 9Contributors 10 11 Eric Zolnowski 12 13Contact 14 15 Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) 16 Eric Zolnowski, AMD (eric.zolnowski 'at' amd.com) 17 18Status 19 20 In Progress. 21 22Version 23 24 Last Modified Date: 10/12/2009 25 Author Revision: 3 26 27Number 28 29 xxx 30 31Dependencies 32 33 The OpenGL Shading Language (GLSL) is required. OpenGL 2.0 or the 34 ARB_shader_objects extension is required. 35 36 NV_transform_feedback or EXT_transform_feedback is required. 37 38 EXT_geometry_shader4 trivially interacts with this extension. 39 40 This extension is written against the OpenGL 2.1 Specification. 41 42 This extension is written against the EXT_transform_feedback extension 43 specification. 44 45 46Overview 47 48 The EXT_transform_feedback extension allows applications to capture 49 primitives to one or more buffer objects when transformed by the GL. 50 This extension provides a few additional capabilities to these extensions, 51 making transform feedback mode more useful. 52 53 First, it provides transform feedback objects which encapsulate transform 54 feedback-related state, allowing applications to replace the entire 55 transform feedback configuration in a single bind call. Second, it 56 provides the ability to pause and resume transform feedback operations. 57 When transform feedback is paused, applications may render without 58 transform feedback or may use transform feedback with different state and 59 a different transform feedback object. When transform feedback is 60 resumed, additional primitives are captured and appended to previously 61 captured primitives for the object. 62 63 Additionally, this extension provides the ability to draw primitives 64 captured in transform feedback mode without querying the captured 65 primitive count. The command DrawTransformFeedbackEXT() is equivalent to 66 glDrawArrays(<mode>, 0, <count>), where <count> is the number of vertices 67 captured to buffer objects during the last transform feedback capture 68 operation on the transform feedback object used. This draw operation only 69 provides a vertex count -- it does not automatically set up vertex array 70 state or vertex buffer object bindings, which must be done separately by 71 the application. 72 73New Procedures and Functions 74 75 void BindTransformFeedbackEXT(enum target, uint id); 76 void DeleteTransformFeedbacksEXT(sizei n, const uint *ids); 77 void GenTransformFeedbacksEXT(sizei n, uint *ids); 78 boolean IsTransformFeedbackEXT(uint id); 79 80 void PauseTransformFeedbackEXT(void); 81 void ResumeTransformFeedbackEXT(void); 82 83 void DrawTransformFeedbackEXT(enum mode, uint id); 84 85New Tokens 86 87 Accepted by the <target> parameter of BindTransformFeedbackEXT: 88 89 TRANSFORM_FEEDBACK_EXT 0x8E22 90 91 Accepted by the <pname> parameter of GetBooleanv, GetDoublev, GetIntegerv, 92 and GetFloatv: 93 94 TRANSFORM_FEEDBACK_BUFFER_PAUSED_EXT 0x8E23 95 TRANSFORM_FEEDBACK_BUFFER_ACTIVE_EXT 0x8E24 96 TRANSFORM_FEEDBACK_BINDING_EXT 0x8E25 97 98Additions to Chapter 2 of the OpenGL 2.1 Specification (OpenGL Operation) 99 100 (Replace the "Section 2.Y" introduced by the EXT_transform_feedback 101 specification.) 102 103 In transform feedback mode, attributes of the vertices of transformed 104 primitives are written out to one or more buffer objects. The vertices are 105 fed back after vertex color clamping but before clipping. If a geometry 106 shader is active, the vertices recorded are those emitted from the geometry 107 shader. The transformed vertices may be optionally discarded after being 108 stored into one or more buffer objects, or they can be passed on down to 109 the clipping stage for further processing. 110 111 112 Section 2.Y.1, Transform Feedback Objects 113 114 The set of buffer objects used to capture vertex attributes and related 115 state are stored in a transform feedback object. If a vertex or geometry 116 shader is active, the set of attributes captured in transform feedback 117 mode is determined using the state of the active program object; 118 otherwise, it is taken from the state of the currently bound transform 119 feedback object, as described below. The name space for transform 120 feedback objects is the unsigned integers. The name zero designates the 121 default transform feedback object. 122 123 A transform feedback object is created by calling 124 125 void BindTransformFeedbackEXT(enum target, uint id) 126 127 with <target> set to TRANSFORM_FEEDBACK_EXT and <id> set an unused 128 transform feedback object name. The resulting transform feedback object 129 is a new state vector, initialized to the default state values described 130 in Table 6.X. Additionally, the new object is bound to the GL state 131 vector and is used for subsequent transform feedback operations. 132 133 BindTransformFeedbackEXT can also be used to bind an existing transform 134 feedback object to the GL state for subsequent use. If the bind is 135 successful, no change is made to the state of the newly bound transform 136 feedback object and any previous binding to <target> is broken. 137 138 While a transform feedback buffer object is bound, GL operations on the 139 target to which it is bound affect the bound transform feedback object, 140 and queries of the target to which a transform feedback object is bound 141 return state from the bound object. When buffer objects are bound for 142 transform feedback, they are attached to the currently bound transform 143 feedback object. Buffer objects are used for transform feedback only if 144 they are attached to the currently bound transform feedback object. 145 146 In the initial state, a default transform feedback object is bound and 147 treated as a transform feedback object with a name of zero. That object 148 is bound any time BindTransformFeedbackEXT() is called with <id> of zero. 149 150 The error INVALID_OPERATION is generated by BindTransformFeedbackEXT if 151 the transform feedback operation is active on the currently bound 152 transform feedback object, and that operation is not paused (as 153 described below). 154 155 Transform feedback objects are deleted by calling 156 157 void DeleteTransformFeedbacksEXT(sizei n, const uint *ids) 158 159 <ids> contains <n> names of transform feedback objects to be deleted. 160 After a transform feedback object is deleted it has no contents, and its 161 name is again unused. Unused names in <ids> are silently ignored, as is 162 the value zero. The default transform feedback object cannot be deleted. 163 The error INVALID_OPERATION is generated by DeleteTransformFeedbacksEXT 164 if the transform feedback operation for any object named by <ids> is 165 currently active. 166 167 The command 168 169 void GenTransformFeedbacksEXT(sizei n, uint *ids) 170 171 returns <n> previously unused transform feedback object names in <ids>. 172 These names are marked as used, for the purposes of 173 GenTransformFeedbacksEXT only, but they acquire transform feedback state 174 only when they are first bound, just as if they were unused. 175 176 177 Section 2.Y.2, Transform Feedback Primitive Capture 178 179 Transform feedback for the currently bound transform feedback object is 180 started and finished by calling 181 182 void BeginTransformFeedbackEXT(enum primitiveMode) 183 184 and 185 186 void EndTransformFeedbackEXT(void), 187 188 respectively. Transform feedback is said to be active after a call to 189 BeginTransformFeedbackEXT and inactive after a call to 190 EndTransformFeedbackEXT. <primitiveMode> is one of TRIANGLES, LINES, or 191 POINTS, and specifies the output type of primitives that will be recorded 192 into the buffer objects bound for transform feedback (see below). 193 194 Transform feedback commands must be paired; the error INVALID_OPERATION is 195 generated by BeginTransformFeedbackEXT if transform feedback is active, 196 and by EndTransformFeedbackEXT if transform feedback is inactive. 197 Transform feedback is initially inactive. 198 199 Transform feedback operations for the currently bound transform feedback 200 object may be paused and resumed by calling 201 202 void PauseTransformFeedbackEXT(void) 203 204 and 205 206 void ResumeTransformFeedbackEXT(void), 207 208 respectively. When transform feedback operations are paused, transform 209 feedback is still considered active and changing most transform feedback 210 state related to the object results in an error. However, a new transform 211 feedback object may be bound while transform feedback is paused. The 212 error INVALID_OPERATION is generated by PauseTransformFeedbackEXT if the 213 currently bound transform feedback is not active or is paused. The error 214 INVALID_OPERATION is generated by ResumeTransformFeedbackEXT if the 215 currently bound transform feedback is not active or is not paused. 216 217 When transform feedback is active and not paused, all geometric primitives 218 generated must be compatible with the value of <primitiveMode> passed to 219 BeginTransformFeedbackEXT. The error INVALID_OPERATION is generated by 220 Begin or any operation that implicitly calls Begin (such as DrawElements) 221 if <mode> is not one of the allowed modes in Table X.1. If a geometry 222 shader is active, its output primitive type is used instead of the <mode> 223 parameter passed to Begin for the purposes of this error check. Any 224 primitive type may be used while transform feedback is paused. 225 226 Transform Feedback 227 primitiveMode allowed render primitive modes 228 ---------------------- --------------------------------- 229 POINTS POINTS 230 LINES LINES, LINE_LOOP, and LINE_STRIP 231 TRIANGLES TRIANGLES, TRIANGLE_STRIP, 232 TRIANGLE_FAN, QUADS, QUAD_STRIP, 233 and POLYGON 234 235 Table X.1 Legal combinations between the transform feedback primitive 236 mode, as passed to BeginTransformFeedbackEXT and the current primitive 237 mode. 238 239 Transform feedback mode captures the values of varying variables written by an 240 active vertex or geometry shader. The error INVALID_OPERATION is 241 generated by BeginTransformFeedbackEXT if no vertex or geometry shader is 242 active. 243 244 Buffer objects are made to be targets of transform feedback by calling one 245 of the commands 246 247 void BindBufferRangeEXT(enum target, uint index, uint buffer, 248 intptr offset, sizeiptr size), 249 void BindBufferOffsetEXT(enum target, uint index, uint buffer, or 250 intptr offset), 251 void BindBufferBaseEXT(enum target, uint index, uint buffer), 252 253 with <target> set to TRANSFORM_FEEDBACK_BUFFER_EXT. There is an array of 254 buffer object binding points that are used while transform feedback is 255 active, plus a single general binding point that can be used by other 256 buffer object manipulation functions (e.g., BindBuffer, MapBuffer). All 257 three commands bind the buffer object named by <buffer> to the general 258 binding point, and additionally bind the buffer object to the binding 259 point in the array given by <index>. The error INVALID_VALUE is generated 260 if <index> is greater than or equal to the value of 261 MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT. 262 263 For BindBufferRangeEXT, <offset> specifies a starting offset into the 264 buffer object <buffer> and <size> specifies the amount of data that can be 265 written to the buffer object while transform feedback mode is active. 266 Both <offset> and <size> are in basic machine units. The error 267 INVALID_VALUE is generated if the value of <size> is less than or equal to 268 zero, or if either <offset> or <size> are not word-aligned. Calling 269 BindBufferOffsetEXT is equivalent of calling BindBufferRangeEXT with 270 <size> = sizeof(buffer) - <offset>, and rounding <size> down so that it is 271 word-aligned. BindBufferBaseEXT is equivalent to calling 272 BindBufferOffsetEXT with an <offset> of 0. 273 274 The set of buffer objects used by a transform feedback object may not 275 change while transform feedback is active. The error INVALID_OPERATION is 276 generated by BindBufferRangeEXT, BindBufferOffsetEXT, or BindBufferBaseEXT 277 if <target> is TRANSFORM_FEEDBACK_BUFER_EXT and transform feedback is 278 currently active. 279 280 When an individual point, line, or triangle primitive reaches the 281 transform feedback stage while transform feedback is active and not 282 paused, the values of the specified varying variables of each vertex are 283 appended to the buffer objects bound to the transform feedback binding 284 points. The attributes of the first vertex received after 285 BeginTransformFeedbackEXT are written at the starting offsets of the bound 286 buffer objects set by BindBufferRangeEXT, and subsequent vertex attributes 287 are appended to the buffer object. When capturing line and triangle 288 primitives, all attributes of the first vertex are written first, followed 289 by attributes of the subsequent vertices. When writing varying variables 290 that are arrays, individual array elements are written in order. For 291 multi-component varying variables, elements of varying arrays, or 292 transformed vertex attributes, the individual components are written in 293 order. The value for any attribute specified to be streamed to a buffer 294 object but not actually written by a vertex or geometry shader is 295 undefined. 296 297 When transform feedback is paused, no vertices are recorded. When 298 transform feedback is resumed, subsequent vertices are appended to the 299 buffer objects bound immediately following the last vertex written while 300 transform feedback was paused. 301 302 When quads and polygons are provided to transform feedback with a 303 primitive mode of TRIANGLES, they will be tessellated and recorded as 304 triangles (the order of tessellation within a primitive is undefined). 305 Individual lines or triangles of a strip or fan primitive will be 306 extracted and recorded separately. Incomplete primitives are not 307 recorded. 308 309 Transform feedback can operate in either INTERLEAVED_ATTRIBS_EXT or 310 SEPARATE_ATTRIBS_EXT mode. In INTERLEAVED_ATTRIBS_EXT mode, the values of 311 one or more varyings or transformed vertex attributes are written 312 interleaved, into the buffer object bound to the first transform feedback 313 binding point (index = 0). If more than one varying variable is written, 314 they will be recorded in the order specified by 315 TransformFeedbackVaryingsEXT (EXT_transform_feedback specification, 316 section 2.15.3). In SEPARATE_ATTRIBS_EXT mode, the first varying variable 317 or transformed vertex attribute specified is written to the first 318 transform feedback binding point; subsequent varying variables are written 319 to the subsequent transform feedback binding points. The total number of 320 variables or transformed attributes that may be captured in 321 SEPARATE_ATTRIBS_EXT mode is given by 322 MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT. 323 324 If recording the vertices of a primitive to the buffer objects being used 325 for transform feedback purposes would result in either exceeding the 326 limits of any buffer object's size, or in exceeding the end position 327 <offset> + <size> - 1, as set by BindBufferRangeEXT, then no vertices of 328 that primitive are recorded in any buffer object, and the counter 329 corresponding to the asynchronous query target 330 TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT (see Section 2.Z) is not 331 incremented. 332 333 In either separate or interleaved modes, all transform feedback binding 334 points that will be written to must have buffer objects bound when 335 BeginTransformFeedbackEXT is called. The error INVALID_OPERATION is 336 generated by BeginTransformFeedbackEXT if any binding point used in 337 transform feedback mode does not have a buffer object bound. In 338 interleaved mode, only the first buffer object binding point is ever 339 written to. 340 341 (add error paragraph describing conditions where it is illegal to change 342 transform feedback-related state) 343 344 When BeginTransformFeedbackEXT is called with an active program object 345 containing a vertex or geometry shader, the set of varying variables 346 captured during transform feedback is taken from the active program object 347 and may not be changed while transform feedback is active. That program 348 object must be active until the EndTransformFeedbackEXT is called, except 349 while the transform feedback object is paused. The error 350 INVALID_OPERATION is generated: 351 352 * by TransformFeedbackVaryingsEXT if the current transform feedback 353 object is active, even if paused; 354 355 * by UseProgram if the current transform feedback object is active and 356 not paused; 357 358 * by LinkProgram if <program> is the name of a program being used by one 359 or more transform feedback objects, even if the objects are not 360 currently bound or are paused; or 361 362 * by ResumeTransformFeedbackEXT if the program object being used by the 363 current transform feedback object is not active. 364 365 366 Section 2.Y.3, Transform Feedback Draw Operations 367 368 When transform feedback is active, the values of varyings or transformed 369 vertex attributes are captured into the buffer objects attached to the 370 current transform feedback object. After transform feedback is complete, 371 subsequent rendering operations may use the contents of these buffer 372 objects (section 2.9). The number of vertices captured during transform 373 feedback is stored in the corresponding transform feedback object and may 374 be used in conjunction with the command 375 376 void DrawTransformFeedbackEXT(enum mode, uint id) 377 378 to replay the captured vertices. This command is equivalent to calling 379 DrawArrays with <mode> set to <mode>, <first> set to zero, and <count> set 380 to the number of vertices captured the last time transform feedback was 381 active on the transform feedback object named by <id>. The error 382 INVALID_VALUE is generated if <id> is not the name of a transform feedback 383 object. The error INVALID_OPERATION is generated if 384 EndTransformFeedbackEXT has never been called while the object named by 385 <id> was bound. No error is generated if the transform feedback object 386 named by <id> is active; the vertex count used for the rendering operation 387 is set by the previous EndTransformFeedbackEXT command. 388 389 390Additions to Chapter 3 of the OpenGL 2.1 Specification (Rasterization) 391 392 None. 393 394Additions to Chapter 4 of the OpenGL 2.1 Specification (Per-Fragment 395Operations and the Frame Buffer) 396 397 None. 398 399Additions to Chapter 5 of the OpenGL 2.1 Specification (Special Functions) 400 401 On p. 244, add a new set of commands to the list of commands not compiled 402 into a display list: 403 404 Transform feedback objects: GenTransformFeedbacksEXT, 405 DeleteTransformFeedbacksEXT, 406 407 (note: IsTransformFeedbackEXT is covered by the "Other queries" rule.) 408 409Additions to Chapter 6 of the OpenGL 2.1 Specification (State and 410State Requests) 411 412 (Add to the "Transform Feedback" query section added by the 413 EXT_transform_feedback extension.) 414 415 The command 416 417 boolean IsTransformFeedbackEXT(uint id) 418 419 returns TRUE if <id> is the name of a transform feedback object. If <id> 420 is a non-zero value that is not the name of a transform feedback object, 421 IsTransformFeedbackEXT() return FALSE. 422 423Additions to Appendix A of the OpenGL 2.1 Specification (Invariance) 424 425 None. 426 427Additions to the AGL/GLX/WGL Specifications 428 429 None. 430 431GLX Protocol 432 433 TBD (Protocol support needs to be added for the new functions.) 434 435Dependencies on NV_transform_feedback2 436 437Dependencies on EXT_transform_feedback 438 439 This language is written against the EXT_transform_feedback 440 specification. 441 442Dependencies on EXT_geometry_shader4 443 444 If EXT_geometry_shader4 is not supported, remove all references to 445 geometry shaders. 446 447Errors 448 449 The error INVALID_OPERATION is generated by BindTransformFeedbackEXT if 450 a transform feedback operation is active on the currently bound transform 451 feedback object, and that operation is not paused (as described below). 452 453 The error INVALID_OPERATION is generated by DeleteTransformFeedbacksEXT 454 if the transform feedback operation for any object named by <ids> is 455 currently active. 456 457 The error INVALID_OPERATION is generated by BeginTransformFeedbackEXT if 458 transform feedback is active. 459 460 The error INVALID_OPERATION is generated by EndTransformFeedbackEXT if 461 transform feedback is inactive. 462 463 The error INVALID_OPERATION is generated by PauseTransformFeedbackEXT if 464 the currently bound transform feedback is not active or is paused. 465 466 The error INVALID_OPERATION is generated by ResumeTransformFeedbackEXT 467 if the currently bound transform feedback is not active or is not paused. 468 469 The error INVALID_OPERATION is generated by Begin or any operation that 470 implicitly calls Begin (such as DrawElements) if transform feedback is 471 active and not paused and if <mode> is incompatible with the 472 <primitiveMode> parameter supplied to BeginTransformFeedbackEXT. 473 474 The error INVALID_VALUE is generated by BindBufferRangeEXT, 475 BindBufferOffsetEXT, or BindBufferBaseEXT if <target> is 476 TRANSFORM_FEEDBACK_BUFFER_EXT and <index> is greater than or equal to the 477 value of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT. 478 479 The error INVALID_VALUE is generated by BindBufferRangeEXT if <size> is 480 less than or equal to zero or either <offset> or <size> are not 481 word-aligned. 482 483 The error INVALID_VALUE is generated by BindBufferOffsetEXT if <offset> is 484 not word-aligned. 485 486 The error INVALID_OPERATION is generated by BindBufferRangeEXT, 487 BindBufferOffsetEXT, or BindBufferBaseEXT if <target> is 488 TRANSFORM_FEEDBACK_BUFFER_EXT and transform feedback is currently active. 489 490 The error INVALID_OPERATION is generated by BeginTransformFeedbackEXT if 491 any binding point used in transform feedback mode does not have a buffer 492 object bound. 493 494 The error INVALID_OPERATION is generated by TransformFeedbackVaryingsEXT 495 if the current transform feedback object is active, even if paused. 496 497 The error INVALID_OPERATION is generated by UseProgram if the current 498 transform feedback object is active and not paused. 499 500 The error INVALID_OPERATION is generated by LinkProgram if <program> is 501 the name of a program being used by one or more transform feedback 502 objects, even if the objects are not currently bound or are paused. 503 504 The error INVALID_OPERATION is generated by ResumeTransformFeedbackEXT if 505 the program object being used by the current transform feedback object is 506 not active. 507 508 The error INVALID_VALUE is generated by DrawTransformFeedbackEXT if <id> 509 is not the name of a transform feedback object. 510 511 The error INVALID_OPERATION is generated by DrawTransformFeedbackEXT if 512 EndTransformFeedbackEXT has never been called while the object named by 513 <id> was bound. 514 515 516New State 517 518 (Add a new table: Table 6.X, Transform Feedback Object State) 519 520 Get Value Type Get Command Init. Value Description Sec Attrib 521 ------------------ ------ -------------- ------------ ------------------------- ----- ------ 522 TRANSFORM_FEEDBACK_ Z+ GetIntegerv 0 Buffer object bound to 6.1.13 - 523 BUFFER_BINDING_EXT generic bind point for 524 transform feedback. 525 TRANSFORM_FEEDBACK_ nxZ+ GetInteger- 0 Buffer object bound to 6.1.13 - 526 BUFFER_BINDING_EXT IndexedvEXT each transform feedback 527 attribute stream. 528 TRANSFORM_FEEDBACK_ nxZ+ GetInteger- 0 Start offset of binding 6.1.13 - 529 BUFFER_START_EXT IndexedvEXT range for each transform 530 feedback attrib. stream 531 TRANSFORM_FEEDBACK_ nxZ+ GetInteger- 0 Size of binding range 6.1.13 - 532 BUFFER_SIZE_EXT IndexedvEXT for each transform 533 TRANSFORM_FEEDBACK_ B GetBooleanv FALSE Is transform feedback 6.1.13 - 534 BUFFER_PAUSED_EXT paused on this object? 535 TRANSFORM_FEEDBACK_ B GetBooleanv FALSE Is transform feedback 6.1.13 - 536 BUFFER_ACTIVE_EXT active on this object? 537 538 [[ Note: This table includes all transform feedback state provided by 539 EXT_transform_feedback, except for transform feedback-related state 540 belonging to query objects and GLSL program objects. The only other 541 transform feedback-related state not present in these objects is the 542 object binding (below) and implementation-dependent limits. ]] 543 544 (Modify table 6.10: Transformation State, p. 275) 545 546 Get Value Type Get Command Init. Value Description Sec Attrib 547 ------------------ ------ -------------- ------------ ------------------------- ----- ------ 548 TRANSFORM_FEEDBACK_ Z+ GetIntegerv 0 Object bound for transform 2.Y - 549 BINDING_EXT feedback operations 550 551New Implementation Dependent State 552 553 None. 554 555Issues 556 557 1. How should we provide the ability to automatically render primitives 558 captured in transform feedback mode? 559 560 RESOLVED: Adding a new transform feedback state object provides 561 encapsulation for two useful operations: pause/resume and automatic 562 rendering. 563 564 When applications pause and possibly switch to different transform 565 feedback state, it is necessary to save the state of the paused 566 transform feedback operation somewhere. The transform feedback object 567 provides a convenient entity to hold this saved state. The transform 568 feedback object is also a convenient place to store final counts for 569 use by actual drawing. 570 571 Additionally, the transform feedback object is helpful in ensuring 572 that the transform feedback state used when resuming transform 573 feedback is the same as when it was paused without a complicated error 574 check. We simply disallow changing the state in an object while 575 transform feedback is active (even when paused), so the state can't 576 become inconsistent while paused. The same basic consistency rules 577 apply to transform feedback state stored separately in a GLSL program 578 object; you can't change them while transform feedback is active in 579 the original extensions, and this extension treats the paused state as 580 active for the purposes of these restrictions. 581 582 Alternately, the in-progress transform feedback state (e.g., vertex 583 counts, pointers into buffer objects) could have been stored with the 584 buffer objects used to capture the primitives. 585 586 2. Are transform feedback objects shared between contexts? 587 588 RESOLVED: No. The amount of state present in one of these objects is 589 fairly small -- there is not a lot of memory saved by avoiding 590 multiple copies through sharing. Additionally, sharing transform 591 feedback objects between contexts doesn't seem particularly useful -- 592 an object could only really be used by one context at a time and 593 explicit synchronization would be required to use the results of one 594 object. 595 596 Note that this resolution is consistent with query objects, which is 597 the primary type of object used in the original transform feedback 598 specification. 599 600 3. How do the new transform feedback objects interact with GLSL program 601 objects? 602 603 RESOLVED: The set of varyings captured during transform feedback and 604 the buffer mode (interleaved or separate) were assigned to the program 605 object in the original EXT_transform_feedback specification. That 606 seems sensible given that the varyings themselves belong to the 607 program object. 608 609 In the original extension, implementations are forbidden to unbind or 610 relink a program object or reassign the set of varyings to capture 611 while transform feedback is active. The same basic restrictions apply 612 in this extension, except that than an application may unbind a 613 program object while transform feedback is paused. In order to resume 614 transform feedback, the same program object must be active. 615 Applications may not relink a program or reassign its captured 616 varyings while it is being actively used for capture in any transform 617 feedback object. 618 619 The actual buffer objects bound in transform feedback mode were bound 620 to the context (not the program object) in the original transform 621 feedback extension. 622 623 4. Should we provide any behavior to "cancel" paused transform feedback 624 operations? If an application fails to assign the correct state 625 (e.g., GLSL program object), a resume operation may fail and the XFB 626 object might get stuck in a paused state indefinitely. 627 628 RESOLVED: Yes. EndTransformFeedback is defined to cancel an active 629 transform feedback operation, even if it is currently paused. 630 631 5. Should buffer object bindings be encapsulated in the new transform 632 feedback object? 633 634 RESOLVED: Yes. This allows applications the convenience of updating 635 all the transform feedback state in one call. Additionally, it 636 ensures that the set of buffer bindings remains consistent while 637 transform feedback is active -- even if we switch objects while 638 paused. 639 640 6. Should we be able to use two different sets of transform feedback 641 state (one for capture, a second for rendering - via 642 DrawTransformFeedbackEXT)? 643 644 RESOLVED: Yes. We should support the ability to capture primitives 645 in transform feedback that are produced by DrawTransformFeedbackEXT. 646 Requiring that applications use the a single transform feedback object 647 for both operations (if even possible) seems inconvenient. As a 648 result, we provide the ability to use separate objects for capture and 649 rendering. 650 651 7. How should the second transform feedback object used for rendering be 652 provided to the GL? 653 654 RESOLVED: The approach chosen by this extension is to have 655 DrawTransformFeedbackEXT() accept a transform feedback object ID. 656 657 An alternate approach would have been to provide a second binding 658 point (TRANSFORM_FEEDBACK_RENDER_EXT?) whose bound object would be used 659 by any DrawTransformFeedbackEXT() call. 660 661 662 8. Can a single transform feedback object be used for both capture and 663 drawing (via DrawTransformFeedback) at the same time? 664 665 RESOLVED: Yes. 666 667 DrawTransformFeedbackEXT is defined to use the vertex count established 668 when the previous transform feedback operation on that object 669 completes (by an EndTransformFeedbackEXT call). If transform feedback 670 is active for an object (paused or not), the accumulated vertex count 671 for the in-progress operation is never used by 672 DrawTransformFeedbackEXT. 673 674 9. Does DrawTransformFeedbackEXT() automatically use the buffer objects 675 from the previous transform feedback operation? If not, does it 676 require that applications set up and use only those buffer manually? 677 678 RESOLVED: DrawTransformFeedbackEXT() couldn't automatically set up 679 buffer objects, even if we wanted to (which we don't). No mechanism 680 exists to automatically line up per-vertex outputs captured during 681 transform feedback against the inputs of a different vertex shader. 682 683 Applications are thus required to manually set up their vertex arrays 684 appropriately prior to calling DrawTransformFeedbackEXT(). 685 Applications are not required to use any of the buffer objects 686 written to during the previous transform feedback operation, and are 687 allowed to use other buffer objects (OK) or vertex arrays not stored 688 in a buffer object at all (legal, but not recommended). The only 689 information the draw call uses from the previous transform feedback 690 operation is the total number of vertices captured. 691 692 10. Does DrawTransformFeedbackEXT() require that an application use the 693 same primitive type for drawing that was used during the previous 694 transform feedback operation? 695 696 RESOLVED: No. We do expect that will be the common case, however. 697 698 11. What happens on if DrawTransformFeedbackEXT() uses a transform feedback 699 object whose last capture operation overflowed, and started dropping 700 primitives. 701 702 RESOLVED: Any primitives discarded during a transform feedback 703 operation will not affect the vertex count extracted by 704 DrawTransformFeedbackEXT(), as though those primitives never existed. 705 706 12. How does the ability to pause/resume transform feedback interact with 707 the TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT query object? 708 709 RESOLVED: There is no explicit interaction in this case. 710 711 The transform feedback-related query objects and transform feedback 712 objects are completely independent. If multiple transform feedback 713 objects are used between BeginQuery() and EndQuery() calls, the query 714 result reflects the number of primitives written using *any* transform 715 feedback object. 716 717 Note that the primitives written counter is never incremented when 718 transform feedback is paused, because no primitives will be written to 719 buffers while transform feedback is paused. 720 721 13. Should we provide a mechanism to query the number of vertices or 722 primitives recorded in the last transform feedback operation on an 723 object? If so, how? 724 725 RESOLVED: No, not in this spec. The existing TRANSFORM_FEEDBACK_ 726 PRIMITIVES_WRITTEN_EXT queries can be used to obtain this information. 727 728 14. Can a buffer object be attached to more than one transform feedback 729 object at the same time? 730 731 RESOLVED: Yes. Applications using transform feedback should avoid 732 cases where transform feedback operations can conflict, including: 733 734 * using multiple threads that simultaneously write to overlapping 735 regions of a single buffer object; or 736 737 * using one or multiple threads, where a portion of a buffer object 738 is written using one transform feedback object while another 739 transform feedback operation writing to an overlapping region of 740 the same buffer is paused. 741 742 15. When a transform feedback object is active and not paused, binding a 743 different transform feedback object without pausing is specified to 744 result in an INVALID_OPERATION error. Should we instead define the 745 bind to implicitly pause and resume as required? 746 747 RESOLVED: No. While implicit pauses and resumes would be convenient, 748 they have interaction issues with the current transform feedback API. 749 750 In particular, transform feedback forbids applications from changing 751 various pieces of relevant state (e.g., transform feedback buffer 752 bindings, active GLSL program object) during an active transform 753 feedback operation. The active GLSL program object may be changed 754 while transform feedback is paused, but it must be restored prior to 755 resuming. 756 757 Consider two active transform feedback objects (A and B) using two 758 different program objects (C and D, respectively). With the current 759 API, you can switch back and forth as follows: 760 761 // Perform first half of transform feedback for object A. 762 UseProgram(C); 763 BindTransformFeedbackEXT(TRANSFORM_FEEDBACK_EXT, A); 764 BeginTransformFeedbackEXT(...); 765 ... 766 PauseTransformFeedbackEXT(); 767 768 // Perform first half of transform feedback for object B. 769 UseProgram(D); 770 BindTransformFeedbackEXT(TRANSFORM_FEEDBACK_EXT, B); 771 BeginTransformFeedbackEXT(...); 772 ... 773 PauseTransformFeedbackEXT(); 774 775 // Perform second half of transform feedback for object A. 776 UseProgram(C); 777 BindTransformFeedbackEXT(TRANSFORM_FEEDBACK_EXT, A); 778 ResumeTransformFeedbackEXT(); 779 ... 780 EndTransformFeedbackEXT(); 781 782 // Perform second half of transform feedback for object B. 783 UseProgram(D); 784 BindTransformFeedbackEXT(TRANSFORM_FEEDBACK_EXT, B); 785 ResumeTransformFeedbackEXT(); 786 ... 787 EndTransformFeedbackEXT(); 788 789 Implicit pauses and resumes would allow applications to omit the 790 PauseTransformFeedbackEXT() and ResumeTransformFeedbackEXT() calls. The 791 problem with this approach is that it's not clear when to change 792 program objects. In the example above, the second call to 793 UseProgram(C) is legal because the bound transform feedback object (B) 794 is paused. If the pause call were removed in favor of implicit 795 pauses, that UseProgram(C) call would be illegal because there is an 796 active transform feedback object. Assume the UseProgram(C) call were 797 moved to be after the BindTransformFeedbackEXT(..., A) call on the next 798 line instead. In that case, the implicit resume on the bind call 799 would be the problem instead -- we'd be resuming a transform feedback 800 operation while the wrong program object (D) is active. 801 802 803Revision History 804 805 Rev. Date Author Changes 806 ---- -------- -------- ----------------------------------------- 807 3 10/12/09 ericz Removed some state that was part of 808 NV_transform_feedback and only applied to 809 fixed function. 810 811 2 09/10/09 ericz Updated issues that were previously UNRESOLVED, 812 based on the latest NV_transform_feedback2 813 spec. Allow EndTransformFeedbackEXT to be 814 called while transform feedback is paused. 815 816 1 06/13/09 ericz Created an initial EXT_transform_feedback2 817 spec by forking off the existing 818 NV_transform_feedback 2 spec.