1Name 2 3 EXT_buffer_storage 4 5Name Strings 6 7 GL_EXT_buffer_storage 8 9Contact 10 11 Daniel Koch, NVIDIA Corporation (dkoch 'at' nvidia.com) 12 13Contributors 14 15 Jonas Gustavsson, Sony Mobile 16 Slawomir Grajewski, Intel 17 Klaus Gerlicher, NVIDIA 18 Contributors to ARB_buffer_storage 19 20Notice 21 22 Copyright (c) 2013 The Khronos Group Inc. Copyright terms at 23 http://www.khronos.org/registry/speccopyright.html 24 25 Portions Copyright (c) 2014 NVIDIA Corporation. 26 27Status 28 29 Complete 30 31Version 32 33 Last Modified Date: May 1, 2015 34 Author Revision: 3 35 36Number 37 38 OpenGL ES Extension #239 39 40Dependencies 41 42 OpenGL ES 3.1 is required. 43 44 This extension is written against the OpenGL ES 3.1 (June 4, 2014) 45 Specification. 46 47 The definition of this extension is affected by the presence of 48 GL_EXT_direct_state_access. 49 50Overview 51 52 OpenGL ES has long supported buffer objects as a means of storing data 53 that may be used to source vertex attributes, pixel data for textures, 54 uniforms and other elements. In un-extended ES, buffer data stores 55 are mutable - that is, they may be de-allocated or resized while they 56 are in use. The GL_EXT_texture_storage extension added immutable storage 57 for texture objects (and was subsequently incorporated into OpenGL ES 3.0). 58 This extension further applies the concept of immutable storage to 59 buffer objects. If an implementation is aware of a buffer's immutability, 60 it may be able to make certain assumptions or apply particular 61 optimizations in order to increase performance or reliability. 62 63 Furthermore, this extension allows applications to pass additional 64 information about a requested allocation to the implementation which it 65 may use to select memory heaps, caching behavior or allocation strategies. 66 67 Finally, this extension introduces the concept of persistent client 68 mappings of buffer objects, which allow clients to retain pointers to a 69 buffer's data store returned as the result of a mapping, and to issue 70 drawing commands while those mappings are in place. 71 72New Procedures and Functions 73 74 void BufferStorageEXT(enum target, 75 sizeiptr size, 76 const void * data, 77 bitfield flags); 78 79 When EXT_direct_state_access is present: 80 81 void NamedBufferStorageEXT(uint buffer, 82 sizeiptr size, 83 const void * data, 84 bitfield flags); 85 86New Tokens 87 88 Accepted in the <flags> parameter of BufferStorageEXT and 89 NamedBufferStorageEXT: 90 91 MAP_READ_BIT 0x0001 (existing) 92 MAP_WRITE_BIT 0x0002 (existing) 93 MAP_PERSISTENT_BIT_EXT 0x0040 94 MAP_COHERENT_BIT_EXT 0x0080 95 DYNAMIC_STORAGE_BIT_EXT 0x0100 96 CLIENT_STORAGE_BIT_EXT 0x0200 97 98 Accepted as part of the <access> parameter to MapBufferRange: 99 100 MAP_PERSISTENT_BIT_EXT 0x0040 (as above) 101 MAP_COHERENT_BIT_EXT 0x0080 (as above) 102 103 Accepted by the <pname> parameter of GetBufferParameter{i|i64}v: 104 105 BUFFER_IMMUTABLE_STORAGE_EXT 0x821F 106 BUFFER_STORAGE_FLAGS_EXT 0x8220 107 108 Accepted by the <barriers> parameter of MemoryBarrier: 109 110 CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 111 112IP Status 113 114 No known IP claims. 115 116Additions to Chapter 2 of the OpenGL ES 3.1 Specification 117(OpenGL ES Fundamentals) 118 119 Insert before the last line of Section 2.6.2, "Buffer Objects", p. 24: 120 121 Under certain circumstances, the data store of a buffer object may 122 be shared between the client and server and accessed simultaneously 123 by both. 124 125Additions to Chapter 6 of the OpenGL ES 3.1 Specification (Buffer Objects) 126 127 Modify Section 6.1 (Creating and Binding Buffer Objects) 128 129 Append to Table 6.2, "Buffer object parameters and their values", p.49: 130 131 +------------------------------+---------+---------+------------------+ 132 | | | Initial | Legal | 133 | Name | Type | Value | Values | 134 +------------------------------+---------+---------+------------------+ 135 | BUFFER_IMMUTABLE_STORAGE_EXT | boolean | FALSE | TRUE, FALSE | 136 | BUFFER_STORAGE_FLAGS_EXT | int | 0 | See section 6.2 | 137 +------------------------------+---------+---------+------------------+ 138 139 140 Modify Section 6.2, (Creating and Modifying Buffer Object Data Stores), 141 p. 57 as follows: 142 143 The data store of a buffer object is created by calling 144 145 void BufferStorageEXT(enum target, 146 sizeiptr size, 147 const void * data, 148 bitfield flags); 149 150 with <target> set to one of the targets listed in Table 6.1, <size> set to 151 the size of the data store in basic machine units and <flags> containing 152 a bitfield describing the intended usage of the data store. The data 153 store of the buffer object bound to <target> is allocated as a result of 154 a call to this function and cannot be de-allocated until the buffer is 155 deleted with a call to DeleteBuffers. Such a store may not be 156 re-allocated through further calls to BufferStorageEXT or BufferData. 157 158 <data> specifies the address in client memory of the data that should 159 be used to initialize the buffer's data store. If <data> is NULL, the 160 data store of the buffer is created, but contains undefined data. 161 Otherwise, <data> should point to an array of at least <size> basic 162 machine units. 163 164 <flags> is the bitwise OR of flags describing the intended usage 165 of the buffer object's data store by the application. Valid flags and 166 their meanings are as follows: 167 168 DYNAMIC_STORAGE_BIT_EXT The contents of the data store may be 169 updated after creation through calls to BufferSubData. If this bit is not 170 set, the buffer content may not be directly updated by the client. The 171 <data> argument may be used to specify the initial content of the buffer's 172 data store regardless of the presence of the DYNAMIC_STORAGE_BIT_EXT. 173 Regardless of the presence of this bit, buffers may always be updated 174 with server-side calls such as CopyBufferSubData. 175 176 MAP_READ_BIT The data store may be mapped by the client for 177 read access and a pointer in the client's address space obtained that may 178 be read from. 179 180 MAP_WRITE_BIT The data store may be mapped by the client for 181 write access and a pointer in the client's address space obtained that may 182 be written to. 183 184 MAP_PERSISTENT_BIT_EXT The client may request that the server read from 185 or write to the buffer while it is mapped. The client's pointer to the 186 data store remains valid so long as the data store is mapped, even during 187 execution of drawing or dispatch commands. 188 189 MAP_COHERENT_BIT_EXT Shared access to buffers that are simultaneously 190 mapped for client access and are used by the server will be coherent, so 191 long as that mapping is performed using MapBufferRange. That is, data 192 written to the store by either the client or server will be visible to any 193 subsequently issued GL commands with no further action taken by the 194 application. In particular: 195 196 - If MAP_COHERENT_BIT_EXT is not set and the client performs a write 197 followed by a call to one of the FlushMapped*BufferRange commands 198 with a range including the written range, then in subsequent 199 commands the server will see the writes. 200 201 - If MAP_COHERENT_BIT_EXT is set and the client performs a write, then in 202 subsequent commands the server will see the writes. 203 204 - If MAP_COHERENT_BIT_EXT is not set and the server performs a write, the 205 application must call MemoryBarrier with the 206 CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT set and then call FenceSync with 207 SYNC_GPU_COMMANDS_COMPLETE (or Finish). Then the CPU will see the 208 writes after the sync is complete. 209 210 - If MAP_COHERENT_BIT_EXT is set and the server does a write, the app must 211 call FenceSync with SYNC_GPU_COMMANDS_COMPLETE (or Finish). Then the 212 CPU will see the writes after the sync is complete. 213 214 CLIENT_STORAGE_BIT_EXT When all other criteria for the buffer storage 215 allocation are met, this bit may be used by an implementation to determine 216 whether to use storage that is local to the server or to the client to 217 serve as the backing store for the buffer. 218 219 If <flags> contains MAP_PERSISTENT_BIT_EXT, it must also contain at least one 220 of MAP_READ_BIT or MAP_WRITE_BIT. 221 222 It is an error to specify MAP_COHERENT_BIT_EXT without also specifying 223 MAP_PERSISTENT_BIT_EXT. 224 225 BufferStorageEXT deletes any existing data store, and sets the values of 226 the buffer object's state variables as shown in table 6.3. 227 228 If any portion of the buffer object is mapped in the current context or 229 any context current to another thread, it is as though UnmapBuffer (see 230 section 6.3.1) is executed in each such context prior to deleting the 231 existing data store. 232 233 Name | Value for | Value for 234 | BufferData | *BufferStorageEXT 235 -----------------------------+-------------------------+------------------ 236 BUFFER_SIZE | <size> | <size> 237 BUFFER_USAGE | <usage> | DYNAMIC_DRAW 238 BUFFER_ACCESS | READ_WRITE | READ_WRITE 239 BUFFER_ACCESS_FLAGS | 0 | 0 240 BUFFER_IMMUTABLE_STORAGE_EXT | FALSE | TRUE 241 BUFFER_MAPPED | FALSE | FALSE 242 BUFFER_MAP_POINTER | NULL | NULL 243 BUFFER_MAP_OFFSET | 0 | 0 244 BUFFER_MAP_LENGTH | 0 | 0 245 BUFFER_STORAGE_FLAGS_EXT | MAP_READ_BIT | | <flags> 246 | MAP_WRITE_BIT | | 247 | DYNAMIC_STORAGE_BIT_EXT | 248 Table 6.3: Buffer object state after calling BufferData, 249 BufferStorageEXT, or NamedBufferStorageEXT. 250 251 A mutable data store may be allocated for a buffer object by calling 252 253 void BufferData(...) 254 255 <include the remainder of Section 6.2 as written, and then append>. 256 257 Calling BufferData is equivalent to calling BufferStorageEXT with 258 <target>, <size> and <data> as specified, and <flags> set to the logical 259 OR of DYNAMIC_STORAGE_BIT_EXT, MAP_READ_BIT and MAP_WRITE_BIT. The GL will 260 use the value of <usage> parameter to BufferData as a hint to further 261 determine the intended use of the buffer. However, BufferStorageEXT 262 allocates immutable storage whereas BufferData allocates mutable storage. 263 Thus, when a buffer's data store is allocated through a call to BufferData, 264 the buffer's BUFFER_IMMUTABLE_STORAGE_EXT flags is set to FALSE. 265 266 Add the following errors: 267 268 An INVALID_OPERATION error is generated by BufferData and BufferStorageEXT 269 if the BUFFER_IMMUTABLE_STORAGE_EXT flag of the buffer bound to <target> is 270 set to TRUE. 271 272 An INVALID_OPERATION error is generated by BufferSubData if the 273 BUFFER_IMMUTABLE_STORAGE_EXT flag of the buffer bound to <target> is TRUE 274 and the value of BUFFER_STORAGE_FLAGS_EXT for the buffer does not have 275 the DYNAMIC_STORAGE_BIT_EXT set. 276 277 The command: 278 279 void NamedBufferStorageEXT(uint buffer, 280 sizeiptr size, 281 const void * data, 282 bitfield flags); 283 284 behaves similarly to BufferStorageEXT, except that the buffer whose storage 285 is to be defined is specified by <buffer> rather than by the current 286 binding to <target>. 287 288 Add the following error: 289 290 An INVALID_OPERATION error is generated by NamedBufferStorageEXT if 291 the BUFFER_IMMUTABLE_STORAGE_EXT flag of <buffer> is set to TRUE. 292 293 294 Modify Section 6.3, (Mapping and Unmapping Buffer Data) 295 296 Add to the bulleted list describing flags that modify buffer mappings, 297 p.54. 298 299 * MAP_PERSISTENT_BIT_EXT indicates that it is not an error for the GL to 300 read data from or write data to the buffer while it is mapped (see 301 section 6.3.2). If this bit is set, the value of 302 BUFFER_STORAGE_FLAGS_EXT for the buffer being mapped must include 303 MAP_PERSISTENT_BIT_EXT. 304 305 * MAP_COHERENT_BIT_EXT indicates that the mapping should be performed 306 coherently. That is, such a mapping follows the rules set forth in 307 section 6.2, "Creating and Modifying Buffer Object Data Stores". 308 If this bit is set, the value of BUFFER_STORAGE_FLAGS_EXT for the 309 buffer being mapped must include MAP_COHERENT_BIT. 310 311 312 Add the following to the description of FlushMappedBufferRange, p.56: 313 314 If a buffer range is mapped with both the MAP_PERSISTENT_BIT_EXT and 315 MAP_FLUSH_EXPLICIT_BIT set, then FlushMappedBufferRange may be called to 316 ensure that data written by the client into the flushed region becomes 317 visible to the server. Data written to a coherent store will always 318 become visible to the server after an unspecified period of time. 319 320 321 Modify Section 6.3.2, "Effects of Mapping Buffers on Other GL Commands" 322 to read: 323 324 Any GL command which attempts to read from, write to, or change the state 325 of a buffer object may generate an INVALID_OPERATION error if all or part 326 of the buffer object is mapped, unless it was allocated by a call to 327 *BufferStorageEXT with the MAP_PERSISTENT_BIT_EXT included in <flags>. 328 However, only commands which explicitly describe this error are required 329 to do so. If an error is not generated, using such commands to perform 330 invalid reads, writes, or state changes will have undefined results and 331 may result in GL interruption or termination. 332 333 334 Modify Section 6.7, (Buffer Object State), p. 62: 335 336 Add the following required state to a buffer object: 337 338 ..., a boolean indicating whether or not buffer storage is 339 immutable, an unsigned integer storing the flags with which it was 340 allocated, ... 341 342Additions to Chapter 7 of the OpenGL ES 3.1 Specification, 343(Programs and Shaders) 344 345 Add to the list of flags accepted by the <barriers> parameter to 346 MemoryBarrier in Section 7.11.2, "Shader Memory Access Synchronization": 347 348 * CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT: Access by the client to 349 persistent mapped regions of buffer objects will reflect data written 350 by shaders prior to the barrier. Note that this may cause additional 351 synchronization operations. 352 353New State 354 355 Append to Table 20.4, "Buffer Object State", p.355: 356 357 +------------------------------+------+----------------------+---------------+---------------------------------+------------+ 358 | Get Value | Type | Get Command | Initial Value | Description | Sec. | 359 +------------------------------+------+----------------------+---------------+---------------------------------+------------+ 360 | BUFFER_IMMUTABLE_STORAGE_EXT | B | GetBufferParameteriv | FALSE | TRUE if buffer's data store is | 6 | 361 | | | | | immutable, FALSE otherwise | | 362 | BUFFER_STORAGE_FLAGS_EXT | Z+ | GetBufferParameteriv | 0 | The buffer object's storage | 6 | 363 | | | | | flags. | | 364 +------------------------------+------+----------------------+---------------+---------------------------------+------------+ 365 366New Implementation Dependent State 367 368 None. 369 370Errors 371 372 INVALID_OPERATION is generated by BufferStorageEXT if zero is bound to 373 <target>. 374 375 INVALID_OPERATION is generated by BufferStorageEXT, NamedBufferStorageEXT 376 and BufferData if the BUFFER_IMMUTABLE_STORAGE flag of the buffer bound to 377 <target> is TRUE. 378 379 INVALID_VALUE is generated by BufferStorageEXT and NamedBufferStorageEXT 380 if <size> is less than or equal to zero. 381 382 INVALID_VALUE is generated by BufferStorageEXT and NamedBufferStorageEXT 383 if <flags> has any bits set other than those defined above. 384 385 INVALID_VALUE is generated by BufferStorageEXT and NamedBufferStorageEXT if 386 <flags> contains MAP_PERSISTENT_BIT_EXT but does not contain 387 at least one of MAP_READ_BIT or 388 MAP_WRITE_BIT. 389 390 INVALID_VALUE is generated by BufferStorageEXT and NamedBufferStorageEXT if 391 <flags> contains MAP_COHERENT_BIT_EXT, but does not also 392 contain MAP_PERSISTENT_BIT_EXT. 393 394 INVALID_OPERATION is generated by MapBufferRange if any of MAP_READ_BIT, 395 MAP_WRITE_BIT, MAP_PERSISTENT_BIT_EXT, or MAP_COHERENT_BIT_EXT are included in 396 <access>, but the same bit is not included in the buffer's storage 397 flags. 398 399 OUT_OF_MEMORY is generated by BufferStorageEXT and NamedBufferStorageEXT if 400 the GL is not able to allocate a data store with the properties requested 401 in <flags>. 402 403 *REMOVE* all errors generated by any command should they detect access to 404 a mapped buffer and replace with language such as: 405 406 INVALID_OPERATION is generated by <command> if the buffer is currently 407 mapped by MapBufferRange unless it was mapped with the 408 MAP_PERSISTENT_BIT_EXT included in <access>. 409 410 411Dependencies on GL_EXT_direct_state_access 412 413 If GL_EXT_direct_state_access is not supported, remove all references to 414 NamedBufferStorageEXT. 415 416Conformance Tests 417 418 TBD 419 420Usage Examples 421 422 Example 1: Updating the content of a buffer which does not have the 423 DYNAMIC flag set: 424 425 // Allocate two buffers, one of which will be our 'staging buffer'. 426 GLuint bufs[2]; 427 glGenBuffers(2, &bufs[0]); 428 429 // Client can map this buffer for write. 430 // One could possibly make this mapping persistent. 431 glBindBuffer(GL_COPY_READ_BUFFER, bufs[0]); 432 glBufferStorageEXT(GL_COPY_READ_BUFFER, size, NULL, 433 GL_MAP_WRITE_BIT); 434 435 // Client cannot read or write this buffer, server can do both. 436 glBindBuffer(GL_COPY_WRITE_BUFFER, bufs[1]); 437 glBufferStorageEXT(GL_COPY_WRITE_BUFFER, size, NULL, 0); 438 439 // Now, map the staging buffer to put data into it. 440 void * data = glMapBufferRange(GL_COPY_READ_BUFFER, 0, size, 441 GL_MAP_WRITE_BIT | 442 GL_MAP_INVALIDATE_BUFFER_BIT); 443 memcpy(data, source_data, size); 444 glUnmapBuffer(GL_COPY_READ_BUFFER); 445 446 // Copy from the staging buffer to the server-side buffer. 447 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, size); 448 449 Example 2: Read from framebuffer into a buffer mapped into client's 450 address space: 451 452 // Create buffer, allocate storage, and create a persistent map. 453 GLuint pbo; 454 glGenBuffers(1, &pbo); 455 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); 456 glBufferStorageEXT(GL_PIXEL_PACK_BUFFER, size, NULL, 457 GL_MAP_READ_BIT | 458 GL_MAP_PERSISTENT_BIT_EXT); 459 460 void * data = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 461 GL_MAP_READ_BIT | 462 GL_MAP_PERSISTENT_BIT_EXT); 463 464 glReadPixels(0, 0, width, height, format, type, NULL); 465 glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT); 466 GLsync fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 467 468 // Do stuff to use time... 469 ReallyExpensiveFunction(); 470 471 glClientWaitSync(fence); 472 473 // Use the data written to the buffer 474 UseDataInMemory(data); 475 476 477Issues 478 479 Note: These issues apply specifically to the definition of the 480 EXT_buffer_storage specification, which is based on the OpenGL 481 extension ARB_buffer_storage as updated in OpenGL 4.5. For the full 482 set of historical issues, see ARB_buffer_storage which can be found 483 in the OpenGL Registry. 484 485 (1) What functionality was changed relative to ARB_buffer_storage? 486 487 - added EXT suffixes 488 - rebased against ES 3.1 489 - removed passing reference to ClearBufferSubData which doesn't exist 490 in OpenGL ES yet. 491 492 (2) What commands are affected by the relaxed errors for persistently 493 mapped buffers? 494 495 RESOLVED: In GL 4.5 the following commands have the relaxed 496 language BufferSubData, ClearBufferSubData, CopyBufferSubData, 497 GetBufferSubData and InvalidateBufferSubData. Of these commands 498 the only ones that apply to ES 3.1 are BufferSubData and 499 CopyBufferSubData. However, if additional extensions add any of 500 the other commands and EXT_buffer_storage is supported, they 501 would have the same behavior in ES. 502 503 (3) Should we keep interactions with the NamedBufferStorageEXT 504 DSA command and interactions with EXT_direct_state_access? 505 506 UNRESOLVED. TBD if there is interest in a DSA extension 507 based on ARB_direct_state_access. 508 509 510Revision History 511 512 Rev. Date Author Changes 513 ---- -------- -------- ----------------------------------------- 514 1 09/17/14 dkoch EXT version based on ARB_buffer_storage v.24 515 516 2 03/27/15 dkoch Update status, clarify dependencies and tokens 517 518 3 05/01/15 dkoch Change description of MAP_COHERENT_BIT for 519 buffer storage so that barriers with 520 CLIENT_MAPPED_BUFFER_BARRIER_BIT do not need 521 to make CPU writes visible to the GPU in 522 this case without an explicit flush (Bug 523 13578, sync w/ ARB_buffer_storage v.25). 524