[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