summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-07-09 17:33:31 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-07-13 15:33:11 +0200
commitda711e5f642cf7421e83fe711192b6c4e3a05aeb (patch)
tree8a81dd5bfa8cf24cb77aaa3d729c9ed4d0d23b9a
parent560ab2c9b116ddaddd90c24f520c4dc66310c9e7 (diff)
Implement new VA/EGL API.staging.13.egl-r1
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r--configure.ac18
-rwxr-xr-xsrc/Makefile.am5
-rwxr-xr-xsrc/i965_drv_video.c27
-rw-r--r--src/i965_drv_video.h2
-rw-r--r--src/i965_output_egl.c298
-rw-r--r--src/i965_output_egl.h40
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 */