• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    APPLE_flush_buffer_range
4
5Name Strings
6
7    GL_APPLE_flush_buffer_range
8
9Contact
10
11    Chris Niederauer, Apple (ccn 'at' apple.com)
12
13Status
14
15    Shipping on Mac OS X.
16
17Version
18
19    Last Modified Date: 19 March 2008
20    Author Revision: 1.1
21
22Number
23
24    321
25
26Dependencies
27
28    Buffer Objects as per ARB_vertex_buffer_object or OpenGL 1.5 are required.
29
30    If ARB_pixel_buffer_object is NOT supported and the OpenGL version is less
31    than 2.1, ignore references to PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER.
32
33    If APPLE_fence or similar fencing mechanism is NOT suppported, Finish can
34    be used in place of TestObject, FinishObject, TestFence and FinishFence.
35
36    Written based on the wording of the OpenGL 2.1 specification.
37
38Overview
39
40    APPLE_flush_buffer_range expands the buffer object API to allow greater
41    performance when a client application only needs to write to a sub-range
42    of a buffer object. To that end, this extension introduces two new buffer
43    object features: non-serialized buffer modification and explicit sub-range
44    flushing for mapped buffer objects.
45
46    OpenGL requires that commands occur in a FIFO manner meaning that any
47    changes to buffer objects either block until the data has been processed by
48    the OpenGL pipeline or else create extra copies to avoid such a block.  By
49    providing a method to asynchronously modify buffer object data, an
50    application is then able to manage the synchronization points themselves
51    and modify ranges of data contained by a buffer object even though OpenGL
52    might still be using other parts of it.
53
54    This extension also provides a method for explicitly flushing ranges of a
55    mapped buffer object so OpenGL does not have to assume that the entire
56    range may have been modified.
57
58    Affects ARB_vertex_buffer_object, ARB_pixel_buffer_object and OpenGL 1.5
59    Buffer Objects.
60
61Issues
62
63    Should the ability to update other Buffer Object state such as BUFFER_SIZE
64    and BUFFER_USAGE be added to BufferParameteriAPPLE?
65
66        RESOLVED:  No.  API already exists for setting this state and allowing
67        this new API to update this state would add more semantics that this
68        extension is not trying to address.  Also as decided when working on
69        the ARB_vertex_buffer_object extension: "It is desirable for the
70        implementation to know the usage when the buffer is initialized, so
71        including it in the initialization command makes sense."
72
73    Should a MapSubBuffer API be added to avoid having the application manually
74    flush memory which is not modified within a buffer object?
75
76        RESOLVED:  No.  An application may still want to modify multiple
77        sections of a buffer object simultaneously such as for procedural data
78        and providing a range flushing routine allows an implementation to
79        effectively achieve the same performance benefits.
80
81        Secondly, providing a MapSubBuffer routine might be confusing to
82        developers as one might think that MapSubBuffers could know which
83        sections need to block or provide temporary intermediary buffers and
84        in theory achieve the same benefits as adding a flag that states that
85        the application would like to asynchronously modify some buffer object
86        data; however, implementing a "smart" MapSubBuffer function would be
87        difficult to make efficient.
88
89    When flushing ranges manually, should new API be added or should
90    BufferSubData be overloaded?
91
92        RESOLVED:  New API should be added specifically for this task.  Trying
93        to override BufferSubData becomes cumbersome for many reasons.  In
94        order to use BufferSubData, the behavior would need to change when
95        called inside of a MapBuffer/UnmapBuffer pair to not throw an error and
96        the <data> parameter would then either not be used or cause a specific
97        behavior.  It is much simpler to provide new API specifically targeted
98        at the task of manually flushing memory regions.  This is also less
99        prone to errors in legacy applications that may incorrectly use
100        BufferSubData in situations that should cause invalid operation errors
101        prior to the introduction of this extension.
102
103New Procedures and Functions
104
105    void BufferParameteriAPPLE(enum target, enum pname, int param);
106
107    void FlushMappedBufferRangeAPPLE(enum target, intptr offset,
108                                     sizeiptr size);
109
110New Tokens
111
112    Accepted by the <pname> parameter of BufferParameteriAPPLE and
113    GetBufferParameteriv:
114
115        BUFFER_SERIALIZED_MODIFY_APPLE      0x8A12
116        BUFFER_FLUSHING_UNMAP_APPLE         0x8A13
117
118Additions to Chapter 2 of the OpenGL 2.0 Specification (Buffer Objects)
119
120    - (2.9, p. 33) Add new BufferParameter parameters:
121
122    Add to Table 2.6 (p. 34):
123
124        Name                             Type     Initial Value   Legal Values
125        ------------------------------   -------  -------------   ------------
126        BUFFER_SERIALIZED_MODIFY_APPLE   boolean      TRUE        TRUE, FALSE
127        BUFFER_FLUSHING_UNMAP_APPLE      boolean      TRUE        TRUE, FALSE
128
129    Change Table 2.7 (p. 36) caption to:
130
131        Table 2.7: Buffer object state set by BufferData.
132
133    Add to the end of Section 2.9 (p. 38):
134
135    The serialized modification and flushing unmap parameters are specified by
136    calling
137
138        void BufferParameteriAPPLE(enum target, enum pname, int param);
139
140    with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER,
141    PIXEL_UNPACK_BUFFER, or PIXEL_PACK_BUFFER.  <pname> is one of
142    BUFFER_SERIALIZED_MODIFY_APPLE or BUFFER_FLUSHING_UNMAP_APPLE and <param>
143    specifies the new value for parameter <pname>.
144        By setting the value of the parameter BUFFER_SERIALIZED_MODIFY_APPLE to
145    FALSE, the client must then manually synchronize any modifcations to the
146    buffer object data and usage by OpenGL.  In order to maintain coherency
147    when BUFFER_SERIALIZED_MODIFY_APPLE is disabled, synchronization must be
148    done after drawing with a buffer object prior to mapping its data for
149    modification using fences.  A fence, such as the type of fence defined in
150    the APPLE_fence extension, allows selective synchronization.  The client
151    can set a fence immediately after drawing with the data in question and
152    test or finish that fence prior to calling MapBuffer or BufferSubData.
153    This serialization relaxation also applies to all OpenGL commands which may
154    write to a buffer object such as ReadPixels and GetTexImage.
155        Setting the value of the parameter BUFFER_FLUSHING_UNMAP_APPLE to FALSE
156    allows the client to specify regions of a mapped buffer object that have
157    been modified by calling
158
159        void FlushMappedBufferRangeAPPLE(enum target, intptr offset,
160                                         sizeiptr size);
161
162    prior to unmapping.  <target> must be set to one of ARRAY_BUFFER,
163    ELEMENT_ARRAY_BUFFER, PIXEL_UNPACK_BUFFER, or PIXEL_PACK_BUFFER.  <offset>
164    and <size> indicate the range of data in the buffer object that has been
165    modified in terms of basic machine units.  An INVALID_VALUE error is
166    generated if <offset> or <size> is less than zero, or if <offset> + <size>
167    is greater than the value of BUFFER_SIZE. When BUFFER_FLUSHING_UNMAP_APPLE
168    is set to FALSE, FlushMappedBufferRangeAPPLE must be called on all modified
169    ranges of a mapped buffer object after the data within each specified range
170    has been modified and prior to unmapping it, allowing OpenGL to flush only
171    the portions of the buffer object that have been modified.  Any modified
172    ranges of a mapped buffer object that are not explicitly flushed prior to
173    unmapping when BUFFER_FLUSHING_UNMAP_APPLE is set to FALSE become
174    undefined.
175
176Errors
177
178    INVALID_ENUM is generated if the <target> parameter of
179    BufferParameteriAPPLE and FlushMappedBufferRangeAPPLE is not ARRAY_BUFFER,
180    ELEMENT_ARRAY_BUFFER, PIXEL_PACK_BUFFER or PIXEL_UNPACK_BUFFER.
181
182    INVALID_ENUM is generated if the <pname> parameter of BufferParameteriAPPLE
183    is not BUFFER_SERIALIZED_MODIFY_APPLE or BUFFER_NON_FLUSHING_UNMAP_APPLE.
184
185    INVALID_OPERATION is generated if BufferParameteriAPPLE or
186    FlushMappedBufferRangeAPPLE is executed while zero is bound to the <target>
187    parameter.
188
189    INVALID_OPERATION is generated if FlushMappedBufferRangeAPPLE is called
190    outside the execution of a MapBuffer and the corresponding execution of
191    UnmapBuffer.
192
193    INVALID_OPERATION may be generated if any of the commands defined in this
194    extension is executed between the execution of Begin and the corresponding
195    execution of End.
196
197    INVALID_VALUE is generated if the <offset> or <size> parameters of
198    FlushMappedBufferRangeAPPLE are negative.
199
200    INVALID_VALUE is generated if the <offset> and <size> parameters of
201    FlushMappedBufferRangeAPPLE define a region of memory that extends beyond
202    that allocated by BufferData.
203
204New State
205
206    Add to Table 6.9 (p. 274):
207                                                                Initial
208    Get Value                       Type  Get Command            Value   Description                     Sec  Attrib
209    ------------------------------  ----  --------------------  -------  ------------------------------  ---  ------
210    BUFFER_SERIALIZED_MODIFY_APPLE   B    GetBufferParameteriv   TRUE    Buffer serialized modify param  2.9    -
211    BUFFER_FLUSHING_UNMAP_APPLE      B    GetBufferParameteriv   TRUE    Buffer flushing unmap param     2.9    -
212
213New Implementation Dependent State
214
215    None
216
217Usage Examples
218
219    This extension can be used in place of using multiple buffer objects for
220    applications that may have algorithms that can not efficiently use the
221    existing buffer object API.
222
223    Convenient macro definition for specifying buffer offsets:
224
225        #define BUFFER_OFFSET(i) ((char *)NULL + (i))
226
227    Example of updating small amounts of data in a large VBO:
228
229        //  setup time
230        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
231        glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
232        glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
233
234        //  update/draw time
235        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
236        GLvoid *data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
237        for i to n {
238            if (need_to_change_region_i) {
239                //  modify region i
240                glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, BUFFER_OFFSET(region_i_offset), region_i_size);
241            }
242        }
243        glUnmapBuffer(GL_ARRAY_BUFFER);
244        //  draw from vertex data in buffer object
245
246    Example of updating sections of a VBO serializing with APPLE_fence:
247
248        //  setup time
249        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
250        glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
251        glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_SERIALIZING_MODIFY_APPLE, GL_FALSE);
252        glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
253
254        //  update/draw time
255        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
256        while(!glTestFenceAPPLE(current_regions_fence))
257        {
258            //  Do some more work if OpenGL is still using the
259            //  portions of the VBO that we want to modify.
260        }
261        GLvoid *data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
262        for i to n in regions {
263            if (need_to_change_region_i) {
264                //  modify region i
265                glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, BUFFER_OFFSET(region_i_offset), region_i_size);
266            }
267        }
268        glUnmapBuffer(GL_ARRAY_BUFFER);
269        //  draw from vertex data in region and set appropriate fence afterward
270
271Revision History
272
273    03/19/2008    1.1
274        - Introduced errors when FlushMappedBufferRangeAPPLE is given bad
275          offset or size parameters.
276        - Clarified that FlushMappedBufferRangeAPPLE must be called after the
277          data in the mapped buffer object range has been modified.
278
279    10/04/2006    1.0
280        - Initial public revision.
281