From b7a8893a2413adfddf4dc836676a19463fb6ffd7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 4 Jun 2010 14:28:59 -0400 Subject: [PATCH] egl: Add EGL_MESA_drm_image extension Create EGLImages from DRM buffer handles. --- docs/MESA_drm_image.spec | 149 ++++++++++++++++++++++++++++++++++++++ include/EGL/eglext.h | 23 ++++++ src/egl/main/eglapi.c | 43 +++++++++++ src/egl/main/eglapi.h | 10 +++ src/egl/main/egldisplay.h | 1 + src/egl/main/eglmisc.c | 1 + 6 files changed, 227 insertions(+) create mode 100644 docs/MESA_drm_image.spec diff --git a/docs/MESA_drm_image.spec b/docs/MESA_drm_image.spec new file mode 100644 index 00000000000..118501c3d3e --- /dev/null +++ b/docs/MESA_drm_image.spec @@ -0,0 +1,149 @@ +Name + + MESA_drm_image + +Name Strings + + EGL_MESA_drm_image + +Contact + + Kristian Høgsberg + +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 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 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 is non-NULL, a global name is assigned to the image and + written to , the handle (local to the DRM file descriptor, + for use with DRM kernel modesetting API) is written to if + non-NULL and the stride (in bytes) is written to , 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. diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h index 171892c93ea..04603931b38 100644 --- a/include/EGL/eglext.h +++ b/include/EGL/eglext.h @@ -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 diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index c62459ec6fb..31c5419bbc3 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -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 diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index 5045a9a272f..127becc9acd 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -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 */ diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 97c9d196ec4..3863cce0108 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -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; diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c index b10783bcb96..eb3dde1fb48 100644 --- a/src/egl/main/eglmisc.c +++ b/src/egl/main/eglmisc.c @@ -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); -- 2.30.2