Update to VA API 0.26
[platform/upstream/libva.git] / src / va.c
1 /*
2  * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  * 
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  * 
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "X11/Xlib.h"
26 #include "va.h"
27 #include "va_backend.h"
28
29 #include "assert.h"
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <dlfcn.h>
34 #include <unistd.h>
35 #include "va_dri.h"
36
37 #define DEFAULT_DRIVER_DIR      "/usr/X11R6/lib/modules/dri"
38 #define DRIVER_EXTENSION        "_drv_video.so"
39 #define DRIVER_INIT_FUNC        "__vaDriverInit_0_26"
40
41 #define CTX(dpy) ((VADriverContextP) dpy );
42 #define CHECK_CONTEXT(dpy) if( !vaContextIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
43 #define ASSERT          assert
44 #define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable.va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN;
45 #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
46 #define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
47
48 #define TRACE(func) if (va_debug_trace) va_infoMessage("[TR] %s\n", #func);
49
50 static VADriverContextP pDriverContexts = NULL;
51 static int va_debug_trace = 0;
52
53 static Bool vaContextIsValid(VADriverContextP arg_ctx)
54 {
55   VADriverContextP ctx = pDriverContexts;
56   
57   while (ctx)
58   {
59       if (ctx == arg_ctx)
60       {
61           return True;
62       }
63       ctx = ctx->pNext;
64   }
65   return False;
66 }
67
68 VADisplay vaGetDisplay (
69     NativeDisplay native_dpy    /* implementation specific */
70 )
71 {
72   VADisplay dpy = NULL;
73   VADriverContextP ctx = pDriverContexts;
74
75   while (ctx)
76   {
77       if (ctx->x11_dpy == (Display *)native_dpy)
78       {
79           dpy = (VADisplay) ctx;
80           break;
81       }
82       ctx = ctx->pNext;
83   }
84   
85   if (!dpy)
86   {
87       /* create new entry */
88       ctx = (VADriverContextP) calloc(1, sizeof(struct VADriverContext));
89       ctx->pNext = pDriverContexts;
90       ctx->x11_dpy = (Display *) native_dpy;
91       pDriverContexts = ctx;
92       dpy = (VADisplay) ctx;
93   }
94   
95   return dpy;
96 }
97
98 static void va_errorMessage(const char *msg, ...)
99 {
100     va_list args;
101
102     fprintf(stderr, "libva error: ");
103     va_start(args, msg);
104     vfprintf(stderr, msg, args);
105     va_end(args);
106 }
107
108 static void va_infoMessage(const char *msg, ...)
109 {
110     va_list args;
111
112     fprintf(stderr, "libva: ");
113     va_start(args, msg);
114     vfprintf(stderr, msg, args);
115     va_end(args);
116 }
117
118 static Bool va_checkVtable(void *ptr, char *function)
119 {
120     if (!ptr)
121     {
122         va_errorMessage("No valid vtable entry for va%s\n", function);
123         return False;
124     }
125     return True;
126 }
127
128 static Bool va_checkMaximum(int value, char *variable)
129 {
130     if (!value)
131     {
132         va_errorMessage("Failed to define max_%s in init\n", variable);
133         return False;
134     }
135     return True;
136 }
137
138 static Bool va_checkString(const char* value, char *variable)
139 {
140     if (!value)
141     {
142         va_errorMessage("Failed to define str_%s in init\n", variable);
143         return False;
144     }
145     return True;
146 }
147
148 static VAStatus va_getDriverName(VADriverContextP ctx, char **driver_name)
149 {
150     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
151     int direct_capable;
152     int driver_major;
153     int driver_minor;
154     int driver_patch;
155     Bool result = True;
156     
157     *driver_name = NULL;
158     if (geteuid() == getuid())
159     {
160         /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
161         if (getenv("LIBVA_DRIVER_NAME"))
162         {
163             /* For easier debugging */
164             *driver_name = strdup(getenv("LIBVA_DRIVER_NAME"));
165             return VA_STATUS_SUCCESS;
166         }
167     }
168     if (result)
169     {
170         result = VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable);
171         if (!result)
172         {
173             va_errorMessage("VA_DRIQueryDirectRenderingCapable failed\n");
174         }
175     }
176     if (result)
177     {
178         result = direct_capable;
179         if (!result)
180         {
181             va_errorMessage("VA_DRIQueryDirectRenderingCapable returned false\n");
182         }
183     }
184     if (result)
185     {
186         result = VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor,
187                                             &driver_patch, driver_name);
188         if (!result)
189         {
190             va_errorMessage("VA_DRIGetClientDriverName returned false\n");
191         }
192     }
193     if (result)
194     {
195         vaStatus = VA_STATUS_SUCCESS;
196         va_infoMessage("VA_DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
197              driver_major, driver_minor, driver_patch, *driver_name, ctx->x11_screen);
198     }
199
200     return vaStatus;
201 }
202
203 static VAStatus va_openDriver(VADriverContextP ctx, char *driver_name)
204 {
205     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
206     char *search_path;
207     char *saveptr;
208     char *driver_dir;
209     
210     if (geteuid() == getuid())
211     {
212         /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
213         search_path = getenv("LIBVA_DRIVERS_PATH");
214         if (!search_path)
215         {
216             search_path = getenv("LIBGL_DRIVERS_PATH");
217         }
218     }
219     if (!search_path)
220     {
221         search_path = DEFAULT_DRIVER_DIR;
222     }
223
224     search_path = strdup(search_path);
225     driver_dir = strtok_r(search_path, ":", &saveptr);
226     while(driver_dir)
227     {
228         void *handle = NULL;
229         char *driver_path = (char *) malloc( strlen(driver_dir) +
230                                              strlen(driver_name) +
231                                              strlen(DRIVER_EXTENSION) + 2 );
232         strcpy( driver_path, driver_dir );
233         strcat( driver_path, "/" );
234         strcat( driver_path, driver_name );
235         strcat( driver_path, DRIVER_EXTENSION );
236         
237         va_infoMessage("Trying to open %s\n", driver_path);
238
239         handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL );
240         if (!handle)
241         {
242             /* Don't give errors for non-existing files */
243             if (0 == access( driver_path, F_OK))
244             {   
245                 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
246             }
247         }
248         else
249         {
250             VADriverInit init_func;
251             init_func = (VADriverInit) dlsym(handle, DRIVER_INIT_FUNC);
252             if (!init_func)
253             {
254                 va_errorMessage("%s has no function %s\n", driver_path, DRIVER_INIT_FUNC);
255                 dlclose(handle);
256             }
257             else
258             {
259                 vaStatus = (*init_func)(ctx);
260
261                 if (VA_STATUS_SUCCESS == vaStatus)
262                 {
263                     CHECK_MAXIMUM(vaStatus, ctx, profiles);
264                     CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
265                     CHECK_MAXIMUM(vaStatus, ctx, attributes);
266                     CHECK_MAXIMUM(vaStatus, ctx, image_formats);
267                     CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
268                     CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
269                     CHECK_STRING(vaStatus, ctx, vendor);
270                     CHECK_VTABLE(vaStatus, ctx, Terminate);
271                     CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
272                     CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
273                     CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
274                     CHECK_VTABLE(vaStatus, ctx, CreateConfig);
275                     CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
276                     CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
277                     CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
278                     CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
279                     CHECK_VTABLE(vaStatus, ctx, CreateContext);
280                     CHECK_VTABLE(vaStatus, ctx, DestroyContext);
281                     CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
282                     CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
283                     CHECK_VTABLE(vaStatus, ctx, MapBuffer);
284                     CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
285                     CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
286                     CHECK_VTABLE(vaStatus, ctx, BeginPicture);
287                     CHECK_VTABLE(vaStatus, ctx, RenderPicture);
288                     CHECK_VTABLE(vaStatus, ctx, EndPicture);
289                     CHECK_VTABLE(vaStatus, ctx, SyncSurface);
290                     CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
291                     CHECK_VTABLE(vaStatus, ctx, PutSurface);
292                     CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
293                     CHECK_VTABLE(vaStatus, ctx, CreateImage);
294                     CHECK_VTABLE(vaStatus, ctx, DestroyImage);
295                     CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
296                     CHECK_VTABLE(vaStatus, ctx, GetImage);
297                     CHECK_VTABLE(vaStatus, ctx, PutImage);
298                     CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
299                     CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
300                     CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
301                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
302                     CHECK_VTABLE(vaStatus, ctx, SetSubpicturePalette);
303                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
304                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
305                     CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
306                     CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
307                     CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
308                     CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
309                     CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
310                     CHECK_VTABLE(vaStatus, ctx, DbgCopySurfaceToBuffer);
311                 }
312                 if (VA_STATUS_SUCCESS != vaStatus)
313                 {
314                     va_errorMessage("%s init failed\n", driver_path);
315                     dlclose(handle);
316                 }
317                 if (VA_STATUS_SUCCESS == vaStatus)
318                 {
319                     ctx->handle = handle;
320                 }
321                 free(driver_path);
322                 break;
323             }
324         }
325         free(driver_path);
326         
327         driver_dir = strtok_r(NULL, ":", &saveptr);
328     }
329     
330     free(search_path);    
331     
332     return vaStatus;
333 }
334
335
336 /*
337  * Returns a short english description of error_status
338  */
339 const char *vaErrorStr(VAStatus error_status)
340 {
341     switch(error_status)
342     {
343         case VA_STATUS_SUCCESS:
344             return "success (no error)";
345         case VA_STATUS_ERROR_ALLOCATION_FAILED:
346             return "resource allocation failed";
347         case VA_STATUS_ERROR_INVALID_CONFIG:
348             return "invalid VAConfigID";
349         case VA_STATUS_ERROR_INVALID_CONTEXT:
350             return "invalid VAContextID";
351         case VA_STATUS_ERROR_INVALID_SURFACE:
352             return "invalid VASurfaceID";
353         case VA_STATUS_ERROR_INVALID_BUFFER:
354             return "invalid VABufferID";
355         case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
356             return "attribute not supported";
357         case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
358             return "list argument exceeds maximum number";
359         case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
360             return "the requested VAProfile is not supported";
361         case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
362             return "the requested VAEntryPoint is not supported";
363         case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
364             return "the requested RT Format is not supported";
365         case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
366             return "the requested VABufferType is not supported";
367         case VA_STATUS_ERROR_UNKNOWN:
368             return "unknown libva error";
369     }
370     return "unknown libva error / description missing";
371 }
372       
373 VAStatus vaInitialize (
374     VADisplay dpy,
375     int *major_version,  /* out */
376     int *minor_version   /* out */
377 )
378 {
379   VADriverContextP ctx = CTX(dpy);
380   char *driver_name = NULL;
381   VAStatus vaStatus;
382   
383   CHECK_CONTEXT(ctx);
384
385   va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL);
386
387   vaStatus = va_getDriverName(ctx, &driver_name);
388   va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
389   
390   if (VA_STATUS_SUCCESS == vaStatus)
391   {
392       vaStatus = va_openDriver(ctx, driver_name);
393       va_infoMessage("va_openDriver() returns %d\n", vaStatus);
394       
395       *major_version = ctx->version_major;
396       *minor_version = ctx->version_minor;
397   }
398
399   if (driver_name)
400   {
401       XFree(driver_name);
402   }
403   return vaStatus;
404 }
405
406
407 /*
408  * After this call, all library internal resources will be cleaned up
409  */ 
410 VAStatus vaTerminate (
411     VADisplay dpy
412 )
413 {
414   VAStatus vaStatus = VA_STATUS_SUCCESS;
415   VADriverContextP old_ctx = CTX(dpy);
416   CHECK_CONTEXT(old_ctx);
417
418   if (old_ctx->handle)
419   {
420       vaStatus = old_ctx->vtable.vaTerminate(old_ctx);
421       dlclose(old_ctx->handle);
422       old_ctx->handle = NULL;
423   }
424
425   if (VA_STATUS_SUCCESS == vaStatus)
426   {
427       VADriverContextP *ctx = &pDriverContexts;
428
429       /* Throw away old_ctx */
430       while (*ctx)
431       {
432           if (*ctx == old_ctx)
433           {
434               *ctx = old_ctx->pNext;
435               old_ctx->pNext = NULL;
436               break;
437           }
438           ctx = &((*ctx)->pNext);
439       }
440       free(old_ctx);
441   }
442   return vaStatus;
443 }
444
445 /*
446  * vaQueryVendorString returns a pointer to a zero-terminated string
447  * describing some aspects of the VA implemenation on a specific
448  * hardware accelerator. The format of the returned string is:
449  * <vendorname>-<major_version>-<minor_version>-<addtional_info>
450  * e.g. for the Intel GMA500 implementation, an example would be:
451  * "IntelGMA500-1.0-0.2-patch3
452  */
453 const char *vaQueryVendorString (
454     VADisplay dpy
455 )
456 {
457   VADriverContextP ctx = CTX(dpy);
458   if( !vaContextIsValid(ctx) )
459   {
460       return NULL;
461   }
462   
463   return ctx->str_vendor;
464 }
465
466
467 /* Get maximum number of profiles supported by the implementation */
468 int vaMaxNumProfiles (
469     VADisplay dpy
470 )
471 {
472   VADriverContextP ctx = CTX(dpy);
473   if( !vaContextIsValid(ctx) )
474   {
475       return 0;
476   }
477   
478   return ctx->max_profiles;
479 }
480
481 /* Get maximum number of entrypoints supported by the implementation */
482 int vaMaxNumEntrypoints (
483     VADisplay dpy
484 )
485 {
486   VADriverContextP ctx = CTX(dpy);
487   if( !vaContextIsValid(ctx) )
488   {
489       return 0;
490   }
491   
492   return ctx->max_entrypoints;
493 }
494
495
496 /* Get maximum number of attributs supported by the implementation */
497 int vaMaxNumConfigAttributes (
498     VADisplay dpy
499 )
500 {
501   VADriverContextP ctx = CTX(dpy);
502   if( !vaContextIsValid(ctx) )
503   {
504       return 0;
505   }
506   
507   return ctx->max_attributes;
508 }
509
510 VAStatus vaQueryConfigEntrypoints (
511     VADisplay dpy,
512     VAProfile profile,
513     VAEntrypoint *entrypoints,  /* out */
514     int *num_entrypoints        /* out */
515 )
516 {
517   VADriverContextP ctx = CTX(dpy);
518   CHECK_CONTEXT(ctx);
519
520   TRACE(vaQueryConfigEntrypoints);
521   return ctx->vtable.vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
522 }
523
524 VAStatus vaGetConfigAttributes (
525     VADisplay dpy,
526     VAProfile profile,
527     VAEntrypoint entrypoint,
528     VAConfigAttrib *attrib_list, /* in/out */
529     int num_attribs
530 )
531 {
532   VADriverContextP ctx = CTX(dpy);
533   CHECK_CONTEXT(ctx);
534
535   TRACE(vaGetConfigAttributes);
536   return ctx->vtable.vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
537 }
538
539 VAStatus vaQueryConfigProfiles (
540     VADisplay dpy,
541     VAProfile *profile_list,    /* out */
542     int *num_profiles           /* out */
543 )
544 {
545   VADriverContextP ctx = CTX(dpy);
546   CHECK_CONTEXT(ctx);
547
548   TRACE(vaQueryConfigProfiles);
549   return ctx->vtable.vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
550 }
551
552 VAStatus vaCreateConfig (
553     VADisplay dpy,
554     VAProfile profile, 
555     VAEntrypoint entrypoint, 
556     VAConfigAttrib *attrib_list,
557     int num_attribs,
558     VAConfigID *config_id /* out */
559 )
560 {
561   VADriverContextP ctx = CTX(dpy);
562   CHECK_CONTEXT(ctx);
563
564   TRACE(vaCreateConfig);
565   return ctx->vtable.vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
566 }
567
568 VAStatus vaDestroyConfig (
569     VADisplay dpy,
570     VAConfigID config_id
571 )
572 {
573   VADriverContextP ctx = CTX(dpy);
574   CHECK_CONTEXT(ctx);
575
576   TRACE(vaDestroyConfig);
577   return ctx->vtable.vaDestroyConfig ( ctx, config_id );
578 }
579
580 VAStatus vaQueryConfigAttributes (
581     VADisplay dpy,
582     VAConfigID config_id, 
583     VAProfile *profile,         /* out */
584     VAEntrypoint *entrypoint,   /* out */
585     VAConfigAttrib *attrib_list,/* out */
586     int *num_attribs            /* out */
587 )
588 {
589   VADriverContextP ctx = CTX(dpy);
590   CHECK_CONTEXT(ctx);
591
592   TRACE(vaQueryConfigAttributes);
593   return ctx->vtable.vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
594 }
595
596 VAStatus vaCreateSurfaces (
597     VADisplay dpy,
598     int width,
599     int height,
600     int format,
601     int num_surfaces,
602     VASurfaceID *surfaces       /* out */
603 )
604 {
605   VADriverContextP ctx = CTX(dpy);
606   CHECK_CONTEXT(ctx);
607
608   TRACE(vaCreateSurfaces);
609   return ctx->vtable.vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces );
610 }
611
612 VAStatus vaDestroySurfaces (
613     VADisplay dpy,
614     VASurfaceID *surface_list,
615     int num_surfaces
616 )
617 {
618   VADriverContextP ctx = CTX(dpy);
619   CHECK_CONTEXT(ctx);
620
621   TRACE(vaDestroySurfaces);
622   return ctx->vtable.vaDestroySurfaces( ctx, surface_list, num_surfaces );
623 }
624
625 VAStatus vaCreateContext (
626     VADisplay dpy,
627     VAConfigID config_id,
628     int picture_width,
629     int picture_height,
630     int flag,
631     VASurfaceID *render_targets,
632     int num_render_targets,
633     VAContextID *context                /* out */
634 )
635 {
636   VADriverContextP ctx = CTX(dpy);
637   CHECK_CONTEXT(ctx);
638
639   TRACE(vaCreateContext);
640   return ctx->vtable.vaCreateContext( ctx, config_id, picture_width, picture_height,
641                                       flag, render_targets, num_render_targets, context );
642 }
643
644 VAStatus vaDestroyContext (
645     VADisplay dpy,
646     VAContextID context
647 )
648 {
649   VADriverContextP ctx = CTX(dpy);
650   CHECK_CONTEXT(ctx);
651
652   TRACE(vaDestroyContext);
653   return ctx->vtable.vaDestroyContext( ctx, context );
654 }
655
656 VAStatus vaCreateBuffer (
657     VADisplay dpy,
658     VAContextID context,        /* in */
659     VABufferType type,          /* in */
660     unsigned int size,          /* in */
661     unsigned int num_elements,  /* in */
662     void *data,                 /* in */
663     VABufferID *buf_id          /* out */
664 )
665 {
666   VADriverContextP ctx = CTX(dpy);
667   CHECK_CONTEXT(ctx);
668
669   TRACE(vaCreateBuffer);
670   return ctx->vtable.vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
671 }
672
673 VAStatus vaBufferSetNumElements (
674     VADisplay dpy,
675     VABufferID buf_id,  /* in */
676     unsigned int num_elements /* in */
677 )
678 {
679   VADriverContextP ctx = CTX(dpy);
680   CHECK_CONTEXT(ctx);
681
682   TRACE(vaBufferSetNumElements);
683   return ctx->vtable.vaBufferSetNumElements( ctx, buf_id, num_elements );
684 }
685
686
687 VAStatus vaMapBuffer (
688     VADisplay dpy,
689     VABufferID buf_id,  /* in */
690     void **pbuf         /* out */
691 )
692 {
693   VADriverContextP ctx = CTX(dpy);
694   CHECK_CONTEXT(ctx);
695
696   TRACE(vaMapBuffer);
697   return ctx->vtable.vaMapBuffer( ctx, buf_id, pbuf );
698 }
699
700 VAStatus vaUnmapBuffer (
701     VADisplay dpy,
702     VABufferID buf_id   /* in */
703 )
704 {
705   VADriverContextP ctx = CTX(dpy);
706   CHECK_CONTEXT(ctx);
707
708   TRACE(vaUnmapBuffer);
709   return ctx->vtable.vaUnmapBuffer( ctx, buf_id );
710 }
711
712 VAStatus vaDestroyBuffer (
713     VADisplay dpy,
714     VABufferID buffer_id
715 )
716 {
717   VADriverContextP ctx = CTX(dpy);
718   CHECK_CONTEXT(ctx);
719
720   TRACE(vaDestroyBuffer);
721   return ctx->vtable.vaDestroyBuffer( ctx, buffer_id );
722 }
723
724 VAStatus vaBeginPicture (
725     VADisplay dpy,
726     VAContextID context,
727     VASurfaceID render_target
728 )
729 {
730   VADriverContextP ctx = CTX(dpy);
731   CHECK_CONTEXT(ctx);
732
733   TRACE(vaBeginPicture);
734   return ctx->vtable.vaBeginPicture( ctx, context, render_target );
735 }
736
737 VAStatus vaRenderPicture (
738     VADisplay dpy,
739     VAContextID context,
740     VABufferID *buffers,
741     int num_buffers
742 )
743 {
744   VADriverContextP ctx = CTX(dpy);
745   CHECK_CONTEXT(ctx);
746
747   TRACE(vaRenderPicture);
748   return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers );
749 }
750
751 VAStatus vaEndPicture (
752     VADisplay dpy,
753     VAContextID context
754 )
755 {
756   VADriverContextP ctx = CTX(dpy);
757   CHECK_CONTEXT(ctx);
758
759   TRACE(vaEndPicture);
760   return ctx->vtable.vaEndPicture( ctx, context );
761 }
762
763 VAStatus vaSyncSurface (
764     VADisplay dpy,
765     VAContextID context,
766     VASurfaceID render_target
767 )
768 {
769   VADriverContextP ctx = CTX(dpy);
770   CHECK_CONTEXT(ctx);
771
772   TRACE(vaSyncSurface);
773   return ctx->vtable.vaSyncSurface( ctx, context, render_target );
774 }
775
776 VAStatus vaQuerySurfaceStatus (
777     VADisplay dpy,
778     VASurfaceID render_target,
779     VASurfaceStatus *status     /* out */
780 )
781 {
782   VADriverContextP ctx = CTX(dpy);
783   CHECK_CONTEXT(ctx);
784
785   TRACE(vaQuerySurfaceStatus);
786   return ctx->vtable.vaQuerySurfaceStatus( ctx, render_target, status );
787 }
788
789 VAStatus vaPutSurface (
790     VADisplay dpy,
791     VASurfaceID surface,
792     Drawable draw, /* X Drawable */
793     short srcx,
794     short srcy,
795     unsigned short srcw,
796     unsigned short srch,
797     short destx,
798     short desty,
799     unsigned short destw,
800     unsigned short desth,
801     VARectangle *cliprects, /* client supplied clip list */
802     unsigned int number_cliprects, /* number of clip rects in the clip list */
803     unsigned int flags /* de-interlacing flags */
804 )
805 {
806   VADriverContextP ctx = CTX(dpy);
807   CHECK_CONTEXT(ctx);
808
809   TRACE(vaPutSurface);
810   return ctx->vtable.vaPutSurface( ctx, surface, draw, srcx, srcy, srcw, srch,
811                                    destx, desty, destw, desth,
812                                    cliprects, number_cliprects, flags );
813 }
814
815 /* Get maximum number of image formats supported by the implementation */
816 int vaMaxNumImageFormats (
817     VADisplay dpy
818 )
819 {
820   VADriverContextP ctx = CTX(dpy);
821   if( !vaContextIsValid(ctx) )
822   {
823       return 0;
824   }
825   
826   return ctx->max_image_formats;
827 }
828
829 VAStatus vaQueryImageFormats (
830     VADisplay dpy,
831     VAImageFormat *format_list, /* out */
832     int *num_formats            /* out */
833 )
834 {
835   VADriverContextP ctx = CTX(dpy);
836   CHECK_CONTEXT(ctx);
837
838   TRACE(vaQueryImageFormats);
839   return ctx->vtable.vaQueryImageFormats ( ctx, format_list, num_formats);
840 }
841
842 /* 
843  * The width and height fields returned in the VAImage structure may get 
844  * enlarged for some YUV formats. The size of the data buffer that needs
845  * to be allocated will be given in the "data_size" field in VAImage.
846  * Image data is not allocated by this function.  The client should
847  * allocate the memory and fill in the VAImage structure's data field
848  * after looking at "data_size" returned from the library.
849  */
850 VAStatus vaCreateImage (
851     VADisplay dpy,
852     VAImageFormat *format,
853     int width,
854     int height,
855     VAImage *image      /* out */
856 )
857 {
858   VADriverContextP ctx = CTX(dpy);
859   CHECK_CONTEXT(ctx);
860
861   TRACE(vaCreateImage);
862   return ctx->vtable.vaCreateImage ( ctx, format, width, height, image);
863 }
864
865 /*
866  * Should call DestroyImage before destroying the surface it is bound to
867  */
868 VAStatus vaDestroyImage (
869     VADisplay dpy,
870     VAImageID image
871 )
872 {
873   VADriverContextP ctx = CTX(dpy);
874   CHECK_CONTEXT(ctx);
875
876   TRACE(vaDestroyImage);
877   return ctx->vtable.vaDestroyImage ( ctx, image);
878 }
879
880 VAStatus vaSetImagePalette (
881     VADisplay dpy,
882     VAImageID image,
883     unsigned char *palette
884 )
885 {
886   VADriverContextP ctx = CTX(dpy);
887   CHECK_CONTEXT(ctx);
888
889   TRACE(vaSetImagePalette);
890   return ctx->vtable.vaSetImagePalette ( ctx, image, palette);
891 }
892
893 /*
894  * Retrieve surface data into a VAImage
895  * Image must be in a format supported by the implementation
896  */
897 VAStatus vaGetImage (
898     VADisplay dpy,
899     VASurfaceID surface,
900     int x,      /* coordinates of the upper left source pixel */
901     int y,
902     unsigned int width, /* width and height of the region */
903     unsigned int height,
904     VAImageID image
905 )
906 {
907   VADriverContextP ctx = CTX(dpy);
908   CHECK_CONTEXT(ctx);
909
910   TRACE(vaGetImage);
911   return ctx->vtable.vaGetImage ( ctx, surface, x, y, width, height, image);
912 }
913
914 /*
915  * Copy data from a VAImage to a surface
916  * Image must be in a format supported by the implementation
917  */
918 VAStatus vaPutImage (
919     VADisplay dpy,
920     VASurfaceID surface,
921     VAImageID image,
922     int src_x,
923     int src_y,
924     unsigned int width,
925     unsigned int height,
926     int dest_x,
927     int dest_y
928 )
929 {
930   VADriverContextP ctx = CTX(dpy);
931   CHECK_CONTEXT(ctx);
932
933   TRACE(vaPutImage);
934   return ctx->vtable.vaPutImage ( ctx, surface, image, src_x, src_y, width, height, dest_x, dest_y );
935 }
936
937 /* Get maximum number of subpicture formats supported by the implementation */
938 int vaMaxNumSubpictureFormats (
939     VADisplay dpy
940 )
941 {
942   VADriverContextP ctx = CTX(dpy);
943   if( !vaContextIsValid(ctx) )
944   {
945       return 0;
946   }
947   
948   return ctx->max_subpic_formats;
949 }
950
951 /* 
952  * Query supported subpicture formats 
953  * The caller must provide a "format_list" array that can hold at
954  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 
955  * for each format to indicate additional capabilities for that format. The actual 
956  * number of formats returned in "format_list" is returned in "num_formats".
957  */
958 VAStatus vaQuerySubpictureFormats (
959     VADisplay dpy,
960     VAImageFormat *format_list, /* out */
961     unsigned int *flags,        /* out */
962     unsigned int *num_formats   /* out */
963 )
964 {
965   VADriverContextP ctx = CTX(dpy);
966   CHECK_CONTEXT(ctx);
967
968   TRACE(vaQuerySubpictureFormats);
969   return ctx->vtable.vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
970 }
971
972 /* 
973  * Subpictures are created with an image associated. 
974  */
975 VAStatus vaCreateSubpicture (
976     VADisplay dpy,
977     VAImageID image,
978     VASubpictureID *subpicture  /* out */
979 )
980 {
981   VADriverContextP ctx = CTX(dpy);
982   CHECK_CONTEXT(ctx);
983
984   TRACE(vaCreateSubpicture);
985   return ctx->vtable.vaCreateSubpicture ( ctx, image, subpicture );
986 }
987
988 /*
989  * Destroy the subpicture before destroying the image it is assocated to
990  */
991 VAStatus vaDestroySubpicture (
992     VADisplay dpy,
993     VASubpictureID subpicture
994 )
995 {
996   VADriverContextP ctx = CTX(dpy);
997   CHECK_CONTEXT(ctx);
998
999   TRACE(vaDestroySubpicture);
1000   return ctx->vtable.vaDestroySubpicture ( ctx, subpicture);
1001 }
1002
1003 VAStatus vaSetSubpictureImage (
1004     VADisplay dpy,
1005     VASubpictureID subpicture,
1006     VAImageID image
1007 )
1008 {
1009   VADriverContextP ctx = CTX(dpy);
1010   CHECK_CONTEXT(ctx);
1011
1012   TRACE(vaSetSubpictureImage);
1013   return ctx->vtable.vaSetSubpictureImage ( ctx, subpicture, image);
1014 }
1015
1016
1017 VAStatus vaSetSubpicturePalette (
1018     VADisplay dpy,
1019     VASubpictureID subpicture,
1020     /* 
1021      * pointer to an array holding the palette data.  The size of the array is 
1022      * num_palette_entries * entry_bytes in size.  The order of the components
1023      * in the palette is described by the component_order in VASubpicture struct
1024      */
1025     unsigned char *palette 
1026 )
1027 {
1028   VADriverContextP ctx = CTX(dpy);
1029   CHECK_CONTEXT(ctx);
1030
1031   TRACE(vaSetSubpicturePalette);
1032   return ctx->vtable.vaSetSubpicturePalette ( ctx, subpicture, palette);
1033 }
1034
1035 /*
1036  * If chromakey is enabled, then the area where the source value falls within
1037  * the chromakey [min, max] range is transparent
1038  */
1039 VAStatus vaSetSubpictureChromakey (
1040     VADisplay dpy,
1041     VASubpictureID subpicture,
1042     unsigned int chromakey_min,
1043     unsigned int chromakey_max,
1044     unsigned int chromakey_mask
1045 )
1046 {
1047   VADriverContextP ctx = CTX(dpy);
1048   CHECK_CONTEXT(ctx);
1049
1050   TRACE(vaSetSubpictureChromakey);
1051   return ctx->vtable.vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1052 }
1053
1054
1055 /*
1056  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 
1057  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1058  * the overall alpha is per-pixel alpha multiplied by the global alpha
1059  */
1060 VAStatus vaSetSubpictureGlobalAlpha (
1061     VADisplay dpy,
1062     VASubpictureID subpicture,
1063     float global_alpha 
1064 )
1065 {
1066   VADriverContextP ctx = CTX(dpy);
1067   CHECK_CONTEXT(ctx);
1068
1069   TRACE(vaSetSubpictureGlobalAlpha);
1070   return ctx->vtable.vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1071 }
1072
1073 /*
1074   vaAssociateSubpicture associates the subpicture with the target_surface.
1075   It defines the region mapping between the subpicture and the target 
1076   surface through source and destination rectangles (with the same width and height).
1077   Both will be displayed at the next call to vaPutSurface.  Additional
1078   associations before the call to vaPutSurface simply overrides the association.
1079 */
1080 VAStatus vaAssociateSubpicture (
1081     VADisplay dpy,
1082     VASubpictureID subpicture,
1083     VASurfaceID *target_surfaces,
1084     int num_surfaces,
1085     short src_x, /* upper left offset in subpicture */
1086     short src_y,
1087     short dest_x, /* upper left offset in surface */
1088     short dest_y,
1089     unsigned short width,
1090     unsigned short height,
1091     /*
1092      * whether to enable chroma-keying or global-alpha
1093      * see VA_SUBPICTURE_XXX values
1094      */
1095     unsigned int flags
1096 )
1097 {
1098   VADriverContextP ctx = CTX(dpy);
1099   CHECK_CONTEXT(ctx);
1100
1101   TRACE(vaAssociateSubpicture);
1102   return ctx->vtable.vaAssociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces, src_x, src_y, dest_x, dest_y, width, height, flags );
1103 }
1104
1105 /*
1106  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1107  */
1108 VAStatus vaDeassociateSubpicture (
1109     VADisplay dpy,
1110     VASubpictureID subpicture,
1111     VASurfaceID *target_surfaces,
1112     int num_surfaces
1113 )
1114 {
1115   VADriverContextP ctx = CTX(dpy);
1116   CHECK_CONTEXT(ctx);
1117
1118   TRACE(vaDeassociateSubpicture);
1119   return ctx->vtable.vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1120 }
1121
1122
1123 /* Get maximum number of display attributes supported by the implementation */
1124 int vaMaxNumDisplayAttributes (
1125     VADisplay dpy
1126 )
1127 {
1128   VADriverContextP ctx = CTX(dpy);
1129   if( !vaContextIsValid(ctx) )
1130   {
1131       return 0;
1132   }
1133   
1134   return ctx->max_display_attributes;
1135 }
1136
1137 /* 
1138  * Query display attributes 
1139  * The caller must provide a "attr_list" array that can hold at
1140  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1141  * returned in "attr_list" is returned in "num_attributes".
1142  */
1143 VAStatus vaQueryDisplayAttributes (
1144     VADisplay dpy,
1145     VADisplayAttribute *attr_list,      /* out */
1146     int *num_attributes                 /* out */
1147 )
1148 {
1149   VADriverContextP ctx = CTX(dpy);
1150   CHECK_CONTEXT(ctx);
1151
1152   TRACE(vaQueryDisplayAttributes);
1153   return ctx->vtable.vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1154 }
1155
1156 /* 
1157  * Get display attributes 
1158  * This function returns the current attribute values in "attr_list".
1159  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1160  * from vaQueryDisplayAttributes() can have their values retrieved.  
1161  */
1162 VAStatus vaGetDisplayAttributes (
1163     VADisplay dpy,
1164     VADisplayAttribute *attr_list,      /* in/out */
1165     int num_attributes
1166 )
1167 {
1168   VADriverContextP ctx = CTX(dpy);
1169   CHECK_CONTEXT(ctx);
1170
1171   TRACE(vaGetDisplayAttributes);
1172   return ctx->vtable.vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1173 }
1174
1175 /* 
1176  * Set display attributes 
1177  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1178  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1179  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1180  */
1181 VAStatus vaSetDisplayAttributes (
1182     VADisplay dpy,
1183     VADisplayAttribute *attr_list,
1184     int num_attributes
1185 )
1186 {
1187   VADriverContextP ctx = CTX(dpy);
1188   CHECK_CONTEXT(ctx);
1189
1190   TRACE(vaSetDisplayAttributes);
1191   return ctx->vtable.vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1192 }
1193
1194
1195
1196 VAStatus vaDbgCopySurfaceToBuffer(VADisplay dpy,
1197     VASurfaceID surface,
1198     void **buffer, /* out */
1199     unsigned int *stride /* out */
1200 )
1201 {
1202   VADriverContextP ctx = CTX(dpy);
1203   CHECK_CONTEXT(ctx);
1204
1205   TRACE(vaDbgCopySurfaceToBuffer);
1206   return ctx->vtable.vaDbgCopySurfaceToBuffer( ctx, surface, buffer, stride );
1207 }
1208