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