MPEG-2 encoding on Haswell
[profile/ivi/vaapi-intel-driver.git] / src / 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 #ifdef ANDROID
30 #include "config_android.h"
31 #else
32 #include "config.h"
33 #endif
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdbool.h>
37 #include <string.h>
38 #include <assert.h>
39
40 #ifdef HAVE_VA_X11
41 # include "i965_output_dri.h"
42 #endif
43
44 #ifdef HAVE_VA_WAYLAND
45 # include "i965_output_wayland.h"
46 #endif
47
48 #include "intel_driver.h"
49 #include "intel_memman.h"
50 #include "intel_batchbuffer.h"
51 #include "i965_defines.h"
52 #include "i965_drv_video.h"
53 #include "i965_decoder.h"
54 #include "i965_encoder.h"
55
56 #define CONFIG_ID_OFFSET                0x01000000
57 #define CONTEXT_ID_OFFSET               0x02000000
58 #define SURFACE_ID_OFFSET               0x04000000
59 #define BUFFER_ID_OFFSET                0x08000000
60 #define IMAGE_ID_OFFSET                 0x0a000000
61 #define SUBPIC_ID_OFFSET                0x10000000
62
63 #define HAS_MPEG2_DECODING(ctx)  ((ctx)->codec_info->has_mpeg2_decoding && \
64                                   (ctx)->intel.has_bsd)
65
66 #define HAS_MPEG2_ENCODING(ctx)  ((ctx)->codec_info->has_mpeg2_encoding && \
67                                   (ctx)->intel.has_bsd)
68
69 #define HAS_H264_DECODING(ctx)  ((ctx)->codec_info->has_h264_decoding && \
70                                  (ctx)->intel.has_bsd)
71
72 #define HAS_H264_ENCODING(ctx)  ((ctx)->codec_info->has_h264_encoding && \
73                                  (ctx)->intel.has_bsd)
74
75 #define HAS_VC1_DECODING(ctx)   ((ctx)->codec_info->has_vc1_decoding && \
76                                  (ctx)->intel.has_bsd)
77
78 #define HAS_JPEG_DECODING(ctx)  ((ctx)->codec_info->has_jpeg_decoding && \
79                                  (ctx)->intel.has_bsd)
80
81 #define HAS_VPP(ctx)    ((ctx)->codec_info->has_vpp)
82
83 #define HAS_ACCELERATED_GETIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_getimage)
84
85 #define HAS_ACCELERATED_PUTIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_putimage)
86
87 #define HAS_TILED_SURFACE(ctx) ((ctx)->codec_info->has_tiled_surface)
88
89 static int get_sampling_from_fourcc(unsigned int fourcc);
90
91 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
92 #define IS_VA_X11(ctx) \
93     (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
94
95 /* Check whether we are rendering to Wayland */
96 #define IS_VA_WAYLAND(ctx) \
97     (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
98
99 enum {
100     I965_SURFACETYPE_RGBA = 1,
101     I965_SURFACETYPE_YUV,
102     I965_SURFACETYPE_INDEXED
103 };
104
105 /* List of supported display attributes */
106 static const VADisplayAttribute i965_display_attributes[] = {
107     {
108         VADisplayAttribRotation,
109         0, 3, VA_ROTATION_NONE,
110         VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
111     },
112 };
113
114 /* List of supported image formats */
115 typedef struct {
116     unsigned int        type;
117     VAImageFormat       va_format;
118 } i965_image_format_map_t;
119
120 static const i965_image_format_map_t
121 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
122     { I965_SURFACETYPE_YUV,
123       { VA_FOURCC('Y','V','1','2'), VA_LSB_FIRST, 12, } },
124     { I965_SURFACETYPE_YUV,
125       { VA_FOURCC('I','4','2','0'), VA_LSB_FIRST, 12, } },
126     { I965_SURFACETYPE_YUV,
127       { VA_FOURCC('N','V','1','2'), VA_LSB_FIRST, 12, } },
128     { I965_SURFACETYPE_YUV,
129       { VA_FOURCC('Y','U','Y','2'), VA_LSB_FIRST, 16, } },
130     { I965_SURFACETYPE_YUV,
131       { VA_FOURCC('U','Y','V','Y'), VA_LSB_FIRST, 16, } },
132     { I965_SURFACETYPE_RGBA,
133       { VA_FOURCC('R','G','B','X'), VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
134     { I965_SURFACETYPE_RGBA,
135       { VA_FOURCC('B','G','R','X'), VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
136 };
137
138 /* List of supported subpicture formats */
139 typedef struct {
140     unsigned int        type;
141     unsigned int        format;
142     VAImageFormat       va_format;
143     unsigned int        va_flags;
144 } i965_subpic_format_map_t;
145
146 static const i965_subpic_format_map_t
147 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
148     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
149       { VA_FOURCC('I','A','4','4'), VA_MSB_FIRST, 8, },
150       VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD },
151     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
152       { VA_FOURCC('A','I','4','4'), VA_MSB_FIRST, 8, },
153       VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD },
154     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
155       { VA_FOURCC('I','A','8','8'), VA_MSB_FIRST, 16, },
156       VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD },
157     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
158       { VA_FOURCC('A','I','8','8'), VA_MSB_FIRST, 16, },
159       VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD },
160      { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
161       { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32,
162         32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
163       VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD },
164     { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
165       { VA_FOURCC('R','G','B','A'), VA_LSB_FIRST, 32,
166         32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
167       VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD },
168 };
169
170 static const i965_subpic_format_map_t *
171 get_subpic_format(const VAImageFormat *va_format)
172 {
173     unsigned int i;
174     for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
175         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
176         if (m->va_format.fourcc == va_format->fourcc &&
177             (m->type == I965_SURFACETYPE_RGBA ?
178              (m->va_format.byte_order == va_format->byte_order &&
179               m->va_format.red_mask   == va_format->red_mask   &&
180               m->va_format.green_mask == va_format->green_mask &&
181               m->va_format.blue_mask  == va_format->blue_mask  &&
182               m->va_format.alpha_mask == va_format->alpha_mask) : 1))
183             return m;
184     }
185     return NULL;
186 }
187
188 extern struct hw_context *i965_proc_context_init(VADriverContextP, struct object_config *);
189 extern struct hw_context *g4x_dec_hw_context_init(VADriverContextP, struct object_config *);
190 static struct hw_codec_info g4x_hw_codec_info = {
191     .dec_hw_context_init = g4x_dec_hw_context_init,
192     .enc_hw_context_init = NULL,
193     .proc_hw_context_init = NULL,
194     .max_width = 2048,
195     .max_height = 2048,
196
197     .has_mpeg2_decoding = 1,
198 };
199
200 extern struct hw_context *ironlake_dec_hw_context_init(VADriverContextP, struct object_config *);
201 static struct hw_codec_info ironlake_hw_codec_info = {
202     .dec_hw_context_init = ironlake_dec_hw_context_init,
203     .enc_hw_context_init = NULL,
204     .proc_hw_context_init = i965_proc_context_init,
205     .max_width = 2048,
206     .max_height = 2048,
207
208     .has_mpeg2_decoding = 1,
209     .has_h264_decoding = 1,
210     .has_vpp = 1,
211     .has_accelerated_putimage = 1,
212 };
213
214 extern struct hw_context *gen6_dec_hw_context_init(VADriverContextP, struct object_config *);
215 extern struct hw_context *gen6_enc_hw_context_init(VADriverContextP, struct object_config *);
216 static struct hw_codec_info gen6_hw_codec_info = {
217     .dec_hw_context_init = gen6_dec_hw_context_init,
218     .enc_hw_context_init = gen6_enc_hw_context_init,
219     .proc_hw_context_init = i965_proc_context_init,
220     .max_width = 2048,
221     .max_height = 2048,
222
223     .has_mpeg2_decoding = 1,
224     .has_h264_decoding = 1,
225     .has_h264_encoding = 1,
226     .has_vc1_decoding = 1,
227     .has_vpp = 1,
228     .has_accelerated_getimage = 1,
229     .has_accelerated_putimage = 1,
230     .has_tiled_surface = 1,
231 };
232
233 extern struct hw_context *gen7_dec_hw_context_init(VADriverContextP, struct object_config *);
234 extern struct hw_context *gen7_enc_hw_context_init(VADriverContextP, struct object_config *);
235 static struct hw_codec_info gen7_hw_codec_info = {
236     .dec_hw_context_init = gen7_dec_hw_context_init,
237     .enc_hw_context_init = gen7_enc_hw_context_init,
238     .proc_hw_context_init = i965_proc_context_init,
239     .max_width = 4096,
240     .max_height = 4096,
241
242     .has_mpeg2_decoding = 1,
243     .has_h264_decoding = 1,
244     .has_h264_encoding = 1,
245     .has_vc1_decoding = 1,
246     .has_jpeg_decoding = 1,
247     .has_vpp = 1,
248     .has_accelerated_getimage = 1,
249     .has_accelerated_putimage = 1,
250     .has_tiled_surface = 1,
251 };
252
253 extern struct hw_context *gen75_proc_context_init(VADriverContextP, struct object_config *);
254 static struct hw_codec_info gen75_hw_codec_info = {
255     .dec_hw_context_init = gen75_dec_hw_context_init,
256     .enc_hw_context_init = gen75_enc_hw_context_init,
257     .proc_hw_context_init = gen75_proc_context_init,
258     .max_width = 4096,
259     .max_height = 4096,
260
261     .has_mpeg2_decoding = 1,
262     .has_mpeg2_encoding = 1,
263     .has_h264_decoding = 1,
264     .has_h264_encoding = 1,
265     .has_vc1_decoding = 1,
266     .has_jpeg_decoding = 1,
267     .has_vpp = 1,
268     .has_accelerated_getimage = 1,
269     .has_accelerated_putimage = 1,
270     .has_tiled_surface = 1,
271 };
272
273 #define I965_PACKED_HEADER_BASE         0
274 #define I965_PACKED_MISC_HEADER_BASE    3
275
276 int
277 va_enc_packed_type_to_idx(int packed_type)
278 {
279     int idx = 0;
280
281     if (packed_type & VAEncPackedHeaderMiscMask) {
282         idx = I965_PACKED_MISC_HEADER_BASE;
283         packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
284         assert(packed_type > 0);
285         idx += (packed_type - 1);
286     } else {
287         idx = I965_PACKED_HEADER_BASE;
288
289         switch (packed_type) {
290         case VAEncPackedHeaderSequence:
291             idx = I965_PACKED_HEADER_BASE + 0;
292             break;
293
294         case VAEncPackedHeaderPicture:
295             idx = I965_PACKED_HEADER_BASE + 1;
296             break;
297
298         case VAEncPackedHeaderSlice:
299             idx = I965_PACKED_HEADER_BASE + 2;
300             break;
301
302         default:
303             /* Should not get here */
304             assert(0);
305             break;
306         }
307     }
308
309     assert(idx < 4);
310     return idx;
311 }
312
313
314 VAStatus 
315 i965_QueryConfigProfiles(VADriverContextP ctx,
316                          VAProfile *profile_list,       /* out */
317                          int *num_profiles)             /* out */
318 {
319     struct i965_driver_data * const i965 = i965_driver_data(ctx);
320     int i = 0;
321
322     if (HAS_MPEG2_DECODING(i965) ||
323         HAS_MPEG2_ENCODING(i965)) {
324         profile_list[i++] = VAProfileMPEG2Simple;
325         profile_list[i++] = VAProfileMPEG2Main;
326     }
327
328     if (HAS_H264_DECODING(i965) ||
329         HAS_H264_ENCODING(i965)) {
330         profile_list[i++] = VAProfileH264Baseline;
331         profile_list[i++] = VAProfileH264Main;
332         profile_list[i++] = VAProfileH264High;
333     }
334
335     if (HAS_VC1_DECODING(i965)) {
336         profile_list[i++] = VAProfileVC1Simple;
337         profile_list[i++] = VAProfileVC1Main;
338         profile_list[i++] = VAProfileVC1Advanced;
339     }
340
341     if (HAS_VPP(i965)) {
342         profile_list[i++] = VAProfileNone;
343     }
344
345     if (HAS_JPEG_DECODING(i965)) {
346         profile_list[i++] = VAProfileJPEGBaseline;
347     }
348
349     /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
350     assert(i <= I965_MAX_PROFILES);
351     *num_profiles = i;
352
353     return VA_STATUS_SUCCESS;
354 }
355
356 VAStatus 
357 i965_QueryConfigEntrypoints(VADriverContextP ctx,
358                             VAProfile profile,
359                             VAEntrypoint *entrypoint_list,      /* out */
360                             int *num_entrypoints)               /* out */
361 {
362     struct i965_driver_data * const i965 = i965_driver_data(ctx);
363     int n = 0;
364
365     switch (profile) {
366     case VAProfileMPEG2Simple:
367     case VAProfileMPEG2Main:
368         if (HAS_MPEG2_DECODING(i965))
369             entrypoint_list[n++] = VAEntrypointVLD;
370
371         if (HAS_MPEG2_ENCODING(i965))
372             entrypoint_list[n++] = VAEntrypointEncSlice;
373
374         break;
375
376     case VAProfileH264Baseline:
377     case VAProfileH264Main:
378     case VAProfileH264High:
379         if (HAS_H264_DECODING(i965))
380             entrypoint_list[n++] = VAEntrypointVLD;
381         
382         if (HAS_H264_ENCODING(i965))
383             entrypoint_list[n++] = VAEntrypointEncSlice;
384
385         break;
386
387     case VAProfileVC1Simple:
388     case VAProfileVC1Main:
389     case VAProfileVC1Advanced:
390         if (HAS_VC1_DECODING(i965))
391             entrypoint_list[n++] = VAEntrypointVLD;
392         break;
393
394     case VAProfileNone:
395         if (HAS_VPP(i965))
396             entrypoint_list[n++] = VAEntrypointVideoProc;
397         break;
398
399     case VAProfileJPEGBaseline:
400         if (HAS_JPEG_DECODING(i965))
401             entrypoint_list[n++] = VAEntrypointVLD;
402         break;
403
404     default:
405         break;
406     }
407
408     /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
409     assert(n <= I965_MAX_ENTRYPOINTS);
410     *num_entrypoints = n;
411     return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
412 }
413
414 VAStatus 
415 i965_GetConfigAttributes(VADriverContextP ctx,
416                          VAProfile profile,
417                          VAEntrypoint entrypoint,
418                          VAConfigAttrib *attrib_list,  /* in/out */
419                          int num_attribs)
420 {
421     int i;
422
423     /* Other attributes don't seem to be defined */
424     /* What to do if we don't know the attribute? */
425     for (i = 0; i < num_attribs; i++) {
426         switch (attrib_list[i].type) {
427         case VAConfigAttribRTFormat:
428             attrib_list[i].value = VA_RT_FORMAT_YUV420;
429             break;
430
431         case VAConfigAttribRateControl:
432             if (entrypoint == VAEntrypointEncSlice) {
433                 attrib_list[i].value = VA_RC_CBR | VA_RC_CQP;
434                 break;
435             }
436
437         case VAConfigAttribEncPackedHeaders:
438             if (entrypoint == VAEntrypointEncSlice) {
439                 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
440                 break;
441             }
442
443         default:
444             /* Do nothing */
445             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
446             break;
447         }
448     }
449
450     return VA_STATUS_SUCCESS;
451 }
452
453 static void 
454 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
455 {
456     object_heap_free(heap, obj);
457 }
458
459 static VAStatus 
460 i965_update_attribute(struct object_config *obj_config, VAConfigAttrib *attrib)
461 {
462     int i;
463
464     /* Check existing attrbiutes */
465     for (i = 0; i < obj_config->num_attribs; i++) {
466         if (obj_config->attrib_list[i].type == attrib->type) {
467             /* Update existing attribute */
468             obj_config->attrib_list[i].value = attrib->value;
469             return VA_STATUS_SUCCESS;
470         }
471     }
472
473     if (obj_config->num_attribs < I965_MAX_CONFIG_ATTRIBUTES) {
474         i = obj_config->num_attribs;
475         obj_config->attrib_list[i].type = attrib->type;
476         obj_config->attrib_list[i].value = attrib->value;
477         obj_config->num_attribs++;
478         return VA_STATUS_SUCCESS;
479     }
480
481     return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
482 }
483
484 VAStatus 
485 i965_CreateConfig(VADriverContextP ctx,
486                   VAProfile profile,
487                   VAEntrypoint entrypoint,
488                   VAConfigAttrib *attrib_list,
489                   int num_attribs,
490                   VAConfigID *config_id)        /* out */
491 {
492     struct i965_driver_data * const i965 = i965_driver_data(ctx);
493     struct object_config *obj_config;
494     int configID;
495     int i;
496     VAStatus vaStatus;
497
498     /* Validate profile & entrypoint */
499     switch (profile) {
500     case VAProfileMPEG2Simple:
501     case VAProfileMPEG2Main:
502         if ((HAS_MPEG2_DECODING(i965) && VAEntrypointVLD == entrypoint) ||
503             (HAS_MPEG2_ENCODING(i965) && VAEntrypointEncSlice == entrypoint)) {
504             vaStatus = VA_STATUS_SUCCESS;
505         } else {
506             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
507         }
508         break;
509
510     case VAProfileH264Baseline:
511     case VAProfileH264Main:
512     case VAProfileH264High:
513         if ((HAS_H264_DECODING(i965) && VAEntrypointVLD == entrypoint) ||
514             (HAS_H264_ENCODING(i965) && VAEntrypointEncSlice == entrypoint)) {
515             vaStatus = VA_STATUS_SUCCESS;
516         } else {
517             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
518         }
519
520         break;
521
522     case VAProfileVC1Simple:
523     case VAProfileVC1Main:
524     case VAProfileVC1Advanced:
525         if (HAS_VC1_DECODING(i965) && VAEntrypointVLD == entrypoint) {
526             vaStatus = VA_STATUS_SUCCESS;
527         } else {
528             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
529         }
530
531         break;
532
533     case VAProfileNone:
534         if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
535             vaStatus = VA_STATUS_SUCCESS;
536         } else {
537             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
538         }
539
540         break;
541
542     case VAProfileJPEGBaseline:
543         if (HAS_JPEG_DECODING(i965) && VAEntrypointVLD == entrypoint) {
544             vaStatus = VA_STATUS_SUCCESS;
545         } else {
546             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
547         }
548
549         break;
550
551     default:
552         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
553         break;
554     }
555
556     if (VA_STATUS_SUCCESS != vaStatus) {
557         return vaStatus;
558     }
559
560     configID = NEW_CONFIG_ID();
561     obj_config = CONFIG(configID);
562
563     if (NULL == obj_config) {
564         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
565         return vaStatus;
566     }
567
568     obj_config->profile = profile;
569     obj_config->entrypoint = entrypoint;
570     obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
571     obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
572     obj_config->num_attribs = 1;
573
574     for(i = 0; i < num_attribs; i++) {
575         vaStatus = i965_update_attribute(obj_config, &(attrib_list[i]));
576
577         if (VA_STATUS_SUCCESS != vaStatus) {
578             break;
579         }
580     }
581
582     /* Error recovery */
583     if (VA_STATUS_SUCCESS != vaStatus) {
584         i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
585     } else {
586         *config_id = configID;
587     }
588
589     return vaStatus;
590 }
591
592 VAStatus 
593 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
594 {
595     struct i965_driver_data *i965 = i965_driver_data(ctx);
596     struct object_config *obj_config = CONFIG(config_id);
597     VAStatus vaStatus;
598
599     if (NULL == obj_config) {
600         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
601         return vaStatus;
602     }
603
604     i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
605     return VA_STATUS_SUCCESS;
606 }
607
608 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
609                                     VAConfigID config_id,
610                                     VAProfile *profile,                 /* out */
611                                     VAEntrypoint *entrypoint,           /* out */
612                                     VAConfigAttrib *attrib_list,        /* out */
613                                     int *num_attribs)                   /* out */
614 {
615     struct i965_driver_data *i965 = i965_driver_data(ctx);
616     struct object_config *obj_config = CONFIG(config_id);
617     VAStatus vaStatus = VA_STATUS_SUCCESS;
618     int i;
619
620     assert(obj_config);
621     *profile = obj_config->profile;
622     *entrypoint = obj_config->entrypoint;
623     *num_attribs = obj_config->num_attribs;
624
625     for(i = 0; i < obj_config->num_attribs; i++) {
626         attrib_list[i] = obj_config->attrib_list[i];
627     }
628
629     return vaStatus;
630 }
631
632 static void 
633 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
634 {
635     struct object_surface *obj_surface = (struct object_surface *)obj;
636
637     dri_bo_unreference(obj_surface->bo);
638     obj_surface->bo = NULL;
639
640     if (obj_surface->free_private_data != NULL) {
641         obj_surface->free_private_data(&obj_surface->private_data);
642         obj_surface->private_data = NULL;
643     }
644
645     object_heap_free(heap, obj);
646 }
647
648 static VAStatus
649 i965_CreateSurfaces2(
650     VADriverContextP    ctx,
651     unsigned int        format,
652     unsigned int        width,
653     unsigned int        height,
654     VASurfaceID        *surfaces,
655     unsigned int        num_surfaces,
656     VASurfaceAttrib    *attrib_list,
657     unsigned int        num_attribs
658     )
659 {
660     struct i965_driver_data *i965 = i965_driver_data(ctx);
661     int i,j;
662     VAStatus vaStatus = VA_STATUS_SUCCESS;
663     int expected_fourcc = 0;
664
665     for (i = 0; i < num_attribs && attrib_list; i++) {
666         if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
667             (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
668             assert(attrib_list[i].value.type == VAGenericValueTypeInteger);
669             expected_fourcc = attrib_list[i].value.value.i;
670             break;
671         }
672     }
673
674     /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
675      * for post-processing (including color conversion) */
676     if (VA_RT_FORMAT_YUV420 != format &&
677         VA_RT_FORMAT_YUV422 != format &&
678         VA_RT_FORMAT_RGB32  != format) {
679         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
680     }
681
682     for (i = 0; i < num_surfaces; i++) {
683         int surfaceID = NEW_SURFACE_ID();
684         struct object_surface *obj_surface = SURFACE(surfaceID);
685
686         if (NULL == obj_surface) {
687             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
688             break;
689         }
690
691         surfaces[i] = surfaceID;
692         obj_surface->status = VASurfaceReady;
693         obj_surface->orig_width = width;
694         obj_surface->orig_height = height;
695
696         obj_surface->subpic_render_idx = 0;
697         for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
698            obj_surface->subpic[j] = VA_INVALID_ID;
699         }
700
701         obj_surface->width = ALIGN(width, 16);
702         obj_surface->height = ALIGN(height, 16);
703         obj_surface->flags = SURFACE_REFERENCED;
704         obj_surface->fourcc = 0;
705         obj_surface->bo = NULL;
706         obj_surface->locked_image_id = VA_INVALID_ID;
707         obj_surface->private_data = NULL;
708         obj_surface->free_private_data = NULL;
709         obj_surface->subsampling = SUBSAMPLE_YUV420;
710
711         if (expected_fourcc) {
712             int tiling = HAS_TILED_SURFACE(i965);
713
714             if (expected_fourcc != VA_FOURCC('N', 'V', '1', '2') &&
715                 expected_fourcc != VA_FOURCC('R', 'G', 'B', 'X') &&
716                 expected_fourcc != VA_FOURCC('R', 'G', 'B', 'A') )
717                 tiling = 0;
718             // todo, should we disable tiling for 422 format?
719                         
720             if (VA_RT_FORMAT_YUV420 == format) {
721                 obj_surface->subsampling = SUBSAMPLE_YUV420;
722             }
723             else if (VA_RT_FORMAT_YUV422 == format) {
724                 obj_surface->subsampling = SUBSAMPLE_YUV422H;
725             }
726             else if (VA_RT_FORMAT_RGB32 == format) {
727                 obj_surface->subsampling = SUBSAMPLE_RGBX;
728             }
729              else {
730                 assert(0);
731             }
732
733             i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, obj_surface->subsampling);
734         }
735     }
736
737     /* Error recovery */
738     if (VA_STATUS_SUCCESS != vaStatus) {
739         /* surfaces[i-1] was the last successful allocation */
740         for (; i--; ) {
741             struct object_surface *obj_surface = SURFACE(surfaces[i]);
742
743             surfaces[i] = VA_INVALID_SURFACE;
744             assert(obj_surface);
745             i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
746         }
747     }
748
749     return vaStatus;
750 }
751
752 VAStatus 
753 i965_CreateSurfaces(VADriverContextP ctx,
754                     int width,
755                     int height,
756                     int format,
757                     int num_surfaces,
758                     VASurfaceID *surfaces)      /* out */
759 {
760     return i965_CreateSurfaces2(ctx,
761                                 format,
762                                 width,
763                                 height,
764                                 surfaces,
765                                 num_surfaces,
766                                 NULL,
767                                 0);
768 }
769
770 VAStatus 
771 i965_DestroySurfaces(VADriverContextP ctx,
772                      VASurfaceID *surface_list,
773                      int num_surfaces)
774 {
775     struct i965_driver_data *i965 = i965_driver_data(ctx);
776     int i;
777
778     for (i = num_surfaces; i--; ) {
779         struct object_surface *obj_surface = SURFACE(surface_list[i]);
780
781         assert(obj_surface);
782         i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
783     }
784
785     return VA_STATUS_SUCCESS;
786 }
787
788 VAStatus 
789 i965_QueryImageFormats(VADriverContextP ctx,
790                        VAImageFormat *format_list,      /* out */
791                        int *num_formats)                /* out */
792 {
793     int n;
794
795     for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
796         const i965_image_format_map_t * const m = &i965_image_formats_map[n];
797         if (format_list)
798             format_list[n] = m->va_format;
799     }
800
801     if (num_formats)
802         *num_formats = n;
803
804     return VA_STATUS_SUCCESS;
805 }
806
807 /*
808  * Guess the format when the usage of a VA surface is unknown
809  * 1. Without a valid context: YV12
810  * 2. The current context is valid:
811  *    a) always NV12 on GEN6 and later
812  *    b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
813  */
814 static void
815 i965_guess_surface_format(VADriverContextP ctx,
816                           VASurfaceID surface,
817                           unsigned int *fourcc,
818                           unsigned int *is_tiled)
819 {
820     struct i965_driver_data *i965 = i965_driver_data(ctx);
821     struct object_context *obj_context = NULL;
822     struct object_config *obj_config = NULL;
823
824     *fourcc = VA_FOURCC('Y', 'V', '1', '2');
825     *is_tiled = 0;
826
827     if (i965->current_context_id == VA_INVALID_ID)
828         return;
829
830     obj_context = CONTEXT(i965->current_context_id);
831
832     if (!obj_context || obj_context->config_id == VA_INVALID_ID)
833         return;
834
835     obj_config = CONFIG(obj_context->config_id);
836
837     if (!obj_config)
838         return;
839
840     if (IS_GEN6(i965->intel.device_id) || IS_GEN7(i965->intel.device_id)) {
841         *fourcc = VA_FOURCC('N', 'V', '1', '2');
842         *is_tiled = 1;
843         return;
844     }
845
846     switch (obj_config->profile) {
847     case VAProfileMPEG2Simple:
848     case VAProfileMPEG2Main:
849         *fourcc = VA_FOURCC('I', '4', '2', '0');
850         *is_tiled = 0;
851         break;
852
853     default:
854         *fourcc = VA_FOURCC('N', 'V', '1', '2');
855         *is_tiled = 0;
856         break;
857     }
858 }
859
860 VAStatus 
861 i965_QuerySubpictureFormats(VADriverContextP ctx,
862                             VAImageFormat *format_list,         /* out */
863                             unsigned int *flags,                /* out */
864                             unsigned int *num_formats)          /* out */
865 {
866     int n;
867
868     for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
869         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
870         if (format_list)
871             format_list[n] = m->va_format;
872         if (flags)
873             flags[n] = m->va_flags;
874     }
875
876     if (num_formats)
877         *num_formats = n;
878
879     return VA_STATUS_SUCCESS;
880 }
881
882 static void 
883 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
884 {
885     //    struct object_subpic *obj_subpic = (struct object_subpic *)obj;
886
887     object_heap_free(heap, obj);
888 }
889
890 VAStatus 
891 i965_CreateSubpicture(VADriverContextP ctx,
892                       VAImageID image,
893                       VASubpictureID *subpicture)         /* out */
894 {
895     struct i965_driver_data *i965 = i965_driver_data(ctx);
896     VASubpictureID subpicID = NEW_SUBPIC_ID()
897     struct object_subpic *obj_subpic = SUBPIC(subpicID);
898
899     if (!obj_subpic)
900         return VA_STATUS_ERROR_ALLOCATION_FAILED;
901
902     struct object_image *obj_image = IMAGE(image);
903     if (!obj_image)
904         return VA_STATUS_ERROR_INVALID_IMAGE;
905
906     const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
907     if (!m)
908         return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
909
910     *subpicture = subpicID;
911     obj_subpic->image  = image;
912     obj_subpic->format = m->format;
913     obj_subpic->width  = obj_image->image.width;
914     obj_subpic->height = obj_image->image.height;
915     obj_subpic->pitch  = obj_image->image.pitches[0];
916     obj_subpic->bo     = obj_image->bo;
917     obj_subpic->global_alpha = 1.0;
918  
919     return VA_STATUS_SUCCESS;
920 }
921
922 VAStatus 
923 i965_DestroySubpicture(VADriverContextP ctx,
924                        VASubpictureID subpicture)
925 {
926     struct i965_driver_data *i965 = i965_driver_data(ctx);
927     struct object_subpic *obj_subpic = SUBPIC(subpicture);
928     i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
929     return VA_STATUS_SUCCESS;
930 }
931
932 VAStatus 
933 i965_SetSubpictureImage(VADriverContextP ctx,
934                         VASubpictureID subpicture,
935                         VAImageID image)
936 {
937     /* TODO */
938     return VA_STATUS_ERROR_UNIMPLEMENTED;
939 }
940
941 VAStatus 
942 i965_SetSubpictureChromakey(VADriverContextP ctx,
943                             VASubpictureID subpicture,
944                             unsigned int chromakey_min,
945                             unsigned int chromakey_max,
946                             unsigned int chromakey_mask)
947 {
948     /* TODO */
949     return VA_STATUS_ERROR_UNIMPLEMENTED;
950 }
951
952 VAStatus 
953 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
954                               VASubpictureID subpicture,
955                               float global_alpha)
956 {
957     struct i965_driver_data *i965 = i965_driver_data(ctx);
958     struct object_subpic *obj_subpic = SUBPIC(subpicture);
959
960     if(global_alpha > 1.0 || global_alpha < 0.0){
961        return VA_STATUS_ERROR_INVALID_PARAMETER;
962     }
963     obj_subpic->global_alpha  = global_alpha;
964
965     return VA_STATUS_SUCCESS;
966 }
967
968 VAStatus 
969 i965_AssociateSubpicture(VADriverContextP ctx,
970                          VASubpictureID subpicture,
971                          VASurfaceID *target_surfaces,
972                          int num_surfaces,
973                          short src_x, /* upper left offset in subpicture */
974                          short src_y,
975                          unsigned short src_width,
976                          unsigned short src_height,
977                          short dest_x, /* upper left offset in surface */
978                          short dest_y,
979                          unsigned short dest_width,
980                          unsigned short dest_height,
981                          /*
982                           * whether to enable chroma-keying or global-alpha
983                           * see VA_SUBPICTURE_XXX values
984                           */
985                          unsigned int flags)
986 {
987     struct i965_driver_data *i965 = i965_driver_data(ctx);
988     struct object_subpic *obj_subpic = SUBPIC(subpicture);
989     int i, j;
990
991     obj_subpic->src_rect.x      = src_x;
992     obj_subpic->src_rect.y      = src_y;
993     obj_subpic->src_rect.width  = src_width;
994     obj_subpic->src_rect.height = src_height;
995     obj_subpic->dst_rect.x      = dest_x;
996     obj_subpic->dst_rect.y      = dest_y;
997     obj_subpic->dst_rect.width  = dest_width;
998     obj_subpic->dst_rect.height = dest_height;
999     obj_subpic->flags           = flags;
1000
1001     for (i = 0; i < num_surfaces; i++) {
1002         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1003         if (!obj_surface)
1004             return VA_STATUS_ERROR_INVALID_SURFACE;
1005
1006         for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1007             if(obj_surface->subpic[j] == VA_INVALID_ID){
1008                obj_surface->subpic[j] = subpicture;
1009                break;
1010             }
1011         }
1012         
1013         if(j == I965_MAX_SUBPIC_SUM){
1014             return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1015         }
1016
1017     }
1018     return VA_STATUS_SUCCESS;
1019 }
1020
1021
1022 VAStatus 
1023 i965_DeassociateSubpicture(VADriverContextP ctx,
1024                            VASubpictureID subpicture,
1025                            VASurfaceID *target_surfaces,
1026                            int num_surfaces)
1027 {
1028     struct i965_driver_data *i965 = i965_driver_data(ctx);
1029     int i, j;
1030
1031     for (i = 0; i < num_surfaces; i++) {
1032         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1033         if (!obj_surface)
1034             return VA_STATUS_ERROR_INVALID_SURFACE;
1035
1036         for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1037             if(obj_surface->subpic[j] == subpicture){
1038                obj_surface->subpic[j] = VA_INVALID_ID;
1039                break;
1040             }
1041         }
1042         
1043         if(j == I965_MAX_SUBPIC_SUM){
1044             return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1045         }
1046     }
1047     return VA_STATUS_SUCCESS;
1048 }
1049
1050 void
1051 i965_reference_buffer_store(struct buffer_store **ptr, 
1052                             struct buffer_store *buffer_store)
1053 {
1054     assert(*ptr == NULL);
1055
1056     if (buffer_store) {
1057         buffer_store->ref_count++;
1058         *ptr = buffer_store;
1059     }
1060 }
1061
1062 void 
1063 i965_release_buffer_store(struct buffer_store **ptr)
1064 {
1065     struct buffer_store *buffer_store = *ptr;
1066
1067     if (buffer_store == NULL)
1068         return;
1069
1070     assert(buffer_store->bo || buffer_store->buffer);
1071     assert(!(buffer_store->bo && buffer_store->buffer));
1072     buffer_store->ref_count--;
1073     
1074     if (buffer_store->ref_count == 0) {
1075         dri_bo_unreference(buffer_store->bo);
1076         free(buffer_store->buffer);
1077         buffer_store->bo = NULL;
1078         buffer_store->buffer = NULL;
1079         free(buffer_store);
1080     }
1081
1082     *ptr = NULL;
1083 }
1084
1085 static void 
1086 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
1087 {
1088     struct object_context *obj_context = (struct object_context *)obj;
1089     int i;
1090
1091     if (obj_context->hw_context) {
1092         obj_context->hw_context->destroy(obj_context->hw_context);
1093         obj_context->hw_context = NULL;
1094     }
1095
1096     if (obj_context->codec_type == CODEC_PROC) {
1097         i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
1098
1099     } else if (obj_context->codec_type == CODEC_ENC) {
1100         assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
1101         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1102         i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
1103
1104         for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
1105             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1106
1107         free(obj_context->codec_state.encode.slice_params);
1108
1109         assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
1110         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1111         i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
1112
1113         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1114             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
1115
1116         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
1117             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
1118
1119         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
1120             i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
1121
1122         for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
1123             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
1124
1125         free(obj_context->codec_state.encode.slice_params_ext);
1126     } else {
1127         assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
1128         assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
1129
1130         i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
1131         i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
1132         i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
1133
1134         for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
1135             i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
1136
1137         for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
1138             i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
1139
1140         free(obj_context->codec_state.decode.slice_params);
1141         free(obj_context->codec_state.decode.slice_datas);
1142     }
1143
1144     free(obj_context->render_targets);
1145     object_heap_free(heap, obj);
1146 }
1147
1148 VAStatus
1149 i965_CreateContext(VADriverContextP ctx,
1150                    VAConfigID config_id,
1151                    int picture_width,
1152                    int picture_height,
1153                    int flag,
1154                    VASurfaceID *render_targets,
1155                    int num_render_targets,
1156                    VAContextID *context)                /* out */
1157 {
1158     struct i965_driver_data *i965 = i965_driver_data(ctx);
1159     struct i965_render_state *render_state = &i965->render_state;
1160     struct object_config *obj_config = CONFIG(config_id);
1161     struct object_context *obj_context = NULL;
1162     VAStatus vaStatus = VA_STATUS_SUCCESS;
1163     int contextID;
1164     int i;
1165
1166     if (NULL == obj_config) {
1167         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1168         return vaStatus;
1169     }
1170
1171     if (picture_width > i965->codec_info->max_width ||
1172         picture_height > i965->codec_info->max_height) {
1173         vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1174         return vaStatus;
1175     }
1176
1177     /* Validate flag */
1178     /* Validate picture dimensions */
1179     contextID = NEW_CONTEXT_ID();
1180     obj_context = CONTEXT(contextID);
1181
1182     if (NULL == obj_context) {
1183         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1184         return vaStatus;
1185     }
1186
1187     render_state->inited = 1;
1188
1189     switch (obj_config->profile) {
1190     case VAProfileH264Baseline:
1191     case VAProfileH264Main:
1192     case VAProfileH264High:
1193         if (!HAS_H264_DECODING(i965) &&
1194             !HAS_H264_ENCODING(i965))
1195             return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1196         render_state->interleaved_uv = 1;
1197         break;
1198     default:
1199         render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_id) || IS_GEN7(i965->intel.device_id));
1200         break;
1201     }
1202
1203     *context = contextID;
1204     obj_context->flags = flag;
1205     obj_context->context_id = contextID;
1206     obj_context->config_id = config_id;
1207     obj_context->picture_width = picture_width;
1208     obj_context->picture_height = picture_height;
1209     obj_context->num_render_targets = num_render_targets;
1210     obj_context->render_targets = 
1211         (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
1212     obj_context->hw_context = NULL;
1213
1214     for(i = 0; i < num_render_targets; i++) {
1215         if (NULL == SURFACE(render_targets[i])) {
1216             vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1217             break;
1218         }
1219
1220         obj_context->render_targets[i] = render_targets[i];
1221     }
1222
1223     if (VA_STATUS_SUCCESS == vaStatus) {
1224         if (VAEntrypointVideoProc == obj_config->entrypoint) {
1225             obj_context->codec_type = CODEC_PROC;
1226             memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
1227             obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
1228             assert(i965->codec_info->proc_hw_context_init);
1229             obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
1230         } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
1231             obj_context->codec_type = CODEC_ENC;
1232             memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
1233             obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
1234             obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
1235             obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
1236                                                                sizeof(*obj_context->codec_state.encode.slice_params));
1237             assert(i965->codec_info->enc_hw_context_init);
1238             obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
1239         } else {
1240             obj_context->codec_type = CODEC_DEC;
1241             memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
1242             obj_context->codec_state.decode.current_render_target = -1;
1243             obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
1244             obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
1245             obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
1246                                                                sizeof(*obj_context->codec_state.decode.slice_params));
1247             obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
1248                                                               sizeof(*obj_context->codec_state.decode.slice_datas));
1249
1250             assert(i965->codec_info->dec_hw_context_init);
1251             obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
1252         }
1253     }
1254
1255     /* Error recovery */
1256     if (VA_STATUS_SUCCESS != vaStatus) {
1257         i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1258     }
1259
1260     i965->current_context_id = contextID;
1261
1262     return vaStatus;
1263 }
1264
1265 VAStatus 
1266 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
1267 {
1268     struct i965_driver_data *i965 = i965_driver_data(ctx);
1269     struct object_context *obj_context = CONTEXT(context);
1270
1271     assert(obj_context);
1272
1273     if (i965->current_context_id == context)
1274         i965->current_context_id = VA_INVALID_ID;
1275
1276     i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1277
1278     return VA_STATUS_SUCCESS;
1279 }
1280
1281 static void 
1282 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
1283 {
1284     struct object_buffer *obj_buffer = (struct object_buffer *)obj;
1285
1286     assert(obj_buffer->buffer_store);
1287     i965_release_buffer_store(&obj_buffer->buffer_store);
1288     object_heap_free(heap, obj);
1289 }
1290
1291 static VAStatus
1292 i965_create_buffer_internal(VADriverContextP ctx,
1293                             VAContextID context,
1294                             VABufferType type,
1295                             unsigned int size,
1296                             unsigned int num_elements,
1297                             void *data,
1298                             dri_bo *store_bo,
1299                             VABufferID *buf_id)
1300 {
1301     struct i965_driver_data *i965 = i965_driver_data(ctx);
1302     struct object_buffer *obj_buffer = NULL;
1303     struct buffer_store *buffer_store = NULL;
1304     int bufferID;
1305
1306     /* Validate type */
1307     switch (type) {
1308     case VAPictureParameterBufferType:
1309     case VAIQMatrixBufferType:
1310     case VAQMatrixBufferType:
1311     case VABitPlaneBufferType:
1312     case VASliceGroupMapBufferType:
1313     case VASliceParameterBufferType:
1314     case VASliceDataBufferType:
1315     case VAMacroblockParameterBufferType:
1316     case VAResidualDataBufferType:
1317     case VADeblockingParameterBufferType:
1318     case VAImageBufferType:
1319     case VAEncCodedBufferType:
1320     case VAEncSequenceParameterBufferType:
1321     case VAEncPictureParameterBufferType:
1322     case VAEncSliceParameterBufferType:
1323     case VAEncPackedHeaderParameterBufferType:
1324     case VAEncPackedHeaderDataBufferType:
1325     case VAEncMiscParameterBufferType:
1326     case VAProcPipelineParameterBufferType:
1327     case VAProcFilterParameterBufferType:
1328     case VAHuffmanTableBufferType:
1329         /* Ok */
1330         break;
1331
1332     default:
1333         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1334     }
1335
1336     bufferID = NEW_BUFFER_ID();
1337     obj_buffer = BUFFER(bufferID);
1338
1339     if (NULL == obj_buffer) {
1340         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1341     }
1342
1343     if (type == VAEncCodedBufferType) {
1344         size += I965_CODEDBUFFER_HEADER_SIZE;
1345         size += 0x1000; /* for upper bound check */
1346     }
1347
1348     obj_buffer->max_num_elements = num_elements;
1349     obj_buffer->num_elements = num_elements;
1350     obj_buffer->size_element = size;
1351     obj_buffer->type = type;
1352     obj_buffer->buffer_store = NULL;
1353     buffer_store = calloc(1, sizeof(struct buffer_store));
1354     assert(buffer_store);
1355     buffer_store->ref_count = 1;
1356
1357     if (store_bo != NULL) {
1358         buffer_store->bo = store_bo;
1359         dri_bo_reference(buffer_store->bo);
1360         
1361         if (data)
1362             dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1363     } else if (type == VASliceDataBufferType || 
1364                type == VAImageBufferType || 
1365                type == VAEncCodedBufferType) {
1366         buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, 
1367                                         "Buffer", 
1368                                         size * num_elements, 64);
1369         assert(buffer_store->bo);
1370
1371         if (type == VAEncCodedBufferType) {
1372             struct i965_coded_buffer_segment *coded_buffer_segment;
1373
1374             dri_bo_map(buffer_store->bo, 1);
1375             coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
1376             coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
1377             coded_buffer_segment->base.bit_offset = 0;
1378             coded_buffer_segment->base.status = 0;
1379             coded_buffer_segment->base.buf = NULL;
1380             coded_buffer_segment->base.next = NULL;
1381             coded_buffer_segment->mapped = 0;
1382             coded_buffer_segment->codec = 0;
1383             dri_bo_unmap(buffer_store->bo);
1384         } else if (data) {
1385             dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1386         }
1387
1388     } else {
1389         int msize = size;
1390         
1391         if (type == VAEncPackedHeaderDataBufferType) {
1392             msize = ALIGN(size, 4);
1393         }
1394
1395         buffer_store->buffer = malloc(msize * num_elements);
1396         assert(buffer_store->buffer);
1397
1398         if (data)
1399             memcpy(buffer_store->buffer, data, size * num_elements);
1400     }
1401
1402     buffer_store->num_elements = obj_buffer->num_elements;
1403     i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
1404     i965_release_buffer_store(&buffer_store);
1405     *buf_id = bufferID;
1406
1407     return VA_STATUS_SUCCESS;
1408 }
1409
1410 VAStatus 
1411 i965_CreateBuffer(VADriverContextP ctx,
1412                   VAContextID context,          /* in */
1413                   VABufferType type,            /* in */
1414                   unsigned int size,            /* in */
1415                   unsigned int num_elements,    /* in */
1416                   void *data,                   /* in */
1417                   VABufferID *buf_id)           /* out */
1418 {
1419     return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
1420 }
1421
1422
1423 VAStatus 
1424 i965_BufferSetNumElements(VADriverContextP ctx,
1425                           VABufferID buf_id,           /* in */
1426                           unsigned int num_elements)   /* in */
1427 {
1428     struct i965_driver_data *i965 = i965_driver_data(ctx);
1429     struct object_buffer *obj_buffer = BUFFER(buf_id);
1430     VAStatus vaStatus = VA_STATUS_SUCCESS;
1431
1432     assert(obj_buffer);
1433
1434     if ((num_elements < 0) || 
1435         (num_elements > obj_buffer->max_num_elements)) {
1436         vaStatus = VA_STATUS_ERROR_UNKNOWN;
1437     } else {
1438         obj_buffer->num_elements = num_elements;
1439         if (obj_buffer->buffer_store != NULL) {
1440             obj_buffer->buffer_store->num_elements = num_elements;
1441         }
1442     }
1443
1444     return vaStatus;
1445 }
1446
1447 VAStatus 
1448 i965_MapBuffer(VADriverContextP ctx,
1449                VABufferID buf_id,       /* in */
1450                void **pbuf)             /* out */
1451 {
1452     struct i965_driver_data *i965 = i965_driver_data(ctx);
1453     struct object_buffer *obj_buffer = BUFFER(buf_id);
1454     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1455
1456     assert(obj_buffer && obj_buffer->buffer_store);
1457     assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
1458     assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
1459
1460     if (NULL != obj_buffer->buffer_store->bo) {
1461         unsigned int tiling, swizzle;
1462
1463         dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1464
1465         if (tiling != I915_TILING_NONE)
1466             drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
1467         else
1468             dri_bo_map(obj_buffer->buffer_store->bo, 1);
1469
1470         assert(obj_buffer->buffer_store->bo->virtual);
1471         *pbuf = obj_buffer->buffer_store->bo->virtual;
1472
1473         if (obj_buffer->type == VAEncCodedBufferType) {
1474             int i;
1475             unsigned char *buffer = NULL;
1476             struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
1477
1478             if (!coded_buffer_segment->mapped) {
1479                 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
1480
1481                 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
1482
1483                 if (coded_buffer_segment->codec == CODED_H264) {
1484                     delimiter0 = H264_DELIMITER0;
1485                     delimiter1 = H264_DELIMITER1;
1486                     delimiter2 = H264_DELIMITER2;
1487                     delimiter3 = H264_DELIMITER3;
1488                     delimiter4 = H264_DELIMITER4;
1489                 } else if (coded_buffer_segment->codec == CODED_MPEG2) {
1490                     delimiter0 = MPEG2_DELIMITER0;
1491                     delimiter1 = MPEG2_DELIMITER1;
1492                     delimiter2 = MPEG2_DELIMITER2;
1493                     delimiter3 = MPEG2_DELIMITER3;
1494                     delimiter4 = MPEG2_DELIMITER4;
1495                 } else {
1496                     assert(0);
1497                 }
1498
1499                 for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
1500                     if ((buffer[i] == delimiter0) &&
1501                         (buffer[i + 1] == delimiter1) &&
1502                         (buffer[i + 2] == delimiter2) &&
1503                         (buffer[i + 3] == delimiter3) &&
1504                         (buffer[i + 4] == delimiter4))
1505                         break;
1506                 }
1507
1508                 if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
1509                     coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
1510                 }
1511
1512                 coded_buffer_segment->base.size = i;
1513                 coded_buffer_segment->mapped = 1;
1514             } else {
1515                 assert(coded_buffer_segment->base.buf);
1516             }
1517         }
1518
1519         vaStatus = VA_STATUS_SUCCESS;
1520     } else if (NULL != obj_buffer->buffer_store->buffer) {
1521         *pbuf = obj_buffer->buffer_store->buffer;
1522         vaStatus = VA_STATUS_SUCCESS;
1523     }
1524
1525     return vaStatus;
1526 }
1527
1528 VAStatus 
1529 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
1530 {
1531     struct i965_driver_data *i965 = i965_driver_data(ctx);
1532     struct object_buffer *obj_buffer = BUFFER(buf_id);
1533     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1534
1535     assert(obj_buffer && obj_buffer->buffer_store);
1536     assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
1537     assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
1538
1539     if (NULL != obj_buffer->buffer_store->bo) {
1540         unsigned int tiling, swizzle;
1541
1542         dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1543
1544         if (tiling != I915_TILING_NONE)
1545             drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
1546         else
1547             dri_bo_unmap(obj_buffer->buffer_store->bo);
1548
1549         vaStatus = VA_STATUS_SUCCESS;
1550     } else if (NULL != obj_buffer->buffer_store->buffer) {
1551         /* Do nothing */
1552         vaStatus = VA_STATUS_SUCCESS;
1553     }
1554
1555     return vaStatus;    
1556 }
1557
1558 VAStatus 
1559 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
1560 {
1561     struct i965_driver_data *i965 = i965_driver_data(ctx);
1562     struct object_buffer *obj_buffer = BUFFER(buffer_id);
1563
1564     assert(obj_buffer);
1565     i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
1566
1567     return VA_STATUS_SUCCESS;
1568 }
1569
1570 VAStatus 
1571 i965_BeginPicture(VADriverContextP ctx,
1572                   VAContextID context,
1573                   VASurfaceID render_target)
1574 {
1575     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1576     struct object_context *obj_context = CONTEXT(context);
1577     struct object_surface *obj_surface = SURFACE(render_target);
1578     struct object_config *obj_config;
1579     VAContextID config;
1580     VAStatus vaStatus;
1581     int i;
1582
1583     assert(obj_context);
1584     assert(obj_surface);
1585
1586     config = obj_context->config_id;
1587     obj_config = CONFIG(config);
1588     assert(obj_config);
1589
1590     switch (obj_config->profile) {
1591     case VAProfileMPEG2Simple:
1592     case VAProfileMPEG2Main:
1593         vaStatus = VA_STATUS_SUCCESS;
1594         break;
1595
1596     case VAProfileH264Baseline:
1597     case VAProfileH264Main:
1598     case VAProfileH264High:
1599         vaStatus = VA_STATUS_SUCCESS;
1600         break;
1601
1602     case VAProfileVC1Simple:
1603     case VAProfileVC1Main:
1604     case VAProfileVC1Advanced:
1605         vaStatus = VA_STATUS_SUCCESS;
1606         break;
1607
1608     case VAProfileJPEGBaseline:
1609         vaStatus = VA_STATUS_SUCCESS;
1610         break;
1611
1612     case VAProfileNone:
1613         vaStatus = VA_STATUS_SUCCESS;
1614         break;
1615
1616     default:
1617         assert(0);
1618         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1619         break;
1620     }
1621
1622     if (obj_context->codec_type == CODEC_PROC) {
1623         obj_context->codec_state.proc.current_render_target = render_target;
1624     } else if (obj_context->codec_type == CODEC_ENC) {
1625         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1626
1627         for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
1628             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1629         }
1630
1631         obj_context->codec_state.encode.num_slice_params = 0;
1632
1633         /* ext */
1634         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1635
1636         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1637             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
1638
1639         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
1640             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
1641
1642         for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
1643             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
1644
1645         obj_context->codec_state.encode.num_slice_params_ext = 0;
1646         obj_context->codec_state.encode.current_render_target = render_target;     /*This is input new frame*/
1647         obj_context->codec_state.encode.last_packed_header_type = 0;
1648     } else {
1649         obj_context->codec_state.decode.current_render_target = render_target;
1650         i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
1651         i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
1652         i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
1653         i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
1654
1655         for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
1656             i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
1657             i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
1658         }
1659
1660         obj_context->codec_state.decode.num_slice_params = 0;
1661         obj_context->codec_state.decode.num_slice_datas = 0;
1662     }
1663
1664     return vaStatus;
1665 }
1666
1667 #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
1668
1669 #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member)           \
1670     static VAStatus                                                     \
1671     i965_render_##category##_##name##_buffer(VADriverContextP ctx,      \
1672                                              struct object_context *obj_context, \
1673                                              struct object_buffer *obj_buffer) \
1674     {                                                                   \
1675         struct category##_state *category = &obj_context->codec_state.category; \
1676         assert(obj_buffer->buffer_store->bo == NULL);                   \
1677         assert(obj_buffer->buffer_store->buffer);                       \
1678         i965_release_buffer_store(&category->member);                   \
1679         i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
1680         return VA_STATUS_SUCCESS;                                       \
1681     }
1682
1683 #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member)            \
1684     static VAStatus                                                     \
1685     i965_render_##category##_##name##_buffer(VADriverContextP ctx,      \
1686                                              struct object_context *obj_context, \
1687                                              struct object_buffer *obj_buffer) \
1688     {                                                                   \
1689         struct category##_state *category = &obj_context->codec_state.category; \
1690         if (category->num_##member == category->max_##member) {         \
1691             category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
1692             memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
1693             category->max_##member += NUM_SLICES;                       \
1694         }                                                               \
1695         i965_release_buffer_store(&category->member[category->num_##member]); \
1696         i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
1697         category->num_##member++;                                       \
1698         return VA_STATUS_SUCCESS;                                       \
1699     }
1700
1701 #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
1702
1703 #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
1704 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
1705 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
1706 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
1707 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
1708
1709 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
1710 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
1711 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
1712
1713 static VAStatus 
1714 i965_decoder_render_picture(VADriverContextP ctx,
1715                             VAContextID context,
1716                             VABufferID *buffers,
1717                             int num_buffers)
1718 {
1719     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1720     struct object_context *obj_context = CONTEXT(context);
1721     VAStatus vaStatus = VA_STATUS_SUCCESS;
1722     int i;
1723
1724     for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
1725         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
1726         assert(obj_buffer);
1727
1728         switch (obj_buffer->type) {
1729         case VAPictureParameterBufferType:
1730             vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
1731             break;
1732             
1733         case VAIQMatrixBufferType:
1734             vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
1735             break;
1736
1737         case VABitPlaneBufferType:
1738             vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
1739             break;
1740
1741         case VASliceParameterBufferType:
1742             vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
1743             break;
1744
1745         case VASliceDataBufferType:
1746             vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
1747             break;
1748
1749         case VAHuffmanTableBufferType:
1750             vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
1751             break;
1752
1753         default:
1754             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1755             break;
1756         }
1757     }
1758
1759     return vaStatus;
1760 }
1761
1762 #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
1763
1764 #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
1765 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)    
1766 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
1767 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
1768 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
1769 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
1770 /* extended buffer */
1771 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
1772 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
1773
1774 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
1775 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
1776 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
1777
1778 static VAStatus
1779 i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
1780                                                    struct object_context *obj_context,
1781                                                    struct object_buffer *obj_buffer,
1782                                                    int type_index)
1783 {
1784     struct encode_state *encode = &obj_context->codec_state.encode;
1785
1786     assert(obj_buffer->buffer_store->bo == NULL);
1787     assert(obj_buffer->buffer_store->buffer);
1788     i965_release_buffer_store(&encode->packed_header_param[type_index]);
1789     i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
1790
1791     return VA_STATUS_SUCCESS;
1792 }
1793
1794 static VAStatus
1795 i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
1796                                               struct object_context *obj_context,
1797                                               struct object_buffer *obj_buffer,
1798                                               int type_index)
1799 {
1800     struct encode_state *encode = &obj_context->codec_state.encode;
1801
1802     assert(obj_buffer->buffer_store->bo == NULL);
1803     assert(obj_buffer->buffer_store->buffer);
1804     i965_release_buffer_store(&encode->packed_header_data[type_index]);
1805     i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
1806
1807     return VA_STATUS_SUCCESS;
1808 }
1809
1810 static VAStatus
1811 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
1812                                           struct object_context *obj_context,
1813                                           struct object_buffer *obj_buffer)
1814 {
1815     struct encode_state *encode = &obj_context->codec_state.encode;
1816     VAEncMiscParameterBuffer *param = NULL;
1817
1818     assert(obj_buffer->buffer_store->bo == NULL);
1819     assert(obj_buffer->buffer_store->buffer);
1820
1821     param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
1822     i965_release_buffer_store(&encode->misc_param[param->type]);
1823     i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
1824
1825     return VA_STATUS_SUCCESS;
1826 }
1827
1828 static VAStatus 
1829 i965_encoder_render_picture(VADriverContextP ctx,
1830                             VAContextID context,
1831                             VABufferID *buffers,
1832                             int num_buffers)
1833 {
1834     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1835     struct object_context *obj_context = CONTEXT(context);
1836     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1837     int i;
1838
1839     for (i = 0; i < num_buffers; i++) {  
1840         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
1841         assert(obj_buffer);
1842
1843         switch (obj_buffer->type) {
1844         case VAQMatrixBufferType:
1845             vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
1846             break;
1847
1848         case VAIQMatrixBufferType:
1849             vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
1850             break;
1851
1852         case VAEncSequenceParameterBufferType:
1853             vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
1854             break;
1855
1856         case VAEncPictureParameterBufferType:
1857             vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
1858             break;
1859
1860         case VAEncSliceParameterBufferType:
1861             vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
1862             break;
1863
1864         case VAEncPackedHeaderParameterBufferType:
1865         {
1866             struct encode_state *encode = &obj_context->codec_state.encode;
1867             VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
1868             encode->last_packed_header_type = param->type;
1869
1870             vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
1871                                                                           obj_context,
1872                                                                           obj_buffer,
1873                                                                           va_enc_packed_type_to_idx(encode->last_packed_header_type));
1874             break;
1875         }
1876
1877         case VAEncPackedHeaderDataBufferType:
1878         {
1879             struct encode_state *encode = &obj_context->codec_state.encode;
1880
1881             assert(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
1882                    encode->last_packed_header_type == VAEncPackedHeaderPicture ||
1883                    encode->last_packed_header_type == VAEncPackedHeaderSlice ||
1884                    ((encode->last_packed_header_type & VAEncPackedHeaderMiscMask == VAEncPackedHeaderMiscMask) &&
1885                     (encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask) != 0)));
1886             vaStatus = i965_encoder_render_packed_header_data_buffer(ctx, 
1887                                                                      obj_context,
1888                                                                      obj_buffer,
1889                                                                      va_enc_packed_type_to_idx(encode->last_packed_header_type));
1890             break;       
1891         }
1892
1893         case VAEncMiscParameterBufferType:
1894             vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
1895                                                                  obj_context,
1896                                                                  obj_buffer);
1897             break;
1898             
1899         default:
1900             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1901             break;
1902         }
1903     }   
1904
1905     return vaStatus;
1906 }
1907
1908 #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
1909
1910 #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
1911 DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)    
1912
1913 static VAStatus 
1914 i965_proc_render_picture(VADriverContextP ctx,
1915                          VAContextID context,
1916                          VABufferID *buffers,
1917                          int num_buffers)
1918 {
1919     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1920     struct object_context *obj_context = CONTEXT(context);
1921     VAStatus vaStatus = VA_STATUS_SUCCESS;
1922     int i;
1923
1924     for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
1925         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
1926         assert(obj_buffer);
1927
1928         switch (obj_buffer->type) {
1929         case VAProcPipelineParameterBufferType:
1930             vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
1931             break;
1932
1933         default:
1934             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1935             break;
1936         }
1937     }
1938
1939     return vaStatus;
1940 }
1941
1942 VAStatus 
1943 i965_RenderPicture(VADriverContextP ctx,
1944                    VAContextID context,
1945                    VABufferID *buffers,
1946                    int num_buffers)
1947 {
1948     struct i965_driver_data *i965 = i965_driver_data(ctx);
1949     struct object_context *obj_context;
1950     struct object_config *obj_config;
1951     VAContextID config;
1952     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1953
1954     obj_context = CONTEXT(context);
1955     assert(obj_context);
1956
1957     config = obj_context->config_id;
1958     obj_config = CONFIG(config);
1959     assert(obj_config);
1960
1961     if (VAEntrypointVideoProc == obj_config->entrypoint) {
1962         vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
1963     } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
1964         vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
1965     } else {
1966         vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
1967     }
1968
1969     return vaStatus;
1970 }
1971
1972 VAStatus 
1973 i965_EndPicture(VADriverContextP ctx, VAContextID context)
1974 {
1975     struct i965_driver_data *i965 = i965_driver_data(ctx); 
1976     struct object_context *obj_context = CONTEXT(context);
1977     struct object_config *obj_config;
1978     VAContextID config;
1979
1980     assert(obj_context);
1981     config = obj_context->config_id;
1982     obj_config = CONFIG(config);
1983     assert(obj_config);
1984
1985     if (obj_context->codec_type == CODEC_PROC) {
1986         assert(VAEntrypointVideoProc == obj_config->entrypoint);
1987     } else if (obj_context->codec_type == CODEC_ENC) {
1988         assert(VAEntrypointEncSlice == obj_config->entrypoint);
1989
1990         assert(obj_context->codec_state.encode.pic_param ||
1991                obj_context->codec_state.encode.pic_param_ext);
1992         assert(obj_context->codec_state.encode.seq_param ||
1993                obj_context->codec_state.encode.seq_param_ext);
1994         assert(obj_context->codec_state.encode.num_slice_params >= 1 ||
1995                obj_context->codec_state.encode.num_slice_params_ext >= 1);
1996     } else {
1997         assert(obj_context->codec_state.decode.pic_param);
1998         assert(obj_context->codec_state.decode.num_slice_params >= 1);
1999         assert(obj_context->codec_state.decode.num_slice_datas >= 1);
2000         assert(obj_context->codec_state.decode.num_slice_params == obj_context->codec_state.decode.num_slice_datas);
2001     }
2002
2003     assert(obj_context->hw_context->run);
2004     obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
2005
2006     return VA_STATUS_SUCCESS;
2007 }
2008
2009 VAStatus 
2010 i965_SyncSurface(VADriverContextP ctx,
2011                  VASurfaceID render_target)
2012 {
2013     struct i965_driver_data *i965 = i965_driver_data(ctx); 
2014     struct object_surface *obj_surface = SURFACE(render_target);
2015
2016     assert(obj_surface);
2017
2018     if(obj_surface->bo)
2019         drm_intel_bo_wait_rendering(obj_surface->bo);
2020
2021     return VA_STATUS_SUCCESS;
2022 }
2023
2024 VAStatus 
2025 i965_QuerySurfaceStatus(VADriverContextP ctx,
2026                         VASurfaceID render_target,
2027                         VASurfaceStatus *status)        /* out */
2028 {
2029     struct i965_driver_data *i965 = i965_driver_data(ctx); 
2030     struct object_surface *obj_surface = SURFACE(render_target);
2031
2032     assert(obj_surface);
2033
2034     if (obj_surface->bo) {
2035         if (drm_intel_bo_busy(obj_surface->bo)){
2036             *status = VASurfaceRendering;
2037         }
2038         else {
2039             *status = VASurfaceReady;
2040         }
2041     } else {
2042         *status = VASurfaceReady;
2043     }
2044
2045     return VA_STATUS_SUCCESS;
2046 }
2047
2048 static VADisplayAttribute *
2049 get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
2050 {
2051     struct i965_driver_data * const i965 = i965_driver_data(ctx);
2052     unsigned int i;
2053
2054     if (!i965->display_attributes)
2055         return NULL;
2056
2057     for (i = 0; i < i965->num_display_attributes; i++) {
2058         if (i965->display_attributes[i].type == type)
2059             return &i965->display_attributes[i];
2060     }
2061     return NULL;
2062 }
2063
2064 static bool
2065 i965_display_attributes_init(VADriverContextP ctx)
2066 {
2067     struct i965_driver_data * const i965 = i965_driver_data(ctx);
2068
2069     i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
2070     i965->display_attributes = malloc(
2071         i965->num_display_attributes * sizeof(i965->display_attributes[0]));
2072     if (!i965->display_attributes)
2073         return false;
2074
2075     memcpy(
2076         i965->display_attributes,
2077         i965_display_attributes,
2078         sizeof(i965_display_attributes)
2079     );
2080
2081     i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
2082     if (!i965->rotation_attrib)
2083         return false;
2084     return true;
2085 }
2086
2087 static void
2088 i965_display_attributes_terminate(VADriverContextP ctx)
2089 {
2090     struct i965_driver_data * const i965 = i965_driver_data(ctx);
2091
2092     if (i965->display_attributes) {
2093         free(i965->display_attributes);
2094         i965->display_attributes = NULL;
2095         i965->num_display_attributes = 0;
2096     }
2097 }
2098
2099 /* 
2100  * Query display attributes 
2101  * The caller must provide a "attr_list" array that can hold at
2102  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
2103  * returned in "attr_list" is returned in "num_attributes".
2104  */
2105 VAStatus 
2106 i965_QueryDisplayAttributes(
2107     VADriverContextP    ctx,
2108     VADisplayAttribute *attribs,        /* out */
2109     int                *num_attribs_ptr /* out */
2110 )
2111 {
2112     const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
2113
2114     if (attribs && num_attribs > 0)
2115         memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
2116
2117     if (num_attribs_ptr)
2118         *num_attribs_ptr = num_attribs;
2119
2120     return VA_STATUS_SUCCESS;
2121 }
2122
2123 /* 
2124  * Get display attributes 
2125  * This function returns the current attribute values in "attr_list".
2126  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
2127  * from vaQueryDisplayAttributes() can have their values retrieved.  
2128  */
2129 VAStatus 
2130 i965_GetDisplayAttributes(
2131     VADriverContextP    ctx,
2132     VADisplayAttribute *attribs,        /* inout */
2133     int                 num_attribs     /* in */
2134 )
2135 {
2136     int i;
2137
2138     for (i = 0; i < num_attribs; i++) {
2139         VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
2140
2141         src_attrib = get_display_attribute(ctx, dst_attrib->type);
2142         if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
2143             dst_attrib->min_value = src_attrib->min_value;
2144             dst_attrib->max_value = src_attrib->max_value;
2145             dst_attrib->value     = src_attrib->value;
2146         }
2147         else
2148             dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
2149     }
2150     return VA_STATUS_SUCCESS;
2151 }
2152
2153 /* 
2154  * Set display attributes 
2155  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
2156  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
2157  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
2158  */
2159 VAStatus 
2160 i965_SetDisplayAttributes(
2161     VADriverContextP    ctx,
2162     VADisplayAttribute *attribs,        /* in */
2163     int                 num_attribs     /* in */
2164 )
2165 {
2166     int i;
2167
2168     for (i = 0; i < num_attribs; i++) {
2169         VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
2170
2171         dst_attrib = get_display_attribute(ctx, src_attrib->type);
2172         if (!dst_attrib)
2173             return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
2174
2175         if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
2176             continue;
2177
2178         if (src_attrib->value < dst_attrib->min_value ||
2179             src_attrib->value > dst_attrib->max_value)
2180             return VA_STATUS_ERROR_INVALID_PARAMETER;
2181
2182         dst_attrib->value = src_attrib->value;
2183         /* XXX: track modified attributes through timestamps */
2184     }
2185     return VA_STATUS_SUCCESS;
2186 }
2187
2188 VAStatus 
2189 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
2190                             VASurfaceID surface,
2191                             void **buffer,              /* out */
2192                             unsigned int *stride)       /* out */
2193 {
2194     /* TODO */
2195     return VA_STATUS_ERROR_UNIMPLEMENTED;
2196 }
2197
2198 static VAStatus 
2199 i965_Init(VADriverContextP ctx)
2200 {
2201     struct i965_driver_data *i965 = i965_driver_data(ctx); 
2202
2203     if (intel_driver_init(ctx) == False)
2204         return VA_STATUS_ERROR_UNKNOWN;
2205
2206     if (IS_HASWELL(i965->intel.device_id))
2207         i965->codec_info = &gen75_hw_codec_info;
2208     else if (IS_G4X(i965->intel.device_id))
2209         i965->codec_info = &g4x_hw_codec_info;
2210     else if (IS_IRONLAKE(i965->intel.device_id))
2211         i965->codec_info = &ironlake_hw_codec_info;
2212     else if (IS_GEN6(i965->intel.device_id))
2213         i965->codec_info = &gen6_hw_codec_info;
2214     else if (IS_GEN7(i965->intel.device_id))
2215         i965->codec_info = &gen7_hw_codec_info;
2216     else
2217         return VA_STATUS_ERROR_UNKNOWN;
2218
2219     i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
2220
2221     if (!i965_display_attributes_init(ctx))
2222         return VA_STATUS_ERROR_UNKNOWN;
2223
2224     if (i965_post_processing_init(ctx) == False)
2225         return VA_STATUS_ERROR_UNKNOWN;
2226
2227     if (i965_render_init(ctx) == False)
2228         return VA_STATUS_ERROR_UNKNOWN;
2229
2230 #ifdef HAVE_VA_WAYLAND
2231     if (IS_VA_WAYLAND(ctx) && !i965_output_wayland_init(ctx))
2232         return VA_STATUS_ERROR_UNKNOWN;
2233 #endif
2234
2235 #ifdef HAVE_VA_X11
2236     if (IS_VA_X11(ctx) && !i965_output_dri_init(ctx))
2237         return VA_STATUS_ERROR_UNKNOWN;
2238 #endif
2239
2240     _i965InitMutex(&i965->render_mutex);
2241     _i965InitMutex(&i965->pp_mutex);
2242
2243     return VA_STATUS_SUCCESS;
2244 }
2245
2246 static void
2247 i965_destroy_heap(struct object_heap *heap, 
2248                   void (*func)(struct object_heap *heap, struct object_base *object))
2249 {
2250     struct object_base *object;
2251     object_heap_iterator iter;    
2252
2253     object = object_heap_first(heap, &iter);
2254
2255     while (object) {
2256         if (func)
2257             func(heap, object);
2258
2259         object = object_heap_next(heap, &iter);
2260     }
2261
2262     object_heap_destroy(heap);
2263 }
2264
2265
2266 VAStatus 
2267 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
2268
2269 VAStatus 
2270 i965_CreateImage(VADriverContextP ctx,
2271                  VAImageFormat *format,
2272                  int width,
2273                  int height,
2274                  VAImage *out_image)        /* out */
2275 {
2276     struct i965_driver_data *i965 = i965_driver_data(ctx);
2277     struct object_image *obj_image;
2278     VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
2279     VAImageID image_id;
2280     unsigned int width2, height2, size2, size;
2281
2282     out_image->image_id = VA_INVALID_ID;
2283     out_image->buf      = VA_INVALID_ID;
2284
2285     image_id = NEW_IMAGE_ID();
2286     if (image_id == VA_INVALID_ID)
2287         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2288
2289     obj_image = IMAGE(image_id);
2290     if (!obj_image)
2291         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2292     obj_image->bo         = NULL;
2293     obj_image->palette    = NULL;
2294     obj_image->derived_surface = VA_INVALID_ID;
2295
2296     VAImage * const image = &obj_image->image;
2297     image->image_id       = image_id;
2298     image->buf            = VA_INVALID_ID;
2299
2300     size    = width * height;
2301     width2  = (width  + 1) / 2;
2302     height2 = (height + 1) / 2;
2303     size2   = width2 * height2;
2304
2305     image->num_palette_entries = 0;
2306     image->entry_bytes         = 0;
2307     memset(image->component_order, 0, sizeof(image->component_order));
2308
2309     switch (format->fourcc) {
2310     case VA_FOURCC('I','A','4','4'):
2311     case VA_FOURCC('A','I','4','4'):
2312         image->num_planes = 1;
2313         image->pitches[0] = width;
2314         image->offsets[0] = 0;
2315         image->data_size  = image->offsets[0] + image->pitches[0] * height;
2316         image->num_palette_entries = 16;
2317         image->entry_bytes         = 3;
2318         image->component_order[0]  = 'R';
2319         image->component_order[1]  = 'G';
2320         image->component_order[2]  = 'B';
2321         break;
2322     case VA_FOURCC('B','G','R','A'):
2323     case VA_FOURCC('R','G','B','A'):
2324     case VA_FOURCC('B','G','R','X'):
2325     case VA_FOURCC('R','G','B','X'):
2326         image->num_planes = 1;
2327         image->pitches[0] = width * 4;
2328         image->offsets[0] = 0;
2329         image->data_size  = image->offsets[0] + image->pitches[0] * height;
2330         break;
2331     case VA_FOURCC('Y','V','1','2'):
2332         image->num_planes = 3;
2333         image->pitches[0] = width;
2334         image->offsets[0] = 0;
2335         image->pitches[1] = width2;
2336         image->offsets[1] = size + size2;
2337         image->pitches[2] = width2;
2338         image->offsets[2] = size;
2339         image->data_size  = size + 2 * size2;
2340         break;
2341     case VA_FOURCC('I','4','2','0'):
2342         image->num_planes = 3;
2343         image->pitches[0] = width;
2344         image->offsets[0] = 0;
2345         image->pitches[1] = width2;
2346         image->offsets[1] = size;
2347         image->pitches[2] = width2;
2348         image->offsets[2] = size + size2;
2349         image->data_size  = size + 2 * size2;
2350         break;
2351     case VA_FOURCC('N','V','1','2'):
2352         image->num_planes = 2;
2353         image->pitches[0] = width;
2354         image->offsets[0] = 0;
2355         image->pitches[1] = width;
2356         image->offsets[1] = size;
2357         image->data_size  = size + 2 * size2;
2358         break;
2359     case VA_FOURCC('Y','U','Y','2'):
2360     case VA_FOURCC('U','Y','V','Y'):
2361         image->num_planes = 1;
2362         image->pitches[0] = width * 2;
2363         image->offsets[0] = 0;
2364         image->data_size  = size * 2;
2365         break;
2366     default:
2367         goto error;
2368     }
2369
2370     va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
2371                                   image->data_size, 1, NULL, &image->buf);
2372     if (va_status != VA_STATUS_SUCCESS)
2373         goto error;
2374
2375     obj_image->bo = BUFFER(image->buf)->buffer_store->bo;
2376     dri_bo_reference(obj_image->bo);
2377
2378     if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
2379         obj_image->palette = malloc(image->num_palette_entries * sizeof(obj_image->palette));
2380         if (!obj_image->palette)
2381             goto error;
2382     }
2383
2384     image->image_id             = image_id;
2385     image->format               = *format;
2386     image->width                = width;
2387     image->height               = height;
2388
2389     *out_image                  = *image;
2390     return VA_STATUS_SUCCESS;
2391
2392  error:
2393     i965_DestroyImage(ctx, image_id);
2394     return va_status;
2395 }
2396
2397 void 
2398 i965_check_alloc_surface_bo(VADriverContextP ctx,
2399                             struct object_surface *obj_surface,
2400                             int tiled,
2401                             unsigned int fourcc,
2402                             unsigned int subsampling)
2403 {
2404     struct i965_driver_data *i965 = i965_driver_data(ctx);
2405     int region_width, region_height;
2406
2407     if (obj_surface->bo) {
2408         assert(obj_surface->fourcc);
2409         assert(obj_surface->fourcc == fourcc);
2410         assert(obj_surface->subsampling == subsampling);
2411         return;
2412     }
2413
2414     obj_surface->x_cb_offset = 0; /* X offset is always 0 */
2415     obj_surface->x_cr_offset = 0;
2416
2417     if (tiled) {
2418         assert(fourcc == VA_FOURCC('N', 'V', '1', '2') ||
2419                fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
2420                fourcc == VA_FOURCC('I', 'M', 'C', '3') || 
2421                fourcc == VA_FOURCC('R', 'G', 'B', 'A') || 
2422                fourcc == VA_FOURCC('R', 'G', 'B', 'X') || 
2423                fourcc == VA_FOURCC('B', 'G', 'R', 'A') || 
2424                fourcc == VA_FOURCC('B', 'G', 'R', 'X') || 
2425                fourcc == VA_FOURCC('Y', 'U', 'Y', '2'));
2426
2427         obj_surface->width = ALIGN(obj_surface->orig_width, 128);
2428         obj_surface->height = ALIGN(obj_surface->orig_height, 32);
2429         region_height = obj_surface->height;
2430
2431         if (fourcc == VA_FOURCC('N', 'V', '1', '2') ||
2432             fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
2433             fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
2434             obj_surface->cb_cr_pitch = obj_surface->width;
2435             region_width = obj_surface->width;
2436         }
2437         else if (fourcc == VA_FOURCC('Y','U', 'Y', '2')) {
2438             obj_surface->cb_cr_pitch = obj_surface->width * 2;
2439             region_width = obj_surface->width * 2;
2440         }
2441         else if (fourcc == VA_FOURCC('R', 'G', 'B', 'A') || 
2442                  fourcc == VA_FOURCC('R', 'G', 'B', 'X') || 
2443                  fourcc == VA_FOURCC('B', 'G', 'R', 'A') || 
2444                  fourcc == VA_FOURCC('B', 'G', 'R', 'X')) {
2445             region_width = obj_surface->width * 4;
2446         }
2447         else {
2448             assert(0);
2449         }
2450                
2451
2452         if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
2453             assert(subsampling == SUBSAMPLE_YUV420);
2454             obj_surface->y_cb_offset = obj_surface->height;
2455             obj_surface->y_cr_offset = obj_surface->height;
2456             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2457             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2458             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
2459         } else if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
2460                    fourcc == VA_FOURCC('I', 'M', 'C', '3') || 
2461                    fourcc == VA_FOURCC('R', 'G', 'B', 'A') || 
2462                    fourcc == VA_FOURCC('R', 'G', 'B', 'X') || 
2463                    fourcc == VA_FOURCC('B', 'G', 'R', 'A') || 
2464                    fourcc == VA_FOURCC('B', 'G', 'R', 'X') || 
2465                    fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
2466             switch (subsampling) {
2467             case SUBSAMPLE_YUV400:
2468                 obj_surface->cb_cr_width = 0;
2469                 obj_surface->cb_cr_height = 0;
2470                 break;
2471
2472             case SUBSAMPLE_YUV420:
2473                 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2474                 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2475                 break;
2476
2477             case SUBSAMPLE_YUV422H:
2478                 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2479                 obj_surface->cb_cr_height = obj_surface->orig_height;
2480                 break;
2481
2482             case SUBSAMPLE_YUV422V:
2483                 obj_surface->cb_cr_width = obj_surface->orig_width;
2484                 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2485                 break;
2486
2487             case SUBSAMPLE_YUV444:
2488                 obj_surface->cb_cr_width = obj_surface->orig_width;
2489                 obj_surface->cb_cr_height = obj_surface->orig_height;
2490                 break;
2491
2492             case SUBSAMPLE_YUV411:
2493                 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
2494                 obj_surface->cb_cr_height = obj_surface->orig_height;
2495                 break;
2496             case SUBSAMPLE_RGBX:
2497                 break;
2498             default:
2499                 assert(0);
2500                 break;
2501             }
2502
2503             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2504
2505             if (fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
2506                 obj_surface->y_cr_offset = obj_surface->height;
2507                 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
2508             } else if (fourcc == VA_FOURCC('I', 'M', 'C', '3')){
2509                 obj_surface->y_cb_offset = obj_surface->height;
2510                 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2511             }
2512             else if (fourcc == VA_FOURCC('Y','U', 'Y', '2')) {
2513                 obj_surface->y_cb_offset = 0; 
2514                 obj_surface->y_cr_offset = 0; 
2515                 region_height = obj_surface->height;
2516             }
2517             else if (fourcc == VA_FOURCC('R', 'G', 'B', 'A') || 
2518                      fourcc == VA_FOURCC('R', 'G', 'B', 'X') || 
2519                      fourcc == VA_FOURCC('B', 'G', 'R', 'A') || 
2520                      fourcc == VA_FOURCC('B', 'G', 'R', 'X')) {
2521                 region_height = obj_surface->height;
2522             }
2523         }
2524     } else {
2525         assert(fourcc != VA_FOURCC('I', 'M', 'C', '1') &&
2526                fourcc != VA_FOURCC('I', 'M', 'C', '3'));
2527         assert(subsampling == SUBSAMPLE_YUV420 || 
2528                subsampling == SUBSAMPLE_YUV422H || 
2529                subsampling == SUBSAMPLE_YUV422V || 
2530                subsampling == SUBSAMPLE_RGBX);
2531
2532         region_width = obj_surface->width;
2533         region_height = obj_surface->height;
2534
2535         switch (fourcc) {
2536         case VA_FOURCC('N', 'V', '1', '2'):
2537             obj_surface->y_cb_offset = obj_surface->height;
2538             obj_surface->y_cr_offset = obj_surface->height;
2539             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2540             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2541             obj_surface->cb_cr_pitch = obj_surface->width;
2542             region_height = obj_surface->height + obj_surface->height / 2;
2543             break;
2544
2545         case VA_FOURCC('Y', 'V', '1', '2'):
2546         case VA_FOURCC('I', '4', '2', '0'):
2547             if (fourcc == VA_FOURCC('Y', 'V', '1', '2')) {
2548                 obj_surface->y_cr_offset = obj_surface->height;
2549                 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
2550             } else {
2551                 obj_surface->y_cb_offset = obj_surface->height;
2552                 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
2553             }
2554
2555             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2556             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2557             obj_surface->cb_cr_pitch = obj_surface->width / 2;
2558             region_height = obj_surface->height + obj_surface->height / 2;
2559             break;
2560
2561         case VA_FOURCC('Y','U', 'Y', '2'):
2562             obj_surface->y_cb_offset = 0;
2563             obj_surface->y_cr_offset = 0;
2564             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2565             obj_surface->cb_cr_height = obj_surface->orig_height;
2566             obj_surface->cb_cr_pitch = obj_surface->width * 2;
2567             region_width = obj_surface->width * 2;
2568             region_height = obj_surface->height;
2569             break;
2570         case VA_FOURCC('R', 'G', 'B', 'A'):
2571         case VA_FOURCC('R', 'G', 'B', 'X'):
2572         case VA_FOURCC('B', 'G', 'R', 'A'):
2573         case VA_FOURCC('B', 'G', 'R', 'X'):
2574             region_width = obj_surface->width * 4;
2575             region_height = obj_surface->height;
2576             break;
2577
2578         default:
2579             assert(0);
2580             break;
2581         }
2582     }
2583
2584     obj_surface->size = ALIGN(region_width * region_height, 0x1000);
2585
2586     if (tiled) {
2587         uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
2588         unsigned long pitch;
2589
2590         obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr, 
2591                                                    "vaapi surface",
2592                                                    region_width,
2593                                                    region_height,
2594                                                    1,
2595                                                    &tiling_mode,
2596                                                    &pitch,
2597                                                    0);
2598         assert(tiling_mode == I915_TILING_Y);
2599         assert(pitch == obj_surface->width     || 
2600                pitch == obj_surface->width * 2 ||
2601                pitch == obj_surface->width * 4) ;
2602     } else {
2603         obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
2604                                        "vaapi surface",
2605                                        obj_surface->size,
2606                                        0x1000);
2607     }
2608
2609     obj_surface->fourcc = fourcc;
2610     obj_surface->subsampling = subsampling;
2611     assert(obj_surface->bo);
2612 }
2613
2614 VAStatus i965_DeriveImage(VADriverContextP ctx,
2615                           VASurfaceID surface,
2616                           VAImage *out_image)        /* out */
2617 {
2618     struct i965_driver_data *i965 = i965_driver_data(ctx);
2619     struct object_image *obj_image;
2620     struct object_surface *obj_surface; 
2621     VAImageID image_id;
2622     unsigned int w_pitch, h_pitch;
2623     VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
2624
2625     out_image->image_id = VA_INVALID_ID;
2626     obj_surface = SURFACE(surface);
2627
2628     if (!obj_surface)
2629         return VA_STATUS_ERROR_INVALID_SURFACE;
2630
2631     if (!obj_surface->bo) {
2632         unsigned int is_tiled = 0;
2633         unsigned int fourcc = VA_FOURCC('Y', 'V', '1', '2');
2634         i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
2635         int sampling = get_sampling_from_fourcc(fourcc);
2636         i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
2637     }
2638
2639     assert(obj_surface->fourcc);
2640
2641     w_pitch = obj_surface->width;
2642     h_pitch = obj_surface->height;
2643
2644     image_id = NEW_IMAGE_ID();
2645
2646     if (image_id == VA_INVALID_ID)
2647         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2648
2649     obj_image = IMAGE(image_id);
2650     
2651     if (!obj_image)
2652         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2653
2654     obj_image->bo = NULL;
2655     obj_image->palette = NULL;
2656     obj_image->derived_surface = VA_INVALID_ID;
2657
2658     VAImage * const image = &obj_image->image;
2659     
2660     memset(image, 0, sizeof(*image));
2661     image->image_id = image_id;
2662     image->buf = VA_INVALID_ID;
2663     image->num_palette_entries = 0;
2664     image->entry_bytes = 0;
2665     image->width = obj_surface->orig_width;
2666     image->height = obj_surface->orig_height;
2667     image->data_size = obj_surface->size;
2668
2669     image->format.fourcc = obj_surface->fourcc;
2670     image->format.byte_order = VA_LSB_FIRST;
2671     image->format.bits_per_pixel = 12;
2672
2673     switch (image->format.fourcc) {
2674     case VA_FOURCC('Y', 'V', '1', '2'):
2675         image->num_planes = 3;
2676         image->pitches[0] = w_pitch; /* Y */
2677         image->offsets[0] = 0;
2678         image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
2679         image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
2680         image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
2681         image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
2682         break;
2683
2684     case VA_FOURCC('N', 'V', '1', '2'):
2685         image->num_planes = 2;
2686         image->pitches[0] = w_pitch; /* Y */
2687         image->offsets[0] = 0;
2688         image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
2689         image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
2690         break;
2691
2692     case VA_FOURCC('I', '4', '2', '0'):
2693         image->num_planes = 3;
2694         image->pitches[0] = w_pitch; /* Y */
2695         image->offsets[0] = 0;
2696         image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
2697         image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
2698         image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
2699         image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
2700         break;
2701     case VA_FOURCC('Y', 'U', 'Y', '2'):
2702         image->num_planes = 1;
2703         image->pitches[0] = obj_surface->width * 2; /* Y, width is aligned already */
2704         image->offsets[0] = 0;
2705         image->pitches[1] = obj_surface->width * 2; /* U */
2706         image->offsets[1] = 0;
2707         image->pitches[2] = obj_surface->width * 2; /* V */
2708         image->offsets[2] = 0;
2709         break;
2710     case VA_FOURCC('R', 'G', 'B', 'A'):
2711     case VA_FOURCC('R', 'G', 'B', 'X'):
2712     case VA_FOURCC('B', 'G', 'R', 'A'):
2713     case VA_FOURCC('B', 'G', 'R', 'X'):
2714         image->num_planes = 1;
2715         image->pitches[0] = obj_surface->width * 4;
2716         break;
2717     default:
2718         goto error;
2719     }
2720
2721     va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
2722                                             obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
2723     if (va_status != VA_STATUS_SUCCESS)
2724         goto error;
2725
2726     obj_image->bo = BUFFER(image->buf)->buffer_store->bo;
2727     dri_bo_reference(obj_image->bo);
2728
2729     if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
2730         obj_image->palette = malloc(image->num_palette_entries * sizeof(obj_image->palette));
2731         if (!obj_image->palette) {
2732             va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
2733             goto error;
2734         }
2735     }
2736
2737     *out_image = *image;
2738     obj_surface->flags |= SURFACE_DERIVED;
2739     obj_image->derived_surface = surface;
2740
2741     return VA_STATUS_SUCCESS;
2742
2743  error:
2744     i965_DestroyImage(ctx, image_id);
2745     return va_status;
2746 }
2747
2748 static void 
2749 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
2750 {
2751     object_heap_free(heap, obj);
2752 }
2753
2754
2755 VAStatus 
2756 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
2757 {
2758     struct i965_driver_data *i965 = i965_driver_data(ctx);
2759     struct object_image *obj_image = IMAGE(image); 
2760     struct object_surface *obj_surface; 
2761
2762     if (!obj_image)
2763         return VA_STATUS_SUCCESS;
2764
2765     dri_bo_unreference(obj_image->bo);
2766     obj_image->bo = NULL;
2767
2768     if (obj_image->image.buf != VA_INVALID_ID) {
2769         i965_DestroyBuffer(ctx, obj_image->image.buf);
2770         obj_image->image.buf = VA_INVALID_ID;
2771     }
2772
2773     if (obj_image->palette) {
2774         free(obj_image->palette);
2775         obj_image->palette = NULL;
2776     }
2777
2778     obj_surface = SURFACE(obj_image->derived_surface);
2779
2780     if (obj_surface) {
2781         obj_surface->flags &= ~SURFACE_DERIVED;
2782     }
2783
2784     i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
2785
2786     return VA_STATUS_SUCCESS;
2787 }
2788
2789 /*
2790  * pointer to an array holding the palette data.  The size of the array is
2791  * num_palette_entries * entry_bytes in size.  The order of the components
2792  * in the palette is described by the component_order in VASubpicture struct
2793  */
2794 VAStatus 
2795 i965_SetImagePalette(VADriverContextP ctx,
2796                      VAImageID image,
2797                      unsigned char *palette)
2798 {
2799     struct i965_driver_data *i965 = i965_driver_data(ctx);
2800     unsigned int i;
2801
2802     struct object_image *obj_image = IMAGE(image);
2803     if (!obj_image)
2804         return VA_STATUS_ERROR_INVALID_IMAGE;
2805
2806     if (!obj_image->palette)
2807         return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
2808
2809     for (i = 0; i < obj_image->image.num_palette_entries; i++)
2810         obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
2811                                  ((unsigned int)palette[3*i + 1] <<  8) |
2812                                  (unsigned int)palette[3*i + 2]);
2813     return VA_STATUS_SUCCESS;
2814 }
2815
2816 static int 
2817 get_sampling_from_fourcc(unsigned int fourcc)
2818 {
2819     int surface_sampling = -1;
2820     switch (fourcc) {
2821     case VA_FOURCC('N', 'V', '1', '2'):
2822     case VA_FOURCC('Y', 'V', '1', '2'):
2823     case VA_FOURCC('I', '4', '2', '0'):
2824     case VA_FOURCC('I', 'M', 'C', '1'):
2825     case VA_FOURCC('I', 'M', 'C', '3'):
2826         surface_sampling = SUBSAMPLE_YUV420;
2827         break;
2828     case VA_FOURCC('Y', 'U', 'Y', '2'):
2829         surface_sampling = SUBSAMPLE_YUV422H;
2830         break;
2831     case VA_FOURCC('R','G','B','A'):
2832     case VA_FOURCC('R','G','B','X'):
2833     case VA_FOURCC('B','G','R','A'):
2834     case VA_FOURCC('B','G','R','X'):
2835     surface_sampling = SUBSAMPLE_RGBX; 
2836         break;
2837     default:
2838         break;
2839     }
2840     return surface_sampling;
2841 }
2842
2843 static inline void
2844 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
2845            const uint8_t *src, unsigned int src_stride,
2846            unsigned int len, unsigned int height)
2847 {
2848     unsigned int i;
2849
2850     for (i = 0; i < height; i++) {
2851         memcpy(dst, src, len);
2852         dst += dst_stride;
2853         src += src_stride;
2854     }
2855 }
2856
2857 static void
2858 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
2859                struct object_surface *obj_surface,
2860                const VARectangle *rect)
2861 {
2862     uint8_t *dst[3], *src[3];
2863     const int Y = 0;
2864     const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
2865     const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
2866     unsigned int tiling, swizzle;
2867
2868     if (!obj_surface->bo)
2869         return;
2870
2871     assert(obj_surface->fourcc);
2872     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
2873
2874     if (tiling != I915_TILING_NONE)
2875         drm_intel_gem_bo_map_gtt(obj_surface->bo);
2876     else
2877         dri_bo_map(obj_surface->bo, 0);
2878
2879     if (!obj_surface->bo->virtual)
2880         return;
2881
2882     /* Dest VA image has either I420 or YV12 format.
2883        Source VA surface alway has I420 format */
2884     dst[Y] = image_data + obj_image->image.offsets[Y];
2885     src[0] = (uint8_t *)obj_surface->bo->virtual;
2886     dst[U] = image_data + obj_image->image.offsets[U];
2887     src[1] = src[0] + obj_surface->width * obj_surface->height;
2888     dst[V] = image_data + obj_image->image.offsets[V];
2889     src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
2890
2891     /* Y plane */
2892     dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
2893     src[0] += rect->y * obj_surface->width + rect->x;
2894     memcpy_pic(dst[Y], obj_image->image.pitches[Y],
2895                src[0], obj_surface->width,
2896                rect->width, rect->height);
2897
2898     /* U plane */
2899     dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
2900     src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
2901     memcpy_pic(dst[U], obj_image->image.pitches[U],
2902                src[1], obj_surface->width / 2,
2903                rect->width / 2, rect->height / 2);
2904
2905     /* V plane */
2906     dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
2907     src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
2908     memcpy_pic(dst[V], obj_image->image.pitches[V],
2909                src[2], obj_surface->width / 2,
2910                rect->width / 2, rect->height / 2);
2911
2912     if (tiling != I915_TILING_NONE)
2913         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
2914     else
2915         dri_bo_unmap(obj_surface->bo);
2916 }
2917
2918 static void
2919 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
2920                struct object_surface *obj_surface,
2921                const VARectangle *rect)
2922 {
2923     uint8_t *dst[2], *src[2];
2924     unsigned int tiling, swizzle;
2925
2926     if (!obj_surface->bo)
2927         return;
2928
2929     assert(obj_surface->fourcc);
2930     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
2931
2932     if (tiling != I915_TILING_NONE)
2933         drm_intel_gem_bo_map_gtt(obj_surface->bo);
2934     else
2935         dri_bo_map(obj_surface->bo, 0);
2936
2937     if (!obj_surface->bo->virtual)
2938         return;
2939
2940     /* Both dest VA image and source surface have NV12 format */
2941     dst[0] = image_data + obj_image->image.offsets[0];
2942     src[0] = (uint8_t *)obj_surface->bo->virtual;
2943     dst[1] = image_data + obj_image->image.offsets[1];
2944     src[1] = src[0] + obj_surface->width * obj_surface->height;
2945
2946     /* Y plane */
2947     dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
2948     src[0] += rect->y * obj_surface->width + rect->x;
2949     memcpy_pic(dst[0], obj_image->image.pitches[0],
2950                src[0], obj_surface->width,
2951                rect->width, rect->height);
2952
2953     /* UV plane */
2954     dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
2955     src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
2956     memcpy_pic(dst[1], obj_image->image.pitches[1],
2957                src[1], obj_surface->width,
2958                rect->width, rect->height / 2);
2959
2960     if (tiling != I915_TILING_NONE)
2961         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
2962     else
2963         dri_bo_unmap(obj_surface->bo);
2964 }
2965
2966 static void
2967 get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
2968                struct object_surface *obj_surface,
2969                const VARectangle *rect)
2970 {
2971     uint8_t *dst, *src;
2972     unsigned int tiling, swizzle;
2973
2974     if (!obj_surface->bo)
2975         return;
2976
2977     assert(obj_surface->fourcc);
2978     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
2979
2980     if (tiling != I915_TILING_NONE)
2981         drm_intel_gem_bo_map_gtt(obj_surface->bo);
2982     else
2983         dri_bo_map(obj_surface->bo, 0);
2984
2985     if (!obj_surface->bo->virtual)
2986         return;
2987
2988     /* Both dest VA image and source surface have YUYV format */
2989     dst = image_data + obj_image->image.offsets[0];
2990     src = (uint8_t *)obj_surface->bo->virtual;
2991
2992     /* Y plane */
2993     dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
2994     src += rect->y * obj_surface->width + rect->x*2;
2995     memcpy_pic(dst, obj_image->image.pitches[0],
2996                src, obj_surface->width*2,
2997                rect->width*2, rect->height);
2998
2999     if (tiling != I915_TILING_NONE)
3000         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3001     else
3002         dri_bo_unmap(obj_surface->bo);
3003 }
3004
3005 static VAStatus 
3006 i965_sw_getimage(VADriverContextP ctx,
3007                  VASurfaceID surface,
3008                  int x,   /* coordinates of the upper left source pixel */
3009                  int y,
3010                  unsigned int width,      /* width and height of the region */
3011                  unsigned int height,
3012                  VAImageID image)
3013 {
3014     struct i965_driver_data *i965 = i965_driver_data(ctx);
3015     struct i965_render_state *render_state = &i965->render_state;
3016
3017     struct object_surface *obj_surface = SURFACE(surface);
3018     if (!obj_surface)
3019         return VA_STATUS_ERROR_INVALID_SURFACE;
3020
3021     struct object_image *obj_image = IMAGE(image);
3022     if (!obj_image)
3023         return VA_STATUS_ERROR_INVALID_IMAGE;
3024
3025     if (x < 0 || y < 0)
3026         return VA_STATUS_ERROR_INVALID_PARAMETER;
3027     if (x + width > obj_surface->orig_width ||
3028         y + height > obj_surface->orig_height)
3029         return VA_STATUS_ERROR_INVALID_PARAMETER;
3030     if (x + width > obj_image->image.width ||
3031         y + height > obj_image->image.height)
3032         return VA_STATUS_ERROR_INVALID_PARAMETER;
3033
3034     if (obj_surface->fourcc != obj_image->image.format.fourcc)
3035         return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3036
3037     VAStatus va_status;
3038     void *image_data = NULL;
3039
3040     va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3041     if (va_status != VA_STATUS_SUCCESS)
3042         return va_status;
3043
3044     VARectangle rect;
3045     rect.x = x;
3046     rect.y = y;
3047     rect.width = width;
3048     rect.height = height;
3049
3050     switch (obj_image->image.format.fourcc) {
3051     case VA_FOURCC('Y','V','1','2'):
3052     case VA_FOURCC('I','4','2','0'):
3053         /* I420 is native format for MPEG-2 decoded surfaces */
3054         if (render_state->interleaved_uv)
3055             goto operation_failed;
3056         get_image_i420(obj_image, image_data, obj_surface, &rect);
3057         break;
3058     case VA_FOURCC('N','V','1','2'):
3059         /* NV12 is native format for H.264 decoded surfaces */
3060         if (!render_state->interleaved_uv)
3061             goto operation_failed;
3062         get_image_nv12(obj_image, image_data, obj_surface, &rect);
3063         break;
3064     case VA_FOURCC('Y','U','Y','2'):
3065         /* YUY2 is the format supported by overlay plane */
3066         get_image_yuy2(obj_image, image_data, obj_surface, &rect);
3067         break;
3068     default:
3069     operation_failed:
3070         va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3071         break;
3072     }
3073
3074     i965_UnmapBuffer(ctx, obj_image->image.buf);
3075     return va_status;
3076 }
3077
3078 static VAStatus 
3079 i965_hw_getimage(VADriverContextP ctx,
3080                  VASurfaceID surface,
3081                  int x,   /* coordinates of the upper left source pixel */
3082                  int y,
3083                  unsigned int width,      /* width and height of the region */
3084                  unsigned int height,
3085                  VAImageID image)
3086 {
3087     struct i965_driver_data *i965 = i965_driver_data(ctx);
3088     struct i965_surface src_surface;
3089     struct i965_surface dst_surface;
3090     VAStatus va_status;
3091     VARectangle rect;
3092     struct object_surface *obj_surface = SURFACE(surface);
3093     struct object_image *obj_image = IMAGE(image);
3094
3095     if (!obj_surface)
3096         return VA_STATUS_ERROR_INVALID_SURFACE;
3097
3098     if (!obj_image)
3099         return VA_STATUS_ERROR_INVALID_IMAGE;
3100
3101     if (x < 0 || y < 0)
3102         return VA_STATUS_ERROR_INVALID_PARAMETER;
3103     if (x + width > obj_surface->orig_width ||
3104         y + height > obj_surface->orig_height)
3105         return VA_STATUS_ERROR_INVALID_PARAMETER;
3106     if (x + width > obj_image->image.width ||
3107         y + height > obj_image->image.height)
3108         return VA_STATUS_ERROR_INVALID_PARAMETER;
3109
3110     if (!obj_surface->bo)
3111         return VA_STATUS_SUCCESS;
3112     assert(obj_image->bo); // image bo is always created, see i965_CreateImage()
3113
3114     rect.x = x;
3115     rect.y = y;
3116     rect.width = width;
3117     rect.height = height;
3118
3119     src_surface.id = surface;
3120     src_surface.type = I965_SURFACE_TYPE_SURFACE;
3121     src_surface.flags = I965_SURFACE_FLAG_FRAME;
3122
3123     dst_surface.id = image;
3124     dst_surface.type = I965_SURFACE_TYPE_IMAGE;
3125     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3126
3127     va_status = i965_image_processing(ctx,
3128                                       &src_surface,
3129                                       &rect,
3130                                       &dst_surface,
3131                                       &rect);
3132
3133
3134     return va_status;
3135 }
3136
3137 VAStatus 
3138 i965_GetImage(VADriverContextP ctx,
3139               VASurfaceID surface,
3140               int x,   /* coordinates of the upper left source pixel */
3141               int y,
3142               unsigned int width,      /* width and height of the region */
3143               unsigned int height,
3144               VAImageID image)
3145 {
3146     struct i965_driver_data * const i965 = i965_driver_data(ctx);
3147     VAStatus va_status;
3148
3149     if (HAS_ACCELERATED_GETIMAGE(i965))
3150         va_status = i965_hw_getimage(ctx,
3151                                      surface,
3152                                      x, y,
3153                                      width, height,
3154                                      image);
3155     else
3156         va_status = i965_sw_getimage(ctx,
3157                                      surface,
3158                                      x, y,
3159                                      width, height,
3160                                      image);
3161
3162     return va_status;
3163 }
3164
3165 static void
3166 put_image_i420(struct object_surface *obj_surface,
3167                const VARectangle *dst_rect,
3168                struct object_image *obj_image, uint8_t *image_data,
3169                const VARectangle *src_rect)
3170 {
3171     uint8_t *dst[3], *src[3];
3172     const int Y = 0;
3173     const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3174     const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3175     unsigned int tiling, swizzle;
3176
3177     if (!obj_surface->bo)
3178         return;
3179
3180     assert(obj_surface->fourcc);
3181     assert(dst_rect->width == src_rect->width);
3182     assert(dst_rect->height == src_rect->height);
3183     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3184
3185     if (tiling != I915_TILING_NONE)
3186         drm_intel_gem_bo_map_gtt(obj_surface->bo);
3187     else
3188         dri_bo_map(obj_surface->bo, 0);
3189
3190     if (!obj_surface->bo->virtual)
3191         return;
3192
3193     /* Dest VA image has either I420 or YV12 format.
3194        Source VA surface alway has I420 format */
3195     dst[0] = (uint8_t *)obj_surface->bo->virtual;
3196     src[Y] = image_data + obj_image->image.offsets[Y];
3197     dst[1] = dst[0] + obj_surface->width * obj_surface->height;
3198     src[U] = image_data + obj_image->image.offsets[U];
3199     dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3200     src[V] = image_data + obj_image->image.offsets[V];
3201
3202     /* Y plane */
3203     dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
3204     src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
3205     memcpy_pic(dst[0], obj_surface->width,
3206                src[Y], obj_image->image.pitches[Y],
3207                src_rect->width, src_rect->height);
3208
3209     /* U plane */
3210     dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3211     src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
3212     memcpy_pic(dst[1], obj_surface->width / 2,
3213                src[U], obj_image->image.pitches[U],
3214                src_rect->width / 2, src_rect->height / 2);
3215
3216     /* V plane */
3217     dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3218     src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
3219     memcpy_pic(dst[2], obj_surface->width / 2,
3220                src[V], obj_image->image.pitches[V],
3221                src_rect->width / 2, src_rect->height / 2);
3222
3223     if (tiling != I915_TILING_NONE)
3224         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3225     else
3226         dri_bo_unmap(obj_surface->bo);
3227 }
3228
3229 static void
3230 put_image_nv12(struct object_surface *obj_surface,
3231                const VARectangle *dst_rect,
3232                struct object_image *obj_image, uint8_t *image_data,
3233                const VARectangle *src_rect)
3234 {
3235     uint8_t *dst[2], *src[2];
3236     unsigned int tiling, swizzle;
3237
3238     if (!obj_surface->bo)
3239         return;
3240
3241     assert(obj_surface->fourcc);
3242     assert(dst_rect->width == src_rect->width);
3243     assert(dst_rect->height == src_rect->height);
3244     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3245
3246     if (tiling != I915_TILING_NONE)
3247         drm_intel_gem_bo_map_gtt(obj_surface->bo);
3248     else
3249         dri_bo_map(obj_surface->bo, 0);
3250
3251     if (!obj_surface->bo->virtual)
3252         return;
3253
3254     /* Both dest VA image and source surface have NV12 format */
3255     dst[0] = (uint8_t *)obj_surface->bo->virtual;
3256     src[0] = image_data + obj_image->image.offsets[0];
3257     dst[1] = dst[0] + obj_surface->width * obj_surface->height;
3258     src[1] = image_data + obj_image->image.offsets[1];
3259
3260     /* Y plane */
3261     dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
3262     src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
3263     memcpy_pic(dst[0], obj_surface->width,
3264                src[0], obj_image->image.pitches[0],
3265                src_rect->width, src_rect->height);
3266
3267     /* UV plane */
3268     dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
3269     src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
3270     memcpy_pic(dst[1], obj_surface->width,
3271                src[1], obj_image->image.pitches[1],
3272                src_rect->width, src_rect->height / 2);
3273
3274     if (tiling != I915_TILING_NONE)
3275         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3276     else
3277         dri_bo_unmap(obj_surface->bo);
3278 }
3279
3280 static void
3281 put_image_yuy2(struct object_surface *obj_surface,
3282                const VARectangle *dst_rect,
3283                struct object_image *obj_image, uint8_t *image_data,
3284                const VARectangle *src_rect)
3285 {
3286     uint8_t *dst, *src;
3287     unsigned int tiling, swizzle;
3288
3289     if (!obj_surface->bo)
3290         return;
3291
3292     assert(obj_surface->fourcc);
3293     assert(dst_rect->width == src_rect->width);
3294     assert(dst_rect->height == src_rect->height);
3295     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3296
3297     if (tiling != I915_TILING_NONE)
3298         drm_intel_gem_bo_map_gtt(obj_surface->bo);
3299     else
3300         dri_bo_map(obj_surface->bo, 0);
3301
3302     if (!obj_surface->bo->virtual)
3303         return;
3304
3305     /* Both dest VA image and source surface have YUY2 format */
3306     dst = (uint8_t *)obj_surface->bo->virtual;
3307     src = image_data + obj_image->image.offsets[0];
3308
3309     /* YUYV packed plane */
3310     dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
3311     src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
3312     memcpy_pic(dst, obj_surface->width*2,
3313                src, obj_image->image.pitches[0],
3314                src_rect->width*2, src_rect->height);
3315
3316     if (tiling != I915_TILING_NONE)
3317         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3318     else
3319         dri_bo_unmap(obj_surface->bo);
3320 }
3321
3322
3323 static VAStatus
3324 i965_sw_putimage(VADriverContextP ctx,
3325                  VASurfaceID surface,
3326                  VAImageID image,
3327                  int src_x,
3328                  int src_y,
3329                  unsigned int src_width,
3330                  unsigned int src_height,
3331                  int dest_x,
3332                  int dest_y,
3333                  unsigned int dest_width,
3334                  unsigned int dest_height)
3335 {
3336     struct i965_driver_data *i965 = i965_driver_data(ctx);
3337     struct object_surface *obj_surface = SURFACE(surface);
3338
3339     if (!obj_surface)
3340         return VA_STATUS_ERROR_INVALID_SURFACE;
3341
3342     struct object_image *obj_image = IMAGE(image);
3343     if (!obj_image)
3344         return VA_STATUS_ERROR_INVALID_IMAGE;
3345
3346     if (src_x < 0 || src_y < 0)
3347         return VA_STATUS_ERROR_INVALID_PARAMETER;
3348     if (src_x + src_width > obj_image->image.width ||
3349         src_y + src_height > obj_image->image.height)
3350         return VA_STATUS_ERROR_INVALID_PARAMETER;
3351     if (dest_x < 0 || dest_y < 0)
3352         return VA_STATUS_ERROR_INVALID_PARAMETER;
3353     if (dest_x + dest_width > obj_surface->orig_width ||
3354         dest_y + dest_height > obj_surface->orig_height)
3355         return VA_STATUS_ERROR_INVALID_PARAMETER;
3356
3357     /* XXX: don't allow scaling */
3358     if (src_width != dest_width || src_height != dest_height)
3359         return VA_STATUS_ERROR_INVALID_PARAMETER;
3360
3361     if (obj_surface->fourcc) {
3362         /* Don't allow format mismatch */
3363         if (obj_surface->fourcc != obj_image->image.format.fourcc)
3364             return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3365     }
3366
3367     else {
3368         /* VA is surface not used for decoding, use same VA image format */
3369         i965_check_alloc_surface_bo(
3370             ctx,
3371             obj_surface,
3372             0, /* XXX: don't use tiled surface */
3373             obj_image->image.format.fourcc,
3374             get_sampling_from_fourcc (obj_image->image.format.fourcc));
3375     }
3376
3377     VAStatus va_status;
3378     void *image_data = NULL;
3379
3380     va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3381     if (va_status != VA_STATUS_SUCCESS)
3382         return va_status;
3383
3384     VARectangle src_rect, dest_rect;
3385     src_rect.x       = src_x;
3386     src_rect.y       = src_y;
3387     src_rect.width   = src_width;
3388     src_rect.height  = src_height;
3389     dest_rect.x      = dest_x;
3390     dest_rect.y      = dest_y;
3391     dest_rect.width  = dest_width;
3392     dest_rect.height = dest_height;
3393      
3394     switch (obj_image->image.format.fourcc) {
3395     case VA_FOURCC('Y','V','1','2'):
3396     case VA_FOURCC('I','4','2','0'):
3397         put_image_i420(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3398         break;
3399     case VA_FOURCC('N','V','1','2'):
3400         put_image_nv12(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3401         break;
3402     case VA_FOURCC('Y','U','Y','2'):
3403         put_image_yuy2(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3404         break;
3405     default:
3406         va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3407         break;
3408     }
3409
3410     i965_UnmapBuffer(ctx, obj_image->image.buf);
3411     return va_status;
3412 }
3413
3414 static VAStatus 
3415 i965_hw_putimage(VADriverContextP ctx,
3416                  VASurfaceID surface,
3417                  VAImageID image,
3418                  int src_x,
3419                  int src_y,
3420                  unsigned int src_width,
3421                  unsigned int src_height,
3422                  int dest_x,
3423                  int dest_y,
3424                  unsigned int dest_width,
3425                  unsigned int dest_height)
3426 {
3427     struct i965_driver_data *i965 = i965_driver_data(ctx);
3428     struct object_surface *obj_surface = SURFACE(surface);
3429     struct object_image *obj_image = IMAGE(image);
3430     struct i965_surface src_surface, dst_surface;
3431     VAStatus va_status = VA_STATUS_SUCCESS;
3432     VARectangle src_rect, dst_rect;
3433
3434     if (!obj_surface)
3435         return VA_STATUS_ERROR_INVALID_SURFACE;
3436
3437     if (!obj_image || !obj_image->bo)
3438         return VA_STATUS_ERROR_INVALID_IMAGE;
3439
3440     if (src_x < 0 ||
3441         src_y < 0 ||
3442         src_x + src_width > obj_image->image.width ||
3443         src_y + src_height > obj_image->image.height)
3444         return VA_STATUS_ERROR_INVALID_PARAMETER;
3445
3446     if (dest_x < 0 ||
3447         dest_y < 0 ||
3448         dest_x + dest_width > obj_surface->orig_width ||
3449         dest_y + dest_height > obj_surface->orig_height)
3450         return VA_STATUS_ERROR_INVALID_PARAMETER;
3451
3452     if (!obj_surface->bo) {
3453         unsigned int tiling, swizzle;
3454         int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
3455         dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
3456
3457         i965_check_alloc_surface_bo(ctx,
3458                                     obj_surface,
3459                                     !!tiling,
3460                                     obj_image->image.format.fourcc,
3461                                     surface_sampling);
3462     }
3463
3464     assert(obj_surface->fourcc);
3465
3466     src_surface.id = image;
3467     src_surface.type = I965_SURFACE_TYPE_IMAGE;
3468     src_surface.flags = I965_SURFACE_FLAG_FRAME;
3469     src_rect.x = src_x;
3470     src_rect.y = src_y;
3471     src_rect.width = src_width;
3472     src_rect.height = src_height;
3473
3474     dst_surface.id = surface;
3475     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3476     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3477     dst_rect.x = dest_x;
3478     dst_rect.y = dest_y;
3479     dst_rect.width = dest_width;
3480     dst_rect.height = dest_height;
3481
3482     va_status = i965_image_processing(ctx,
3483                                       &src_surface,
3484                                       &src_rect,
3485                                       &dst_surface,
3486                                       &dst_rect);
3487
3488     return  va_status;
3489 }
3490
3491 static VAStatus 
3492 i965_PutImage(VADriverContextP ctx,
3493               VASurfaceID surface,
3494               VAImageID image,
3495               int src_x,
3496               int src_y,
3497               unsigned int src_width,
3498               unsigned int src_height,
3499               int dest_x,
3500               int dest_y,
3501               unsigned int dest_width,
3502               unsigned int dest_height)
3503 {
3504     struct i965_driver_data *i965 = i965_driver_data(ctx);
3505     VAStatus va_status = VA_STATUS_SUCCESS;
3506
3507     if (HAS_ACCELERATED_PUTIMAGE(i965))
3508         va_status = i965_hw_putimage(ctx,
3509                                      surface,
3510                                      image,
3511                                      src_x,
3512                                      src_y,
3513                                      src_width,
3514                                      src_height,
3515                                      dest_x,
3516                                      dest_y,
3517                                      dest_width,
3518                                      dest_height);
3519     else 
3520         va_status = i965_sw_putimage(ctx,
3521                                      surface,
3522                                      image,
3523                                      src_x,
3524                                      src_y,
3525                                      src_width,
3526                                      src_height,
3527                                      dest_x,
3528                                      dest_y,
3529                                      dest_width,
3530                                      dest_height);
3531
3532     return va_status;
3533 }
3534
3535 VAStatus 
3536 i965_PutSurface(VADriverContextP ctx,
3537                 VASurfaceID surface,
3538                 void *draw, /* X Drawable */
3539                 short srcx,
3540                 short srcy,
3541                 unsigned short srcw,
3542                 unsigned short srch,
3543                 short destx,
3544                 short desty,
3545                 unsigned short destw,
3546                 unsigned short desth,
3547                 VARectangle *cliprects, /* client supplied clip list */
3548                 unsigned int number_cliprects, /* number of clip rects in the clip list */
3549                 unsigned int flags) /* de-interlacing flags */
3550 {
3551 #ifdef HAVE_VA_X11
3552     if (IS_VA_X11(ctx)) {
3553         VARectangle src_rect, dst_rect;
3554
3555         src_rect.x      = srcx;
3556         src_rect.y      = srcy;
3557         src_rect.width  = srcw;
3558         src_rect.height = srch;
3559
3560         dst_rect.x      = destx;
3561         dst_rect.y      = desty;
3562         dst_rect.width  = destw;
3563         dst_rect.height = desth;
3564
3565         return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
3566                                     cliprects, number_cliprects, flags);
3567     }
3568 #endif
3569     return VA_STATUS_ERROR_UNIMPLEMENTED;
3570 }
3571
3572 VAStatus 
3573 i965_Terminate(VADriverContextP ctx)
3574 {
3575     struct i965_driver_data *i965 = i965_driver_data(ctx);
3576
3577     if (i965->batch)
3578         intel_batchbuffer_free(i965->batch);
3579
3580     _i965DestroyMutex(&i965->pp_mutex);
3581     _i965DestroyMutex(&i965->render_mutex);
3582
3583 #ifdef HAVE_VA_X11
3584     if (IS_VA_X11(ctx))
3585         i965_output_dri_terminate(ctx);
3586 #endif
3587
3588 #ifdef HAVE_VA_WAYLAND
3589     if (IS_VA_WAYLAND(ctx))
3590         i965_output_wayland_terminate(ctx);
3591 #endif
3592
3593     if (i965_render_terminate(ctx) == False)
3594         return VA_STATUS_ERROR_UNKNOWN;
3595
3596     if (i965_post_processing_terminate(ctx) == False)
3597         return VA_STATUS_ERROR_UNKNOWN;
3598
3599     i965_display_attributes_terminate(ctx);
3600
3601     i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
3602     i965_destroy_heap(&i965->image_heap, i965_destroy_image);
3603     i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
3604     i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
3605     i965_destroy_heap(&i965->context_heap, i965_destroy_context);
3606     i965_destroy_heap(&i965->config_heap, i965_destroy_config);
3607
3608     if (intel_driver_terminate(ctx) == False)
3609         return VA_STATUS_ERROR_UNKNOWN;
3610
3611     free(ctx->pDriverData);
3612     ctx->pDriverData = NULL;
3613
3614     return VA_STATUS_SUCCESS;
3615 }
3616
3617 static VAStatus
3618 i965_BufferInfo(
3619     VADriverContextP ctx,       /* in */
3620     VABufferID buf_id,          /* in */
3621     VABufferType *type,         /* out */
3622     unsigned int *size,         /* out */
3623     unsigned int *num_elements  /* out */
3624 )
3625 {
3626     struct i965_driver_data *i965 = NULL;
3627     struct object_buffer *obj_buffer = NULL;
3628
3629     i965 = i965_driver_data(ctx);
3630     obj_buffer = BUFFER(buf_id);
3631
3632     *type = obj_buffer->type;
3633     *size = obj_buffer->size_element;
3634     *num_elements = obj_buffer->num_elements;
3635
3636     return VA_STATUS_SUCCESS;
3637 }
3638
3639 static VAStatus
3640 i965_LockSurface(
3641     VADriverContextP ctx,           /* in */
3642     VASurfaceID surface,            /* in */
3643     unsigned int *fourcc,           /* out */
3644     unsigned int *luma_stride,      /* out */
3645     unsigned int *chroma_u_stride,  /* out */
3646     unsigned int *chroma_v_stride,  /* out */
3647     unsigned int *luma_offset,      /* out */
3648     unsigned int *chroma_u_offset,  /* out */
3649     unsigned int *chroma_v_offset,  /* out */
3650     unsigned int *buffer_name,      /* out */
3651     void **buffer                   /* out */
3652 )
3653 {
3654     VAStatus vaStatus = VA_STATUS_SUCCESS;
3655     struct i965_driver_data *i965 = i965_driver_data(ctx);
3656     struct object_surface *obj_surface = NULL;
3657     VAImage tmpImage;
3658
3659     assert(fourcc);
3660     assert(luma_stride);
3661     assert(chroma_u_stride);
3662     assert(chroma_v_stride);
3663     assert(luma_offset);
3664     assert(chroma_u_offset);
3665     assert(chroma_v_offset);
3666     assert(buffer_name);
3667     assert(buffer);
3668
3669     tmpImage.image_id = VA_INVALID_ID;
3670
3671     obj_surface = SURFACE(surface);
3672     if (obj_surface == NULL) {
3673         // Surface is absent.
3674         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
3675         goto error;
3676     }
3677
3678     // Lock functionality is absent now.
3679     if (obj_surface->locked_image_id != VA_INVALID_ID) {
3680         // Surface is locked already.
3681         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
3682         goto error;
3683     }
3684
3685     vaStatus = i965_DeriveImage(
3686         ctx,
3687         surface,
3688         &tmpImage);
3689     if (vaStatus != VA_STATUS_SUCCESS) {
3690         goto error;
3691     }
3692
3693     obj_surface->locked_image_id = tmpImage.image_id;
3694
3695     vaStatus = i965_MapBuffer(
3696         ctx,
3697         tmpImage.buf,
3698         buffer);
3699     if (vaStatus != VA_STATUS_SUCCESS) {
3700         goto error;
3701     }
3702
3703     *fourcc = tmpImage.format.fourcc;
3704     *luma_offset = tmpImage.offsets[0];
3705     *luma_stride = tmpImage.pitches[0];
3706     *chroma_u_offset = tmpImage.offsets[1];
3707     *chroma_u_stride = tmpImage.pitches[1];
3708     *chroma_v_offset = tmpImage.offsets[2];
3709     *chroma_v_stride = tmpImage.pitches[2];
3710     *buffer_name = tmpImage.buf;
3711
3712 error:
3713     if (vaStatus != VA_STATUS_SUCCESS) {
3714         buffer = NULL;
3715     }
3716
3717     return vaStatus;
3718 }
3719
3720 static VAStatus
3721 i965_UnlockSurface(
3722     VADriverContextP ctx,   /* in */
3723     VASurfaceID surface     /* in */
3724 )
3725 {
3726     VAStatus vaStatus = VA_STATUS_SUCCESS;
3727     struct i965_driver_data *i965 = i965_driver_data(ctx);
3728     struct object_image *locked_img = NULL;
3729     struct object_surface *obj_surface = NULL;
3730
3731     obj_surface = SURFACE(surface);
3732
3733     if (obj_surface == NULL) {
3734         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is absent
3735         return vaStatus;
3736     }
3737     if (obj_surface->locked_image_id == VA_INVALID_ID) {
3738         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is not locked
3739         return vaStatus;
3740     }
3741
3742     locked_img = IMAGE(obj_surface->locked_image_id);
3743     if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
3744         // Work image was deallocated before i965_UnlockSurface()
3745         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
3746         goto error;
3747     }
3748
3749     vaStatus = i965_UnmapBuffer(
3750         ctx,
3751         locked_img->image.buf);
3752     if (vaStatus != VA_STATUS_SUCCESS) {
3753         goto error;
3754     }
3755
3756     vaStatus = i965_DestroyImage(
3757         ctx,
3758         locked_img->image.image_id);
3759     if (vaStatus != VA_STATUS_SUCCESS) {
3760         goto error;
3761     }
3762
3763     locked_img->image.image_id = VA_INVALID_ID;
3764
3765  error:
3766     obj_surface->locked_image_id = VA_INVALID_ID;
3767
3768     return vaStatus;
3769 }
3770
3771 static VAStatus
3772 i965_GetSurfaceAttributes(
3773     VADriverContextP ctx,
3774     VAConfigID config,
3775     VASurfaceAttrib *attrib_list,
3776     unsigned int num_attribs
3777     )
3778 {
3779     VAStatus vaStatus = VA_STATUS_SUCCESS;
3780     struct i965_driver_data *i965 = i965_driver_data(ctx);
3781     struct object_config *obj_config;
3782     int i;
3783
3784     if (config == VA_INVALID_ID)
3785         return VA_STATUS_ERROR_INVALID_CONFIG;
3786
3787     obj_config = CONFIG(config);
3788
3789     if (obj_config == NULL)
3790         return VA_STATUS_ERROR_INVALID_CONFIG;
3791     
3792     if (attrib_list == NULL || num_attribs == 0)
3793         return VA_STATUS_ERROR_INVALID_PARAMETER;
3794
3795     for (i = 0; i < num_attribs; i++) {
3796         switch (attrib_list[i].type) {
3797         case VASurfaceAttribPixelFormat:
3798             attrib_list[i].value.type = VAGenericValueTypeInteger;
3799             attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
3800
3801             if (attrib_list[i].value.value.i == 0) {
3802                 if (IS_G4X(i965->intel.device_id)) {
3803                     if (obj_config->profile == VAProfileMPEG2Simple ||
3804                         obj_config->profile == VAProfileMPEG2Main) {
3805                         attrib_list[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
3806                     } else {
3807                         assert(0);
3808                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3809                     }
3810                 } else if (IS_IRONLAKE(i965->intel.device_id)) {
3811                     if (obj_config->profile == VAProfileMPEG2Simple ||
3812                         obj_config->profile == VAProfileMPEG2Main) {
3813                         attrib_list[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
3814                     } else if (obj_config->profile == VAProfileH264Baseline ||
3815                                obj_config->profile == VAProfileH264Main ||
3816                                obj_config->profile == VAProfileH264High) {
3817                         attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
3818                     } else if (obj_config->profile == VAProfileNone) {
3819                         attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
3820                     } else {
3821                         assert(0);
3822                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3823                     }
3824                 } else if (IS_GEN6(i965->intel.device_id)) {
3825                     attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');                    
3826                 } else if (IS_GEN7(i965->intel.device_id)) {
3827                     if (obj_config->profile == VAProfileJPEGBaseline)
3828                         attrib_list[i].value.value.i = 0; /* internal format */
3829                     else
3830                         attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
3831                 }
3832             } else {
3833                 if (IS_G4X(i965->intel.device_id)) {
3834                     if (obj_config->profile == VAProfileMPEG2Simple ||
3835                         obj_config->profile == VAProfileMPEG2Main) {
3836                         if (attrib_list[i].value.value.i != VA_FOURCC('I', '4', '2', '0')) {
3837                             attrib_list[i].value.value.i = 0;
3838                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3839                         }
3840                     } else {
3841                         assert(0);
3842                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3843                     }
3844                 } else if (IS_IRONLAKE(i965->intel.device_id)) {
3845                     if (obj_config->profile == VAProfileMPEG2Simple ||
3846                         obj_config->profile == VAProfileMPEG2Main) {
3847                         if (attrib_list[i].value.value.i != VA_FOURCC('I', '4', '2', '0')) {
3848                             attrib_list[i].value.value.i = 0;                            
3849                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3850                         }
3851                     } else if (obj_config->profile == VAProfileH264Baseline ||
3852                                obj_config->profile == VAProfileH264Main ||
3853                                obj_config->profile == VAProfileH264High) {
3854                         if (attrib_list[i].value.value.i != VA_FOURCC('N', 'V', '1', '2')) {
3855                             attrib_list[i].value.value.i = 0;
3856                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3857                         }
3858                     } else if (obj_config->profile == VAProfileNone) {
3859                         switch (attrib_list[i].value.value.i) {
3860                         case VA_FOURCC('N', 'V', '1', '2'):
3861                         case VA_FOURCC('I', '4', '2', '0'):
3862                         case VA_FOURCC('Y', 'V', '1', '2'):
3863                         case VA_FOURCC('Y', 'U', 'Y', '2'):
3864                         case VA_FOURCC('B', 'G', 'R', 'A'):
3865                         case VA_FOURCC('B', 'G', 'R', 'X'):
3866                         case VA_FOURCC('R', 'G', 'B', 'X'):
3867                         case VA_FOURCC('R', 'G', 'B', 'A'):
3868                             break;
3869                         default:
3870                             attrib_list[i].value.value.i = 0;                            
3871                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3872                             break;
3873                         }
3874                     } else {
3875                         assert(0);
3876                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3877                     }
3878                 } else if (IS_GEN6(i965->intel.device_id)) {
3879                     if (obj_config->entrypoint == VAEntrypointEncSlice ||
3880                         obj_config->entrypoint == VAEntrypointVideoProc) {
3881                         switch (attrib_list[i].value.value.i) {
3882                         case VA_FOURCC('N', 'V', '1', '2'):
3883                         case VA_FOURCC('I', '4', '2', '0'):
3884                         case VA_FOURCC('Y', 'V', '1', '2'):
3885                         case VA_FOURCC('Y', 'U', 'Y', '2'):
3886                         case VA_FOURCC('B', 'G', 'R', 'A'):
3887                         case VA_FOURCC('B', 'G', 'R', 'X'):
3888                         case VA_FOURCC('R', 'G', 'B', 'X'):
3889                         case VA_FOURCC('R', 'G', 'B', 'A'):
3890                             break;
3891                         default:
3892                             attrib_list[i].value.value.i = 0;                            
3893                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3894                             break;
3895                         }
3896                     } else {
3897                         if (attrib_list[i].value.value.i != VA_FOURCC('N', 'V', '1', '2')) {
3898                             attrib_list[i].value.value.i = 0;
3899                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3900                         }
3901                     }
3902                 } else if (IS_GEN7(i965->intel.device_id)) {
3903                     if (obj_config->entrypoint == VAEntrypointEncSlice ||
3904                         obj_config->entrypoint == VAEntrypointVideoProc) {
3905                         switch (attrib_list[i].value.value.i) {
3906                         case VA_FOURCC('N', 'V', '1', '2'):
3907                         case VA_FOURCC('I', '4', '2', '0'):
3908                         case VA_FOURCC('Y', 'V', '1', '2'):
3909                             break;
3910                         default:
3911                             attrib_list[i].value.value.i = 0;                            
3912                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3913                             break;
3914                         }
3915                     } else {
3916                         if (obj_config->profile == VAProfileJPEGBaseline) {
3917                             attrib_list[i].value.value.i = 0;   /* JPEG decoding always uses an internal format */
3918                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3919                         } else {
3920                             if (attrib_list[i].value.value.i != VA_FOURCC('N', 'V', '1', '2')) {
3921                                 attrib_list[i].value.value.i = 0;
3922                                 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
3923                             }
3924                         }
3925                     }
3926                 }
3927             }
3928
3929             break;
3930         case VASurfaceAttribMinWidth:
3931             /* FIXME: add support for it later */
3932             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3933             break;
3934         case VASurfaceAttribMaxWidth:
3935             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3936             break;
3937         case VASurfaceAttribMinHeight:
3938             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3939             break;
3940         case VASurfaceAttribMaxHeight:
3941             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3942             break;
3943         default:
3944             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
3945             break;
3946         }
3947     }
3948
3949     return vaStatus;
3950 }
3951
3952 /* 
3953  * Query video processing pipeline 
3954  */
3955 VAStatus i965_QueryVideoProcFilters(
3956     VADriverContextP    ctx,
3957     VAContextID         context,
3958     VAProcFilterType   *filters,
3959     unsigned int       *num_filters
3960     )
3961 {
3962     struct i965_driver_data *const i965 = i965_driver_data(ctx);
3963     unsigned int i = 0;
3964     
3965     if (HAS_VPP(i965)) {
3966         filters[i++] = VAProcFilterNoiseReduction;
3967         filters[i++] = VAProcFilterDeinterlacing;
3968     }
3969
3970     if(IS_HASWELL(i965->intel.device_id)){
3971         filters[i++] = VAProcFilterNone;
3972         filters[i++] = VAProcFilterSharpening;
3973         filters[i++] = VAProcFilterColorBalance;
3974         filters[i++] = VAProcFilterColorStandard;
3975     }
3976
3977     *num_filters = i;
3978
3979     return VA_STATUS_SUCCESS;
3980 }
3981
3982 VAStatus i965_QueryVideoProcFilterCaps(
3983     VADriverContextP    ctx,
3984     VAContextID         context,
3985     VAProcFilterType    type,
3986     void               *filter_caps,
3987     unsigned int       *num_filter_caps
3988     )
3989 {
3990     struct i965_driver_data *const i965 = i965_driver_data(ctx);
3991     unsigned int i = 0;
3992
3993     if (type == VAProcFilterNoiseReduction) {
3994         VAProcFilterCap *cap = filter_caps;
3995
3996         cap->range.min_value = 0.0;
3997         cap->range.max_value = 1.0;
3998         cap->range.default_value = 0.5;
3999         cap->range.step = 0.03125; /* 1.0 / 32 */
4000         i++;
4001     } else if (type == VAProcFilterDeinterlacing) {
4002         VAProcFilterCapDeinterlacing *cap = filter_caps;
4003         
4004         cap->type = VAProcDeinterlacingBob;
4005         i++;
4006         cap++;
4007     }
4008
4009     if(IS_HASWELL(i965->intel.device_id)){
4010        if(type == VAProcFilterColorBalance){
4011          VAProcFilterCapColorBalance *cap = filter_caps;
4012          cap->type = VAProcColorBalanceHue;
4013          cap->range.min_value = -180.0;
4014          cap->range.max_value = 180.0;
4015          cap->range.default_value = 0.0;
4016          cap->range.step = 1.0; 
4017          i++;
4018          cap ++; 
4019  
4020          cap->type = VAProcColorBalanceSaturation;
4021          cap->range.min_value = 0.0;
4022          cap->range.max_value = 10.0;
4023          cap->range.default_value = 0.0;
4024          cap->range.step = 0.1; 
4025          i++;
4026          cap ++; 
4027  
4028          cap->type = VAProcColorBalanceBrightness;
4029          cap->range.min_value = -100.0;
4030          cap->range.max_value = 100.0;
4031          cap->range.default_value = 0.0;
4032          cap->range.step = 1.0; 
4033          i++;
4034          cap ++; 
4035  
4036          cap->type = VAProcColorBalanceContrast;
4037          cap->range.min_value = 0.0;
4038          cap->range.max_value = 10.0;
4039          cap->range.default_value = 0.0;
4040          cap->range.step = 0.1; 
4041          i++;
4042          cap ++; 
4043       }
4044     }
4045
4046
4047     *num_filter_caps = i;
4048
4049     return VA_STATUS_SUCCESS;
4050 }
4051
4052 static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
4053     VAProcColorStandardBT601,
4054 };
4055
4056 static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
4057     VAProcColorStandardBT601,
4058 };
4059
4060 VAStatus i965_QueryVideoProcPipelineCaps(
4061     VADriverContextP ctx,
4062     VAContextID context,
4063     VABufferID *filters,
4064     unsigned int num_filters,
4065     VAProcPipelineCaps *pipeline_cap     /* out */
4066     )
4067 {
4068     struct i965_driver_data * const i965 = i965_driver_data(ctx);
4069     unsigned int i = 0;
4070
4071     pipeline_cap->pipeline_flags = 0;
4072     pipeline_cap->filter_flags = 0;
4073     pipeline_cap->num_forward_references = 0;
4074     pipeline_cap->num_backward_references = 0;
4075     pipeline_cap->num_input_color_standards = 1;
4076     pipeline_cap->input_color_standards = vpp_input_color_standards;
4077     pipeline_cap->num_output_color_standards = 1;
4078     pipeline_cap->output_color_standards = vpp_output_color_standards;
4079
4080     for (i = 0; i < num_filters; i++) {
4081         struct object_buffer *obj_buffer = BUFFER(filters[i]);
4082         VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
4083
4084         if (base->type == VAProcFilterNoiseReduction) {
4085             VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
4086             (void)denoise;
4087         } else if (base->type == VAProcFilterDeinterlacing) {
4088             VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
4089
4090             assert(deint->algorithm == VAProcDeinterlacingWeave ||
4091                    deint->algorithm == VAProcDeinterlacingBob);
4092         }
4093     }
4094
4095     return VA_STATUS_SUCCESS;
4096 }
4097
4098 VAStatus DLL_EXPORT
4099 VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
4100
4101 VAStatus 
4102 VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
4103 {
4104     struct VADriverVTable * const vtable = ctx->vtable;
4105     struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
4106
4107     struct i965_driver_data *i965;
4108     int result;
4109
4110     ctx->version_major = VA_MAJOR_VERSION;
4111     ctx->version_minor = VA_MINOR_VERSION;
4112     ctx->max_profiles = I965_MAX_PROFILES;
4113     ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
4114     ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
4115     ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
4116     ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
4117     ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
4118
4119     vtable->vaTerminate = i965_Terminate;
4120     vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
4121     vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
4122     vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
4123     vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
4124     vtable->vaCreateConfig = i965_CreateConfig;
4125     vtable->vaDestroyConfig = i965_DestroyConfig;
4126     vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
4127     vtable->vaCreateSurfaces = i965_CreateSurfaces;
4128     vtable->vaDestroySurfaces = i965_DestroySurfaces;
4129     vtable->vaCreateContext = i965_CreateContext;
4130     vtable->vaDestroyContext = i965_DestroyContext;
4131     vtable->vaCreateBuffer = i965_CreateBuffer;
4132     vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
4133     vtable->vaMapBuffer = i965_MapBuffer;
4134     vtable->vaUnmapBuffer = i965_UnmapBuffer;
4135     vtable->vaDestroyBuffer = i965_DestroyBuffer;
4136     vtable->vaBeginPicture = i965_BeginPicture;
4137     vtable->vaRenderPicture = i965_RenderPicture;
4138     vtable->vaEndPicture = i965_EndPicture;
4139     vtable->vaSyncSurface = i965_SyncSurface;
4140     vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
4141     vtable->vaPutSurface = i965_PutSurface;
4142     vtable->vaQueryImageFormats = i965_QueryImageFormats;
4143     vtable->vaCreateImage = i965_CreateImage;
4144     vtable->vaDeriveImage = i965_DeriveImage;
4145     vtable->vaDestroyImage = i965_DestroyImage;
4146     vtable->vaSetImagePalette = i965_SetImagePalette;
4147     vtable->vaGetImage = i965_GetImage;
4148     vtable->vaPutImage = i965_PutImage;
4149     vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
4150     vtable->vaCreateSubpicture = i965_CreateSubpicture;
4151     vtable->vaDestroySubpicture = i965_DestroySubpicture;
4152     vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
4153     vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
4154     vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
4155     vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
4156     vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
4157     vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
4158     vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
4159     vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
4160     vtable->vaBufferInfo = i965_BufferInfo;
4161     vtable->vaLockSurface = i965_LockSurface;
4162     vtable->vaUnlockSurface = i965_UnlockSurface;
4163     vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
4164     vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
4165
4166     vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
4167     vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
4168     vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
4169
4170     i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
4171     assert(i965);
4172     ctx->pDriverData = (void *)i965;
4173
4174     result = object_heap_init(&i965->config_heap, 
4175                               sizeof(struct object_config), 
4176                               CONFIG_ID_OFFSET);
4177     assert(result == 0);
4178
4179     result = object_heap_init(&i965->context_heap, 
4180                               sizeof(struct object_context), 
4181                               CONTEXT_ID_OFFSET);
4182     assert(result == 0);
4183
4184     result = object_heap_init(&i965->surface_heap, 
4185                               sizeof(struct object_surface), 
4186                               SURFACE_ID_OFFSET);
4187     assert(result == 0);
4188
4189     result = object_heap_init(&i965->buffer_heap, 
4190                               sizeof(struct object_buffer), 
4191                               BUFFER_ID_OFFSET);
4192     assert(result == 0);
4193
4194     result = object_heap_init(&i965->image_heap, 
4195                               sizeof(struct object_image), 
4196                               IMAGE_ID_OFFSET);
4197     assert(result == 0);
4198
4199     result = object_heap_init(&i965->subpic_heap, 
4200                               sizeof(struct object_subpic), 
4201                               SUBPIC_ID_OFFSET);
4202     assert(result == 0);
4203
4204     sprintf(i965->va_vendor, "%s %s driver - %d.%d.%d",
4205             INTEL_STR_DRIVER_VENDOR,
4206             INTEL_STR_DRIVER_NAME,
4207             INTEL_DRIVER_MAJOR_VERSION,
4208             INTEL_DRIVER_MINOR_VERSION,
4209             INTEL_DRIVER_MICRO_VERSION);
4210
4211     if (INTEL_DRIVER_PRE_VERSION > 0) {
4212         const int len = strlen(i965->va_vendor);
4213         sprintf(&i965->va_vendor[len], ".pre%d", INTEL_DRIVER_PRE_VERSION);
4214     }
4215
4216     i965->current_context_id = VA_INVALID_ID;
4217
4218     ctx->str_vendor = i965->va_vendor;
4219     
4220     return i965_Init(ctx);
4221 }