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