| 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 4.2. | |
| 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.4. 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, and flush the command stream as if /Flush/ were inserted | |
| immediately after the semaphore operation. | |
| 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 memory 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 21 of the OpenGL 4.5 Specification (Special Functions) | |
| Add the following to section 21.4.1, Commands Not Usable in Display | |
| Lists. | |
| Under the "Memory objects" section: | |
| DeleteMemoryObjectsEXT, CreateMemoryObjectsEXT, | |
| MemoryObjectParameterivEXT | |
| Under the "Pixels and textures" section: | |
| TexStorageMem2DEXT, TexStorageMem2DMultisampleEXT, | |
| TexStorageMem3DEXT, TexStorageMem3DMultisampleEXT, | |
| TextureStorageMem2DEXT, TextureStorageMem2DMultisampleEXT, | |
| TextureStorageMem3DEXT, TextureStorageMem3DMultisampleEXT, | |
| TexStorageMem1DEXT, TextureStorageMem1DEXT | |
| Under the "Buffer objects" section: | |
| BufferStorageMemEXT, NamedBufferStorageMemEXT | |
| Under the "GL command stream management" section: | |
| GenSemaphoresEXT, DeleteSemaphoresEXT, SemaphoreParameterui64vEXT, | |
| WaitSemaphoreEXT, SignalSemaphoreEXT | |
| 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 external 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 15, 2022-07-15 (James Jones) | |
| - Noted SignalSemaphoreEXT implicitly flushes the command stream | |
| - Added commands to the list of commands not permitted in display | |
| lists. | |
| 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. |