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