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