diff options
author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-07-09 17:33:31 +0200 |
---|---|---|
committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-07-13 15:33:11 +0200 |
commit | da711e5f642cf7421e83fe711192b6c4e3a05aeb (patch) | |
tree | 8a81dd5bfa8cf24cb77aaa3d729c9ed4d0d23b9a | |
parent | 560ab2c9b116ddaddd90c24f520c4dc66310c9e7 (diff) |
Implement new VA/EGL API.staging.13.egl-r1
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r-- | configure.ac | 18 | ||||
-rwxr-xr-x | src/Makefile.am | 5 | ||||
-rwxr-xr-x | src/i965_drv_video.c | 27 | ||||
-rw-r--r-- | src/i965_drv_video.h | 2 | ||||
-rw-r--r-- | src/i965_output_egl.c | 298 | ||||
-rw-r--r-- | src/i965_output_egl.h | 40 |
6 files changed, 390 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index 1093ba0..5cc8c41 100644 --- a/configure.ac +++ b/configure.ac @@ -41,6 +41,11 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [ AC_SUBST(AM_DEFAULT_VERBOSITY) ]) +AC_ARG_ENABLE(egl, + [AC_HELP_STRING([--enable-egl], + [build with VA/EGL API support @<:@default=yes@:>@])], + [], [enable_egl="yes"]) + AC_DISABLE_STATIC AC_PROG_LIBTOOL AC_PROG_CC @@ -81,6 +86,15 @@ VA_DRIVER_INIT_FUNC="__vaDriverInit_${VA_MAJOR_VERSION}_${VA_MINOR_VERSION}" AC_DEFINE_UNQUOTED([VA_DRIVER_INIT_FUNC], [$VA_DRIVER_INIT_FUNC], [Define driver entry-point]) +dnl Check for VA/EGL API +USE_EGL="$enable_egl" +if test "$USE_EGL" = "yes"; then + PKG_CHECK_MODULES(LIBVA_EGL_DEPS, [libva-egl], + [AC_DEFINE([HAVE_VA_EGL], [1], [Defined to 1 if VA/EGL API is enabled])], + [USE_EGL="no"]) +fi +AM_CONDITIONAL(USE_EGL, test "$USE_EGL" = "yes") + dnl Check for VA-API drivers path AC_MSG_CHECKING([for VA drivers path]) LIBVA_DRIVERS_PATH=`$PKG_CONFIG libva --variable driverdir` @@ -109,9 +123,13 @@ AC_OUTPUT([ ]) dnl Print summary +VIDEO_OUTPUTS="" +AS_IF([test "$USE_EGL" = "yes"], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS egl"]) + echo echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR echo VA-API drivers path .............. : $LIBVA_DRIVERS_PATH +echo Video outputs .................... : $VIDEO_OUTPUTS echo diff --git a/src/Makefile.am b/src/Makefile.am index b8cc501..b12033e 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,6 +102,11 @@ source_h = \ object_heap.h \ $(NULL) +if USE_EGL +source_c += i965_output_egl.c +source_h += i965_output_egl.h +endif + i965_drv_video_la_LTLIBRARIES = i965_drv_video.la i965_drv_video_ladir = $(LIBVA_DRIVERS_PATH) i965_drv_video_la_CFLAGS = $(driver_cflags) diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index 41f8b0f..0666fbb 100755 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -44,6 +44,10 @@ #include "i965_defines.h" #include "i965_drv_video.h" +#ifdef HAVE_VA_EGL +# include "i965_output_egl.h" +#endif + #define CONFIG_ID_OFFSET 0x01000000 #define CONTEXT_ID_OFFSET 0x02000000 #define SURFACE_ID_OFFSET 0x04000000 @@ -552,6 +556,13 @@ i965_destroy_surface(struct object_heap *heap, struct object_base *obj) { struct object_surface *obj_surface = (struct object_surface *)obj; +#ifdef HAVE_VA_EGL + if (obj_surface->egl_client_buffer) { + i965_destroy_egl_client_buffer(obj_surface->egl_client_buffer); + obj_surface->egl_client_buffer = NULL; + } +#endif + dri_bo_unreference(obj_surface->bo); obj_surface->bo = NULL; @@ -1991,6 +2002,11 @@ i965_Init(VADriverContextP ctx) if (i965_render_init(ctx) == False) return VA_STATUS_ERROR_UNKNOWN; +#ifdef HAVE_VA_EGL + if (!i965_output_egl_init(ctx)) + return VA_STATUS_ERROR_UNKNOWN; +#endif + _i965InitMutex(&i965->render_mutex); _i965InitMutex(&i965->pp_mutex); @@ -2476,6 +2492,13 @@ i965_DestroyImage(VADriverContextP ctx, VAImageID image) if (!obj_image) return VA_STATUS_SUCCESS; +#ifdef HAVE_VA_EGL + if (obj_image->egl_client_buffer) { + i965_destroy_egl_client_buffer(obj_image->egl_client_buffer); + obj_image->egl_client_buffer = NULL; + } +#endif + dri_bo_unreference(obj_image->bo); obj_image->bo = NULL; @@ -3377,6 +3400,10 @@ i965_Terminate(VADriverContextP ctx) _i965DestroyMutex(&i965->pp_mutex); _i965DestroyMutex(&i965->render_mutex); +#ifdef HAVE_VA_EGL + i965_output_egl_terminate(ctx); +#endif + if (i965_render_terminate(ctx) == False) return VA_STATUS_ERROR_UNKNOWN; diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h index e40e9b4..f8913f7 100644 --- a/src/i965_drv_video.h +++ b/src/i965_drv_video.h @@ -209,6 +209,7 @@ struct object_surface int cb_cr_width; int cb_cr_height; int cb_cr_pitch; + struct va_egl_client_buffer *egl_client_buffer; }; struct object_buffer @@ -228,6 +229,7 @@ struct object_image dri_bo *bo; unsigned int *palette; VASurfaceID derived_surface; + struct va_egl_client_buffer *egl_client_buffer; }; struct object_subpic diff --git a/src/i965_output_egl.c b/src/i965_output_egl.c new file mode 100644 index 0000000..17ba182 --- /dev/null +++ b/src/i965_output_egl.c @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2012 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <va/va_egl.h> +#include <va/va_backend_egl.h> +#include "i965_defines.h" +#include "i965_drv_video.h" +#include "i965_output_egl.h" + +static inline void +swap_planes(struct va_egl_client_buffer *buf, int plane_a, int plane_b) +{ + uint32_t tmp_pitch = buf->pitches[plane_a]; + intptr_t tmp_offset = buf->offsets[plane_a]; + buf->pitches[plane_a] = buf->pitches[plane_b]; + buf->offsets[plane_a] = buf->offsets[plane_b]; + buf->pitches[plane_b] = tmp_pitch; + buf->offsets[plane_b] = tmp_offset; +} + +static void +va_egl_client_buffer_destroy(struct va_egl_client_buffer *buf) +{ + if (!buf) + return; + + if (buf->private_data) { + if (buf->destroy_private_data) + buf->destroy_private_data(buf->private_data); + buf->private_data = NULL; + } + free(buf); +} + +static struct va_egl_client_buffer * +va_egl_client_buffer_new_from_surface(struct object_surface *obj_surface) +{ + struct va_egl_client_buffer *buf; + uint32_t name; + + buf = calloc(1, sizeof(*buf)); + if (!buf) + return NULL; + + if (drm_intel_bo_flink(obj_surface->bo, &name) != 0) + goto error; + + buf->version = VA_EGL_CLIENT_BUFFER_VERSION; + buf->handle = name; + buf->width = obj_surface->orig_width; + buf->height = obj_surface->orig_height; + + switch (obj_surface->fourcc) { + case VA_FOURCC('N','V','1','2'): + buf->structure = VA_EGL_BUFFER_STRUCTURE_Y_UV; + buf->format = VA_EGL_PIXEL_FORMAT_NV12; + buf->num_planes = 2; + buf->pitches[0] = obj_surface->width; /* Y */ + buf->offsets[0] = 0; + buf->pitches[1] = obj_surface->cb_cr_pitch; /* UV */ + buf->offsets[1] = obj_surface->width * obj_surface->y_cb_offset; + break; + case VA_FOURCC('I','4','2','0'): + case VA_FOURCC('Y','V','1','2'): + case VA_FOURCC('I','M','C','1'): + case VA_FOURCC('I','M','C','3'): + buf->structure = VA_EGL_BUFFER_STRUCTURE_Y_U_V; + switch (obj_surface->subsampling) { + case SUBSAMPLE_YUV400: + buf->format = VA_EGL_PIXEL_FORMAT_GRAY8; + break; + case SUBSAMPLE_YUV411: + buf->format = VA_EGL_PIXEL_FORMAT_YUV411P; + break; + case SUBSAMPLE_YUV420: + buf->format = VA_EGL_PIXEL_FORMAT_YUV420P; + break; + case SUBSAMPLE_YUV422H: + case SUBSAMPLE_YUV422V: + buf->format = VA_EGL_PIXEL_FORMAT_YUV422P; + break; + case SUBSAMPLE_YUV444: + buf->format = VA_EGL_PIXEL_FORMAT_YUV444P; + break; + default: + assert(0 && "unsupported subsampling"); + abort(); + } + buf->num_planes = 3; + buf->pitches[0] = obj_surface->width; /* Y */ + buf->offsets[0] = 0; + buf->pitches[1] = obj_surface->cb_cr_pitch; /* U */ + buf->offsets[1] = obj_surface->width * obj_surface->y_cb_offset; + buf->pitches[2] = obj_surface->cb_cr_pitch; /* V */ + buf->offsets[2] = obj_surface->width * obj_surface->y_cr_offset; + break; + default: + assert(0 && "unsupported pixel format"); + abort(); + break; + } + return buf; + +error: + va_egl_client_buffer_destroy(buf); + return NULL; +} + +static struct va_egl_client_buffer * +va_egl_client_buffer_new_from_image(struct object_image *obj_image) +{ + const VAImage * const image = &obj_image->image; + struct va_egl_client_buffer *buf; + uint32_t name; + unsigned int i; + + buf = calloc(1, sizeof(*buf)); + if (!buf) + return NULL; + + if (drm_intel_bo_flink(obj_image->bo, &name) != 0) + goto error; + + buf->version = VA_EGL_CLIENT_BUFFER_VERSION; + buf->handle = name; + buf->width = image->width; + buf->height = image->height; + + buf->num_planes = image->num_planes; + for (i = 0; i < buf->num_planes; i++) { + buf->pitches[i] = image->pitches[i]; + buf->offsets[i] = image->offsets[i]; + } + + /* Normalize plane info and format */ + switch (image->format.fourcc) { + case VA_FOURCC('B','G','R','A'): + buf->structure = VA_EGL_BUFFER_STRUCTURE_RGBA; + buf->format = VA_EGL_PIXEL_FORMAT_ARGB8888; + break; + // fall-through + case VA_FOURCC('R','G','B','A'): + buf->structure = VA_EGL_BUFFER_STRUCTURE_RGBA; + buf->format = VA_EGL_PIXEL_FORMAT_ABGR8888; + break; + case VA_FOURCC('N','V','1','2'): + buf->structure = VA_EGL_BUFFER_STRUCTURE_Y_UV; + buf->format = VA_EGL_PIXEL_FORMAT_NV12; + break; + case VA_FOURCC('I','4','2','0'): + case VA_FOURCC('Y','V','1','2'): + /* XXX: only 4:2:0 subsampling is supported for VA images */ + buf->structure = VA_EGL_BUFFER_STRUCTURE_Y_U_V; + buf->format = VA_EGL_PIXEL_FORMAT_YUV420P; + swap_planes(buf, 1, 2); + break; + default: + assert(0 && "unsupported pixel format"); + abort(); + break; + } + return buf; + +error: + va_egl_client_buffer_destroy(buf); + return NULL; +} + +void +i965_destroy_egl_client_buffer(struct va_egl_client_buffer *buf) +{ + va_egl_client_buffer_destroy(buf); +} + +static void +va_buffer_info_init( + VABufferInfoEGL *out_buffer_info, + struct va_egl_client_buffer *buf +) +{ + out_buffer_info->buffer = buf; + out_buffer_info->structure = buf->structure; + out_buffer_info->width = buf->width; + out_buffer_info->height = buf->height; +} + +/* Hook return buffer info associated with the VA surface. */ +static VAStatus +va_GetSurfaceBufferEGL( + VADriverContextP ctx, + VASurfaceID surface, + VABufferInfoEGL *out_buffer_info +) +{ + struct i965_driver_data * const i965 = i965_driver_data(ctx); + struct object_surface *obj_surface; + struct va_egl_client_buffer *buf; + + obj_surface = SURFACE(surface); + if (!obj_surface) + return VA_STATUS_ERROR_INVALID_SURFACE; + + if (!out_buffer_info) + return VA_STATUS_ERROR_INVALID_PARAMETER; + + buf = obj_surface->egl_client_buffer; + if (!buf) { + buf = va_egl_client_buffer_new_from_surface(obj_surface); + if (!buf) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + obj_surface->egl_client_buffer = buf; + } + + va_buffer_info_init(out_buffer_info, buf); + return VA_STATUS_SUCCESS; +} + +/** Hook to return buffer info associated with the VA image. */ +VAStatus +va_GetImageBufferEGL( + VADriverContextP ctx, + VAImageID image, + VABufferInfoEGL *out_buffer_info +) +{ + struct i965_driver_data * const i965 = i965_driver_data(ctx); + struct object_image *obj_image; + struct va_egl_client_buffer *buf; + + obj_image = IMAGE(image); + if (!obj_image) + return VA_STATUS_ERROR_INVALID_IMAGE; + + /* XXX: we don't support paletted formats yet */ + if (obj_image->palette) + return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; + + if (!out_buffer_info) + return VA_STATUS_ERROR_INVALID_PARAMETER; + + buf = obj_image->egl_client_buffer; + if (!buf) { + buf = va_egl_client_buffer_new_from_image(obj_image); + if (!buf) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + obj_image->egl_client_buffer = buf; + } + + va_buffer_info_init(out_buffer_info, buf); + return VA_STATUS_SUCCESS; +} + +bool +i965_output_egl_init(VADriverContextP ctx) +{ + struct VADriverVTableEGL *vtable; + + vtable = calloc(1, sizeof(*vtable)); + if (!vtable) + return false; + ctx->vtable_egl = vtable; + + vtable->version = VA_EGL_VTABLE_VERSION; + vtable->vaGetSurfaceBufferEGL = va_GetSurfaceBufferEGL; + vtable->vaGetImageBufferEGL = va_GetImageBufferEGL; + return true; +} + +void +i965_output_egl_terminate(VADriverContextP ctx) +{ + free(ctx->vtable_egl); + ctx->vtable_egl = NULL; +} diff --git a/src/i965_output_egl.h b/src/i965_output_egl.h new file mode 100644 index 0000000..f713ac9 --- /dev/null +++ b/src/i965_output_egl.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef I965_OUTPUT_EGL_H +#define I965_OUTPUT_EGL_H + +#include <stdbool.h> +#include <va/va_backend.h> + +bool +i965_output_egl_init(VADriverContextP ctx); + +void +i965_output_egl_terminate(VADriverContextP ctx); + +void +i965_destroy_egl_client_buffer(struct va_egl_client_buffer *buf); + +#endif /* I965_OUTPUT_EGL_H */ |