2 * @COPYRIGHT@ Intel Confidential - Unreleased Software
7 #include "va_backend.h"
17 #define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri"
18 #define DRIVER_EXTENSION "_drv_video.so"
19 #define DRIVER_INIT_FUNC "__vaDriverInit_0_18"
21 #define CTX(dpy) ((VADriverContextP) dpy );
22 #define ASSERT_CONTEXT(dpy) assert( vaDbgContextIsValid(dpy) )
24 #define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable.va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN;
25 #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
27 #define TRACE(func) if (va_debug_trace) va_infoMessage("[TR] %s\n", #func);
29 static VADriverContextP pDriverContexts = NULL;
30 static int va_debug_trace = 0;
32 static Bool vaDbgContextIsValid(VADriverContextP arg_ctx)
34 VADriverContextP ctx = pDriverContexts;
47 VADisplay vaGetDisplay (
48 NativeDisplay native_dpy /* implementation specific */
52 VADriverContextP ctx = pDriverContexts;
56 if (ctx->x11_dpy == (Display *)native_dpy)
58 dpy = (VADisplay) ctx;
66 /* create new entry */
67 ctx = (VADriverContextP) calloc(1, sizeof(struct VADriverContext));
68 ctx->pNext = pDriverContexts;
69 ctx->x11_dpy = (Display *) native_dpy;
70 pDriverContexts = ctx;
71 dpy = (VADisplay) ctx;
77 static void va_errorMessage(const char *msg, ...)
81 fprintf(stderr, "libva error: ");
83 vfprintf(stderr, msg, args);
87 static void va_infoMessage(const char *msg, ...)
91 fprintf(stderr, "libva: ");
93 vfprintf(stderr, msg, args);
97 static Bool va_checkVtable(void *ptr, char *function)
101 va_errorMessage("No valid vtable entry for va%s\n", function);
107 static Bool va_checkMaximum(int value, char *variable)
111 va_errorMessage("Failed to define max_%s in init\n", variable);
117 static VAStatus va_getDriverName(VADriverContextP ctx, char **driver_name)
119 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
127 if (geteuid() == getuid())
129 /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
130 if (getenv("LIBVA_DRIVER_NAME"))
132 /* For easier debugging */
133 *driver_name = strdup(getenv("LIBVA_DRIVER_NAME"));
134 return VA_STATUS_SUCCESS;
139 result = XF86DRIQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable);
142 va_errorMessage("XF86DRIQueryDirectRenderingCapable failed\n");
147 result = direct_capable;
150 va_errorMessage("XF86DRIQueryDirectRenderingCapable returned false\n");
155 result = XF86DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor,
156 &driver_patch, driver_name);
159 va_errorMessage("XF86DRIGetClientDriverName returned false\n");
164 vaStatus = VA_STATUS_SUCCESS;
165 va_infoMessage("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
166 driver_major, driver_minor, driver_patch, *driver_name, ctx->x11_screen);
172 static VAStatus va_openDriver(VADriverContextP ctx, char *driver_name)
174 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
179 if (geteuid() == getuid())
181 /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
182 search_path = getenv("LIBVA_DRIVERS_PATH");
185 search_path = getenv("LIBGL_DRIVERS_PATH");
190 search_path = DEFAULT_DRIVER_DIR;
193 search_path = strdup(search_path);
194 driver_dir = strtok_r(search_path, ":", &saveptr);
198 char *driver_path = (char *) malloc( strlen(driver_dir) +
199 strlen(driver_name) +
200 strlen(DRIVER_EXTENSION) + 2 );
201 strcpy( driver_path, driver_dir );
202 strcat( driver_path, "/" );
203 strcat( driver_path, driver_name );
204 strcat( driver_path, DRIVER_EXTENSION );
206 va_infoMessage("Trying to open %s\n", driver_path);
208 handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL );
211 /* Don't give errors for non-existing files */
212 if (0 == access( driver_path, F_OK))
214 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
219 VADriverInit init_func;
220 init_func = (VADriverInit) dlsym(handle, DRIVER_INIT_FUNC);
223 va_errorMessage("%s has no function %s\n", driver_path, DRIVER_INIT_FUNC);
228 vaStatus = (*init_func)(ctx);
230 if (VA_STATUS_SUCCESS == vaStatus)
232 CHECK_MAXIMUM(vaStatus, ctx, profiles);
233 CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
234 CHECK_MAXIMUM(vaStatus, ctx, attributes);
235 CHECK_VTABLE(vaStatus, ctx, Terminate);
236 CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
237 CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
238 CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
239 CHECK_VTABLE(vaStatus, ctx, CreateConfig);
240 CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
241 CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
242 CHECK_VTABLE(vaStatus, ctx, DestroySurface);
243 CHECK_VTABLE(vaStatus, ctx, CreateContext);
244 CHECK_VTABLE(vaStatus, ctx, DestroyContext);
245 CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
246 CHECK_VTABLE(vaStatus, ctx, BufferData);
247 CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
248 CHECK_VTABLE(vaStatus, ctx, MapBuffer);
249 CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
250 CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
251 CHECK_VTABLE(vaStatus, ctx, BeginPicture);
252 CHECK_VTABLE(vaStatus, ctx, RenderPicture);
253 CHECK_VTABLE(vaStatus, ctx, EndPicture);
254 CHECK_VTABLE(vaStatus, ctx, SyncSurface);
255 CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
256 CHECK_VTABLE(vaStatus, ctx, PutSurface);
257 CHECK_VTABLE(vaStatus, ctx, DbgCopySurfaceToBuffer);
259 if (VA_STATUS_SUCCESS != vaStatus)
261 va_errorMessage("%s init failed\n", driver_path);
264 if (VA_STATUS_SUCCESS == vaStatus)
266 ctx->handle = handle;
274 driver_dir = strtok_r(NULL, ":", &saveptr);
284 * Returns a short english description of error_status
286 const char *vaErrorStr(VAStatus error_status)
290 case VA_STATUS_SUCCESS:
291 return "success (no error)";
292 case VA_STATUS_ERROR_ALLOCATION_FAILED:
293 return "resource allocation failed";
294 case VA_STATUS_ERROR_INVALID_CONFIG:
295 return "invalid VAConfigID";
296 case VA_STATUS_ERROR_INVALID_CONTEXT:
297 return "invalid VAContextID";
298 case VA_STATUS_ERROR_INVALID_SURFACE:
299 return "invalid VASurfaceID";
300 case VA_STATUS_ERROR_INVALID_BUFFER:
301 return "invalid VABufferID";
302 case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
303 return "attribute not supported";
304 case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
305 return "list argument exceeds maximum number";
306 case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
307 return "the requested VAProfile is not supported";
308 case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
309 return "the requested VAEntryPoint is not supported";
310 case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
311 return "the requested RT Format is not supported";
312 case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
313 return "the requested VABufferType is not supported";
314 case VA_STATUS_ERROR_UNKNOWN:
315 return "unknown libva error";
317 return "unknwon libva error / description missing";
320 VAStatus vaInitialize (
322 int *major_version, /* out */
323 int *minor_version /* out */
326 VADriverContextP ctx = CTX(dpy);
327 char *driver_name = NULL;
332 va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL);
334 vaStatus = va_getDriverName(ctx, &driver_name);
335 va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
337 if (VA_STATUS_SUCCESS == vaStatus)
339 vaStatus = va_openDriver(ctx, driver_name);
340 va_infoMessage("va_openDriver() returns %d\n", vaStatus);
342 *major_version = ctx->version_major;
343 *minor_version = ctx->version_minor;
355 * After this call, all library internal resources will be cleaned up
357 VAStatus vaTerminate (
361 VAStatus vaStatus = VA_STATUS_SUCCESS;
362 VADriverContextP old_ctx = CTX(dpy);
363 ASSERT_CONTEXT(old_ctx);
367 vaStatus = old_ctx->vtable.vaTerminate(old_ctx);
368 dlclose(old_ctx->handle);
369 old_ctx->handle = NULL;
372 if (VA_STATUS_SUCCESS == vaStatus)
374 VADriverContextP *ctx = &pDriverContexts;
376 /* Throw away old_ctx */
381 *ctx = old_ctx->pNext;
382 old_ctx->pNext = NULL;
385 ctx = &((*ctx)->pNext);
392 /* Get maximum number of profiles supported by the implementation */
393 int vaMaxNumProfiles (
397 VADriverContextP ctx = CTX(dpy);
400 return ctx->max_profiles;
403 /* Get maximum number of entrypoints supported by the implementation */
404 int vaMaxNumEntrypoints (
408 VADriverContextP ctx = CTX(dpy);
411 return ctx->max_entrypoints;
414 /* Get maximum number of attributs supported by the implementation */
415 int vaMaxNumConfigAttributes (
419 VADriverContextP ctx = CTX(dpy);
422 return ctx->max_attributes;
426 VAStatus vaQueryConfigEntrypoints (
429 VAEntrypoint *entrypoints, /* out */
430 int *num_entrypoints /* out */
433 VADriverContextP ctx = CTX(dpy);
436 TRACE(vaQueryConfigEntrypoints);
437 return ctx->vtable.vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
440 VAStatus vaQueryConfigAttributes (
443 VAEntrypoint entrypoint,
444 VAConfigAttrib *attrib_list, /* in/out */
448 VADriverContextP ctx = CTX(dpy);
451 TRACE(vaQueryConfigAttributes);
452 return ctx->vtable.vaQueryConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
455 VAStatus vaQueryConfigProfiles (
457 VAProfile *profile_list, /* out */
458 int *num_profiles /* out */
461 VADriverContextP ctx = CTX(dpy);
464 TRACE(vaQueryConfigProfiles);
465 return ctx->vtable.vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
468 VAStatus vaCreateConfig (
471 VAEntrypoint entrypoint,
472 VAConfigAttrib *attrib_list,
474 VAConfigID *config_id /* out */
477 VADriverContextP ctx = CTX(dpy);
480 TRACE(vaCreateConfig);
481 return ctx->vtable.vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
484 VAStatus vaGetConfigAttributes (
486 VAConfigID config_id,
487 VAProfile *profile, /* out */
488 VAEntrypoint *entrypoint, /* out */
489 VAConfigAttrib *attrib_list,/* out */
490 int *num_attribs /* out */
493 VADriverContextP ctx = CTX(dpy);
496 TRACE(vaGetConfigAttributes);
497 return ctx->vtable.vaGetConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
500 VAStatus vaCreateSurfaces (
506 VASurface *surfaces /* out */
509 VADriverContextP ctx = CTX(dpy);
512 TRACE(vaCreateSurfaces);
513 return ctx->vtable.vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces );
516 VAStatus vaDestroySurface (
518 VASurface *surface_list,
522 VADriverContextP ctx = CTX(dpy);
525 TRACE(vaDestroySurface);
526 return ctx->vtable.vaDestroySurface( ctx, surface_list, num_surfaces );
529 VAStatus vaCreateContext (
531 VAConfigID config_id,
535 VASurface *render_targets,
536 int num_render_targets,
537 VAContext *context /* out */
540 VADriverContextP ctx = CTX(dpy);
543 TRACE(vaCreateContext);
544 return ctx->vtable.vaCreateContext( ctx, config_id, picture_width, picture_height,
545 flag, render_targets, num_render_targets, context );
548 VAStatus vaDestroyContext (
553 VADriverContextP ctx = CTX(dpy);
556 TRACE(vaDestroyContext);
557 return ctx->vtable.vaDestroyContext( ctx, context );
560 VAStatus vaCreateBuffer (
562 VABufferType type, /* in */
563 VABufferID *buf_id /* out */
566 VADriverContextP ctx = CTX(dpy);
569 TRACE(vaCreateBuffer);
570 return ctx->vtable.vaCreateBuffer( ctx, type, buf_id);
573 VAStatus vaBufferData (
575 VABufferID buf_id, /* in */
576 unsigned int size, /* in */
577 unsigned int num_elements, /* in */
581 VADriverContextP ctx = CTX(dpy);
585 return ctx->vtable.vaBufferData( ctx, buf_id, size, num_elements, data);
588 VAStatus vaBufferSetNumElements (
590 VABufferID buf_id, /* in */
591 unsigned int num_elements /* in */
594 VADriverContextP ctx = CTX(dpy);
597 TRACE(vaBufferSetNumElements);
598 return ctx->vtable.vaBufferSetNumElements( ctx, buf_id, num_elements );
602 VAStatus vaMapBuffer (
604 VABufferID buf_id, /* in */
605 void **pbuf /* out */
608 VADriverContextP ctx = CTX(dpy);
612 return ctx->vtable.vaMapBuffer( ctx, buf_id, pbuf );
615 VAStatus vaUnmapBuffer (
617 VABufferID buf_id /* in */
620 VADriverContextP ctx = CTX(dpy);
623 TRACE(vaUnmapBuffer);
624 return ctx->vtable.vaUnmapBuffer( ctx, buf_id );
627 VAStatus vaDestroyBuffer (
632 VADriverContextP ctx = CTX(dpy);
635 TRACE(vaDestroyBuffer);
636 return ctx->vtable.vaDestroyBuffer( ctx, buffer_id );
639 VAStatus vaBeginPicture (
642 VASurface *render_target
645 VADriverContextP ctx = CTX(dpy);
648 TRACE(vaBeginPicture);
649 return ctx->vtable.vaBeginPicture( ctx, context, render_target );
652 VAStatus vaRenderPicture (
659 VADriverContextP ctx = CTX(dpy);
662 TRACE(vaRenderPicture);
663 return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers );
666 VAStatus vaEndPicture (
671 VADriverContextP ctx = CTX(dpy);
675 return ctx->vtable.vaEndPicture( ctx, context );
678 VAStatus vaSyncSurface (
681 VASurface *render_target
684 VADriverContextP ctx = CTX(dpy);
687 TRACE(vaSyncSurface);
688 return ctx->vtable.vaSyncSurface( ctx, context, render_target );
691 VAStatus vaQuerySurfaceStatus (
694 VASurface *render_target,
695 VASurfaceStatus *status /* out */
698 VADriverContextP ctx = CTX(dpy);
701 TRACE(vaQuerySurfaceStatus);
702 return ctx->vtable.vaQuerySurfaceStatus( ctx, context, render_target, status );
705 VAStatus vaPutSurface (
708 Drawable draw, /* X Drawable */
715 unsigned short destw,
716 unsigned short desth,
717 int flags /* de-interlacing flags */
720 VADriverContextP ctx = CTX(dpy);
724 return ctx->vtable.vaPutSurface( ctx, surface, draw, srcx, srcy, srcw, srch,
725 destx, desty, destw, desth, flags );
728 VAStatus vaDbgCopySurfaceToBuffer(VADisplay dpy,
730 void **buffer, /* out */
731 unsigned int *stride /* out */
734 VADriverContextP ctx = CTX(dpy);
737 TRACE(vaDbgCopySurfaceToBuffer);
738 return ctx->vtable.vaDbgCopySurfaceToBuffer( ctx, surface, buffer, stride );