OSDN Git Service

i965_drv_video: simplify put_surface() and put_subpicture() args.
[android-x86/hardware-intel-common-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 "config.h"
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34
35 #include "va/x11/va_dricommon.h"
36
37 #include "intel_driver.h"
38 #include "intel_memman.h"
39 #include "intel_batchbuffer.h"
40 #include "i965_defines.h"
41 #include "i965_drv_video.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 #define HAS_MPEG2(ctx)  (IS_G4X((ctx)->intel.device_id) ||      \
51                          IS_IRONLAKE((ctx)->intel.device_id) || \
52                          ((IS_GEN6((ctx)->intel.device_id) ||   \
53                            IS_GEN7((ctx)->intel.device_id)) &&  \
54                           (ctx)->intel.has_bsd))
55
56 #define HAS_H264(ctx)   ((IS_GEN7((ctx)->intel.device_id) ||            \
57                           IS_GEN6((ctx)->intel.device_id) ||            \
58                           IS_IRONLAKE((ctx)->intel.device_id)) &&       \
59                          (ctx)->intel.has_bsd)
60
61 #define HAS_VC1(ctx)    ((IS_GEN7((ctx)->intel.device_id) ||    \
62                           IS_GEN6((ctx)->intel.device_id)) &&   \
63                          (ctx)->intel.has_bsd)
64
65 #define HAS_TILED_SURFACE(ctx) ((IS_GEN7((ctx)->intel.device_id) ||     \
66                                  IS_GEN6((ctx)->intel.device_id)) &&    \
67                                 (ctx)->render_state.interleaved_uv)
68
69 #define HAS_ENCODER(ctx)        ((IS_GEN7((ctx)->intel.device_id) ||    \
70                                   IS_GEN6((ctx)->intel.device_id)) &&   \
71                                  (ctx)->intel.has_bsd)
72
73 enum {
74     I965_SURFACETYPE_RGBA = 1,
75     I965_SURFACETYPE_YUV,
76     I965_SURFACETYPE_INDEXED
77 };
78
79 /* List of supported image formats */
80 typedef struct {
81     unsigned int        type;
82     VAImageFormat       va_format;
83 } i965_image_format_map_t;
84
85 static const i965_image_format_map_t
86 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
87     { I965_SURFACETYPE_YUV,
88       { VA_FOURCC('Y','V','1','2'), VA_LSB_FIRST, 12, } },
89     { I965_SURFACETYPE_YUV,
90       { VA_FOURCC('I','4','2','0'), VA_LSB_FIRST, 12, } },
91     { I965_SURFACETYPE_YUV,
92       { VA_FOURCC('N','V','1','2'), VA_LSB_FIRST, 12, } },
93 };
94
95 /* List of supported subpicture formats */
96 typedef struct {
97     unsigned int        type;
98     unsigned int        format;
99     VAImageFormat       va_format;
100     unsigned int        va_flags;
101 } i965_subpic_format_map_t;
102
103 static const i965_subpic_format_map_t
104 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
105     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
106       { VA_FOURCC('I','A','4','4'), VA_MSB_FIRST, 8, },
107       0 },
108     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
109       { VA_FOURCC('A','I','4','4'), VA_MSB_FIRST, 8, },
110       0 },
111     { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
112       { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32,
113         32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
114       0 },
115     { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
116       { VA_FOURCC('R','G','B','A'), VA_LSB_FIRST, 32,
117         32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
118       0 },
119 };
120
121 static const i965_subpic_format_map_t *
122 get_subpic_format(const VAImageFormat *va_format)
123 {
124     unsigned int i;
125     for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
126         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
127         if (m->va_format.fourcc == va_format->fourcc &&
128             (m->type == I965_SURFACETYPE_RGBA ?
129              (m->va_format.byte_order == va_format->byte_order &&
130               m->va_format.red_mask   == va_format->red_mask   &&
131               m->va_format.green_mask == va_format->green_mask &&
132               m->va_format.blue_mask  == va_format->blue_mask  &&
133               m->va_format.alpha_mask == va_format->alpha_mask) : 1))
134             return m;
135     }
136     return NULL;
137 }
138
139 extern struct hw_context *g4x_dec_hw_context_init(VADriverContextP, VAProfile);
140 static struct hw_codec_info g4x_hw_codec_info = {
141     .dec_hw_context_init = g4x_dec_hw_context_init,
142     .enc_hw_context_init = NULL,
143 };
144
145 extern struct hw_context *ironlake_dec_hw_context_init(VADriverContextP, VAProfile);
146 static struct hw_codec_info ironlake_hw_codec_info = {
147     .dec_hw_context_init = ironlake_dec_hw_context_init,
148     .enc_hw_context_init = NULL,
149 };
150
151 extern struct hw_context *gen6_dec_hw_context_init(VADriverContextP, VAProfile);
152 extern struct hw_context *gen6_enc_hw_context_init(VADriverContextP, VAProfile);
153 static struct hw_codec_info gen6_hw_codec_info = {
154     .dec_hw_context_init = gen6_dec_hw_context_init,
155     .enc_hw_context_init = gen6_enc_hw_context_init,
156 };
157
158 extern struct hw_context *gen7_dec_hw_context_init(VADriverContextP, VAProfile);
159 static struct hw_codec_info gen7_hw_codec_info = {
160     .dec_hw_context_init = gen7_dec_hw_context_init,
161     .enc_hw_context_init = gen6_enc_hw_context_init,
162 };
163
164 VAStatus 
165 i965_QueryConfigProfiles(VADriverContextP ctx,
166                          VAProfile *profile_list,       /* out */
167                          int *num_profiles)             /* out */
168 {
169     struct i965_driver_data * const i965 = i965_driver_data(ctx);
170     int i = 0;
171
172     if (HAS_MPEG2(i965)) {
173         profile_list[i++] = VAProfileMPEG2Simple;
174         profile_list[i++] = VAProfileMPEG2Main;
175     }
176
177     if (HAS_H264(i965)) {
178         profile_list[i++] = VAProfileH264Baseline;
179         profile_list[i++] = VAProfileH264Main;
180         profile_list[i++] = VAProfileH264High;
181     }
182
183     if (HAS_VC1(i965)) {
184         profile_list[i++] = VAProfileVC1Simple;
185         profile_list[i++] = VAProfileVC1Main;
186         profile_list[i++] = VAProfileVC1Advanced;
187     }
188
189     /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
190     assert(i <= I965_MAX_PROFILES);
191     *num_profiles = i;
192
193     return VA_STATUS_SUCCESS;
194 }
195
196 VAStatus 
197 i965_QueryConfigEntrypoints(VADriverContextP ctx,
198                             VAProfile profile,
199                             VAEntrypoint *entrypoint_list,      /* out */
200                             int *num_entrypoints)               /* out */
201 {
202     struct i965_driver_data * const i965 = i965_driver_data(ctx);
203     int n = 0;
204
205     switch (profile) {
206     case VAProfileMPEG2Simple:
207     case VAProfileMPEG2Main:
208         if (HAS_MPEG2(i965))
209             entrypoint_list[n++] = VAEntrypointVLD;
210         break;
211
212     case VAProfileH264Baseline:
213     case VAProfileH264Main:
214     case VAProfileH264High:
215         if (HAS_H264(i965))
216             entrypoint_list[n++] = VAEntrypointVLD;
217         
218         if (HAS_ENCODER(i965))
219             entrypoint_list[n++] = VAEntrypointEncSlice;
220
221         break;
222
223     case VAProfileVC1Simple:
224     case VAProfileVC1Main:
225     case VAProfileVC1Advanced:
226         if (HAS_VC1(i965))
227             entrypoint_list[n++] = VAEntrypointVLD;
228         break;
229
230     default:
231         break;
232     }
233
234     /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
235     assert(n <= I965_MAX_ENTRYPOINTS);
236     *num_entrypoints = n;
237     return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
238 }
239
240 VAStatus 
241 i965_GetConfigAttributes(VADriverContextP ctx,
242                          VAProfile profile,
243                          VAEntrypoint entrypoint,
244                          VAConfigAttrib *attrib_list,  /* in/out */
245                          int num_attribs)
246 {
247     int i;
248
249     /* Other attributes don't seem to be defined */
250     /* What to do if we don't know the attribute? */
251     for (i = 0; i < num_attribs; i++) {
252         switch (attrib_list[i].type) {
253         case VAConfigAttribRTFormat:
254             attrib_list[i].value = VA_RT_FORMAT_YUV420;
255             break;
256
257         case VAConfigAttribRateControl:
258             attrib_list[i].value = VA_RC_VBR;
259             break;
260
261         default:
262             /* Do nothing */
263             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
264             break;
265         }
266     }
267
268     return VA_STATUS_SUCCESS;
269 }
270
271 static void 
272 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
273 {
274     object_heap_free(heap, obj);
275 }
276
277 static VAStatus 
278 i965_update_attribute(struct object_config *obj_config, VAConfigAttrib *attrib)
279 {
280     int i;
281
282     /* Check existing attrbiutes */
283     for (i = 0; obj_config->num_attribs < i; i++) {
284         if (obj_config->attrib_list[i].type == attrib->type) {
285             /* Update existing attribute */
286             obj_config->attrib_list[i].value = attrib->value;
287             return VA_STATUS_SUCCESS;
288         }
289     }
290
291     if (obj_config->num_attribs < I965_MAX_CONFIG_ATTRIBUTES) {
292         i = obj_config->num_attribs;
293         obj_config->attrib_list[i].type = attrib->type;
294         obj_config->attrib_list[i].value = attrib->value;
295         obj_config->num_attribs++;
296         return VA_STATUS_SUCCESS;
297     }
298
299     return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
300 }
301
302 VAStatus 
303 i965_CreateConfig(VADriverContextP ctx,
304                   VAProfile profile,
305                   VAEntrypoint entrypoint,
306                   VAConfigAttrib *attrib_list,
307                   int num_attribs,
308                   VAConfigID *config_id)        /* out */
309 {
310     struct i965_driver_data * const i965 = i965_driver_data(ctx);
311     struct object_config *obj_config;
312     int configID;
313     int i;
314     VAStatus vaStatus;
315
316     /* Validate profile & entrypoint */
317     switch (profile) {
318     case VAProfileMPEG2Simple:
319     case VAProfileMPEG2Main:
320         if (HAS_MPEG2(i965) && VAEntrypointVLD == entrypoint) {
321             vaStatus = VA_STATUS_SUCCESS;
322         } else {
323             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
324         }
325         break;
326
327     case VAProfileH264Baseline:
328     case VAProfileH264Main:
329     case VAProfileH264High:
330         if ((HAS_H264(i965) && VAEntrypointVLD == entrypoint) ||
331             (HAS_ENCODER(i965) && VAEntrypointEncSlice == entrypoint)) {
332             vaStatus = VA_STATUS_SUCCESS;
333         } else {
334             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
335         }
336
337         break;
338
339     case VAProfileVC1Simple:
340     case VAProfileVC1Main:
341     case VAProfileVC1Advanced:
342         if (HAS_VC1(i965) && VAEntrypointVLD == entrypoint) {
343             vaStatus = VA_STATUS_SUCCESS;
344         } else {
345             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
346         }
347
348         break;
349
350     default:
351         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
352         break;
353     }
354
355     if (VA_STATUS_SUCCESS != vaStatus) {
356         return vaStatus;
357     }
358
359     configID = NEW_CONFIG_ID();
360     obj_config = CONFIG(configID);
361
362     if (NULL == obj_config) {
363         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
364         return vaStatus;
365     }
366
367     obj_config->profile = profile;
368     obj_config->entrypoint = entrypoint;
369     obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
370     obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
371     obj_config->num_attribs = 1;
372
373     for(i = 0; i < num_attribs; i++) {
374         vaStatus = i965_update_attribute(obj_config, &(attrib_list[i]));
375
376         if (VA_STATUS_SUCCESS != vaStatus) {
377             break;
378         }
379     }
380
381     /* Error recovery */
382     if (VA_STATUS_SUCCESS != vaStatus) {
383         i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
384     } else {
385         *config_id = configID;
386     }
387
388     return vaStatus;
389 }
390
391 VAStatus 
392 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
393 {
394     struct i965_driver_data *i965 = i965_driver_data(ctx);
395     struct object_config *obj_config = CONFIG(config_id);
396     VAStatus vaStatus;
397
398     if (NULL == obj_config) {
399         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
400         return vaStatus;
401     }
402
403     i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
404     return VA_STATUS_SUCCESS;
405 }
406
407 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
408                                     VAConfigID config_id,
409                                     VAProfile *profile,                 /* out */
410                                     VAEntrypoint *entrypoint,           /* out */
411                                     VAConfigAttrib *attrib_list,        /* out */
412                                     int *num_attribs)                   /* out */
413 {
414     struct i965_driver_data *i965 = i965_driver_data(ctx);
415     struct object_config *obj_config = CONFIG(config_id);
416     VAStatus vaStatus = VA_STATUS_SUCCESS;
417     int i;
418
419     assert(obj_config);
420     *profile = obj_config->profile;
421     *entrypoint = obj_config->entrypoint;
422     *num_attribs = obj_config->num_attribs;
423
424     for(i = 0; i < obj_config->num_attribs; i++) {
425         attrib_list[i] = obj_config->attrib_list[i];
426     }
427
428     return vaStatus;
429 }
430
431 static void 
432 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
433 {
434     struct object_surface *obj_surface = (struct object_surface *)obj;
435
436     dri_bo_unreference(obj_surface->bo);
437     obj_surface->bo = NULL;
438     dri_bo_unreference(obj_surface->pp_out_bo);
439     obj_surface->pp_out_bo = NULL;
440
441     if (obj_surface->free_private_data != NULL) {
442         obj_surface->free_private_data(&obj_surface->private_data);
443         obj_surface->private_data = NULL;
444     }
445
446     object_heap_free(heap, obj);
447 }
448
449 VAStatus 
450 i965_CreateSurfaces(VADriverContextP ctx,
451                     int width,
452                     int height,
453                     int format,
454                     int num_surfaces,
455                     VASurfaceID *surfaces)      /* out */
456 {
457     struct i965_driver_data *i965 = i965_driver_data(ctx);
458     int i;
459     VAStatus vaStatus = VA_STATUS_SUCCESS;
460
461     /* We only support one format */
462     if (VA_RT_FORMAT_YUV420 != format) {
463         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
464     }
465
466     for (i = 0; i < num_surfaces; i++) {
467         int surfaceID = NEW_SURFACE_ID();
468         struct object_surface *obj_surface = SURFACE(surfaceID);
469
470         if (NULL == obj_surface) {
471             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
472             break;
473         }
474
475         surfaces[i] = surfaceID;
476         obj_surface->status = VASurfaceReady;
477         obj_surface->subpic = VA_INVALID_ID;
478         obj_surface->orig_width = width;
479         obj_surface->orig_height = height;
480
481         if (IS_GEN6(i965->intel.device_id) ||
482             IS_GEN7(i965->intel.device_id)) {
483             obj_surface->width = ALIGN(obj_surface->orig_width, 128);
484             obj_surface->height = ALIGN(obj_surface->orig_height, 32);
485         } else {
486             obj_surface->width = ALIGN(obj_surface->orig_width, 16);
487             obj_surface->height = ALIGN(obj_surface->orig_height, 16);
488         }
489
490         obj_surface->size = SIZE_YUV420(obj_surface->width, obj_surface->height);
491         obj_surface->flags = SURFACE_REFERENCED;
492         obj_surface->fourcc = 0;
493         obj_surface->bo = NULL;
494         obj_surface->pp_out_bo = NULL;
495         obj_surface->locked_image_id = VA_INVALID_ID;
496         obj_surface->private_data = NULL;
497         obj_surface->free_private_data = NULL;
498     }
499
500     /* Error recovery */
501     if (VA_STATUS_SUCCESS != vaStatus) {
502         /* surfaces[i-1] was the last successful allocation */
503         for (; i--; ) {
504             struct object_surface *obj_surface = SURFACE(surfaces[i]);
505
506             surfaces[i] = VA_INVALID_SURFACE;
507             assert(obj_surface);
508             i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
509         }
510     }
511
512     return vaStatus;
513 }
514
515 VAStatus 
516 i965_DestroySurfaces(VADriverContextP ctx,
517                      VASurfaceID *surface_list,
518                      int num_surfaces)
519 {
520     struct i965_driver_data *i965 = i965_driver_data(ctx);
521     int i;
522
523     for (i = num_surfaces; i--; ) {
524         struct object_surface *obj_surface = SURFACE(surface_list[i]);
525
526         assert(obj_surface);
527         i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
528     }
529
530     return VA_STATUS_SUCCESS;
531 }
532
533 VAStatus 
534 i965_QueryImageFormats(VADriverContextP ctx,
535                        VAImageFormat *format_list,      /* out */
536                        int *num_formats)                /* out */
537 {
538     int n;
539
540     for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
541         const i965_image_format_map_t * const m = &i965_image_formats_map[n];
542         if (format_list)
543             format_list[n] = m->va_format;
544     }
545
546     if (num_formats)
547         *num_formats = n;
548
549     return VA_STATUS_SUCCESS;
550 }
551
552 VAStatus 
553 i965_PutImage(VADriverContextP ctx,
554               VASurfaceID surface,
555               VAImageID image,
556               int src_x,
557               int src_y,
558               unsigned int src_width,
559               unsigned int src_height,
560               int dest_x,
561               int dest_y,
562               unsigned int dest_width,
563               unsigned int dest_height)
564 {
565     return VA_STATUS_SUCCESS;
566 }
567
568 VAStatus 
569 i965_QuerySubpictureFormats(VADriverContextP ctx,
570                             VAImageFormat *format_list,         /* out */
571                             unsigned int *flags,                /* out */
572                             unsigned int *num_formats)          /* out */
573 {
574     int n;
575
576     for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
577         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
578         if (format_list)
579             format_list[n] = m->va_format;
580         if (flags)
581             flags[n] = m->va_flags;
582     }
583
584     if (num_formats)
585         *num_formats = n;
586
587     return VA_STATUS_SUCCESS;
588 }
589
590 static void 
591 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
592 {
593     //    struct object_subpic *obj_subpic = (struct object_subpic *)obj;
594
595     object_heap_free(heap, obj);
596 }
597
598 VAStatus 
599 i965_CreateSubpicture(VADriverContextP ctx,
600                       VAImageID image,
601                       VASubpictureID *subpicture)         /* out */
602 {
603     struct i965_driver_data *i965 = i965_driver_data(ctx);
604     VASubpictureID subpicID = NEW_SUBPIC_ID()
605     struct object_subpic *obj_subpic = SUBPIC(subpicID);
606
607     if (!obj_subpic)
608         return VA_STATUS_ERROR_ALLOCATION_FAILED;
609
610     struct object_image *obj_image = IMAGE(image);
611     if (!obj_image)
612         return VA_STATUS_ERROR_INVALID_IMAGE;
613
614     const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
615     if (!m)
616         return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
617
618     *subpicture = subpicID;
619     obj_subpic->image  = image;
620     obj_subpic->format = m->format;
621     obj_subpic->width  = obj_image->image.width;
622     obj_subpic->height = obj_image->image.height;
623     obj_subpic->pitch  = obj_image->image.pitches[0];
624     obj_subpic->bo     = obj_image->bo;
625     return VA_STATUS_SUCCESS;
626 }
627
628 VAStatus 
629 i965_DestroySubpicture(VADriverContextP ctx,
630                        VASubpictureID subpicture)
631 {
632     struct i965_driver_data *i965 = i965_driver_data(ctx);
633     struct object_subpic *obj_subpic = SUBPIC(subpicture);
634     i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
635     return VA_STATUS_SUCCESS;
636 }
637
638 VAStatus 
639 i965_SetSubpictureImage(VADriverContextP ctx,
640                         VASubpictureID subpicture,
641                         VAImageID image)
642 {
643     /* TODO */
644     return VA_STATUS_ERROR_UNIMPLEMENTED;
645 }
646
647 VAStatus 
648 i965_SetSubpictureChromakey(VADriverContextP ctx,
649                             VASubpictureID subpicture,
650                             unsigned int chromakey_min,
651                             unsigned int chromakey_max,
652                             unsigned int chromakey_mask)
653 {
654     /* TODO */
655     return VA_STATUS_ERROR_UNIMPLEMENTED;
656 }
657
658 VAStatus 
659 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
660                               VASubpictureID subpicture,
661                               float global_alpha)
662 {
663     /* TODO */
664     return VA_STATUS_ERROR_UNIMPLEMENTED;
665 }
666
667 VAStatus 
668 i965_AssociateSubpicture(VADriverContextP ctx,
669                          VASubpictureID subpicture,
670                          VASurfaceID *target_surfaces,
671                          int num_surfaces,
672                          short src_x, /* upper left offset in subpicture */
673                          short src_y,
674                          unsigned short src_width,
675                          unsigned short src_height,
676                          short dest_x, /* upper left offset in surface */
677                          short dest_y,
678                          unsigned short dest_width,
679                          unsigned short dest_height,
680                          /*
681                           * whether to enable chroma-keying or global-alpha
682                           * see VA_SUBPICTURE_XXX values
683                           */
684                          unsigned int flags)
685 {
686     struct i965_driver_data *i965 = i965_driver_data(ctx);
687     struct object_subpic *obj_subpic = SUBPIC(subpicture);
688     int i;
689
690     obj_subpic->src_rect.x      = src_x;
691     obj_subpic->src_rect.y      = src_y;
692     obj_subpic->src_rect.width  = src_width;
693     obj_subpic->src_rect.height = src_height;
694     obj_subpic->dst_rect.x      = dest_x;
695     obj_subpic->dst_rect.y      = dest_y;
696     obj_subpic->dst_rect.width  = dest_width;
697     obj_subpic->dst_rect.height = dest_height;
698
699     for (i = 0; i < num_surfaces; i++) {
700         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
701         if (!obj_surface)
702             return VA_STATUS_ERROR_INVALID_SURFACE;
703         obj_surface->subpic = subpicture;
704     }
705     return VA_STATUS_SUCCESS;
706 }
707
708
709 VAStatus 
710 i965_DeassociateSubpicture(VADriverContextP ctx,
711                            VASubpictureID subpicture,
712                            VASurfaceID *target_surfaces,
713                            int num_surfaces)
714 {
715     struct i965_driver_data *i965 = i965_driver_data(ctx);
716     int i;
717
718     for (i = 0; i < num_surfaces; i++) {
719         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
720         if (!obj_surface)
721             return VA_STATUS_ERROR_INVALID_SURFACE;
722         if (obj_surface->subpic == subpicture)
723             obj_surface->subpic = VA_INVALID_ID;
724     }
725     return VA_STATUS_SUCCESS;
726 }
727
728 void
729 i965_reference_buffer_store(struct buffer_store **ptr, 
730                             struct buffer_store *buffer_store)
731 {
732     assert(*ptr == NULL);
733
734     if (buffer_store) {
735         buffer_store->ref_count++;
736         *ptr = buffer_store;
737     }
738 }
739
740 void 
741 i965_release_buffer_store(struct buffer_store **ptr)
742 {
743     struct buffer_store *buffer_store = *ptr;
744
745     if (buffer_store == NULL)
746         return;
747
748     assert(buffer_store->bo || buffer_store->buffer);
749     assert(!(buffer_store->bo && buffer_store->buffer));
750     buffer_store->ref_count--;
751     
752     if (buffer_store->ref_count == 0) {
753         dri_bo_unreference(buffer_store->bo);
754         free(buffer_store->buffer);
755         buffer_store->bo = NULL;
756         buffer_store->buffer = NULL;
757         free(buffer_store);
758     }
759
760     *ptr = NULL;
761 }
762
763 static void 
764 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
765 {
766     struct object_context *obj_context = (struct object_context *)obj;
767     int i;
768
769     if (obj_context->hw_context) {
770         obj_context->hw_context->destroy(obj_context->hw_context);
771         obj_context->hw_context = NULL;
772     }
773
774     if (obj_context->codec_type == CODEC_ENC) {
775         assert(obj_context->codec_state.enc.num_slice_params <= obj_context->codec_state.enc.max_slice_params);
776         i965_release_buffer_store(&obj_context->codec_state.enc.pic_param);
777         i965_release_buffer_store(&obj_context->codec_state.enc.seq_param);
778     } else {
779         assert(obj_context->codec_state.dec.num_slice_params <= obj_context->codec_state.dec.max_slice_params);
780         assert(obj_context->codec_state.dec.num_slice_datas <= obj_context->codec_state.dec.max_slice_datas);
781
782         i965_release_buffer_store(&obj_context->codec_state.dec.pic_param);
783         i965_release_buffer_store(&obj_context->codec_state.dec.iq_matrix);
784         i965_release_buffer_store(&obj_context->codec_state.dec.bit_plane);
785
786         for (i = 0; i < obj_context->codec_state.dec.num_slice_params; i++)
787             i965_release_buffer_store(&obj_context->codec_state.dec.slice_params[i]);
788
789         for (i = 0; i < obj_context->codec_state.dec.num_slice_datas; i++)
790             i965_release_buffer_store(&obj_context->codec_state.dec.slice_datas[i]);
791
792         free(obj_context->codec_state.dec.slice_params);
793         free(obj_context->codec_state.dec.slice_datas);
794     }
795
796     free(obj_context->render_targets);
797     object_heap_free(heap, obj);
798 }
799
800 VAStatus
801 i965_CreateContext(VADriverContextP ctx,
802                    VAConfigID config_id,
803                    int picture_width,
804                    int picture_height,
805                    int flag,
806                    VASurfaceID *render_targets,
807                    int num_render_targets,
808                    VAContextID *context)                /* out */
809 {
810     struct i965_driver_data *i965 = i965_driver_data(ctx);
811     struct i965_render_state *render_state = &i965->render_state;
812     struct object_config *obj_config = CONFIG(config_id);
813     struct object_context *obj_context = NULL;
814     VAStatus vaStatus = VA_STATUS_SUCCESS;
815     int contextID;
816     int i;
817
818     if (NULL == obj_config) {
819         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
820         return vaStatus;
821     }
822
823     /* Validate flag */
824     /* Validate picture dimensions */
825     contextID = NEW_CONTEXT_ID();
826     obj_context = CONTEXT(contextID);
827
828     if (NULL == obj_context) {
829         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
830         return vaStatus;
831     }
832
833     render_state->inited = 1;
834
835     switch (obj_config->profile) {
836     case VAProfileH264Baseline:
837     case VAProfileH264Main:
838     case VAProfileH264High:
839         if (!HAS_H264(i965))
840             return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
841         render_state->interleaved_uv = 1;
842         break;
843     default:
844         render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_id) || IS_GEN7(i965->intel.device_id));
845         break;
846     }
847
848     *context = contextID;
849     obj_context->flags = flag;
850     obj_context->context_id = contextID;
851     obj_context->config_id = config_id;
852     obj_context->picture_width = picture_width;
853     obj_context->picture_height = picture_height;
854     obj_context->num_render_targets = num_render_targets;
855     obj_context->render_targets = 
856         (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
857     obj_context->hw_context = NULL;
858
859     for(i = 0; i < num_render_targets; i++) {
860         if (NULL == SURFACE(render_targets[i])) {
861             vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
862             break;
863         }
864
865         obj_context->render_targets[i] = render_targets[i];
866     }
867
868     if (VA_STATUS_SUCCESS == vaStatus) {
869         if (VAEntrypointEncSlice == obj_config->entrypoint ) { /*encode routin only*/
870             obj_context->codec_type = CODEC_ENC;
871             memset(&obj_context->codec_state.enc, 0, sizeof(obj_context->codec_state.enc));
872             obj_context->codec_state.enc.current_render_target = VA_INVALID_ID;
873             obj_context->codec_state.enc.max_slice_params = NUM_SLICES;
874             obj_context->codec_state.enc.slice_params = calloc(obj_context->codec_state.enc.max_slice_params,
875                                                                sizeof(*obj_context->codec_state.enc.slice_params));
876             assert(i965->codec_info->enc_hw_context_init);
877             obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config->profile);
878         } else {
879             obj_context->codec_type = CODEC_DEC;
880             memset(&obj_context->codec_state.dec, 0, sizeof(obj_context->codec_state.dec));
881             obj_context->codec_state.dec.current_render_target = -1;
882             obj_context->codec_state.dec.max_slice_params = NUM_SLICES;
883             obj_context->codec_state.dec.max_slice_datas = NUM_SLICES;
884             obj_context->codec_state.dec.slice_params = calloc(obj_context->codec_state.dec.max_slice_params,
885                                                                sizeof(*obj_context->codec_state.dec.slice_params));
886             obj_context->codec_state.dec.slice_datas = calloc(obj_context->codec_state.dec.max_slice_datas,
887                                                               sizeof(*obj_context->codec_state.dec.slice_datas));
888
889             assert(i965->codec_info->dec_hw_context_init);
890             obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config->profile);
891         }
892     }
893
894     /* Error recovery */
895     if (VA_STATUS_SUCCESS != vaStatus) {
896         i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
897     }
898
899     return vaStatus;
900 }
901
902 VAStatus 
903 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
904 {
905     struct i965_driver_data *i965 = i965_driver_data(ctx);
906     struct object_context *obj_context = CONTEXT(context);
907
908     assert(obj_context);
909     i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
910
911     return VA_STATUS_SUCCESS;
912 }
913
914 static void 
915 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
916 {
917     struct object_buffer *obj_buffer = (struct object_buffer *)obj;
918
919     assert(obj_buffer->buffer_store);
920     i965_release_buffer_store(&obj_buffer->buffer_store);
921     object_heap_free(heap, obj);
922 }
923
924 static VAStatus
925 i965_create_buffer_internal(VADriverContextP ctx,
926                             VAContextID context,
927                             VABufferType type,
928                             unsigned int size,
929                             unsigned int num_elements,
930                             void *data,
931                             dri_bo *store_bo,
932                             VABufferID *buf_id)
933 {
934     struct i965_driver_data *i965 = i965_driver_data(ctx);
935     struct object_buffer *obj_buffer = NULL;
936     struct buffer_store *buffer_store = NULL;
937     int bufferID;
938
939     /* Validate type */
940     switch (type) {
941     case VAPictureParameterBufferType:
942     case VAIQMatrixBufferType:
943     case VABitPlaneBufferType:
944     case VASliceGroupMapBufferType:
945     case VASliceParameterBufferType:
946     case VASliceDataBufferType:
947     case VAMacroblockParameterBufferType:
948     case VAResidualDataBufferType:
949     case VADeblockingParameterBufferType:
950     case VAImageBufferType:
951     case VAEncCodedBufferType:
952     case VAEncSequenceParameterBufferType:
953     case VAEncPictureParameterBufferType:
954     case VAEncSliceParameterBufferType:
955         /* Ok */
956         break;
957
958     default:
959         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
960     }
961
962     bufferID = NEW_BUFFER_ID();
963     obj_buffer = BUFFER(bufferID);
964
965     if (NULL == obj_buffer) {
966         return VA_STATUS_ERROR_ALLOCATION_FAILED;
967     }
968
969     if (type == VAEncCodedBufferType) {
970         size += ALIGN(sizeof(VACodedBufferSegment), 64);
971     }
972
973     obj_buffer->max_num_elements = num_elements;
974     obj_buffer->num_elements = num_elements;
975     obj_buffer->size_element = size;
976     obj_buffer->type = type;
977     obj_buffer->buffer_store = NULL;
978     buffer_store = calloc(1, sizeof(struct buffer_store));
979     assert(buffer_store);
980     buffer_store->ref_count = 1;
981
982     if (store_bo != NULL) {
983         buffer_store->bo = store_bo;
984         dri_bo_reference(buffer_store->bo);
985         
986         if (data)
987             dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
988     } else if (type == VASliceDataBufferType || type == VAImageBufferType || type == VAEncCodedBufferType) {
989         buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, 
990                                         "Buffer", 
991                                         size * num_elements, 64);
992         assert(buffer_store->bo);
993
994         if (type == VAEncCodedBufferType) {
995             VACodedBufferSegment *coded_buffer_segment;
996             dri_bo_map(buffer_store->bo, 1);
997             coded_buffer_segment = (VACodedBufferSegment *)buffer_store->bo->virtual;
998             coded_buffer_segment->size = size - ALIGN(sizeof(VACodedBufferSegment), 64);
999             coded_buffer_segment->bit_offset = 0;
1000             coded_buffer_segment->status = 0;
1001             coded_buffer_segment->buf = NULL;
1002             coded_buffer_segment->next = NULL;
1003             dri_bo_unmap(buffer_store->bo);
1004         } else if (data) {
1005             dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1006         }
1007
1008     } else {
1009         buffer_store->buffer = malloc(size * num_elements);
1010         assert(buffer_store->buffer);
1011
1012         if (data)
1013             memcpy(buffer_store->buffer, data, size * num_elements);
1014     }
1015
1016     buffer_store->num_elements = obj_buffer->num_elements;
1017     i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
1018     i965_release_buffer_store(&buffer_store);
1019     *buf_id = bufferID;
1020
1021     return VA_STATUS_SUCCESS;
1022 }
1023
1024 VAStatus 
1025 i965_CreateBuffer(VADriverContextP ctx,
1026                   VAContextID context,          /* in */
1027                   VABufferType type,            /* in */
1028                   unsigned int size,            /* in */
1029                   unsigned int num_elements,    /* in */
1030                   void *data,                   /* in */
1031                   VABufferID *buf_id)           /* out */
1032 {
1033     return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
1034 }
1035
1036
1037 VAStatus 
1038 i965_BufferSetNumElements(VADriverContextP ctx,
1039                           VABufferID buf_id,           /* in */
1040                           unsigned int num_elements)   /* in */
1041 {
1042     struct i965_driver_data *i965 = i965_driver_data(ctx);
1043     struct object_buffer *obj_buffer = BUFFER(buf_id);
1044     VAStatus vaStatus = VA_STATUS_SUCCESS;
1045
1046     assert(obj_buffer);
1047
1048     if ((num_elements < 0) || 
1049         (num_elements > obj_buffer->max_num_elements)) {
1050         vaStatus = VA_STATUS_ERROR_UNKNOWN;
1051     } else {
1052         obj_buffer->num_elements = num_elements;
1053         if (obj_buffer->buffer_store != NULL) {
1054             obj_buffer->buffer_store->num_elements = num_elements;
1055         }
1056     }
1057
1058     return vaStatus;
1059 }
1060
1061 VAStatus 
1062 i965_MapBuffer(VADriverContextP ctx,
1063                VABufferID buf_id,       /* in */
1064                void **pbuf)             /* out */
1065 {
1066     struct i965_driver_data *i965 = i965_driver_data(ctx);
1067     struct object_buffer *obj_buffer = BUFFER(buf_id);
1068     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1069
1070     assert(obj_buffer && obj_buffer->buffer_store);
1071     assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
1072     assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
1073
1074     if (NULL != obj_buffer->buffer_store->bo) {
1075         unsigned int tiling, swizzle;
1076
1077         dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1078
1079         if (tiling != I915_TILING_NONE)
1080             drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
1081         else
1082             dri_bo_map(obj_buffer->buffer_store->bo, 1);
1083
1084         assert(obj_buffer->buffer_store->bo->virtual);
1085         *pbuf = obj_buffer->buffer_store->bo->virtual;
1086
1087         if (obj_buffer->type == VAEncCodedBufferType) {
1088             VACodedBufferSegment *coded_buffer_segment = (VACodedBufferSegment *)(obj_buffer->buffer_store->bo->virtual);
1089             coded_buffer_segment->buf = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + ALIGN(sizeof(VACodedBufferSegment), 64);
1090         }
1091
1092         vaStatus = VA_STATUS_SUCCESS;
1093     } else if (NULL != obj_buffer->buffer_store->buffer) {
1094         *pbuf = obj_buffer->buffer_store->buffer;
1095         vaStatus = VA_STATUS_SUCCESS;
1096     }
1097
1098     return vaStatus;
1099 }
1100
1101 VAStatus 
1102 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
1103 {
1104     struct i965_driver_data *i965 = i965_driver_data(ctx);
1105     struct object_buffer *obj_buffer = BUFFER(buf_id);
1106     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1107
1108     assert(obj_buffer && obj_buffer->buffer_store);
1109     assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
1110     assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
1111
1112     if (NULL != obj_buffer->buffer_store->bo) {
1113         unsigned int tiling, swizzle;
1114
1115         dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1116
1117         if (tiling != I915_TILING_NONE)
1118             drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
1119         else
1120             dri_bo_unmap(obj_buffer->buffer_store->bo);
1121
1122         vaStatus = VA_STATUS_SUCCESS;
1123     } else if (NULL != obj_buffer->buffer_store->buffer) {
1124         /* Do nothing */
1125         vaStatus = VA_STATUS_SUCCESS;
1126     }
1127
1128     return vaStatus;    
1129 }
1130
1131 VAStatus 
1132 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
1133 {
1134     struct i965_driver_data *i965 = i965_driver_data(ctx);
1135     struct object_buffer *obj_buffer = BUFFER(buffer_id);
1136
1137     assert(obj_buffer);
1138     i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
1139
1140     return VA_STATUS_SUCCESS;
1141 }
1142
1143 VAStatus 
1144 i965_BeginPicture(VADriverContextP ctx,
1145                   VAContextID context,
1146                   VASurfaceID render_target)
1147 {
1148     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1149     struct object_context *obj_context = CONTEXT(context);
1150     struct object_surface *obj_surface = SURFACE(render_target);
1151     struct object_config *obj_config;
1152     VAContextID config;
1153     VAStatus vaStatus;
1154
1155     assert(obj_context);
1156     assert(obj_surface);
1157
1158     config = obj_context->config_id;
1159     obj_config = CONFIG(config);
1160     assert(obj_config);
1161
1162     switch (obj_config->profile) {
1163     case VAProfileMPEG2Simple:
1164     case VAProfileMPEG2Main:
1165         vaStatus = VA_STATUS_SUCCESS;
1166         break;
1167
1168     case VAProfileH264Baseline:
1169     case VAProfileH264Main:
1170     case VAProfileH264High:
1171         vaStatus = VA_STATUS_SUCCESS;
1172         break;
1173
1174     case VAProfileVC1Simple:
1175     case VAProfileVC1Main:
1176     case VAProfileVC1Advanced:
1177         vaStatus = VA_STATUS_SUCCESS;
1178         break;
1179
1180     default:
1181         assert(0);
1182         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1183         break;
1184     }
1185
1186     if (obj_context->codec_type == CODEC_ENC)
1187         obj_context->codec_state.enc.current_render_target = render_target;     /*This is input new frame*/
1188     else
1189         obj_context->codec_state.dec.current_render_target = render_target;
1190
1191     return vaStatus;
1192 }
1193
1194 static VAStatus
1195 i965_render_picture_parameter_buffer(VADriverContextP ctx,
1196                                      struct object_context *obj_context,
1197                                      struct object_buffer *obj_buffer)
1198 {
1199     assert(obj_buffer->buffer_store->bo == NULL);
1200     assert(obj_buffer->buffer_store->buffer);
1201     i965_release_buffer_store(&obj_context->codec_state.dec.pic_param);
1202     i965_reference_buffer_store(&obj_context->codec_state.dec.pic_param,
1203                                 obj_buffer->buffer_store);
1204
1205     return VA_STATUS_SUCCESS;
1206 }
1207
1208 static VAStatus
1209 i965_render_iq_matrix_buffer(VADriverContextP ctx,
1210                              struct object_context *obj_context,
1211                              struct object_buffer *obj_buffer)
1212 {
1213     assert(obj_buffer->buffer_store->bo == NULL);
1214     assert(obj_buffer->buffer_store->buffer);
1215     i965_release_buffer_store(&obj_context->codec_state.dec.iq_matrix);
1216     i965_reference_buffer_store(&obj_context->codec_state.dec.iq_matrix,
1217                                 obj_buffer->buffer_store);
1218
1219     return VA_STATUS_SUCCESS;
1220 }
1221
1222 static VAStatus
1223 i965_render_bit_plane_buffer(VADriverContextP ctx,
1224                              struct object_context *obj_context,
1225                              struct object_buffer *obj_buffer)
1226 {
1227     assert(obj_buffer->buffer_store->bo == NULL);
1228     assert(obj_buffer->buffer_store->buffer);
1229     i965_release_buffer_store(&obj_context->codec_state.dec.bit_plane);
1230     i965_reference_buffer_store(&obj_context->codec_state.dec.bit_plane,
1231                                 obj_buffer->buffer_store);
1232     
1233     return VA_STATUS_SUCCESS;
1234 }
1235
1236 static VAStatus
1237 i965_render_slice_parameter_buffer(VADriverContextP ctx,
1238                                    struct object_context *obj_context,
1239                                    struct object_buffer *obj_buffer)
1240 {
1241     assert(obj_buffer->buffer_store->bo == NULL);
1242     assert(obj_buffer->buffer_store->buffer);
1243     
1244     if (obj_context->codec_state.dec.num_slice_params == obj_context->codec_state.dec.max_slice_params) {
1245         obj_context->codec_state.dec.slice_params = realloc(obj_context->codec_state.dec.slice_params,
1246                                                          (obj_context->codec_state.dec.max_slice_params + NUM_SLICES) * sizeof(*obj_context->codec_state.dec.slice_params));
1247         memset(obj_context->codec_state.dec.slice_params + obj_context->codec_state.dec.max_slice_params, 0, NUM_SLICES * sizeof(*obj_context->codec_state.dec.slice_params));
1248         obj_context->codec_state.dec.max_slice_params += NUM_SLICES;
1249     }
1250         
1251     i965_release_buffer_store(&obj_context->codec_state.dec.slice_params[obj_context->codec_state.dec.num_slice_params]);
1252     i965_reference_buffer_store(&obj_context->codec_state.dec.slice_params[obj_context->codec_state.dec.num_slice_params],
1253                                 obj_buffer->buffer_store);
1254     obj_context->codec_state.dec.num_slice_params++;
1255     
1256     return VA_STATUS_SUCCESS;
1257 }
1258
1259 static VAStatus
1260 i965_render_slice_data_buffer(VADriverContextP ctx,
1261                               struct object_context *obj_context,
1262                               struct object_buffer *obj_buffer)
1263 {
1264     assert(obj_buffer->buffer_store->buffer == NULL);
1265     assert(obj_buffer->buffer_store->bo);
1266
1267     if (obj_context->codec_state.dec.num_slice_datas == obj_context->codec_state.dec.max_slice_datas) {
1268         obj_context->codec_state.dec.slice_datas = realloc(obj_context->codec_state.dec.slice_datas,
1269                                                         (obj_context->codec_state.dec.max_slice_datas + NUM_SLICES) * sizeof(*obj_context->codec_state.dec.slice_datas));
1270         memset(obj_context->codec_state.dec.slice_datas + obj_context->codec_state.dec.max_slice_datas, 0, NUM_SLICES * sizeof(*obj_context->codec_state.dec.slice_datas));
1271         obj_context->codec_state.dec.max_slice_datas += NUM_SLICES;
1272     }
1273         
1274     i965_release_buffer_store(&obj_context->codec_state.dec.slice_datas[obj_context->codec_state.dec.num_slice_datas]);
1275     i965_reference_buffer_store(&obj_context->codec_state.dec.slice_datas[obj_context->codec_state.dec.num_slice_datas],
1276                                 obj_buffer->buffer_store);
1277     obj_context->codec_state.dec.num_slice_datas++;
1278     
1279     return VA_STATUS_SUCCESS;
1280 }
1281
1282 static VAStatus 
1283 i965_decoder_render_picture(VADriverContextP ctx,
1284                             VAContextID context,
1285                             VABufferID *buffers,
1286                             int num_buffers)
1287 {
1288     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1289     struct object_context *obj_context = CONTEXT(context);
1290     VAStatus vaStatus;
1291     int i;
1292
1293     for (i = 0; i < num_buffers; i++) {
1294         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
1295         assert(obj_buffer);
1296
1297         switch (obj_buffer->type) {
1298         case VAPictureParameterBufferType:
1299             vaStatus = i965_render_picture_parameter_buffer(ctx, obj_context, obj_buffer);
1300             break;
1301             
1302         case VAIQMatrixBufferType:
1303             vaStatus = i965_render_iq_matrix_buffer(ctx, obj_context, obj_buffer);
1304             break;
1305
1306         case VABitPlaneBufferType:
1307             vaStatus = i965_render_bit_plane_buffer(ctx, obj_context, obj_buffer);
1308             break;
1309
1310         case VASliceParameterBufferType:
1311             vaStatus = i965_render_slice_parameter_buffer(ctx, obj_context, obj_buffer);
1312             break;
1313
1314         case VASliceDataBufferType:
1315             vaStatus = i965_render_slice_data_buffer(ctx, obj_context, obj_buffer);
1316             break;
1317
1318         default:
1319             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1320             break;
1321         }
1322     }
1323
1324     return vaStatus;
1325 }
1326
1327 static VAStatus
1328 i965_encoder_render_squence_parameter_buffer(VADriverContextP ctx, 
1329                                              struct object_context *obj_context,
1330                                              struct object_buffer *obj_buffer)
1331 {
1332     assert(obj_buffer->buffer_store->bo == NULL);
1333     assert(obj_buffer->buffer_store->buffer);
1334     i965_release_buffer_store(&obj_context->codec_state.enc.seq_param);
1335     i965_reference_buffer_store(&obj_context->codec_state.enc.seq_param,
1336                                 obj_buffer->buffer_store);
1337
1338     return VA_STATUS_SUCCESS;
1339 }
1340
1341
1342 static VAStatus
1343 i965_encoder_render_picture_parameter_buffer(VADriverContextP ctx, 
1344                                              struct object_context *obj_context,
1345                                              struct object_buffer *obj_buffer)
1346 {
1347     assert(obj_buffer->buffer_store->bo == NULL);
1348     assert(obj_buffer->buffer_store->buffer);
1349     i965_release_buffer_store(&obj_context->codec_state.enc.pic_param);
1350     i965_reference_buffer_store(&obj_context->codec_state.enc.pic_param,
1351                                 obj_buffer->buffer_store);
1352
1353     return VA_STATUS_SUCCESS;
1354 }
1355
1356 static VAStatus
1357 i965_encoder_render_slice_parameter_buffer(VADriverContextP ctx, 
1358                                            struct object_context *obj_context,
1359                                            struct object_buffer *obj_buffer)
1360 {
1361     if (obj_context->codec_state.enc.num_slice_params == obj_context->codec_state.enc.max_slice_params) {
1362         obj_context->codec_state.enc.slice_params = realloc(obj_context->codec_state.enc.slice_params,
1363                                                             (obj_context->codec_state.enc.max_slice_params + NUM_SLICES) * sizeof(*obj_context->codec_state.enc.slice_params));
1364         memset(obj_context->codec_state.enc.slice_params + obj_context->codec_state.enc.max_slice_params, 0, NUM_SLICES * sizeof(*obj_context->codec_state.enc.slice_params));
1365         obj_context->codec_state.enc.max_slice_params += NUM_SLICES;
1366     }
1367
1368     i965_release_buffer_store(&obj_context->codec_state.enc.slice_params[obj_context->codec_state.enc.num_slice_params]);
1369     i965_reference_buffer_store(&obj_context->codec_state.enc.slice_params[obj_context->codec_state.enc.num_slice_params],
1370                                 obj_buffer->buffer_store);
1371     obj_context->codec_state.enc.num_slice_params++;
1372     
1373     return VA_STATUS_SUCCESS;
1374 }
1375
1376 static VAStatus
1377 i965_encoder_render_picture_control_buffer(VADriverContextP ctx, 
1378                                            struct object_context *obj_context,
1379                                            struct object_buffer *obj_buffer)
1380 {
1381     assert(obj_buffer->buffer_store->bo == NULL);
1382     assert(obj_buffer->buffer_store->buffer);
1383     i965_release_buffer_store(&obj_context->codec_state.enc.pic_control);
1384     i965_reference_buffer_store(&obj_context->codec_state.enc.pic_control,
1385                                 obj_buffer->buffer_store);
1386
1387     return VA_STATUS_SUCCESS;
1388 }
1389
1390 static VAStatus
1391 i965_encoder_render_qmatrix_buffer(VADriverContextP ctx, 
1392                                    struct object_context *obj_context,
1393                                    struct object_buffer *obj_buffer)
1394 {
1395     assert(obj_buffer->buffer_store->bo == NULL);
1396     assert(obj_buffer->buffer_store->buffer);
1397     i965_release_buffer_store(&obj_context->codec_state.enc.q_matrix);
1398     i965_reference_buffer_store(&obj_context->codec_state.enc.iq_matrix,
1399                                 obj_buffer->buffer_store);
1400     
1401     return VA_STATUS_SUCCESS;
1402 }
1403
1404 static VAStatus
1405 i965_encoder_render_iqmatrix_buffer(VADriverContextP ctx, 
1406                                     struct object_context *obj_context,
1407                                     struct object_buffer *obj_buffer)
1408 {
1409     assert(obj_buffer->buffer_store->bo == NULL);
1410     assert(obj_buffer->buffer_store->buffer);
1411     i965_release_buffer_store(&obj_context->codec_state.enc.iq_matrix);
1412     i965_reference_buffer_store(&obj_context->codec_state.enc.iq_matrix,
1413                                 obj_buffer->buffer_store);
1414
1415     return VA_STATUS_SUCCESS;
1416 }
1417
1418 static VAStatus 
1419 i965_encoder_render_picture(VADriverContextP ctx,
1420                             VAContextID context,
1421                             VABufferID *buffers,
1422                             int num_buffers)
1423 {
1424     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1425     struct object_context *obj_context = CONTEXT(context);
1426     VAStatus vaStatus;
1427     int i;
1428
1429     for (i = 0; i < num_buffers; i++) {  
1430         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
1431         assert(obj_buffer);
1432
1433         switch (obj_buffer->type) {
1434         case VAEncSequenceParameterBufferType:
1435             vaStatus = i965_encoder_render_squence_parameter_buffer(ctx, obj_context, obj_buffer);
1436             break;
1437
1438         case VAEncPictureParameterBufferType:
1439             vaStatus = i965_encoder_render_picture_parameter_buffer(ctx, obj_context, obj_buffer);
1440             break;              
1441
1442         case VAEncSliceParameterBufferType:
1443             vaStatus = i965_encoder_render_slice_parameter_buffer(ctx, obj_context, obj_buffer);
1444             break;
1445
1446         case VAPictureParameterBufferType:
1447             vaStatus = i965_encoder_render_picture_control_buffer(ctx, obj_context, obj_buffer);
1448             break;
1449
1450         case VAQMatrixBufferType:
1451             vaStatus = i965_encoder_render_qmatrix_buffer(ctx, obj_context, obj_buffer);
1452             break;
1453
1454         case VAIQMatrixBufferType:
1455             vaStatus = i965_encoder_render_iqmatrix_buffer(ctx, obj_context, obj_buffer);
1456             break;
1457
1458         default:
1459             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1460             break;
1461         }
1462     }   
1463
1464     return vaStatus;
1465 }
1466
1467 VAStatus 
1468 i965_RenderPicture(VADriverContextP ctx,
1469                    VAContextID context,
1470                    VABufferID *buffers,
1471                    int num_buffers)
1472 {
1473     struct i965_driver_data *i965 = i965_driver_data(ctx);
1474     struct object_context *obj_context;
1475     struct object_config *obj_config;
1476     VAContextID config;
1477     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1478
1479     obj_context = CONTEXT(context);
1480     assert(obj_context);
1481
1482     config = obj_context->config_id;
1483     obj_config = CONFIG(config);
1484     assert(obj_config);
1485
1486     if (VAEntrypointEncSlice == obj_config->entrypoint ){
1487         vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
1488     } else {
1489         vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
1490     }
1491
1492     return vaStatus;
1493 }
1494
1495 VAStatus 
1496 i965_EndPicture(VADriverContextP ctx, VAContextID context)
1497 {
1498     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1499     struct object_context *obj_context = CONTEXT(context);
1500     struct object_config *obj_config;
1501     VAContextID config;
1502     int i;
1503
1504     assert(obj_context);
1505     config = obj_context->config_id;
1506     obj_config = CONFIG(config);
1507     assert(obj_config);
1508
1509     if (obj_context->codec_type == CODEC_ENC) {
1510         assert(VAEntrypointEncSlice == obj_config->entrypoint);
1511
1512         assert(obj_context->codec_state.enc.pic_param);
1513         assert(obj_context->codec_state.enc.seq_param);
1514         assert(obj_context->codec_state.enc.num_slice_params >= 1);
1515     } else {
1516         assert(obj_context->codec_state.dec.pic_param);
1517         assert(obj_context->codec_state.dec.num_slice_params >= 1);
1518         assert(obj_context->codec_state.dec.num_slice_datas >= 1);
1519         assert(obj_context->codec_state.dec.num_slice_params == obj_context->codec_state.dec.num_slice_datas);
1520     }
1521
1522     assert(obj_context->hw_context->run);
1523     obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
1524
1525     if (obj_context->codec_type == CODEC_ENC) {
1526         obj_context->codec_state.enc.current_render_target = VA_INVALID_SURFACE;
1527         obj_context->codec_state.enc.num_slice_params = 0;
1528         i965_release_buffer_store(&obj_context->codec_state.enc.pic_param);
1529         i965_release_buffer_store(&obj_context->codec_state.enc.seq_param);
1530
1531         for (i = 0; i < obj_context->codec_state.enc.num_slice_params; i++) {
1532             i965_release_buffer_store(&obj_context->codec_state.enc.slice_params[i]);
1533         }
1534     } else {
1535         obj_context->codec_state.dec.current_render_target = -1;
1536         obj_context->codec_state.dec.num_slice_params = 0;
1537         obj_context->codec_state.dec.num_slice_datas = 0;
1538         i965_release_buffer_store(&obj_context->codec_state.dec.pic_param);
1539         i965_release_buffer_store(&obj_context->codec_state.dec.iq_matrix);
1540         i965_release_buffer_store(&obj_context->codec_state.dec.bit_plane);
1541
1542         for (i = 0; i < obj_context->codec_state.dec.num_slice_params; i++) {
1543             i965_release_buffer_store(&obj_context->codec_state.dec.slice_params[i]);
1544             i965_release_buffer_store(&obj_context->codec_state.dec.slice_datas[i]);
1545         }
1546     }
1547
1548     return VA_STATUS_SUCCESS;
1549 }
1550
1551 VAStatus 
1552 i965_SyncSurface(VADriverContextP ctx,
1553                  VASurfaceID render_target)
1554 {
1555     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1556     struct object_surface *obj_surface = SURFACE(render_target);
1557
1558     assert(obj_surface);
1559
1560     return VA_STATUS_SUCCESS;
1561 }
1562
1563 VAStatus 
1564 i965_QuerySurfaceStatus(VADriverContextP ctx,
1565                         VASurfaceID render_target,
1566                         VASurfaceStatus *status)        /* out */
1567 {
1568     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1569     struct object_surface *obj_surface = SURFACE(render_target);
1570
1571     assert(obj_surface);
1572
1573     /* Usually GEM will handle synchronization with the graphics hardware */
1574 #if 0
1575     if (obj_surface->bo) {
1576         dri_bo_map(obj_surface->bo, 0);
1577         dri_bo_unmap(obj_surface->bo);
1578     }
1579 #endif
1580     
1581     *status = obj_surface->status;
1582
1583     return VA_STATUS_SUCCESS;
1584 }
1585
1586
1587 /* 
1588  * Query display attributes 
1589  * The caller must provide a "attr_list" array that can hold at
1590  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1591  * returned in "attr_list" is returned in "num_attributes".
1592  */
1593 VAStatus 
1594 i965_QueryDisplayAttributes(VADriverContextP ctx,
1595                             VADisplayAttribute *attr_list,    /* out */
1596                             int *num_attributes)              /* out */
1597 {
1598     if (num_attributes)
1599         *num_attributes = 0;
1600
1601     return VA_STATUS_SUCCESS;
1602 }
1603
1604 /* 
1605  * Get display attributes 
1606  * This function returns the current attribute values in "attr_list".
1607  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1608  * from vaQueryDisplayAttributes() can have their values retrieved.  
1609  */
1610 VAStatus 
1611 i965_GetDisplayAttributes(VADriverContextP ctx,
1612                           VADisplayAttribute *attr_list,    /* in/out */
1613                           int num_attributes)
1614 {
1615     /* TODO */
1616     return VA_STATUS_ERROR_UNIMPLEMENTED;
1617 }
1618
1619 /* 
1620  * Set display attributes 
1621  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1622  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1623  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1624  */
1625 VAStatus 
1626 i965_SetDisplayAttributes(VADriverContextP ctx,
1627                           VADisplayAttribute *attr_list,
1628                           int num_attributes)
1629 {
1630     /* TODO */
1631     return VA_STATUS_ERROR_UNIMPLEMENTED;
1632 }
1633
1634 VAStatus 
1635 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
1636                             VASurfaceID surface,
1637                             void **buffer,              /* out */
1638                             unsigned int *stride)       /* out */
1639 {
1640     /* TODO */
1641     return VA_STATUS_ERROR_UNIMPLEMENTED;
1642 }
1643
1644 static VAStatus 
1645 i965_Init(VADriverContextP ctx)
1646 {
1647     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1648
1649     if (intel_driver_init(ctx) == False)
1650         return VA_STATUS_ERROR_UNKNOWN;
1651
1652     if (IS_G4X(i965->intel.device_id))
1653         i965->codec_info = &g4x_hw_codec_info;
1654     else if (IS_IRONLAKE(i965->intel.device_id))
1655         i965->codec_info = &ironlake_hw_codec_info;
1656     else if (IS_GEN6(i965->intel.device_id))
1657         i965->codec_info = &gen6_hw_codec_info;
1658     else if (IS_GEN7(i965->intel.device_id))
1659         i965->codec_info = &gen7_hw_codec_info;
1660     else
1661         return VA_STATUS_ERROR_UNKNOWN;
1662
1663     if (i965_post_processing_init(ctx) == False)
1664         return VA_STATUS_ERROR_UNKNOWN;
1665
1666     if (i965_render_init(ctx) == False)
1667         return VA_STATUS_ERROR_UNKNOWN;
1668
1669     _i965InitMutex(&i965->render_mutex);
1670     i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER);
1671
1672     return VA_STATUS_SUCCESS;
1673 }
1674
1675 static void
1676 i965_destroy_heap(struct object_heap *heap, 
1677                   void (*func)(struct object_heap *heap, struct object_base *object))
1678 {
1679     struct object_base *object;
1680     object_heap_iterator iter;    
1681
1682     object = object_heap_first(heap, &iter);
1683
1684     while (object) {
1685         if (func)
1686             func(heap, object);
1687
1688         object = object_heap_next(heap, &iter);
1689     }
1690
1691     object_heap_destroy(heap);
1692 }
1693
1694
1695 VAStatus 
1696 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
1697
1698 VAStatus 
1699 i965_CreateImage(VADriverContextP ctx,
1700                  VAImageFormat *format,
1701                  int width,
1702                  int height,
1703                  VAImage *out_image)        /* out */
1704 {
1705     struct i965_driver_data *i965 = i965_driver_data(ctx);
1706     struct object_image *obj_image;
1707     VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
1708     VAImageID image_id;
1709     unsigned int width2, height2, size2, size;
1710
1711     out_image->image_id = VA_INVALID_ID;
1712     out_image->buf      = VA_INVALID_ID;
1713
1714     image_id = NEW_IMAGE_ID();
1715     if (image_id == VA_INVALID_ID)
1716         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1717
1718     obj_image = IMAGE(image_id);
1719     if (!obj_image)
1720         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1721     obj_image->bo         = NULL;
1722     obj_image->palette    = NULL;
1723     obj_image->derived_surface = VA_INVALID_ID;
1724
1725     VAImage * const image = &obj_image->image;
1726     image->image_id       = image_id;
1727     image->buf            = VA_INVALID_ID;
1728
1729     size    = width * height;
1730     width2  = (width  + 1) / 2;
1731     height2 = (height + 1) / 2;
1732     size2   = width2 * height2;
1733
1734     image->num_palette_entries = 0;
1735     image->entry_bytes         = 0;
1736     memset(image->component_order, 0, sizeof(image->component_order));
1737
1738     switch (format->fourcc) {
1739     case VA_FOURCC('I','A','4','4'):
1740     case VA_FOURCC('A','I','4','4'):
1741         image->num_planes = 1;
1742         image->pitches[0] = width;
1743         image->offsets[0] = 0;
1744         image->data_size  = image->offsets[0] + image->pitches[0] * height;
1745         image->num_palette_entries = 16;
1746         image->entry_bytes         = 3;
1747         image->component_order[0]  = 'R';
1748         image->component_order[1]  = 'G';
1749         image->component_order[2]  = 'B';
1750         break;
1751     case VA_FOURCC('A','R','G','B'):
1752     case VA_FOURCC('A','B','G','R'):
1753     case VA_FOURCC('B','G','R','A'):
1754     case VA_FOURCC('R','G','B','A'):
1755         image->num_planes = 1;
1756         image->pitches[0] = width * 4;
1757         image->offsets[0] = 0;
1758         image->data_size  = image->offsets[0] + image->pitches[0] * height;
1759         break;
1760     case VA_FOURCC('Y','V','1','2'):
1761         image->num_planes = 3;
1762         image->pitches[0] = width;
1763         image->offsets[0] = 0;
1764         image->pitches[1] = width2;
1765         image->offsets[1] = size + size2;
1766         image->pitches[2] = width2;
1767         image->offsets[2] = size;
1768         image->data_size  = size + 2 * size2;
1769         break;
1770     case VA_FOURCC('I','4','2','0'):
1771         image->num_planes = 3;
1772         image->pitches[0] = width;
1773         image->offsets[0] = 0;
1774         image->pitches[1] = width2;
1775         image->offsets[1] = size;
1776         image->pitches[2] = width2;
1777         image->offsets[2] = size + size2;
1778         image->data_size  = size + 2 * size2;
1779         break;
1780     case VA_FOURCC('N','V','1','2'):
1781         image->num_planes = 2;
1782         image->pitches[0] = width;
1783         image->offsets[0] = 0;
1784         image->pitches[1] = width;
1785         image->offsets[1] = size;
1786         image->data_size  = size + 2 * size2;
1787         break;
1788     default:
1789         goto error;
1790     }
1791
1792     va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
1793                                   image->data_size, 1, NULL, &image->buf);
1794     if (va_status != VA_STATUS_SUCCESS)
1795         goto error;
1796
1797     obj_image->bo = BUFFER(image->buf)->buffer_store->bo;
1798     dri_bo_reference(obj_image->bo);
1799
1800     if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
1801         obj_image->palette = malloc(image->num_palette_entries * sizeof(obj_image->palette));
1802         if (!obj_image->palette)
1803             goto error;
1804     }
1805
1806     image->image_id             = image_id;
1807     image->format               = *format;
1808     image->width                = width;
1809     image->height               = height;
1810
1811     *out_image                  = *image;
1812     return VA_STATUS_SUCCESS;
1813
1814  error:
1815     i965_DestroyImage(ctx, image_id);
1816     return va_status;
1817 }
1818
1819 void 
1820 i965_check_alloc_surface_bo(VADriverContextP ctx,
1821                             struct object_surface *obj_surface,
1822                             int tiled,
1823                             unsigned int fourcc)
1824 {
1825     struct i965_driver_data *i965 = i965_driver_data(ctx);
1826
1827     if (obj_surface->bo)
1828         return;
1829
1830     if (tiled) {
1831         uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
1832         unsigned long pitch;
1833
1834         obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr, 
1835                                                    "vaapi surface",
1836                                                    obj_surface->width, 
1837                                                    obj_surface->height + obj_surface->height / 2,
1838                                                    1,
1839                                                    &tiling_mode,
1840                                                    &pitch,
1841                                                    0);
1842         assert(tiling_mode == I915_TILING_Y);
1843         assert(pitch == obj_surface->width);
1844     } else {
1845         obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
1846                                        "vaapi surface",
1847                                        obj_surface->size,
1848                                        0x1000);
1849     }
1850
1851     obj_surface->fourcc = fourcc;
1852     assert(obj_surface->bo);
1853 }
1854
1855 VAStatus i965_DeriveImage(VADriverContextP ctx,
1856                           VASurfaceID surface,
1857                           VAImage *out_image)        /* out */
1858 {
1859     struct i965_driver_data *i965 = i965_driver_data(ctx);
1860     struct i965_render_state *render_state = &i965->render_state;
1861     struct object_image *obj_image;
1862     struct object_surface *obj_surface; 
1863     VAImageID image_id;
1864     unsigned int w_pitch, h_pitch;
1865     unsigned int data_size;
1866     VAStatus va_status;
1867
1868     out_image->image_id = VA_INVALID_ID;
1869     obj_surface = SURFACE(surface);
1870
1871     if (!obj_surface)
1872         return VA_STATUS_ERROR_INVALID_SURFACE;
1873
1874     w_pitch = obj_surface->width;
1875     h_pitch = obj_surface->height;
1876     data_size = obj_surface->orig_width * obj_surface->orig_height +
1877         2 * (((obj_surface->orig_width + 1) / 2) * ((obj_surface->orig_height + 1) / 2));
1878
1879     image_id = NEW_IMAGE_ID();
1880
1881     if (image_id == VA_INVALID_ID)
1882         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1883
1884     obj_image = IMAGE(image_id);
1885     
1886     if (!obj_image)
1887         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1888
1889     obj_image->bo = NULL;
1890     obj_image->palette = NULL;
1891     obj_image->derived_surface = VA_INVALID_ID;
1892
1893     VAImage * const image = &obj_image->image;
1894     
1895     memset(image, 0, sizeof(*image));
1896     image->image_id = image_id;
1897     image->buf = VA_INVALID_ID;
1898     image->num_palette_entries = 0;
1899     image->entry_bytes = 0;
1900     image->width = obj_surface->orig_width;
1901     image->height = obj_surface->orig_height;
1902     image->data_size = data_size;
1903
1904     if (!render_state->inited) {
1905             image->format.fourcc = VA_FOURCC('Y','V','1','2');
1906             image->format.byte_order = VA_LSB_FIRST;
1907             image->format.bits_per_pixel = 12;
1908             image->num_planes = 3;
1909             image->pitches[0] = w_pitch;
1910             image->offsets[0] = 0;
1911             image->pitches[1] = w_pitch / 2;
1912             image->offsets[1] = w_pitch * h_pitch;
1913             image->pitches[2] = w_pitch / 2;
1914             image->offsets[2] = w_pitch * h_pitch + (w_pitch / 2) * (h_pitch / 2);
1915     } else {
1916         if (render_state->interleaved_uv) {
1917             image->format.fourcc = VA_FOURCC('N','V','1','2');
1918             image->format.byte_order = VA_LSB_FIRST;
1919             image->format.bits_per_pixel = 12;
1920             image->num_planes = 2;
1921             image->pitches[0] = w_pitch;
1922             image->offsets[0] = 0;
1923             image->pitches[1] = w_pitch;
1924             image->offsets[1] = w_pitch * h_pitch;
1925         } else {
1926             image->format.fourcc = VA_FOURCC('I','4','2','0');
1927             image->format.byte_order = VA_LSB_FIRST;
1928             image->format.bits_per_pixel = 12;
1929             image->num_planes = 3;
1930             image->pitches[0] = w_pitch;
1931             image->offsets[0] = 0;
1932             image->pitches[1] = w_pitch / 2;
1933             image->offsets[1] = w_pitch * h_pitch;
1934             image->pitches[2] = w_pitch / 2;
1935             image->offsets[2] = w_pitch * h_pitch + (w_pitch / 2) * (h_pitch / 2);
1936         }
1937     }
1938
1939     i965_check_alloc_surface_bo(ctx, obj_surface, HAS_TILED_SURFACE(i965), image->format.fourcc);
1940     va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
1941                                             obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
1942     if (va_status != VA_STATUS_SUCCESS)
1943         goto error;
1944
1945     obj_image->bo = BUFFER(image->buf)->buffer_store->bo;
1946     dri_bo_reference(obj_image->bo);
1947
1948     if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
1949         obj_image->palette = malloc(image->num_palette_entries * sizeof(obj_image->palette));
1950         if (!obj_image->palette) {
1951             va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1952             goto error;
1953         }
1954     }
1955
1956     *out_image = *image;
1957     obj_surface->flags |= SURFACE_DERIVED;
1958     obj_image->derived_surface = surface;
1959
1960     return VA_STATUS_SUCCESS;
1961
1962  error:
1963     i965_DestroyImage(ctx, image_id);
1964     return va_status;
1965 }
1966
1967 static void 
1968 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
1969 {
1970     object_heap_free(heap, obj);
1971 }
1972
1973
1974 VAStatus 
1975 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
1976 {
1977     struct i965_driver_data *i965 = i965_driver_data(ctx);
1978     struct object_image *obj_image = IMAGE(image); 
1979     struct object_surface *obj_surface; 
1980
1981     if (!obj_image)
1982         return VA_STATUS_SUCCESS;
1983
1984     dri_bo_unreference(obj_image->bo);
1985     obj_image->bo = NULL;
1986
1987     if (obj_image->image.buf != VA_INVALID_ID) {
1988         i965_DestroyBuffer(ctx, obj_image->image.buf);
1989         obj_image->image.buf = VA_INVALID_ID;
1990     }
1991
1992     if (obj_image->palette) {
1993         free(obj_image->palette);
1994         obj_image->palette = NULL;
1995     }
1996
1997     obj_surface = SURFACE(obj_image->derived_surface);
1998
1999     if (obj_surface) {
2000         obj_surface->flags &= ~SURFACE_DERIVED;
2001     }
2002
2003     i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
2004
2005     return VA_STATUS_SUCCESS;
2006 }
2007
2008 /*
2009  * pointer to an array holding the palette data.  The size of the array is
2010  * num_palette_entries * entry_bytes in size.  The order of the components
2011  * in the palette is described by the component_order in VASubpicture struct
2012  */
2013 VAStatus 
2014 i965_SetImagePalette(VADriverContextP ctx,
2015                      VAImageID image,
2016                      unsigned char *palette)
2017 {
2018     struct i965_driver_data *i965 = i965_driver_data(ctx);
2019     unsigned int i;
2020
2021     struct object_image *obj_image = IMAGE(image);
2022     if (!obj_image)
2023         return VA_STATUS_ERROR_INVALID_IMAGE;
2024
2025     if (!obj_image->palette)
2026         return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
2027
2028     for (i = 0; i < obj_image->image.num_palette_entries; i++)
2029         obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
2030                                  ((unsigned int)palette[3*i + 1] <<  8) |
2031                                  (unsigned int)palette[3*i + 2]);
2032     return VA_STATUS_SUCCESS;
2033 }
2034
2035 static inline void
2036 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
2037            const uint8_t *src, unsigned int src_stride,
2038            unsigned int len, unsigned int height)
2039 {
2040     unsigned int i;
2041
2042     for (i = 0; i < height; i++) {
2043         memcpy(dst, src, len);
2044         dst += dst_stride;
2045         src += src_stride;
2046     }
2047 }
2048
2049 static void
2050 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
2051                struct object_surface *obj_surface,
2052                const VARectangle *rect)
2053 {
2054     uint8_t *dst[3], *src[3];
2055     const int Y = 0;
2056     const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
2057     const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
2058     unsigned int tiling, swizzle;
2059
2060     if (!obj_surface->bo)
2061         return;
2062
2063     assert(obj_surface->fourcc);
2064     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
2065
2066     if (tiling != I915_TILING_NONE)
2067         drm_intel_gem_bo_map_gtt(obj_surface->bo);
2068     else
2069         dri_bo_map(obj_surface->bo, 0);
2070
2071     if (!obj_surface->bo->virtual)
2072         return;
2073
2074     /* Dest VA image has either I420 or YV12 format.
2075        Source VA surface alway has I420 format */
2076     dst[Y] = image_data + obj_image->image.offsets[Y];
2077     src[0] = (uint8_t *)obj_surface->bo->virtual;
2078     dst[U] = image_data + obj_image->image.offsets[U];
2079     src[1] = src[0] + obj_surface->width * obj_surface->height;
2080     dst[V] = image_data + obj_image->image.offsets[V];
2081     src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
2082
2083     /* Y plane */
2084     dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
2085     src[0] += rect->y * obj_surface->width + rect->x;
2086     memcpy_pic(dst[Y], obj_image->image.pitches[Y],
2087                src[0], obj_surface->width,
2088                rect->width, rect->height);
2089
2090     /* U plane */
2091     dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
2092     src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
2093     memcpy_pic(dst[U], obj_image->image.pitches[U],
2094                src[1], obj_surface->width / 2,
2095                rect->width / 2, rect->height / 2);
2096
2097     /* V plane */
2098     dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
2099     src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
2100     memcpy_pic(dst[V], obj_image->image.pitches[V],
2101                src[2], obj_surface->width / 2,
2102                rect->width / 2, rect->height / 2);
2103
2104     if (tiling != I915_TILING_NONE)
2105         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
2106     else
2107         dri_bo_unmap(obj_surface->bo);
2108 }
2109
2110 static void
2111 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
2112                struct object_surface *obj_surface,
2113                const VARectangle *rect)
2114 {
2115     uint8_t *dst[2], *src[2];
2116     unsigned int tiling, swizzle;
2117
2118     if (!obj_surface->bo)
2119         return;
2120
2121     assert(obj_surface->fourcc);
2122     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
2123
2124     if (tiling != I915_TILING_NONE)
2125         drm_intel_gem_bo_map_gtt(obj_surface->bo);
2126     else
2127         dri_bo_map(obj_surface->bo, 0);
2128
2129     if (!obj_surface->bo->virtual)
2130         return;
2131
2132     /* Both dest VA image and source surface have NV12 format */
2133     dst[0] = image_data + obj_image->image.offsets[0];
2134     src[0] = (uint8_t *)obj_surface->bo->virtual;
2135     dst[1] = image_data + obj_image->image.offsets[1];
2136     src[1] = src[0] + obj_surface->width * obj_surface->height;
2137
2138     /* Y plane */
2139     dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
2140     src[0] += rect->y * obj_surface->width + rect->x;
2141     memcpy_pic(dst[0], obj_image->image.pitches[0],
2142                src[0], obj_surface->width,
2143                rect->width, rect->height);
2144
2145     /* UV plane */
2146     dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
2147     src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
2148     memcpy_pic(dst[1], obj_image->image.pitches[1],
2149                src[1], obj_surface->width,
2150                rect->width, rect->height / 2);
2151
2152     if (tiling != I915_TILING_NONE)
2153         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
2154     else
2155         dri_bo_unmap(obj_surface->bo);
2156 }
2157
2158 VAStatus 
2159 i965_GetImage(VADriverContextP ctx,
2160               VASurfaceID surface,
2161               int x,   /* coordinates of the upper left source pixel */
2162               int y,
2163               unsigned int width,      /* width and height of the region */
2164               unsigned int height,
2165               VAImageID image)
2166 {
2167     struct i965_driver_data *i965 = i965_driver_data(ctx);
2168     struct i965_render_state *render_state = &i965->render_state;
2169
2170     struct object_surface *obj_surface = SURFACE(surface);
2171     if (!obj_surface)
2172         return VA_STATUS_ERROR_INVALID_SURFACE;
2173
2174     struct object_image *obj_image = IMAGE(image);
2175     if (!obj_image)
2176         return VA_STATUS_ERROR_INVALID_IMAGE;
2177
2178     if (x < 0 || y < 0)
2179         return VA_STATUS_ERROR_INVALID_PARAMETER;
2180     if (x + width > obj_surface->orig_width ||
2181         y + height > obj_surface->orig_height)
2182         return VA_STATUS_ERROR_INVALID_PARAMETER;
2183     if (x + width > obj_image->image.width ||
2184         y + height > obj_image->image.height)
2185         return VA_STATUS_ERROR_INVALID_PARAMETER;
2186
2187     VAStatus va_status;
2188     void *image_data = NULL;
2189
2190     va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
2191     if (va_status != VA_STATUS_SUCCESS)
2192         return va_status;
2193
2194     VARectangle rect;
2195     rect.x = x;
2196     rect.y = y;
2197     rect.width = width;
2198     rect.height = height;
2199
2200     switch (obj_image->image.format.fourcc) {
2201     case VA_FOURCC('Y','V','1','2'):
2202     case VA_FOURCC('I','4','2','0'):
2203         /* I420 is native format for MPEG-2 decoded surfaces */
2204         if (render_state->interleaved_uv)
2205             goto operation_failed;
2206         get_image_i420(obj_image, image_data, obj_surface, &rect);
2207         break;
2208     case VA_FOURCC('N','V','1','2'):
2209         /* NV12 is native format for H.264 decoded surfaces */
2210         if (!render_state->interleaved_uv)
2211             goto operation_failed;
2212         get_image_nv12(obj_image, image_data, obj_surface, &rect);
2213         break;
2214     default:
2215     operation_failed:
2216         va_status = VA_STATUS_ERROR_OPERATION_FAILED;
2217         break;
2218     }
2219
2220     i965_UnmapBuffer(ctx, obj_image->image.buf);
2221     return va_status;
2222 }
2223
2224 VAStatus 
2225 i965_PutSurface(VADriverContextP ctx,
2226                 VASurfaceID surface,
2227                 void *draw, /* X Drawable */
2228                 short srcx,
2229                 short srcy,
2230                 unsigned short srcw,
2231                 unsigned short srch,
2232                 short destx,
2233                 short desty,
2234                 unsigned short destw,
2235                 unsigned short desth,
2236                 VARectangle *cliprects, /* client supplied clip list */
2237                 unsigned int number_cliprects, /* number of clip rects in the clip list */
2238                 unsigned int flags) /* de-interlacing flags */
2239 {
2240     struct i965_driver_data *i965 = i965_driver_data(ctx); 
2241     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
2242     struct i965_render_state *render_state = &i965->render_state;
2243     struct dri_drawable *dri_drawable;
2244     union dri_buffer *buffer;
2245     struct intel_region *dest_region;
2246     struct object_surface *obj_surface; 
2247     VARectangle src_rect, dst_rect;
2248     int ret;
2249     uint32_t name;
2250     Bool new_region = False;
2251     int pp_flag = 0;
2252
2253     /* Currently don't support DRI1 */
2254     if (dri_state->driConnectedFlag != VA_DRI2)
2255         return VA_STATUS_ERROR_UNKNOWN;
2256
2257     /* Some broken sources such as H.264 conformance case FM2_SVA_C
2258      * will get here
2259      */
2260     obj_surface = SURFACE(surface);
2261     if (!obj_surface || !obj_surface->bo)
2262         return VA_STATUS_SUCCESS;
2263
2264     _i965LockMutex(&i965->render_mutex);
2265
2266     dri_drawable = dri_get_drawable(ctx, (Drawable)draw);
2267     assert(dri_drawable);
2268
2269     buffer = dri_get_rendering_buffer(ctx, dri_drawable);
2270     assert(buffer);
2271     
2272     dest_region = render_state->draw_region;
2273
2274     if (dest_region) {
2275         assert(dest_region->bo);
2276         dri_bo_flink(dest_region->bo, &name);
2277         
2278         if (buffer->dri2.name != name) {
2279             new_region = True;
2280             dri_bo_unreference(dest_region->bo);
2281         }
2282     } else {
2283         dest_region = (struct intel_region *)calloc(1, sizeof(*dest_region));
2284         assert(dest_region);
2285         render_state->draw_region = dest_region;
2286         new_region = True;
2287     }
2288
2289     if (new_region) {
2290         dest_region->x = dri_drawable->x;
2291         dest_region->y = dri_drawable->y;
2292         dest_region->width = dri_drawable->width;
2293         dest_region->height = dri_drawable->height;
2294         dest_region->cpp = buffer->dri2.cpp;
2295         dest_region->pitch = buffer->dri2.pitch;
2296
2297         dest_region->bo = intel_bo_gem_create_from_name(i965->intel.bufmgr, "rendering buffer", buffer->dri2.name);
2298         assert(dest_region->bo);
2299
2300         ret = dri_bo_get_tiling(dest_region->bo, &(dest_region->tiling), &(dest_region->swizzle));
2301         assert(ret == 0);
2302     }
2303
2304     if ((flags & VA_FILTER_SCALING_MASK) == VA_FILTER_SCALING_NL_ANAMORPHIC)
2305         pp_flag |= I965_PP_FLAG_AVS;
2306
2307     if (flags & (VA_BOTTOM_FIELD | VA_TOP_FIELD))
2308         pp_flag |= I965_PP_FLAG_DEINTERLACING;
2309
2310     src_rect.x      = srcx;
2311     src_rect.y      = srcy;
2312     src_rect.width  = srcw;
2313     src_rect.height = srch;
2314
2315     dst_rect.x      = destx;
2316     dst_rect.y      = desty;
2317     dst_rect.width  = destw;
2318     dst_rect.height = desth;
2319
2320     intel_render_put_surface(ctx, surface, &src_rect, &dst_rect, pp_flag);
2321
2322     if(obj_surface->subpic != VA_INVALID_ID) {
2323         intel_render_put_subpicture(ctx, surface, &src_rect, &dst_rect);
2324     }
2325
2326     dri_swap_buffer(ctx, dri_drawable);
2327     obj_surface->flags |= SURFACE_DISPLAYED;
2328
2329     if ((obj_surface->flags & SURFACE_ALL_MASK) == SURFACE_DISPLAYED) {
2330         dri_bo_unreference(obj_surface->bo);
2331         obj_surface->bo = NULL;
2332         obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
2333
2334         if (obj_surface->free_private_data)
2335             obj_surface->free_private_data(&obj_surface->private_data);
2336     }
2337
2338     _i965UnlockMutex(&i965->render_mutex);
2339
2340     return VA_STATUS_SUCCESS;
2341 }
2342
2343 VAStatus 
2344 i965_Terminate(VADriverContextP ctx)
2345 {
2346     struct i965_driver_data *i965 = i965_driver_data(ctx);
2347
2348     if (i965->batch)
2349         intel_batchbuffer_free(i965->batch);
2350
2351     _i965DestroyMutex(&i965->render_mutex);
2352
2353     if (i965_render_terminate(ctx) == False)
2354         return VA_STATUS_ERROR_UNKNOWN;
2355
2356     if (i965_post_processing_terminate(ctx) == False)
2357         return VA_STATUS_ERROR_UNKNOWN;
2358
2359     if (intel_driver_terminate(ctx) == False)
2360         return VA_STATUS_ERROR_UNKNOWN;
2361
2362     i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
2363     i965_destroy_heap(&i965->image_heap, i965_destroy_image);
2364     i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
2365     i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
2366     i965_destroy_heap(&i965->context_heap, i965_destroy_context);
2367     i965_destroy_heap(&i965->config_heap, i965_destroy_config);
2368
2369     free(ctx->pDriverData);
2370     ctx->pDriverData = NULL;
2371
2372     return VA_STATUS_SUCCESS;
2373 }
2374
2375 static VAStatus
2376 i965_BufferInfo(
2377     VADriverContextP ctx,       /* in */
2378     VABufferID buf_id,          /* in */
2379     VABufferType *type,         /* out */
2380     unsigned int *size,         /* out */
2381     unsigned int *num_elements  /* out */
2382 )
2383 {
2384     struct i965_driver_data *i965 = NULL;
2385     struct object_buffer *obj_buffer = NULL;
2386
2387     i965 = i965_driver_data(ctx);
2388     obj_buffer = BUFFER(buf_id);
2389
2390     *type = obj_buffer->type;
2391     *size = obj_buffer->size_element;
2392     *num_elements = obj_buffer->num_elements;
2393
2394     return VA_STATUS_SUCCESS;
2395 }
2396
2397 static VAStatus
2398 i965_LockSurface(
2399     VADriverContextP ctx,           /* in */
2400     VASurfaceID surface,            /* in */
2401     unsigned int *fourcc,           /* out */
2402     unsigned int *luma_stride,      /* out */
2403     unsigned int *chroma_u_stride,  /* out */
2404     unsigned int *chroma_v_stride,  /* out */
2405     unsigned int *luma_offset,      /* out */
2406     unsigned int *chroma_u_offset,  /* out */
2407     unsigned int *chroma_v_offset,  /* out */
2408     unsigned int *buffer_name,      /* out */
2409     void **buffer                   /* out */
2410 )
2411 {
2412     VAStatus vaStatus = VA_STATUS_SUCCESS;
2413     struct i965_driver_data *i965 = i965_driver_data(ctx);
2414     struct object_surface *obj_surface = NULL;
2415     VAImage tmpImage;
2416
2417     assert(fourcc);
2418     assert(luma_stride);
2419     assert(chroma_u_stride);
2420     assert(chroma_v_stride);
2421     assert(luma_offset);
2422     assert(chroma_u_offset);
2423     assert(chroma_v_offset);
2424     assert(buffer_name);
2425     assert(buffer);
2426
2427     tmpImage.image_id = VA_INVALID_ID;
2428
2429     obj_surface = SURFACE(surface);
2430     if (obj_surface == NULL) {
2431         // Surface is absent.
2432         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2433         goto error;
2434     }
2435
2436     // Lock functionality is absent now.
2437     if (obj_surface->locked_image_id != VA_INVALID_ID) {
2438         // Surface is locked already.
2439         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2440         goto error;
2441     }
2442
2443     vaStatus = i965_DeriveImage(
2444         ctx,
2445         surface,
2446         &tmpImage);
2447     if (vaStatus != VA_STATUS_SUCCESS) {
2448         goto error;
2449     }
2450
2451     obj_surface->locked_image_id = tmpImage.image_id;
2452
2453     vaStatus = i965_MapBuffer(
2454         ctx,
2455         tmpImage.buf,
2456         buffer);
2457     if (vaStatus != VA_STATUS_SUCCESS) {
2458         goto error;
2459     }
2460
2461     *fourcc = tmpImage.format.fourcc;
2462     *luma_offset = tmpImage.offsets[0];
2463     *luma_stride = tmpImage.pitches[0];
2464     *chroma_u_offset = tmpImage.offsets[1];
2465     *chroma_u_stride = tmpImage.pitches[1];
2466     *chroma_v_offset = tmpImage.offsets[2];
2467     *chroma_v_stride = tmpImage.pitches[2];
2468     *buffer_name = tmpImage.buf;
2469
2470 error:
2471     if (vaStatus != VA_STATUS_SUCCESS) {
2472         buffer = NULL;
2473     }
2474
2475     return vaStatus;
2476 }
2477
2478 static VAStatus
2479 i965_UnlockSurface(
2480     VADriverContextP ctx,   /* in */
2481     VASurfaceID surface     /* in */
2482 )
2483 {
2484     VAStatus vaStatus = VA_STATUS_SUCCESS;
2485     struct i965_driver_data *i965 = i965_driver_data(ctx);
2486     struct object_image *locked_img = NULL;
2487     struct object_surface *obj_surface = NULL;
2488
2489     obj_surface = SURFACE(surface);
2490
2491     if (obj_surface == NULL) {
2492         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is absent
2493         goto error;
2494     }
2495     if (obj_surface->locked_image_id == VA_INVALID_ID) {
2496         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is not locked
2497         goto error;
2498     }
2499
2500     locked_img = IMAGE(obj_surface->locked_image_id);
2501     if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
2502         // Work image was deallocated before i965_UnlockSurface()
2503         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2504         goto error;
2505     }
2506
2507     vaStatus = i965_UnmapBuffer(
2508         ctx,
2509         locked_img->image.buf);
2510     if (vaStatus != VA_STATUS_SUCCESS) {
2511         goto error;
2512     }
2513
2514     vaStatus = i965_DestroyImage(
2515         ctx,
2516         locked_img->image.image_id);
2517     if (vaStatus != VA_STATUS_SUCCESS) {
2518         goto error;
2519     }
2520
2521     locked_img->image.image_id = VA_INVALID_ID;
2522
2523  error:
2524     return vaStatus;
2525 }
2526
2527 VAStatus 
2528 VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
2529 {
2530     struct VADriverVTable * const vtable = ctx->vtable;
2531     struct i965_driver_data *i965;
2532     int result;
2533
2534     ctx->version_major = VA_MAJOR_VERSION;
2535     ctx->version_minor = VA_MINOR_VERSION;
2536     ctx->max_profiles = I965_MAX_PROFILES;
2537     ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
2538     ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
2539     ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
2540     ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
2541     ctx->max_display_attributes = I965_MAX_DISPLAY_ATTRIBUTES;
2542     ctx->str_vendor = I965_STR_VENDOR;
2543
2544     vtable->vaTerminate = i965_Terminate;
2545     vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
2546     vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
2547     vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
2548     vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
2549     vtable->vaCreateConfig = i965_CreateConfig;
2550     vtable->vaDestroyConfig = i965_DestroyConfig;
2551     vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
2552     vtable->vaCreateSurfaces = i965_CreateSurfaces;
2553     vtable->vaDestroySurfaces = i965_DestroySurfaces;
2554     vtable->vaCreateContext = i965_CreateContext;
2555     vtable->vaDestroyContext = i965_DestroyContext;
2556     vtable->vaCreateBuffer = i965_CreateBuffer;
2557     vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
2558     vtable->vaMapBuffer = i965_MapBuffer;
2559     vtable->vaUnmapBuffer = i965_UnmapBuffer;
2560     vtable->vaDestroyBuffer = i965_DestroyBuffer;
2561     vtable->vaBeginPicture = i965_BeginPicture;
2562     vtable->vaRenderPicture = i965_RenderPicture;
2563     vtable->vaEndPicture = i965_EndPicture;
2564     vtable->vaSyncSurface = i965_SyncSurface;
2565     vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
2566     vtable->vaPutSurface = i965_PutSurface;
2567     vtable->vaQueryImageFormats = i965_QueryImageFormats;
2568     vtable->vaCreateImage = i965_CreateImage;
2569     vtable->vaDeriveImage = i965_DeriveImage;
2570     vtable->vaDestroyImage = i965_DestroyImage;
2571     vtable->vaSetImagePalette = i965_SetImagePalette;
2572     vtable->vaGetImage = i965_GetImage;
2573     vtable->vaPutImage = i965_PutImage;
2574     vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
2575     vtable->vaCreateSubpicture = i965_CreateSubpicture;
2576     vtable->vaDestroySubpicture = i965_DestroySubpicture;
2577     vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
2578     vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
2579     vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
2580     vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
2581     vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
2582     vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
2583     vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
2584     vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
2585     vtable->vaBufferInfo = i965_BufferInfo;
2586     vtable->vaLockSurface = i965_LockSurface;
2587     vtable->vaUnlockSurface = i965_UnlockSurface;
2588     //    vtable->vaDbgCopySurfaceToBuffer = i965_DbgCopySurfaceToBuffer;
2589
2590     i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
2591     assert(i965);
2592     ctx->pDriverData = (void *)i965;
2593
2594     result = object_heap_init(&i965->config_heap, 
2595                               sizeof(struct object_config), 
2596                               CONFIG_ID_OFFSET);
2597     assert(result == 0);
2598
2599     result = object_heap_init(&i965->context_heap, 
2600                               sizeof(struct object_context), 
2601                               CONTEXT_ID_OFFSET);
2602     assert(result == 0);
2603
2604     result = object_heap_init(&i965->surface_heap, 
2605                               sizeof(struct object_surface), 
2606                               SURFACE_ID_OFFSET);
2607     assert(result == 0);
2608
2609     result = object_heap_init(&i965->buffer_heap, 
2610                               sizeof(struct object_buffer), 
2611                               BUFFER_ID_OFFSET);
2612     assert(result == 0);
2613
2614     result = object_heap_init(&i965->image_heap, 
2615                               sizeof(struct object_image), 
2616                               IMAGE_ID_OFFSET);
2617     assert(result == 0);
2618
2619     result = object_heap_init(&i965->subpic_heap, 
2620                               sizeof(struct object_subpic), 
2621                               SUBPIC_ID_OFFSET);
2622     assert(result == 0);
2623     
2624     return i965_Init(ctx);
2625 }