summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2015-09-06 09:39:09 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2015-09-06 14:13:27 +0800
commit3bbaff8b4180d2510c8c77d9e4d19bf84853f31a (patch)
tree0b8dce61a7d820379c2598e4409853e39d44334b /src
parent2f254ecd154d59553a1e3949f66161bade6ca2b7 (diff)
Wrapper the DriverContextP of backend driver
The default directory of backend driver is used.(LIBVA_DRIVERS_PATH). Only when the backend driver exists, the wrapper is initialized and added. Otherwise it won't be initialized. And the option of "enable-wrapper" is added, which is used to determine whether the wrapper of backend driver is supported. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Signed-off-by: Sean V Kelley <seanvk@posteo.de>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/Makefile.am1
-rw-r--r--src/i965_drv_video.c146
-rw-r--r--src/i965_drv_video.h2
3 files changed, 149 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index dc82c43..a170aee 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,7 @@ AM_CPPFLAGS = \
-DPTHREADS \
$(DRM_CFLAGS) \
$(LIBVA_DEPS_CFLAGS) \
+ -DVA_DRIVERS_PATH="\"$(LIBVA_DRIVERS_PATH)\"" \
$(NULL)
driver_cflags = \
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index a446b74..4df5fad 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -29,6 +29,7 @@
#include "sysdeps.h"
#include <unistd.h>
+#include <dlfcn.h>
#ifdef HAVE_VA_X11
# include "i965_output_dri.h"
@@ -5731,6 +5732,133 @@ error:
return false;
}
+/* Only when the option of "enable-wrapper" is passed, it is possible
+ * to initialize/load the wrapper context of backend driver.
+ * Otherwise it is not loaded.
+ */
+#if HAVE_USE_WRAPPER
+
+static VAStatus
+i965_initialize_wrapper(VADriverContextP ctx, const char *driver_name)
+{
+#define DRIVER_EXTENSION "_drv_video.so"
+
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+
+ VADriverContextP wrapper_pdrvctx;
+ struct VADriverVTable *vtable;
+ char *search_path, *driver_dir;
+ char *saveptr;
+ char driver_path[256];
+ void *handle = NULL;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ bool driver_loaded = false;
+
+ if (!(IS_HASWELL(i965->intel.device_info) ||
+ IS_GEN8(i965->intel.device_info) ||
+ IS_GEN9(i965->intel.device_info))) {
+ return VA_STATUS_ERROR_UNIMPLEMENTED;
+ }
+
+ wrapper_pdrvctx = calloc(1, sizeof(*wrapper_pdrvctx));
+ vtable = calloc(1, sizeof(*vtable));
+
+ if (!wrapper_pdrvctx || !vtable) {
+ fprintf(stderr, "Failed to allocate memory for wrapper \n");
+ free(wrapper_pdrvctx);
+ free(vtable);
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ /* use the same drm_state with CTX */
+ wrapper_pdrvctx->drm_state = ctx->drm_state;
+ wrapper_pdrvctx->display_type = ctx->display_type;
+ wrapper_pdrvctx->vtable = vtable;
+
+ search_path = VA_DRIVERS_PATH;
+ search_path = strdup((const char *)search_path);
+
+ driver_dir = strtok_r(search_path, ":", &saveptr);
+ while (driver_dir && !driver_loaded) {
+ memset(driver_path, 0, sizeof(driver_path));
+ sprintf(driver_path, "%s/%s%s", driver_dir, driver_name, DRIVER_EXTENSION);
+
+ if (access(driver_path, F_OK)) {
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ continue;
+ }
+
+ handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
+ if (!handle) {
+ fprintf(stderr, "failed to open %s\n", driver_path);
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ continue;
+ }
+ {
+ VADriverInit init_func = NULL;
+ char init_func_s[256];
+ int i;
+
+ static const struct {
+ int major;
+ int minor;
+ } compatible_versions[] = {
+ { VA_MAJOR_VERSION, VA_MINOR_VERSION },
+ { 0, 37 },
+ { 0, 36 },
+ { 0, 35 },
+ { 0, 34 },
+ { 0, 33 },
+ { 0, 32 },
+ { -1, }
+ };
+ for (i = 0; compatible_versions[i].major >= 0; i++) {
+ snprintf(init_func_s, sizeof(init_func_s),
+ "__vaDriverInit_%d_%d",
+ compatible_versions[i].major,
+ compatible_versions[i].minor);
+ init_func = (VADriverInit)dlsym(handle, init_func_s);
+ if (init_func) {
+ break;
+ }
+ }
+ if (compatible_versions[i].major < 0) {
+ dlclose(handle);
+ fprintf(stderr, "%s has no function %s\n",
+ driver_path, init_func_s);
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ continue;
+ }
+
+ if (init_func)
+ va_status = (*init_func)(wrapper_pdrvctx);
+
+ if (va_status != VA_STATUS_SUCCESS) {
+ dlclose(handle);
+ fprintf(stderr, "%s init failed\n", driver_path);
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ continue;
+ }
+
+ wrapper_pdrvctx->handle = handle;
+ driver_loaded = true;
+ }
+ }
+
+ free(search_path);
+
+ if (driver_loaded) {
+ i965->wrapper_pdrvctx = wrapper_pdrvctx;
+ return VA_STATUS_SUCCESS;
+ } else {
+ fprintf(stderr, "Failed to wrapper %s%s\n", driver_name, DRIVER_EXTENSION);
+ free(vtable);
+ free(wrapper_pdrvctx);
+ return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+#endif
+
static VAStatus
i965_Init(VADriverContextP ctx)
{
@@ -5763,6 +5891,10 @@ i965_Init(VADriverContextP ctx)
if (i965->codec_info && i965->codec_info->preinit_hw_codec)
i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
+#if HAVE_USE_WRAPPER
+ i965_initialize_wrapper(ctx, "hybrid");
+#endif
+
return VA_STATUS_SUCCESS;
} else {
i--;
@@ -5784,6 +5916,19 @@ i965_Terminate(VADriverContextP ctx)
struct i965_driver_data *i965 = i965_driver_data(ctx);
int i;
+ if (i965->wrapper_pdrvctx) {
+ VADriverContextP pdrvctx;
+ pdrvctx = i965->wrapper_pdrvctx;
+ if (pdrvctx->handle) {
+ pdrvctx->vtable->vaTerminate(pdrvctx);
+ dlclose(pdrvctx->handle);
+ pdrvctx->handle = NULL;
+ }
+ free(pdrvctx->vtable);
+ free(pdrvctx);
+ i965->wrapper_pdrvctx = NULL;
+ }
+
if (i965) {
for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
if (i965_sub_ops[i - 1].display_type == 0 ||
@@ -5882,6 +6027,7 @@ VA_DRIVER_INIT_FUNC( VADriverContextP ctx )
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
+ i965->wrapper_pdrvctx = NULL;
ctx->pDriverData = (void *)i965;
ret = i965_Init(ctx);
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 84b557e..de71221 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -424,6 +424,8 @@ struct i965_driver_data
/* VA/Wayland specific data */
struct va_wl_output *wl_output;
+
+ VADriverContextP wrapper_pdrvctx;
};
#define NEW_CONFIG_ID() object_heap_allocate(&i965->config_heap);