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 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 set to one of the targets listed in table 2.8, set to the size of the data store in basic machine units, and data pointing to the source data in client memory. If is not EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, then if is non-null, the source data is copied to the buffer object's data store. If is null, then the contents of the buffer object's data store are undefined. If 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. 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 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.