1Name 2 3 NV_pixel_buffer_object 4 5Name Strings 6 7 GL_NV_pixel_buffer_object 8 9Contributors 10 11 Contributors to ARB_pixel_buffer_object 12 Greg Roth, NVIDIA 13 14Contact 15 16 Mathias Heyer, NVIDIA Corporation (mheyer 'at' nvidia.com) 17 18Status 19 20 Complete. 21 22Version 23 24 Last Modified Date: April 27th, 2020 25 Revision: 3.0 26 27Number 28 29 OpenGL ES Extension #134 30 31Dependencies 32 33 Written based on the wording of the OpenGL ES 2.0 specification. 34 35 OES_mapbuffer affects the definition of this specification 36 EXT_map_buffer_range affects the definition of this specification 37 38Overview 39 40 This extension permits buffer objects to be used not only with vertex 41 array data, but also with pixel data. The intent is to provide more 42 acceleration opportunities for OpenGL pixel commands. 43 44 While a single buffer object can be bound for both vertex arrays and 45 pixel commands, we use the designations vertex buffer object (VBO) 46 and pixel buffer object (PBO) to indicate their particular usage in 47 a given situation. 48 49 This extension does not add any new functionality to buffer objects 50 themselves. It simply adds two new targets to which buffer objects 51 can be bound: GL_PIXEL_PACK_BUFFER_NV and GL_PIXEL_UNPACK_BUFFER_NV. 52 When a buffer object is bound to the GL_PIXEL_PACK_BUFFER_NV target, 53 commands such as glReadPixels pack (write) their data into a buffer 54 object. When a buffer object is bound to the GL_PIXEL_UNPACK_BUFFER_NV 55 target, commands such as glTexImage2D unpack (read) their 56 data from a buffer object. 57 58 There are a several approaches to improve graphics performance 59 with PBOs. Some of the most interesting approaches are: 60 61 - Streaming texture updates: If the application uses 62 glMapBufferOES/glMapBufferRangeEXT/glUnmapBufferOES to write 63 its data for glTexSubImage into a buffer object, at least one of 64 the data copies usually required to download a texture can be 65 eliminated, significantly increasing texture download performance. 66 67 - Asynchronous glReadPixels: If an application needs to read back a 68 number of images and process them with the CPU, the existing GL 69 interface makes it nearly impossible to pipeline this operation. 70 The driver will typically send the hardware a readback command 71 when glReadPixels is called, and then wait for all of the data to 72 be available before returning control to the application. Then, 73 the application can either process the data immediately or call 74 glReadPixels again; in neither case will the readback overlap with 75 the processing. If the application issues several readbacks 76 into several buffer objects, however, and then maps each one to 77 process its data, then the readbacks can proceed in parallel with 78 the data processing. 79 80 - Render to vertex array: The application can use a fragment 81 program to render some image into one of its buffers, then read 82 this image out into a buffer object via glReadPixels. Then, it can 83 use this buffer object as a source of vertex data. 84 85 86New Procedures and Functions 87 88 None. 89 90 91New Tokens 92 93 Accepted by the <target> parameters of BindBuffer, BufferData, 94 BufferSubData, MapBufferOES, MapBufferRangeEXT, UnmapBufferOES, 95 FlushMappedBufferRangeEXT, GetBufferParameteriv, and 96 GetBufferPointervOES: 97 98 PIXEL_PACK_BUFFER_NV 0x88EB 99 PIXEL_UNPACK_BUFFER_NV 0x88EC 100 101 Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, 102 GetFloatv: 103 104 PIXEL_PACK_BUFFER_BINDING_NV 0x88ED 105 PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF 106 107 108Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL Operation) 109 110 -- Section 2.9 "Buffer Objects" 111 112 Replace the first two paragraphs with: 113 114 "The vertex data arrays described in section 2.8 are stored in 115 client memory. It is sometimes desirable to store frequently accessed 116 client data, such as vertex array and pixel data, in high-performance 117 server memory. GL buffer objects provide a mechanism for clients to 118 use to allocate, initialize, and access such memory." 119 120 The name space for buffer objects is the unsigned integer, with zero 121 reserved for the GL. A buffer object is created by binding an unused 122 name to a buffer target. The binding is effected by calling 123 124 void BindBuffer(enum target, uint buffer); 125 126 <target> must be one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, 127 PIXEL_UNPACK_BUFFER_NV, or PIXEL_PACK_BUFFER_NV. The ARRAY_BUFFER 128 target is discussed in section 2.9.1 The ELEMENT_ARRAY_BUFFER target 129 is discussed in section 2.9.2. The PIXEL_UNPACK_BUFFER_NV and 130 PIXEL_PACK_BUFFER_NV targets are discussed later in sections 3.7.1 and 131 4.3. If the buffer object named <buffer> has not been 132 previously bound or has been deleted since the last binding, the 133 GL creates a new state vector, initialized with a zero-sized memory 134 buffer and comprising the state values listed in table 2.5." 135 136 Replace the 5th paragraph with: 137 138 "Initially, each buffer object target is bound to zero. There is 139 no buffer object corresponding to the name zero so client attempts 140 to modify or query buffer object state for a target bound to zero 141 generate an INVALID_OPERATION error." 142 143 Replace the phrase listing the valid targets for BufferData in the 144 9th paragraph with: 145 146 "with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, 147 PIXEL_UNPACK_BUFFER_NV, or PIXEL_PACK_BUFFER_NV," 148 149 In the 10th paragraph describing buffer object usage modes, replace 150 the phrase "specified once" with "specified once per repetition of 151 the usage pattern" for the STREAM_* and STATIC_* usage values. 152 153 Also in the 10th paragraph describing buffer object usage modes, 154 replace the phrases "of a GL drawing command." and "for GL drawing 155 commands." with "for GL drawing and image specification commands." for 156 the *_DRAW usage values. 157 158 Replace the phrase listing the valid targets for BufferSubData with: 159 160 "with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, 161 PIXEL_UNPACK_BUFFER_NV, or PIXEL_PACK_BUFFER_NV." 162 163 Replace the phrase listing the valid targets for MapBufferOES with: 164 165 "with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, 166 PIXEL_UNPACK_BUFFER_NV, or PIXEL_PACK_BUFFER_NV." 167 168 Replace the phrase listing the valid targets for UnmapBufferOES with: 169 170 "with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, 171 PIXEL_UNPACK_BUFFER_NV, or PIXEL_PACK_BUFFER_NV." 172 173 Replace the phrase listing the valid targets for MapBufferRangeEXT 174 with: 175 176 "with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, 177 PIXEL_UNPACK_BUFFER_NV, or PIXEL_PACK_BUFFER_NV." 178 179 Replace the phrase listing the valid targets for 180 FlushMappedBufferRangeEXT with: 181 182 "with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, 183 PIXEL_UNPACK_BUFFER_NV, or PIXEL_PACK_BUFFER_NV." 184 185 -- Section 2.9.2 "Array Indices in Buffer Objects" 186 187 Delete the 3rd paragraph that explains how the ELEMENT_ARRAY_BUFFER 188 target is acceptable for the commands specified in section 2.9. 189 The updated section 2.9 language already says this. 190 191Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) 192 193 -- Section 3.6 "Pixel Rectangles" 194 195 Replace the last two paragraphs with: 196 197 "This section describes only how these rectangles are defined in 198 buffer object and client memory, and the steps involved in 199 transferring pixel rectangles from buffer object or client memory 200 to the GL or vice-versa. 201 Parameters controlling the encoding of pixels in buffer object or 202 client memory (for reading and writing) are set with the command 203 PixelStorei." 204 205 -- Rename Section 3.6.1 "Pixel Storage Modes and Pixel Buffer Objects" 206 207 Add to the end of the section: 208 209 "In addition to storing pixel data in client memory, pixel data 210 may also be stored in buffer objects (described in section 2.9). 211 The current pixel unpack and pack buffer objects are designated 212 by the PIXEL_UNPACK_BUFFER_NV and PIXEL_PACK_BUFFER_NV targets 213 respectively. 214 215 Initially, zero is bound for the PIXEL_UNPACK_BUFFER_NV, indicating 216 that image specification commands such as TexImage*D source their 217 pixels from client memory pointer parameters. However, if a non-zero 218 buffer object is bound as the current pixel unpack buffer, then 219 the pointer parameter is treated as an offset into the designated 220 buffer object." 221 222 223 -- Section 3.6.2 "Transfer of Pixel Rectangles", page 61. 224 225 Change the 1st sentence of the 1st paragraph to read: 226 227 "The process of transferring pixels encoded in buffer object 228 or client memory is diagrammed in figure 3.5." 229 230 Change the 4th sentence of the 2nd paragraph to read: 231 232 "<data> refers to the data to be transferred." 233 234 [data is no longer necessarily a pointer.] 235 236 Change the initial phrase in the 1st sentence of the 1st paragraph 237 in subsection "Unpacking" to read: 238 239 "Data are taken from the currently bound pixel unpack buffer or 240 client memory as a sequence of..." 241 242 Insert this paragraph after the 1st paragraph in subsection 243 "Unpacking": 244 245 "If a pixel unpack buffer is bound (as indicated by a non-zero 246 value of PIXEL_UNPACK_BUFFER_BINDING_NV), <data> is an offset 247 into the pixel unpack buffer and the pixels are unpacked from the 248 buffer relative to this offset; otherwise, <data> is a pointer to 249 a block client memory and the pixels are unpacked from the client 250 memory relative to the pointer. If a pixel unpack buffer object 251 is bound and unpacking the pixel data according to the process 252 described below would access memory beyond the size of the pixel 253 unpack buffer's memory size, INVALID_OPERATION results. If a pixel 254 unpack buffer object is bound and <data> is not evenly divisible 255 into the number of basic machine units needed to store in memory the 256 corresponding GL data type from table 3.4 for the <type> parameter, 257 INVALID_OPERATION results." 258 259 -- Section 3.7.1 "Texture Image Specification", page 66. 260 261 Replace the last phrase in the 2nd to last sentence in the 1st 262 paragraph with: 263 264 "and a reference to the image data in the currently bound pixel unpack 265 buffer or client memory, as described in section 3.6.2." 266 267 Replace the 1st sentence in the 9th paragraph with: 268 269 "The image itself (referred to by <data>) is a sequence of groups 270 of values." 271 272 Replace the last paragraph with: 273 274 "If the data argument of TexImage2D is a NULL pointer, and the 275 pixel unpack buffer object is zero, a two- or three-dimensional 276 texel array is created with the specified target, level, internalformat, 277 border, width, height, and depth, but with unspecified image contents. 278 In this case no pixel values are accessed in client memory, and no pixel 279 processing is performed. Errors are generated, however, exactly as though 280 the data pointer were valid. Otherwise if the pixel unpack buffer object 281 is non-zero, the data argument is treatedly normally to refer to the 282 beginning of the pixel unpack buffer object's data." 283 284 -- Section 3.7.3 "Compressed Texture Images", page 73. 285 286 Replace the 3rd sentence of the 2nd paragraph with: 287 288 "<data> refers to compressed image data stored in the compressed 289 image format corresponding to internalformat. If a pixel 290 unpack buffer is bound (as indicated by a non-zero value of 291 PIXEL_UNPACK_BUFFER_BINDING_NV), <data> is an offset into the 292 pixel unpack buffer and the compressed data is read from the buffer 293 relative to this offset; otherwise, <data> is a pointer to a block 294 client memory and the compressed data is read from the client memory 295 relative to the pointer." 296 297 Replace the 2nd sentence in the 3rd paragraph with: 298 299 "Compressed texture images are treated as an array of <imageSize> 300 ubytes relative to <data>. If a pixel unpack buffer object is bound 301 and data+imageSize is greater than the size of the pixel buffer, 302 INVALID_OPERATION results." 303 304Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment 305Operations and the Frame Buffer) 306 307 -- Section 4.3 "Reading Pixels", page 104. 308 309 Replace the first paragraph with: 310 311 "Pixels may be read from the framebuffer to pixel pack buffer or 312 client memory using the ReadPixels commands, as described below. 313 Pixels may also be copied from pixel unpack buffer, client memory or 314 the framebuffer to texture images in the GL using the TexImage2D and 315 CopyTexImage2D commands, as described in section 3.7.1. 316 317 -- Section 4.3.1 "Reading Pixels", page 104. 318 319 Replace 1st sentence of the 1st paragraph with: 320 321 "The method for reading pixels from the framebuffer and placing them in 322 pixel pack buffer or client memory is diagrammed in figure 4.2." 323 324 Add this paragraph after the 1st paragraph: 325 326 "Initially, zero is bound for the PIXEL_PACK_BUFFER_NV, indicating 327 that image read and query commands such as ReadPixels return 328 pixels results into client memory pointer parameters. However, if 329 a non-zero buffer object is bound as the current pixel pack buffer, 330 then the pointer parameter is treated as an offset into the designated 331 buffer object." 332 333 Rename "Placement in Client Memory" to "Placement in Pixel Pack 334 Buffer or Client Memory". 335 336 Insert this paragraph at the start of the newly renamed 337 subsection "Placement in Pixel Pack Buffer or Client Memory": 338 339 "If a pixel pack buffer is bound (as indicated by a non-zero value 340 of PIXEL_PACK_BUFFER_BINDING_NV), <data> is an offset into the 341 pixel pack buffer and the pixels are packed into the 342 buffer relative to this offset; otherwise, <data> is a pointer to a 343 block client memory and the pixels are packed into the client memory 344 relative to the pointer. If a pixel pack buffer object is bound and 345 packing the pixel data according to the pixel pack storage state 346 would access memory beyond the size of the pixel pack buffer's 347 memory size, INVALID_OPERATION results. If a pixel pack buffer object 348 is bound and <data> is not evenly divisible into the number of basic 349 machine units needed to store in memory the corresponding GL data type 350 from table 3.5 for the <type> parameter, INVALID_OPERATION results." 351 352 353Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) 354 355 None 356 357 358Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State 359Requests) 360 361--- Section 6.1.3 Enumerated Queries 362 363 Change the 1st sentence of the 3rd paragraph to read: 364 "The command 365 void GetBufferParameteriv( enum target, enum value, T data ); 366 returns information about <target>, which may be one of ARRAY_BUFFER, 367 ELEMENT_ARRAY_BUFFER, PIXEL_PACK_BUFFER_NV, PIXEL_UNPACK_BUFFER_NV 368 indicating the currently bound vertex array, element array, pixel pack 369 and pixel unpack buffer object." 370 371 -- Section 6.1.13 "Buffer Object Queries". 372 373 (description of glGetBufferPointervOES) 374 Change the 2nd sentence of the 2nd paragraph to read: 375 "<target> is ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, PIXEL_PACK_BUFFER_NV, 376 or PIXEL_UNPACK_BUFFER_NV." 377 378 379Errors 380 381 INVALID_ENUM is generated if the <target> parameter of 382 BindBuffer, BufferData, BufferSubData, MapBufferOES, UnmapBufferOES, 383 GetBufferParameteriv or GetBufferPointervOES is not 384 one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, PIXEL_PACK_BUFFER_NV, 385 or PIXEL_UNPACK_BUFFER_NV. 386 387 INVALID_OPERATION is generated if CompressedTexImage2D, 388 CompressedTexSubImage2D, TexImage2D or TexSubImage2D would unpack 389 (read) data from the currently bound PIXEL_UNPACK_BUFFER_NV buffer 390 object such that the memory reads required for the command would exceed 391 the memory (data store) size of the buffer object. 392 393 INVALID_OPERATION is generated if ReadPixels or ReadnPixelsEXT 394 would pack (write) data to the currently bound PIXEL_PACK_BUFFER_NV 395 buffer object such that the memory writes required for the command would 396 exceed the memory (data store) size of the buffer object. 397 398 INVALID_OPERATION is generated by ReadPixels or ReadnPixelsEXT 399 if the current PIXEL_PACK_BUFFER_BINDING_NV value is non-zero and the 400 table/image/values/span/img/data parameter is not evenly divisible 401 into the number of basic machine units needed to store in memory a 402 datum indicated by the type parameter. 403 404 INVALID_OPERATION is generated by TexImage2D or TexSubImage2D 405 if current PIXEL_UNPACK_BUFFER_BINDING_NV value is non-zero and the data 406 parameter is not evenly divisible into the number of basic machine 407 units needed to store in memory a datum indicated by the type 408 parameter. 409 410Dependencies on OES_mapbuffer 411 412 If OES_mapbuffer is not present, references to MapBufferOES and 413 UnmapBufferOES should be ignored and language referring to mapped 414 buffer objects should be removed. 415 416Dependencies on EXT_map_buffer_range 417 418 If EXT_map_buffer_range is not present, references to 419 MapBufferRangeEXT anf FlushMappedBufferRangeEXT should be ignored. 420 421New State 422 423(table 6.13, Pixels, p. 147) 424 425 Initial 426 Get Value Type Get Command Value Sec 427 ------------------------------- ---- ----------- ------- ------ 428 PIXEL_PACK_BUFFER_BINDING_NV Z+ GetIntegerv 0 4.3.1 429 PIXEL_UNPACK_BUFFER_BINDING_NV Z+ GetIntegerv 0 3.6.1 430 431 432 433Usage Examples 434 435 Convenient macro definition for specifying buffer offsets: 436 437 #define BUFFER_OFFSET(i) ((char *)NULL + (i)) 438 439 Example 1: Render to vertex array: 440 441 const int numberVertices = 100; 442 443 // Create a buffer object for a number of vertices consisting of 444 // 4 float values per vertex 445 glGenBuffers(1, vertexBuffer); 446 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, vertexBuffer); 447 glBufferData(GL_PIXEL_PACK_BUFFER_NV, numberVertices*4, 448 NULL, GL_DYNAMIC_DRAW); 449 450 // Render vertex data into 100x1 strip of framebuffer using a 451 // shader program 452 glUseProgram(program); 453 renderVertexData(); 454 glBindProgramARB(FRAGMENT_PROGRAM_ARB, 0); 455 456 // Read the vertex data back from framebuffer 457 glReadPixels(0, 0, numberVertices, 1, GL_BGRA, GL_UNSIGNED_BYTE, 458 BUFFER_OFFSET(0)); 459 460 // Change the binding point of the buffer object to 461 // the vertex array binding point 462 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 463 464 glEnableVertexAttribArray(0); 465 glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, BUFFER_OFFSET(0)); 466 glDrawArrays(TRIANGLE_STRIP, 0, numberVertices); 467 468 469 Example 2: Streaming textures 470 471 Streaming textures using pixel buffer objects: 472 473 const int texWidth = 256; 474 const int texHeight = 256; 475 const int texsize = texWidth * texHeight * 4; 476 void *pboMemory, *texData; 477 478 // Define texture level zero (without an image); notice the 479 // explicit bind to the zero pixel unpack buffer object so that 480 // pass NULL for the image data leaves the texture image 481 // unspecified. 482 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_NV, 0); 483 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, 484 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 485 486 // Create and bind texture image buffer object 487 glGenBuffers(1, &texBuffer); 488 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_NV, texBuffer); 489 490 // Setup texture environment 491 ... 492 493 texData = getNextImage(); 494 495 while (texData) { 496 497 // Reset the contents of the texSize-sized buffer object 498 glBufferData(GL_PIXEL_UNPACK_BUFFER_NV, texSize, NULL, 499 GL_STREAM_DRAW); 500 501 // Map the texture image buffer (the contents of which 502 // are undefined due to the previous glBufferData) 503 pboMemory = glMapBufferOES(GL_PIXEL_UNPACK_BUFFER_NV, 504 GL_WRITE_ONLY); 505 506 // Modify (sub-)buffer data 507 memcpy(pboMemory, texData, texsize); 508 509 // Unmap the texture image buffer 510 glUnmapBufferOES(GL_PIXEL_UNPACK_BUFFER_NV); 511 512 // Update (sub-)teximage from texture image buffer 513 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, 514 GL_RGBA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)); 515 516 // Draw textured geometry 517 ... 518 519 texData = getNextImage(); 520 } 521 522 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_NV, 0); 523 524 525 Example 3: Asynchronous glReadPixels 526 527 Traditional glReadPixels: 528 529 const int imagewidth = 640; 530 const int imageheight = 480; 531 GLubyte readBuffer[imagewidth*imageheight*4]; 532 533 // Render to framebuffer 534 renderScene() 535 536 // Read image from framebuffer 537 glReadPixels(0, 0, imagewidth, imageheight, GL_RGBA, 538 GL_UNSIGNED_BYTE, readBuffer); 539 540 // Process image when glReadPixels returns after reading the 541 // whole buffer 542 processImage(readBuffer); 543 544 545 Asynchronous glReadPixels: 546 547 const int imagewidth = 640; 548 const int imageheight = 480; 549 const int imageSize = imagewidth*imageheight*4; 550 551 glGenBuffers(2, imageBuffers); 552 553 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[0]); 554 glBufferData(GL_PIXEL_PACK_BUFFER_NV, imageSize / 2, NULL, 555 GL_STREAM_DRAW); 556 557 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[1]); 558 glBufferData(GL_PIXEL_PACK_BUFFER_NV, imageSize / 2, NULL, 559 GL_STREAM_DRAW); 560 561 // Render to framebuffer 562 glDrawBuffer(GL_BACK); 563 renderScene(); 564 565 // Bind two different buffer objects and start the glReadPixels 566 // asynchronously. Each call will return directly after 567 // starting the DMA transfer. 568 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[0]); 569 glReadPixels(0, 0, imagewidth, imageheight/2, GL_RGBA, 570 GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)); 571 572 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[1]); 573 glReadPixels(0, imageheight/2, imagewidth, imageheight/2, GL_RGBA, 574 GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)); 575 576 // Process partial images. Mapping the buffer waits for 577 // outstanding DMA transfers into the buffer to finish. 578 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[0]); 579 pboMemory1 = glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER_NV, 0, 580 imageSize/2, GL_MAP_READ_BIT_EXT); 581 processImage(pboMemory1); 582 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[1]); 583 pboMemory2 = glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER_NV, 0, 584 imageSize/2, GL_MAP_READ_BIT_EXT); 585 processImage(pboMemory2); 586 587 // Unmap the image buffers 588 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[0]); 589 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_NV); 590 glBindBuffer(GL_PIXEL_PACK_BUFFER_NV, imageBuffers[1]); 591 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_NV); 592 593 594Issues 595 596 597 1) Can a given buffer be used for both vertex and pixel data? 598 599 RESOLVED: YES. All buffers can be used with all buffer bindings, 600 in whatever combinations the application finds useful. Consider 601 yourself warned, however, by the following issue. 602 603 2) May implementations make use of the target as a hint to select 604 an appropriate memory space for the buffer? 605 606 RESOLVED: YES, as long as such behavior is transparent to the 607 application. Some implementations may choose different memory 608 spaces for different targets. 609 In fact, one can imagine arbitrarily complicated heuristics for 610 selecting the memory space, based on factors such as the target, 611 the "usage" argument, and the application's observed behavior. 612 613 While it is entirely legal to create a buffer object by binding 614 it to GL_ARRAY_BUFFER and loading it with data, then using it 615 with the GL_PIXEL_UNPACK_BUFFER_NV or GL_PIXEL_PACK_BUFFER_NV 616 binding, such behavior is liable to confuse the driver and may 617 hurt performance. If the driver implemented the hypothetical 618 heuristic described earlier, such a buffer might have already 619 been located in AGP memory, and so the driver would have to choose 620 between two bad options: relocate the buffer into video memory, or 621 accept lower performance caused by streaming pixel data from AGP. 622 623 3) Should the INVALID_OPERATION error be generated if a pixel 624 command would access data outside the range of the bound PBO? 625 626 RESOLVED: YES. This requires considering the command parameters 627 (such as width/height/depth/format/type/pointer), the current 628 pixel store (pack/unpack) state, and the command operation itself 629 to determine the maximum addressed byte for the pixel command. 630 631 This behavior should increase the reliability of using PBO and 632 guard against programmer mistakes. 633 634 This is particularly important for glReadPixels where returning 635 data into a region outside the PBO could cause corruption of 636 application memory. 637 638 Such bounds checking is substantially more expensive for VBO 639 accesses because bounds checking on a per-vertex element basis 640 for each of multiple enabled vertex arrays prior to performing 641 the command compromises the performance justification of VBO. 642 643 4) If a pixel command with a bound PBO accesses data outside the 644 range of the PBO, thereby generating a GL_INVALID_OPERATION error, 645 can the pixel command end up being partially processed? 646 647 RESOLVED: NO. As for all GL errors excepting GL_OUT_OF_MEMORY 648 situations, "the command generating the error is ignored so that 649 it has no effect on GL state or framebuffer contents." 650 651 This means implementations must determine before the pixel command 652 is performed whether the resulting read or write operations on 653 the bound PBO will exceed the size of the PBO. 654 655 This means an implementation is NOT allowed to detect out of 656 bounds accesses in the middle of performing the command. 657 658 5) Should an INVALID_OPERATION error be generated if the offset 659 within a pixel buffer to a datum comprising of N basic machine 660 units is not a multiple of N? 661 662 RESOLVED: YES. This was stated for VBOs but no error was 663 defined if the rule was violated. Perhaps this needs to be 664 better specified for VBO. 665 666 For PBO, it is reasonable and cheap to enforce the alignment rule. 667 For pixel commands it means making sure the offset is evenly 668 divisible by the component or group size in basic machine units. 669 670 This check is independent of the pixel store state because the 671 pixel store state is specified in terms of pixels (not basic 672 machine units) so pixel store addressing cannot create an 673 unaligned access as long as the base offset is aligned. 674 675 Certain commands (specifically, 676 glCompressedTexImage2D, glCompressedTexSubImage2D) are not 677 affected by this error because the data accessed is addressed 678 at the granularity of basic machine units. 679 680 6) Various commands do not make explicit reference to supporting 681 packing or unpacking from a pixel buffer object but rather specify 682 that parameters are handled in the same manner as glReadPixels, 683 or the glCompressedTexImage commands. So do such 684 commands (example: glCompressedTexSubImage2D) use pixel buffers? 685 686 RESOLVED: YES. Commands that have their behavior defined based 687 on commands that read or write from pixel buffers will themselves 688 read or write from pixel buffers. Relying on this reduces the 689 amount of specification language to be updated. 690 691 7) What is the complete list of commands that can unpack (read) 692 pixels from the current pixel unpack buffer object? 693 694 glCompressedTexImage2D 695 glCompressedTexSubImage2D 696 glTexImage2D 697 glTexSubImage2D 698 699 8) What is the complete list of commands that can pack (write) 700 pixels into the current pixel pack buffer object? 701 702 glReadPixels 703 704 9) Prior to this extension, passing zero for the data argument of 705 glTexImage2D defined a texture image level without supplying an image. 706 How does this behavior change with this extension? 707 708 RESOLVED: The "unspecified image" behavior of the glTexImage 709 calls only applies when bound to a zero pixel unpack buffer 710 object. 711 712 When bound to a non-zero pixel unpack buffer object, the data 713 argument to these calls is treated as an offset rather than 714 a pointer so zero is a reasonable and even likely value that 715 corresponds to the very beginning of the buffer object's data. 716 717 So to create a texture image level with unspecified image data, 718 you MUST bind to the zero pixel unpack buffer object. 719 720 See the ammended language at the end of section 3.7.1. 721 722 10) How does this extension support video frame grabbers? 723 724 RESOLVED: This extension extends buffer objects so they can 725 operate with pixel commands, rather than just vertex array 726 commands. 727 728 We anticipate that a future extension may provide a mechanism 729 for transferring video frames from video frame grabber hardware 730 or vertices from motion capture hardware (or any other source 731 of aquired real-time data) directly into a buffer object to 732 eliminate a copy. Ideally, such transfers would be possible 733 without requiring mapping of the buffer object. But this 734 extension does not provide such functionality. 735 736 We anticipate such functionality to involve binding a buffer 737 object to a new target type, configuring a source (or sink) for 738 data (video frames, motion capture vertex sets, etc.), and then 739 commands to initiate data transfers to the bound buffer object. 740 741 11) Is this the "right" way to expose render-to-vertex-array? 742 743 DISCUSSION: You can use this extension to render an image 744 into a framebuffer, copy the pixels into a buffer object with 745 glReadPixels, and then configure vertex arrays to source the pixel 746 data as vertex attributes. This necessarily involves a copy 747 from the framebuffer to the buffer object. Future extensions 748 may provide mechanisms for copy-free render-to-vertex-array 749 capabilities but that is not a design goal of this extension. 750 751Revision History 752 753 3 04/27/2020 fix example code: GL_STREAM_READ is not available in ES2.0 754 glMapBufferOES does not allow reading from the mapped pointer. 755 2 10/23/2012 more cleanup, interaction with EXT_map_buffer_range 756 1 04/19/2012 initial revision 757 - took ARB_pixel_buffer_object, stripped everything not applicable to 758 ES, changed references to tables and sections; changed all wording 759 to fit ES' language. 760 761