summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac27
-rw-r--r--include/EGL/eglmesaext.h9
-rw-r--r--src/egl/drivers/dri2/Makefile.am1
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c155
-rw-r--r--src/egl/drivers/dri2/egl_dri2.h5
-rw-r--r--src/egl/main/eglimage.c8
-rw-r--r--src/egl/main/eglimage.h4
7 files changed, 209 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 89686b47fc..a177abe4fd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -604,6 +604,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@:>@])],
@@ -1558,6 +1563,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
@@ -2252,6 +2278,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 d476d18a27..82b56525db 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/src/egl/drivers/dri2/Makefile.am b/src/egl/drivers/dri2/Makefile.am
index 49ec06bbec..c11ee3c02b 100644
--- a/src/egl/drivers/dri2/Makefile.am
+++ b/src/egl/drivers/dri2/Makefile.am
@@ -30,6 +30,7 @@ AM_CFLAGS = \
$(DEFINES) \
$(LIBDRM_CFLAGS) \
$(LIBUDEV_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 464f76850f..fb9f91e0ed 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1175,6 +1175,157 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
}
#endif
+#ifdef HAVE_VA_EGL_INTEROP
+/* Ensure the DRIimage is attached to the VA/EGL client buffer */
+static __DRIimage *
+dri2_va_reference_buffer(_EGLDisplay *disp, struct va_egl_client_buffer *buffer)
+{
+ struct dri2_egl_display * const dri2_dpy = dri2_egl_display(disp);
+ int format, stride;
+
+ switch (buffer->format) {
+ case VA_EGL_PIXEL_FORMAT_ARGB8888:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ stride = buffer->pitches[0] / 4;
+ break;
+ case VA_EGL_PIXEL_FORMAT_XRGB8888:
+ format = __DRI_IMAGE_FORMAT_XRGB8888;
+ stride = buffer->pitches[0] / 4;
+ break;
+ case VA_EGL_PIXEL_FORMAT_ABGR8888:
+ format = __DRI_IMAGE_FORMAT_ABGR8888;
+ stride = buffer->pitches[0] / 4;
+ break;
+ case VA_EGL_PIXEL_FORMAT_NV12:
+ case VA_EGL_PIXEL_FORMAT_YUV410P:
+ case VA_EGL_PIXEL_FORMAT_YUV411P:
+ case VA_EGL_PIXEL_FORMAT_YUV420P:
+ case VA_EGL_PIXEL_FORMAT_YUV422P:
+ case VA_EGL_PIXEL_FORMAT_YUV444P:
+ format = __DRI_IMAGE_FORMAT_NONE;
+ stride = buffer->pitches[0];
+ break;
+ default:
+ _eglLog(_EGL_DEBUG, "DRI2-VA: failed to validate pixel format %d",
+ buffer->format);
+ return NULL;
+ }
+ return dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
+ buffer->width,
+ buffer->height,
+ format,
+ buffer->handle,
+ stride,
+ NULL);
+}
+
+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);
+ struct va_egl_client_buffer *buffer = _buffer;
+ const struct dri_image_descriptor *desc;
+ __DRIimage *dri_image;
+ _EGLImageAttribs attrs;
+ EGLint plane, width, height, stride, cpp, offset, err;
+ uint32_t structure, format;
+
+ if (!buffer || buffer->version != VA_EGL_CLIENT_BUFFER_VERSION) {
+ _eglError(EGL_BAD_PARAMETER, "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;
+ }
+
+ structure = attrs.VABufferStructureINTEL;
+ if (structure && structure != buffer->structure) {
+ _eglError(EGL_BAD_PARAMETER,
+ "DRI2-VA: buffer structure coercition is not supported yet");
+ return NULL;
+ }
+
+ structure = attrs.VAPictureStructureINTEL;
+ if (structure != VA_EGL_PICTURE_STRUCTURE_FRAME) {
+ _eglError(EGL_BAD_PARAMETER,
+ "DRI2-VA: interlaced picture structure is not supported yet");
+ return NULL;
+ }
+
+ dri_image = buffer->private_data;
+ if (!dri_image) {
+ dri_image = dri2_va_reference_buffer(disp, buffer);
+ if (!dri_image) {
+ _eglError(EGL_BAD_ALLOC, "DRI2-VA: could not reference VA buffer");
+ return NULL;
+ }
+ buffer->private_data = dri_image;
+ buffer->destroy_private_data =
+ (void (*)(void *))dri2_dpy->image->destroyImage;
+ }
+
+ switch (buffer->format) {
+ case VA_EGL_PIXEL_FORMAT_ARGB8888:
+ desc = &dri_image_desc_ARGB8888;
+ break;
+ case VA_EGL_PIXEL_FORMAT_XRGB8888:
+ desc = &dri_image_desc_XRGB8888;
+ break;
+ case VA_EGL_PIXEL_FORMAT_NV12:
+ desc = &dri_image_desc_NV12;
+ break;
+ case VA_EGL_PIXEL_FORMAT_YUV420P:
+ desc = &dri_image_desc_YUV420;
+ break;
+ case VA_EGL_PIXEL_FORMAT_YUV422P:
+ desc = &dri_image_desc_YUV422;
+ break;
+ case VA_EGL_PIXEL_FORMAT_YUV444P:
+ desc = &dri_image_desc_YUV444;
+ break;
+ default:
+ desc = NULL;
+ break;
+ }
+ if (!desc) {
+ _eglError(EGL_BAD_PARAMETER, "DRI2-VA: unsupported pixel format");
+ return NULL;
+ }
+
+ if (plane >= desc->nplanes) {
+ _eglError(EGL_BAD_PARAMETER, "DRI2-VA: invalid plane index");
+ return NULL;
+ }
+
+ format = desc->planes[plane].dri_format;
+ width = buffer->width >> desc->planes[plane].width_shift;
+ height = buffer->height >> desc->planes[plane].height_shift;
+ stride = buffer->pitches[plane];
+ cpp = desc->planes[plane].cpp;
+ offset = buffer->offsets[plane];
+
+ dri_image = dri2_dpy->image->createSubImage(dri_image, width, height,format,
+ offset, stride / cpp, 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,
@@ -1191,6 +1342,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/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index c30e2305d8..48d958e435 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -44,6 +44,11 @@
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
+#ifdef HAVE_VA_EGL_INTEROP
+# include <va/va_egl.h>
+# include <va/va_backend_egl.h>
+#endif
+
#ifdef HAVE_DRM_PLATFORM
#include <gbm_driint.h>
#endif
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index bfae709bb3..0ffe673c0a 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 9cc86d58b2..d1d163b110 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;
};
/**