| Name |
| |
| EXT_external_objects |
| |
| Name Strings |
| |
| GL_EXT_memory_object |
| GL_EXT_semaphore |
| |
| Contributors |
| |
| Carsten Rohde, NVIDIA |
| Dave Airlie, Red Hat |
| James Jones, NVIDIA |
| Jan-Harald Fredriksen, ARM |
| Jeff Juliano, NVIDIA |
| Michael Worcester, Imagination Technologies |
| |
| Contact |
| |
| James Jones, NVIDIA (jajones 'at' nvidia.com) |
| |
| Status |
| |
| Complete |
| |
| Version |
| |
| Last Modified Date: July 18, 2018 |
| Revision: 14 |
| |
| Number |
| |
| 503 |
| OpenGL ES Extension #280 |
| |
| Dependencies |
| |
| Written against the OpenGL 4.5 and OpenGL ES 3.2 specifications. |
| |
| GL_EXT_memory_object requires ARB_texture_storage or a version of |
| OpenGL or OpenGL ES that incorporates it. |
| |
| GL_EXT_semaphore requires OpenGL 1.0. |
| |
| ARB_direct_state_access (OpenGL) interacts with GL_EXT_memory_object |
| when OpenGL < 4.5 is used. |
| |
| ARB_sparse_texture (OpenGL) interacts with GL_EXT_memory_object |
| |
| EXT_sparse_texture (OpenGL ES) interacts with GL_EXT_memory_object |
| |
| EXT_protected_textures (OpenGL ES) interacts with GL_EXT_memory_object |
| |
| Overview |
| |
| The Vulkan API introduces the concept of explicit memory objects and |
| reusable synchronization objects. This extension brings those |
| concepts to the OpenGL API via two new object types: |
| |
| Memory objects |
| Semaphores |
| |
| Rather than allocating memory as a response to object allocation, |
| memory allocation and binding are two separate operations in Vulkan. |
| This extension allows an OpenGL application to import a Vulkan |
| memory object, and to bind textures and/or buffer objects to it. |
| |
| No methods to import memory objects are defined here. Separate |
| platform-specific extensions are defined for this purpose. |
| |
| Semaphores are synchronization primitives that can be waited on and |
| signaled only by the GPU, or in GL terms, in the GL server. They |
| are similar in concept to GL's "sync" objects and EGL's "EGLSync" |
| objects, but different enough that compatibilities between the two |
| are difficult to derive. |
| |
| Rather than attempt to map Vulkan semaphores on to GL/EGL sync |
| objects to achieve interoperability, this extension introduces a new |
| object, GL semaphores, that map directly to the semantics of Vulkan |
| semaphores. To achieve full image and buffer memory coherence with |
| a Vulkan driver, the commands that manipulate semaphores also allow |
| external usage information to be imported and exported. |
| |
| New Procedures and Functions |
| |
| The following commands are added if either of the GL_EXT_memory_object |
| or GL_EXT_semaphore strings are reported: |
| |
| void GetUnsignedBytevEXT(enum pname, |
| ubyte *data); |
| |
| void GetUnsignedBytei_vEXT(enum target, |
| uint index, |
| ubyte *data); |
| |
| If the GL_EXT_memory_object string is reported, the following |
| commands are added: |
| |
| void DeleteMemoryObjectsEXT(sizei n, |
| const uint *memoryObjects); |
| |
| boolean IsMemoryObjectEXT(uint memoryObject); |
| |
| void CreateMemoryObjectsEXT(sizei n, |
| uint *memoryObjects); |
| |
| void MemoryObjectParameterivEXT(uint memoryObject, |
| enum pname, |
| const int *params); |
| |
| void GetMemoryObjectParameterivEXT(uint memoryObject |
| enum pname, |
| int *params); |
| |
| void TexStorageMem2DEXT(enum target, |
| sizei levels, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| uint memory, |
| uint64 offset); |
| |
| void TexStorageMem2DMultisampleEXT(enum target, |
| sizei samples, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| boolean fixedSampleLocations, |
| uint memory, |
| uint64 offset); |
| |
| void TexStorageMem3DEXT(enum target, |
| sizei levels, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| sizei depth, |
| uint memory, |
| uint64 offset); |
| |
| void TexStorageMem3DMultisampleEXT(enum target, |
| sizei samples, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| sizei depth, |
| boolean fixedSampleLocations, |
| uint memory, |
| uint64 offset); |
| |
| void BufferStorageMemEXT(enum target, |
| sizeiptr size, |
| uint memory, |
| uint64 offset); |
| |
| [[ The following are added if direct state access is supported ]] |
| |
| void TextureStorageMem2DEXT(uint texture, |
| sizei levels, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| uint memory, |
| uint64 offset); |
| |
| void TextureStorageMem2DMultisampleEXT(uint texture, |
| sizei samples, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| boolean fixedSampleLocations, |
| uint memory, |
| uint64 offset); |
| |
| void TextureStorageMem3DEXT(uint texture, |
| sizei levels, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| sizei depth, |
| uint memory, |
| uint64 offset); |
| |
| void TextureStorageMem3DMultisampleEXT(uint texture, |
| sizei samples, |
| enum internalFormat, |
| sizei width, |
| sizei height, |
| sizei depth, |
| boolean fixedSampleLocations, |
| uint memory, |
| uint64 offset); |
| |
| void NamedBufferStorageMemEXT(uint buffer, |
| sizeiptr size, |
| uint memory, |
| uint64 offset); |
| |
| [[ The following are available in OpenGL only ]] |
| |
| void TexStorageMem1DEXT(enum target, |
| sizei levels, |
| enum internalFormat, |
| sizei width, |
| uint memory, |
| uint64 offset); |
| |
| [[ The following are availble in OpenGL only, and only when |
| direct state access is available ]] |
| |
| void TextureStorageMem1DEXT(uint texture, |
| sizei levels, |
| enum internalFormat, |
| sizei width, |
| uint memory, |
| uint64 offset); |
| |
| If the GL_EXT_semaphore string is reported, the following |
| commands are added: |
| |
| void GenSemaphoresEXT(sizei n, |
| uint *semaphores); |
| |
| void DeleteSemaphoresEXT(sizei n, |
| const uint *semaphores); |
| |
| boolean IsSemaphoreEXT(uint semaphore); |
| |
| void SemaphoreParameterui64vEXT(uint semaphore, |
| enum pname, |
| const uint64 *params); |
| |
| void GetSemaphoreParameterui64vEXT(uint semaphore, |
| enum pname, |
| uint64 *params); |
| |
| void WaitSemaphoreEXT(uint semaphore, |
| uint numBufferBarriers, |
| const uint *buffers, |
| uint numTextureBarriers, |
| const uint *textures, |
| const GLenum *srcLayouts); |
| |
| void SignalSemaphoreEXT(uint semaphore, |
| uint numBufferBarriers, |
| const uint *buffers, |
| uint numTextureBarriers, |
| const uint *textures, |
| const GLenum *dstLayouts); |
| |
| New Tokens |
| |
| If the GL_EXT_memory_object string is reported, the following tokens are |
| added: |
| |
| Accepted by the <pname> parameter of TexParameter{ifx}{v}, |
| TexParameterI{i ui}v, TextureParameter{if}{v}, TextureParameterI{i ui}v, |
| GetTexParameter{if}v, GetTexParameterI{i ui}v, GetTextureParameter{if}v, |
| and GetTextureParameterI{i ui}v: |
| |
| TEXTURE_TILING_EXT 0x9580 |
| |
| Accepted by the <pname> parameter of MemoryObjectParameterivEXT, and |
| GetMemoryObjectParameterivEXT: |
| |
| DEDICATED_MEMORY_OBJECT_EXT 0x9581 |
| |
| [[ The following are available when GL_EXT_protected_textures is |
| available ]] |
| |
| PROTECTED_MEMORY_OBJECT_EXT 0x959B |
| |
| Accepted by the <pname> parameter of GetInternalFormativ or |
| GetInternalFormati64v: |
| |
| NUM_TILING_TYPES_EXT 0x9582 |
| TILING_TYPES_EXT 0x9583 |
| |
| Returned in the <params> parameter of GetInternalFormativ or |
| GetInternalFormati64v when the <pname> parameter is TILING_TYPES_EXT, |
| returned in the <params> parameter of GetTexParameter{if}v, |
| GetTexParameterI{i ui}v, GetTextureParameter{if}v, and |
| GetTextureParameterI{i ui}v when the <pname> parameter is |
| TEXTURE_TILING_EXT, and accepted by the <params> parameter of |
| TexParameter{ifx}{v}, TexParameterI{i ui}v, TextureParameter{if}{v}, |
| TextureParameterI{i ui}v when the <pname> parameter is |
| TEXTURE_TILING_EXT: |
| |
| OPTIMAL_TILING_EXT 0x9584 |
| LINEAR_TILING_EXT 0x9585 |
| |
| The following tokens are added if either of the GL_EXT_memory_object or |
| GL_EXT_semaphore strings are reported: |
| |
| Accepted by the <pname> parameter of GetBooleanv, GetDoublev, GetFloatv, |
| GetIntegerv, GetInteger64v, GetUnsignedBytevEXT, and the <target> |
| parameter of GetBooleani_v, GetIntegeri_v,GetFloati_v, GetDoublei_v, |
| GetInteger64i_v, and GetUnsignedBytei_vEXT: |
| |
| NUM_DEVICE_UUIDS_EXT 0x9596 |
| DEVICE_UUID_EXT 0x9597 |
| DRIVER_UUID_EXT 0x9598 |
| |
| Constant values: |
| |
| UUID_SIZE_EXT 16 |
| |
| If the GL_EXT_semaphore string is reported, the following tokens are |
| added: |
| |
| Accepted by the <dstLayouts> parameter of SignalSemaphoreEXT and the |
| <srcLayouts> parameter of WaitSemaphoreEXT: |
| |
| LAYOUT_GENERAL_EXT 0x958D |
| LAYOUT_COLOR_ATTACHMENT_EXT 0x958E |
| LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F |
| LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 |
| LAYOUT_SHADER_READ_ONLY_EXT 0x9591 |
| LAYOUT_TRANSFER_SRC_EXT 0x9592 |
| LAYOUT_TRANSFER_DST_EXT 0x9593 |
| LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530 |
| LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531 |
| |
| Additions to Chapter 2 of the OpenGL 4.5 Specification (OpenGL |
| Fundamentals) |
| |
| Add two new sections after 2.6.13 (Sync Objects) |
| |
| 2.6.14 Semaphore Objects |
| |
| A /semaphore object/ is a synchronization primitive similar to a |
| /sync object/, but with semantics based on Vulkan semaphores. |
| |
| Semaphore objects may be shared. They are described in detail in |
| section XXX. |
| |
| 2.6.15 Memory Objects |
| |
| Many GL objects have some associated data stored in GL server |
| memory. /Memory objects/ are an abstract representation of GL |
| server memory suitable for use as the backing store of a |
| /buffer object/, a /texture object/, or both, depending on how |
| the memory referred to by the object was allocated. Memory |
| objects can not be created directly within the GL. They must be |
| imported from an API capable of allocating abstract memory, such |
| as Vulkan. |
| |
| Memory objects may be shared. They are described in detail in |
| Chapter 6 (Memory Objects). |
| |
| Additions to Chapter 4 of the OpenGL 4.5 Specification (Event Model) |
| |
| Add a new section between sections 4.1, "Sync Objects and Fences" |
| and section 4.2, "Query Objects and Asynchronous Queries" |
| |
| 4.2 Semaphore Objects |
| |
| Like sync objects, a semaphore object acts as a /synchronization |
| primitive/. However, semaphore objects differ from sync objects |
| in several ways: |
| |
| * They may only be created by importing an external semaphore |
| handle into the GL. |
| |
| * They are reusable. |
| |
| * As a corollary to the above behavior, separate commands are |
| provided to create and signal semaphore objects. |
| |
| * Their state is reset upon completion of a wait operation. |
| |
| * As a corollary to the above behavior, only a single waiter may |
| be associated with a unique signal command. |
| |
| * There is no way to wait for a semaphore to become signaled in |
| the GL client. All waits operations execute in the GL server, |
| and semaphores have no queryable state. |
| |
| The command |
| |
| void GenSemaphoresEXT(sizei n, |
| uint *semaphores); |
| |
| returns <n> previous unused semaphore names in <semaphores>. |
| These names are marked as used, for the purposes of |
| GenSemaphoresEXT only, but they are associated with semaphore |
| state only when an external semaphore handle is imported to |
| them. |
| |
| Semaphore objects are deleted by calling |
| |
| void DeleteSemaphoresEXT(sizei n, |
| const uint *semaphores); |
| |
| <semaphores> contains <n> names of semaphores to be deleted. |
| After a semaphore is deleted, it unreferences any external |
| semaphore state it referenced, and its name is again unused. |
| Unused names in <semaphores> are silently ignored, as is the |
| value zero. |
| |
| The command |
| |
| boolean IsSemaphoreEXT(uint semaphore); |
| |
| returns TRUE if <semaphore> is the name of a semaphore. If |
| <semaphore> is zero, or if <semaphore> is a non-zero value that |
| is not the name of a semaphore, IsSemaphore returns FALSE. |
| |
| 4.2.1 Importing External Semaphore Handles into Semaphores |
| |
| A semaphore is created by importing an external semaphore object |
| via a reference to its associated external handle. The |
| supported set of external handle types and associated import |
| functions are listed in table 4.2. |
| |
| Table 4.2: Commands for importing external semaphore handles. |
| |
| | Handle Type | Import command | |
| +-------------+----------------+ |
| +-------------+----------------+ |
| |
| Applications must only import external semaphore handles exported |
| from the same device or set of devices used by the current context, |
| and from compatible driver versions. To determine which devices are |
| used by the current context, first call GetIntegerv with <pname> set |
| to NUM_DEVICE_UUIDS_EXT, then call GetUnsignedBytei_vEXT with <target> |
| set to DEVICE_UUID_EXT, <index> set to a value in the range [0, |
| <number of device UUIDs>), and <data> set to point to an array of |
| UUID_SIZE_EXT unsigned bytes. To determine the driver ID of the |
| current context, call GetUnsignedBytevEXT with <pname> set to |
| DRIVER_UUID_EXT and <data> set to point to an array of UUID_SIZE_EXT |
| unsigned bytes. |
| |
| These device and driver ID values can be used to correlate devices |
| and determine driver compatibility across process and API boundaries. |
| |
| External handles are often defined using platform-specific |
| types. Therefore, the base GL specification defines no methods |
| to import an external handle. |
| |
| 4.2.2 Semaphore Parameters |
| |
| Semaphore parameters control how semaphore wait and signal |
| operations behave. Table 4.3 defines which parameters are available |
| for a semaphore based on the external handle type from which it was |
| imported. Semaphore parameters are set using the command |
| |
| void SemaphoreParameterui64vEXT(uint semaphore, |
| enum pname, |
| const uint64 *params); |
| |
| <semaphore> is the name of the semaphore object on which the |
| parameter <pname> will be set to the value(s) in <pname>. |
| |
| Table 4.3: Semaphore parameters |
| |
| | Name | External Handle Types | Legal Values | |
| +------+-----------------------+--------------+ |
| +------+-----------------------+--------------+ |
| |
| Parameters of a semaphore object may be queried with the command |
| |
| void GetSemaphoreParameterui64EXT(uint semaphore, |
| enum pname, |
| uint64 *params); |
| |
| <semaphore> is the semaphore object from with the parameter <pname> |
| is queried. The value(s) of the parameter are returned in <params>. |
| <pname> may be any value in table 4.3. |
| |
| 4.2.3 Waiting for Semaphores |
| |
| The command |
| |
| void WaitSemaphoreEXT(uint semaphore, |
| uint numBufferBarriers, |
| const uint *buffers, |
| uint numTextureBarriers, |
| const uint *textures, |
| const GLenum *srcLayouts); |
| |
| Returns immediately but causes GL server to block until |
| <semaphore> is signaled. If an error occurs, WaitSemaphore |
| generates a GL error as specified below, and does not cause the |
| GL server to block. |
| |
| After completion of the semaphore wait operation, the semaphore |
| will be returned to the unsignaled state. Calling WaitSemaphore on |
| a semaphore that has not previously had a signal operation flushed |
| to the GL server or submitted by an external semaphore signaler |
| since the semaphore was created or last waited on results in |
| undefined behavior. |
| |
| Following completion of the semaphore wait operation, memory will |
| also be made visible in the specified buffer and texture objects. |
| Since texture layout state is managed internally by the GL, but may |
| have been modified by an external API, the current layout of the |
| textures must be specified to initialize internal GL state prior to |
| using the textures after an external access. The valid layouts |
| correspond to those specified by the Vulkan API, as described in |
| table 4.3. However, the layouts do not necessarily correspond to an |
| optimal state for any particular GL operation. The GL will simply |
| perform appropriate transitions internally as necessary based on the |
| specified current layout of the texture. |
| |
| Table 4.4: Texture layouts and corresponding Vulkan Image Layouts |
| |
| | Texture Layout | Equivalent Vulkan Image Layout | |
| +--------------------------------------------------+----------------------------------------------------------------+ |
| | GL_NONE | VK_IMAGE_LAYOUT_UNDEFINED | |
| | GL_LAYOUT_GENERAL_EXT | VK_IMAGE_LAYOUT_GENERAL | |
| | GL_LAYOUT_COLOR_ATTACHMENT_EXT | VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL | |
| | GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT | VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT | |
| | GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT | VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL | |
| | GL_LAYOUT_SHADER_READ_ONLY_EXT | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL | |
| | GL_LAYOUT_TRANSFER_SRC_EXT | VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL | |
| | GL_LAYOUT_TRANSFER_DST_EXT | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL | |
| | GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT | VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR | |
| | GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT | VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR | |
| +-------------------------------------------------------------------------------------------------------------------+ |
| |
| 4.2.4 Signaling Semaphores |
| |
| The command |
| |
| void SignalSemaphoreEXT(uint semaphore, |
| uint numBufferBarriers, |
| const uint *buffers, |
| uint numTextureBarriers, |
| const uint *textures, |
| const GLenum *dstLayouts); |
| |
| will insert a semaphore signaling operation in the GL command |
| stream. |
| |
| Prior to signaling the semaphore, memory used by the specified |
| buffer objects and textures will be made visible, and textures |
| can be transitioned to a specified internal layout to allow |
| applications to access the textures using a consistent layout in |
| an external API or process. Possible layouts are specified in |
| table 4.3, along with their corresponding layout in the Vulkan |
| API. |
| |
| Add a new Chapter, "Memory Objects", between Chapter 5 (Shared Objects |
| and Multiple Contexts) and Chapter 6 (Buffer Objects) |
| |
| Memory objects reference a fixed-size allocation of abstract server |
| memory. The memory may not be accessed directly, but may be bound |
| to other objects that require a data store in server memory. The |
| memory itself is allocated outside the scope of the GL, and is |
| merely referenced by a memory object. |
| |
| The command |
| |
| void CreateMemoryObjectsEXT(sizei n, uint *memoryObjects); |
| |
| returns <n> previously unused memory object names in <memoryObjects>. |
| The memory objects named contain default state, but initially have no |
| external memory associated with them. |
| |
| Memory objects are deleted by calling |
| |
| void DeleteMemoryObjectsEXT(sizei n, const uint *memoryObjects); |
| |
| <memoryObjects> contains <n> names of memory objects to be deleted. |
| After a memory object is deleted, it references no server memory, |
| and its name is again unused. |
| |
| Unused names in <memoryObjects> are silently ignored, as is the |
| value zero. |
| |
| The command |
| |
| boolean IsMemoryObjectEXT(uint memoryObject); |
| |
| returns TRUE if <memoryObject> is the name of a memory object. If |
| <memoryObject> is zero, or if <memoryObject> is a non-zero value |
| that is not the name of a memory object, IsMemoryObjectEXT returns |
| FALSE. |
| |
| 6.1 Importing Abstract Memory into a Memory Object |
| |
| A memory object is associated with external memory by importing an |
| externally-allocated abstract memory region via a reference to an |
| associated external handle. The supported set of external handle types |
| and their corresponding import functions are listed in table 6.1. |
| |
| Table 6.1: Commands for importing external memory handles. |
| |
| | Handle Type | Import command | |
| +-------------+----------------+ |
| +-------------+----------------+ |
| |
| Applications must only import external semaphore handles exported |
| from the same device or set of devices used by the current context. |
| Refer to section 4.2.1 for methods to determine which devices are |
| used by the current context. |
| |
| External handles are often defined using platform-specific types. |
| Therefore, the base GL specification defines no methods to import an |
| external handle. |
| |
| 6.2 Memory object parameters |
| |
| Memory object parameters are set using the command |
| |
| void MemoryObjectParameterivEXT(uint memoryObject, |
| enum pname, |
| const int *params); |
| |
| <memoryObject> is the name of the memory object on which the parameter |
| <pname> will be set to the value(s) in <params>. The possible values for |
| <pname> are specified in table 6.2. |
| |
| Table 6.2: Memory Object Parameters. |
| |
| | Name | Legal Values | |
| +-----------------------------+--------------+ |
| | DEDICATED_MEMORY_OBJECT_EXT | FALSE, TRUE | |
| | PROTECTED_MEMORY_OBJECT_EXT | FALSE, TRUE | |
| +-----------------------------+--------------+ |
| |
| The parameter DEDICATED_MEMORY_OBJECT_EXT must be set to TRUE when the |
| external memory handle from which the object's memory will be imported |
| was created as a dedicated allocation. |
| |
| The parameter PROTECTED_MEMORY_OBJECT_EXT must be set to TRUE when the |
| external memory handle from which the object's memory will be imported |
| refers to a protected resource. The definition of a protected resource |
| is outside the scope of this extension. |
| |
| Memory object parameters become immutable once the object is associated |
| with external memory by an import operation. An INVALID_OPERATION error |
| is generated if <memoryObject> is immutable. |
| |
| The parameters of a memory object may be queried with the command: |
| |
| void GetMemoryObjectParameterivEXT(uint memoryObject |
| enum pname, |
| int *params); |
| |
| The value(s) of the parameter <pname> from the memory object |
| <memoryObject> are returned in <params>. |
| |
| Additions to Chapter 6 of the OpenGL 4.5 Specification (Buffer Objects) |
| |
| Modify the list of commands described in 6.2 "Creating and Modifying |
| Buffer Object Data Stores" to add the following: |
| |
| void BufferStorageMemEXT(enum target, |
| sizeiptr size, |
| uint memory, |
| uint64 offset); |
| |
| void NamedBufferStorageMemEXT(uint buffer, |
| sizeiptr size, |
| uint memory, |
| uint64 offset); |
| |
| Replace the two paragraphs after the above list of commands with the |
| following: |
| |
| "For BufferStorage and BufferStorageMemEXT, the buffer object is |
| that bound to <target>, which must be one of the values listed |
| in table 6.1. For NamedBufferStorage and |
| NamedBufferStorageMemEXT, <buffer> is the name of the buffer |
| object. For all the above commands, <size> is the size of the |
| data store in basic machine units. For BufferStorageMemEXT and |
| NamedBufferStorageMemEXT, <memory> and <offset> define a region |
| of abstract memory that will be used as the data store for |
| <buffer>. The implementation may restrict which values of |
| <offset> are valid for a given memory object and buffer |
| parameter combination. These restrictions are outside the scope |
| of this extension and must be determined by querying the API or |
| mechanism which created the resource which <memory> refers to. |
| If an invalid offset is specified an INVALID_VALUE error is |
| generated. |
| |
| "The data store of the buffer object is allocated or referenced |
| as a result of these commands, and cannot be de-allocated or |
| unreferenced until the buffer is deleted with a call to |
| DeleteBuffers." |
| |
| Replace the paragraph that beings "BufferStorage and |
| NamedBufferStorage delete..." with the following: |
| |
| "BufferStorage, BufferStorageMemEXT, NamedBufferStorage, and |
| NamedBufferStorageMemEXT delete any existing data store, and set |
| the values of the buffer object's state variables as shown in |
| table 6.3." |
| |
| Add the following to the list of errors for the BufferStorage |
| functions" |
| |
| "An INVALID_VALUE error is generated by BufferStorageMemEXT and |
| NamedBufferStorageMemEXT if <memory> is 0, or if <offset> + |
| <size> is greater than the size of the specified |
| memory object. |
| |
| "An INVALID_VALUE error is generated if <offset> is not a valid |
| value for <memory> or the texture." |
| |
| "An INVALID_OPERATION error is generated if <memory> names a valid |
| memory object which has no associated memory." |
| |
| Modify the header for the third column in table 6.2 to read |
| "Value for *BufferStorage*", and update the table description to |
| include the new memory object buffer storage commands. |
| |
| Modify the first sentence of section 6.3, "Mapping and Unmapping |
| Buffer Data", to read as follows: |
| |
| "If the data store for a buffer object is not a reference to a |
| memory object, all or part of the data store may be mapped into |
| the client's address space with the commands:" |
| |
| Add the following to the list of errors for the MapBufferRange and |
| MapNamedBufferRange commands: |
| |
| An INVALID_OPERATION error is generated by Map*BufferRange if |
| the specified buffer is referencing a memory object as its data |
| store. |
| |
| Additions to Chapter 8 of the OpenGL 4.5 Specification (Textures and |
| Samplers) |
| |
| For each list of TexStorage* commands in the 1D, 2D, 3D, |
| 2DMultisample, and 3DMultisample families, add the following |
| variants: |
| |
| void TexStorageMem*EXT(<existing parameters>, |
| uint memory, |
| uint64 offset); |
| |
| void TextureStorageMem*EXT(<existing parameters>, |
| uint memory, |
| uint64 offset); |
| |
| For each family of TexStorage* commands, add appropriate language to |
| the description based on the following template: |
| |
| "Calling TexStorageMem*EXT or TextureStorageMem*EXT is |
| equivalent to calling TexStorage* or TextureStorage* |
| except that rather than allocating new memory for the texture's |
| image data, the memory at <offset> in the memory object |
| specified by <memory> will be used. The implementation may |
| restrict which values of <offset> are valid for a given memory |
| object and texture parameter combination. These restrictions are |
| outside the scope of this extension and must be determined by |
| querying the API or mechanism which created the resource which |
| <memory> refers to. If an invalid offset is specified an |
| INVALID_VALUE error is generated." |
| |
| Add errors based on the following template for each family of |
| TexStorage* commands: |
| |
| "An INVALID_VALUE error is generated if <memory> is 0, or if |
| the memory object is not large enough to contain the specified |
| texture's image data." |
| |
| "An INVALID_VALUE error is generated if <offset> is not a valid |
| value for <memory> or the texture." |
| |
| "An INVALID_OPERATION error is generated if <memory> names a valid |
| memory object which has no associated memory." |
| |
| "An INVALID_OPERATION error is generated if <memory> is a protected |
| memory object and the texture parameter TEXTURE_PROTECTED_EXT is not |
| TRUE." |
| |
| Insert the following before Table 8.17: |
| |
| "If <pname> is TEXTURE_TILING_EXT then the state is stored in the |
| texture, but only takes effect the next time storage is allocated |
| from a memory object for the texture object using TexStorageMem*EXT |
| or TextureStorageMem*EXT. If the value of TEXTURE_IMMUTABLE_FORMAT |
| is TRUE, then TEXTURE_TILING_EXT cannot be changed and an |
| INVALID_OPERATION error is generated." |
| |
| Add the following to table 8.17: Texture parameters and their values. |
| |
| | Name | Type | Legal values | |
| +--------------------+---------+---------------------------------------+ |
| | TEXTURE_TILING_EXT | enum | OPTIMAL_TILING_EXT, LINEAR_TILING_EXT | |
| +--------------------+---------+---------------------------------------+ |
| |
| Additions to Chapter 22 of the OpenGL 4.5 Specification (Context state |
| Queries) |
| |
| Add the following to the end of the first list of functions in section |
| 22.1, Simple Queries: |
| |
| void GetUnsignedBytevEXT(enum pname, |
| ubyte *data); |
| |
| Replace the sentence following that list with: |
| |
| The commands obtain boolean, integer, 64-bit integer, floating- |
| point, double-precision, or unsigned byte state variables. |
| |
| Add the following to the end of the list of indexed simple state query |
| commands: |
| |
| void GetUnsignedBytei_vEXT(enum target, |
| uint index, |
| ubyte *data); |
| |
| |
| |
| Add the following to section 22.3.2, Other Internal Format Queries: |
| |
| NUM_TILING_TYPES_EXT: The number of tiling types that would be |
| returned by querying TILING_TYPES_EXT is returned in <params>. |
| |
| TILING_TYPES_EXT: The tiling type supported when using memory |
| objects to create textures with <internalFormat> and <target> |
| are written to <params>, in the order in which they occur in |
| table 22.3. Possible values are those listed in table 22.3. |
| |
| Table 22.3: Possible tiling types supported by textures using |
| memory objects. |
| |
| | Tiling Type | |
| +--------------------+ |
| | OPTIMAL_TILING_EXT | |
| | LINEAR_TILING_EXT | |
| +--------------------+ |
| |
| Errors |
| |
| New State |
| |
| Issues |
| |
| 1) Should only DSA-style texture and buffer object binding |
| functions be added to keep the number of new functions |
| to a minimum? |
| |
| RESOLVED: No. Both DSA and traditional entry points will be added. |
| |
| 2) Should the type of the memory <size> and <offset> parameters be |
| GLsizeiptr, GLintptr, GLint64, or GLuint64? |
| |
| RESOLVED: GLuint64. This matches the VkDeviceSize semantics. |
| |
| 3) Should there be a way to allocate memory within OpenGL in |
| addition to importing it? |
| |
| RESOLVED: No. This could be covered in a separate extension, but |
| this would involve building up all the memory property |
| infrastructure Vulkan already has. Applications wishing to use |
| memory objects in OpenGL will need to leverage the allocation and |
| memory capability querying mechanisms present in Vulkan to perform |
| the actual allocations, and then map the capabilities to GL |
| equivalents when using them. |
| |
| 4) How are sparse textures handled? |
| |
| RESOLVED: Sparse texture support is deferred to a later extension. |
| Late in the development of this specification, it was discovered |
| that naively extending TexPageCommitmentARB to accept an offset |
| and memory object parameter results in a subtly awkward interface |
| when used to build GL sparse textures equivalent to those of Vulkan |
| sparse images, due to the lack of a defined memory layout ordering |
| for array textures. Developing a better interface would have |
| further delayed release of the basic functionality defined here, |
| which is in higher demand. |
| |
| 5) Do memory objects created as dedicated allocations need special |
| handling? |
| |
| RESOLVED: No. Like other memory regions, these allocations must be |
| bound to GL objects compatible with those they are bound to in |
| Vulkan to avoid aliasing issues, but otherwise no special handling |
| is required. |
| |
| 6) Should the BufferStorage functions still take a flags parameter? |
| |
| RESOLVED: No. The flags are not relevant when the memory has |
| already been allocated externally. |
| |
| 7) Should the Buffer commands be called BufferStorage or BufferData? |
| |
| RESOLVED: BufferStorage. GL has both commands, while GL ES has only |
| BufferData. The difference between the two GL commands is |
| immutability. The naming of the BufferStorage seems more consistent |
| with the usage, since data is not specified with these commands, but |
| a backing store is, and immutability for Vulkan memory-backed buffer |
| objects seems desirable. However, if GLES implementations can not |
| support immutable buffers, BufferData() support can be added in a |
| future extension with some added driver complexity. |
| |
| 8) Can semaphore commands be issued inside of Begin/End, or be |
| included in display lists? |
| |
| RESOLVED: No. |
| |
| 9) Do ownership transfer and memory barrier commands need to be |
| included in the semaphore operations? |
| |
| RESOLVED: Yes, these are needed for proper synchronization on some |
| implementations. Presumably only the source side of the barriers |
| needs to be specified when transitioning from external to GL usage, |
| and only the destination side needs to be specified when |
| transitioning from GL to external usage. That should give the |
| OpenGL driver sufficient knowledge to perform any needed automatic |
| transitions based on subsequent usage within the GL API. |
| |
| Still, it is unclear how much of the Vulkan pipeline barrier API |
| should be explicitly exposed in the GL API: |
| |
| * Should queue ownership be included? There is no equivalent |
| idiom to define this on top of in GL. However, since the |
| external side is the only portion specified by the |
| application, it could be described in Vulkan terms. |
| |
| * Should image layout be included? Similar to the above, there |
| is no GL concept of this, but Vulkan terms could be leveraged. |
| |
| * Should access type be included? This maps relatively well to |
| OpenGL memory barrier bits, but there is not a 1-1 |
| correspondence. |
| |
| * Should the pipeline stage be included? This could be mapped |
| to stages defined in the GL state machine, but such explicit |
| references to the stages are not thus far included in GL |
| language or tokens. |
| |
| Another option is to require the Vulkan driver to put images, |
| buffers, and their memory in a particular state before sharing |
| them with OpenGL. For example, require applications to |
| transition to the GENERAL image layout, dstStageMask of |
| TOP_OF_PIPE or ALL_COMMANDS, dstAccessMask will include |
| MEMORY_WRITE_BIT | MEMORY_READ_BIT or some new "more external" |
| version of these, and the dstQueueFamilyIndex must be IGNORED |
| while srcQueueFamilyIndex must be a valid queue family (a |
| currently illegal situation). |
| |
| 10) Should the barrier functionality be included in the semaphore |
| operation commands? |
| |
| RESOLVED: Yes. The only time such barriers are required in GL is |
| when synchronizing with external memory accesses, which is also the |
| only time semaphores should be used. For internal synchronization, |
| existing GL and EGL commands should be used. Since the use cases |
| align, it makes sense to make them a single command to cut down on |
| the potential for misuse and keep the API footprint as small as |
| possible. |
| |
| 11) Must both Gen[MemoryObjects,Semaphores]EXT commands and |
| Create[MemoryObjects,Semaphores]EXT commands be defined, or is |
| one or the other sufficient? |
| |
| RESOLVED: One variant is sufficient for each object type. |
| |
| 12) Should buffer objects backed by memory objects be mappable? |
| |
| RESOLVED: No. This would complicate the API as interactions between |
| GL and Vulkan cache flushing semantics would need to be defined. |
| |
| 13) Does the usage information provided when creating Vulkan images |
| need to be specified when creating textures on memory objects? |
| If so, how is it specified? |
| |
| RESOLVED: There are a few options for specifying the usage in |
| OpenGL: |
| |
| * Have some sort of GLX/EGL-like attrib list that allows users |
| to specify an arbitrary set of usage parameters. |
| |
| * Allow applications to re-use the Vulkan usage flags directly |
| in GL. |
| |
| * Re-define all the Vulkan image usage flags in GL, and update |
| the list via new GL interop extensions as new Vulkan usage |
| flags are added by Vulkan extensions. |
| |
| None of these are very compelling. They all complicate the OpenGL |
| API significantly and have a high spec maintenance burden as new |
| extensions are added. |
| |
| Other options for resolving the overall issue of GL knowing the |
| usage include: |
| |
| * Disallow Vulkan implementations from utilizing the usage |
| information as input when determining the internal parameters of a |
| Vulkan image used with eternal memory. |
| |
| * Only allow Vulkan implementations to utilize the usage information |
| when using the dedicated allocation path where it can be stored as |
| a form of metadata along with the memory. |
| |
| * Require applications to specify all supported usage flags at image |
| creation time on the Vulkan side for images that are intended to |
| alias with OpenGL textures. |
| |
| The first two options have the downside of potentially limiting the |
| ability of implementations to fully optimize external images |
| regardless of their use case. The last option constrains the |
| limitations to the case of interoperation with OpenGL, making it a |
| less onerous requirement for implementations while still keeping the |
| OpenGL side of the API relatively simple compared to the options |
| involving re-specification of image usage on the OpenGL side. |
| |
| The agreed resolution is to use the final option: Require all |
| supported usage flags be specified by the application on the Vulkan |
| side if the image is intended to alias with an OpenGL texture. |
| |
| 14) Are memory barriers for textures and buffer objects needed with |
| semaphore signal/wait operations, or should a blanket availability/ |
| visibility rule be applied like in Vulkan<->Vulkan semaphore |
| synchronization? |
| |
| RESOLVED: Perhaps extra availability/visibility operations need to |
| be performed to enable external accesses, so it is safest to require |
| explicit specification of the resources that need to be made |
| available and visible as part of a semaphore synchronization |
| operation. |
| |
| 15) Are OpenGL equivalents of the Vulkan image creation flags related to |
| sparse properties needed? |
| |
| RESOLVED: Sparse support is not included in this extension. |
| |
| Prior to this resolution, the proposed resolution was as follows: |
| |
| No. For the purposes of OpenGL, the functionality of all the Vulkan |
| sparse image creation flags is contained in the existing |
| TEXTURE_SPARSE texture parameter. Because OpenGL does not have the |
| same sparse feature granularity as Vulkan, applications wishing to |
| create a sparse image that will alias with an OpenGL sparse texture |
| will be required to set all of the sparse bits. Images not intended |
| to alias with an OpenGL texture without the TEXTURE_SPARSE flag set |
| must have none of the Vulkan sparse bits set. |
| |
| 16) How do Vulkan sparse block sizes and OpenGL virtual page sizes |
| interact? |
| |
| RESOLVED: Sparse support is not included in this extension. |
| |
| Prior to this resolution, the proposed resolution was as follows: |
| |
| The application must use an OpenGL virtual page size with dimensions |
| matching those of the Vulkan sparse block size for any Vulkan images |
| aliasing OpenGL sparse textures. If no such virtual page size exists, |
| such aliasing is not supported. |
| |
| 17) Is an OpenGL equivalent of the mutable format Vulkan image creation |
| parameter needed? |
| |
| RESOLVED: No. However, Vulkan applications will be required to set |
| the mutable format bit when creating an image that will alias with |
| an OpenGL texture on an OpenGL implementation that supports |
| ARB_texture_view, OES_texture_view, EXT_texture_view, or OpenGL 4.3 |
| and above. |
| |
| 18) Is an OpenGL equivalent of the tiling Vulkan image creation |
| parameter needed? |
| |
| RESOLVED: Yes. Further, OpenGL implementations may not support |
| creating textures from Vulkan images using certain tiling types, so |
| a query is needed to determine the types supported. |
| |
| 19) Is a way to specify dedicated allocation semantics needed? |
| |
| RESOLVED: Yes. Importing dedicated allocation-style memory may |
| require the driver to use different paths than importing purely |
| abstract memory. Additionally, textures and buffer objects may need to derive meta-data from their associated memory object if |
| it is a dedicated allocation. Therefore, a dedicated allocation |
| parameter should be added to the memory objects. Additional |
| parameters for textures and buffer objects are not required because |
| unlike Vulkan, OpenGL exposes no application-visible texture or |
| buffer state that would vary depending on whether a dedicated |
| allocation will be used for their storage. Therefore, they can |
| inherit the state from the memory object associated with them at |
| storage specification time. Note that allowing parameters to be |
| specified on a memory object prior to the import operation requires |
| separate memory import from memory object instantiation commands. |
| |
| 20) How should devices be correlated between OpenGL Vulkan, and other |
| APIs? |
| |
| RESOLVED: Device UUID, LUID, and node mask queries are introduced, |
| corresponding to those added to the Vulkan API for external memory/ |
| semaphore purposes. Because contexts may be associated with |
| multiple physical GPUs in some cases, multiple values are returned |
| for device UUIDs and multiple bits are set in the device node masks. |
| It is not expected that a single context will be associated with |
| multiple DXGI adapters, so only one LUID is returned. |
| |
| When sharing with Vulkan device groups, the device UUIDs used by the |
| context must match those of the Vulkan physical devices in the |
| Vulkan device group. Future extensions could relax this |
| requirement. |
| |
| 21) How do applications determine valid values for the <offset> |
| parameter of the new storage allocation/binding functions? |
| |
| RESOLVED: This is outside the scope of this extension. The API or |
| mechanism which allocated the memory must provide this information. |
| However, the GL will generate an error if an invalid offset is used. |
| |
| 22) Are there any interactions with the EXT_protected_textures |
| extension? |
| |
| RESOLVED: Yes. Memory objects can be marked as protected or not |
| protected before import. This state must match that of the |
| imported resource. For all textures bound to a given memory object, |
| the value of the TEXTURE_PROTECTED_EXT parameter of the textures |
| must match the PROTECTED_MEMORY_OBJECT_EXT parameter of the memory |
| object. |
| |
| 23) How do applications detect when the new texture layouts |
| corresponding to the image layouts in VK_KHR_maintenance2 are |
| supported in OpenGL? |
| |
| RESOLVED: OpenGL contexts that report the GL_EXT_semaphore extension |
| string and have a DRIVER_UUID_EXT and DEVICE_UUID_EXT corresponding |
| to a Vulkan driver that supports VK_KHR_maintenance2 must support |
| the new OpenGL texture layouts. |
| |
| Revision History |
| |
| Revision 14, 2018-07-18 (James Jones) |
| - Fixed a typo: Replace NamedBufferStroage with NamedBufferStorage |
| |
| Revision 13, 2017-09-26 (James Jones) |
| - Added new image layouts corresponding to those from |
| VK_KHR_maintenance2. |
| - Added issue 23 and resolution. |
| |
| Revision 12, 2017-06-08 (Andres Rodriguez) |
| - Fixed parameter name in MemoryObjectParameterivEXT's description. |
| - Fixed missing EXT suffix in some mentions of GetUnsignedByte* |
| |
| Revision 11, 2017-06-02 (James Jones) |
| - Added extension numbers. |
| - Fixed the name of GetSemaphoreParameterui64vEXT. |
| - Clarified which extensions each command and token belongs to. |
| - Marked complete. |
| |
| Revision 10, 2017-05-24 (James Jones) |
| - Added issue 21 and resolution. |
| - Added issue 22 and resolution. |
| - Removed sparse texture support. |
| - Filled in real token values |
| - Further documented the new LAYOUT tokens. |
| |
| Revision 9, 2017-04-05 (James Jones) |
| - Added context device UUID queries. |
| |
| Revision 8, 2017-04-04 (James Jones) |
| - Clarified semaphore semantics |
| |
| Revision 7, 2017-03-28 (James Jones) |
| - Fixed various typos. |
| |
| Revision 6, 2017-03-17 (James Jones) |
| - Renamed from KHR to EXT. |
| - Added texture tiling parameters. |
| - Added semaphore parameter manipulation functions. |
| - Replaced GenMemoryObjectsEXT with CreateMemoryObjectsEXT |
| - Added memory object parameter manipulation functions. |
| - Updated issue 13 with a proposed resolution. |
| - Added issues 15-19 and proposed resolutions. |
| |
| Revision 5, 2016-10-22 (James Jones) |
| - Added proposed memory barrier semantics to the semaphore commands. |
| - Added issue 14. |
| - Added some clarifications to issue 13 |
| |
| Revision 4, 2016-09-28 (James Jones) |
| - Merged in GL_KHR_semaphore to reduce number of specs. |
| - Added spec body describing the new commands. |
| - Added issues 9-13. |
| |
| Revision 3, 2016-08-15 (James Jones and Jeff Juliano) |
| - Clarified overview text. |
| |
| Revision 2, 2016-08-07 (James Jones) |
| - Added non-contiguous sparse binding support via |
| TexPageCommitmentMemKHR(). |
| |
| Revision 1, 2016-08-05 (James Jones) |
| - Initial draft. |