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