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