i965_drv_video: store kernel info in the corresponding context
[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     if (obj_surface->bo == NULL) {
520         struct i965_driver_data *i965 = i965_driver_data(ctx);  
521         
522         obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
523                                        "vaapi surface",
524                                        obj_surface->size,
525                                        0x1000);
526     }
527
528     if (picture_structure == MPEG_FRAME) {
529         i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
530                                        0, w, h, 
531                                        is_dst, 0, 0,
532                                        media_context);
533         i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
534                                        w * h, w / 2, h / 2, 
535                                        is_dst, 0, 0,
536                                        media_context);
537         i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
538                                        w * h + w * h / 4, w / 2, h / 2, 
539                                        is_dst, 0, 0,
540                                        media_context);
541     } else {
542         if (surface == SURFACE_TARGET) {
543             i965_media_mpeg2_surface_state(ctx, 3, obj_surface,
544                                            0, w, h, 
545                                            False, 0, 0,
546                                            media_context);
547             i965_media_mpeg2_surface_state(ctx, 10, obj_surface,
548                                            w * h, w / 2, h / 2, 
549                                            False, 0, 0,
550                                            media_context);
551             i965_media_mpeg2_surface_state(ctx, 11, obj_surface,
552                                            w * h + w * h / 4, w / 2, h / 2, 
553                                            False, 0, 0,
554                                            media_context);
555             if (picture_structure == MPEG_TOP_FIELD) {
556                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
557                                                0, w, h, 
558                                                True, 1, 0,
559                                                media_context);
560                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
561                                                w * h, w / 2, h / 2, 
562                                                True, 1, 0,
563                                                media_context);
564                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
565                                                w * h + w * h / 4, w / 2, h / 2, 
566                                                True, 1, 0,
567                                                media_context);
568             } else {
569                 assert(picture_structure == MPEG_BOTTOM_FIELD);
570                 i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
571                                                0, w, h, 
572                                                True, 1, 1,
573                                                media_context);
574                 i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
575                                                w * h, w / 2, h / 2, 
576                                                True, 1, 1,
577                                                media_context);
578                 i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
579                                                w * h + w * h / 4, w / 2, h / 2, 
580                                                True, 1, 1,
581                                                media_context);
582             }
583         } else {
584             i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
585                                            0, w, h, 
586                                            is_dst, 0, 0,
587                                            media_context);
588             i965_media_mpeg2_surface_state(ctx, base_index + 1, obj_surface,
589                                            w * h, w / 2, h / 2, 
590                                            is_dst, 0, 0,
591                                            media_context);
592             i965_media_mpeg2_surface_state(ctx, base_index + 2, obj_surface,
593                                            w * h + w * h / 4, w / 2, h / 2, 
594                                            is_dst, 0, 0,
595                                            media_context);
596         }
597     }
598 }
599
600 void 
601 i965_media_mpeg2_surfaces_setup(VADriverContextP ctx, 
602                                 struct decode_state *decode_state,
603                                 struct i965_media_context *media_context)
604 {
605     struct i965_driver_data *i965 = i965_driver_data(ctx);  
606     struct object_surface *obj_surface;
607     VAPictureParameterBufferMPEG2 *param;
608
609     assert(decode_state->pic_param && decode_state->pic_param->buffer);
610     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
611
612     obj_surface = SURFACE(decode_state->current_render_target);
613     assert(obj_surface);
614     i965_media_mpeg2_surface_setup(ctx, 0, obj_surface, True,
615                                    param->picture_coding_extension.bits.picture_structure,
616                                    SURFACE_TARGET,
617                                    media_context);
618
619     obj_surface = SURFACE(param->forward_reference_picture);
620     if (!obj_surface) {
621 //        assert(param->picture_coding_type == 1); /* I-picture */
622     } else {
623         i965_media_mpeg2_surface_setup(ctx, 4, obj_surface, False,
624                                        param->picture_coding_extension.bits.picture_structure, 
625                                        SURFACE_FORWARD,
626                                        media_context);
627         obj_surface = SURFACE(param->backward_reference_picture);
628         if (!obj_surface) {
629             assert(param->picture_coding_type == 2); /* P-picture */
630
631             obj_surface = SURFACE(param->forward_reference_picture);
632             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
633                                            param->picture_coding_extension.bits.picture_structure, 
634                                            SURFACE_BACKWARD,
635                                            media_context);
636         } else {
637             assert(param->picture_coding_type == 3); /* B-picture */
638             i965_media_mpeg2_surface_setup(ctx, 7, obj_surface, False,
639                                            param->picture_coding_extension.bits.picture_structure,
640                                            SURFACE_BIDIRECT,
641                                            media_context);
642         }
643     }
644 }
645
646 static void
647 i965_media_mpeg2_binding_table(VADriverContextP ctx, struct i965_media_context *media_context)
648 {
649     int i;
650     unsigned int *binding_table;
651     dri_bo *bo = media_context->binding_table.bo;
652
653     dri_bo_map(bo, 1);
654     assert(bo->virtual);
655     binding_table = bo->virtual;
656     memset(binding_table, 0, bo->size);
657
658     for (i = 0; i < MAX_MEDIA_SURFACES; i++) {
659         if (media_context->surface_state[i].bo) {
660             binding_table[i] = media_context->surface_state[i].bo->offset;
661             dri_bo_emit_reloc(bo,
662                               I915_GEM_DOMAIN_INSTRUCTION, 0,
663                               0,
664                               i * sizeof(*binding_table),
665                               media_context->surface_state[i].bo);
666         }
667     }
668
669     dri_bo_unmap(media_context->binding_table.bo);
670 }
671
672 static void
673 i965_media_mpeg2_vfe_state(VADriverContextP ctx, struct i965_media_context *media_context)
674 {
675     struct i965_vfe_state *vfe_state;
676     dri_bo *bo;
677
678     bo = media_context->vfe_state.bo;
679     dri_bo_map(bo, 1);
680     assert(bo->virtual);
681     vfe_state = bo->virtual;
682     memset(vfe_state, 0, sizeof(*vfe_state));
683     vfe_state->vfe0.extend_vfe_state_present = 1;
684     vfe_state->vfe1.vfe_mode = VFE_VLD_MODE;
685     vfe_state->vfe1.num_urb_entries = media_context->urb.num_vfe_entries;
686     vfe_state->vfe1.children_present = 0;
687     vfe_state->vfe1.urb_entry_alloc_size = media_context->urb.size_vfe_entry - 1;
688     vfe_state->vfe1.max_threads = media_context->urb.num_vfe_entries - 1;
689     vfe_state->vfe2.interface_descriptor_base = 
690         media_context->idrt.bo->offset >> 4; /* reloc */
691     dri_bo_emit_reloc(bo,
692                       I915_GEM_DOMAIN_INSTRUCTION, 0,
693                       0,
694                       offsetof(struct i965_vfe_state, vfe2),
695                       media_context->idrt.bo);
696     dri_bo_unmap(bo);
697 }
698
699 static void 
700 i965_media_mpeg2_interface_descriptor_remap_table(VADriverContextP ctx, struct i965_media_context *media_context)
701 {
702     struct i965_mpeg2_context *i965_mpeg2_context = (struct i965_mpeg2_context *)media_context->private_context;
703     struct i965_interface_descriptor *desc;
704     int i;
705     dri_bo *bo;
706
707     bo = media_context->idrt.bo;
708     dri_bo_map(bo, 1);
709     assert(bo->virtual);
710     desc = bo->virtual;
711
712     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
713         memset(desc, 0, sizeof(*desc));
714         desc->desc0.grf_reg_blocks = 15;
715         desc->desc0.kernel_start_pointer = i965_mpeg2_context->vld_kernels[i].bo->offset >> 6; /* reloc */
716         desc->desc1.const_urb_entry_read_offset = 0;
717         desc->desc1.const_urb_entry_read_len = 30;
718         desc->desc3.binding_table_entry_count = 0;
719         desc->desc3.binding_table_pointer = 
720             media_context->binding_table.bo->offset >> 5; /*reloc */
721
722         dri_bo_emit_reloc(bo,
723                           I915_GEM_DOMAIN_INSTRUCTION, 0,
724                           desc->desc0.grf_reg_blocks,
725                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc0),
726                           i965_mpeg2_context->vld_kernels[i].bo);
727
728         dri_bo_emit_reloc(bo,
729                           I915_GEM_DOMAIN_INSTRUCTION, 0,
730                           desc->desc3.binding_table_entry_count,
731                           i * sizeof(*desc) + offsetof(struct i965_interface_descriptor, desc3),
732                           media_context->binding_table.bo);
733         desc++;
734     }
735
736     dri_bo_unmap(bo);
737 }
738
739 void
740 i965_media_mpeg2_vld_state(VADriverContextP ctx,
741                            struct decode_state *decode_state,
742                            struct i965_media_context *media_context)
743 {
744     struct i965_vld_state *vld_state;
745     VAPictureParameterBufferMPEG2 *param;
746
747     assert(decode_state->pic_param && decode_state->pic_param->buffer);
748     param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
749
750     assert(media_context->extended_state.bo);
751     dri_bo_map(media_context->extended_state.bo, 1);
752     assert(media_context->extended_state.bo->virtual);
753     vld_state = media_context->extended_state.bo->virtual;
754     memset(vld_state, 0, sizeof(*vld_state));
755
756     vld_state->vld0.f_code_0_0 = ((param->f_code >> 12) & 0xf);
757     vld_state->vld0.f_code_0_1 = ((param->f_code >> 8) & 0xf);
758     vld_state->vld0.f_code_1_0 = ((param->f_code >> 4) & 0xf);
759     vld_state->vld0.f_code_1_1 = (param->f_code & 0xf);
760     vld_state->vld0.intra_dc_precision = param->picture_coding_extension.bits.intra_dc_precision;
761     vld_state->vld0.picture_structure = param->picture_coding_extension.bits.picture_structure;
762     vld_state->vld0.top_field_first = param->picture_coding_extension.bits.top_field_first;
763     vld_state->vld0.frame_predict_frame_dct = param->picture_coding_extension.bits.frame_pred_frame_dct;
764     vld_state->vld0.concealment_motion_vector = param->picture_coding_extension.bits.concealment_motion_vectors;
765     vld_state->vld0.quantizer_scale_type = param->picture_coding_extension.bits.q_scale_type;
766     vld_state->vld0.intra_vlc_format = param->picture_coding_extension.bits.intra_vlc_format;
767     vld_state->vld0.scan_order = param->picture_coding_extension.bits.alternate_scan;
768
769     vld_state->vld1.picture_coding_type = param->picture_coding_type;
770
771     if (vld_state->vld0.picture_structure == MPEG_FRAME) {
772         /*frame picture*/ 
773         vld_state->desc_remap_table0.index_0 = FRAME_INTRA;
774         vld_state->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD;
775         vld_state->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD;
776         vld_state->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT; /* dual prime */
777         vld_state->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD;
778         vld_state->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD;
779         vld_state->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT;
780         vld_state->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT;
781
782         vld_state->desc_remap_table1.index_8 = FRAME_INTRA;
783         vld_state->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD;
784         vld_state->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD;
785         vld_state->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT;
786         vld_state->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD;
787         vld_state->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD;
788         vld_state->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT;
789         vld_state->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT;
790     } else {
791         /*field picture*/
792         vld_state->desc_remap_table0.index_0 = FIELD_INTRA;
793         vld_state->desc_remap_table0.index_1 = FIELD_FORWARD;
794         vld_state->desc_remap_table0.index_2 = FIELD_FORWARD_16X8;
795         vld_state->desc_remap_table0.index_3 = FIELD_BIDIRECT; /* dual prime */
796         vld_state->desc_remap_table0.index_4 = FIELD_BACKWARD;
797         vld_state->desc_remap_table0.index_5 = FIELD_BACKWARD_16X8;
798         vld_state->desc_remap_table0.index_6 = FIELD_BIDIRECT;
799         vld_state->desc_remap_table0.index_7 = FIELD_BIDIRECT_16X8;
800     }
801
802     dri_bo_unmap(media_context->extended_state.bo);
803 }
804
805 static void
806 i965_media_mpeg2_upload_constants(VADriverContextP ctx,
807                                   struct decode_state *decode_state,
808                                   struct i965_media_context *media_context)
809 {
810     struct i965_mpeg2_context *i965_mpeg2_context = (struct i965_mpeg2_context *)media_context->private_context;
811     int i, j;
812     unsigned char *constant_buffer;
813     unsigned char *qmx;
814     unsigned int *lib_reloc;
815     int lib_reloc_offset = 0;
816
817     dri_bo_map(media_context->curbe.bo, 1);
818     assert(media_context->curbe.bo->virtual);
819     constant_buffer = media_context->curbe.bo->virtual;
820
821     /* iq_matrix */
822     if (decode_state->iq_matrix && decode_state->iq_matrix->buffer) {
823         VAIQMatrixBufferMPEG2 *iq_matrix = (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
824
825         /* Upload quantisation matrix in row-major order. The mplayer vaapi
826          * patch passes quantisation matrix in zig-zag order to va library.
827          * Do we need a flag in VAIQMatrixBufferMPEG2 to specify the order
828          * of the quantisation matrix?
829          */
830         qmx = constant_buffer;
831         if (iq_matrix->load_intra_quantiser_matrix) {
832             for (i = 0; i < 64; i++) {
833                 j = zigzag_direct[i];
834                 qmx[j] = iq_matrix->intra_quantiser_matrix[i];
835             }
836         }
837
838         qmx = constant_buffer + 64;
839         if (iq_matrix->load_non_intra_quantiser_matrix) {
840             for (i = 0; i < 64; i++) {
841                 j = zigzag_direct[i];
842                 qmx[j] = iq_matrix->non_intra_quantiser_matrix[i];
843             }
844         }
845
846         /* no chroma quantisation matrices for 4:2:0 data */
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     int i, j;
886     VASliceParameterBufferMPEG2 *slice_param;
887
888     for (j = 0; j < decode_state->num_slice_params; j++) {
889         assert(decode_state->slice_params[j] && decode_state->slice_params[j]->buffer);
890         assert(decode_state->slice_datas[j] && decode_state->slice_datas[j]->bo);
891         slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer;
892
893         for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
894             assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
895
896             BEGIN_BATCH(ctx, 6);
897             OUT_BATCH(ctx, CMD_MEDIA_OBJECT | 4);
898             OUT_BATCH(ctx, 0);
899             OUT_BATCH(ctx, slice_param->slice_data_size - (slice_param->macroblock_offset >> 3));
900             OUT_RELOC(ctx, decode_state->slice_datas[j]->bo, 
901                       I915_GEM_DOMAIN_SAMPLER, 0, 
902                       slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3));
903             OUT_BATCH(ctx, 
904                       ((slice_param->slice_horizontal_position << 24) |     
905                        (slice_param->slice_vertical_position << 16) |
906                        (127 << 8) | 
907                        (slice_param->macroblock_offset & 0x7)));
908             OUT_BATCH(ctx, slice_param->quantiser_scale_code << 24);
909             ADVANCE_BATCH(ctx);          
910             slice_param++;
911         }
912     }
913 }
914
915 static void
916 i965_media_mpeg2_free_private_context(void **data)
917 {
918     struct i965_mpeg2_context *i965_mpeg2_context = *data;
919     int i;
920
921     if (i965_mpeg2_context == NULL)
922         return;
923
924     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
925         struct i965_kernel *kernel = &i965_mpeg2_context->vld_kernels[i];
926
927         dri_bo_unreference(kernel->bo);
928         kernel->bo = NULL;
929     }
930
931     free(i965_mpeg2_context);
932     *data = NULL;
933 }
934
935 void 
936 i965_media_mpeg2_decode_init(VADriverContextP ctx, 
937                              struct decode_state *decode_state, 
938                              struct i965_media_context *media_context)
939 {
940     struct i965_driver_data *i965 = i965_driver_data(ctx);
941     dri_bo *bo;
942
943     dri_bo_unreference(media_context->indirect_object.bo);
944     media_context->indirect_object.bo = NULL;
945
946     media_context->extended_state.enabled = 1;
947     dri_bo_unreference(media_context->extended_state.bo);
948     bo = dri_bo_alloc(i965->intel.bufmgr, 
949                       "vld state", 
950                       sizeof(struct i965_vld_state), 32);
951     assert(bo);
952     media_context->extended_state.bo = bo;
953 }
954
955 void 
956 i965_media_mpeg2_dec_context_init(VADriverContextP ctx, struct i965_media_context *media_context)
957 {
958     struct i965_driver_data *i965 = i965_driver_data(ctx);
959     struct i965_mpeg2_context *i965_mpeg2_context;
960     int i;
961
962     i965_mpeg2_context = calloc(1, sizeof(struct i965_mpeg2_context));
963
964     /* kernel */
965     assert(NUM_MPEG2_VLD_KERNELS == (sizeof(mpeg2_vld_kernels_gen4) / 
966                                      sizeof(mpeg2_vld_kernels_gen4[0])));
967     assert(NUM_MPEG2_VLD_KERNELS == (sizeof(mpeg2_vld_kernels_gen5) / 
968                                      sizeof(mpeg2_vld_kernels_gen5[0])));
969     assert(NUM_MPEG2_VLD_KERNELS <= MAX_INTERFACE_DESC);
970
971     if (IS_IRONLAKE(i965->intel.device_id))
972         memcpy(i965_mpeg2_context->vld_kernels, mpeg2_vld_kernels_gen5, sizeof(i965_mpeg2_context->vld_kernels));
973     else
974         memcpy(i965_mpeg2_context->vld_kernels, mpeg2_vld_kernels_gen4, sizeof(i965_mpeg2_context->vld_kernels));
975
976     for (i = 0; i < NUM_MPEG2_VLD_KERNELS; i++) {
977         struct i965_kernel *kernel = &i965_mpeg2_context->vld_kernels[i];
978         kernel->bo = dri_bo_alloc(i965->intel.bufmgr, 
979                                   kernel->name, 
980                                   kernel->size, 64);
981         assert(kernel->bo);
982         dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
983     }
984
985     /* URB */
986     media_context->urb.num_vfe_entries = 28;
987     media_context->urb.size_vfe_entry = 13;
988
989     media_context->urb.num_cs_entries = 1;
990     media_context->urb.size_cs_entry = 16;
991
992     media_context->urb.vfe_start = 0;
993     media_context->urb.cs_start = media_context->urb.vfe_start + 
994         media_context->urb.num_vfe_entries * media_context->urb.size_vfe_entry;
995     assert(media_context->urb.cs_start + 
996            media_context->urb.num_cs_entries * media_context->urb.size_cs_entry <= URB_SIZE((&i965->intel)));
997
998     /* hook functions */
999     media_context->media_states_setup = i965_media_mpeg2_states_setup;
1000     media_context->media_objects = i965_media_mpeg2_objects;
1001     media_context->private_context = i965_mpeg2_context;
1002     media_context->free_private_context = i965_media_mpeg2_free_private_context;
1003 }