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