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.

