Signed-off-by: Gwenole Beauchesne <gwenole.beauche...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev