OSDN Git Service

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