i965_drv_video: improved MV quality for VME
[platform/upstream/libva.git] / i965_drv_video / i965_media_mpeg2.c
1 /*
2  * Copyright © 2009 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Xiang Haihao <haihao.xiang@intel.com>
26  *    Zou Nan hai <nanhai.zou@intel.com>
27  *
28  */
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <assert.h>
34
35 #include <va/va_backend.h>
36
37 #include "intel_batchbuffer.h"
38 #include "intel_driver.h"
39 #include "i965_defines.h"
40 #include "i965_drv_video.h"
41
42 #include "i965_media.h"
43 #include "i965_media_mpeg2.h"
44
45 #define SURFACE_TARGET      0
46 #define SURFACE_FORWARD     1
47 #define SURFACE_BACKWARD    2
48 #define SURFACE_BIDIRECT    3
49
50 enum interface {
51     FRAME_INTRA = 0,
52     FRAME_FRAME_PRED_FORWARD,
53     FRAME_FRAME_PRED_BACKWARD,
54     FRAME_FRAME_PRED_BIDIRECT,
55     FRAME_FIELD_PRED_FORWARD,
56     FRAME_FIELD_PRED_BACKWARD,
57     FRAME_FIELD_PRED_BIDIRECT,
58     LIB_INTERFACE,
59     FIELD_INTRA,
60     FIELD_FORWARD,
61     FIELD_FORWARD_16X8,
62     FIELD_BACKWARD,
63     FIELD_BACKWARD_16X8,
64     FIELD_BIDIRECT,
65     FIELD_BIDIRECT_16X8
66 };
67
68 /* idct table */
69 #define C0 23170
70 #define C1 22725
71 #define C2 21407
72 #define C3 19266
73 #define C4 16383
74 #define C5 12873
75 #define C6 8867
76 #define C7 4520
77 const uint32_t idct_table[] = {
78     C4, C1, C2, C3, C4, C5, C6, C7,             //g5
79     C4, C1, C2, C3, C4, C5, C6, C7,
80     C4, C3, C6,-C7,-C4,-C1,-C2,-C5,
81     C4, C3, C6,-C7,-C4,-C1,-C2,-C5,
82     C4, C5,-C6,-C1,-C4, C7, C2, C3,
83     C4, C5,-C6,-C1,-C4, C7, C2, C3,
84     C4, C7,-C2,-C5, C4, C3,-C6,-C1,
85     C4, C7,-C2,-C5, C4, C3,-C6,-C1,
86     C4,-C7,-C2, C5, C4,-C3,-C6, C1,
87     C4,-C7,-C2, C5, C4,-C3,-C6, C1,
88     C4,-C5,-C6, C1,-C4,-C7, C2,-C3,
89     C4,-C5,-C6, C1,-C4,-C7, C2,-C3,
90     C4,-C3, C6, C7,-C4, C1,-C2, C5,
91     C4,-C3, C6, C7,-C4, C1,-C2, C5,
92     C4,-C1, C2,-C3, C4,-C5, C6,-C7,
93     C4,-C1, C2,-C3, C4,-C5, C6,-C7              //g20
94 };
95 #undef C0
96 #undef C1
97 #undef C2
98 #undef C3
99 #undef C4
100 #undef C5
101 #undef C6
102 #undef C7
103
104 const uint32_t zigzag_direct[64] = {
105     0,   1,  8, 16,  9,  2,  3, 10,
106     17, 24, 32, 25, 18, 11,  4,  5,
107     12, 19, 26, 33, 40, 48, 41, 34,
108     27, 20, 13,  6,  7, 14, 21, 28,
109     35, 42, 49, 56, 57, 50, 43, 36,
110     29, 22, 15, 23, 30, 37, 44, 51,
111     58, 59, 52, 45, 38, 31, 39, 46,
112     53, 60, 61, 54, 47, 55, 62, 63
113 };
114
115 static const uint32_t frame_intra_kernel[][4] = {
116    #include "shaders/mpeg2/vld/frame_intra.g4b"
117 };
118 static const uint32_t frame_frame_pred_forward_kernel[][4] = {
119    #include "shaders/mpeg2/vld/frame_frame_pred_forward.g4b"
120 };
121 static const uint32_t frame_frame_pred_backward_kernel[][4] = {
122    #include "shaders/mpeg2/vld/frame_frame_pred_backward.g4b"
123 };
124 static const uint32_t frame_frame_pred_bidirect_kernel[][4] = {
125    #include "shaders/mpeg2/vld/frame_frame_pred_bidirect.g4b"
126 };
127 static const uint32_t frame_field_pred_forward_kernel[][4] = {
128    #include "shaders/mpeg2/vld/frame_field_pred_forward.g4b"
129 };
130 static const uint32_t frame_field_pred_backward_kernel[][4] = {
131    #include "shaders/mpeg2/vld/frame_field_pred_backward.g4b"
132 };
133 static const uint32_t frame_field_pred_bidirect_kernel[][4] = {
134    #include "shaders/mpeg2/vld/frame_field_pred_bidirect.g4b"
135 };
136 static const uint32_t lib_kernel[][4] = {
137    #include "shaders/mpeg2/vld/lib.g4b"
138 };
139 /*field picture*/
140 static const uint32_t field_intra_kernel[][4] = {
141    #include "shaders/mpeg2/vld/field_intra.g4b"
142 };
143 static const uint32_t field_forward_kernel[][4] = {
144    #include "shaders/mpeg2/vld/field_forward.g4b"
145 };
146 static const uint32_t field_forward_16x8_kernel[][4] = {
147    #include "shaders/mpeg2/vld/field_forward_16x8.g4b"
148 };
149 static const uint32_t field_backward_kernel[][4] = {
150    #include "shaders/mpeg2/vld/field_backward.g4b"
151 };
152 static const uint32_t field_backward_16x8_kernel[][4] = {
153    #include "shaders/mpeg2/vld/field_backward_16x8.g4b"
154 };
155 static const uint32_t field_bidirect_kernel[][4] = {
156    #include "shaders/mpeg2/vld/field_bidirect.g4b"
157 };
158 static const uint32_t field_bidirect_16x8_kernel[][4] = {
159    #include "shaders/mpeg2/vld/field_bidirect_16x8.g4b"
160 };
161
162 static struct i965_kernel  mpeg2_vld_kernels_gen4[] = {
163     {
164         "FRAME_INTRA",
165         FRAME_INTRA,
166         frame_intra_kernel, 
167         sizeof(frame_intra_kernel),
168         NULL
169     },
170
171     {
172         "FRAME_FRAME_PRED_FORWARD",
173         FRAME_FRAME_PRED_FORWARD,
174         frame_frame_pred_forward_kernel, 
175         sizeof(frame_frame_pred_forward_kernel),
176         NULL
177     },
178
179     {
180         "FRAME_FRAME_PRED_BACKWARD",
181         FRAME_FRAME_PRED_BACKWARD,
182         frame_frame_pred_backward_kernel, 
183         sizeof(frame_frame_pred_backward_kernel),
184         NULL
185     },
186
187     {   
188         "FRAME_FRAME_PRED_BIDIRECT",
189         FRAME_FRAME_PRED_BIDIRECT,
190         frame_frame_pred_bidirect_kernel, 
191         sizeof(frame_frame_pred_bidirect_kernel),
192         NULL
193     },
194
195     {
196         "FRAME_FIELD_PRED_FORWARD",
197         FRAME_FIELD_PRED_FORWARD,
198         frame_field_pred_forward_kernel, 
199         sizeof(frame_field_pred_forward_kernel),
200         NULL
201     },
202
203     {
204         "FRAME_FIELD_PRED_BACKWARD",
205         FRAME_FIELD_PRED_BACKWARD,
206         frame_field_pred_backward_kernel, 
207         sizeof(frame_field_pred_backward_kernel),
208         NULL
209     },
210
211     {
212         "FRAME_FIELD_PRED_BIDIRECT",
213         FRAME_FIELD_PRED_BIDIRECT,
214         frame_field_pred_bidirect_kernel, 
215         sizeof(frame_field_pred_bidirect_kernel),
216         NULL
217     },
218     
219     {   
220         "LIB",
221         LIB_INTERFACE,
222         lib_kernel, 
223         sizeof(lib_kernel),
224         NULL
225     },
226
227     {
228         "FIELD_INTRA",
229         FIELD_INTRA,
230         field_intra_kernel, 
231         sizeof(field_intra_kernel),
232         NULL
233     },
234
235     {
236         "FIELD_FORWARD",
237         FIELD_FORWARD,
238         field_forward_kernel, 
239         sizeof(field_forward_kernel),
240         NULL
241     },
242
243     {
244         "FIELD_FORWARD_16X8",
245         FIELD_FORWARD_16X8,
246         field_forward_16x8_kernel, 
247         sizeof(field_forward_16x8_kernel),
248         NULL
249     },
250
251     {
252         "FIELD_BACKWARD",
253         FIELD_BACKWARD,
254         field_backward_kernel, 
255         sizeof(field_backward_kernel),
256         NULL
257     },
258
259     {
260         "FIELD_BACKWARD_16X8",
261         FIELD_BACKWARD_16X8,
262         field_backward_16x8_kernel, 
263         sizeof(field_backward_16x8_kernel),
264         NULL
265     },
266
267     {
268         "FIELD_BIDIRECT",
269         FIELD_BIDIRECT,
270         field_bidirect_kernel, 
271         sizeof(field_bidirect_kernel),
272         NULL
273     },
274
275     {
276         "FIELD_BIDIRECT_16X8",
277         FIELD_BIDIRECT_16X8,
278         field_bidirect_16x8_kernel, 
279         sizeof(field_bidirect_16x8_kernel),
280         NULL
281     }
282 };
283
284 /* On IRONLAKE */
285 static const uint32_t frame_intra_kernel_gen5[][4] = {
286    #include "shaders/mpeg2/vld/frame_intra.g4b.gen5"
287 };
288 static const uint32_t frame_frame_pred_forward_kernel_gen5[][4] = {
289    #include "shaders/mpeg2/vld/frame_frame_pred_forward.g4b.gen5"
290 };
291 static const uint32_t frame_frame_pred_backward_kernel_gen5[][4] = {
292    #include "shaders/mpeg2/vld/frame_frame_pred_backward.g4b.gen5"
293 };
294 static const uint32_t frame_frame_pred_bidirect_kernel_gen5[][4] = {
295    #include "shaders/mpeg2/vld/frame_frame_pred_bidirect.g4b.gen5"
296 };
297 static const uint32_t frame_field_pred_forward_kernel_gen5[][4] = {
298    #include "shaders/mpeg2/vld/frame_field_pred_forward.g4b.gen5"
299 };
300 static const uint32_t frame_field_pred_backward_kernel_gen5[][4] = {
301    #include "shaders/mpeg2/vld/frame_field_pred_backward.g4b.gen5"
302 };
303 static const uint32_t frame_field_pred_bidirect_kernel_gen5[][4] = {
304    #include "shaders/mpeg2/vld/frame_field_pred_bidirect.g4b.gen5"
305 };
306 static const uint32_t lib_kernel_gen5[][4] = {
307    #include "shaders/mpeg2/vld/lib.g4b.gen5"
308 };
309 /*field picture*/
310 static const uint32_t field_intra_kernel_gen5[][4] = {
311    #include "shaders/mpeg2/vld/field_intra.g4b.gen5"
312 };
313 static const uint32_t field_forward_kernel_gen5[][4] = {
314    #include "shaders/mpeg2/vld/field_forward.g4b.gen5"
315 };
316 static const uint32_t field_forward_16x8_kernel_gen5[][4] = {
317    #include "shaders/mpeg2/vld/field_forward_16x8.g4b.gen5"
318 };
319 static const uint32_t field_backward_kernel_gen5[][4] = {
320    #include "shaders/mpeg2/vld/field_backward.g4b.gen5"
321 };
322 static const uint32_t field_backward_16x8_kernel_gen5[][4] = {
323    #include "shaders/mpeg2/vld/field_backward_16x8.g4b.gen5"
324 };
325 static const uint32_t field_bidirect_kernel_gen5[][4] = {
326    #include "shaders/mpeg2/vld/field_bidirect.g4b.gen5"
327 };
328 static const uint32_t field_bidirect_16x8_kernel_gen5[][4] = {
329    #include "shaders/mpeg2/vld/field_bidirect_16x8.g4b.gen5"
330 };
331
332 static struct i965_kernel  mpeg2_vld_kernels_gen5[] = {
333     {
334         "FRAME_INTRA",
335         FRAME_INTRA,
336         frame_intra_kernel_gen5, 
337         sizeof(frame_intra_kernel_gen5),
338         NULL
339     },
340
341     {
342         "FRAME_FRAME_PRED_FORWARD",
343         FRAME_FRAME_PRED_FORWARD,
344         frame_frame_pred_forward_kernel_gen5, 
345         sizeof(frame_frame_pred_forward_kernel_gen5),
346         NULL
347     },
348
349     {
350         "FRAME_FRAME_PRED_BACKWARD",
351         FRAME_FRAME_PRED_BACKWARD,
352         frame_frame_pred_backward_kernel_gen5, 
353         sizeof(frame_frame_pred_backward_kernel_gen5),
354         NULL
355     },
356
357     {   
358         "FRAME_FRAME_PRED_BIDIRECT",
359         FRAME_FRAME_PRED_BIDIRECT,
360         frame_frame_pred_bidirect_kernel_gen5, 
361         sizeof(frame_frame_pred_bidirect_kernel_gen5),
362         NULL
363     },
364
365     {
366         "FRAME_FIELD_PRED_FORWARD",
367         FRAME_FIELD_PRED_FORWARD,
368         frame_field_pred_forward_kernel_gen5, 
369         sizeof(frame_field_pred_forward_kernel_gen5),
370         NULL
371     },
372
373     {
374         "FRAME_FIELD_PRED_BACKWARD",
375         FRAME_FIELD_PRED_BACKWARD,
376         frame_field_pred_backward_kernel_gen5, 
377         sizeof(frame_field_pred_backward_kernel_gen5),
378         NULL
379     },
380
381     {
382         "FRAME_FIELD_PRED_BIDIRECT",
383         FRAME_FIELD_PRED_BIDIRECT,
384         frame_field_pred_bidirect_kernel_gen5, 
385         sizeof(frame_field_pred_bidirect_kernel_gen5),
386         NULL
387     },
388     
389     {   
390         "LIB",
391         LIB_INTERFACE,
392         lib_kernel_gen5, 
393         sizeof(lib_kernel_gen5),
394         NULL
395     },
396
397     {
398         "FIELD_INTRA",
399         FIELD_INTRA,
400         field_intra_kernel_gen5, 
401         sizeof(field_intra_kernel_gen5),
402         NULL
403     },
404
405     {
406         "FIELD_FORWARD",
407         FIELD_FORWARD,
408         field_forward_kernel_gen5, 
409         sizeof(field_forward_kernel_gen5),
410         NULL
411     },
412
413     {
414         "FIELD_FORWARD_16X8",
415         FIELD_FORWARD_16X8,
416         field_forward_16x8_kernel_gen5, 
417         sizeof(field_forward_16x8_kernel_gen5),
418         NULL
419     },
420
421     {
422         "FIELD_BACKWARD",
423         FIELD_BACKWARD,
424         field_backward_kernel_gen5, 
425         sizeof(field_backward_kernel_gen5),
426         NULL
427     },
428
429     {
430         "FIELD_BACKWARD_16X8",
431         FIELD_BACKWARD_16X8,
432         field_backward_16x8_kernel_gen5, 
433         sizeof(field_backward_16x8_kernel_gen5),
434         NULL
435     },
436
437     {
438         "FIELD_BIDIRECT",
439         FIELD_BIDIRECT,
440         field_bidirect_kernel_gen5, 
441         sizeof(field_bidirect_kernel_gen5),
442         NULL
443     },
444
445     {
446         "FIELD_BIDIRECT_16X8",
447         FIELD_BIDIRECT_16X8,
448         field_bidirect_16x8_kernel_gen5, 
449         sizeof(field_bidirect_16x8_kernel_gen5),
450         NULL
451     }
452 };
453
454 static void
455 i965_media_mpeg2_surface_state(VADriverContextP ctx, 
456                                int index,
457                                struct object_surface *obj_surface,
458                                unsigned long offset, 
459                                int w, int h,
460                                Bool is_dst,
461                                int vert_line_stride,
462                                int vert_line_stride_ofs,
463                                struct i965_media_context *media_context)
464 {
465     struct i965_driver_data *i965 = i965_driver_data(ctx);  
466     struct i965_surface_state *ss;
467     dri_bo *bo;
468     uint32_t write_domain, read_domain;
469
470     bo = dri_bo_alloc(i965->intel.bufmgr, 
471                       "surface state", 
472                       sizeof(struct i965_surface_state), 32);
473     assert(bo);
474     dri_bo_map(bo, 1);
475     assert(bo->virtual);
476     ss = bo->virtual;
477     memset(ss, 0, sizeof(*ss));
478     ss->ss0.surface_type = I965_SURFACE_2D;
479     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_SINT;
480     ss->ss0.vert_line_stride = vert_line_stride;
481     ss->ss0.vert_line_stride_ofs = vert_line_stride_ofs;
482     ss->ss1.base_addr = obj_surface->bo->offset + offset;
483     ss->ss2.width = w - 1;
484     ss->ss2.height = h - 1;
485     ss->ss3.pitch = w - 1;
486
487     if (is_dst) {
488         write_domain = I915_GEM_DOMAIN_RENDER;
489         read_domain = I915_GEM_DOMAIN_RENDER;
490     } else {
491         write_domain = 0;
492         read_domain = I915_GEM_DOMAIN_SAMPLER;
493     }
494
495     dri_bo_emit_reloc(bo,
496                       read_domain, write_domain,
497                       offset,
498                       offsetof(struct i965_surface_state, ss1),
499                       obj_surface->bo);
500     dri_bo_unmap(bo);
501
502     assert(index < MAX_MEDIA_SURFACES);
503 //    assert(media_context->surface_state[index].bo == NULL);
504     media_context->surface_state[index].bo = bo;
505 }
506
507 static void
508 i965_media_mpeg2_surface_setup(VADriverContextP ctx, 
509                                int base_index,
510                                struct object_surface *obj_surface, 
511                                Bool is_dst, 
512                                int picture_structure,
513                                int surface,
514                                struct i965_media_context *media_context)
515 {
516     int w = obj_surface->width;
517     int h = obj_surface->height;
518
519     i965_check_alloc_surface_bo(ctx, obj_surface, 0);
520
521     if (picture_structure == MPEG_FRAME) {
522         i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
523                                        0, w, h, 
524                                        is_dst, 0, 0,
525                                        media_context);
526         i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
527                                        w * h, w / 2, h / 2, 
528                                        is_dst, 0, 0,
529                                        media_context);
530         i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
531                                        w * h + w * h / 4, w / 2, h / 2, 
532                                        is_dst, 0, 0,
533                                        media_context);
534     } else {
535         if (surface == SURFACE_TARGET) {
536             i965_media_mpeg2_surface_state(ctx, 3, obj_surface,
537                                            0, w, h, 
538                                            False, 0, 0,
539                                            media_context);
540             i965_media_mpeg2_surface_state(ctx, 10, obj_surface,
541                                            w * h, w / 2, h / 2, 
542                                            False, 0, 0,
543                                            media_context);
544             i965_media_mpeg2_surface_state(ctx, 11, obj_surface,
545                                            w * h + w * h / 4, w / 2, h / 2, 
546                                            False, 0, 0,
547                                            media_context);
548             if (picture_structure == MPEG_TOP_FIELD) {
549                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
550                                                0, w, h, 
551                                                True, 1, 0,
552                                                media_context);
553                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
554                                                w * h, w / 2, h / 2, 
555                                                True, 1, 0,
556                                                media_context);
557                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
558                                                w * h + w * h / 4, w / 2, h / 2, 
559                                                True, 1, 0,
560                                                media_context);
561             } else {
562                 assert(picture_structure == MPEG_BOTTOM_FIELD);
563                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
564                                                0, w, h, 
565                                                True, 1, 1,
566                                                media_context);
567                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
568                                                w * h, w / 2, h / 2, 
569                                                True, 1, 1,
570                                                media_context);
571                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
572                                                w * h + w * h / 4, w / 2, h / 2, 
573                                                True, 1, 1,
574                                                media_context);
575             }
576         } else {
577             i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
578                                            0, w, h, 
579                                            is_dst, 0, 0,
580                                            media_context);
581             i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
582                                            w * h, w / 2, h / 2, 
583                                            is_dst, 0, 0,
584                                            media_context);
585             i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
586                                            w * h + w * h / 4, w / 2, h / 2, 
587                                            is_dst, 0, 0,
588                                            media_context);
589         }
590     }
591 }
592
593 void 
594 i965_media_mpeg2_surfaces_setup(VADriverContextP ctx, 
595                                 struct decode_state *decode_state,
596                                 struct i965_media_context *media_context)
597 {
598     struct i965_driver_data *i965 = i965_driver_data(ctx);  
599     struct object_surface *obj_surface;
600     VAPictureParameterBufferMPEG2 *param;
601
602     assert(decode_state->pic_param && decode_state->pic_param->buffer);
603     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
604
605     obj_surface = SURFACE(decode_state->current_render_target);
606     assert(obj_surface);
607     i965_media_mpeg2_surface_setup(ctx, 0, obj_surface, True,
608                                    param->picture_coding_extension.bits.picture_structure,
609                                    SURFACE_TARGET,
610                                    media_context);
611
612     obj_surface = SURFACE(param->forward_reference_picture);
613     if (!obj_surface) {
614 //        assert(param->picture_coding_type == 1); /* I-picture */
615     } else {
616         i965_media_mpeg2_surface_setup(ctx, 4, obj_surface, False,
617                                        param->picture_coding_extension.bits.picture_structure, 
618                                        SURFACE_FORWARD,
619                                        media_context);
620         obj_surface = SURFACE(param->backward_reference_picture);
621         if (!obj_surface) {
622             assert(param->picture_coding_type == 2); /* P-picture */
623
624             obj_surface = SURFACE(param->forward_reference_picture);
625             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
626                                            param->picture_coding_extension.bits.picture_structure, 
627                                            SURFACE_BACKWARD,
628                                            media_context);
629         } else {
630             assert(param->picture_coding_type == 3); /* B-picture */
631             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
632                                            param->picture_coding_extension.bits.picture_structure,
633                                            SURFACE_BIDIRECT,
634                                            media_context);
635         }
636     }
637 }
638
639 static void
640 i965_media_mpeg2_binding_table(VADriverContextP ctx, struct i965_media_context *media_context)
641 {
642     int i;
643     unsigned int *binding_table;
644     dri_bo *bo = media_context->binding_table.bo;
645
646     dri_bo_map(bo, 1);
647     assert(bo->virtual);
648     binding_table = bo->virtual;
649     memset(binding_table, 0, bo->size);
650
651     for (i = 0; i < MAX_MEDIA_SURFACES; i++) {
652         if (media_context->surface_state[i].bo) {
653             binding_table[i] = media_context->surface_state[i].bo->offset;
654             dri_bo_emit_reloc(bo,
655                               I915_GEM_DOMAIN_INSTRUCTION, 0,
656                               0,
657                               i * sizeof(*binding_table),
658                               media_context->surface_state[i].bo);
659         }
660     }
661
662     dri_bo_unmap(media_context->binding_table.bo);
663 }
664
665 static void
666 i965_media_mpeg2_vfe_state(VADriverContextP ctx, struct i965_media_context *media_context)
667 {
668     struct i965_vfe_state *vfe_state;
669     dri_bo *bo;
670
671     bo = media_context->vfe_state.bo;
672     dri_bo_map(bo, 1);
673     assert(bo->virtual);
674     vfe_state = bo->virtual;
675     memset(vfe_state, 0, sizeof(*vfe_state));
676     vfe_state->vfe0.extend_vfe_state_present = 1;
677     vfe_state->vfe1.vfe_mode = VFE_VLD_MODE;
678     vfe_state->vfe1.num_urb_entries = media_context->urb.num_vfe_entries;
679     vfe_state->vfe1.children_present = 0;
680     vfe_state->vfe1.urb_entry_alloc_size = media_context->urb.size_vfe_entry - 1;
681     vfe_state->vfe1.max_threads = media_context->urb.num_vfe_entries - 1;
682     vfe_state->vfe2.interface_descriptor_base = 
683         media_context->idrt.bo->offset >> 4; /* reloc */
684     dri_bo_emit_reloc(bo,
685                       I915_GEM_DOMAIN_INSTRUCTION, 0,
686                       0,
687                       offsetof(struct i965_vfe_state, vfe2),
688                       media_context->idrt.bo);
689     dri_bo_unmap(bo);
690 }
691
692 static void 
693 i965_media_mpeg2_interface_descriptor_remap_table(VADriverContextP ctx, struct i965_media_context *media_context)
694 {
695     struct i965_mpeg2_context *i965_mpeg2_context = (struct i965_mpeg2_context *)media_context->private_context;
696     struct i965_interface_descriptor *desc;
697     int i;
698     dri_bo *bo;
699
700     bo = media_context->idrt.bo;
701     dri_bo_map(bo, 1);
702     assert(bo->virtual);
703     desc = bo->virtual;
704
705     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
706         memset(desc, 0, sizeof(*desc));
707         desc->desc0.grf_reg_blocks = 15;
708         desc->desc0.kernel_start_pointer = i965_mpeg2_context->vld_kernels[i].bo->offset >> 6; /* reloc */
709         desc->desc1.const_urb_entry_read_offset = 0;
710         desc->desc1.const_urb_entry_read_len = 30;
711         desc->desc3.binding_table_entry_count = 0;
712         desc->desc3.binding_table_pointer = 
713             media_context->binding_table.bo->offset >> 5; /*reloc */
714
715         dri_bo_emit_reloc(bo,
716                           I915_GEM_DOMAIN_INSTRUCTION, 0,
717                           desc->desc0.grf_reg_blocks,
718                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc0),
719                           i965_mpeg2_context->vld_kernels[i].bo);
720
721         dri_bo_emit_reloc(bo,
722                           I915_GEM_DOMAIN_INSTRUCTION, 0,
723                           desc->desc3.binding_table_entry_count,
724                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc3),
725                           media_context->binding_table.bo);
726         desc++;
727     }
728
729     dri_bo_unmap(bo);
730 }
731
732 void
733 i965_media_mpeg2_vld_state(VADriverContextP ctx,
734                            struct decode_state *decode_state,
735                            struct i965_media_context *media_context)
736 {
737     struct i965_vld_state *vld_state;
738     VAPictureParameterBufferMPEG2 *param;
739
740     assert(decode_state->pic_param && decode_state->pic_param->buffer);
741     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
742
743     assert(media_context->extended_state.bo);
744     dri_bo_map(media_context->extended_state.bo, 1);
745     assert(media_context->extended_state.bo->virtual);
746     vld_state = media_context->extended_state.bo->virtual;
747     memset(vld_state, 0, sizeof(*vld_state));
748
749     vld_state->vld0.f_code_0_0 = ((param->f_code >> 12) & 0xf);
750     vld_state->vld0.f_code_0_1 = ((param->f_code >> 8) & 0xf);
751     vld_state->vld0.f_code_1_0 = ((param->f_code >> 4) & 0xf);
752     vld_state->vld0.f_code_1_1 = (param->f_code & 0xf);
753     vld_state->vld0.intra_dc_precision = param->picture_coding_extension.bits.intra_dc_precision;
754     vld_state->vld0.picture_structure = param->picture_coding_extension.bits.picture_structure;
755     vld_state->vld0.top_field_first = param->picture_coding_extension.bits.top_field_first;
756     vld_state->vld0.frame_predict_frame_dct = param->picture_coding_extension.bits.frame_pred_frame_dct;
757     vld_state->vld0.concealment_motion_vector = param->picture_coding_extension.bits.concealment_motion_vectors;
758     vld_state->vld0.quantizer_scale_type = param->picture_coding_extension.bits.q_scale_type;
759     vld_state->vld0.intra_vlc_format = param->picture_coding_extension.bits.intra_vlc_format;
760     vld_state->vld0.scan_order = param->picture_coding_extension.bits.alternate_scan;
761
762     vld_state->vld1.picture_coding_type = param->picture_coding_type;
763
764     if (vld_state->vld0.picture_structure == MPEG_FRAME) {
765         /*frame picture*/ 
766         vld_state->desc_remap_table0.index_0 = FRAME_INTRA;
767         vld_state->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD;
768         vld_state->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD;
769         vld_state->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT; /* dual prime */
770         vld_state->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD;
771         vld_state->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD;
772         vld_state->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT;
773         vld_state->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT;
774
775         vld_state->desc_remap_table1.index_8 = FRAME_INTRA;
776         vld_state->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD;
777         vld_state->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD;
778         vld_state->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT;
779         vld_state->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD;
780         vld_state->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD;
781         vld_state->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT;
782         vld_state->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT;
783     } else {
784         /*field picture*/
785         vld_state->desc_remap_table0.index_0 = FIELD_INTRA;
786         vld_state->desc_remap_table0.index_1 = FIELD_FORWARD;
787         vld_state->desc_remap_table0.index_2 = FIELD_FORWARD_16X8;
788         vld_state->desc_remap_table0.index_3 = FIELD_BIDIRECT; /* dual prime */
789         vld_state->desc_remap_table0.index_4 = FIELD_BACKWARD;
790         vld_state->desc_remap_table0.index_5 = FIELD_BACKWARD_16X8;
791         vld_state->desc_remap_table0.index_6 = FIELD_BIDIRECT;
792         vld_state->desc_remap_table0.index_7 = FIELD_BIDIRECT_16X8;
793     }
794
795     dri_bo_unmap(media_context->extended_state.bo);
796 }
797
798 static void
799 i965_media_mpeg2_upload_constants(VADriverContextP ctx,
800                                   struct decode_state *decode_state,
801                                   struct i965_media_context *media_context)
802 {
803     struct i965_mpeg2_context *i965_mpeg2_context = (struct i965_mpeg2_context *)media_context->private_context;
804     int i, j;
805     unsigned char *constant_buffer;
806     unsigned char *qmx;
807     unsigned int *lib_reloc;
808     int lib_reloc_offset = 0;
809
810     dri_bo_map(media_context->curbe.bo, 1);
811     assert(media_context->curbe.bo->virtual);
812     constant_buffer = media_context->curbe.bo->virtual;
813
814     /* iq_matrix */
815     if (decode_state->iq_matrix && decode_state->iq_matrix->buffer) {
816         VAIQMatrixBufferMPEG2 *iq_matrix = (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
817
818         /* Upload quantisation matrix in row-major order. The mplayer vaapi
819          * patch passes quantisation matrix in zig-zag order to va library.
820          * Do we need a flag in VAIQMatrixBufferMPEG2 to specify the order
821          * of the quantisation matrix?
822          */
823         qmx = constant_buffer;
824         if (iq_matrix->load_intra_quantiser_matrix) {
825             for (i = 0; i < 64; i++) {
826                 j = zigzag_direct[i];
827                 qmx[j] = iq_matrix->intra_quantiser_matrix[i];
828             }
829         }
830
831         qmx = constant_buffer + 64;
832         if (iq_matrix->load_non_intra_quantiser_matrix) {
833             for (i = 0; i < 64; i++) {
834                 j = zigzag_direct[i];
835                 qmx[j] = iq_matrix->non_intra_quantiser_matrix[i];
836             }
837         }
838
839         /* no chroma quantisation matrices for 4:2:0 data */
840     }
841
842     /* idct table */
843     memcpy(constant_buffer + 128, idct_table, sizeof(idct_table));
844
845     /* idct lib reloc */
846     lib_reloc_offset = 128 + sizeof(idct_table);
847     lib_reloc = (unsigned int *)(constant_buffer + lib_reloc_offset);
848     for (i = 0; i < 8; i++) {
849         lib_reloc[i] = i965_mpeg2_context->vld_kernels[LIB_INTERFACE].bo->offset;
850         dri_bo_emit_reloc(media_context->curbe.bo,
851                           I915_GEM_DOMAIN_INSTRUCTION, 0,
852                           0,
853                           lib_reloc_offset + i * sizeof(unsigned int),
854                           i965_mpeg2_context->vld_kernels[LIB_INTERFACE].bo);
855     }
856
857     dri_bo_unmap(media_context->curbe.bo);
858 }
859
860 static void
861 i965_media_mpeg2_states_setup(VADriverContextP ctx, 
862                               struct decode_state *decode_state, 
863                               struct i965_media_context *media_context)
864 {
865     i965_media_mpeg2_surfaces_setup(ctx, decode_state, media_context);
866     i965_media_mpeg2_binding_table(ctx, media_context);
867     i965_media_mpeg2_interface_descriptor_remap_table(ctx, media_context);
868     i965_media_mpeg2_vld_state(ctx, decode_state, media_context);
869     i965_media_mpeg2_vfe_state(ctx, media_context);
870     i965_media_mpeg2_upload_constants(ctx, decode_state, media_context);
871 }
872
873 static void
874 i965_media_mpeg2_objects(VADriverContextP ctx, 
875                          struct decode_state *decode_state,
876                          struct i965_media_context *media_context)
877 {
878     struct intel_batchbuffer *batch = media_context->base.batch;
879     VASliceParameterBufferMPEG2 *slice_param;
880     int i, j;
881
882     for (j = 0; j < decode_state->num_slice_params; j++) {
883         assert(decode_state->slice_params[j] && decode_state->slice_params[j]->buffer);
884         assert(decode_state->slice_datas[j] && decode_state->slice_datas[j]->bo);
885         slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer;
886
887         for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
888             assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
889
890             BEGIN_BATCH(batch, 6);
891             OUT_BATCH(batch, CMD_MEDIA_OBJECT | 4);
892             OUT_BATCH(batch, 0);
893             OUT_BATCH(batch, slice_param->slice_data_size - (slice_param->macroblock_offset >> 3));
894             OUT_RELOC(batch, decode_state->slice_datas[j]->bo, 
895                       I915_GEM_DOMAIN_SAMPLER, 0, 
896                       slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3));
897             OUT_BATCH(batch, 
898                       ((slice_param->slice_horizontal_position << 24) |     
899                        (slice_param->slice_vertical_position << 16) |
900                        (127 << 8) | 
901                        (slice_param->macroblock_offset & 0x7)));
902             OUT_BATCH(batch, slice_param->quantiser_scale_code << 24);
903             ADVANCE_BATCH(batch);          
904             slice_param++;
905         }
906     }
907 }
908
909 static void
910 i965_media_mpeg2_free_private_context(void **data)
911 {
912     struct i965_mpeg2_context *i965_mpeg2_context = *data;
913     int i;
914
915     if (i965_mpeg2_context == NULL)
916         return;
917
918     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
919         struct i965_kernel *kernel = &i965_mpeg2_context->vld_kernels[i];
920
921         dri_bo_unreference(kernel->bo);
922         kernel->bo = NULL;
923     }
924
925     free(i965_mpeg2_context);
926     *data = NULL;
927 }
928
929 void 
930 i965_media_mpeg2_decode_init(VADriverContextP ctx, 
931                              struct decode_state *decode_state, 
932                              struct i965_media_context *media_context)
933 {
934     struct i965_driver_data *i965 = i965_driver_data(ctx);
935     dri_bo *bo;
936
937     dri_bo_unreference(media_context->indirect_object.bo);
938     media_context->indirect_object.bo = NULL;
939
940     media_context->extended_state.enabled = 1;
941     dri_bo_unreference(media_context->extended_state.bo);
942     bo = dri_bo_alloc(i965->intel.bufmgr, 
943                       "vld state", 
944                       sizeof(struct i965_vld_state), 32);
945     assert(bo);
946     media_context->extended_state.bo = bo;
947 }
948
949 void 
950 i965_media_mpeg2_dec_context_init(VADriverContextP ctx, struct i965_media_context *media_context)
951 {
952     struct i965_driver_data *i965 = i965_driver_data(ctx);
953     struct i965_mpeg2_context *i965_mpeg2_context;
954     int i;
955
956     i965_mpeg2_context = calloc(1, sizeof(struct i965_mpeg2_context));
957
958     /* kernel */
959     assert(NUM_MPEG2_VLD_KERNELS == (sizeof(mpeg2_vld_kernels_gen4) / 
960                                      sizeof(mpeg2_vld_kernels_gen4[0])));
961     assert(NUM_MPEG2_VLD_KERNELS == (sizeof(mpeg2_vld_kernels_gen5) / 
962                                      sizeof(mpeg2_vld_kernels_gen5[0])));
963     assert(NUM_MPEG2_VLD_KERNELS <= MAX_INTERFACE_DESC);
964
965     if (IS_IRONLAKE(i965->intel.device_id))
966         memcpy(i965_mpeg2_context->vld_kernels, mpeg2_vld_kernels_gen5, sizeof(i965_mpeg2_context->vld_kernels));
967     else
968         memcpy(i965_mpeg2_context->vld_kernels, mpeg2_vld_kernels_gen4, sizeof(i965_mpeg2_context->vld_kernels));
969
970     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
971         struct i965_kernel *kernel = &i965_mpeg2_context->vld_kernels[i];
972         kernel->bo = dri_bo_alloc(i965->intel.bufmgr, 
973                                   kernel->name, 
974                                   kernel->size, 64);
975         assert(kernel->bo);
976         dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
977     }
978
979     /* URB */
980     media_context->urb.num_vfe_entries = 28;
981     media_context->urb.size_vfe_entry = 13;
982
983     media_context->urb.num_cs_entries = 1;
984     media_context->urb.size_cs_entry = 16;
985
986     media_context->urb.vfe_start = 0;
987     media_context->urb.cs_start = media_context->urb.vfe_start + 
988         media_context->urb.num_vfe_entries * media_context->urb.size_vfe_entry;
989     assert(media_context->urb.cs_start + 
990            media_context->urb.num_cs_entries * media_context->urb.size_cs_entry <= URB_SIZE((&i965->intel)));
991
992     /* hook functions */
993     media_context->media_states_setup = i965_media_mpeg2_states_setup;
994     media_context->media_objects = i965_media_mpeg2_objects;
995     media_context->private_context = i965_mpeg2_context;
996     media_context->free_private_context = i965_media_mpeg2_free_private_context;
997 }