Mesa (master): egl: Add EGL_MESA_drm_image extension

Kristian Høgsberg krh at kemper.freedesktop.org
Wed Aug 25 13:20:48 UTC 2010


Module: Mesa
Branch: master
Commit: b7a8893a2413adfddf4dc836676a19463fb6ffd7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b7a8893a2413adfddf4dc836676a19463fb6ffd7

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Fri Jun  4 14:28:59 2010 -0400

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(+), 0 deletions(-)

diff --git a/docs/MESA_drm_image.spec b/docs/MESA_drm_image.spec
new file mode 100644
index 0000000..118501c
--- /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 <krh at 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.
diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index 171892c..0460393 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 c62459e..31c5419 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -894,6 +894,10 @@ eglGetProcAddress(const char *procname)
 #ifdef EGL_NOK_swap_region
       { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
 #endif
+#ifdef EGL_MESA_drm_image
+      { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
+      { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
+#endif
       { NULL, NULL }
    };
    EGLint i;
@@ -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 5045a9a..127becc 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 97c9d19..3863cce 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 b10783b..eb3dde1 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);




More information about the mesa-commit mailing list