diff options
-rw-r--r-- | configure.ac | 27 | ||||
-rw-r--r-- | include/EGL/eglmesaext.h | 9 | ||||
-rw-r--r-- | src/egl/drivers/dri2/Makefile.am | 1 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 155 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.h | 5 | ||||
-rw-r--r-- | src/egl/main/eglimage.c | 8 | ||||
-rw-r--r-- | src/egl/main/eglimage.h | 4 |
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; }; /** |