[Mesa-dev] [PATCH] [RFC] egl: propose simple EGL_MESA_image_dma_buf_export v2

Dave Airlie airlied at gmail.com
Mon Mar 2 19:57:08 PST 2015


From: Dave Airlie <airlied at redhat.com>

At the moment to get an EGL image to a dma-buf file descriptor,
you have to use EGL_MESA_drm_image, and then use libdrm to
convert this to a file descriptor.

This extension just provides an API modelled on EGL_MESA_drm_image,
to return a dma-buf file descriptor.

v2: update spec for new API proposal
add internal queries to get the fourcc back from intel driver.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 docs/specs/MESA_image_dma_buf_export.txt | 89 ++++++++++++++++++++++++++++++++
 include/EGL/eglmesaext.h                 |  5 ++
 include/GL/internal/dri_interface.h      |  4 +-
 src/egl/drivers/dri2/egl_dri2.c          | 50 +++++++++++++++++-
 src/egl/main/eglapi.c                    | 46 +++++++++++++++++
 src/egl/main/eglapi.h                    | 10 ++++
 src/egl/main/egldisplay.h                |  2 +
 src/egl/main/eglfallbacks.c              |  5 ++
 src/egl/main/eglmisc.c                   |  2 +
 src/mesa/drivers/dri/i965/intel_screen.c | 25 ++++++++-
 10 files changed, 234 insertions(+), 4 deletions(-)
 create mode 100644 docs/specs/MESA_image_dma_buf_export.txt

diff --git a/docs/specs/MESA_image_dma_buf_export.txt b/docs/specs/MESA_image_dma_buf_export.txt
new file mode 100644
index 0000000..3d737c6
--- /dev/null
+++ b/docs/specs/MESA_image_dma_buf_export.txt
@@ -0,0 +1,89 @@
+Name
+
+    MESA_image_dma_buf_export
+
+Name Strings
+
+    EGL_MESA_image_dma_buf_export
+
+Contact
+
+    Dave Airlie <airlied at redhat.com>
+
+Status
+
+    Proposal
+
+Version
+
+    Version 2
+
+Number
+
+ <unnumbered>
+
+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
+    dma-buf infrastructure.  The extension lets the application get a file descriptor
+    corresponding to an EGL image.
+
+    It is designed to provide the opposing functionality to EGL_EXT_image_dma_buf_import.
+
+IP Status
+
+    Open-source; freely implementable.
+
+New Procedures and Functions
+
+    EGLBoolean eglExportDMABUFImageQueryMESA(EGLDisplay dpy,
+                                  EGLImageKHR image,
+				  int *fourcc,
+				  int *num_planes);
+
+    EGLBoolean eglExportDMABUFImageMESA(EGLDisplay dpy,
+                                        EGLImageKHR image,
+                                        int *fd,
+ 				        EGLint *stride);
+
+New Tokens
+
+
+Additions to the EGL 1.4 Specification:
+
+    To create a global passable file descriptior for a buffer, call
+
+       EGLBoolean eglExportDMABUFImageQueryMESA(EGLDisplay dpy,
+                                  EGLImageKHR image,
+				  int *fourcc,
+				  int *num_planes);
+
+    to retrieve the drm_fourcc code, and number of planes in the image.
+
+    Then call, passing an array of fd, stride sized to the number of planes.
+    
+        EGLBoolean eglExportDMABUFImageMESA(EGLDisplay dpy,
+                                         EGLImageKHR image,
+					 int *fd,
+                                         EGLint *stride);
+
+    If <fd> is non-NULL, a global file descriptor per plane is assigned to the
+    image and written to the array of ints <fd>, and the stride of each plane (in bytes) is written to <stride>, if non-NULL.
+
+Issues
+
+
+Revision History
+
+    Version 2, March, 2015
+        Add a query interface (Dave Airlie)
+    Version 1, June 3, 2014
+        Initial draft (Dave Airlie)
+
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index 5fcc527..575f438 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -170,6 +170,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
 #define EGL_NO_CONFIG_MESA			((EGLConfig)0)
 #endif
 
+#ifndef EGL_MESA_image_dma_buf_export
+#define EGL_MESA_image_dma_buf_export 1
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *fourcc, EGLint *nplanes);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fd, EGLint *stride);
+#endif
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 1d670b1..eb7da23 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1006,7 +1006,7 @@ struct __DRIdri2ExtensionRec {
  * extensions.
  */
 #define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 10
+#define __DRI_IMAGE_VERSION 11
 
 /**
  * These formats correspond to the similarly named MESA_FORMAT_*
@@ -1097,6 +1097,8 @@ struct __DRIdri2ExtensionRec {
 #define __DRI_IMAGE_ATTRIB_FD           0x2007 /* available in versions
                                                 * 7+. Each query will return a
                                                 * new fd. */
+#define __DRI_IMAGE_ATTRIB_FOURCC       0x2008 /* available in versions 11 */
+#define __DRI_IMAGE_ATTRIB_NUM_PLANES   0x2009 /* available in versions 11 */
 
 enum __DRIYUVColorSpace {
    __DRI_YUV_COLOR_SPACE_UNDEFINED = 0,
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 6306483..35b02fe 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -524,8 +524,14 @@ dri2_setup_screen(_EGLDisplay *disp)
 
          capabilities = dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
          disp->Extensions.MESA_drm_image = (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0;
-      } else
+
+         if (dri2_dpy->image->base.version >= 11)
+            disp->Extensions.MESA_image_dma_buf_export = EGL_TRUE;
+      } else {
          disp->Extensions.MESA_drm_image = EGL_TRUE;
+         if (dri2_dpy->image->base.version >= 11)
+            disp->Extensions.MESA_image_dma_buf_export = EGL_TRUE;
+      }
 
       disp->Extensions.KHR_image_base = EGL_TRUE;
       disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
@@ -1964,6 +1970,46 @@ dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img,
 
    return EGL_TRUE;
 }
+
+static EGLBoolean
+dri2_export_dma_buf_image_query_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img,
+                                     EGLint *fourcc, EGLint *nplanes)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+
+   (void) drv;
+
+
+   if (nplanes)
+      dri2_dpy->image->queryImage(dri2_img->dri_image,
+				  __DRI_IMAGE_ATTRIB_NUM_PLANES, nplanes);
+   if (fourcc)
+      dri2_dpy->image->queryImage(dri2_img->dri_image,
+				  __DRI_IMAGE_ATTRIB_FOURCC, fourcc);
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+dri2_export_dma_buf_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img,
+                               int *fd, EGLint *stride)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+
+   (void) drv;
+
+   if (fd)
+      dri2_dpy->image->queryImage(dri2_img->dri_image,
+				  __DRI_IMAGE_ATTRIB_FD, fd);
+
+   if (stride)
+      dri2_dpy->image->queryImage(dri2_img->dri_image,
+				  __DRI_IMAGE_ATTRIB_STRIDE, stride);
+
+   return EGL_TRUE;
+}
 #endif
 
 #ifdef HAVE_WAYLAND_PLATFORM
@@ -2218,6 +2264,8 @@ _eglBuiltInDriverDRI2(const char *args)
 #ifdef HAVE_LIBDRM
    dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa;
    dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa;
+   dri2_drv->base.API.ExportDMABUFImageQueryMESA = dri2_export_dma_buf_image_query_mesa;
+   dri2_drv->base.API.ExportDMABUFImageMESA = dri2_export_dma_buf_image_mesa;
 #endif
 #ifdef HAVE_WAYLAND_PLATFORM
    dri2_drv->base.API.BindWaylandDisplayWL = dri2_bind_wayland_display_wl;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index db44a26..6ea9b49 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -1114,6 +1114,10 @@ eglGetProcAddress(const char *procname)
       { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
       { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
       { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
+#ifdef EGL_MESA_drm_buf_image_export
+      { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
+      { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
+#endif
       { NULL, NULL }
    };
    EGLint i;
@@ -1801,3 +1805,45 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
 
    RETURN_EGL_EVAL(disp, ret);
 }
+
+#ifdef EGL_MESA_image_dma_buf_export
+EGLBoolean EGLAPIENTRY
+eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
+                              EGLint *fourcc, EGLint *nplanes)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLImage *img = _eglLookupImage(image, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   assert(disp->Extensions.MESA_image_dma_buf_export);
+
+   if (!img)
+      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+   ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+EGLBoolean EGLAPIENTRY
+eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image,
+                         int *fd, EGLint *stride)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLImage *img = _eglLookupImage(image, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   assert(disp->Extensions.MESA_image_dma_buf_export);
+
+   if (!img)
+      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+   ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fd, stride);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+#endif
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index cb01cab..b5ec852 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -141,6 +141,11 @@ typedef EGLBoolean (*SwapBuffersWithDamageEXT_t) (_EGLDriver *drv, _EGLDisplay *
 
 typedef EGLBoolean (*GetSyncValuesCHROMIUM_t) (_EGLDisplay *dpy, _EGLSurface *surface, EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc);
 
+#ifdef EGL_MESA_image_dma_buf_export
+typedef EGLBoolean (*ExportDMABUFImageQueryMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *fourcc, EGLint *stride);
+typedef EGLBoolean (*ExportDMABUFImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, int *fd, EGLint *stride);
+#endif
+
 /**
  * The API dispatcher jumps through these functions
  */
@@ -228,6 +233,11 @@ struct _egl_api
 
    QueryBufferAge_t QueryBufferAge;
    GetSyncValuesCHROMIUM_t GetSyncValuesCHROMIUM;
+
+#ifdef EGL_MESA_image_dma_buf_export
+   ExportDMABUFImageQueryMESA_t ExportDMABUFImageQueryMESA;
+   ExportDMABUFImageMESA_t ExportDMABUFImageMESA;
+#endif
 };
 
 #endif /* EGLAPI_INCLUDED */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index bcdc2b2..8581cb2 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -123,6 +123,8 @@ struct _egl_extensions
    EGLBoolean EXT_buffer_age;
    EGLBoolean EXT_swap_buffers_with_damage;
    EGLBoolean EXT_image_dma_buf_import;
+
+   EGLBoolean MESA_image_dma_buf_export;
 };
 
 
diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c
index 0b70e92..6127426 100644
--- a/src/egl/main/eglfallbacks.c
+++ b/src/egl/main/eglfallbacks.c
@@ -120,4 +120,9 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
 #ifdef EGL_NOK_swap_region
    drv->API.SwapBuffersRegionNOK = NULL;
 #endif
+
+#ifdef EGL_MESA_dma_buf_image_export
+   drv->API.ExportDMABUFImageQueryMESA = NULL;
+   drv->API.ExportDMABUFImageMESA = NULL;
+#endif
 }
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 2f49809..7837684 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -126,6 +126,8 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
 
    _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
+
+   _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
 #undef _EGL_CHECK_EXTENSION
 }
 
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index cea7ddf..39e8eaf 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -300,6 +300,17 @@ intel_image_format_lookup(int fourcc)
    return f;
 }
 
+static boolean intel_lookup_fourcc(int dri_format, int *fourcc)
+{
+   for (unsigned i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
+      if (intel_image_formats[i].planes[0].dri_format == dri_format) {
+         *fourcc = intel_image_formats[i].fourcc;
+         return true;
+      }
+   }
+   return false;
+}
+
 static __DRIimage *
 intel_allocate_image(int dri_format, void *loaderPrivate)
 {
@@ -559,6 +570,14 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
       if (drm_intel_bo_gem_export_to_prime(image->bo, value) == 0)
          return true;
       return false;
+   case __DRI_IMAGE_ATTRIB_FOURCC:
+      if (intel_lookup_fourcc(image->dri_format, value))
+         return true;
+      return false;
+   case __DRI_IMAGE_ATTRIB_NUM_PLANES:
+      *value = 1;
+      return true;
+
   default:
       return false;
    }
@@ -784,7 +803,7 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
 }
 
 static const __DRIimageExtension intelImageExtension = {
-    .base = { __DRI_IMAGE, 8 },
+    .base = { __DRI_IMAGE, 11 },
 
     .createImageFromName                = intel_create_image_from_name,
     .createImageFromRenderbuffer        = intel_create_image_from_renderbuffer,
@@ -797,7 +816,9 @@ static const __DRIimageExtension intelImageExtension = {
     .fromPlanar                         = intel_from_planar,
     .createImageFromTexture             = intel_create_image_from_texture,
     .createImageFromFds                 = intel_create_image_from_fds,
-    .createImageFromDmaBufs             = intel_create_image_from_dma_bufs
+    .createImageFromDmaBufs             = intel_create_image_from_dma_bufs,
+    .blitImage                          = NULL,
+    .getCapabilities                    = NULL
 };
 
 static int
-- 
2.1.0



More information about the mesa-dev mailing list