OSDN Git Service

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