OSDN Git Service

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