Name | |
EXT_external_buffer | |
Name Strings | |
GL_EXT_external_buffer | |
Contact | |
Jeff Leger (jleger 'at' qti.qualcomm.com) | |
Contributors | |
Sam Holmes | |
Maurice Ribble | |
Matt Netsch | |
Jeremy Gebben | |
John Bates | |
Craig Donner | |
Jeff Leger | |
Rob VanReenen | |
Tom Kneeland | |
Jesse Hall | |
Jan-Harald Fredriksen | |
Daniel Koch | |
Mathias Heyer | |
Status | |
Complete | |
Version | |
Last Modified Date: May 29, 2017 | |
Revision: 1.0 | |
Number | |
OpenGL ES Extension #284 | |
OpenGL Extension #508 | |
Dependencies | |
OpenGL ES 3.1 and EXT_buffer_storage are required for OpenGL ES | |
implementations. | |
OpenGL 4.4 is required for OpenGL implementations. | |
This extension is written against the OpenGL ES 3.1 (June 4, 2014) | |
Specification. | |
This extension is written against version 3 of EXT_buffer_storage. | |
The definition of this extension is affected by the presence of | |
GL_EXT_direct_state_access, GL_ARB_direct_state_access, or OpenGL 4.5. | |
Overview | |
Extension EXT_buffer_storage introduced immutable storage buffers to | |
OpenGL ES. This extension allows the data store for an immutable buffer to | |
be sourced from an external EGLClientBuffer, allowing sharing of EGL client | |
buffers across APIs, across processes, and across different processing | |
cores such as the GPU, CPU, and DSP. | |
Operations can then be performed on the external buffer using standard | |
GL buffer object procedures. The data in the allocation is not copied to | |
the buffer object's data store; the external allocation represents a single | |
memory allocation that can be shared across multiple GL objects -- this | |
aspect is similar to EGL external images. On the other hand, the external | |
buffer does not provide lifetime guarantees including orphaning and sibling | |
behavior as provided by EGL external images. | |
The EGLClientBuffer must be allocated in a way which permits this shared | |
access. For example, on Android via a shareable Android hardware buffer. | |
This extension does not enable support for arbitrary EGLClientBuffers to be | |
used as an external buffer. | |
It is the application's responsibility to ensure synchronization between | |
operations performed by separate components (DSP / CPU / GPU) and processes | |
on the external buffer. Additionally the application is responsible for | |
avoiding violating existing GL spec requirements. For example, mapping a | |
single shared allocation to two GL buffer objects and then performing | |
CopyBufferSubData such that the read and write regions overlap would | |
violate the existing CopyBufferSubData spec regarding copies performed | |
with the same buffer set for source and destination. | |
The application must take any steps necessary to ensure memory access to | |
the external buffer behaves as required by the application. For example, | |
preventing compilation differences in data padding from causing data to be | |
inadvertently corrupted by using defined structure alignment methods such | |
as the std140 layout qualifier. The application is responsible for | |
managing the lifetime of the external buffer, ensuring that the external | |
buffer is not deleted as long as there are any GL buffer objects referring | |
to it. | |
New Types | |
/* | |
* GLeglClientBufferEXT is an opaque handle to an EGLClientBuffer | |
*/ | |
typedef void* GLeglClientBufferEXT; | |
New Procedures and Functions | |
void BufferStorageExternalEXT(enum target, | |
intptr offset, | |
sizeiptr size, | |
eglClientBufferEXT clientBuffer, | |
bitfield flags); | |
[[ The following is only added if GL_EXT_direct_state_access, | |
GL_ARB_direct_state_access, or OpenGL 4.5 is supported. ]] | |
void NamedBufferStorageExternalEXT(uint buffer, | |
intptr offset, | |
sizeiptr size, | |
eglClientBufferEXT clientBuffer, | |
bitfield flags); | |
New Tokens | |
None | |
Additions to Chapter 6 of the OpenGL ES 3.1 Specification (Buffer Objects) | |
Modify Section 6.2, (Creating and Modifying Buffer Object Data Stores). After | |
the section describing BufferStorageEXT, insert the following: | |
The command | |
void BufferStorageExternalEXT(enum target, intptr offset, | |
sizeiptr size, eglClientBufferEXT clientBuffer, | |
bitfield flags); | |
behaves similar to BufferStorageEXT, but rather than allocate an immutable | |
data store, the specified client buffer is referenced as the immutable | |
data store. Such a store may not be modified through further calls to | |
BufferStorageExternalEXT, BufferStorageEXT, or BufferData. | |
<target> Specifies the target buffer object. The symbolic constant must be | |
one of the targets listed in table 6.1. <offset> and <size> specify, in | |
basic machine units, the range of the client buffer to be bound to the data | |
store. <offset> must be zero. | |
<clientBuffer> Is the handle of a valid EGLClientBuffer resource (cast | |
into type eglClientBufferEXT). The EGLClientBuffer must be allocated in a | |
platform-specific way which permits shared access. For example, on Android | |
via a sharable Android hardware buffer (struct AHardwareBuffer), converted | |
into EGLClientBuffer via extension EGL_ANDROID_get_native_client_buffer. | |
Other platforms would require a similar mechanism. This extension does not | |
enable support for arbitrary EGLClientBuffers to be used as a shared buffer. | |
<flags> is the bitwise OR of flags describing the intended usage of the buffer | |
object's external data store by the application. Valid flags and their | |
meanings are as described for BufferStorageEXT. | |
The values of the buffer object's state variables will match those for other | |
*BufferStorageEXT calls, as specified in table 6.3. | |
The behavior follows other immutable buffers; BufferStorageExternalEXT sets the | |
created buffer's BUFFER_IMMUTABLE_STORAGE_EXT to TRUE. | |
[[ The following is only added if GL_EXT_direct_state_access, | |
GL_ARB_direct_state_access, or OpenGL 4.5 is supported. ]] | |
The command | |
void NamedBufferStorageExternalEXT(uint buffer, intptr offset, | |
sizeiptr size, eglClientBufferEXT clientBuffer, | |
bitfield flags); | |
behaves similarly to BufferStorageExternalEXT, except that the buffer whose | |
storage is to be defined is specified by <buffer> rather than by the current | |
binding to <target>. | |
Errors | |
INVALID_OPERATION is generated by BufferStorageExternalEXT if zero is bound to | |
<target>. | |
INVALID_OPERATION is generated by BufferStorageExternalEXT, if the | |
BUFFER_IMMUTABLE_STORAGE flag of the buffer bound to <target> is TRUE. | |
INVALID_VALUE is generated by BufferStorageExternalEXT if <offset> is not 0. | |
INVALID_VALUE is generated by BufferStorageExternalEXT if <size> is 0 | |
or negative. | |
INVALID_VALUE is generated by BufferStorageExternalEXT if <offset> + <size> | |
exceeds the size of the EGLClientBuffer. | |
INVALID_VALUE is generated by BufferStorageExternalEXT if <flags> has any | |
bits set other than those defined above. | |
INVALID_VALUE is generated by BufferStorageExternalEXT if <flags> contains | |
MAP_PERSISTENT_BIT_EXT but does not contain at least one of MAP_READ_BIT or | |
MAP_WRITE_BIT. | |
INVALID_VALUE is generated by BufferStorageExternalEXT if <flags> contains | |
MAP_COHERENT_BIT_EXT, but does not also contain MAP_PERSISTENT_BIT_EXT. | |
INVALID_ENUM is generated by BufferStorageExternalEXT if <target> is not one | |
of the accepted buffer targets. | |
INVALID_OPERATION is generated by BufferStorageExternalEXT if the shared | |
buffer is not allocated in a way which permits shared access by the GPU. | |
[[ The following is only added if GL_EXT_direct_state_access or | |
GL_ARB_direct_state_access is supported. ]] | |
An INVALID_OPERATION error is generated by NamedBufferStorageExternalEXT if | |
the BUFFER_IMMUTABLE_STORAGE_EXT flag of <buffer> is set to TRUE. | |
Interactions with GL_EXT_direct_state_access, GL_ARB_direct_state_access and | |
OpenGL 4.5 | |
If none of GL_EXT_direct_state_access, GL_ARB_direct_state_access, or | |
OpenGL 4.5, the NamedBufferStorageExternalEXT entry-point is not | |
added and all references to it should be ignored. | |
Issues | |
1. How are possible GPU cache interactions handled? | |
The application is responsible for synchronizing writes to the shared buffer | |
by other processing cores (e.g. DSP), and making those available to CPU | |
reads for the processing of client-side GL commands (e.g., BufferSubData). | |
The GL implementation should guarantee that available writes by other cores | |
(e.g., DSP) are visible to the GPU when server-side commands read from the | |
shared buffer. | |
PROPOSED: The exact granularity with which available writes from other cores | |
e.g., DSP) become visible to the CPU and GPU is implementation dependent. | |
2. Should EGLClientBuffers, be directly referenced by the GL API? | |
For images, a set of EGL and client API extensions provide import/export | |
of EGLImages from client APIs and native buffers. The EGLImage also provides | |
lifetime guarantees including orphaning and sibling behavior. This extension | |
is more narrowly focused, specifically targeted to the import of EGLClientBuffers | |
as GL buffers, and requiring the application to manage the resource lifetime. | |
As such, it may not warrant a new EGL object or EGL extension. | |
RESOLVED: A corresponding EGL object and extension is not required. When | |
using this extension, applications are expected to cast EGLClientBuffer as | |
GLeglClientBufferEXT. | |
Revision History | |
Rev. Date Author Changes | |
---- ---------- -------- ----------------------------------------- | |
0.1 04/18/2017 sholmes Initial version. Based on QCOM_shared_buffer. | |
0.2 05/16/2017 jleger Renamed the extension and reworked it to to | |
be an extension to EXT_buffer_storage. | |
0.3 05/24/2017 jleger Add offset parameter and other cleanup. | |
0.4 05/25/2017 jleger Add DSA entrypoint and minor cleanup. | |
1.0 05/29/2017 dgkoch Add interactions with GL, minor cleanup. |