15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    EXT_map_buffer_range
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_EXT_map_buffer_range
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciContributors
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Contributors to ARB_map_buffer_range desktop OpenGL extension from which 
125bd8deadSopenharmony_ci    this extension borrows heavily
135bd8deadSopenharmony_ci
145bd8deadSopenharmony_ciContact
155bd8deadSopenharmony_ci
165bd8deadSopenharmony_ci    Benj Lipchak (lipchak 'at' apple 'dot' com)
175bd8deadSopenharmony_ci
185bd8deadSopenharmony_ciStatus
195bd8deadSopenharmony_ci
205bd8deadSopenharmony_ci    Complete
215bd8deadSopenharmony_ci
225bd8deadSopenharmony_ciVersion
235bd8deadSopenharmony_ci
245bd8deadSopenharmony_ci    Last Modified Date: August 21, 2014
255bd8deadSopenharmony_ci    Author Revision: 4
265bd8deadSopenharmony_ci
275bd8deadSopenharmony_ciNumber
285bd8deadSopenharmony_ci
295bd8deadSopenharmony_ci    OpenGL ES Extension #121
305bd8deadSopenharmony_ci
315bd8deadSopenharmony_ciDependencies
325bd8deadSopenharmony_ci
335bd8deadSopenharmony_ci    OpenGL ES 1.1 or OpenGL ES 2.0 is required.
345bd8deadSopenharmony_ci    
355bd8deadSopenharmony_ci    OES_mapbuffer is required.
365bd8deadSopenharmony_ci
375bd8deadSopenharmony_ci    This specification is written against the OpenGL ES 2.0.25 specification.
385bd8deadSopenharmony_ci
395bd8deadSopenharmony_ciOverview
405bd8deadSopenharmony_ci
415bd8deadSopenharmony_ci    EXT_map_buffer_range expands the buffer object API to allow greater
425bd8deadSopenharmony_ci    performance when a client application only needs to write to a sub-range
435bd8deadSopenharmony_ci    of a buffer object. To that end, this extension introduces two new buffer
445bd8deadSopenharmony_ci    object features: non-serialized buffer modification and explicit sub-range
455bd8deadSopenharmony_ci    flushing for mapped buffer objects.
465bd8deadSopenharmony_ci
475bd8deadSopenharmony_ci    OpenGL requires that commands occur in a FIFO manner meaning that any
485bd8deadSopenharmony_ci    changes to buffer objects either block until the data has been processed by
495bd8deadSopenharmony_ci    the OpenGL pipeline or else create extra copies to avoid such a block.  By
505bd8deadSopenharmony_ci    providing a method to asynchronously modify buffer object data, an
515bd8deadSopenharmony_ci    application is then able to manage the synchronization points themselves
525bd8deadSopenharmony_ci    and modify ranges of data contained by a buffer object even though OpenGL
535bd8deadSopenharmony_ci    might still be using other parts of it.
545bd8deadSopenharmony_ci
555bd8deadSopenharmony_ci    This extension also provides a method for explicitly flushing ranges of a
565bd8deadSopenharmony_ci    mapped buffer object so OpenGL does not have to assume that the entire
575bd8deadSopenharmony_ci    range may have been modified.  Further, it allows the application to more
585bd8deadSopenharmony_ci    precisely specify its intent with respect to reading, writing, and whether
595bd8deadSopenharmony_ci    the previous contents of a mapped range of interest need be preserved
605bd8deadSopenharmony_ci    prior to modification.
615bd8deadSopenharmony_ci
625bd8deadSopenharmony_ciNew Procedures and Functions
635bd8deadSopenharmony_ci
645bd8deadSopenharmony_ci    void *MapBufferRangeEXT(enum target, intptr offset, sizeiptr length,
655bd8deadSopenharmony_ci        bitfield access);
665bd8deadSopenharmony_ci
675bd8deadSopenharmony_ci    void FlushMappedBufferRangeEXT(enum target, intptr offset, 
685bd8deadSopenharmony_ci        sizeiptr length);
695bd8deadSopenharmony_ci
705bd8deadSopenharmony_ci
715bd8deadSopenharmony_ciNew Tokens
725bd8deadSopenharmony_ci
735bd8deadSopenharmony_ci    Accepted by the <access> parameter of MapBufferRangeEXT:
745bd8deadSopenharmony_ci
755bd8deadSopenharmony_ci    MAP_READ_BIT_EXT                  0x0001
765bd8deadSopenharmony_ci    MAP_WRITE_BIT_EXT                 0x0002
775bd8deadSopenharmony_ci    MAP_INVALIDATE_RANGE_BIT_EXT      0x0004
785bd8deadSopenharmony_ci    MAP_INVALIDATE_BUFFER_BIT_EXT     0x0008
795bd8deadSopenharmony_ci    MAP_FLUSH_EXPLICIT_BIT_EXT        0x0010
805bd8deadSopenharmony_ci    MAP_UNSYNCHRONIZED_BIT_EXT        0x0020
815bd8deadSopenharmony_ci
825bd8deadSopenharmony_ci
835bd8deadSopenharmony_ciAdditions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation)
845bd8deadSopenharmony_ci
855bd8deadSopenharmony_ci    Add to the end of Section 2.9 "Buffer Objects" (p. 24):
865bd8deadSopenharmony_ci
875bd8deadSopenharmony_ci    All or part of the data store of a buffer object may be mapped into the
885bd8deadSopenharmony_ci    client's address space by calling
895bd8deadSopenharmony_ci
905bd8deadSopenharmony_ci    void *MapBufferRangeEXT(enum target, intptr offset, sizeiptr length,
915bd8deadSopenharmony_ci        bitfield access);
925bd8deadSopenharmony_ci
935bd8deadSopenharmony_ci    with <target> set to ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER. 
945bd8deadSopenharmony_ci    <offset> and <length> indicate the range of data in the
955bd8deadSopenharmony_ci    buffer object that is to be mapped, in terms of basic machine units.
965bd8deadSopenharmony_ci    <access> is a bitfield containing flags which describe the requested
975bd8deadSopenharmony_ci    mapping. These flags are described below.
985bd8deadSopenharmony_ci
995bd8deadSopenharmony_ci    If no error occurs, a pointer to the beginning of the mapped range is
1005bd8deadSopenharmony_ci    returned once all pending operations on that buffer have completed, and 
1015bd8deadSopenharmony_ci    may be used to modify and/or query the corresponding range of the buffer, 
1025bd8deadSopenharmony_ci    according to the following flag bits set in <access>:
1035bd8deadSopenharmony_ci
1045bd8deadSopenharmony_ci    * MAP_READ_BIT_EXT indicates that the returned pointer may be used to 
1055bd8deadSopenharmony_ci    read buffer object data. No GL error is generated if the pointer is used 
1065bd8deadSopenharmony_ci    to query a mapping which excludes this flag, but the result is undefined 
1075bd8deadSopenharmony_ci    and system errors (possibly including program termination) may occur.
1085bd8deadSopenharmony_ci
1095bd8deadSopenharmony_ci    * MAP_WRITE_BIT_EXT indicates that the returned pointer may be used to 
1105bd8deadSopenharmony_ci    modify buffer object data. No GL error is generated if the pointer is used
1115bd8deadSopenharmony_ci    to modify a mapping which excludes this flag, but the result is undefined 
1125bd8deadSopenharmony_ci    and system errors (possibly including program termination) may occur.
1135bd8deadSopenharmony_ci
1145bd8deadSopenharmony_ci    Pointer values returned by MapBufferRangeEXT may not be passed as 
1155bd8deadSopenharmony_ci    parameter values to GL commands. For example, they may not be used to 
1165bd8deadSopenharmony_ci    specify array pointers, or to specify or query pixel or texture image 
1175bd8deadSopenharmony_ci    data; such actions produce undefined results, although implementations 
1185bd8deadSopenharmony_ci    may not check for such behavior for performance reasons.
1195bd8deadSopenharmony_ci    
1205bd8deadSopenharmony_ci    Mappings to the data stores of buffer objects may have nonstandard 
1215bd8deadSopenharmony_ci    performance characteristics. For example, such mappings may be marked as 
1225bd8deadSopenharmony_ci    uncacheable regions of memory, and in such cases reading from them may be 
1235bd8deadSopenharmony_ci    very slow. To ensure optimal performance, the client should use the 
1245bd8deadSopenharmony_ci    mapping in a fashion consistent with the values of BUFFER_USAGE and 
1255bd8deadSopenharmony_ci    <access>. Using a mapping in a fashion inconsistent with these values is 
1265bd8deadSopenharmony_ci    liable to be multiple orders of magnitude slower than using normal memory.
1275bd8deadSopenharmony_ci
1285bd8deadSopenharmony_ci    The following optional flag bits in <access> may be used to modify the 
1295bd8deadSopenharmony_ci    mapping:
1305bd8deadSopenharmony_ci
1315bd8deadSopenharmony_ci    * MAP_INVALIDATE_RANGE_BIT_EXT indicates that the previous contents of 
1325bd8deadSopenharmony_ci    the specified range may be discarded. Data within this range are undefined
1335bd8deadSopenharmony_ci    with the exception of subsequently written data. No GL error is generated 
1345bd8deadSopenharmony_ci    if subsequent GL operations access unwritten data, but the result is 
1355bd8deadSopenharmony_ci    undefined and system errors (possibly including program termination) may 
1365bd8deadSopenharmony_ci    occur. This flag may not be used in combination with MAP_READ_BIT_EXT.
1375bd8deadSopenharmony_ci
1385bd8deadSopenharmony_ci    * MAP_INVALIDATE_BUFFER_BIT_EXT indicates that the previous contents of 
1395bd8deadSopenharmony_ci    the entire buffer may be discarded. Data within the entire buffer are 
1405bd8deadSopenharmony_ci    undefined with the exception of subsequently written data. No GL error is 
1415bd8deadSopenharmony_ci    generated if subsequent GL operations access unwritten data, but the 
1425bd8deadSopenharmony_ci    result is undefined and system errors (possibly including program 
1435bd8deadSopenharmony_ci    termination) may occur. This flag may not be used in combination with 
1445bd8deadSopenharmony_ci    MAP_READ_BIT_EXT.
1455bd8deadSopenharmony_ci
1465bd8deadSopenharmony_ci    * MAP_FLUSH_EXPLICIT_BIT_EXT indicates that one or more discrete 
1475bd8deadSopenharmony_ci    subranges of the mapping may be modified. When this flag is set, 
1485bd8deadSopenharmony_ci    modifications to each subrange must be explicitly flushed by calling 
1495bd8deadSopenharmony_ci    FlushMappedBufferRangeEXT. No GL error is set if a subrange of the 
1505bd8deadSopenharmony_ci    mapping is modified and not flushed, but data within the corresponding 
1515bd8deadSopenharmony_ci    subrange of the buffer is undefined. This flag may only be used in 
1525bd8deadSopenharmony_ci    conjunction with MAP_WRITE_BIT_EXT. When this option is selected, 
1535bd8deadSopenharmony_ci    flushing is strictly limited to regions that are explicitly indicated 
1545bd8deadSopenharmony_ci    with calls to FlushMappedBufferRangeEXT prior to unmap; if this
1555bd8deadSopenharmony_ci    option is not selected UnmapBufferOES will automatically flush the entire
1565bd8deadSopenharmony_ci    mapped range when called.
1575bd8deadSopenharmony_ci
1585bd8deadSopenharmony_ci    * MAP_UNSYNCHRONIZED_BIT_EXT indicates that the GL should not attempt 
1595bd8deadSopenharmony_ci    to synchronize pending operations on the buffer prior to returning from
1605bd8deadSopenharmony_ci    MapBufferRangeEXT. No GL error is generated if pending operations which 
1615bd8deadSopenharmony_ci    source or modify the buffer overlap the mapped region, but the result of 
1625bd8deadSopenharmony_ci    such previous and any subsequent operations is undefined.
1635bd8deadSopenharmony_ci
1645bd8deadSopenharmony_ci    A successful MapBufferRangeEXT sets buffer object state values as shown 
1655bd8deadSopenharmony_ci    in table 2.mbr.
1665bd8deadSopenharmony_ci    
1675bd8deadSopenharmony_ci    Name                 Value
1685bd8deadSopenharmony_ci    -------------------  -----
1695bd8deadSopenharmony_ci    BUFFER_ACCESS_FLAGS  <access>
1705bd8deadSopenharmony_ci    BUFFER_MAPPED        TRUE
1715bd8deadSopenharmony_ci    BUFFER_MAP_POINTER   pointer to the data store
1725bd8deadSopenharmony_ci    BUFFER_MAP_OFFSET    <offset>
1735bd8deadSopenharmony_ci    BUFFER_MAP_LENGTH    <length>
1745bd8deadSopenharmony_ci    
1755bd8deadSopenharmony_ci    Table 2.mbr: Buffer object state set by MapBufferRangeEXT.
1765bd8deadSopenharmony_ci
1775bd8deadSopenharmony_ci    If an error occurs, MapBufferRangeEXT returns a NULL pointer.
1785bd8deadSopenharmony_ci    
1795bd8deadSopenharmony_ci    An INVALID_VALUE error is generated if <offset> or <length> is negative, 
1805bd8deadSopenharmony_ci    if <offset> + <length> is greater than the value of BUFFER_SIZE, or if 
1815bd8deadSopenharmony_ci    <access> has any bits set other than those defined above.
1825bd8deadSopenharmony_ci    
1835bd8deadSopenharmony_ci    An INVALID_OPERATION error is generated for any of the following 
1845bd8deadSopenharmony_ci    conditions:
1855bd8deadSopenharmony_ci    
1865bd8deadSopenharmony_ci    * <length> is zero.
1875bd8deadSopenharmony_ci    * The buffer is already in a mapped state.
1885bd8deadSopenharmony_ci    * Neither MAP_READ_BIT_EXT nor MAP_WRITE_BIT_EXT is set.
1895bd8deadSopenharmony_ci    * MAP_READ_BIT_EXT is set and any of MAP_INVALIDATE_RANGE_BIT_EXT, 
1905bd8deadSopenharmony_ci      MAP_INVALIDATE_BUFFER_BIT_EXT, or MAP_UNSYNCHRONIZED_BIT_EXT is set.
1915bd8deadSopenharmony_ci    * MAP_FLUSH_EXPLICIT_BIT_EXT is set and MAP_WRITE_BIT_EXT is not set.
1925bd8deadSopenharmony_ci    
1935bd8deadSopenharmony_ci    An OUT_OF_MEMORY error is generated if MapBufferRangeEXT fails because
1945bd8deadSopenharmony_ci    memory for the mapping could not be obtained.
1955bd8deadSopenharmony_ci
1965bd8deadSopenharmony_ci    No error is generated if memory outside the mapped range is modified or
1975bd8deadSopenharmony_ci    queried, but the result is undefined and system errors (possibly including
1985bd8deadSopenharmony_ci    program termination) may occur.
1995bd8deadSopenharmony_ci
2005bd8deadSopenharmony_ci    If a buffer is mapped with the MAP_FLUSH_EXPLICIT_BIT_EXT flag, 
2015bd8deadSopenharmony_ci    modifications to the mapped range may be indicated by calling
2025bd8deadSopenharmony_ci
2035bd8deadSopenharmony_ci    void FlushMappedBufferRangeEXT(enum target, intptr offset, 
2045bd8deadSopenharmony_ci        sizeiptr length);
2055bd8deadSopenharmony_ci
2065bd8deadSopenharmony_ci    with <target> set to ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER. <offset> and 
2075bd8deadSopenharmony_ci    <length> indicate a modified subrange of the mapping, in basic machine 
2085bd8deadSopenharmony_ci    units. The specified subrange to flush is relative to the start of the 
2095bd8deadSopenharmony_ci    currently mapped range of buffer. FlushMappedBufferRangeEXT may be 
2105bd8deadSopenharmony_ci    called multiple times to indicate distinct subranges of the mapping which 
2115bd8deadSopenharmony_ci    require flushing.
2125bd8deadSopenharmony_ci
2135bd8deadSopenharmony_ci    An INVALID_VALUE error is generated if <offset> or <length> is negative, 
2145bd8deadSopenharmony_ci    or if <offset> + <length> exceeds the size of the mapping.
2155bd8deadSopenharmony_ci
2165bd8deadSopenharmony_ci    An INVALID_OPERATION error is generated if zero is bound to <target>.
2175bd8deadSopenharmony_ci
2185bd8deadSopenharmony_ci    An INVALID_OPERATION error is generated if the buffer bound to <target> 
2195bd8deadSopenharmony_ci    is not mapped, or is mapped without the MAP_FLUSH_EXPLICIT_BIT_EXT flag.
2205bd8deadSopenharmony_ci
2215bd8deadSopenharmony_ciNew Implementation Dependent State
2225bd8deadSopenharmony_ci
2235bd8deadSopenharmony_ci    None
2245bd8deadSopenharmony_ci
2255bd8deadSopenharmony_ciUsage Examples
2265bd8deadSopenharmony_ci
2275bd8deadSopenharmony_ci    /* bind and initialize a buffer object */
2285bd8deadSopenharmony_ci    int size = 65536;
2295bd8deadSopenharmony_ci    glBindBuffer(GL_ARRAY_BUFFER, 1);
2305bd8deadSopenharmony_ci    glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
2315bd8deadSopenharmony_ci
2325bd8deadSopenharmony_ci/* the following are not meant to be executed as a group, since there are no
2335bd8deadSopenharmony_ci * unmap calls shown here - they are meant to show different combinations of
2345bd8deadSopenharmony_ci * map options in conjunction with MapBufferRangeEXT and 
2355bd8deadSopenharmony_ci * FlushMappedBufferRangeEXT.
2365bd8deadSopenharmony_ci */
2375bd8deadSopenharmony_ci
2385bd8deadSopenharmony_ci    /* Map the entire buffer with read and write
2395bd8deadSopenharmony_ci     * (identical semantics to MapBufferOES).
2405bd8deadSopenharmony_ci     */
2415bd8deadSopenharmony_ci    void *ptr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, size, 
2425bd8deadSopenharmony_ci        MAP_READ_BIT_EXT | MAP_WRITE_BIT_EXT);
2435bd8deadSopenharmony_ci
2445bd8deadSopenharmony_ci    /* Map the entire buffer as write only.
2455bd8deadSopenharmony_ci     */
2465bd8deadSopenharmony_ci    void *ptr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, size, 
2475bd8deadSopenharmony_ci        MAP_WRITE_BIT_EXT);
2485bd8deadSopenharmony_ci
2495bd8deadSopenharmony_ci
2505bd8deadSopenharmony_ci    /* Map the last 1K bytes of the buffer as write only.
2515bd8deadSopenharmony_ci     */
2525bd8deadSopenharmony_ci    void *ptr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, size-1024, 1024, 
2535bd8deadSopenharmony_ci        MAP_WRITE_BIT_EXT);
2545bd8deadSopenharmony_ci
2555bd8deadSopenharmony_ci
2565bd8deadSopenharmony_ci    /* Map the last 1K bytes of the buffer as write only, and invalidate the 
2575bd8deadSopenharmony_ci     * range. Locations within that range can assume undefined values.
2585bd8deadSopenharmony_ci     * Locations written while mapped take on new values as expected.
2595bd8deadSopenharmony_ci     * No changes occur outside the range mapped.
2605bd8deadSopenharmony_ci     */
2615bd8deadSopenharmony_ci    void *ptr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, size-1024, 1024, 
2625bd8deadSopenharmony_ci        MAP_WRITE_BIT_EXT | MAP_INVALIDATE_RANGE_BIT_EXT);
2635bd8deadSopenharmony_ci
2645bd8deadSopenharmony_ci
2655bd8deadSopenharmony_ci    /* Map the first 1K bytes of the buffer as write only, and invalidate the 
2665bd8deadSopenharmony_ci     * entire buffer. All locations within the buffer can assume undefined 
2675bd8deadSopenharmony_ci     * values. Locations written while mapped take on new values as expected.
2685bd8deadSopenharmony_ci     */
2695bd8deadSopenharmony_ci    void *ptr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 1024, 
2705bd8deadSopenharmony_ci        MAP_WRITE_BIT_EXT | MAP_INVALIDATE_BUFFER_BIT_EXT);
2715bd8deadSopenharmony_ci
2725bd8deadSopenharmony_ci
2735bd8deadSopenharmony_ci    /* Map the first 32K bytes of the buffer as write only, and invalidate 
2745bd8deadSopenharmony_ci     * that range. Indicate that we will explicitly inform GL which ranges are 
2755bd8deadSopenharmony_ci     * actually written. Locations within that range can assume undefined 
2765bd8deadSopenharmony_ci     * values. Only the locations which are written and subsequently flushed 
2775bd8deadSopenharmony_ci     * are guaranteed to take on defined values.
2785bd8deadSopenharmony_ci     * Write data to the first 8KB of the range, then flush it.
2795bd8deadSopenharmony_ci     * Write data to the last 8KB of the range, then flush it.
2805bd8deadSopenharmony_ci     */
2815bd8deadSopenharmony_ci    void *ptr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32768, 
2825bd8deadSopenharmony_ci        MAP_WRITE_BIT_EXT | MAP_INVALIDATE_RANGE_BIT_EXT | 
2835bd8deadSopenharmony_ci        MAP_FLUSH_EXPLICIT_BIT_EXT);
2845bd8deadSopenharmony_ci
2855bd8deadSopenharmony_ci    memset(ptr, 0x00, 8192);           /* write zeroes to first 8KB of range */
2865bd8deadSopenharmony_ci    glFlushMappedBufferRangeEXT(GL_ARRAY_BUFFER, 0, 8192);
2875bd8deadSopenharmony_ci
2885bd8deadSopenharmony_ci    memset(((char*)ptr)+24576, 0xFF, 8192);/* write FFs to last 8KB of range */
2895bd8deadSopenharmony_ci    glFlushMappedBufferRangeEXT(GL_ARRAY_BUFFER, 24576, 8192);
2905bd8deadSopenharmony_ci
2915bd8deadSopenharmony_ci
2925bd8deadSopenharmony_ci    /* Map the entire buffer for write - unsynchronized.
2935bd8deadSopenharmony_ci     * GL will not block for prior operations to complete.  Application must
2945bd8deadSopenharmony_ci     * use other synchronization techniques to ensure correct operation.
2955bd8deadSopenharmony_ci     */
2965bd8deadSopenharmony_ci    void *ptr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, size, 
2975bd8deadSopenharmony_ci        MAP_WRITE_BIT_EXT | MAP_UNSYNCHRONIZED_BIT_EXT);
2985bd8deadSopenharmony_ci
2995bd8deadSopenharmony_ci
3005bd8deadSopenharmony_ciRevision History
3015bd8deadSopenharmony_ci
3025bd8deadSopenharmony_ci    Version 4, 2014/08/21 - Fix typo OES_map_buffer -> OES_mapbuffer.
3035bd8deadSopenharmony_ci    Version 3, 2012/06/21 - Recast from APPLE to multivendor EXT
3045bd8deadSopenharmony_ci    Version 2, 2012/06/18 - Correct spec to indicate ES 1.1 may also be okay.
3055bd8deadSopenharmony_ci    Version 1, 2012/06/01 - Conversion from ARB_map_buffer_range to 
3065bd8deadSopenharmony_ci                            APPLE_map_buffer_range for ES.
307