Create EGLImages from DRM buffer handles.tags/mesa-7.9-rc1
@@ -0,0 +1,149 @@ | |||
Name | |||
MESA_drm_image | |||
Name Strings | |||
EGL_MESA_drm_image | |||
Contact | |||
Kristian Høgsberg <krh@bitplanet.net> | |||
Status | |||
Proposal | |||
Version | |||
Version 2, August 25, 2010 | |||
Number | |||
EGL Extension #not assigned | |||
Dependencies | |||
Reguires EGL 1.4 or later. This extension is written against the | |||
wording of the EGL 1.4 specification. | |||
EGL_KHR_base_image is required. | |||
Overview | |||
This extension provides entry points for integrating EGLImage with the | |||
Linux DRM mode setting and memory management drivers. The extension | |||
lets applications create EGLImages without a client API resource and | |||
lets the application get the DRM buffer handles. | |||
IP Status | |||
Open-source; freely implementable. | |||
New Procedures and Functions | |||
EGLImageKHR eglCreateDRMImageMESA(EGLDisplay dpy, | |||
const EGLint *attrib_list); | |||
EGLBoolean eglExportDRMImageMESA(EGLDisplay dpy, | |||
EGLImageKHR image, | |||
EGLint *name, | |||
EGLint *handle, | |||
EGLint *stride); | |||
New Tokens | |||
Accepted in the <attrib_list> parameter of eglCreateDRMImageMESA: | |||
EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 | |||
EGL_DRM_BUFFER_USE_MESA 0x31D1 | |||
Accepted as values for the EGL_IMAGE_FORMAT_MESA attribute: | |||
EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 | |||
Bits accepted in EGL_DRM_BUFFER_USE_MESA: | |||
EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x0001 | |||
EGL_DRM_BUFFER_USE_SHARE_MESA 0x0002 | |||
Accepted in the <target> parameter of eglCreateImageKHR: | |||
EGL_DRM_BUFFER_MESA 0x31D3 | |||
Use when importing drm buffer: | |||
EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 | |||
EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 | |||
Additions to the EGL 1.4 Specification: | |||
To create a DRM EGLImage, call | |||
EGLImageKHR eglCreateDRMImageMESA(EGLDisplay dpy, | |||
const EGLint *attrib_list); | |||
In the attribute list, pass EGL_WIDTH, EGL_EIGHT and format and | |||
use in the attrib list using EGL_DRM_BUFFER_FORMAT_MESA and | |||
EGL_DRM_BUFFER_USE_MESA. The only format specified by this | |||
extension is EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, where each pixel | |||
is a CPU-endian, 32-bit quantity, with alpha in the upper 8 bits, | |||
then red, then green, then blue. The bit values accepted by | |||
EGL_DRM_BUFFER_USE_MESA are EGL_DRM_BUFFER_USE_SCANOUT_MESA and | |||
EGL_DRM_BUFFER_USE_SHARE_MESA. EGL_DRM_BUFFER_USE_SCANOUT_MESA | |||
requests that the created EGLImage should be usable as a scanout | |||
buffer with the DRM kernel modesetting API. The | |||
EGL_DRM_BUFFER_USE_SHARE_MESA bit requests that the EGLImage can | |||
be shared with other processes by passing the underlying DRM | |||
buffer name. | |||
To create a process local handle or a global DRM name for a | |||
buffer, call | |||
EGLBoolean eglExportDRMImageMESA(EGLDisplay dpy, | |||
EGLImageKHR image, | |||
EGLint *name, | |||
EGLint *handle, | |||
EGLint *stride); | |||
If <name> is non-NULL, a global name is assigned to the image and | |||
written to <name>, the handle (local to the DRM file descriptor, | |||
for use with DRM kernel modesetting API) is written to <handle> if | |||
non-NULL and the stride (in bytes) is written to <stride>, if | |||
non-NULL. | |||
Import a shared buffer by calling eglCreateImageKHR with | |||
EGL_DRM_BUFFER_MESA as the target, using EGL_WIDTH, EGL_HEIGHT, | |||
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_STRIDE_MESA | |||
in the attrib list. | |||
Issues | |||
1. Why don't we use eglCreateImageKHR with a target that | |||
indicates that we want to create an EGLImage from scratch? | |||
RESOLVED: The eglCreateImageKHR entry point is reserved for | |||
creating an EGLImage from an already existing client API | |||
resource. This is fine when we're creating the EGLImage from | |||
an existing DRM buffer name, it doesn't seem right to overload | |||
the function to also allocate the underlying resource. | |||
2. Why don't we use an eglQueryImageMESA type functions for | |||
querying the DRM EGLImage attributes (name, handle, and stride)? | |||
RESOLVED: The eglQueryImage function has been proposed often, | |||
but it goes against the EGLImage design. EGLImages are opaque | |||
handles to a 2D array of pixels, which can be passed between | |||
client APIs. By referenceing an EGLImage in a client API, the | |||
EGLImage target (a texture, a renderbuffer or such) can be | |||
used to query the attributes of the EGLImage. We don't have a | |||
full client API for creating and querying DRM buffers, though, | |||
so we use a new EGL extension entry point instead. | |||
Revision History | |||
Version 1, June 3, 2010 | |||
Initial draft (Kristian Høgsberg) | |||
Version 2, August 25, 2010 | |||
Flesh out the extension a bit, add final EGL tokens, capture | |||
some of the original discussion in the issues section. |
@@ -120,6 +120,29 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGL | |||
#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */ | |||
#endif | |||
#ifndef EGL_MESA_drm_image | |||
#define EGL_MESA_drm_image 1 | |||
#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* eglCreateImageKHR attribute */ | |||
#define EGL_DRM_BUFFER_USE_MESA 0x31D1 | |||
/* EGL_DRM_BUFFER_FORMAT_MESA tokens */ | |||
#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 | |||
/* EGL_DRM_BUFFER_USE_MESA bits */ | |||
#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x0001 | |||
#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x0002 | |||
#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */ | |||
#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 /* eglCreateImageKHR attribute */ | |||
#ifdef EGL_EGLEXT_PROTOTYPES | |||
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attrib_list); | |||
EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); | |||
#endif | |||
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESA) (EGLDisplay dpy, const EGLint *attrib_list); | |||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); | |||
#endif | |||
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */ | |||
#ifndef EGL_KHR_reusable_sync | |||
#define EGL_KHR_reusable_sync 1 |
@@ -893,6 +893,10 @@ eglGetProcAddress(const char *procname) | |||
#endif /* EGL_KHR_image_base */ | |||
#ifdef EGL_NOK_swap_region | |||
{ "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, | |||
#endif | |||
#ifdef EGL_MESA_drm_image | |||
{ "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, | |||
{ "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, | |||
#endif | |||
{ NULL, NULL } | |||
}; | |||
@@ -1416,3 +1420,42 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, | |||
} | |||
#endif /* EGL_NOK_swap_region */ | |||
#ifdef EGL_MESA_drm_image | |||
EGLImageKHR EGLAPIENTRY | |||
eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) | |||
{ | |||
_EGLDisplay *disp = _eglLockDisplay(dpy); | |||
_EGLDriver *drv; | |||
_EGLImage *img; | |||
EGLImageKHR ret; | |||
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); | |||
img = drv->API.CreateDRMImageMESA(drv, disp, attr_list); | |||
ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR; | |||
RETURN_EGL_EVAL(disp, ret); | |||
} | |||
EGLBoolean EGLAPIENTRY | |||
eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, | |||
EGLint *name, EGLint *handle, EGLint *stride) | |||
{ | |||
_EGLDisplay *disp = _eglLockDisplay(dpy); | |||
_EGLImage *img = _eglLookupImage(image, disp); | |||
_EGLDriver *drv; | |||
EGLBoolean ret; | |||
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); | |||
if (!img) | |||
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); | |||
ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride); | |||
RETURN_EGL_EVAL(disp, ret); | |||
} | |||
#endif |
@@ -90,6 +90,11 @@ typedef EGLBoolean (*GetSyncAttribKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGL | |||
typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects); | |||
#endif | |||
#ifdef EGL_MESA_drm_image | |||
typedef _EGLImage *(*CreateDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attr_list); | |||
typedef EGLBoolean (*ExportDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *name, EGLint *handle, EGLint *stride); | |||
#endif | |||
/** | |||
* The API dispatcher jumps through these functions | |||
*/ | |||
@@ -159,6 +164,11 @@ struct _egl_api | |||
#ifdef EGL_NOK_swap_region | |||
SwapBuffersRegionNOK_t SwapBuffersRegionNOK; | |||
#endif | |||
#ifdef EGL_MESA_drm_image | |||
CreateDRMImageMESA_t CreateDRMImageMESA; | |||
ExportDRMImageMESA_t ExportDRMImageMESA; | |||
#endif | |||
}; | |||
#endif /* EGLAPI_INCLUDED */ |
@@ -54,6 +54,7 @@ struct _egl_extensions | |||
EGLBoolean MESA_screen_surface; | |||
EGLBoolean MESA_copy_context; | |||
EGLBoolean MESA_drm_display; | |||
EGLBoolean MESA_drm_image; | |||
EGLBoolean KHR_image_base; | |||
EGLBoolean KHR_image_pixmap; |
@@ -85,6 +85,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy) | |||
_EGL_CHECK_EXTENSION(MESA_screen_surface); | |||
_EGL_CHECK_EXTENSION(MESA_copy_context); | |||
_EGL_CHECK_EXTENSION(MESA_drm_display); | |||
_EGL_CHECK_EXTENSION(MESA_drm_image); | |||
_EGL_CHECK_EXTENSION(KHR_image_base); | |||
_EGL_CHECK_EXTENSION(KHR_image_pixmap); |