15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    APPLE_flush_buffer_range
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_APPLE_flush_buffer_range
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciContact
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Chris Niederauer, Apple (ccn 'at' apple.com)
125bd8deadSopenharmony_ci
135bd8deadSopenharmony_ciStatus
145bd8deadSopenharmony_ci
155bd8deadSopenharmony_ci    Shipping on Mac OS X.
165bd8deadSopenharmony_ci
175bd8deadSopenharmony_ciVersion
185bd8deadSopenharmony_ci
195bd8deadSopenharmony_ci    Last Modified Date: 19 March 2008
205bd8deadSopenharmony_ci    Author Revision: 1.1
215bd8deadSopenharmony_ci
225bd8deadSopenharmony_ciNumber
235bd8deadSopenharmony_ci
245bd8deadSopenharmony_ci    321
255bd8deadSopenharmony_ci
265bd8deadSopenharmony_ciDependencies
275bd8deadSopenharmony_ci
285bd8deadSopenharmony_ci    Buffer Objects as per ARB_vertex_buffer_object or OpenGL 1.5 are required.
295bd8deadSopenharmony_ci
305bd8deadSopenharmony_ci    If ARB_pixel_buffer_object is NOT supported and the OpenGL version is less
315bd8deadSopenharmony_ci    than 2.1, ignore references to PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER.
325bd8deadSopenharmony_ci
335bd8deadSopenharmony_ci    If APPLE_fence or similar fencing mechanism is NOT suppported, Finish can
345bd8deadSopenharmony_ci    be used in place of TestObject, FinishObject, TestFence and FinishFence.
355bd8deadSopenharmony_ci
365bd8deadSopenharmony_ci    Written based on the wording of the OpenGL 2.1 specification.
375bd8deadSopenharmony_ci
385bd8deadSopenharmony_ciOverview
395bd8deadSopenharmony_ci
405bd8deadSopenharmony_ci    APPLE_flush_buffer_range expands the buffer object API to allow greater
415bd8deadSopenharmony_ci    performance when a client application only needs to write to a sub-range
425bd8deadSopenharmony_ci    of a buffer object. To that end, this extension introduces two new buffer
435bd8deadSopenharmony_ci    object features: non-serialized buffer modification and explicit sub-range
445bd8deadSopenharmony_ci    flushing for mapped buffer objects.
455bd8deadSopenharmony_ci
465bd8deadSopenharmony_ci    OpenGL requires that commands occur in a FIFO manner meaning that any
475bd8deadSopenharmony_ci    changes to buffer objects either block until the data has been processed by
485bd8deadSopenharmony_ci    the OpenGL pipeline or else create extra copies to avoid such a block.  By
495bd8deadSopenharmony_ci    providing a method to asynchronously modify buffer object data, an
505bd8deadSopenharmony_ci    application is then able to manage the synchronization points themselves
515bd8deadSopenharmony_ci    and modify ranges of data contained by a buffer object even though OpenGL
525bd8deadSopenharmony_ci    might still be using other parts of it.
535bd8deadSopenharmony_ci
545bd8deadSopenharmony_ci    This extension also provides a method for explicitly flushing ranges of a
555bd8deadSopenharmony_ci    mapped buffer object so OpenGL does not have to assume that the entire
565bd8deadSopenharmony_ci    range may have been modified.
575bd8deadSopenharmony_ci
585bd8deadSopenharmony_ci    Affects ARB_vertex_buffer_object, ARB_pixel_buffer_object and OpenGL 1.5
595bd8deadSopenharmony_ci    Buffer Objects.
605bd8deadSopenharmony_ci
615bd8deadSopenharmony_ciIssues
625bd8deadSopenharmony_ci
635bd8deadSopenharmony_ci    Should the ability to update other Buffer Object state such as BUFFER_SIZE
645bd8deadSopenharmony_ci    and BUFFER_USAGE be added to BufferParameteriAPPLE?
655bd8deadSopenharmony_ci
665bd8deadSopenharmony_ci        RESOLVED:  No.  API already exists for setting this state and allowing
675bd8deadSopenharmony_ci        this new API to update this state would add more semantics that this
685bd8deadSopenharmony_ci        extension is not trying to address.  Also as decided when working on
695bd8deadSopenharmony_ci        the ARB_vertex_buffer_object extension: "It is desirable for the
705bd8deadSopenharmony_ci        implementation to know the usage when the buffer is initialized, so
715bd8deadSopenharmony_ci        including it in the initialization command makes sense."
725bd8deadSopenharmony_ci
735bd8deadSopenharmony_ci    Should a MapSubBuffer API be added to avoid having the application manually
745bd8deadSopenharmony_ci    flush memory which is not modified within a buffer object?
755bd8deadSopenharmony_ci
765bd8deadSopenharmony_ci        RESOLVED:  No.  An application may still want to modify multiple
775bd8deadSopenharmony_ci        sections of a buffer object simultaneously such as for procedural data
785bd8deadSopenharmony_ci        and providing a range flushing routine allows an implementation to
795bd8deadSopenharmony_ci        effectively achieve the same performance benefits.
805bd8deadSopenharmony_ci
815bd8deadSopenharmony_ci        Secondly, providing a MapSubBuffer routine might be confusing to
825bd8deadSopenharmony_ci        developers as one might think that MapSubBuffers could know which
835bd8deadSopenharmony_ci        sections need to block or provide temporary intermediary buffers and
845bd8deadSopenharmony_ci        in theory achieve the same benefits as adding a flag that states that
855bd8deadSopenharmony_ci        the application would like to asynchronously modify some buffer object
865bd8deadSopenharmony_ci        data; however, implementing a "smart" MapSubBuffer function would be
875bd8deadSopenharmony_ci        difficult to make efficient.
885bd8deadSopenharmony_ci
895bd8deadSopenharmony_ci    When flushing ranges manually, should new API be added or should
905bd8deadSopenharmony_ci    BufferSubData be overloaded?
915bd8deadSopenharmony_ci
925bd8deadSopenharmony_ci        RESOLVED:  New API should be added specifically for this task.  Trying
935bd8deadSopenharmony_ci        to override BufferSubData becomes cumbersome for many reasons.  In
945bd8deadSopenharmony_ci        order to use BufferSubData, the behavior would need to change when
955bd8deadSopenharmony_ci        called inside of a MapBuffer/UnmapBuffer pair to not throw an error and
965bd8deadSopenharmony_ci        the <data> parameter would then either not be used or cause a specific
975bd8deadSopenharmony_ci        behavior.  It is much simpler to provide new API specifically targeted
985bd8deadSopenharmony_ci        at the task of manually flushing memory regions.  This is also less
995bd8deadSopenharmony_ci        prone to errors in legacy applications that may incorrectly use
1005bd8deadSopenharmony_ci        BufferSubData in situations that should cause invalid operation errors
1015bd8deadSopenharmony_ci        prior to the introduction of this extension.
1025bd8deadSopenharmony_ci
1035bd8deadSopenharmony_ciNew Procedures and Functions
1045bd8deadSopenharmony_ci
1055bd8deadSopenharmony_ci    void BufferParameteriAPPLE(enum target, enum pname, int param);
1065bd8deadSopenharmony_ci
1075bd8deadSopenharmony_ci    void FlushMappedBufferRangeAPPLE(enum target, intptr offset,
1085bd8deadSopenharmony_ci                                     sizeiptr size);
1095bd8deadSopenharmony_ci
1105bd8deadSopenharmony_ciNew Tokens
1115bd8deadSopenharmony_ci
1125bd8deadSopenharmony_ci    Accepted by the <pname> parameter of BufferParameteriAPPLE and
1135bd8deadSopenharmony_ci    GetBufferParameteriv:
1145bd8deadSopenharmony_ci
1155bd8deadSopenharmony_ci        BUFFER_SERIALIZED_MODIFY_APPLE      0x8A12
1165bd8deadSopenharmony_ci        BUFFER_FLUSHING_UNMAP_APPLE         0x8A13
1175bd8deadSopenharmony_ci
1185bd8deadSopenharmony_ciAdditions to Chapter 2 of the OpenGL 2.0 Specification (Buffer Objects)
1195bd8deadSopenharmony_ci
1205bd8deadSopenharmony_ci    - (2.9, p. 33) Add new BufferParameter parameters:
1215bd8deadSopenharmony_ci
1225bd8deadSopenharmony_ci    Add to Table 2.6 (p. 34):
1235bd8deadSopenharmony_ci
1245bd8deadSopenharmony_ci        Name                             Type     Initial Value   Legal Values
1255bd8deadSopenharmony_ci        ------------------------------   -------  -------------   ------------
1265bd8deadSopenharmony_ci        BUFFER_SERIALIZED_MODIFY_APPLE   boolean      TRUE        TRUE, FALSE
1275bd8deadSopenharmony_ci        BUFFER_FLUSHING_UNMAP_APPLE      boolean      TRUE        TRUE, FALSE
1285bd8deadSopenharmony_ci
1295bd8deadSopenharmony_ci    Change Table 2.7 (p. 36) caption to:
1305bd8deadSopenharmony_ci
1315bd8deadSopenharmony_ci        Table 2.7: Buffer object state set by BufferData.
1325bd8deadSopenharmony_ci
1335bd8deadSopenharmony_ci    Add to the end of Section 2.9 (p. 38):
1345bd8deadSopenharmony_ci
1355bd8deadSopenharmony_ci    The serialized modification and flushing unmap parameters are specified by
1365bd8deadSopenharmony_ci    calling
1375bd8deadSopenharmony_ci
1385bd8deadSopenharmony_ci        void BufferParameteriAPPLE(enum target, enum pname, int param);
1395bd8deadSopenharmony_ci
1405bd8deadSopenharmony_ci    with <target> set to one of ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER,
1415bd8deadSopenharmony_ci    PIXEL_UNPACK_BUFFER, or PIXEL_PACK_BUFFER.  <pname> is one of
1425bd8deadSopenharmony_ci    BUFFER_SERIALIZED_MODIFY_APPLE or BUFFER_FLUSHING_UNMAP_APPLE and <param>
1435bd8deadSopenharmony_ci    specifies the new value for parameter <pname>.
1445bd8deadSopenharmony_ci        By setting the value of the parameter BUFFER_SERIALIZED_MODIFY_APPLE to
1455bd8deadSopenharmony_ci    FALSE, the client must then manually synchronize any modifcations to the
1465bd8deadSopenharmony_ci    buffer object data and usage by OpenGL.  In order to maintain coherency
1475bd8deadSopenharmony_ci    when BUFFER_SERIALIZED_MODIFY_APPLE is disabled, synchronization must be
1485bd8deadSopenharmony_ci    done after drawing with a buffer object prior to mapping its data for
1495bd8deadSopenharmony_ci    modification using fences.  A fence, such as the type of fence defined in
1505bd8deadSopenharmony_ci    the APPLE_fence extension, allows selective synchronization.  The client
1515bd8deadSopenharmony_ci    can set a fence immediately after drawing with the data in question and
1525bd8deadSopenharmony_ci    test or finish that fence prior to calling MapBuffer or BufferSubData.
1535bd8deadSopenharmony_ci    This serialization relaxation also applies to all OpenGL commands which may
1545bd8deadSopenharmony_ci    write to a buffer object such as ReadPixels and GetTexImage.
1555bd8deadSopenharmony_ci        Setting the value of the parameter BUFFER_FLUSHING_UNMAP_APPLE to FALSE
1565bd8deadSopenharmony_ci    allows the client to specify regions of a mapped buffer object that have
1575bd8deadSopenharmony_ci    been modified by calling
1585bd8deadSopenharmony_ci
1595bd8deadSopenharmony_ci        void FlushMappedBufferRangeAPPLE(enum target, intptr offset,
1605bd8deadSopenharmony_ci                                         sizeiptr size);
1615bd8deadSopenharmony_ci
1625bd8deadSopenharmony_ci    prior to unmapping.  <target> must be set to one of ARRAY_BUFFER,
1635bd8deadSopenharmony_ci    ELEMENT_ARRAY_BUFFER, PIXEL_UNPACK_BUFFER, or PIXEL_PACK_BUFFER.  <offset>
1645bd8deadSopenharmony_ci    and <size> indicate the range of data in the buffer object that has been
1655bd8deadSopenharmony_ci    modified in terms of basic machine units.  An INVALID_VALUE error is
1665bd8deadSopenharmony_ci    generated if <offset> or <size> is less than zero, or if <offset> + <size>
1675bd8deadSopenharmony_ci    is greater than the value of BUFFER_SIZE. When BUFFER_FLUSHING_UNMAP_APPLE
1685bd8deadSopenharmony_ci    is set to FALSE, FlushMappedBufferRangeAPPLE must be called on all modified
1695bd8deadSopenharmony_ci    ranges of a mapped buffer object after the data within each specified range
1705bd8deadSopenharmony_ci    has been modified and prior to unmapping it, allowing OpenGL to flush only
1715bd8deadSopenharmony_ci    the portions of the buffer object that have been modified.  Any modified
1725bd8deadSopenharmony_ci    ranges of a mapped buffer object that are not explicitly flushed prior to
1735bd8deadSopenharmony_ci    unmapping when BUFFER_FLUSHING_UNMAP_APPLE is set to FALSE become
1745bd8deadSopenharmony_ci    undefined.
1755bd8deadSopenharmony_ci
1765bd8deadSopenharmony_ciErrors
1775bd8deadSopenharmony_ci
1785bd8deadSopenharmony_ci    INVALID_ENUM is generated if the <target> parameter of
1795bd8deadSopenharmony_ci    BufferParameteriAPPLE and FlushMappedBufferRangeAPPLE is not ARRAY_BUFFER,
1805bd8deadSopenharmony_ci    ELEMENT_ARRAY_BUFFER, PIXEL_PACK_BUFFER or PIXEL_UNPACK_BUFFER.
1815bd8deadSopenharmony_ci
1825bd8deadSopenharmony_ci    INVALID_ENUM is generated if the <pname> parameter of BufferParameteriAPPLE
1835bd8deadSopenharmony_ci    is not BUFFER_SERIALIZED_MODIFY_APPLE or BUFFER_NON_FLUSHING_UNMAP_APPLE.
1845bd8deadSopenharmony_ci
1855bd8deadSopenharmony_ci    INVALID_OPERATION is generated if BufferParameteriAPPLE or
1865bd8deadSopenharmony_ci    FlushMappedBufferRangeAPPLE is executed while zero is bound to the <target>
1875bd8deadSopenharmony_ci    parameter.
1885bd8deadSopenharmony_ci
1895bd8deadSopenharmony_ci    INVALID_OPERATION is generated if FlushMappedBufferRangeAPPLE is called
1905bd8deadSopenharmony_ci    outside the execution of a MapBuffer and the corresponding execution of
1915bd8deadSopenharmony_ci    UnmapBuffer.
1925bd8deadSopenharmony_ci
1935bd8deadSopenharmony_ci    INVALID_OPERATION may be generated if any of the commands defined in this
1945bd8deadSopenharmony_ci    extension is executed between the execution of Begin and the corresponding
1955bd8deadSopenharmony_ci    execution of End.
1965bd8deadSopenharmony_ci
1975bd8deadSopenharmony_ci    INVALID_VALUE is generated if the <offset> or <size> parameters of
1985bd8deadSopenharmony_ci    FlushMappedBufferRangeAPPLE are negative.
1995bd8deadSopenharmony_ci
2005bd8deadSopenharmony_ci    INVALID_VALUE is generated if the <offset> and <size> parameters of
2015bd8deadSopenharmony_ci    FlushMappedBufferRangeAPPLE define a region of memory that extends beyond
2025bd8deadSopenharmony_ci    that allocated by BufferData.
2035bd8deadSopenharmony_ci
2045bd8deadSopenharmony_ciNew State
2055bd8deadSopenharmony_ci
2065bd8deadSopenharmony_ci    Add to Table 6.9 (p. 274):
2075bd8deadSopenharmony_ci                                                                Initial
2085bd8deadSopenharmony_ci    Get Value                       Type  Get Command            Value   Description                     Sec  Attrib
2095bd8deadSopenharmony_ci    ------------------------------  ----  --------------------  -------  ------------------------------  ---  ------
2105bd8deadSopenharmony_ci    BUFFER_SERIALIZED_MODIFY_APPLE   B    GetBufferParameteriv   TRUE    Buffer serialized modify param  2.9    -
2115bd8deadSopenharmony_ci    BUFFER_FLUSHING_UNMAP_APPLE      B    GetBufferParameteriv   TRUE    Buffer flushing unmap param     2.9    -
2125bd8deadSopenharmony_ci
2135bd8deadSopenharmony_ciNew Implementation Dependent State
2145bd8deadSopenharmony_ci
2155bd8deadSopenharmony_ci    None
2165bd8deadSopenharmony_ci
2175bd8deadSopenharmony_ciUsage Examples
2185bd8deadSopenharmony_ci
2195bd8deadSopenharmony_ci    This extension can be used in place of using multiple buffer objects for
2205bd8deadSopenharmony_ci    applications that may have algorithms that can not efficiently use the
2215bd8deadSopenharmony_ci    existing buffer object API.
2225bd8deadSopenharmony_ci
2235bd8deadSopenharmony_ci    Convenient macro definition for specifying buffer offsets:
2245bd8deadSopenharmony_ci
2255bd8deadSopenharmony_ci        #define BUFFER_OFFSET(i) ((char *)NULL + (i))
2265bd8deadSopenharmony_ci
2275bd8deadSopenharmony_ci    Example of updating small amounts of data in a large VBO:
2285bd8deadSopenharmony_ci
2295bd8deadSopenharmony_ci        //  setup time
2305bd8deadSopenharmony_ci        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
2315bd8deadSopenharmony_ci        glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
2325bd8deadSopenharmony_ci        glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
2335bd8deadSopenharmony_ci
2345bd8deadSopenharmony_ci        //  update/draw time
2355bd8deadSopenharmony_ci        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
2365bd8deadSopenharmony_ci        GLvoid *data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
2375bd8deadSopenharmony_ci        for i to n {
2385bd8deadSopenharmony_ci            if (need_to_change_region_i) {
2395bd8deadSopenharmony_ci                //  modify region i
2405bd8deadSopenharmony_ci                glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, BUFFER_OFFSET(region_i_offset), region_i_size);
2415bd8deadSopenharmony_ci            }
2425bd8deadSopenharmony_ci        }
2435bd8deadSopenharmony_ci        glUnmapBuffer(GL_ARRAY_BUFFER);
2445bd8deadSopenharmony_ci        //  draw from vertex data in buffer object
2455bd8deadSopenharmony_ci
2465bd8deadSopenharmony_ci    Example of updating sections of a VBO serializing with APPLE_fence:
2475bd8deadSopenharmony_ci
2485bd8deadSopenharmony_ci        //  setup time
2495bd8deadSopenharmony_ci        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
2505bd8deadSopenharmony_ci        glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
2515bd8deadSopenharmony_ci        glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_SERIALIZING_MODIFY_APPLE, GL_FALSE);
2525bd8deadSopenharmony_ci        glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
2535bd8deadSopenharmony_ci
2545bd8deadSopenharmony_ci        //  update/draw time
2555bd8deadSopenharmony_ci        glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
2565bd8deadSopenharmony_ci        while(!glTestFenceAPPLE(current_regions_fence))
2575bd8deadSopenharmony_ci        {
2585bd8deadSopenharmony_ci            //  Do some more work if OpenGL is still using the
2595bd8deadSopenharmony_ci            //  portions of the VBO that we want to modify.
2605bd8deadSopenharmony_ci        }
2615bd8deadSopenharmony_ci        GLvoid *data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
2625bd8deadSopenharmony_ci        for i to n in regions {
2635bd8deadSopenharmony_ci            if (need_to_change_region_i) {
2645bd8deadSopenharmony_ci                //  modify region i
2655bd8deadSopenharmony_ci                glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, BUFFER_OFFSET(region_i_offset), region_i_size);
2665bd8deadSopenharmony_ci            }
2675bd8deadSopenharmony_ci        }
2685bd8deadSopenharmony_ci        glUnmapBuffer(GL_ARRAY_BUFFER);
2695bd8deadSopenharmony_ci        //  draw from vertex data in region and set appropriate fence afterward
2705bd8deadSopenharmony_ci
2715bd8deadSopenharmony_ciRevision History
2725bd8deadSopenharmony_ci
2735bd8deadSopenharmony_ci    03/19/2008    1.1
2745bd8deadSopenharmony_ci        - Introduced errors when FlushMappedBufferRangeAPPLE is given bad
2755bd8deadSopenharmony_ci          offset or size parameters.
2765bd8deadSopenharmony_ci        - Clarified that FlushMappedBufferRangeAPPLE must be called after the
2775bd8deadSopenharmony_ci          data in the mapped buffer object range has been modified.
2785bd8deadSopenharmony_ci
2795bd8deadSopenharmony_ci    10/04/2006    1.0
2805bd8deadSopenharmony_ci        - Initial public revision.
281