• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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