[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