[Mesa-dev] [PATCH v2 1/2] egl: add initial implementation for VA/EGL interop.

Gwenole Beauchesne gb.devel at gmail.com
Fri Sep 14 06:12:58 PDT 2012


Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
 configure.ac                        |   27 ++++++++++++++++++++
 include/EGL/eglmesaext.h            |    9 +++++++
 include/GL/internal/dri_interface.h |   30 ++++++++++++++++++++++-
 src/egl/drivers/dri2/Makefile.am    |    1 +
 src/egl/drivers/dri2/egl_dri2.c     |   46 +++++++++++++++++++++++++++++++++++
 src/egl/main/eglimage.c             |    8 ++++++
 src/egl/main/eglimage.h             |    4 +++
 7 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 4193496..3ed24c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -595,6 +595,11 @@ AC_ARG_ENABLE([va],
          [enable va library @<:@default=auto@:>@])],
    [enable_va="$enableval"],
    [enable_va=auto])
+AC_ARG_ENABLE([vaapi],
+   [AS_HELP_STRING([--enable-vaapi-egl],
+         [enable VA/EGL interop @<:@default=auto@:>@])],
+   [enable_vaapi_egl="$enableval"],
+   [enable_vaapi_egl=yes])
 AC_ARG_ENABLE([opencl],
    [AS_HELP_STRING([--enable-opencl],
          [enable OpenCL library @<:@default=no@:>@])],
@@ -1426,6 +1431,27 @@ if test "x$enable_va" = xyes; then
 fi
 
 dnl
+dnl VA-API / EGL interop
+dnl
+
+if test "x$enable_egl" != xyes; then
+    enable_vaapi_egl="no"
+fi
+if test "x$enable_vaapi_egl" = xyes; then
+    PKG_CHECK_MODULES([LIBVA_EGL], [libva-egl], [:], [enable_vaapi_egl="no"])
+fi
+if test "x$enable_vaapi_egl" = xyes; then
+    saved_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $LIBVA_EGL_CFLAGS"
+    AC_CHECK_HEADERS([va/va_egl.h], [:], [enable_vaapi_egl="no"])
+    AC_CHECK_HEADERS([va/va_backend_egl.h], [:], [enable_vaapi_egl="no"])
+    CPPFLAGS="$saved_CPPFLAGS"
+fi
+if test "x$enable_vaapi_egl" = xyes; then
+    DEFINES="$DEFINES -DHAVE_VA_EGL_INTEROP"
+fi
+
+dnl
 dnl OpenCL configuration
 dnl
 
@@ -2069,6 +2095,7 @@ if test "$enable_egl" = yes; then
     else
         echo "        EGL drivers:    $egl_drivers"
     fi
+    echo "        VA/EGL interop:  $enable_vaapi_egl"
 fi
 
 echo ""
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index d476d18..82b5652 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -153,6 +153,15 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
 #define EGL_NATIVE_BUFFER_ANDROID       0x3140  /* eglCreateImageKHR target */
 #endif
 
+#ifndef EGL_INTEL_VA_pixel_buffer
+#define EGL_INTEL_VA_pixel_buffer 1
+
+#define EGL_VA_PIXEL_BUFFER_INTEL       0x31DB /* eglCreateImageKHR target */
+#define EGL_VA_BUFFER_PLANE_INTEL       0x31D6 /* eglCreateImageKHR attribute */
+#define EGL_VA_BUFFER_STRUCTURE_INTEL   0x3080 /* eglCreateImageKHR attribute */
+#define EGL_VA_PICTURE_STRUCTURE_INTEL  0x31DA /* eglCreateImageKHR attribute */
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 1e0f1d0..1a6cf0a 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -912,7 +912,7 @@ struct __DRIdri2ExtensionRec {
  * extensions.
  */
 #define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 5
+#define __DRI_IMAGE_VERSION 6
 
 /**
  * These formats correspond to the similarly named MESA_FORMAT_*
@@ -1061,6 +1061,34 @@ struct __DRIimageExtensionRec {
     */
     __DRIimage *(*fromPlanar)(__DRIimage *image, int plane,
                               void *loaderPrivate);
+
+   /**
+    * Create an image out of a VA/EGL buffer. This entry-point lets us create
+    * individual __DRIimages for different planes in a planar buffer, similar
+    * to fromPlanar(), but with a VA/EGL buffer as source.
+    *
+    * Buffer structure, if non-zero, specifies the desired sampling from the
+    * client application. e.g. if a YUV surface was provided but
+    * @buffer_structure is VA_EGL_BUFFER_STRUCTURE_RGBA, this means the user
+    * would like to get RGBA samples from the YUV surface, i.e. color space
+    * conversion is to be performed by the underlying hardware without shader
+    * code. If the hardware does not support this capability, the function
+    * shall return NULL, thus indicating to client application that a planar
+    * format should be tried instead and suitable shader code provided.
+    *
+    * Picture structure represents the full frame (default, if zero), the top
+    * or the bottom field for interlaced surfaces. Note that for those two
+    * modes, this basically actually means whether to render every other line
+    * or not. If not proper hardware function supports that capability, or
+    * that using double stride and half height doesn't work, then this
+    * entry-point shall return NULL.
+    *
+    * \since 6
+    */
+    __DRIimage *(*createImageFromVABuffer)(__DRIscreen *screen, void *buffer,
+                                           int buffer_structure, int plane,
+                                           int picture_structure,
+                                           void *loaderPrivate);
 };
 
 
diff --git a/src/egl/drivers/dri2/Makefile.am b/src/egl/drivers/dri2/Makefile.am
index 45f7dfa..8bc6b4c 100644
--- a/src/egl/drivers/dri2/Makefile.am
+++ b/src/egl/drivers/dri2/Makefile.am
@@ -31,6 +31,7 @@ AM_CFLAGS = \
 	$(LIBDRM_CFLAGS) \
 	$(LIBUDEV_CFLAGS) \
 	$(LIBKMS_CFLAGS) \
+	$(LIBVA_EGL_CFLAGS) \
 	-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\"
 
 noinst_LTLIBRARIES = libegl_dri2.la
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 4b58c35..71707eb 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1145,6 +1145,48 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
 }
 #endif
 
+#ifdef HAVE_VA_EGL_INTEROP
+static _EGLImage *
+dri2_create_image_va_pixel_buffer(_EGLDisplay *disp, _EGLContext *ctx,
+                                  EGLClientBuffer buffer,
+                                  const EGLint *attr_list)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   __DRIimage *dri_image;
+   _EGLImageAttribs attrs;
+   EGLint plane, err;
+
+   if (dri2_dpy->image->base.version < 6)
+      return NULL;
+   if (!dri2_dpy->image->createImageFromVABuffer) {
+      _eglError(EGL_BAD_DISPLAY, "DRI2-VA: unsupported EGLClientBuffer");
+      return NULL;
+   }
+
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS) {
+      _eglError(EGL_BAD_PARAMETER,
+                "DRI2-VA: failed to parse eglCreateImageKHR() attributes");
+      return NULL;
+   }
+
+   plane = attrs.PlaneWL;
+   if (plane < 0) {
+      _eglError(EGL_BAD_PARAMETER, "DRI2-VA: got negative plane value");
+      return NULL;
+   }
+
+   dri_image = dri2_dpy->image->createImageFromVABuffer(dri2_dpy->dri_screen,
+      buffer, attrs.VABufferStructureINTEL, plane,
+      attrs.VAPictureStructureINTEL, NULL);
+   if (!dri_image) {
+      _eglError(EGL_BAD_ALLOC, "DRI2-VA: could not create sub-buffer");
+      return NULL;
+   }
+   return dri2_create_image(disp, dri_image);
+}
+#endif
+
 _EGLImage *
 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
 		      _EGLContext *ctx, EGLenum target,
@@ -1161,6 +1203,10 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
    case EGL_WAYLAND_BUFFER_WL:
       return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
 #endif
+#ifdef HAVE_VA_EGL_INTEROP
+   case EGL_VA_PIXEL_BUFFER_INTEL:
+      return dri2_create_image_va_pixel_buffer(disp, ctx, buffer, attr_list);
+#endif
    default:
       _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
       return EGL_NO_IMAGE_KHR;
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index bfae709..0ffe673 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -93,6 +93,14 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
          attrs->PlaneWL = val;
          break;
 
+      /* EGL_INTEL_VA_pixel_buffer */
+      case EGL_VA_BUFFER_STRUCTURE_INTEL:
+         attrs->VABufferStructureINTEL = val;
+         break;
+      case EGL_VA_PICTURE_STRUCTURE_INTEL:
+         attrs->VAPictureStructureINTEL = val;
+         break;
+
       default:
          /* unknown attrs are ignored */
          break;
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 9cc86d5..d1d163b 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -53,6 +53,10 @@ struct _egl_image_attribs
 
    /* EGL_WL_bind_wayland_display */
    EGLint PlaneWL;
+
+   /* EGL_INTEL_VA_pixel_buffer */
+   EGLint VABufferStructureINTEL;
+   EGLint VAPictureStructureINTEL;
 };
 
 /**
-- 
1.7.9.5



More information about the mesa-dev mailing list