| Name | 
 |  | 
 |     AMD_pinned_memory | 
 |  | 
 | Name Strings | 
 |  | 
 |     GL_AMD_pinned_memory | 
 |  | 
 | Contributors | 
 |  | 
 |     Pierre Boudier | 
 |     Graham Sellers | 
 |  | 
 | Contact | 
 |  | 
 |     Pierre Boudier, AMD (pierre.boudier 'at' amd.com) | 
 |  | 
 | IP Status | 
 |  | 
 |     None. | 
 |  | 
 | Status | 
 |  | 
 |     Shipping | 
 |  | 
 | Version | 
 |  | 
 |     Last Modified Date: June 4, 2013 | 
 |     Revision: 2.0 | 
 |  | 
 | Number | 
 |  | 
 |     411 | 
 |  | 
 | Dependencies | 
 |  | 
 |     This specification is written against the OpenGL 4.2 (Core) Specification, | 
 |     dated August 8, 2011. | 
 |  | 
 | Overview | 
 |  | 
 |     This extension defines an interface that allows improved control | 
 |     of the physical memory used by the graphics device. | 
 |  | 
 |     It allows an existing page of system memory allocated by the application | 
 |     to be used as memory directly accessible to the graphics processor. One | 
 |     example application of this functionality would be to be able to avoid an | 
 |     explicit synchronous copy with sub-system of the application; for instance | 
 |     it is possible to directly draw from a system memory copy of a video | 
 |     image. | 
 |  | 
 | New Procedures and Functions | 
 |  | 
 |     None | 
 |  | 
 | New Tokens | 
 |  | 
 |     Accepted by the <target> parameters of BindBuffer, BufferData, | 
 |     BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, | 
 |     GetBufferParameteriv, GetBufferPointerv, MapBufferRange: | 
 |  | 
 |         EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD              0x9160 | 
 |  | 
 | Additions to Chapter 2 of the OpenGL 4.2 (Core Profile) Specification | 
 | (OpenGL Operation) | 
 |  | 
 |     Additions to the table Table 2.8: Buffer object binding targets. | 
 |  | 
 |     +-------------------------------------+---------------------------------+-------------------------+ | 
 |     | Target name                         | Purpose                         | Described in section(s) | | 
 |     +-------------------------------------+---------------------------------+-------------------------+ | 
 |     | EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD  | Application-owned memory buffer | 2.9.2                   | | 
 |     +-------------------------------------+---------------------------------+-------------------------+ | 
 |  | 
 |     Modifications to Section 2.9.2, "Creating Buffer Object Data Stores" | 
 |  | 
 |         2.9.2 Creating Buffer Object Data Stores | 
 |  | 
 |     The data store of a buffer object is created and initialized by calling | 
 |  | 
 |         void BufferData( enum target, sizeiptr size, const void *data, enum usage ); | 
 |  | 
 |     with <target> set to one of the targets listed in table 2.8, <size> set to | 
 |     the size of the data store in basic machine units, and data pointing to the | 
 |     source data in client memory. If <target> is not | 
 |     EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, then if <data> is non-null, the source | 
 |     data is copied to the buffer object's data store. If <data> is null, then | 
 |     the contents of the buffer object's data store are undefined. If <target> | 
 |     is EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, then the client's memory is used | 
 |     directly by the GL for all subsequent operations on the buffer object's | 
 |     data store. In this case, the application must guarantee the existence of | 
 |     the buffer for the lifetime of the buffer object, or until its data store | 
 |     is re-specified by another call to BufferData. <usage> is specified as one | 
 |     of nine enumerated values, indicating the expected application usage | 
 |     pattern of the data store. The values are: ... | 
 |  | 
 | Additions to Chapter 3 of the OpenGL 4.2 (Core Profile) Specification | 
 | (Rasterization) | 
 |  | 
 |     None. | 
 |  | 
 | Additions to Chapter 4 of the OpenGL 4.2 (Core Profile) Specification | 
 | (Per-Fragment Operations and the Framebuffer) | 
 |  | 
 |     None. | 
 |  | 
 | Additions to Chapter 5 of the OpenGL 4.2 (Core Profile) Specification | 
 | (Special Functions) | 
 |  | 
 |     None. | 
 |  | 
 | Additions to Chapter 6 of the OpenGL 4.2 (Core Profile) Specification | 
 | (State and State Requests) | 
 |  | 
 |     None. | 
 |  | 
 | Errors | 
 |  | 
 |     INVALID_OPERATION is generated by BufferData if <target> is | 
 |     EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, and the store cannot be mapped to the | 
 |     GPU address space. | 
 |  | 
 | Issues | 
 |  | 
 |     1) When a system memory is shared with the GL, do we need extra | 
 |        synchronization for the application to update the content? | 
 |  | 
 |         RESOLVED: NO. once the memory page has been shared with the GL, | 
 |         then all the regular OpenGL commands can be used to ensure | 
 |         proper synchronization. the newly created buffer object is | 
 |         no different from the ones that were allocated by GL, except | 
 |         that the physical pages cannot be changed (but virtual mapping | 
 |         can change). | 
 |  | 
 |     2) Can the application still use the buffer using the CPU address? | 
 |  | 
 |         RESOLVED: YES. However, this access would be completely | 
 |         non synchronized to the OpenGL pipeline, unless explicit | 
 |         synchronization is being used (for example, through glFinish or by using | 
 |         sync objects). | 
 |  | 
 |     3) Can the application free the memory? | 
 |  | 
 |         RESOLVED: YES. However, the underlying buffer object should | 
 |         have been deleted from the OpenGL to prevent any access by | 
 |         the GPU, or the result is undefined, including program or even system | 
 |         termination. | 
 |  | 
 |     4) Is glMapBuffer on a shared buffer guaranteed to return the same system | 
 |        address which was specified at creation time? | 
 |  | 
 |         RESOLVED: NO. The GL implementation might return a different virtual | 
 |         mapping of that memory, although the same physical page will be used. | 
 |  | 
 |     5) Is there any limitation on offset/size? | 
 |  | 
 |         RESOLVED: YES. Since the pinning of system memory is eventually handled | 
 |         by the OS, there might be different restriction. It is recommended to | 
 |         align the offset/size to the underlying page size (4k seems to be | 
 |         widespread). | 
 |  | 
 |     6) What happens if you use this extension on two separate buffers which are | 
 |        sharing the same underlying physical page? | 
 |  | 
 |         RESOLVED: The behavior is undefined. some OS will not refcount how | 
 |         many times a physical page is locked for GPU access, and may therefore | 
 |         either fail to lock, or fail to properly unlock. | 
 |  | 
 |     7) Should there be a query for the alignment value of offset/size? | 
 |  | 
 |         RESOLVED: NO. on the same system, it is possible to have several | 
 |         different page sizes. | 
 |  | 
 |     8) Why is the error produced for failure to pin memory INVALID_OPERATION? | 
 |        Why not OUT_OF_MEMORY? | 
 |  | 
 |        OUT_OF_MEMORY invalidates OpenGL context state. Failure to pin memory | 
 |        does not upset the state of the context, and so an error that does not | 
 |        have this semantic was chosen. The exact cause of the failure may be | 
 |        reported by a debug context. | 
 |  | 
 | Example Usage | 
 |  | 
 |     The GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD target is used simply for the | 
 |     purposes of allocation through BufferData. It is otherwise not referenced | 
 |     by the GL (much like GL_COPY_READ_BUFFER, for example). Once the buffer's | 
 |     data store has been associated with client memory, that memory may be used | 
 |     for any purpose such as vertex attributes (GL_ARRAY_BUFFER), TBO | 
 |     (GL_TEXTURE_BUFFER), pixel reads and writes (GL_PIXEL_UNPACK_BUFFER, | 
 |     GL_PIXEL_PACK_BUFFER) or transform feedback (GL_TRANSFORM_FEEDBACK_BUFFER). | 
 |  | 
 |     As an example, consider the following example, which performs an | 
 |     asynchronous pixel readback to client memory: | 
 |  | 
 |        GLuint buffer; | 
 |        glGenBuffers(1, &buffer); | 
 |        glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, buffer); | 
 |  | 
 |        void * memory = malloc(1024 * 1024 * 4); | 
 |        glBufferData(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 1024 * 1024 * 4, GL_STREAM_COPY, memory); | 
 |  | 
 |        glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0); | 
 |        glBindBuffer(GL_PIXEL_PACK_BUFFER_AMD, buffer); | 
 |        glReadPixels(0, 0, 1024, 1024, GL_RGBA, GL_UNSIGNED_BYTE, 0); | 
 |  | 
 |        GLsync s = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); | 
 |  | 
 |        // Data will eventually end up in 'memory'. Other processing may occur | 
 |        // during the transfer time. | 
 |  | 
 |        glClientWaitSync(s, GL_SYNC_FLUSH_COMMANDS_BIT, ~0ull); | 
 |  | 
 |        // It is now safe to use 'memory' | 
 |  | 
 | Revision History | 
 |  | 
 |     Rev.    Date      Author    Changes | 
 |     ----  --------    --------  ----------------------------------------- | 
 |  | 
 |      2    04/05/2013  gsellers  Fixed a couple of typos. | 
 |      1    11/30/2011  gsellers  Cleanup and minor updates. | 
 |      xx   03/22/2011  pboudier  Initial draft. | 
 |  |