OSDN Git Service

i965_drv_video: add support for H264 on Clarkdale/Arrandale
[android-x86/hardware-intel-common-libva.git] / i965_drv_video / i965_avc_bsd.c
1 /*
2  * Copyright © 2010 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  *
27  */
28 #include <stdio.h>
29 #include <string.h>
30 #include <assert.h>
31
32 #include "va_backend.h"
33
34 #include "intel_batchbuffer.h"
35 #include "intel_driver.h"
36
37 #include "i965_defines.h"
38 #include "i965_drv_video.h"
39 #include "i965_avc_bsd.h"
40 #include "i965_media_h264.h"
41 #include "i965_media.h"
42
43 static void
44 i965_bsd_ind_obj_base_address(VADriverContextP ctx, struct decode_state *decode_state)
45 {
46     dri_bo *ind_bo = decode_state->slice_data->bo;
47
48     BEGIN_BCS_BATCH(ctx, 3);
49     OUT_BCS_BATCH(ctx, CMD_BSD_IND_OBJ_BASE_ADDR | (3 - 2));
50     OUT_BCS_RELOC(ctx, ind_bo,
51                   I915_GEM_DOMAIN_INSTRUCTION, 0,
52                   0);
53     OUT_BCS_BATCH(ctx, 0);
54     ADVANCE_BCS_BATCH(ctx);
55 }
56
57 static void
58 i965_avc_bsd_img_state(VADriverContextP ctx, struct decode_state *decode_state)
59 {
60     int qm_present_flag;
61     int img_struct;
62     int mbaff_frame_flag;
63     unsigned int avc_it_command_header;
64     unsigned int width_in_mbs, height_in_mbs;
65     VAPictureParameterBufferH264 *pic_param;
66
67     if (decode_state->iq_matrix && decode_state->iq_matrix->buffer)
68         qm_present_flag = 1;
69     else
70         qm_present_flag = 0; /* built-in QM matrices */
71
72     assert(decode_state->pic_param && decode_state->pic_param->buffer);
73     pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
74
75     assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
76
77     if (pic_param->CurrPic.flags & VA_PICTURE_H264_TOP_FIELD)
78         img_struct = 1;
79     else if (pic_param->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD)
80         img_struct = 3;
81     else
82         img_struct = 0;
83
84     if ((img_struct & 0x1) == 0x1) {
85         assert(pic_param->pic_fields.bits.field_pic_flag == 0x1);
86     } else {
87         assert(pic_param->pic_fields.bits.field_pic_flag == 0x0);
88     }
89
90     if (pic_param->seq_fields.bits.frame_mbs_only_flag) { /* a frame containing only frame macroblocks */
91         assert(pic_param->seq_fields.bits.mb_adaptive_frame_field_flag == 0);
92         assert(pic_param->pic_fields.bits.field_pic_flag == 0);
93     } else {
94         assert(pic_param->seq_fields.bits.direct_8x8_inference_flag == 1); /* see H.264 spec */
95     }
96
97     mbaff_frame_flag = (pic_param->seq_fields.bits.mb_adaptive_frame_field_flag &&
98                         !pic_param->pic_fields.bits.field_pic_flag);
99
100     width_in_mbs = ((pic_param->picture_width_in_mbs_minus1 + 1) & 0xff);
101     height_in_mbs = ((pic_param->picture_height_in_mbs_minus1 + 1) & 0xff); /* frame height */
102                                                                                
103     assert(!((width_in_mbs * height_in_mbs) & 0x8000)); /* hardware requirement */
104
105     /* BSD unit doesn't support 4:2:2 and 4:4:4 picture */
106     assert(pic_param->seq_fields.bits.chroma_format_idc == 0 || /* monochrome picture */
107            pic_param->seq_fields.bits.chroma_format_idc == 1);  /* 4:2:0 */
108     assert(pic_param->seq_fields.bits.residual_colour_transform_flag == 0); /* only available for 4:4:4 */
109
110     avc_it_command_header = (CMD_MEDIA_OBJECT_EX | (12 - 2));
111
112     BEGIN_BCS_BATCH(ctx, 6);
113     OUT_BCS_BATCH(ctx, CMD_AVC_BSD_IMG_STATE | (6 - 2));
114     OUT_BCS_BATCH(ctx, 
115                   ((width_in_mbs * height_in_mbs) & 0x7fff));
116     OUT_BCS_BATCH(ctx, 
117                   (height_in_mbs << 16) | 
118                   (width_in_mbs << 0));
119     OUT_BCS_BATCH(ctx, 
120                   (pic_param->second_chroma_qp_index_offset << 24) |
121                   (pic_param->chroma_qp_index_offset << 16) | 
122                   (SCAN_RASTER_ORDER << 15) | /* AVC ILDB Data */
123                   (SCAN_SPECIAL_ORDER << 14) | /* AVC IT Command */
124                   (SCAN_RASTER_ORDER << 13) | /* AVC IT Data */
125                   (1 << 12) | /* always 1, hardware requirement */
126                   (qm_present_flag << 10) |
127                   (img_struct << 8) |
128                   (16 << 0)); /* FIXME: always support 16 reference frames ??? */
129     OUT_BCS_BATCH(ctx,
130                   (RESIDUAL_DATA_OFFSET << 24) | /* residual data offset */
131                   (0 << 17) | /* don't overwrite SRT */
132                   (0 << 16) | /* Un-SRT (Unsynchronized Root Thread) */
133                   (0 << 12) | /* FIXME: no 16MV ??? */
134                   (pic_param->seq_fields.bits.chroma_format_idc << 10) |
135                   (1 << 8)  | /* Enable ILDB writing output */
136                   (pic_param->pic_fields.bits.entropy_coding_mode_flag << 7) |
137                   ((!pic_param->pic_fields.bits.reference_pic_flag) << 6) |
138                   (pic_param->pic_fields.bits.constrained_intra_pred_flag << 5) |
139                   (pic_param->seq_fields.bits.direct_8x8_inference_flag << 4) |
140                   (pic_param->pic_fields.bits.transform_8x8_mode_flag << 3) |
141                   (pic_param->seq_fields.bits.frame_mbs_only_flag << 2) |
142                   (mbaff_frame_flag << 1) |
143                   (pic_param->pic_fields.bits.field_pic_flag << 0));
144     OUT_BCS_BATCH(ctx, avc_it_command_header);
145     ADVANCE_BCS_BATCH(ctx);
146 }
147
148 static void
149 i965_avc_bsd_qm_state(VADriverContextP ctx, struct decode_state *decode_state)
150 {
151     int cmd_len;
152     VAIQMatrixBufferH264 *iq_matrix;
153     VAPictureParameterBufferH264 *pic_param;
154
155     if (!decode_state->iq_matrix || !decode_state->iq_matrix->buffer)
156         return;
157
158     iq_matrix = (VAIQMatrixBufferH264 *)decode_state->iq_matrix->buffer;
159
160     assert(decode_state->pic_param && decode_state->pic_param->buffer);
161     pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
162
163     cmd_len = 2 + 6 * 4; /* always load six 4x4 scaling matrices */
164
165     if (pic_param->pic_fields.bits.transform_8x8_mode_flag)
166         cmd_len += 2 * 16; /* load two 8x8 scaling matrices */
167
168     BEGIN_BCS_BATCH(ctx, cmd_len);
169     OUT_BCS_BATCH(ctx, CMD_AVC_BSD_QM_STATE | (cmd_len - 2));
170
171     if (pic_param->pic_fields.bits.transform_8x8_mode_flag)
172         OUT_BCS_BATCH(ctx, 
173                       (0x0  << 8) | /* don't use default built-in matrices */
174                       (0xff << 0)); /* six 4x4 and two 8x8 scaling matrices */
175     else
176         OUT_BCS_BATCH(ctx, 
177                       (0x0  << 8) | /* don't use default built-in matrices */
178                       (0x3f << 0)); /* six 4x4 scaling matrices */
179
180     intel_batchbuffer_data_bcs(ctx, &iq_matrix->ScalingList4x4[0][0], 6 * 4 * 4);
181
182     if (pic_param->pic_fields.bits.transform_8x8_mode_flag)
183         intel_batchbuffer_data_bcs(ctx, &iq_matrix->ScalingList8x8[0][0], 2 * 16 * 4);
184
185     ADVANCE_BCS_BATCH(ctx);
186 }
187
188 static void
189 i965_avc_bsd_slice_state(VADriverContextP ctx, 
190                          VAPictureParameterBufferH264 *pic_param, 
191                          VASliceParameterBufferH264 *slice_param)
192 {
193     struct i965_driver_data *i965 = i965_driver_data(ctx);
194     struct i965_media_state *media_state = &i965->media_state;
195     struct i965_h264_context *i965_h264_context = (struct i965_h264_context *)media_state->private_context;
196     int present_flag, cmd_len, list, j;
197     struct {
198         unsigned char bottom_idc:1;
199         unsigned char frame_store_index:4;
200         unsigned char field_picture:1;
201         unsigned char long_term:1;
202         unsigned char non_exist:1;
203     } refs[32];
204     char weightoffsets[32 * 6];
205
206     /* don't issue SLICE_STATE for intra-prediction decoding */
207     if (slice_param->slice_type == SLICE_TYPE_I)
208         return;
209
210     cmd_len = 2;
211
212     if (slice_param->slice_type == SLICE_TYPE_P) {
213         present_flag = PRESENT_REF_LIST0;
214         cmd_len += 8;
215     } else { 
216         present_flag = PRESENT_REF_LIST0 | PRESENT_REF_LIST1;
217         cmd_len += 16;
218     }
219
220     if (slice_param->luma_weight_l0_flag | slice_param->chroma_weight_l0_flag) {
221         present_flag |= PRESENT_WEIGHT_OFFSET_L0;
222         cmd_len += 48;
223         assert((pic_param->pic_fields.bits.weighted_pred_flag == 1) || /* P slice */
224                (pic_param->pic_fields.bits.weighted_bipred_idc == 1)); /* B slice */
225     }
226
227     if (slice_param->luma_weight_l1_flag | slice_param->chroma_weight_l1_flag) {
228         present_flag |= PRESENT_WEIGHT_OFFSET_L1;
229         cmd_len += 48;
230         assert(slice_param->slice_type == SLICE_TYPE_B);
231         assert(pic_param->pic_fields.bits.weighted_bipred_idc == 1);
232     }
233
234     BEGIN_BCS_BATCH(ctx, cmd_len);
235     OUT_BCS_BATCH(ctx, CMD_AVC_BSD_SLICE_STATE | (cmd_len - 2));
236     OUT_BCS_BATCH(ctx, present_flag);
237
238     for (list = 0; list < 2; list++) {
239         int flag;
240         VAPictureH264 *va_pic;
241
242         if (list == 0) {
243             flag = PRESENT_REF_LIST0;
244             va_pic = slice_param->RefPicList0;
245         } else {
246             flag = PRESENT_REF_LIST1;
247             va_pic = slice_param->RefPicList1;
248         }
249
250         if (!(present_flag & flag))
251             continue;
252
253         for (j = 0; j < 32; j++) {
254             if (va_pic->flags & VA_PICTURE_H264_INVALID) {
255                 refs[j].non_exist = 1;
256                 refs[j].long_term = 1;
257                 refs[j].field_picture = 1;
258                 refs[j].frame_store_index = 0xf;
259                 refs[j].bottom_idc = 1;
260             } else {
261                 int frame_idx;
262                 
263                 for (frame_idx = 0; frame_idx < 16; frame_idx++) {
264                     VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[frame_idx];
265                     
266                     if (!(ref_pic->flags & VA_PICTURE_H264_INVALID)) {
267                         if (ref_pic->picture_id == va_pic->picture_id)
268                             break;
269                     }       
270                 }
271                 
272                 assert(frame_idx < 16);
273                 
274                 refs[j].non_exist = 0;
275                 refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
276                 refs[j].field_picture = !!(va_pic->flags & 
277                                            (VA_PICTURE_H264_TOP_FIELD | 
278                                             VA_PICTURE_H264_BOTTOM_FIELD));
279                 refs[j].frame_store_index = frame_idx;
280                 refs[j].bottom_idc = !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD);
281             }
282
283             va_pic++;
284         }
285         
286         intel_batchbuffer_data_bcs(ctx, refs, sizeof(refs));
287     }
288
289     i965_h264_context->weight128_luma_l0 = 0;
290     i965_h264_context->weight128_luma_l1 = 0;
291     i965_h264_context->weight128_chroma_l0 = 0;
292     i965_h264_context->weight128_chroma_l1 = 0;
293
294     i965_h264_context->weight128_offset0_flag = 0;
295     i965_h264_context->weight128_offset0 = 0;
296
297     if (present_flag & PRESENT_WEIGHT_OFFSET_L0) {
298         for (j = 0; j < 32; j++) {
299             weightoffsets[j * 6 + 0] = slice_param->luma_offset_l0[j];
300             weightoffsets[j * 6 + 1] = slice_param->luma_weight_l0[j];
301             weightoffsets[j * 6 + 2] = slice_param->chroma_offset_l0[j][0];
302             weightoffsets[j * 6 + 3] = slice_param->chroma_weight_l0[j][0];
303             weightoffsets[j * 6 + 4] = slice_param->chroma_offset_l0[j][1];
304             weightoffsets[j * 6 + 5] = slice_param->chroma_weight_l0[j][1];
305
306             if (pic_param->pic_fields.bits.weighted_bipred_idc == 1) {
307                 if (i965_h264_context->use_hw_w128) {
308                     if (slice_param->luma_weight_l0[j] == 128)
309                         i965_h264_context->weight128_luma_l0 |= (1 << j);
310
311                     if (slice_param->chroma_weight_l0[j][0] == 128 ||
312                         slice_param->chroma_weight_l0[j][1] == 128)
313                         i965_h264_context->weight128_chroma_l0 |= (1 << j);
314                 } else {
315                     /* FIXME: workaround for weight 128 */
316                     if (slice_param->luma_weight_l0[j] == 128 ||
317                         slice_param->chroma_weight_l0[j][0] == 128 ||
318                         slice_param->chroma_weight_l0[j][1] == 128)
319                         i965_h264_context->weight128_offset0_flag = 1;
320                 }
321             }
322         }
323
324         intel_batchbuffer_data_bcs(ctx, weightoffsets, sizeof(weightoffsets));
325     }
326
327     if (present_flag & PRESENT_WEIGHT_OFFSET_L1) {
328         for (j = 0; j < 32; j++) {
329             weightoffsets[j * 6 + 0] = slice_param->luma_offset_l1[j];
330             weightoffsets[j * 6 + 1] = slice_param->luma_weight_l1[j];
331             weightoffsets[j * 6 + 2] = slice_param->chroma_offset_l1[j][0];
332             weightoffsets[j * 6 + 3] = slice_param->chroma_weight_l1[j][0];
333             weightoffsets[j * 6 + 4] = slice_param->chroma_offset_l1[j][1];
334             weightoffsets[j * 6 + 5] = slice_param->chroma_weight_l1[j][1];
335
336             if (pic_param->pic_fields.bits.weighted_bipred_idc == 1) {
337                 if (i965_h264_context->use_hw_w128) {
338                     if (slice_param->luma_weight_l1[j] == 128)
339                         i965_h264_context->weight128_luma_l1 |= (1 << j);
340
341                     if (slice_param->chroma_weight_l1[j][0] == 128 ||
342                         slice_param->chroma_weight_l1[j][1] == 128)
343                         i965_h264_context->weight128_chroma_l1 |= (1 << j);
344                 } else {
345                     if (slice_param->luma_weight_l0[j] == 128 ||
346                         slice_param->chroma_weight_l0[j][0] == 128 ||
347                         slice_param->chroma_weight_l0[j][1] == 128)
348                         i965_h264_context->weight128_offset0_flag = 1;
349                 }
350             }
351         }
352
353         intel_batchbuffer_data_bcs(ctx, weightoffsets, sizeof(weightoffsets));
354     }
355
356     ADVANCE_BCS_BATCH(ctx);
357 }
358
359 static void
360 i965_avc_bsd_buf_base_state(VADriverContextP ctx, struct decode_state *decode_state)
361 {
362     struct i965_driver_data *i965 = i965_driver_data(ctx);
363     struct i965_media_state *media_state = &i965->media_state;
364     struct i965_h264_context *i965_h264_context;
365     struct i965_avc_bsd_context *i965_avc_bsd_context;
366     int i;
367     VAPictureParameterBufferH264 *pic_param;
368     VAPictureH264 *va_pic;
369     struct object_surface *obj_surface;
370
371     assert(decode_state->pic_param && decode_state->pic_param->buffer);
372     pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
373
374     assert(media_state->private_context);
375     i965_h264_context = (struct i965_h264_context *)media_state->private_context;
376     i965_avc_bsd_context = &i965_h264_context->i965_avc_bsd_context;
377
378     BEGIN_BCS_BATCH(ctx, 74);
379     OUT_BCS_BATCH(ctx, CMD_AVC_BSD_BUF_BASE_STATE | (74 - 2));
380     OUT_BCS_RELOC(ctx, i965_avc_bsd_context->bsd_raw_store.bo,
381                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
382                   0);
383     OUT_BCS_RELOC(ctx, i965_avc_bsd_context->mpr_row_store.bo,
384                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
385                   0);
386     OUT_BCS_RELOC(ctx, i965_h264_context->avc_it_command_mb_info.bo,
387                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
388                   i965_h264_context->avc_it_command_mb_info.mbs * i965_h264_context->use_avc_hw_scoreboard * MB_CMD_IN_BYTES);
389     OUT_BCS_RELOC(ctx, i965_h264_context->avc_it_data.bo,
390                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
391                   (i965_h264_context->avc_it_data.write_offset << 6));
392     OUT_BCS_RELOC(ctx, i965_avc_bsd_context->ildb_data.bo,
393                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
394                   0);
395
396     for (i = 0; i < 16; i++) {
397         va_pic = &pic_param->ReferenceFrames[i];
398
399         if (!(va_pic->flags & VA_PICTURE_H264_INVALID)) {
400             obj_surface = SURFACE(va_pic->picture_id);
401             assert(obj_surface);
402             OUT_BCS_RELOC(ctx, obj_surface->direct_mv_wr_top_bo,
403                           I915_GEM_DOMAIN_INSTRUCTION, 0,
404                           0);
405
406             if (pic_param->pic_fields.bits.field_pic_flag && 
407                 !pic_param->seq_fields.bits.direct_8x8_inference_flag)
408                 OUT_BCS_RELOC(ctx, obj_surface->direct_mv_wr_bottom_bo,
409                               I915_GEM_DOMAIN_INSTRUCTION, 0,
410                               0);
411             else 
412                 OUT_BCS_RELOC(ctx, obj_surface->direct_mv_wr_top_bo,
413                               I915_GEM_DOMAIN_INSTRUCTION, 0,
414                               0);
415         } else {
416             OUT_BCS_BATCH(ctx, 0);
417             OUT_BCS_BATCH(ctx, 0);
418         }
419     }
420
421     va_pic = &pic_param->CurrPic;
422     assert(!(va_pic->flags & VA_PICTURE_H264_INVALID));
423     obj_surface = SURFACE(va_pic->picture_id);
424     assert(obj_surface);
425     OUT_BCS_RELOC(ctx, obj_surface->direct_mv_wr_top_bo,
426                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
427                   0);
428
429     if (pic_param->pic_fields.bits.field_pic_flag && 
430         !pic_param->seq_fields.bits.direct_8x8_inference_flag)
431         OUT_BCS_RELOC(ctx, obj_surface->direct_mv_wr_bottom_bo,
432                       I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
433                       0);
434     else
435         OUT_BCS_RELOC(ctx, obj_surface->direct_mv_wr_top_bo,
436                       I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
437                       0);
438
439     /* POC List */
440     for (i = 0; i < 16; i++) {
441         va_pic = &pic_param->ReferenceFrames[i];
442         if (!(va_pic->flags & VA_PICTURE_H264_INVALID)) {
443             OUT_BCS_BATCH(ctx, va_pic->TopFieldOrderCnt);
444             OUT_BCS_BATCH(ctx, va_pic->BottomFieldOrderCnt);
445         } else {
446             OUT_BCS_BATCH(ctx, 0);
447             OUT_BCS_BATCH(ctx, 0);
448         }
449     }
450
451     OUT_BCS_BATCH(ctx, va_pic->TopFieldOrderCnt);
452     OUT_BCS_BATCH(ctx, va_pic->BottomFieldOrderCnt);
453
454     ADVANCE_BCS_BATCH(ctx);
455 }
456
457 static void
458 g4x_avc_bsd_object(VADriverContextP ctx, 
459                    struct decode_state *decode_state,
460                    VAPictureParameterBufferH264 *pic_param,
461                    VASliceParameterBufferH264 *slice_param)
462 {
463     int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
464     int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
465
466     if (slice_param) {
467         int encrypted, counter_value, cmd_len;
468         int slice_hor_pos, slice_ver_pos;
469         int num_ref_idx_l0, num_ref_idx_l1;
470         int field_or_mbaff_picture = (pic_param->pic_fields.bits.field_pic_flag ||
471                                       pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
472         int slice_data_bit_offset;
473         int weighted_pred_idc = 0;
474
475         encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
476
477         if (encrypted) {
478             cmd_len = 9;
479             counter_value = 0; /* FIXME: ??? */
480         } else 
481             cmd_len = 8;
482
483         slice_data_bit_offset = slice_param->slice_data_bit_offset;    
484
485         if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC)
486             slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8);
487
488         if (slice_param->slice_type == SLICE_TYPE_I) {
489             assert(slice_param->num_ref_idx_l0_active_minus1 == 0);
490             assert(slice_param->num_ref_idx_l1_active_minus1 == 0);
491             num_ref_idx_l0 = 0;
492             num_ref_idx_l1 = 0;
493         } else if (slice_param->slice_type == SLICE_TYPE_P) {
494             assert(slice_param->num_ref_idx_l1_active_minus1 == 0);
495             num_ref_idx_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
496             num_ref_idx_l1 = 0;
497         } else {
498             num_ref_idx_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
499             num_ref_idx_l1 = slice_param->num_ref_idx_l1_active_minus1 + 1;
500         }
501
502         if (slice_param->slice_type == SLICE_TYPE_P)
503             weighted_pred_idc = pic_param->pic_fields.bits.weighted_pred_flag;
504         else if (slice_param->slice_type == SLICE_TYPE_B)
505             weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc;
506
507         slice_hor_pos = slice_param->first_mb_in_slice % width_in_mbs; 
508         slice_ver_pos = slice_param->first_mb_in_slice / width_in_mbs;
509         slice_ver_pos <<= (1 + field_or_mbaff_picture); /* FIXME: right ??? */
510
511         BEGIN_BCS_BATCH(ctx, cmd_len);
512         OUT_BCS_BATCH(ctx, CMD_AVC_BSD_OBJECT | (cmd_len - 2));
513         OUT_BCS_BATCH(ctx, 
514                       (encrypted << 31) |
515                       ((slice_param->slice_data_size - (slice_data_bit_offset >> 3)) << 0));
516         OUT_BCS_BATCH(ctx, 
517                       (slice_param->slice_data_offset +
518                        (slice_data_bit_offset >> 3)));
519         OUT_BCS_BATCH(ctx, 
520                       (0 << 31) | /* concealment mode: 0->intra 16x16 prediction, 1->inter P Copy */
521                       (0 << 14) | /* ignore BSDPrematureComplete Error handling */
522                       (0 << 13) | /* FIXME: ??? */
523                       (0 << 12) | /* ignore MPR Error handling */
524                       (0 << 10) | /* ignore Entropy Error handling */
525                       (0 << 8)  | /* ignore MB Header Error handling */
526                       (slice_param->slice_type << 0));
527         OUT_BCS_BATCH(ctx, 
528                       (num_ref_idx_l1 << 24) |
529                       (num_ref_idx_l0 << 16) |
530                       (slice_param->chroma_log2_weight_denom << 8) |
531                       (slice_param->luma_log2_weight_denom << 0));
532         OUT_BCS_BATCH(ctx, 
533                       (weighted_pred_idc << 30) |
534                       (slice_param->direct_spatial_mv_pred_flag << 29) |
535                       (slice_param->disable_deblocking_filter_idc << 27) |
536                       (slice_param->cabac_init_idc << 24) |
537                       ((pic_param->pic_init_qp_minus26 + 26 + slice_param->slice_qp_delta) << 16) |
538                       ((slice_param->slice_beta_offset_div2 & 0xf) << 8) |
539                       ((slice_param->slice_alpha_c0_offset_div2 & 0xf) << 0));
540         OUT_BCS_BATCH(ctx, 
541                       (slice_ver_pos << 24) |
542                       (slice_hor_pos << 16) | 
543                       (slice_param->first_mb_in_slice << 0));
544         OUT_BCS_BATCH(ctx, 
545                       (0 << 7) | /* FIXME: ??? */
546                       ((0x7 - (slice_data_bit_offset & 0x7)) << 0));
547
548         if (encrypted) {
549             OUT_BCS_BATCH(ctx, counter_value);
550         }
551
552         ADVANCE_BCS_BATCH(ctx); 
553     } else {
554         BEGIN_BCS_BATCH(ctx, 8); 
555         OUT_BCS_BATCH(ctx, CMD_AVC_BSD_OBJECT | (8 - 2));
556         OUT_BCS_BATCH(ctx, 0); /* indirect data length for phantom slice is 0 */
557         OUT_BCS_BATCH(ctx, 0); /* indirect data start address for phantom slice is 0 */
558         OUT_BCS_BATCH(ctx, 0);
559         OUT_BCS_BATCH(ctx, 0);
560         OUT_BCS_BATCH(ctx, 0);
561         OUT_BCS_BATCH(ctx, width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag));
562         OUT_BCS_BATCH(ctx, 0);
563         ADVANCE_BCS_BATCH(ctx);
564     }
565 }
566
567 static void
568 ironlake_avc_bsd_object(VADriverContextP ctx, 
569                         struct decode_state *decode_state,
570                         VAPictureParameterBufferH264 *pic_param,
571                         VASliceParameterBufferH264 *slice_param)
572 {
573     int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
574     int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
575
576     if (slice_param) {
577         struct i965_driver_data *i965 = i965_driver_data(ctx);
578         struct i965_media_state *media_state = &i965->media_state;
579         struct i965_h264_context *i965_h264_context = (struct i965_h264_context *)media_state->private_context;
580         int encrypted, counter_value;
581         int slice_hor_pos, slice_ver_pos;
582         int num_ref_idx_l0, num_ref_idx_l1;
583         int field_or_mbaff_picture = (pic_param->pic_fields.bits.field_pic_flag ||
584                                       pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
585         int slice_data_bit_offset;
586         int weighted_pred_idc = 0;
587
588         encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
589
590         if (encrypted) {
591             counter_value = 0; /* FIXME: ??? */
592         } else 
593             counter_value = 0;
594
595         slice_data_bit_offset = slice_param->slice_data_bit_offset;    
596
597         if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC)
598             slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8);
599
600         if (slice_param->slice_type == SLICE_TYPE_I) {
601             assert(slice_param->num_ref_idx_l0_active_minus1 == 0);
602             assert(slice_param->num_ref_idx_l1_active_minus1 == 0);
603             num_ref_idx_l0 = 0;
604             num_ref_idx_l1 = 0;
605         } else if (slice_param->slice_type == SLICE_TYPE_P) {
606             assert(slice_param->num_ref_idx_l1_active_minus1 == 0);
607             num_ref_idx_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
608             num_ref_idx_l1 = 0;
609         } else {
610             num_ref_idx_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
611             num_ref_idx_l1 = slice_param->num_ref_idx_l1_active_minus1 + 1;
612         }
613
614         if (slice_param->slice_type == SLICE_TYPE_P)
615             weighted_pred_idc = pic_param->pic_fields.bits.weighted_pred_flag;
616         else if (slice_param->slice_type == SLICE_TYPE_B)
617             weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc;
618
619         slice_hor_pos = slice_param->first_mb_in_slice % width_in_mbs; 
620         slice_ver_pos = slice_param->first_mb_in_slice / width_in_mbs;
621         slice_ver_pos <<= (1 + field_or_mbaff_picture); /* FIXME: right ??? */
622
623         BEGIN_BCS_BATCH(ctx, 16);
624         OUT_BCS_BATCH(ctx, CMD_AVC_BSD_OBJECT | (16 - 2));
625         OUT_BCS_BATCH(ctx, 
626                       (encrypted << 31) |
627                       (0 << 30) | /* FIXME: packet based bit stream */
628                       (0 << 29) | /* FIXME: packet format */
629                       ((slice_param->slice_data_size - (slice_data_bit_offset >> 3)) << 0));
630         OUT_BCS_BATCH(ctx, 
631                       (slice_param->slice_data_offset +
632                        (slice_data_bit_offset >> 3)));
633         OUT_BCS_BATCH(ctx, 
634                       (0 << 31) | /* concealment mode: 0->intra 16x16 prediction, 1->inter P Copy */
635                       (0 << 14) | /* ignore BSDPrematureComplete Error handling */
636                       (0 << 13) | /* FIXME: ??? */
637                       (0 << 12) | /* ignore MPR Error handling */
638                       (0 << 10) | /* ignore Entropy Error handling */
639                       (0 << 8)  | /* ignore MB Header Error handling */
640                       (slice_param->slice_type << 0));
641         OUT_BCS_BATCH(ctx, 
642                       (num_ref_idx_l1 << 24) |
643                       (num_ref_idx_l0 << 16) |
644                       (slice_param->chroma_log2_weight_denom << 8) |
645                       (slice_param->luma_log2_weight_denom << 0));
646         OUT_BCS_BATCH(ctx, 
647                       (weighted_pred_idc << 30) |
648                       (slice_param->direct_spatial_mv_pred_flag << 29) |
649                       (slice_param->disable_deblocking_filter_idc << 27) |
650                       (slice_param->cabac_init_idc << 24) |
651                       ((pic_param->pic_init_qp_minus26 + 26 + slice_param->slice_qp_delta) << 16) |
652                       ((slice_param->slice_beta_offset_div2 & 0xf) << 8) |
653                       ((slice_param->slice_alpha_c0_offset_div2 & 0xf) << 0));
654         OUT_BCS_BATCH(ctx, 
655                       (slice_ver_pos << 24) |
656                       (slice_hor_pos << 16) | 
657                       (slice_param->first_mb_in_slice << 0));
658         OUT_BCS_BATCH(ctx, 
659                       (0 << 7) | /* FIXME: ??? */
660                       ((0x7 - (slice_data_bit_offset & 0x7)) << 0));
661         OUT_BCS_BATCH(ctx, counter_value);
662         
663         /* FIXME: dw9-dw11 */
664         OUT_BCS_BATCH(ctx, 0);
665         OUT_BCS_BATCH(ctx, 0);
666         OUT_BCS_BATCH(ctx, 0);
667         OUT_BCS_BATCH(ctx, i965_h264_context->weight128_luma_l0);
668         OUT_BCS_BATCH(ctx, i965_h264_context->weight128_luma_l1);
669         OUT_BCS_BATCH(ctx, i965_h264_context->weight128_chroma_l0);
670         OUT_BCS_BATCH(ctx, i965_h264_context->weight128_chroma_l1);
671
672         ADVANCE_BCS_BATCH(ctx); 
673     } else {
674         BEGIN_BCS_BATCH(ctx, 16);
675         OUT_BCS_BATCH(ctx, CMD_AVC_BSD_OBJECT | (16 - 2));
676         OUT_BCS_BATCH(ctx, 0); /* indirect data length for phantom slice is 0 */
677         OUT_BCS_BATCH(ctx, 0); /* indirect data start address for phantom slice is 0 */
678         OUT_BCS_BATCH(ctx, 0);
679         OUT_BCS_BATCH(ctx, 0);
680         OUT_BCS_BATCH(ctx, 0);
681         OUT_BCS_BATCH(ctx, width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag));
682         OUT_BCS_BATCH(ctx, 0);
683         OUT_BCS_BATCH(ctx, 0);
684         OUT_BCS_BATCH(ctx, 0);
685         OUT_BCS_BATCH(ctx, 0);
686         OUT_BCS_BATCH(ctx, 0);
687         OUT_BCS_BATCH(ctx, 0);
688         OUT_BCS_BATCH(ctx, 0);
689         OUT_BCS_BATCH(ctx, 0);
690         OUT_BCS_BATCH(ctx, 0);
691         ADVANCE_BCS_BATCH(ctx);
692     }
693 }
694
695 static void
696 i965_avc_bsd_object(VADriverContextP ctx, 
697                     struct decode_state *decode_state,
698                     VAPictureParameterBufferH264 *pic_param,
699                     VASliceParameterBufferH264 *slice_param)
700 {
701     struct i965_driver_data *i965 = i965_driver_data(ctx);
702
703     if (IS_IRONLAKE(i965->intel.device_id))
704         ironlake_avc_bsd_object(ctx, decode_state, pic_param, slice_param);
705     else
706         g4x_avc_bsd_object(ctx, decode_state, pic_param, slice_param);
707 }
708
709 static void
710 i965_avc_bsd_phantom_slice(VADriverContextP ctx, 
711                            struct decode_state *decode_state,
712                            VAPictureParameterBufferH264 *pic_param)
713 {
714     i965_avc_bsd_object(ctx, decode_state, pic_param, NULL);
715 }
716
717 void 
718 i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state)
719 {
720     int i;
721     VAPictureParameterBufferH264 *pic_param;
722     VASliceParameterBufferH264 *slice_param;
723
724     assert(decode_state->pic_param && decode_state->pic_param->buffer);
725     pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
726     assert(decode_state->slice_param && decode_state->slice_param->buffer);
727     slice_param = (VASliceParameterBufferH264 *)decode_state->slice_param->buffer;
728
729     intel_batchbuffer_start_atomic_bcs(ctx, 0x1000);
730     i965_bsd_ind_obj_base_address(ctx, decode_state);
731
732     assert(decode_state->num_slices == 1); /* FIXME: */
733     for (i = 0; i < decode_state->num_slices; i++) {
734         assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
735         assert((slice_param->slice_type == SLICE_TYPE_I) ||
736                (slice_param->slice_type == SLICE_TYPE_P) ||
737                (slice_param->slice_type == SLICE_TYPE_B)); /* hardware requirement */
738
739         if (i == 0) {
740             i965_avc_bsd_img_state(ctx, decode_state);
741             i965_avc_bsd_qm_state(ctx, decode_state);
742         }
743
744         i965_avc_bsd_slice_state(ctx, pic_param, slice_param);
745         i965_avc_bsd_buf_base_state(ctx, decode_state);
746         i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param);
747         slice_param++;
748     }
749
750     i965_avc_bsd_phantom_slice(ctx, decode_state, pic_param);
751     intel_batchbuffer_emit_mi_flush_bcs(ctx);
752     intel_batchbuffer_end_atomic_bcs(ctx);
753     intel_batchbuffer_flush_bcs(ctx);
754 }
755
756 void 
757 i965_avc_bsd_decode_init(VADriverContextP ctx)
758 {
759     struct i965_driver_data *i965 = i965_driver_data(ctx);
760     struct i965_media_state *media_state = &i965->media_state;
761     struct i965_h264_context *i965_h264_context = (struct i965_h264_context *)media_state->private_context;
762     struct i965_avc_bsd_context *i965_avc_bsd_context;
763     dri_bo *bo;
764
765     assert(i965_h264_context);
766     i965_avc_bsd_context = &i965_h264_context->i965_avc_bsd_context;
767
768     dri_bo_unreference(i965_avc_bsd_context->bsd_raw_store.bo);
769     bo = dri_bo_alloc(i965->intel.bufmgr,
770                       "bsd raw store",
771                       0x4000, /* at least 11520 bytes to support 120 MBs per row */
772                       64);
773     assert(bo);
774     i965_avc_bsd_context->bsd_raw_store.bo = bo;
775
776     dri_bo_unreference(i965_avc_bsd_context->mpr_row_store.bo);
777     bo = dri_bo_alloc(i965->intel.bufmgr,
778                       "mpr row store",
779                       0x2000, /* at least 7680 bytes to support 120 MBs per row */
780                       64);
781     assert(bo);
782     i965_avc_bsd_context->mpr_row_store.bo = bo;
783
784     dri_bo_unreference(i965_avc_bsd_context->ildb_data.bo);
785     bo = dri_bo_alloc(i965->intel.bufmgr,
786                       "ildb data",
787                       0x100000, /* at least 1044480 bytes */
788                       64);
789     assert(bo);
790     i965_avc_bsd_context->ildb_data.bo = bo;
791 }
792
793 Bool 
794 i965_avc_bsd_ternimate(struct i965_avc_bsd_context *i965_avc_bsd_context)
795 {
796     dri_bo_unreference(i965_avc_bsd_context->bsd_raw_store.bo);
797     dri_bo_unreference(i965_avc_bsd_context->mpr_row_store.bo);
798     dri_bo_unreference(i965_avc_bsd_context->ildb_data.bo);
799
800     return True;
801 }