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