db020250adb4734f93ebef682a0475aac8d1f7bb
[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 <stdio.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include <va/va_backend.h>
35
36 #include "intel_batchbuffer.h"
37 #include "intel_driver.h"
38 #include "i965_defines.h"
39 #include "i965_drv_video.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 uint32_t frame_intra_kernel[][4] = {
115    #include "shaders/mpeg2/vld/frame_intra.g4b"
116 };
117 static uint32_t frame_frame_pred_forward_kernel[][4] = {
118    #include "shaders/mpeg2/vld/frame_frame_pred_forward.g4b"
119 };
120 static uint32_t frame_frame_pred_backward_kernel[][4] = {
121    #include "shaders/mpeg2/vld/frame_frame_pred_backward.g4b"
122 };
123 static uint32_t frame_frame_pred_bidirect_kernel[][4] = {
124    #include "shaders/mpeg2/vld/frame_frame_pred_bidirect.g4b"
125 };
126 static uint32_t frame_field_pred_forward_kernel[][4] = {
127    #include "shaders/mpeg2/vld/frame_field_pred_forward.g4b"
128 };
129 static uint32_t frame_field_pred_backward_kernel[][4] = {
130    #include "shaders/mpeg2/vld/frame_field_pred_backward.g4b"
131 };
132 static uint32_t frame_field_pred_bidirect_kernel[][4] = {
133    #include "shaders/mpeg2/vld/frame_field_pred_bidirect.g4b"
134 };
135 static uint32_t lib_kernel[][4] = {
136    #include "shaders/mpeg2/vld/lib.g4b"
137 };
138 /*field picture*/
139 static uint32_t field_intra_kernel[][4] = {
140    #include "shaders/mpeg2/vld/field_intra.g4b"
141 };
142 static uint32_t field_forward_kernel[][4] = {
143    #include "shaders/mpeg2/vld/field_forward.g4b"
144 };
145 static uint32_t field_forward_16x8_kernel[][4] = {
146    #include "shaders/mpeg2/vld/field_forward_16x8.g4b"
147 };
148 static uint32_t field_backward_kernel[][4] = {
149    #include "shaders/mpeg2/vld/field_backward.g4b"
150 };
151 static uint32_t field_backward_16x8_kernel[][4] = {
152    #include "shaders/mpeg2/vld/field_backward_16x8.g4b"
153 };
154 static uint32_t field_bidirect_kernel[][4] = {
155    #include "shaders/mpeg2/vld/field_bidirect.g4b"
156 };
157 static uint32_t field_bidirect_16x8_kernel[][4] = {
158    #include "shaders/mpeg2/vld/field_bidirect_16x8.g4b"
159 };
160
161 static struct media_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 uint32_t frame_intra_kernel_gen5[][4] = {
285    #include "shaders/mpeg2/vld/frame_intra.g4b.gen5"
286 };
287 static uint32_t frame_frame_pred_forward_kernel_gen5[][4] = {
288    #include "shaders/mpeg2/vld/frame_frame_pred_forward.g4b.gen5"
289 };
290 static uint32_t frame_frame_pred_backward_kernel_gen5[][4] = {
291    #include "shaders/mpeg2/vld/frame_frame_pred_backward.g4b.gen5"
292 };
293 static uint32_t frame_frame_pred_bidirect_kernel_gen5[][4] = {
294    #include "shaders/mpeg2/vld/frame_frame_pred_bidirect.g4b.gen5"
295 };
296 static uint32_t frame_field_pred_forward_kernel_gen5[][4] = {
297    #include "shaders/mpeg2/vld/frame_field_pred_forward.g4b.gen5"
298 };
299 static uint32_t frame_field_pred_backward_kernel_gen5[][4] = {
300    #include "shaders/mpeg2/vld/frame_field_pred_backward.g4b.gen5"
301 };
302 static uint32_t frame_field_pred_bidirect_kernel_gen5[][4] = {
303    #include "shaders/mpeg2/vld/frame_field_pred_bidirect.g4b.gen5"
304 };
305 static uint32_t lib_kernel_gen5[][4] = {
306    #include "shaders/mpeg2/vld/lib.g4b.gen5"
307 };
308 /*field picture*/
309 static uint32_t field_intra_kernel_gen5[][4] = {
310    #include "shaders/mpeg2/vld/field_intra.g4b.gen5"
311 };
312 static uint32_t field_forward_kernel_gen5[][4] = {
313    #include "shaders/mpeg2/vld/field_forward.g4b.gen5"
314 };
315 static uint32_t field_forward_16x8_kernel_gen5[][4] = {
316    #include "shaders/mpeg2/vld/field_forward_16x8.g4b.gen5"
317 };
318 static uint32_t field_backward_kernel_gen5[][4] = {
319    #include "shaders/mpeg2/vld/field_backward.g4b.gen5"
320 };
321 static uint32_t field_backward_16x8_kernel_gen5[][4] = {
322    #include "shaders/mpeg2/vld/field_backward_16x8.g4b.gen5"
323 };
324 static uint32_t field_bidirect_kernel_gen5[][4] = {
325    #include "shaders/mpeg2/vld/field_bidirect.g4b.gen5"
326 };
327 static uint32_t field_bidirect_16x8_kernel_gen5[][4] = {
328    #include "shaders/mpeg2/vld/field_bidirect_16x8.g4b.gen5"
329 };
330
331 static struct media_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 struct media_kernel  *mpeg2_vld_kernels = NULL;
454
455 #define NUM_MPEG2_VLD_KERNELS (sizeof(mpeg2_vld_kernels_gen4)/sizeof(mpeg2_vld_kernels_gen4[0]))
456
457 static void
458 i965_media_mpeg2_surface_state(VADriverContextP ctx, 
459                                int index,
460                                struct object_surface *obj_surface,
461                                unsigned long offset, 
462                                int w, int h,
463                                Bool is_dst,
464                                int vert_line_stride,
465                                int vert_line_stride_ofs,
466                                struct i965_media_context *media_context)
467 {
468     struct i965_driver_data *i965 = i965_driver_data(ctx);  
469     struct i965_surface_state *ss;
470     dri_bo *bo;
471     uint32_t write_domain, read_domain;
472
473     bo = dri_bo_alloc(i965->intel.bufmgr, 
474                       "surface state", 
475                       sizeof(struct i965_surface_state), 32);
476     assert(bo);
477     dri_bo_map(bo, 1);
478     assert(bo->virtual);
479     ss = bo->virtual;
480     memset(ss, 0, sizeof(*ss));
481     ss->ss0.surface_type = I965_SURFACE_2D;
482     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_SINT;
483     ss->ss0.vert_line_stride = vert_line_stride;
484     ss->ss0.vert_line_stride_ofs = vert_line_stride_ofs;
485     ss->ss1.base_addr = obj_surface->bo->offset + offset;
486     ss->ss2.width = w - 1;
487     ss->ss2.height = h - 1;
488     ss->ss3.pitch = w - 1;
489
490     if (is_dst) {
491         write_domain = I915_GEM_DOMAIN_RENDER;
492         read_domain = I915_GEM_DOMAIN_RENDER;
493     } else {
494         write_domain = 0;
495         read_domain = I915_GEM_DOMAIN_SAMPLER;
496     }
497
498     dri_bo_emit_reloc(bo,
499                       read_domain, write_domain,
500                       offset,
501                       offsetof(struct i965_surface_state, ss1),
502                       obj_surface->bo);
503     dri_bo_unmap(bo);
504
505     assert(index < MAX_MEDIA_SURFACES);
506 //    assert(media_context->surface_state[index].bo == NULL);
507     media_context->surface_state[index].bo = bo;
508 }
509
510 static void
511 i965_media_mpeg2_surface_setup(VADriverContextP ctx, 
512                                int base_index,
513                                struct object_surface *obj_surface, 
514                                Bool is_dst, 
515                                int picture_structure,
516                                int surface,
517                                struct i965_media_context *media_context)
518 {
519     int w = obj_surface->width;
520     int h = obj_surface->height;
521
522     if (obj_surface->bo == NULL) {
523         struct i965_driver_data *i965 = i965_driver_data(ctx);  
524         
525         obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
526                                        "vaapi surface",
527                                        obj_surface->size,
528                                        0x1000);
529     }
530
531     if (picture_structure == MPEG_FRAME) {
532         i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
533                                        0, w, h, 
534                                        is_dst, 0, 0,
535                                        media_context);
536         i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
537                                        w * h, w / 2, h / 2, 
538                                        is_dst, 0, 0,
539                                        media_context);
540         i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
541                                        w * h + w * h / 4, w / 2, h / 2, 
542                                        is_dst, 0, 0,
543                                        media_context);
544     } else {
545         if (surface == SURFACE_TARGET) {
546             i965_media_mpeg2_surface_state(ctx, 3, obj_surface,
547                                            0, w, h, 
548                                            False, 0, 0,
549                                            media_context);
550             i965_media_mpeg2_surface_state(ctx, 10, obj_surface,
551                                            w * h, w / 2, h / 2, 
552                                            False, 0, 0,
553                                            media_context);
554             i965_media_mpeg2_surface_state(ctx, 11, obj_surface,
555                                            w * h + w * h / 4, w / 2, h / 2, 
556                                            False, 0, 0,
557                                            media_context);
558             if (picture_structure == MPEG_TOP_FIELD) {
559                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
560                                                0, w, h, 
561                                                True, 1, 0,
562                                                media_context);
563                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
564                                                w * h, w / 2, h / 2, 
565                                                True, 1, 0,
566                                                media_context);
567                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
568                                                w * h + w * h / 4, w / 2, h / 2, 
569                                                True, 1, 0,
570                                                media_context);
571             } else {
572                 assert(picture_structure == MPEG_BOTTOM_FIELD);
573                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
574                                                0, w, h, 
575                                                True, 1, 1,
576                                                media_context);
577                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
578                                                w * h, w / 2, h / 2, 
579                                                True, 1, 1,
580                                                media_context);
581                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
582                                                w * h + w * h / 4, w / 2, h / 2, 
583                                                True, 1, 1,
584                                                media_context);
585             }
586         } else {
587             i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
588                                            0, w, h, 
589                                            is_dst, 0, 0,
590                                            media_context);
591             i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
592                                            w * h, w / 2, h / 2, 
593                                            is_dst, 0, 0,
594                                            media_context);
595             i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
596                                            w * h + w * h / 4, w / 2, h / 2, 
597                                            is_dst, 0, 0,
598                                            media_context);
599         }
600     }
601 }
602
603 void 
604 i965_media_mpeg2_surfaces_setup(VADriverContextP ctx, 
605                                 struct decode_state *decode_state,
606                                 struct i965_media_context *media_context)
607 {
608     struct i965_driver_data *i965 = i965_driver_data(ctx);  
609     struct object_surface *obj_surface;
610     VAPictureParameterBufferMPEG2 *param;
611
612     assert(decode_state->pic_param && decode_state->pic_param->buffer);
613     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
614
615     obj_surface = SURFACE(decode_state->current_render_target);
616     assert(obj_surface);
617     i965_media_mpeg2_surface_setup(ctx, 0, obj_surface, True,
618                                    param->picture_coding_extension.bits.picture_structure,
619                                    SURFACE_TARGET,
620                                    media_context);
621
622     obj_surface = SURFACE(param->forward_reference_picture);
623     if (!obj_surface) {
624 //        assert(param->picture_coding_type == 1); /* I-picture */
625     } else {
626         i965_media_mpeg2_surface_setup(ctx, 4, obj_surface, False,
627                                        param->picture_coding_extension.bits.picture_structure, 
628                                        SURFACE_FORWARD,
629                                        media_context);
630         obj_surface = SURFACE(param->backward_reference_picture);
631         if (!obj_surface) {
632             assert(param->picture_coding_type == 2); /* P-picture */
633
634             obj_surface = SURFACE(param->forward_reference_picture);
635             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
636                                            param->picture_coding_extension.bits.picture_structure, 
637                                            SURFACE_BACKWARD,
638                                            media_context);
639         } else {
640             assert(param->picture_coding_type == 3); /* B-picture */
641             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
642                                            param->picture_coding_extension.bits.picture_structure,
643                                            SURFACE_BIDIRECT,
644                                            media_context);
645         }
646     }
647 }
648
649 static void
650 i965_media_mpeg2_binding_table(VADriverContextP ctx, struct i965_media_context *media_context)
651 {
652     int i;
653     unsigned int *binding_table;
654     dri_bo *bo = media_context->binding_table.bo;
655
656     dri_bo_map(bo, 1);
657     assert(bo->virtual);
658     binding_table = bo->virtual;
659     memset(binding_table, 0, bo->size);
660
661     for (i = 0; i < MAX_MEDIA_SURFACES; i++) {
662         if (media_context->surface_state[i].bo) {
663             binding_table[i] = media_context->surface_state[i].bo->offset;
664             dri_bo_emit_reloc(bo,
665                               I915_GEM_DOMAIN_INSTRUCTION, 0,
666                               0,
667                               i * sizeof(*binding_table),
668                               media_context->surface_state[i].bo);
669         }
670     }
671
672     dri_bo_unmap(media_context->binding_table.bo);
673 }
674
675 static void
676 i965_media_mpeg2_vfe_state(VADriverContextP ctx, struct i965_media_context *media_context)
677 {
678     struct i965_vfe_state *vfe_state;
679     dri_bo *bo;
680
681     bo = media_context->vfe_state.bo;
682     dri_bo_map(bo, 1);
683     assert(bo->virtual);
684     vfe_state = bo->virtual;
685     memset(vfe_state, 0, sizeof(*vfe_state));
686     vfe_state->vfe0.extend_vfe_state_present = 1;
687     vfe_state->vfe1.vfe_mode = VFE_VLD_MODE;
688     vfe_state->vfe1.num_urb_entries = media_context->urb.num_vfe_entries;
689     vfe_state->vfe1.children_present = 0;
690     vfe_state->vfe1.urb_entry_alloc_size = media_context->urb.size_vfe_entry - 1;
691     vfe_state->vfe1.max_threads = media_context->urb.num_vfe_entries - 1;
692     vfe_state->vfe2.interface_descriptor_base = 
693         media_context->idrt.bo->offset >> 4; /* reloc */
694     dri_bo_emit_reloc(bo,
695                       I915_GEM_DOMAIN_INSTRUCTION, 0,
696                       0,
697                       offsetof(struct i965_vfe_state, vfe2),
698                       media_context->idrt.bo);
699     dri_bo_unmap(bo);
700 }
701
702 static void 
703 i965_media_mpeg2_interface_descriptor_remap_table(VADriverContextP ctx, struct i965_media_context *media_context)
704 {
705     struct i965_interface_descriptor *desc;
706     int i;
707     dri_bo *bo;
708
709     bo = media_context->idrt.bo;
710     dri_bo_map(bo, 1);
711     assert(bo->virtual);
712     desc = bo->virtual;
713
714     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
715         memset(desc, 0, sizeof(*desc));
716         desc->desc0.grf_reg_blocks = 15;
717         desc->desc0.kernel_start_pointer = mpeg2_vld_kernels[i].bo->offset >> 6; /* reloc */
718         desc->desc1.const_urb_entry_read_offset = 0;
719         desc->desc1.const_urb_entry_read_len = 30;
720         desc->desc3.binding_table_entry_count = 0;
721         desc->desc3.binding_table_pointer = 
722             media_context->binding_table.bo->offset >> 5; /*reloc */
723
724         dri_bo_emit_reloc(bo,
725                           I915_GEM_DOMAIN_INSTRUCTION, 0,
726                           desc->desc0.grf_reg_blocks,
727                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc0),
728                           mpeg2_vld_kernels[i].bo);
729
730         dri_bo_emit_reloc(bo,
731                           I915_GEM_DOMAIN_INSTRUCTION, 0,
732                           desc->desc3.binding_table_entry_count,
733                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc3),
734                           media_context->binding_table.bo);
735         desc++;
736     }
737
738     dri_bo_unmap(bo);
739 }
740
741 void
742 i965_media_mpeg2_vld_state(VADriverContextP ctx,
743                            struct decode_state *decode_state,
744                            struct i965_media_context *media_context)
745 {
746     struct i965_vld_state *vld_state;
747     VAPictureParameterBufferMPEG2 *param;
748
749     assert(decode_state->pic_param && decode_state->pic_param->buffer);
750     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
751
752     assert(media_context->extended_state.bo);
753     dri_bo_map(media_context->extended_state.bo, 1);
754     assert(media_context->extended_state.bo->virtual);
755     vld_state = media_context->extended_state.bo->virtual;
756     memset(vld_state, 0, sizeof(*vld_state));
757
758     vld_state->vld0.f_code_0_0 = ((param->f_code >> 12) & 0xf);
759     vld_state->vld0.f_code_0_1 = ((param->f_code >> 8) & 0xf);
760     vld_state->vld0.f_code_1_0 = ((param->f_code >> 4) & 0xf);
761     vld_state->vld0.f_code_1_1 = (param->f_code & 0xf);
762     vld_state->vld0.intra_dc_precision = param->picture_coding_extension.bits.intra_dc_precision;
763     vld_state->vld0.picture_structure = param->picture_coding_extension.bits.picture_structure;
764     vld_state->vld0.top_field_first = param->picture_coding_extension.bits.top_field_first;
765     vld_state->vld0.frame_predict_frame_dct = param->picture_coding_extension.bits.frame_pred_frame_dct;
766     vld_state->vld0.concealment_motion_vector = param->picture_coding_extension.bits.concealment_motion_vectors;
767     vld_state->vld0.quantizer_scale_type = param->picture_coding_extension.bits.q_scale_type;
768     vld_state->vld0.intra_vlc_format = param->picture_coding_extension.bits.intra_vlc_format;
769     vld_state->vld0.scan_order = param->picture_coding_extension.bits.alternate_scan;
770
771     vld_state->vld1.picture_coding_type = param->picture_coding_type;
772
773     if (vld_state->vld0.picture_structure == MPEG_FRAME) {
774         /*frame picture*/ 
775         vld_state->desc_remap_table0.index_0 = FRAME_INTRA;
776         vld_state->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD;
777         vld_state->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD;
778         vld_state->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT; /* dual prime */
779         vld_state->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD;
780         vld_state->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD;
781         vld_state->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT;
782         vld_state->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT;
783
784         vld_state->desc_remap_table1.index_8 = FRAME_INTRA;
785         vld_state->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD;
786         vld_state->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD;
787         vld_state->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT;
788         vld_state->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD;
789         vld_state->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD;
790         vld_state->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT;
791         vld_state->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT;
792     } else {
793         /*field picture*/
794         vld_state->desc_remap_table0.index_0 = FIELD_INTRA;
795         vld_state->desc_remap_table0.index_1 = FIELD_FORWARD;
796         vld_state->desc_remap_table0.index_2 = FIELD_FORWARD_16X8;
797         vld_state->desc_remap_table0.index_3 = FIELD_BIDIRECT; /* dual prime */
798         vld_state->desc_remap_table0.index_4 = FIELD_BACKWARD;
799         vld_state->desc_remap_table0.index_5 = FIELD_BACKWARD_16X8;
800         vld_state->desc_remap_table0.index_6 = FIELD_BIDIRECT;
801         vld_state->desc_remap_table0.index_7 = FIELD_BIDIRECT_16X8;
802     }
803
804     dri_bo_unmap(media_context->extended_state.bo);
805 }
806
807 static void
808 i965_media_mpeg2_upload_constants(VADriverContextP ctx,
809                                   struct decode_state *decode_state,
810                                   struct i965_media_context *media_context)
811 {
812     int i, j;
813     unsigned char *constant_buffer;
814     unsigned char *qmx;
815     unsigned int *lib_reloc;
816     int lib_reloc_offset = 0;
817
818     dri_bo_map(media_context->curbe.bo, 1);
819     assert(media_context->curbe.bo->virtual);
820     constant_buffer = media_context->curbe.bo->virtual;
821
822     /* iq_matrix */
823     if (decode_state->iq_matrix && decode_state->iq_matrix->buffer) {
824         VAIQMatrixBufferMPEG2 *iq_matrix = (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
825
826         /* Upload quantisation matrix in row-major order. The mplayer vaapi
827          * patch passes quantisation matrix in zig-zag order to va library.
828          * Do we need a flag in VAIQMatrixBufferMPEG2 to specify the order
829          * of the quantisation matrix?
830          */
831         qmx = constant_buffer;
832         if (iq_matrix->load_intra_quantiser_matrix) {
833             for (i = 0; i < 64; i++) {
834                 j = zigzag_direct[i];
835                 qmx[j] = iq_matrix->intra_quantiser_matrix[i];
836             }
837         }
838
839         qmx = constant_buffer + 64;
840         if (iq_matrix->load_non_intra_quantiser_matrix) {
841             for (i = 0; i < 64; i++) {
842                 j = zigzag_direct[i];
843                 qmx[j] = iq_matrix->non_intra_quantiser_matrix[i];
844             }
845         }
846
847         /* no chroma quantisation matrices for 4:2:0 data */
848     }
849
850     /* idct table */
851     memcpy(constant_buffer + 128, idct_table, sizeof(idct_table));
852
853     /* idct lib reloc */
854     lib_reloc_offset = 128 + sizeof(idct_table);
855     lib_reloc = (unsigned int *)(constant_buffer + lib_reloc_offset);
856     for (i = 0; i < 8; i++) {
857         lib_reloc[i] = mpeg2_vld_kernels[LIB_INTERFACE].bo->offset;
858         dri_bo_emit_reloc(media_context->curbe.bo,
859                           I915_GEM_DOMAIN_INSTRUCTION, 0,
860                           0,
861                           lib_reloc_offset + i * sizeof(unsigned int),
862                           mpeg2_vld_kernels[LIB_INTERFACE].bo);
863     }
864
865     dri_bo_unmap(media_context->curbe.bo);
866 }
867
868 static void
869 i965_media_mpeg2_states_setup(VADriverContextP ctx, 
870                               struct decode_state *decode_state, 
871                               struct i965_media_context *media_context)
872 {
873     i965_media_mpeg2_surfaces_setup(ctx, decode_state, media_context);
874     i965_media_mpeg2_binding_table(ctx, media_context);
875     i965_media_mpeg2_interface_descriptor_remap_table(ctx, media_context);
876     i965_media_mpeg2_vld_state(ctx, decode_state, media_context);
877     i965_media_mpeg2_vfe_state(ctx, media_context);
878     i965_media_mpeg2_upload_constants(ctx, decode_state, media_context);
879 }
880
881 static void
882 i965_media_mpeg2_objects(VADriverContextP ctx, 
883                          struct decode_state *decode_state,
884                          struct i965_media_context *media_context)
885 {
886     int i, j;
887     VASliceParameterBufferMPEG2 *slice_param;
888
889     for (j = 0; j < decode_state->num_slice_params; j++) {
890         assert(decode_state->slice_params[j] && decode_state->slice_params[j]->buffer);
891         assert(decode_state->slice_datas[j] && decode_state->slice_datas[j]->bo);
892         slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer;
893
894         for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
895             assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
896
897             BEGIN_BATCH(ctx, 6);
898             OUT_BATCH(ctx, CMD_MEDIA_OBJECT | 4);
899             OUT_BATCH(ctx, 0);
900             OUT_BATCH(ctx, slice_param->slice_data_size - (slice_param->macroblock_offset >> 3));
901             OUT_RELOC(ctx, decode_state->slice_datas[j]->bo, 
902                       I915_GEM_DOMAIN_SAMPLER, 0, 
903                       slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3));
904             OUT_BATCH(ctx, 
905                       ((slice_param->slice_horizontal_position << 24) |     
906                        (slice_param->slice_vertical_position << 16) |
907                        (127 << 8) | 
908                        (slice_param->macroblock_offset & 0x7)));
909             OUT_BATCH(ctx, slice_param->quantiser_scale_code << 24);
910             ADVANCE_BATCH(ctx);          
911             slice_param++;
912         }
913     }
914 }
915
916 static void
917 i965_media_mpeg2_free_private_context(void **data)
918 {
919     int i;
920
921     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
922         struct media_kernel *kernel = &mpeg2_vld_kernels[i];
923
924         dri_bo_unreference(kernel->bo);
925         kernel->bo = NULL;
926     }
927
928     mpeg2_vld_kernels = NULL;
929 }
930
931 void 
932 i965_media_mpeg2_decode_init(VADriverContextP ctx, 
933                              struct decode_state *decode_state, 
934                              struct i965_media_context *media_context)
935 {
936     struct i965_driver_data *i965 = i965_driver_data(ctx);
937     dri_bo *bo;
938
939     dri_bo_unreference(media_context->indirect_object.bo);
940     media_context->indirect_object.bo = NULL;
941
942     media_context->extended_state.enabled = 1;
943     dri_bo_unreference(media_context->extended_state.bo);
944     bo = dri_bo_alloc(i965->intel.bufmgr, 
945                       "vld state", 
946                       sizeof(struct i965_vld_state), 32);
947     assert(bo);
948     media_context->extended_state.bo = bo;
949 }
950
951 void 
952 i965_media_mpeg2_dec_context_init(VADriverContextP ctx, struct i965_media_context *media_context)
953 {
954     struct i965_driver_data *i965 = i965_driver_data(ctx);
955     int i;
956
957     /* kernel */
958     if (mpeg2_vld_kernels == NULL) {
959         assert(NUM_MPEG2_VLD_KERNELS == (sizeof(mpeg2_vld_kernels_gen5) / 
960                                          sizeof(mpeg2_vld_kernels_gen5[0])));
961         assert(NUM_MPEG2_VLD_KERNELS <= MAX_INTERFACE_DESC);
962
963         if (IS_IRONLAKE(i965->intel.device_id))
964             mpeg2_vld_kernels = mpeg2_vld_kernels_gen5;
965         else
966             mpeg2_vld_kernels = mpeg2_vld_kernels_gen4;
967
968         for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
969             struct media_kernel *kernel = &mpeg2_vld_kernels[i];
970             kernel->bo = dri_bo_alloc(i965->intel.bufmgr, 
971                                       kernel->name, 
972                                       kernel->size, 64);
973             assert(kernel->bo);
974             dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
975         }
976     }
977
978     /* URB */
979     media_context->urb.num_vfe_entries = 28;
980     media_context->urb.size_vfe_entry = 13;
981
982     media_context->urb.num_cs_entries = 1;
983     media_context->urb.size_cs_entry = 16;
984
985     media_context->urb.vfe_start = 0;
986     media_context->urb.cs_start = media_context->urb.vfe_start + 
987         media_context->urb.num_vfe_entries * media_context->urb.size_vfe_entry;
988     assert(media_context->urb.cs_start + 
989            media_context->urb.num_cs_entries * media_context->urb.size_cs_entry <= URB_SIZE((&i965->intel)));
990
991     /* hook functions */
992     media_context->media_states_setup = i965_media_mpeg2_states_setup;
993     media_context->media_objects = i965_media_mpeg2_objects;
994     media_context->private_context = i965_mpeg2_context;
995     media_context->free_private_context = i965_media_mpeg2_free_private_context;
996 }