c9028345db6589623fc0325f3bacc51d5b9cdf1a
[profile/ivi/libva.git] / i965_drv_video / i965_drv_video.c
1 /*
2  * Copyright © 2009 Intel Corporation
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  * Authors:
25  *    Xiang Haihao <haihao.xiang@intel.com>
26  *    Zou Nan hai <nanhai.zou@intel.com>
27  *
28  */
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include "va/x11/va_dricommon.h"
35
36 #include "intel_driver.h"
37 #include "intel_memman.h"
38 #include "intel_batchbuffer.h"
39
40 #include "i965_media.h"
41 #include "i965_drv_video.h"
42 #include "i965_defines.h"
43
44 #define CONFIG_ID_OFFSET                0x01000000
45 #define CONTEXT_ID_OFFSET               0x02000000
46 #define SURFACE_ID_OFFSET               0x04000000
47 #define BUFFER_ID_OFFSET                0x08000000
48 #define IMAGE_ID_OFFSET                 0x0a000000
49 #define SUBPIC_ID_OFFSET                0x10000000
50
51 enum {
52     I965_SURFACETYPE_RGBA = 1,
53     I965_SURFACETYPE_YUV,
54     I965_SURFACETYPE_INDEXED
55 };
56
57 /* List of supported subpicture formats */
58 typedef struct {
59     unsigned int        type;
60     unsigned int        format;
61     VAImageFormat       va_format;
62     unsigned int        va_flags;
63 } i965_subpic_format_map_t;
64
65 static const i965_subpic_format_map_t
66 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
67     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
68       { VA_FOURCC('I','A','4','4'), VA_MSB_FIRST, 8, },
69       0 },
70     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
71       { VA_FOURCC('A','I','4','4'), VA_MSB_FIRST, 8, },
72       0 },
73 };
74
75 static const i965_subpic_format_map_t *
76 get_subpic_format(const VAImageFormat *va_format)
77 {
78     unsigned int i;
79     for (i = 0; i < sizeof(i965_subpic_formats_map)/sizeof(i965_subpic_formats_map[0]); i++) {
80         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
81         if (m->va_format.fourcc == va_format->fourcc &&
82             (m->type == I965_SURFACETYPE_RGBA ?
83              (m->va_format.byte_order == va_format->byte_order &&
84               m->va_format.red_mask   == va_format->red_mask   &&
85               m->va_format.green_mask == va_format->green_mask &&
86               m->va_format.blue_mask  == va_format->blue_mask  &&
87               m->va_format.alpha_mask == va_format->alpha_mask) : 1))
88             return m;
89     }
90     return NULL;
91 }
92
93 VAStatus 
94 i965_QueryConfigProfiles(VADriverContextP ctx,
95                          VAProfile *profile_list,       /* out */
96                          int *num_profiles)             /* out */
97 {
98     int i = 0;
99
100     profile_list[i++] = VAProfileMPEG2Simple;
101     profile_list[i++] = VAProfileMPEG2Main;
102     profile_list[i++] = VAProfileH264Baseline;
103     profile_list[i++] = VAProfileH264Main;
104     profile_list[i++] = VAProfileH264High;
105
106     /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
107     assert(i <= I965_MAX_PROFILES);
108     *num_profiles = i;
109
110     return VA_STATUS_SUCCESS;
111 }
112
113 VAStatus 
114 i965_QueryConfigEntrypoints(VADriverContextP ctx,
115                             VAProfile profile,
116                             VAEntrypoint *entrypoint_list,      /* out */
117                             int *num_entrypoints)               /* out */
118 {
119     VAStatus vaStatus = VA_STATUS_SUCCESS;
120
121     switch (profile) {
122     case VAProfileMPEG2Simple:
123     case VAProfileMPEG2Main:
124         *num_entrypoints = 1;
125         entrypoint_list[0] = VAEntrypointVLD;
126         break;
127
128     case VAProfileH264Baseline:
129     case VAProfileH264Main:
130     case VAProfileH264High:
131         *num_entrypoints = 1;
132         entrypoint_list[0] = VAEntrypointVLD;
133         break;
134
135     default:
136         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
137         *num_entrypoints = 0;
138         break;
139     }
140
141     /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
142     assert(*num_entrypoints <= I965_MAX_ENTRYPOINTS);
143
144     return vaStatus;
145 }
146
147 VAStatus 
148 i965_GetConfigAttributes(VADriverContextP ctx,
149                          VAProfile profile,
150                          VAEntrypoint entrypoint,
151                          VAConfigAttrib *attrib_list,  /* in/out */
152                          int num_attribs)
153 {
154     int i;
155
156     /* Other attributes don't seem to be defined */
157     /* What to do if we don't know the attribute? */
158     for (i = 0; i < num_attribs; i++) {
159         switch (attrib_list[i].type) {
160         case VAConfigAttribRTFormat:
161             attrib_list[i].value = VA_RT_FORMAT_YUV420;
162             break;
163
164         default:
165             /* Do nothing */
166             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
167             break;
168         }
169     }
170
171     return VA_STATUS_SUCCESS;
172 }
173
174 static void 
175 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
176 {
177     object_heap_free(heap, obj);
178 }
179
180 static VAStatus 
181 i965_update_attribute(struct object_config *obj_config, VAConfigAttrib *attrib)
182 {
183     int i;
184
185     /* Check existing attrbiutes */
186     for (i = 0; obj_config->num_attribs < i; i++) {
187         if (obj_config->attrib_list[i].type == attrib->type) {
188             /* Update existing attribute */
189             obj_config->attrib_list[i].value = attrib->value;
190             return VA_STATUS_SUCCESS;
191         }
192     }
193
194     if (obj_config->num_attribs < I965_MAX_CONFIG_ATTRIBUTES) {
195         i = obj_config->num_attribs;
196         obj_config->attrib_list[i].type = attrib->type;
197         obj_config->attrib_list[i].value = attrib->value;
198         obj_config->num_attribs++;
199         return VA_STATUS_SUCCESS;
200     }
201
202     return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
203 }
204
205 VAStatus 
206 i965_CreateConfig(VADriverContextP ctx,
207                   VAProfile profile,
208                   VAEntrypoint entrypoint,
209                   VAConfigAttrib *attrib_list,
210                   int num_attribs,
211                   VAConfigID *config_id)                /* out */
212 {
213     struct i965_driver_data *i965 = i965_driver_data(ctx);
214     struct object_config *obj_config;
215     int configID;
216     int i;
217     VAStatus vaStatus;
218
219     /* Validate profile & entrypoint */
220     switch (profile) {
221     case VAProfileMPEG2Simple:
222     case VAProfileMPEG2Main:
223         if (VAEntrypointVLD == entrypoint) {
224             vaStatus = VA_STATUS_SUCCESS;
225         } else {
226             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
227         }
228         break;
229
230     case VAProfileH264Baseline:
231     case VAProfileH264Main:
232     case VAProfileH264High:
233         if (VAEntrypointVLD == entrypoint) {
234             vaStatus = VA_STATUS_SUCCESS;
235         } else {
236             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
237         }
238
239         break;
240
241     default:
242         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
243         break;
244     }
245
246     if (VA_STATUS_SUCCESS != vaStatus) {
247         return vaStatus;
248     }
249
250     configID = NEW_CONFIG_ID();
251     obj_config = CONFIG(configID);
252
253     if (NULL == obj_config) {
254         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
255         return vaStatus;
256     }
257
258     obj_config->profile = profile;
259     obj_config->entrypoint = entrypoint;
260     obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
261     obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
262     obj_config->num_attribs = 1;
263
264     for(i = 0; i < num_attribs; i++) {
265         vaStatus = i965_update_attribute(obj_config, &(attrib_list[i]));
266
267         if (VA_STATUS_SUCCESS != vaStatus) {
268             break;
269         }
270     }
271
272     /* Error recovery */
273     if (VA_STATUS_SUCCESS != vaStatus) {
274         i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
275     } else {
276         *config_id = configID;
277     }
278
279     return vaStatus;
280 }
281
282 VAStatus 
283 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
284 {
285     struct i965_driver_data *i965 = i965_driver_data(ctx);
286     struct object_config *obj_config = CONFIG(config_id);
287     VAStatus vaStatus;
288
289     if (NULL == obj_config) {
290         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
291         return vaStatus;
292     }
293
294     i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
295     return VA_STATUS_SUCCESS;
296 }
297
298 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
299                                     VAConfigID config_id,
300                                     VAProfile *profile,                 /* out */
301                                     VAEntrypoint *entrypoint,           /* out */
302                                     VAConfigAttrib *attrib_list,        /* out */
303                                     int *num_attribs)                   /* out */
304 {
305     struct i965_driver_data *i965 = i965_driver_data(ctx);
306     struct object_config *obj_config = CONFIG(config_id);
307     VAStatus vaStatus = VA_STATUS_SUCCESS;
308     int i;
309
310     assert(obj_config);
311     *profile = obj_config->profile;
312     *entrypoint = obj_config->entrypoint;
313     *num_attribs = obj_config->num_attribs;
314
315     for(i = 0; i < obj_config->num_attribs; i++) {
316         attrib_list[i] = obj_config->attrib_list[i];
317     }
318
319     return vaStatus;
320 }
321
322 static void 
323 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
324 {
325     struct object_surface *obj_surface = (struct object_surface *)obj;
326
327     dri_bo_unreference(obj_surface->bo);
328     obj_surface->bo = NULL;
329
330     if (obj_surface->free_private_data != NULL) {
331         obj_surface->free_private_data(&obj_surface->private_data);
332         obj_surface->private_data = NULL;
333     }
334
335     object_heap_free(heap, obj);
336 }
337
338 VAStatus 
339 i965_CreateSurfaces(VADriverContextP ctx,
340                     int width,
341                     int height,
342                     int format,
343                     int num_surfaces,
344                     VASurfaceID *surfaces)      /* out */
345 {
346     struct i965_driver_data *i965 = i965_driver_data(ctx);
347     int i;
348     VAStatus vaStatus = VA_STATUS_SUCCESS;
349
350     /* We only support one format */
351     if (VA_RT_FORMAT_YUV420 != format) {
352         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
353     }
354
355     for (i = 0; i < num_surfaces; i++) {
356         int surfaceID = NEW_SURFACE_ID();
357         struct object_surface *obj_surface = SURFACE(surfaceID);
358
359         if (NULL == obj_surface) {
360             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
361             break;
362         }
363
364         surfaces[i] = surfaceID;
365         obj_surface->status = VASurfaceReady;
366         obj_surface->subpic = VA_INVALID_ID;
367         obj_surface->width = width;
368         obj_surface->height = height;
369         obj_surface->size = SIZE_YUV420(width, height);
370         obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
371                                        "vaapi surface",
372                                        obj_surface->size,
373                                        64);
374         assert(obj_surface->bo);
375         obj_surface->private_data = NULL;
376         obj_surface->free_private_data = NULL;
377     }
378
379     /* Error recovery */
380     if (VA_STATUS_SUCCESS != vaStatus) {
381         /* surfaces[i-1] was the last successful allocation */
382         for (; i--; ) {
383             struct object_surface *obj_surface = SURFACE(surfaces[i]);
384
385             surfaces[i] = VA_INVALID_SURFACE;
386             assert(obj_surface);
387             i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
388         }
389     }
390
391     return vaStatus;
392 }
393
394 VAStatus 
395 i965_DestroySurfaces(VADriverContextP ctx,
396                      VASurfaceID *surface_list,
397                      int num_surfaces)
398 {
399     struct i965_driver_data *i965 = i965_driver_data(ctx);
400     int i;
401
402     for (i = num_surfaces; i--; ) {
403         struct object_surface *obj_surface = SURFACE(surface_list[i]);
404
405         assert(obj_surface);
406         i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
407     }
408
409     return VA_STATUS_SUCCESS;
410 }
411
412 VAStatus 
413 i965_QueryImageFormats(VADriverContextP ctx,
414                        VAImageFormat *format_list,      /* out */
415                        int *num_formats)                /* out */
416 {
417     if (num_formats)
418         *num_formats = 0;
419
420     return VA_STATUS_SUCCESS;
421 }
422
423 VAStatus 
424 i965_PutImage(VADriverContextP ctx,
425                VASurfaceID surface,
426                VAImageID image,
427                int src_x,
428                int src_y,
429                unsigned int src_width,
430                unsigned int src_height,
431                int dest_x,
432                int dest_y,
433                unsigned int dest_width,
434                unsigned int dest_height)
435 {
436     return VA_STATUS_SUCCESS;
437 }
438
439 VAStatus 
440 i965_QuerySubpictureFormats(VADriverContextP ctx,
441                             VAImageFormat *format_list,         /* out */
442                             unsigned int *flags,                /* out */
443                             unsigned int *num_formats)          /* out */
444 {
445     int n;
446
447     for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
448         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
449         if (format_list)
450             format_list[n] = m->va_format;
451         if (flags)
452             flags[n] = m->va_flags;
453     }
454
455     if (num_formats)
456         *num_formats = n;
457
458     return VA_STATUS_SUCCESS;
459 }
460
461 static void 
462 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
463 {
464 //    struct object_subpic *obj_subpic = (struct object_subpic *)obj;
465
466     object_heap_free(heap, obj);
467 }
468
469 VAStatus 
470 i965_CreateSubpicture(VADriverContextP ctx,
471                       VAImageID image,
472                       VASubpictureID *subpicture)         /* out */
473 {
474     struct i965_driver_data *i965 = i965_driver_data(ctx);
475     VASubpictureID subpicID = NEW_SUBPIC_ID()
476         
477     struct object_subpic *obj_subpic = SUBPIC(subpicID);
478     if (!obj_subpic)
479         return VA_STATUS_ERROR_ALLOCATION_FAILED;
480
481     struct object_image *obj_image = IMAGE(image);
482     if (!obj_image)
483         return VA_STATUS_ERROR_INVALID_IMAGE;
484
485     const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
486     if (!m)
487         return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
488
489     *subpicture = subpicID;
490     obj_subpic->image  = image;
491     obj_subpic->format = m->format;
492     obj_subpic->width  = obj_image->image.width;
493     obj_subpic->height = obj_image->image.height;
494     obj_subpic->bo     = obj_image->bo;
495     return VA_STATUS_SUCCESS;
496 }
497
498 VAStatus 
499 i965_DestroySubpicture(VADriverContextP ctx,
500                        VASubpictureID subpicture)
501 {
502         
503     struct i965_driver_data *i965 = i965_driver_data(ctx);
504     struct object_subpic *obj_subpic = SUBPIC(subpicture);
505     i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
506     return VA_STATUS_SUCCESS;
507 }
508
509 VAStatus 
510 i965_SetSubpictureImage(VADriverContextP ctx,
511                         VASubpictureID subpicture,
512                         VAImageID image)
513 {
514     return VA_STATUS_SUCCESS;
515 }
516
517 VAStatus 
518 i965_SetSubpictureChromakey(VADriverContextP ctx,
519                             VASubpictureID subpicture,
520                             unsigned int chromakey_min,
521                             unsigned int chromakey_max,
522                             unsigned int chromakey_mask)
523 {
524     return VA_STATUS_SUCCESS;
525 }
526
527 VAStatus 
528 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
529                               VASubpictureID subpicture,
530                               float global_alpha)
531 {
532     return VA_STATUS_SUCCESS;
533 }
534
535 VAStatus 
536 i965_AssociateSubpicture(VADriverContextP ctx,
537                          VASubpictureID subpicture,
538                          VASurfaceID *target_surfaces,
539                          int num_surfaces,
540                          short src_x, /* upper left offset in subpicture */
541                          short src_y,
542                          unsigned short src_width,
543                          unsigned short src_height,
544                          short dest_x, /* upper left offset in surface */
545                          short dest_y,
546                          unsigned short dest_width,
547                          unsigned short dest_height,
548                          /*
549                           * whether to enable chroma-keying or global-alpha
550                           * see VA_SUBPICTURE_XXX values
551                           */
552                          unsigned int flags)
553 {
554     struct i965_driver_data *i965 = i965_driver_data(ctx);
555     struct object_subpic *obj_subpic = SUBPIC(subpicture);
556     int i;
557
558     obj_subpic->src_rect.x      = src_x;
559     obj_subpic->src_rect.y      = src_y;
560     obj_subpic->src_rect.width  = src_width;
561     obj_subpic->src_rect.height = src_height;
562     obj_subpic->dst_rect.x      = dest_x;
563     obj_subpic->dst_rect.y      = dest_y;
564     obj_subpic->dst_rect.width  = dest_width;
565     obj_subpic->dst_rect.height = dest_height;
566
567     for (i = 0; i < num_surfaces; i++) {
568         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
569         if (!obj_surface)
570             return VA_STATUS_ERROR_INVALID_SURFACE;
571         obj_surface->subpic = subpicture;
572     }
573     return VA_STATUS_SUCCESS;
574 }
575
576
577 VAStatus 
578 i965_DeassociateSubpicture(VADriverContextP ctx,
579                            VASubpictureID subpicture,
580                            VASurfaceID *target_surfaces,
581                            int num_surfaces)
582 {
583     struct i965_driver_data *i965 = i965_driver_data(ctx);
584     int i;
585
586     for (i = 0; i < num_surfaces; i++) {
587         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
588         if (!obj_surface)
589             return VA_STATUS_ERROR_INVALID_SURFACE;
590         if (obj_surface->subpic == subpicture)
591             obj_surface->subpic = VA_INVALID_ID;
592     }
593     return VA_STATUS_SUCCESS;
594 }
595
596 static void
597 i965_reference_buffer_store(struct buffer_store **ptr, 
598                             struct buffer_store *buffer_store)
599 {
600     assert(*ptr == NULL);
601
602     if (buffer_store) {
603         buffer_store->ref_count++;
604         *ptr = buffer_store;
605     }
606 }
607
608 static void 
609 i965_release_buffer_store(struct buffer_store **ptr)
610 {
611     struct buffer_store *buffer_store = *ptr;
612
613     if (buffer_store == NULL)
614         return;
615
616     assert(buffer_store->bo || buffer_store->buffer);
617     assert(!(buffer_store->bo && buffer_store->buffer));
618     buffer_store->ref_count--;
619     
620     if (buffer_store->ref_count == 0) {
621         dri_bo_unreference(buffer_store->bo);
622         free(buffer_store->buffer);
623         buffer_store->bo = NULL;
624         buffer_store->buffer = NULL;
625         free(buffer_store);
626     }
627
628     *ptr = NULL;
629 }
630
631 static void 
632 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
633 {
634     struct object_context *obj_context = (struct object_context *)obj;
635     int i;
636
637     assert(obj_context->decode_state.num_slice_params <= obj_context->decode_state.max_slice_params);
638     assert(obj_context->decode_state.num_slice_datas <= obj_context->decode_state.max_slice_datas);
639
640     i965_release_buffer_store(&obj_context->decode_state.pic_param);
641     i965_release_buffer_store(&obj_context->decode_state.iq_matrix);
642     i965_release_buffer_store(&obj_context->decode_state.bit_plane);
643
644     for (i = 0; i < obj_context->decode_state.num_slice_params; i++)
645         i965_release_buffer_store(&obj_context->decode_state.slice_params[i]);
646
647     for (i = 0; i < obj_context->decode_state.num_slice_datas; i++)
648         i965_release_buffer_store(&obj_context->decode_state.slice_datas[i]);
649
650     free(obj_context->decode_state.slice_params);
651     free(obj_context->decode_state.slice_datas);
652     free(obj_context->render_targets);
653     object_heap_free(heap, obj);
654 }
655
656 VAStatus 
657 i965_CreateContext(VADriverContextP ctx,
658                    VAConfigID config_id,
659                    int picture_width,
660                    int picture_height,
661                    int flag,
662                    VASurfaceID *render_targets,
663                    int num_render_targets,
664                    VAContextID *context)                /* out */
665 {
666     struct i965_driver_data *i965 = i965_driver_data(ctx);
667     struct object_config *obj_config = CONFIG(config_id);
668     struct object_context *obj_context = NULL;
669     VAStatus vaStatus = VA_STATUS_SUCCESS;
670     int contextID;
671     int i;
672
673     if (NULL == obj_config) {
674         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
675         return vaStatus;
676     }
677
678     /* Validate flag */
679     /* Validate picture dimensions */
680     contextID = NEW_CONTEXT_ID();
681     obj_context = CONTEXT(contextID);
682
683     if (NULL == obj_context) {
684         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
685         return vaStatus;
686     }
687
688     obj_context->context_id = contextID;
689     *context = contextID;
690     memset(&obj_context->decode_state, 0, sizeof(obj_context->decode_state));
691     obj_context->decode_state.current_render_target = -1;
692     obj_context->decode_state.max_slice_params = NUM_SLICES;
693     obj_context->decode_state.max_slice_datas = NUM_SLICES;
694     obj_context->decode_state.slice_params = calloc(obj_context->decode_state.max_slice_params,
695                                                     sizeof(*obj_context->decode_state.slice_params));
696     obj_context->decode_state.slice_datas = calloc(obj_context->decode_state.max_slice_datas,
697                                                    sizeof(*obj_context->decode_state.slice_datas));
698     obj_context->config_id = config_id;
699     obj_context->picture_width = picture_width;
700     obj_context->picture_height = picture_height;
701     obj_context->num_render_targets = num_render_targets;
702     obj_context->render_targets = 
703         (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
704
705     for(i = 0; i < num_render_targets; i++) {
706         if (NULL == SURFACE(render_targets[i])) {
707             vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
708             break;
709         }
710
711         obj_context->render_targets[i] = render_targets[i];
712     }
713
714     obj_context->flags = flag;
715
716     /* Error recovery */
717     if (VA_STATUS_SUCCESS != vaStatus) {
718         i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
719     }
720
721     return vaStatus;
722 }
723
724 VAStatus 
725 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
726 {
727     struct i965_driver_data *i965 = i965_driver_data(ctx);
728     struct object_context *obj_context = CONTEXT(context);
729
730     assert(obj_context);
731     i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
732
733     return VA_STATUS_SUCCESS;
734 }
735
736 static void 
737 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
738 {
739     struct object_buffer *obj_buffer = (struct object_buffer *)obj;
740
741     assert(obj_buffer->buffer_store);
742     i965_release_buffer_store(&obj_buffer->buffer_store);
743     object_heap_free(heap, obj);
744 }
745
746 VAStatus 
747 i965_CreateBuffer(VADriverContextP ctx,
748                   VAContextID context,          /* in */
749                   VABufferType type,            /* in */
750                   unsigned int size,            /* in */
751                   unsigned int num_elements,    /* in */
752                   void *data,                   /* in */
753                   VABufferID *buf_id)           /* out */
754 {
755     struct i965_driver_data *i965 = i965_driver_data(ctx);
756     struct object_buffer *obj_buffer = NULL;
757     struct buffer_store *buffer_store = NULL;
758     int bufferID;
759
760     /* Validate type */
761     switch (type) {
762     case VAPictureParameterBufferType:
763     case VAIQMatrixBufferType:
764     case VABitPlaneBufferType:
765     case VASliceGroupMapBufferType:
766     case VASliceParameterBufferType:
767     case VASliceDataBufferType:
768     case VAMacroblockParameterBufferType:
769     case VAResidualDataBufferType:
770     case VADeblockingParameterBufferType:
771     case VAImageBufferType:
772         /* Ok */
773         break;
774
775     default:
776         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
777     }
778
779     bufferID = NEW_BUFFER_ID();
780     obj_buffer = BUFFER(bufferID);
781
782     if (NULL == obj_buffer) {
783         return VA_STATUS_ERROR_ALLOCATION_FAILED;
784     }
785
786     obj_buffer->max_num_elements = num_elements;
787     obj_buffer->num_elements = num_elements;
788     obj_buffer->size_element = size;
789     obj_buffer->type = type;
790     obj_buffer->buffer_store = NULL;
791     buffer_store = calloc(1, sizeof(struct buffer_store));
792     assert(buffer_store);
793     buffer_store->ref_count = 1;
794
795     if (type == VASliceDataBufferType || type == VAImageBufferType) {
796         buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, 
797                                       "Buffer", 
798                                       size * num_elements, 64);
799         assert(buffer_store->bo);
800
801         if (data)
802             dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
803     } else {
804         buffer_store->buffer = malloc(size * num_elements);
805         assert(buffer_store->buffer);
806
807         if (data)
808             memcpy(buffer_store->buffer, data, size * num_elements);
809     }
810
811     buffer_store->num_elements = obj_buffer->num_elements;
812     i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
813     i965_release_buffer_store(&buffer_store);
814     *buf_id = bufferID;
815
816     return VA_STATUS_SUCCESS;
817 }
818
819
820 VAStatus 
821 i965_BufferSetNumElements(VADriverContextP ctx,
822                           VABufferID buf_id,           /* in */
823                           unsigned int num_elements)   /* in */
824 {
825     struct i965_driver_data *i965 = i965_driver_data(ctx);
826     struct object_buffer *obj_buffer = BUFFER(buf_id);
827     VAStatus vaStatus = VA_STATUS_SUCCESS;
828
829     assert(obj_buffer);
830
831     if ((num_elements < 0) || 
832         (num_elements > obj_buffer->max_num_elements)) {
833         vaStatus = VA_STATUS_ERROR_UNKNOWN;
834     } else {
835         obj_buffer->num_elements = num_elements;
836     }
837
838     return vaStatus;
839 }
840
841 VAStatus 
842 i965_MapBuffer(VADriverContextP ctx,
843                VABufferID buf_id,       /* in */
844                void **pbuf)             /* out */
845 {
846     struct i965_driver_data *i965 = i965_driver_data(ctx);
847     struct object_buffer *obj_buffer = BUFFER(buf_id);
848     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
849
850     assert(obj_buffer && obj_buffer->buffer_store);
851     assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
852     assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
853
854     if (NULL != obj_buffer->buffer_store->bo) {
855         dri_bo_map(obj_buffer->buffer_store->bo, 1);
856         assert(obj_buffer->buffer_store->bo->virtual);
857         *pbuf = obj_buffer->buffer_store->bo->virtual;
858         vaStatus = VA_STATUS_SUCCESS;
859     } else if (NULL != obj_buffer->buffer_store->buffer) {
860         *pbuf = obj_buffer->buffer_store->buffer;
861         vaStatus = VA_STATUS_SUCCESS;
862     }
863
864     return vaStatus;
865 }
866
867 VAStatus 
868 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
869 {
870     struct i965_driver_data *i965 = i965_driver_data(ctx);
871     struct object_buffer *obj_buffer = BUFFER(buf_id);
872     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
873
874     assert(obj_buffer && obj_buffer->buffer_store);
875     assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
876     assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
877
878     if (NULL != obj_buffer->buffer_store->bo) {
879         dri_bo_unmap(obj_buffer->buffer_store->bo);
880         vaStatus = VA_STATUS_SUCCESS;
881     } else if (NULL != obj_buffer->buffer_store->buffer) {
882         /* Do nothing */
883         vaStatus = VA_STATUS_SUCCESS;
884     }
885
886     return vaStatus;    
887 }
888
889 VAStatus 
890 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
891 {
892     struct i965_driver_data *i965 = i965_driver_data(ctx);
893     struct object_buffer *obj_buffer = BUFFER(buffer_id);
894
895     assert(obj_buffer);
896     i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
897
898     return VA_STATUS_SUCCESS;
899 }
900
901 VAStatus 
902 i965_BeginPicture(VADriverContextP ctx,
903                   VAContextID context,
904                   VASurfaceID render_target)
905 {
906     struct i965_driver_data *i965 = i965_driver_data(ctx); 
907     struct object_context *obj_context = CONTEXT(context);
908     struct object_surface *obj_surface = SURFACE(render_target);
909     struct object_config *obj_config;
910     VAContextID config;
911     VAStatus vaStatus;
912
913     assert(obj_context);
914     assert(obj_surface);
915
916     config = obj_context->config_id;
917     obj_config = CONFIG(config);
918     assert(obj_config);
919
920     switch (obj_config->profile) {
921     case VAProfileMPEG2Simple:
922     case VAProfileMPEG2Main:
923         vaStatus = VA_STATUS_SUCCESS;
924         break;
925
926     case VAProfileH264Baseline:
927     case VAProfileH264Main:
928     case VAProfileH264High:
929         vaStatus = VA_STATUS_SUCCESS;
930         break;
931
932     default:
933         assert(0);
934         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
935         break;
936     }
937
938     obj_context->decode_state.current_render_target = render_target;
939
940     return vaStatus;
941 }
942
943 static VAStatus
944 i965_render_picture_parameter_buffer(VADriverContextP ctx,
945                                      struct object_context *obj_context,
946                                      struct object_buffer *obj_buffer)
947 {
948     assert(obj_buffer->buffer_store->bo == NULL);
949     assert(obj_buffer->buffer_store->buffer);
950     i965_release_buffer_store(&obj_context->decode_state.pic_param);
951     i965_reference_buffer_store(&obj_context->decode_state.pic_param,
952                                 obj_buffer->buffer_store);
953
954     return VA_STATUS_SUCCESS;
955 }
956
957 static VAStatus
958 i965_render_iq_matrix_buffer(VADriverContextP ctx,
959                              struct object_context *obj_context,
960                              struct object_buffer *obj_buffer)
961 {
962     assert(obj_buffer->buffer_store->bo == NULL);
963     assert(obj_buffer->buffer_store->buffer);
964     i965_release_buffer_store(&obj_context->decode_state.iq_matrix);
965     i965_reference_buffer_store(&obj_context->decode_state.iq_matrix,
966                                 obj_buffer->buffer_store);
967
968     return VA_STATUS_SUCCESS;
969 }
970
971 static VAStatus
972 i965_render_bit_plane_buffer(VADriverContextP ctx,
973                              struct object_context *obj_context,
974                              struct object_buffer *obj_buffer)
975 {
976     assert(obj_buffer->buffer_store->bo == NULL);
977     assert(obj_buffer->buffer_store->buffer);
978     i965_release_buffer_store(&obj_context->decode_state.bit_plane);
979     i965_reference_buffer_store(&obj_context->decode_state.bit_plane,
980                                  obj_buffer->buffer_store);
981     
982     return VA_STATUS_SUCCESS;
983 }
984
985 static VAStatus
986 i965_render_slice_parameter_buffer(VADriverContextP ctx,
987                                    struct object_context *obj_context,
988                                    struct object_buffer *obj_buffer)
989 {
990     assert(obj_buffer->buffer_store->bo == NULL);
991     assert(obj_buffer->buffer_store->buffer);
992     
993     if (obj_context->decode_state.num_slice_params == obj_context->decode_state.max_slice_params) {
994         obj_context->decode_state.slice_params = realloc(obj_context->decode_state.slice_params,
995                                                         (obj_context->decode_state.max_slice_params + NUM_SLICES) * sizeof(*obj_context->decode_state.slice_params));
996         memset(obj_context->decode_state.slice_params + obj_context->decode_state.max_slice_params, 0, NUM_SLICES * sizeof(*obj_context->decode_state.slice_params));
997         obj_context->decode_state.max_slice_params += NUM_SLICES;
998     }
999         
1000     i965_release_buffer_store(&obj_context->decode_state.slice_params[obj_context->decode_state.num_slice_params]);
1001     i965_reference_buffer_store(&obj_context->decode_state.slice_params[obj_context->decode_state.num_slice_params],
1002                                 obj_buffer->buffer_store);
1003     obj_context->decode_state.num_slice_params++;
1004     
1005     return VA_STATUS_SUCCESS;
1006 }
1007
1008 static VAStatus
1009 i965_render_slice_data_buffer(VADriverContextP ctx,
1010                               struct object_context *obj_context,
1011                               struct object_buffer *obj_buffer)
1012 {
1013     assert(obj_buffer->buffer_store->buffer == NULL);
1014     assert(obj_buffer->buffer_store->bo);
1015
1016     if (obj_context->decode_state.num_slice_datas == obj_context->decode_state.max_slice_datas) {
1017         obj_context->decode_state.slice_datas = realloc(obj_context->decode_state.slice_datas,
1018                                                         (obj_context->decode_state.max_slice_datas + NUM_SLICES) * sizeof(*obj_context->decode_state.slice_datas));
1019         memset(obj_context->decode_state.slice_datas + obj_context->decode_state.max_slice_datas, 0, NUM_SLICES * sizeof(*obj_context->decode_state.slice_datas));
1020         obj_context->decode_state.max_slice_datas += NUM_SLICES;
1021     }
1022         
1023     i965_release_buffer_store(&obj_context->decode_state.slice_datas[obj_context->decode_state.num_slice_datas]);
1024     i965_reference_buffer_store(&obj_context->decode_state.slice_datas[obj_context->decode_state.num_slice_datas],
1025                                 obj_buffer->buffer_store);
1026     obj_context->decode_state.num_slice_datas++;
1027     
1028     return VA_STATUS_SUCCESS;
1029 }
1030
1031 VAStatus 
1032 i965_RenderPicture(VADriverContextP ctx,
1033                    VAContextID context,
1034                    VABufferID *buffers,
1035                    int num_buffers)
1036 {
1037     struct i965_driver_data *i965 = i965_driver_data(ctx);
1038     struct object_context *obj_context;
1039     int i;
1040     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1041
1042     obj_context = CONTEXT(context);
1043     assert(obj_context);
1044
1045     for (i = 0; i < num_buffers; i++) {
1046         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
1047         assert(obj_buffer);
1048
1049         switch (obj_buffer->type) {
1050         case VAPictureParameterBufferType:
1051             vaStatus = i965_render_picture_parameter_buffer(ctx, obj_context, obj_buffer);
1052             break;
1053             
1054         case VAIQMatrixBufferType:
1055             vaStatus = i965_render_iq_matrix_buffer(ctx, obj_context, obj_buffer);
1056             break;
1057
1058         case VABitPlaneBufferType:
1059             vaStatus = i965_render_bit_plane_buffer(ctx, obj_context, obj_buffer);
1060             break;
1061
1062         case VASliceParameterBufferType:
1063             vaStatus = i965_render_slice_parameter_buffer(ctx, obj_context, obj_buffer);
1064             break;
1065
1066         case VASliceDataBufferType:
1067             vaStatus = i965_render_slice_data_buffer(ctx, obj_context, obj_buffer);
1068             break;
1069
1070         default:
1071             break;
1072         }
1073     }
1074
1075     return vaStatus;
1076 }
1077
1078 VAStatus 
1079 i965_EndPicture(VADriverContextP ctx, VAContextID context)
1080 {
1081     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1082     struct i965_render_state *render_state = &i965->render_state;
1083     struct object_context *obj_context = CONTEXT(context);
1084     struct object_config *obj_config;
1085     VAContextID config;
1086     int i;
1087
1088     assert(obj_context);
1089     assert(obj_context->decode_state.pic_param);
1090     assert(obj_context->decode_state.num_slice_params >= 1);
1091     assert(obj_context->decode_state.num_slice_datas >= 1);
1092     assert(obj_context->decode_state.num_slice_params == obj_context->decode_state.num_slice_datas);
1093
1094     config = obj_context->config_id;
1095     obj_config = CONFIG(config);
1096     assert(obj_config);
1097
1098     switch (obj_config->profile) {
1099     case VAProfileH264Baseline:
1100     case VAProfileH264Main:
1101     case VAProfileH264High:
1102         render_state->interleaved_uv = 1;
1103         break;
1104
1105     default:
1106         render_state->interleaved_uv = 0;
1107     }
1108
1109     i965_media_decode_picture(ctx, obj_config->profile, &obj_context->decode_state);
1110     obj_context->decode_state.current_render_target = -1;
1111     obj_context->decode_state.num_slice_params = 0;
1112     obj_context->decode_state.num_slice_datas = 0;
1113     i965_release_buffer_store(&obj_context->decode_state.pic_param);
1114     i965_release_buffer_store(&obj_context->decode_state.iq_matrix);
1115     i965_release_buffer_store(&obj_context->decode_state.bit_plane);
1116
1117     for (i = 0; i < obj_context->decode_state.num_slice_params; i++) {
1118         i965_release_buffer_store(&obj_context->decode_state.slice_params[i]);
1119         i965_release_buffer_store(&obj_context->decode_state.slice_datas[i]);
1120     }
1121
1122     return VA_STATUS_SUCCESS;
1123 }
1124
1125 VAStatus 
1126 i965_SyncSurface(VADriverContextP ctx,
1127                  VASurfaceID render_target)
1128 {
1129     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1130     struct object_surface *obj_surface = SURFACE(render_target);
1131
1132     assert(obj_surface);
1133
1134     return VA_STATUS_SUCCESS;
1135 }
1136
1137 VAStatus 
1138 i965_QuerySurfaceStatus(VADriverContextP ctx,
1139                         VASurfaceID render_target,
1140                         VASurfaceStatus *status)        /* out */
1141 {
1142     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1143     struct object_surface *obj_surface = SURFACE(render_target);
1144
1145     assert(obj_surface);
1146     *status = obj_surface->status;
1147
1148     return VA_STATUS_SUCCESS;
1149 }
1150
1151
1152 /* 
1153  * Query display attributes 
1154  * The caller must provide a "attr_list" array that can hold at
1155  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1156  * returned in "attr_list" is returned in "num_attributes".
1157  */
1158 VAStatus 
1159 i965_QueryDisplayAttributes(VADriverContextP ctx,
1160                             VADisplayAttribute *attr_list,      /* out */
1161                             int *num_attributes)                /* out */
1162 {
1163     if (num_attributes)
1164         *num_attributes = 0;
1165
1166     return VA_STATUS_SUCCESS;
1167 }
1168
1169 /* 
1170  * Get display attributes 
1171  * This function returns the current attribute values in "attr_list".
1172  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1173  * from vaQueryDisplayAttributes() can have their values retrieved.  
1174  */
1175 VAStatus 
1176 i965_GetDisplayAttributes(VADriverContextP ctx,
1177                           VADisplayAttribute *attr_list,        /* in/out */
1178                           int num_attributes)
1179 {
1180     /* TODO */
1181     return VA_STATUS_ERROR_UNKNOWN;
1182 }
1183
1184 /* 
1185  * Set display attributes 
1186  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1187  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1188  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1189  */
1190 VAStatus 
1191 i965_SetDisplayAttributes(VADriverContextP ctx,
1192                           VADisplayAttribute *attr_list,
1193                           int num_attributes)
1194 {
1195     /* TODO */
1196     return VA_STATUS_ERROR_UNKNOWN;
1197 }
1198
1199 VAStatus 
1200 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
1201                             VASurfaceID surface,
1202                             void **buffer,              /* out */
1203                             unsigned int *stride)       /* out */
1204 {
1205     /* TODO */
1206     return VA_STATUS_ERROR_UNKNOWN;
1207 }
1208
1209 static VAStatus 
1210 i965_Init(VADriverContextP ctx)
1211 {
1212     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1213
1214     if (intel_driver_init(ctx) == False)
1215         return VA_STATUS_ERROR_UNKNOWN;
1216
1217     if (!IS_G4X(i965->intel.device_id) &&
1218         !IS_IRONLAKE(i965->intel.device_id))
1219         return VA_STATUS_ERROR_UNKNOWN;
1220
1221     if (i965_media_init(ctx) == False)
1222         return VA_STATUS_ERROR_UNKNOWN;
1223
1224     if (i965_render_init(ctx) == False)
1225         return VA_STATUS_ERROR_UNKNOWN;
1226
1227     return VA_STATUS_SUCCESS;
1228 }
1229
1230 static void
1231 i965_destroy_heap(struct object_heap *heap, 
1232                   void (*func)(struct object_heap *heap, struct object_base *object))
1233 {
1234     struct object_base *object;
1235     object_heap_iterator iter;    
1236
1237     object = object_heap_first(heap, &iter);
1238
1239     while (object) {
1240         if (func)
1241             func(heap, object);
1242
1243         object = object_heap_next(heap, &iter);
1244     }
1245
1246     object_heap_destroy(heap);
1247 }
1248
1249
1250 VAStatus 
1251 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
1252
1253 VAStatus 
1254 i965_CreateImage(VADriverContextP ctx,
1255                  VAImageFormat *format,
1256                  int width,
1257                  int height,
1258                  VAImage *out_image)        /* out */
1259 {
1260     struct i965_driver_data *i965 = i965_driver_data(ctx);
1261     struct object_image *obj_image;
1262     VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
1263     VAImageID image_id;
1264     unsigned int width2, height2, size2, size;
1265
1266     out_image->image_id = VA_INVALID_ID;
1267     out_image->buf      = VA_INVALID_ID;
1268
1269     image_id = NEW_IMAGE_ID();
1270     if (image_id == VA_INVALID_ID)
1271         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1272
1273     obj_image = IMAGE(image_id);
1274     if (!obj_image)
1275         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1276     obj_image->bo         = NULL;
1277     obj_image->palette    = NULL;
1278
1279     VAImage * const image = &obj_image->image;
1280     image->image_id       = image_id;
1281     image->buf            = VA_INVALID_ID;
1282
1283     size    = width * height;
1284     width2  = (width  + 1) / 2;
1285     height2 = (height + 1) / 2;
1286     size2   = width2 * height2;
1287
1288     image->num_palette_entries = 0;
1289     image->entry_bytes         = 0;
1290     memset(image->component_order, 0, sizeof(image->component_order));
1291
1292     switch (format->fourcc) {
1293     case VA_FOURCC('I','A','4','4'):
1294     case VA_FOURCC('A','I','4','4'):
1295         image->num_planes = 1;
1296         image->pitches[0] = width;
1297         image->offsets[0] = 0;
1298         image->data_size  = image->offsets[0] + image->pitches[0] * height;
1299         image->num_palette_entries = 16;
1300         image->entry_bytes         = 3;
1301         image->component_order[0]  = 'R';
1302         image->component_order[1]  = 'G';
1303         image->component_order[2]  = 'B';
1304         break;
1305     default:
1306         goto error;
1307     }
1308
1309     va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
1310                                   image->data_size, 1, NULL, &image->buf);
1311     if (va_status != VA_STATUS_SUCCESS)
1312         goto error;
1313
1314     obj_image->bo = BUFFER(image->buf)->buffer_store->bo;
1315
1316     if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
1317         obj_image->palette = malloc(image->num_palette_entries * sizeof(obj_image->palette));
1318         if (!obj_image->palette)
1319             goto error;
1320     }
1321
1322     image->image_id             = image_id;
1323     image->format               = *format;
1324     image->width                = width;
1325     image->height               = height;
1326
1327     *out_image                  = *image;
1328     return VA_STATUS_SUCCESS;
1329
1330  error:
1331     i965_DestroyImage(ctx, image_id);
1332     return va_status;
1333 }
1334
1335 VAStatus i965_DeriveImage(VADriverContextP ctx,
1336                           VASurfaceID surface,
1337                           VAImage *image)        /* out */
1338 {
1339     return VA_STATUS_SUCCESS;
1340 }
1341
1342 static void 
1343 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
1344 {
1345     object_heap_free(heap, obj);
1346 }
1347
1348
1349 VAStatus 
1350 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
1351 {
1352     struct i965_driver_data *i965 = i965_driver_data(ctx);
1353     struct object_image *obj_image = IMAGE(image); 
1354
1355     if (!obj_image)
1356         return VA_STATUS_SUCCESS;
1357
1358     if (obj_image->image.buf != VA_INVALID_ID) {
1359         i965_DestroyBuffer(ctx, obj_image->image.buf);
1360         obj_image->image.buf = VA_INVALID_ID;
1361     }
1362
1363     if (obj_image->palette) {
1364         free(obj_image->palette);
1365         obj_image->palette = NULL;
1366     }
1367
1368     i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
1369         
1370     return VA_STATUS_SUCCESS;
1371 }
1372
1373 /*
1374  * pointer to an array holding the palette data.  The size of the array is
1375  * num_palette_entries * entry_bytes in size.  The order of the components
1376  * in the palette is described by the component_order in VASubpicture struct
1377  */
1378 VAStatus 
1379 i965_SetImagePalette(VADriverContextP ctx,
1380                      VAImageID image,
1381                      unsigned char *palette)
1382 {
1383     struct i965_driver_data *i965 = i965_driver_data(ctx);
1384     unsigned int i;
1385
1386     struct object_image *obj_image = IMAGE(image);
1387     if (!obj_image)
1388         return VA_STATUS_ERROR_INVALID_IMAGE;
1389
1390     if (!obj_image->palette)
1391         return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
1392
1393     for (i = 0; i < obj_image->image.num_palette_entries; i++)
1394         obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
1395                                  ((unsigned int)palette[3*i + 1] <<  8) |
1396                                   (unsigned int)palette[3*i + 2]);
1397     return VA_STATUS_SUCCESS;
1398 }
1399
1400 VAStatus 
1401 i965_GetImage(VADriverContextP ctx,
1402               VASurfaceID surface,
1403               int x,   /* coordinates of the upper left source pixel */
1404               int y,
1405               unsigned int width,      /* width and height of the region */
1406               unsigned int height,
1407               VAImageID image)
1408 {
1409     return VA_STATUS_SUCCESS;
1410 }
1411
1412 VAStatus 
1413 i965_PutSurface(VADriverContextP ctx,
1414                 VASurfaceID surface,
1415                 Drawable draw, /* X Drawable */
1416                 short srcx,
1417                 short srcy,
1418                 unsigned short srcw,
1419                 unsigned short srch,
1420                 short destx,
1421                 short desty,
1422                 unsigned short destw,
1423                 unsigned short desth,
1424                 VARectangle *cliprects, /* client supplied clip list */
1425                 unsigned int number_cliprects, /* number of clip rects in the clip list */
1426                 unsigned int flags) /* de-interlacing flags */
1427 {
1428     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1429     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
1430     struct i965_render_state *render_state = &i965->render_state;
1431     struct dri_drawable *dri_drawable;
1432     union dri_buffer *buffer;
1433     struct intel_region *dest_region;
1434     struct object_surface *obj_surface; 
1435         int ret;
1436     uint32_t name;
1437     Bool new_region = False;
1438     /* Currently don't support DRI1 */
1439     if (dri_state->driConnectedFlag != VA_DRI2)
1440         return VA_STATUS_ERROR_UNKNOWN;
1441
1442     dri_drawable = dri_get_drawable(ctx, draw);
1443     assert(dri_drawable);
1444
1445     buffer = dri_get_rendering_buffer(ctx, dri_drawable);
1446     assert(buffer);
1447     
1448     dest_region = render_state->draw_region;
1449
1450     if (dest_region) {
1451         assert(dest_region->bo);
1452         dri_bo_flink(dest_region->bo, &name);
1453         
1454         if (buffer->dri2.name != name) {
1455             new_region = True;
1456             dri_bo_unreference(dest_region->bo);
1457         }
1458     } else {
1459         dest_region = (struct intel_region *)calloc(1, sizeof(*dest_region));
1460         assert(dest_region);
1461         render_state->draw_region = dest_region;
1462         new_region = True;
1463     }
1464
1465     if (new_region) {
1466         dest_region->x = dri_drawable->x;
1467         dest_region->y = dri_drawable->y;
1468         dest_region->width = dri_drawable->width;
1469         dest_region->height = dri_drawable->height;
1470         dest_region->cpp = buffer->dri2.cpp;
1471         dest_region->pitch = buffer->dri2.pitch;
1472
1473         dest_region->bo = intel_bo_gem_create_from_name(i965->intel.bufmgr, "rendering buffer", buffer->dri2.name);
1474         assert(dest_region->bo);
1475
1476         ret = dri_bo_get_tiling(dest_region->bo, &(dest_region->tiling), &(dest_region->swizzle));
1477         assert(ret == 0);
1478     }
1479
1480     i965_render_put_surface(ctx, surface,
1481                             srcx, srcy, srcw, srch,
1482                             destx, desty, destw, desth);
1483     obj_surface = SURFACE(surface);
1484     if(obj_surface->subpic != VA_INVALID_ID) {  
1485         i965_render_put_subpic(ctx, surface,
1486                            srcx, srcy, srcw, srch,
1487                            destx, desty, destw, desth);
1488     } 
1489     dri_swap_buffer(ctx, dri_drawable);
1490
1491     return VA_STATUS_SUCCESS;
1492 }
1493
1494 VAStatus 
1495 i965_Terminate(VADriverContextP ctx)
1496 {
1497     struct i965_driver_data *i965 = i965_driver_data(ctx);
1498
1499     if (i965_render_terminate(ctx) == False)
1500         return VA_STATUS_ERROR_UNKNOWN;
1501
1502     if (i965_media_terminate(ctx) == False)
1503         return VA_STATUS_ERROR_UNKNOWN;
1504
1505     if (intel_driver_terminate(ctx) == False)
1506         return VA_STATUS_ERROR_UNKNOWN;
1507
1508     i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
1509     i965_destroy_heap(&i965->image_heap, i965_destroy_image);
1510     i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
1511     i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
1512     i965_destroy_heap(&i965->context_heap, i965_destroy_context);
1513     i965_destroy_heap(&i965->config_heap, i965_destroy_config);
1514
1515     free(ctx->pDriverData);
1516     ctx->pDriverData = NULL;
1517
1518     return VA_STATUS_SUCCESS;
1519 }
1520
1521 VAStatus 
1522 __vaDriverInit_0_31(  VADriverContextP ctx )
1523 {
1524     struct i965_driver_data *i965;
1525     int result;
1526
1527     ctx->version_major = VA_MAJOR_VERSION;
1528     ctx->version_minor = VA_MINOR_VERSION;
1529     ctx->max_profiles = I965_MAX_PROFILES;
1530     ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
1531     ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
1532     ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
1533     ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
1534     ctx->max_display_attributes = I965_MAX_DISPLAY_ATTRIBUTES;
1535     ctx->str_vendor = I965_STR_VENDOR;
1536
1537     ctx->vtable.vaTerminate = i965_Terminate;
1538     ctx->vtable.vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
1539     ctx->vtable.vaQueryConfigProfiles = i965_QueryConfigProfiles;
1540     ctx->vtable.vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
1541     ctx->vtable.vaQueryConfigAttributes = i965_QueryConfigAttributes;
1542     ctx->vtable.vaCreateConfig = i965_CreateConfig;
1543     ctx->vtable.vaDestroyConfig = i965_DestroyConfig;
1544     ctx->vtable.vaGetConfigAttributes = i965_GetConfigAttributes;
1545     ctx->vtable.vaCreateSurfaces = i965_CreateSurfaces;
1546     ctx->vtable.vaDestroySurfaces = i965_DestroySurfaces;
1547     ctx->vtable.vaCreateContext = i965_CreateContext;
1548     ctx->vtable.vaDestroyContext = i965_DestroyContext;
1549     ctx->vtable.vaCreateBuffer = i965_CreateBuffer;
1550     ctx->vtable.vaBufferSetNumElements = i965_BufferSetNumElements;
1551     ctx->vtable.vaMapBuffer = i965_MapBuffer;
1552     ctx->vtable.vaUnmapBuffer = i965_UnmapBuffer;
1553     ctx->vtable.vaDestroyBuffer = i965_DestroyBuffer;
1554     ctx->vtable.vaBeginPicture = i965_BeginPicture;
1555     ctx->vtable.vaRenderPicture = i965_RenderPicture;
1556     ctx->vtable.vaEndPicture = i965_EndPicture;
1557     ctx->vtable.vaSyncSurface = i965_SyncSurface;
1558     ctx->vtable.vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
1559     ctx->vtable.vaPutSurface = i965_PutSurface;
1560     ctx->vtable.vaQueryImageFormats = i965_QueryImageFormats;
1561     ctx->vtable.vaCreateImage = i965_CreateImage;
1562     ctx->vtable.vaDeriveImage = i965_DeriveImage;
1563     ctx->vtable.vaDestroyImage = i965_DestroyImage;
1564     ctx->vtable.vaSetImagePalette = i965_SetImagePalette;
1565     ctx->vtable.vaGetImage = i965_GetImage;
1566     ctx->vtable.vaPutImage = i965_PutImage;
1567     ctx->vtable.vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
1568     ctx->vtable.vaCreateSubpicture = i965_CreateSubpicture;
1569     ctx->vtable.vaDestroySubpicture = i965_DestroySubpicture;
1570     ctx->vtable.vaSetSubpictureImage = i965_SetSubpictureImage;
1571     ctx->vtable.vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
1572     ctx->vtable.vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
1573     ctx->vtable.vaAssociateSubpicture = i965_AssociateSubpicture;
1574     ctx->vtable.vaDeassociateSubpicture = i965_DeassociateSubpicture;
1575     ctx->vtable.vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
1576     ctx->vtable.vaGetDisplayAttributes = i965_GetDisplayAttributes;
1577     ctx->vtable.vaSetDisplayAttributes = i965_SetDisplayAttributes;
1578 //    ctx->vtable.vaDbgCopySurfaceToBuffer = i965_DbgCopySurfaceToBuffer;
1579
1580     i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
1581     assert(i965);
1582     ctx->pDriverData = (void *)i965;
1583
1584     result = object_heap_init(&i965->config_heap, 
1585                               sizeof(struct object_config), 
1586                               CONFIG_ID_OFFSET);
1587     assert(result == 0);
1588
1589     result = object_heap_init(&i965->context_heap, 
1590                               sizeof(struct object_context), 
1591                               CONTEXT_ID_OFFSET);
1592     assert(result == 0);
1593
1594     result = object_heap_init(&i965->surface_heap, 
1595                               sizeof(struct object_surface), 
1596                               SURFACE_ID_OFFSET);
1597     assert(result == 0);
1598
1599     result = object_heap_init(&i965->buffer_heap, 
1600                               sizeof(struct object_buffer), 
1601                               BUFFER_ID_OFFSET);
1602     assert(result == 0);
1603
1604     result = object_heap_init(&i965->image_heap, 
1605                               sizeof(struct object_image), 
1606                               IMAGE_ID_OFFSET);
1607     assert(result == 0);
1608         
1609     result = object_heap_init(&i965->subpic_heap, 
1610                               sizeof(struct object_subpic), 
1611                               SUBPIC_ID_OFFSET);
1612     assert(result == 0);
1613
1614     return i965_Init(ctx);
1615 }