OSDN Git Service

* VC1: Add 'quantizer' to pic params
[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        29
39 #define DRIVER_INIT_FUNC        "__vaDriverInit_0_29"
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 = NULL;
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, DeriveImage);
303                     CHECK_VTABLE(vaStatus, ctx, DestroyImage);
304                     CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
305                     CHECK_VTABLE(vaStatus, ctx, GetImage);
306                     CHECK_VTABLE(vaStatus, ctx, PutImage);
307                     CHECK_VTABLE(vaStatus, ctx, PutImage2);
308                     CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
309                     CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
310                     CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
311                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
312                     CHECK_VTABLE(vaStatus, ctx, SetSubpicturePalette);
313                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
314                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
315                     CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
316                     CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture2);
317                     CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
318                     CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
319                     CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
320                     CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
321                     CHECK_VTABLE(vaStatus, ctx, DbgCopySurfaceToBuffer);
322                 }
323                 if (VA_STATUS_SUCCESS != vaStatus)
324                 {
325                     va_errorMessage("%s init failed\n", driver_path);
326                     dlclose(handle);
327                 }
328                 if (VA_STATUS_SUCCESS == vaStatus)
329                 {
330                     ctx->handle = handle;
331                 }
332                 free(driver_path);
333                 break;
334             }
335         }
336         free(driver_path);
337         
338         driver_dir = strtok_r(NULL, ":", &saveptr);
339     }
340     
341     free(search_path);    
342     
343     return vaStatus;
344 }
345
346 VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
347 {
348     VADriverContextP ctx = CTX(dpy);
349     if( !vaContextIsValid(ctx) )
350         return NULL;
351
352     if (NULL == ctx->handle)
353         return NULL;
354         
355     return (VAPrivFunc) dlsym(ctx->handle, func);
356 }
357
358
359 /*
360  * Returns a short english description of error_status
361  */
362 const char *vaErrorStr(VAStatus error_status)
363 {
364     switch(error_status)
365     {
366         case VA_STATUS_SUCCESS:
367             return "success (no error)";
368         case VA_STATUS_ERROR_ALLOCATION_FAILED:
369             return "resource allocation failed";
370         case VA_STATUS_ERROR_INVALID_CONFIG:
371             return "invalid VAConfigID";
372         case VA_STATUS_ERROR_INVALID_CONTEXT:
373             return "invalid VAContextID";
374         case VA_STATUS_ERROR_INVALID_SURFACE:
375             return "invalid VASurfaceID";
376         case VA_STATUS_ERROR_INVALID_BUFFER:
377             return "invalid VABufferID";
378         case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
379             return "attribute not supported";
380         case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
381             return "list argument exceeds maximum number";
382         case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
383             return "the requested VAProfile is not supported";
384         case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
385             return "the requested VAEntryPoint is not supported";
386         case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
387             return "the requested RT Format is not supported";
388         case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
389             return "the requested VABufferType is not supported";
390         case VA_STATUS_ERROR_SURFACE_BUSY:
391             return "surface is in use";
392         case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
393             return "flag not supported";
394         case VA_STATUS_ERROR_UNKNOWN:
395             return "unknown libva error";
396     }
397     return "unknown libva error / description missing";
398 }
399       
400 VAStatus vaInitialize (
401     VADisplay dpy,
402     int *major_version,  /* out */
403     int *minor_version   /* out */
404 )
405 {
406   VADriverContextP ctx = CTX(dpy);
407   char *driver_name = NULL;
408   VAStatus vaStatus;
409   
410   CHECK_CONTEXT(ctx);
411
412   va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL);
413
414   vaStatus = va_getDriverName(ctx, &driver_name);
415   va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
416   
417   if (VA_STATUS_SUCCESS == vaStatus)
418   {
419       vaStatus = va_openDriver(ctx, driver_name);
420       va_infoMessage("va_openDriver() returns %d\n", vaStatus);
421       
422       *major_version = VA_MAJOR_VERSION;
423       *minor_version = VA_MINOR_VERSION;
424   }
425
426   if (driver_name)
427   {
428       XFree(driver_name);
429   }
430   return vaStatus;
431 }
432
433
434 /*
435  * After this call, all library internal resources will be cleaned up
436  */ 
437 VAStatus vaTerminate (
438     VADisplay dpy
439 )
440 {
441   VAStatus vaStatus = VA_STATUS_SUCCESS;
442   VADriverContextP old_ctx = CTX(dpy);
443   CHECK_CONTEXT(old_ctx);
444
445   if (old_ctx->handle)
446   {
447       vaStatus = old_ctx->vtable.vaTerminate(old_ctx);
448       dlclose(old_ctx->handle);
449       old_ctx->handle = NULL;
450   }
451
452   if (VA_STATUS_SUCCESS == vaStatus)
453   {
454       VADriverContextP *ctx = &pDriverContexts;
455
456       /* Throw away old_ctx */
457       while (*ctx)
458       {
459           if (*ctx == old_ctx)
460           {
461               *ctx = old_ctx->pNext;
462               old_ctx->pNext = NULL;
463               break;
464           }
465           ctx = &((*ctx)->pNext);
466       }
467       free(old_ctx);
468   }
469   return vaStatus;
470 }
471
472 /*
473  * vaQueryVendorString returns a pointer to a zero-terminated string
474  * describing some aspects of the VA implemenation on a specific
475  * hardware accelerator. The format of the returned string is:
476  * <vendorname>-<major_version>-<minor_version>-<addtional_info>
477  * e.g. for the Intel GMA500 implementation, an example would be:
478  * "IntelGMA500-1.0-0.2-patch3
479  */
480 const char *vaQueryVendorString (
481     VADisplay dpy
482 )
483 {
484   VADriverContextP ctx = CTX(dpy);
485   if( !vaContextIsValid(ctx) )
486   {
487       return NULL;
488   }
489   
490   return ctx->str_vendor;
491 }
492
493
494 /* Get maximum number of profiles supported by the implementation */
495 int vaMaxNumProfiles (
496     VADisplay dpy
497 )
498 {
499   VADriverContextP ctx = CTX(dpy);
500   if( !vaContextIsValid(ctx) )
501   {
502       return 0;
503   }
504   
505   return ctx->max_profiles;
506 }
507
508 /* Get maximum number of entrypoints supported by the implementation */
509 int vaMaxNumEntrypoints (
510     VADisplay dpy
511 )
512 {
513   VADriverContextP ctx = CTX(dpy);
514   if( !vaContextIsValid(ctx) )
515   {
516       return 0;
517   }
518   
519   return ctx->max_entrypoints;
520 }
521
522
523 /* Get maximum number of attributs supported by the implementation */
524 int vaMaxNumConfigAttributes (
525     VADisplay dpy
526 )
527 {
528   VADriverContextP ctx = CTX(dpy);
529   if( !vaContextIsValid(ctx) )
530   {
531       return 0;
532   }
533   
534   return ctx->max_attributes;
535 }
536
537 VAStatus vaQueryConfigEntrypoints (
538     VADisplay dpy,
539     VAProfile profile,
540     VAEntrypoint *entrypoints,  /* out */
541     int *num_entrypoints        /* out */
542 )
543 {
544   VADriverContextP ctx = CTX(dpy);
545   CHECK_CONTEXT(ctx);
546
547   TRACE(vaQueryConfigEntrypoints);
548   return ctx->vtable.vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
549 }
550
551 VAStatus vaGetConfigAttributes (
552     VADisplay dpy,
553     VAProfile profile,
554     VAEntrypoint entrypoint,
555     VAConfigAttrib *attrib_list, /* in/out */
556     int num_attribs
557 )
558 {
559   VADriverContextP ctx = CTX(dpy);
560   CHECK_CONTEXT(ctx);
561
562   TRACE(vaGetConfigAttributes);
563   return ctx->vtable.vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
564 }
565
566 VAStatus vaQueryConfigProfiles (
567     VADisplay dpy,
568     VAProfile *profile_list,    /* out */
569     int *num_profiles           /* out */
570 )
571 {
572   VADriverContextP ctx = CTX(dpy);
573   CHECK_CONTEXT(ctx);
574
575   TRACE(vaQueryConfigProfiles);
576   return ctx->vtable.vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
577 }
578
579 VAStatus vaCreateConfig (
580     VADisplay dpy,
581     VAProfile profile, 
582     VAEntrypoint entrypoint, 
583     VAConfigAttrib *attrib_list,
584     int num_attribs,
585     VAConfigID *config_id /* out */
586 )
587 {
588   VADriverContextP ctx = CTX(dpy);
589   CHECK_CONTEXT(ctx);
590
591   TRACE(vaCreateConfig);
592   return ctx->vtable.vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
593 }
594
595 VAStatus vaDestroyConfig (
596     VADisplay dpy,
597     VAConfigID config_id
598 )
599 {
600   VADriverContextP ctx = CTX(dpy);
601   CHECK_CONTEXT(ctx);
602
603   TRACE(vaDestroyConfig);
604   return ctx->vtable.vaDestroyConfig ( ctx, config_id );
605 }
606
607 VAStatus vaQueryConfigAttributes (
608     VADisplay dpy,
609     VAConfigID config_id, 
610     VAProfile *profile,         /* out */
611     VAEntrypoint *entrypoint,   /* out */
612     VAConfigAttrib *attrib_list,/* out */
613     int *num_attribs            /* out */
614 )
615 {
616   VADriverContextP ctx = CTX(dpy);
617   CHECK_CONTEXT(ctx);
618
619   TRACE(vaQueryConfigAttributes);
620   return ctx->vtable.vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
621 }
622
623 VAStatus vaCreateSurfaces (
624     VADisplay dpy,
625     int width,
626     int height,
627     int format,
628     int num_surfaces,
629     VASurfaceID *surfaces       /* out */
630 )
631 {
632   VADriverContextP ctx = CTX(dpy);
633   CHECK_CONTEXT(ctx);
634
635   TRACE(vaCreateSurfaces);
636   return ctx->vtable.vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces );
637 }
638
639 VAStatus vaDestroySurfaces (
640     VADisplay dpy,
641     VASurfaceID *surface_list,
642     int num_surfaces
643 )
644 {
645   VADriverContextP ctx = CTX(dpy);
646   CHECK_CONTEXT(ctx);
647
648   TRACE(vaDestroySurfaces);
649   return ctx->vtable.vaDestroySurfaces( ctx, surface_list, num_surfaces );
650 }
651
652 VAStatus vaCreateContext (
653     VADisplay dpy,
654     VAConfigID config_id,
655     int picture_width,
656     int picture_height,
657     int flag,
658     VASurfaceID *render_targets,
659     int num_render_targets,
660     VAContextID *context                /* out */
661 )
662 {
663   VADriverContextP ctx = CTX(dpy);
664   CHECK_CONTEXT(ctx);
665
666   TRACE(vaCreateContext);
667   return ctx->vtable.vaCreateContext( ctx, config_id, picture_width, picture_height,
668                                       flag, render_targets, num_render_targets, context );
669 }
670
671 VAStatus vaDestroyContext (
672     VADisplay dpy,
673     VAContextID context
674 )
675 {
676   VADriverContextP ctx = CTX(dpy);
677   CHECK_CONTEXT(ctx);
678
679   TRACE(vaDestroyContext);
680   return ctx->vtable.vaDestroyContext( ctx, context );
681 }
682
683 VAStatus vaCreateBuffer (
684     VADisplay dpy,
685     VAContextID context,        /* in */
686     VABufferType type,          /* in */
687     unsigned int size,          /* in */
688     unsigned int num_elements,  /* in */
689     void *data,                 /* in */
690     VABufferID *buf_id          /* out */
691 )
692 {
693   VADriverContextP ctx = CTX(dpy);
694   CHECK_CONTEXT(ctx);
695
696   TRACE(vaCreateBuffer);
697   return ctx->vtable.vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
698 }
699
700 VAStatus vaBufferSetNumElements (
701     VADisplay dpy,
702     VABufferID buf_id,  /* in */
703     unsigned int num_elements /* in */
704 )
705 {
706   VADriverContextP ctx = CTX(dpy);
707   CHECK_CONTEXT(ctx);
708
709   TRACE(vaBufferSetNumElements);
710   return ctx->vtable.vaBufferSetNumElements( ctx, buf_id, num_elements );
711 }
712
713
714 VAStatus vaMapBuffer (
715     VADisplay dpy,
716     VABufferID buf_id,  /* in */
717     void **pbuf         /* out */
718 )
719 {
720   VADriverContextP ctx = CTX(dpy);
721   CHECK_CONTEXT(ctx);
722
723   TRACE(vaMapBuffer);
724   return ctx->vtable.vaMapBuffer( ctx, buf_id, pbuf );
725 }
726
727 VAStatus vaUnmapBuffer (
728     VADisplay dpy,
729     VABufferID buf_id   /* in */
730 )
731 {
732   VADriverContextP ctx = CTX(dpy);
733   CHECK_CONTEXT(ctx);
734
735   TRACE(vaUnmapBuffer);
736   return ctx->vtable.vaUnmapBuffer( ctx, buf_id );
737 }
738
739 VAStatus vaDestroyBuffer (
740     VADisplay dpy,
741     VABufferID buffer_id
742 )
743 {
744   VADriverContextP ctx = CTX(dpy);
745   CHECK_CONTEXT(ctx);
746
747   TRACE(vaDestroyBuffer);
748   return ctx->vtable.vaDestroyBuffer( ctx, buffer_id );
749 }
750
751 VAStatus vaBeginPicture (
752     VADisplay dpy,
753     VAContextID context,
754     VASurfaceID render_target
755 )
756 {
757   VADriverContextP ctx = CTX(dpy);
758   CHECK_CONTEXT(ctx);
759
760   TRACE(vaBeginPicture);
761   return ctx->vtable.vaBeginPicture( ctx, context, render_target );
762 }
763
764 VAStatus vaRenderPicture (
765     VADisplay dpy,
766     VAContextID context,
767     VABufferID *buffers,
768     int num_buffers
769 )
770 {
771   VADriverContextP ctx = CTX(dpy);
772   CHECK_CONTEXT(ctx);
773
774   TRACE(vaRenderPicture);
775   return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers );
776 }
777
778 VAStatus vaEndPicture (
779     VADisplay dpy,
780     VAContextID context
781 )
782 {
783   VADriverContextP ctx = CTX(dpy);
784   CHECK_CONTEXT(ctx);
785
786   TRACE(vaEndPicture);
787   return ctx->vtable.vaEndPicture( ctx, context );
788 }
789
790 VAStatus vaSyncSurface (
791     VADisplay dpy,
792     VAContextID context,
793     VASurfaceID render_target
794 )
795 {
796   VADriverContextP ctx = CTX(dpy);
797   CHECK_CONTEXT(ctx);
798
799   TRACE(vaSyncSurface);
800   return ctx->vtable.vaSyncSurface( ctx, context, render_target );
801 }
802
803 VAStatus vaQuerySurfaceStatus (
804     VADisplay dpy,
805     VASurfaceID render_target,
806     VASurfaceStatus *status     /* out */
807 )
808 {
809   VADriverContextP ctx = CTX(dpy);
810   CHECK_CONTEXT(ctx);
811
812   TRACE(vaQuerySurfaceStatus);
813   return ctx->vtable.vaQuerySurfaceStatus( ctx, render_target, status );
814 }
815
816 VAStatus vaPutSurface (
817     VADisplay dpy,
818     VASurfaceID surface,
819     Drawable draw, /* X Drawable */
820     short srcx,
821     short srcy,
822     unsigned short srcw,
823     unsigned short srch,
824     short destx,
825     short desty,
826     unsigned short destw,
827     unsigned short desth,
828     VARectangle *cliprects, /* client supplied clip list */
829     unsigned int number_cliprects, /* number of clip rects in the clip list */
830     unsigned int flags /* de-interlacing flags */
831 )
832 {
833   VADriverContextP ctx = CTX(dpy);
834   CHECK_CONTEXT(ctx);
835
836   TRACE(vaPutSurface);
837   return ctx->vtable.vaPutSurface( ctx, surface, draw, srcx, srcy, srcw, srch,
838                                    destx, desty, destw, desth,
839                                    cliprects, number_cliprects, flags );
840 }
841
842 /* Get maximum number of image formats supported by the implementation */
843 int vaMaxNumImageFormats (
844     VADisplay dpy
845 )
846 {
847   VADriverContextP ctx = CTX(dpy);
848   if( !vaContextIsValid(ctx) )
849   {
850       return 0;
851   }
852   
853   return ctx->max_image_formats;
854 }
855
856 VAStatus vaQueryImageFormats (
857     VADisplay dpy,
858     VAImageFormat *format_list, /* out */
859     int *num_formats            /* out */
860 )
861 {
862   VADriverContextP ctx = CTX(dpy);
863   CHECK_CONTEXT(ctx);
864
865   TRACE(vaQueryImageFormats);
866   return ctx->vtable.vaQueryImageFormats ( ctx, format_list, num_formats);
867 }
868
869 /* 
870  * The width and height fields returned in the VAImage structure may get 
871  * enlarged for some YUV formats. The size of the data buffer that needs
872  * to be allocated will be given in the "data_size" field in VAImage.
873  * Image data is not allocated by this function.  The client should
874  * allocate the memory and fill in the VAImage structure's data field
875  * after looking at "data_size" returned from the library.
876  */
877 VAStatus vaCreateImage (
878     VADisplay dpy,
879     VAImageFormat *format,
880     int width,
881     int height,
882     VAImage *image      /* out */
883 )
884 {
885   VADriverContextP ctx = CTX(dpy);
886   CHECK_CONTEXT(ctx);
887
888   TRACE(vaCreateImage);
889   return ctx->vtable.vaCreateImage ( ctx, format, width, height, image);
890 }
891
892 /*
893  * Should call DestroyImage before destroying the surface it is bound to
894  */
895 VAStatus vaDestroyImage (
896     VADisplay dpy,
897     VAImageID image
898 )
899 {
900   VADriverContextP ctx = CTX(dpy);
901   CHECK_CONTEXT(ctx);
902
903   TRACE(vaDestroyImage);
904   return ctx->vtable.vaDestroyImage ( ctx, image);
905 }
906
907 VAStatus vaSetImagePalette (
908     VADisplay dpy,
909     VAImageID image,
910     unsigned char *palette
911 )
912 {
913   VADriverContextP ctx = CTX(dpy);
914   CHECK_CONTEXT(ctx);
915
916   TRACE(vaSetImagePalette);
917   return ctx->vtable.vaSetImagePalette ( ctx, image, palette);
918 }
919
920 /*
921  * Retrieve surface data into a VAImage
922  * Image must be in a format supported by the implementation
923  */
924 VAStatus vaGetImage (
925     VADisplay dpy,
926     VASurfaceID surface,
927     int x,      /* coordinates of the upper left source pixel */
928     int y,
929     unsigned int width, /* width and height of the region */
930     unsigned int height,
931     VAImageID image
932 )
933 {
934   VADriverContextP ctx = CTX(dpy);
935   CHECK_CONTEXT(ctx);
936
937   TRACE(vaGetImage);
938   return ctx->vtable.vaGetImage ( ctx, surface, x, y, width, height, image);
939 }
940
941 /*
942  * Copy data from a VAImage to a surface
943  * Image must be in a format supported by the implementation
944  */
945 VAStatus vaPutImage (
946     VADisplay dpy,
947     VASurfaceID surface,
948     VAImageID image,
949     int src_x,
950     int src_y,
951     unsigned int width,
952     unsigned int height,
953     int dest_x,
954     int dest_y
955 )
956 {
957   VADriverContextP ctx = CTX(dpy);
958   CHECK_CONTEXT(ctx);
959
960   TRACE(vaPutImage);
961   return ctx->vtable.vaPutImage ( ctx, surface, image, src_x, src_y, width, height, dest_x, dest_y );
962 }
963
964 /*
965  * Similar to vaPutImage but with additional destination width
966  * and height arguments to enable scaling
967  */
968 VAStatus vaPutImage2 (
969     VADisplay dpy,
970     VASurfaceID surface,
971     VAImageID image,
972     int src_x,
973     int src_y,
974     unsigned int src_width,
975     unsigned int src_height,
976     int dest_x,
977     int dest_y,
978     unsigned int dest_width,
979     unsigned int dest_height
980 )
981 {
982   VADriverContextP ctx = CTX(dpy);
983   CHECK_CONTEXT(ctx);
984
985   TRACE(vaPutImage2);
986   return ctx->vtable.vaPutImage2 ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
987 }
988
989 /*
990  * Derive an VAImage from an existing surface.
991  * This interface will derive a VAImage and corresponding image buffer from
992  * an existing VA Surface. The image buffer can then be mapped/unmapped for
993  * direct CPU access. This operation is only possible on implementations with
994  * direct rendering capabilities and internal surface formats that can be
995  * represented with a VAImage. When the operation is not possible this interface
996  * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
997  * to using vaCreateImage + vaPutImage to accomplish the same task in an
998  * indirect manner.
999  *
1000  * Implementations should only return success when the resulting image buffer
1001  * would be useable with vaMap/Unmap.
1002  *
1003  * When directly accessing a surface special care must be taken to insure
1004  * proper synchronization with the graphics hardware. Clients should call
1005  * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
1006  * rendering or currently being displayed by an overlay.
1007  *
1008  * Additionally nothing about the contents of a surface should be assumed
1009  * following a vaPutSurface. Implementations are free to modify the surface for
1010  * scaling or subpicture blending within a call to vaPutImage.
1011  *
1012  * Calls to vaPutImage or vaGetImage using the same surface from which the image
1013  * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
1014  * vaGetImage with other surfaces is supported.
1015  *
1016  * An image created with vaDeriveImage should be freed with vaDestroyImage. The
1017  * image and image buffer structures will be destroyed; however, the underlying
1018  * surface will remain unchanged until freed with vaDestroySurfaces.
1019  */
1020 VAStatus vaDeriveImage (
1021     VADisplay dpy,
1022     VASurfaceID surface,
1023     VAImage *image      /* out */
1024 )
1025 {
1026   VADriverContextP ctx = CTX(dpy);
1027   CHECK_CONTEXT(ctx);
1028
1029   TRACE(vaDeriveImage);
1030   return ctx->vtable.vaDeriveImage ( ctx, surface, image );
1031 }
1032
1033
1034 /* Get maximum number of subpicture formats supported by the implementation */
1035 int vaMaxNumSubpictureFormats (
1036     VADisplay dpy
1037 )
1038 {
1039   VADriverContextP ctx = CTX(dpy);
1040   if( !vaContextIsValid(ctx) )
1041   {
1042       return 0;
1043   }
1044   
1045   return ctx->max_subpic_formats;
1046 }
1047
1048 /* 
1049  * Query supported subpicture formats 
1050  * The caller must provide a "format_list" array that can hold at
1051  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 
1052  * for each format to indicate additional capabilities for that format. The actual 
1053  * number of formats returned in "format_list" is returned in "num_formats".
1054  */
1055 VAStatus vaQuerySubpictureFormats (
1056     VADisplay dpy,
1057     VAImageFormat *format_list, /* out */
1058     unsigned int *flags,        /* out */
1059     unsigned int *num_formats   /* out */
1060 )
1061 {
1062   VADriverContextP ctx = CTX(dpy);
1063   CHECK_CONTEXT(ctx);
1064
1065   TRACE(vaQuerySubpictureFormats);
1066   return ctx->vtable.vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
1067 }
1068
1069 /* 
1070  * Subpictures are created with an image associated. 
1071  */
1072 VAStatus vaCreateSubpicture (
1073     VADisplay dpy,
1074     VAImageID image,
1075     VASubpictureID *subpicture  /* out */
1076 )
1077 {
1078   VADriverContextP ctx = CTX(dpy);
1079   CHECK_CONTEXT(ctx);
1080
1081   TRACE(vaCreateSubpicture);
1082   return ctx->vtable.vaCreateSubpicture ( ctx, image, subpicture );
1083 }
1084
1085 /*
1086  * Destroy the subpicture before destroying the image it is assocated to
1087  */
1088 VAStatus vaDestroySubpicture (
1089     VADisplay dpy,
1090     VASubpictureID subpicture
1091 )
1092 {
1093   VADriverContextP ctx = CTX(dpy);
1094   CHECK_CONTEXT(ctx);
1095
1096   TRACE(vaDestroySubpicture);
1097   return ctx->vtable.vaDestroySubpicture ( ctx, subpicture);
1098 }
1099
1100 VAStatus vaSetSubpictureImage (
1101     VADisplay dpy,
1102     VASubpictureID subpicture,
1103     VAImageID image
1104 )
1105 {
1106   VADriverContextP ctx = CTX(dpy);
1107   CHECK_CONTEXT(ctx);
1108
1109   TRACE(vaSetSubpictureImage);
1110   return ctx->vtable.vaSetSubpictureImage ( ctx, subpicture, image);
1111 }
1112
1113 #warning TODO: Remove vaSetSubpicturePalette in rev 0.29
1114 VAStatus vaSetSubpicturePalette (
1115     VADisplay dpy,
1116     VASubpictureID subpicture,
1117     /* 
1118      * pointer to an array holding the palette data.  The size of the array is 
1119      * num_palette_entries * entry_bytes in size.  The order of the components
1120      * in the palette is described by the component_order in VASubpicture struct
1121      */
1122     unsigned char *palette 
1123 )
1124 {
1125   VADriverContextP ctx = CTX(dpy);
1126   CHECK_CONTEXT(ctx);
1127
1128   TRACE(vaSetSubpicturePalette);
1129   return ctx->vtable.vaSetSubpicturePalette ( ctx, subpicture, palette);
1130 }
1131
1132 /*
1133  * If chromakey is enabled, then the area where the source value falls within
1134  * the chromakey [min, max] range is transparent
1135  */
1136 VAStatus vaSetSubpictureChromakey (
1137     VADisplay dpy,
1138     VASubpictureID subpicture,
1139     unsigned int chromakey_min,
1140     unsigned int chromakey_max,
1141     unsigned int chromakey_mask
1142 )
1143 {
1144   VADriverContextP ctx = CTX(dpy);
1145   CHECK_CONTEXT(ctx);
1146
1147   TRACE(vaSetSubpictureChromakey);
1148   return ctx->vtable.vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1149 }
1150
1151
1152 /*
1153  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 
1154  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1155  * the overall alpha is per-pixel alpha multiplied by the global alpha
1156  */
1157 VAStatus vaSetSubpictureGlobalAlpha (
1158     VADisplay dpy,
1159     VASubpictureID subpicture,
1160     float global_alpha 
1161 )
1162 {
1163   VADriverContextP ctx = CTX(dpy);
1164   CHECK_CONTEXT(ctx);
1165
1166   TRACE(vaSetSubpictureGlobalAlpha);
1167   return ctx->vtable.vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1168 }
1169
1170 /*
1171   vaAssociateSubpicture associates the subpicture with the target_surface.
1172   It defines the region mapping between the subpicture and the target 
1173   surface through source and destination rectangles (with the same width and height).
1174   Both will be displayed at the next call to vaPutSurface.  Additional
1175   associations before the call to vaPutSurface simply overrides the association.
1176 */
1177 VAStatus vaAssociateSubpicture (
1178     VADisplay dpy,
1179     VASubpictureID subpicture,
1180     VASurfaceID *target_surfaces,
1181     int num_surfaces,
1182     short src_x, /* upper left offset in subpicture */
1183     short src_y,
1184     short dest_x, /* upper left offset in surface */
1185     short dest_y,
1186     unsigned short width,
1187     unsigned short height,
1188     /*
1189      * whether to enable chroma-keying or global-alpha
1190      * see VA_SUBPICTURE_XXX values
1191      */
1192     unsigned int flags
1193 )
1194 {
1195   VADriverContextP ctx = CTX(dpy);
1196   CHECK_CONTEXT(ctx);
1197
1198   TRACE(vaAssociateSubpicture);
1199   return ctx->vtable.vaAssociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces, src_x, src_y, dest_x, dest_y, width, height, flags );
1200 }
1201
1202 VAStatus vaAssociateSubpicture2 (
1203     VADisplay dpy,
1204     VASubpictureID subpicture,
1205     VASurfaceID *target_surfaces,
1206     int num_surfaces,
1207     short src_x, /* upper left offset in subpicture */
1208     short src_y,
1209     unsigned short src_width,
1210     unsigned short src_height,
1211     short dest_x, /* upper left offset in surface */
1212     short dest_y,
1213     unsigned short dest_width,
1214     unsigned short dest_height,
1215     /*
1216      * whether to enable chroma-keying or global-alpha
1217      * see VA_SUBPICTURE_XXX values
1218      */
1219     unsigned int flags
1220 )
1221 {
1222   VADriverContextP ctx = CTX(dpy);
1223   CHECK_CONTEXT(ctx);
1224
1225   TRACE(vaAssociateSubpicture2);
1226   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 );
1227 }
1228
1229 /*
1230  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1231  */
1232 VAStatus vaDeassociateSubpicture (
1233     VADisplay dpy,
1234     VASubpictureID subpicture,
1235     VASurfaceID *target_surfaces,
1236     int num_surfaces
1237 )
1238 {
1239   VADriverContextP ctx = CTX(dpy);
1240   CHECK_CONTEXT(ctx);
1241
1242   TRACE(vaDeassociateSubpicture);
1243   return ctx->vtable.vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1244 }
1245
1246
1247 /* Get maximum number of display attributes supported by the implementation */
1248 int vaMaxNumDisplayAttributes (
1249     VADisplay dpy
1250 )
1251 {
1252   VADriverContextP ctx = CTX(dpy);
1253   if( !vaContextIsValid(ctx) )
1254   {
1255       return 0;
1256   }
1257   
1258   return ctx->max_display_attributes;
1259 }
1260
1261 /* 
1262  * Query display attributes 
1263  * The caller must provide a "attr_list" array that can hold at
1264  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1265  * returned in "attr_list" is returned in "num_attributes".
1266  */
1267 VAStatus vaQueryDisplayAttributes (
1268     VADisplay dpy,
1269     VADisplayAttribute *attr_list,      /* out */
1270     int *num_attributes                 /* out */
1271 )
1272 {
1273   VADriverContextP ctx = CTX(dpy);
1274   CHECK_CONTEXT(ctx);
1275
1276   TRACE(vaQueryDisplayAttributes);
1277   return ctx->vtable.vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1278 }
1279
1280 /* 
1281  * Get display attributes 
1282  * This function returns the current attribute values in "attr_list".
1283  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1284  * from vaQueryDisplayAttributes() can have their values retrieved.  
1285  */
1286 VAStatus vaGetDisplayAttributes (
1287     VADisplay dpy,
1288     VADisplayAttribute *attr_list,      /* in/out */
1289     int num_attributes
1290 )
1291 {
1292   VADriverContextP ctx = CTX(dpy);
1293   CHECK_CONTEXT(ctx);
1294
1295   TRACE(vaGetDisplayAttributes);
1296   return ctx->vtable.vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1297 }
1298
1299 /* 
1300  * Set display attributes 
1301  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1302  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1303  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1304  */
1305 VAStatus vaSetDisplayAttributes (
1306     VADisplay dpy,
1307     VADisplayAttribute *attr_list,
1308     int num_attributes
1309 )
1310 {
1311   VADriverContextP ctx = CTX(dpy);
1312   CHECK_CONTEXT(ctx);
1313
1314   TRACE(vaSetDisplayAttributes);
1315   return ctx->vtable.vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1316 }
1317
1318
1319 #warning TODO: Remove vaDbgCopySurfaceToBuffer in rev 0.29
1320 VAStatus vaDbgCopySurfaceToBuffer(VADisplay dpy,
1321     VASurfaceID surface,
1322     void **buffer, /* out */
1323     unsigned int *stride /* out */
1324 )
1325 {
1326   VADriverContextP ctx = CTX(dpy);
1327   CHECK_CONTEXT(ctx);
1328
1329   TRACE(vaDbgCopySurfaceToBuffer);
1330   return ctx->vtable.vaDbgCopySurfaceToBuffer( ctx, surface, buffer, stride );
1331 }
1332