Encoder: directly use the surface object of the input surface
[platform/upstream/libva-intel-driver.git] / src / gen7_mfc.c
1 /*
2  * Copyright © 2011 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  *    Zhou Chang <chang.zhou@intel.com>
26  *    Xiang, Haihao <haihao.xiang@intel.com>
27  *
28  */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34
35 #include "intel_batchbuffer.h"
36 #include "i965_defines.h"
37 #include "i965_structs.h"
38 #include "i965_drv_video.h"
39 #include "i965_encoder.h"
40 #include "i965_encoder_utils.h"
41 #include "gen6_mfc.h"
42 #include "gen6_vme.h"
43
44 extern void
45 gen6_mfc_pipe_buf_addr_state(VADriverContextP ctx, 
46                              struct intel_encoder_context *encoder_context);
47 extern void
48 gen6_mfc_bsp_buf_base_addr_state(VADriverContextP ctx, 
49                              struct intel_encoder_context *encoder_context);
50 extern void 
51 gen6_mfc_init(VADriverContextP ctx, 
52               struct encode_state *encode_state,
53               struct intel_encoder_context *encoder_context);
54
55 extern VAStatus
56 gen6_mfc_run(VADriverContextP ctx, 
57              struct encode_state *encode_state,
58              struct intel_encoder_context *encoder_context);
59
60 extern VAStatus
61 gen6_mfc_stop(VADriverContextP ctx, 
62               struct encode_state *encode_state,
63               struct intel_encoder_context *encoder_context,
64               int *encoded_bits_size);
65
66 extern VAStatus
67 gen6_mfc_avc_encode_picture(VADriverContextP ctx, 
68                             struct encode_state *encode_state,
69                             struct intel_encoder_context *encoder_context);
70
71 static const uint32_t gen7_mfc_batchbuffer_avc_intra[][4] = {
72 #include "shaders/utils/mfc_batchbuffer_avc_intra.g7b"
73 };
74
75 static const uint32_t gen7_mfc_batchbuffer_avc_inter[][4] = {
76 #include "shaders/utils/mfc_batchbuffer_avc_inter.g7b"
77 };
78
79 static struct i965_kernel gen7_mfc_kernels[] = {
80     {
81         "MFC AVC INTRA BATCHBUFFER ",
82         MFC_BATCHBUFFER_AVC_INTRA,
83         gen7_mfc_batchbuffer_avc_intra,
84         sizeof(gen7_mfc_batchbuffer_avc_intra),
85         NULL
86     },
87
88     {
89         "MFC AVC INTER BATCHBUFFER ",
90         MFC_BATCHBUFFER_AVC_INTER,
91         gen7_mfc_batchbuffer_avc_inter,
92         sizeof(gen7_mfc_batchbuffer_avc_inter),
93         NULL
94     },
95 };
96
97 static void
98 gen7_mfc_pipe_mode_select(VADriverContextP ctx,
99                           int standard_select,
100                           struct intel_encoder_context *encoder_context)
101 {
102     struct intel_batchbuffer *batch = encoder_context->base.batch;
103     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
104
105     assert(standard_select == MFX_FORMAT_MPEG2 ||
106            standard_select == MFX_FORMAT_AVC);
107
108     BEGIN_BCS_BATCH(batch, 5);
109
110     OUT_BCS_BATCH(batch, MFX_PIPE_MODE_SELECT | (5 - 2));
111     OUT_BCS_BATCH(batch,
112                   (MFX_LONG_MODE << 17) | /* Must be long format for encoder */
113                   (MFD_MODE_VLD << 15) | /* VLD mode */
114                   (1 << 10) | /* Stream-Out Enable */
115                   ((!!mfc_context->post_deblocking_output.bo) << 9)  | /* Post Deblocking Output */
116                   ((!!mfc_context->pre_deblocking_output.bo) << 8)  | /* Pre Deblocking Output */
117                   (0 << 8)  | /* Pre Deblocking Output */
118                   (0 << 5)  | /* not in stitch mode */
119                   (1 << 4)  | /* encoding mode */
120                   (standard_select << 0));  /* standard select: avc or mpeg2 */
121     OUT_BCS_BATCH(batch,
122                   (0 << 7)  | /* expand NOA bus flag */
123                   (0 << 6)  | /* disable slice-level clock gating */
124                   (0 << 5)  | /* disable clock gating for NOA */
125                   (0 << 4)  | /* terminate if AVC motion and POC table error occurs */
126                   (0 << 3)  | /* terminate if AVC mbdata error occurs */
127                   (0 << 2)  | /* terminate if AVC CABAC/CAVLC decode error occurs */
128                   (0 << 1)  |
129                   (0 << 0));
130     OUT_BCS_BATCH(batch, 0);
131     OUT_BCS_BATCH(batch, 0);
132
133     ADVANCE_BCS_BATCH(batch);
134 }
135
136 static void
137 gen7_mfc_surface_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
138 {
139     struct intel_batchbuffer *batch = encoder_context->base.batch;
140     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
141
142     BEGIN_BCS_BATCH(batch, 6);
143
144     OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
145     OUT_BCS_BATCH(batch, 0);
146     OUT_BCS_BATCH(batch,
147                   ((mfc_context->surface_state.height - 1) << 18) |
148                   ((mfc_context->surface_state.width - 1) << 4));
149     OUT_BCS_BATCH(batch,
150                   (MFX_SURFACE_PLANAR_420_8 << 28) | /* 420 planar YUV surface */
151                   (1 << 27) | /* must be 1 for interleave U/V, hardware requirement */
152                   (0 << 22) | /* surface object control state, FIXME??? */
153                   ((mfc_context->surface_state.w_pitch - 1) << 3) | /* pitch */
154                   (0 << 2)  | /* must be 0 for interleave U/V */
155                   (1 << 1)  | /* must be tiled */
156                   (I965_TILEWALK_YMAJOR << 0));  /* tile walk, TILEWALK_YMAJOR */
157     OUT_BCS_BATCH(batch,
158                   (0 << 16) |                                                           /* must be 0 for interleave U/V */
159                   (mfc_context->surface_state.h_pitch));                /* y offset for U(cb) */
160     OUT_BCS_BATCH(batch, 0);
161
162     ADVANCE_BCS_BATCH(batch);
163 }
164
165 static void
166 gen7_mfc_ind_obj_base_addr_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
167 {
168     struct intel_batchbuffer *batch = encoder_context->base.batch;
169     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
170     struct gen6_vme_context *vme_context = encoder_context->vme_context;
171
172     BEGIN_BCS_BATCH(batch, 11);
173
174     OUT_BCS_BATCH(batch, MFX_IND_OBJ_BASE_ADDR_STATE | (11 - 2));
175     OUT_BCS_BATCH(batch, 0);
176     OUT_BCS_BATCH(batch, 0);
177     /* MFX Indirect MV Object Base Address */
178     OUT_BCS_RELOC(batch, vme_context->vme_output.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
179     OUT_BCS_BATCH(batch, 0x80000000); /* must set, up to 2G */
180     OUT_BCS_BATCH(batch, 0);
181     OUT_BCS_BATCH(batch, 0);
182     OUT_BCS_BATCH(batch, 0);
183     OUT_BCS_BATCH(batch, 0);
184     /*MFC Indirect PAK-BSE Object Base Address for Encoder*/    
185     OUT_BCS_RELOC(batch,
186                   mfc_context->mfc_indirect_pak_bse_object.bo,
187                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
188                   0);
189     OUT_BCS_RELOC(batch,
190                   mfc_context->mfc_indirect_pak_bse_object.bo,
191                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
192                   mfc_context->mfc_indirect_pak_bse_object.end_offset);
193
194     ADVANCE_BCS_BATCH(batch);
195 }
196
197 static void
198 gen7_mfc_avc_img_state(VADriverContextP ctx, struct encode_state *encode_state,  
199                        struct intel_encoder_context *encoder_context)
200 {
201     struct intel_batchbuffer *batch = encoder_context->base.batch;
202     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
203     VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
204
205     int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
206     int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
207
208     BEGIN_BCS_BATCH(batch, 16);
209
210     OUT_BCS_BATCH(batch, MFX_AVC_IMG_STATE | (16 - 2));
211         /*DW1 frame size */
212     OUT_BCS_BATCH(batch,
213                   ((width_in_mbs * height_in_mbs) & 0xFFFF));
214     OUT_BCS_BATCH(batch, 
215                   ((height_in_mbs - 1) << 16) | 
216                   ((width_in_mbs - 1) << 0));
217         /*DW3 Qp setting */
218     OUT_BCS_BATCH(batch, 
219                   (0 << 24) |   /* Second Chroma QP Offset */
220                   (0 << 16) |   /* Chroma QP Offset */
221                   (0 << 14) |   /* Max-bit conformance Intra flag */
222                   (0 << 13) |   /* Max Macroblock size conformance Inter flag */
223                   (pPicParameter->pic_fields.bits.weighted_pred_flag << 12) |   /*Weighted_Pred_Flag */
224                   (pPicParameter->pic_fields.bits.weighted_bipred_idc << 10) |  /* Weighted_BiPred_Idc */
225                   (0 << 8)  |   /* FIXME: Image Structure */
226                   (0 << 0) );   /* Current Decoed Image Frame Store ID, reserved in Encode mode */
227     OUT_BCS_BATCH(batch,
228                   (0 << 16) |   /* Mininum Frame size */
229                   (0 << 15) |   /* Disable reading of Macroblock Status Buffer */
230                   (0 << 14) |   /* Load BitStream Pointer only once, 1 slic 1 frame */
231                   (0 << 13) |   /* CABAC 0 word insertion test enable */
232                   (1 << 12) |   /* MVUnpackedEnable,compliant to DXVA */
233                   (1 << 10) |   /* Chroma Format IDC, 4:2:0 */
234                   (0 << 9)  |   /* FIXME: MbMvFormatFlag */
235                   (pPicParameter->pic_fields.bits.entropy_coding_mode_flag << 7)  |   /*0:CAVLC encoding mode,1:CABAC*/
236                   (0 << 6)  |   /* Only valid for VLD decoding mode */
237                   (0 << 5)  |   /* Constrained Intra Predition Flag, from PPS */
238                   (0 << 4)  |   /* Direct 8x8 inference flag */
239                   (pPicParameter->pic_fields.bits.transform_8x8_mode_flag << 3)  |   /*8x8 or 4x4 IDCT Transform Mode Flag*/
240                   (1 << 2)  |   /* Frame MB only flag */
241                   (0 << 1)  |   /* MBAFF mode is in active */
242                   (0 << 0));    /* Field picture flag */
243         /*DW5 trequllis quantization */
244     OUT_BCS_BATCH(batch, 0);    /* Mainly about MB rate control and debug, just ignoring */
245     OUT_BCS_BATCH(batch,        /* Inter and Intra Conformance Max size limit */
246                   (0xBB8 << 16) |       /* InterMbMaxSz */
247                   (0xEE8) );            /* IntraMbMaxSz */
248         /* DW7 */
249     OUT_BCS_BATCH(batch, 0);            /* Reserved */
250     OUT_BCS_BATCH(batch, 0);            /* Slice QP Delta for bitrate control */
251     OUT_BCS_BATCH(batch, 0);            /* Slice QP Delta for bitrate control */
252         /* DW10 frame bit setting */    
253     OUT_BCS_BATCH(batch, 0x8C000000);
254     OUT_BCS_BATCH(batch, 0x00010000);
255     OUT_BCS_BATCH(batch, 0);
256         /* DW13 Ref setting */
257     OUT_BCS_BATCH(batch, 0x02010100);
258     OUT_BCS_BATCH(batch, 0);
259     OUT_BCS_BATCH(batch, 0);
260
261     ADVANCE_BCS_BATCH(batch);
262 }
263
264 static void
265 gen7_mfc_qm_state(VADriverContextP ctx,
266                   int qm_type,
267                   unsigned int *qm,
268                   int qm_length,
269                   struct intel_encoder_context *encoder_context)
270 {
271     struct intel_batchbuffer *batch = encoder_context->base.batch;
272     unsigned int qm_buffer[16];
273
274     assert(qm_length <= 16);
275     assert(sizeof(*qm) == 4);
276     memcpy(qm_buffer, qm, qm_length * 4);
277
278     BEGIN_BCS_BATCH(batch, 18);
279     OUT_BCS_BATCH(batch, MFX_QM_STATE | (18 - 2));
280     OUT_BCS_BATCH(batch, qm_type << 0);
281     intel_batchbuffer_data(batch, qm_buffer, 16 * 4);
282     ADVANCE_BCS_BATCH(batch);
283 }
284
285 static void
286 gen7_mfc_avc_qm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
287 {
288     unsigned int qm[16] = {
289         0x10101010, 0x10101010, 0x10101010, 0x10101010,
290         0x10101010, 0x10101010, 0x10101010, 0x10101010,
291         0x10101010, 0x10101010, 0x10101010, 0x10101010,
292         0x10101010, 0x10101010, 0x10101010, 0x10101010
293     };
294
295     gen7_mfc_qm_state(ctx, MFX_QM_AVC_4X4_INTRA_MATRIX, qm, 12, encoder_context);
296     gen7_mfc_qm_state(ctx, MFX_QM_AVC_4X4_INTER_MATRIX, qm, 12, encoder_context);
297     gen7_mfc_qm_state(ctx, MFX_QM_AVC_8x8_INTRA_MATRIX, qm, 16, encoder_context);
298     gen7_mfc_qm_state(ctx, MFX_QM_AVC_8x8_INTER_MATRIX, qm, 16, encoder_context);
299 }
300
301 static void
302 gen7_mfc_fqm_state(VADriverContextP ctx,
303                    int fqm_type,
304                    unsigned int *fqm,
305                    int fqm_length,
306                    struct intel_encoder_context *encoder_context)
307 {
308     struct intel_batchbuffer *batch = encoder_context->base.batch;
309     unsigned int fqm_buffer[32];
310
311     assert(fqm_length <= 32);
312     assert(sizeof(*fqm) == 4);
313     memcpy(fqm_buffer, fqm, fqm_length * 4);
314
315     BEGIN_BCS_BATCH(batch, 34);
316     OUT_BCS_BATCH(batch, MFX_FQM_STATE | (34 - 2));
317     OUT_BCS_BATCH(batch, fqm_type << 0);
318     intel_batchbuffer_data(batch, fqm_buffer, 32 * 4);
319     ADVANCE_BCS_BATCH(batch);
320 }
321
322 static void
323 gen7_mfc_avc_fqm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
324 {
325     unsigned int qm[32] = {
326         0x10001000, 0x10001000, 0x10001000, 0x10001000,
327         0x10001000, 0x10001000, 0x10001000, 0x10001000,
328         0x10001000, 0x10001000, 0x10001000, 0x10001000,
329         0x10001000, 0x10001000, 0x10001000, 0x10001000,
330         0x10001000, 0x10001000, 0x10001000, 0x10001000,
331         0x10001000, 0x10001000, 0x10001000, 0x10001000,
332         0x10001000, 0x10001000, 0x10001000, 0x10001000,
333         0x10001000, 0x10001000, 0x10001000, 0x10001000
334     };
335
336     gen7_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTRA_MATRIX, qm, 24, encoder_context);
337     gen7_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTER_MATRIX, qm, 24, encoder_context);
338     gen7_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTRA_MATRIX, qm, 32, encoder_context);
339     gen7_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTER_MATRIX, qm, 32, encoder_context);
340 }
341
342 static void
343 gen7_mfc_avc_insert_object(VADriverContextP ctx, struct intel_encoder_context *encoder_context,
344                            unsigned int *insert_data, int lenght_in_dws, int data_bits_in_last_dw,
345                            int skip_emul_byte_count, int is_last_header, int is_end_of_slice, int emulation_flag,
346                            struct intel_batchbuffer *batch)
347 {
348     if (batch == NULL)
349         batch = encoder_context->base.batch;
350
351     BEGIN_BCS_BATCH(batch, lenght_in_dws + 2);
352
353     OUT_BCS_BATCH(batch, MFX_INSERT_OBJECT | (lenght_in_dws + 2 - 2));
354     OUT_BCS_BATCH(batch,
355                   (0 << 16) |   /* always start at offset 0 */
356                   (data_bits_in_last_dw << 8) |
357                   (skip_emul_byte_count << 4) |
358                   (!!emulation_flag << 3) |
359                   ((!!is_last_header) << 2) |
360                   ((!!is_end_of_slice) << 1) |
361                   (0 << 0));    /* FIXME: ??? */
362     intel_batchbuffer_data(batch, insert_data, lenght_in_dws * 4);
363
364     ADVANCE_BCS_BATCH(batch);
365 }
366
367 static const int
368 va_to_gen7_mpeg2_picture_type[3] = {
369     1,  /* I */
370     2,  /* P */
371     3   /* B */
372 };
373
374 static void
375 gen7_mfc_mpeg2_pic_state(VADriverContextP ctx,
376                           struct intel_encoder_context *encoder_context,
377                           struct encode_state *encode_state)
378 {
379     struct intel_batchbuffer *batch = encoder_context->base.batch;
380     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
381     VAEncPictureParameterBufferMPEG2 *pic_param;
382     int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
383     int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
384
385     assert(encode_state->pic_param_ext && encode_state->pic_param_ext->buffer);
386     pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
387
388     BEGIN_BCS_BATCH(batch, 13);
389     OUT_BCS_BATCH(batch, MFX_MPEG2_PIC_STATE | (13 - 2));
390     OUT_BCS_BATCH(batch,
391                   (pic_param->f_code[1][1] & 0xf) << 28 | /* f_code[1][1] */
392                   (pic_param->f_code[1][0] & 0xf) << 24 | /* f_code[1][0] */
393                   (pic_param->f_code[0][1] & 0xf) << 20 | /* f_code[0][1] */
394                   (pic_param->f_code[0][0] & 0xf) << 16 | /* f_code[0][0] */
395                   pic_param->picture_coding_extension.bits.intra_dc_precision << 14 |
396                   pic_param->picture_coding_extension.bits.picture_structure << 12 |
397                   pic_param->picture_coding_extension.bits.top_field_first << 11 |
398                   pic_param->picture_coding_extension.bits.frame_pred_frame_dct << 10 |
399                   pic_param->picture_coding_extension.bits.concealment_motion_vectors << 9 |
400                   pic_param->picture_coding_extension.bits.q_scale_type << 8 |
401                   pic_param->picture_coding_extension.bits.intra_vlc_format << 7 | 
402                   pic_param->picture_coding_extension.bits.alternate_scan << 6);
403     OUT_BCS_BATCH(batch,
404                   0 << 14 |     /* LoadSlicePointerFlag, 0 means only loading bitstream pointer once */
405                   va_to_gen7_mpeg2_picture_type[pic_param->picture_type] << 9 |
406                   0);
407     OUT_BCS_BATCH(batch,
408                   1 << 31 |     /* slice concealment */
409                   (height_in_mbs - 1) << 16 |
410                   (width_in_mbs - 1));
411     OUT_BCS_BATCH(batch, 0);
412     OUT_BCS_BATCH(batch, 0);
413     OUT_BCS_BATCH(batch,
414                   0xFFF << 16 | /* InterMBMaxSize */
415                   0xFFF << 0 |  /* IntraMBMaxSize */
416                   0);
417     OUT_BCS_BATCH(batch, 0);
418     OUT_BCS_BATCH(batch, 0);
419     OUT_BCS_BATCH(batch, 0);
420     OUT_BCS_BATCH(batch, 0);
421     OUT_BCS_BATCH(batch, 0);
422     OUT_BCS_BATCH(batch, 0);
423     ADVANCE_BCS_BATCH(batch);
424 }
425
426 static void
427 gen7_mfc_mpeg2_qm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
428 {
429     unsigned char intra_qm[64] = {
430          8, 16, 19, 22, 26, 27, 29, 34,
431         16, 16, 22, 24, 27, 29, 34, 37,
432         19, 22, 26, 27, 29, 34, 34, 38,
433         22, 22, 26, 27, 29, 34, 37, 40,
434         22, 26, 27, 29, 32, 35, 40, 48,
435         26, 27, 29, 32, 35, 40, 48, 58,
436         26, 27, 29, 34, 38, 46, 56, 69,
437         27, 29, 35, 38, 46, 56, 69, 83
438     };
439
440     unsigned char non_intra_qm[64] = {
441         16, 16, 16, 16, 16, 16, 16, 16,
442         16, 16, 16, 16, 16, 16, 16, 16,
443         16, 16, 16, 16, 16, 16, 16, 16,
444         16, 16, 16, 16, 16, 16, 16, 16,
445         16, 16, 16, 16, 16, 16, 16, 16,
446         16, 16, 16, 16, 16, 16, 16, 16,
447         16, 16, 16, 16, 16, 16, 16, 16,
448         16, 16, 16, 16, 16, 16, 16, 16
449     };
450
451     gen7_mfc_qm_state(ctx, MFX_QM_MPEG_INTRA_QUANTIZER_MATRIX, (unsigned int *)intra_qm, 16, encoder_context);
452     gen7_mfc_qm_state(ctx, MFX_QM_MPEG_NON_INTRA_QUANTIZER_MATRIX, (unsigned int *)non_intra_qm, 16,encoder_context);
453 }
454
455 static void
456 gen7_mfc_mpeg2_fqm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
457 {
458     unsigned short intra_fqm[64] = {
459          65536/0x8, 65536/0x10, 65536/0x13, 65536/0x16, 65536/0x16, 65536/0x1a, 65536/0x1a, 65536/0x1b,
460          65536/0x10, 65536/0x10, 65536/0x16, 65536/0x16, 65536/0x1a, 65536/0x1b, 65536/0x1b, 65536/0x1d,
461          65536/0x13, 65536/0x16, 65536/0x1a, 65536/0x1a, 65536/0x1b, 65536/0x1d, 65536/0x1d, 65536/0x23,
462          65536/0x16, 65536/0x18, 65536/0x1b, 65536/0x1b, 65536/0x13, 65536/0x20, 65536/0x22, 65536/0x26,
463          65536/0x1a, 65536/0x1b, 65536/0x13, 65536/0x13, 65536/0x20, 65536/0x23, 65536/0x26, 65536/0x2e,
464          65536/0x1b, 65536/0x1d, 65536/0x22, 65536/0x22, 65536/0x23, 65536/0x28, 65536/0x2e, 65536/0x38,
465          65536/0x1d, 65536/0x22, 65536/0x22, 65536/0x25, 65536/0x28, 65536/0x30, 65536/0x38, 65536/0x45,
466          65536/0x22, 65536/0x25, 65536/0x26, 65536/0x28, 65536/0x30, 65536/0x3a, 65536/0x45, 65536/0x53,
467     };
468
469     unsigned short non_intra_fqm[64] = {
470         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
471         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
472         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
473         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
474         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
475         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
476         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
477         0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
478     };
479
480     gen7_mfc_fqm_state(ctx, MFX_QM_MPEG_INTRA_QUANTIZER_MATRIX, (unsigned int *)intra_fqm, 32, encoder_context);
481     gen7_mfc_fqm_state(ctx, MFX_QM_MPEG_NON_INTRA_QUANTIZER_MATRIX, (unsigned int *)non_intra_fqm, 32, encoder_context);
482 }
483
484 static void
485 gen7_mfc_mpeg2_slicegroup_state(VADriverContextP ctx,
486                                  struct intel_encoder_context *encoder_context,
487                                  int x, int y,
488                                  int next_x, int next_y,
489                                  int is_fisrt_slice_group,
490                                  int is_last_slice_group,
491                                  int intra_slice,
492                                  int qp,
493                                  struct intel_batchbuffer *batch)
494 {
495     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
496
497     if (batch == NULL)
498         batch = encoder_context->base.batch;
499
500     BEGIN_BCS_BATCH(batch, 8);
501
502     OUT_BCS_BATCH(batch, MFC_MPEG2_SLICEGROUP_STATE | (8 - 2));
503     OUT_BCS_BATCH(batch,
504                   0 << 31 |                             /* MbRateCtrlFlag */
505                   !!is_last_slice_group << 19 |         /* IsLastSliceGrp */
506                   1 << 17 |                             /* Insert Header before the first slice group data */
507                   1 << 16 |                             /* SliceData PresentFlag: always 1 */
508                   1 << 15 |                             /* TailPresentFlag: always 1 */
509                   0 << 14 |                             /* FirstSliceHdrDisabled: slice header for each slice */
510                   !!intra_slice << 13 |                 /* IntraSlice */
511                   !!intra_slice << 12 |                 /* IntraSliceFlag */
512                   0);
513     OUT_BCS_BATCH(batch,
514                   next_y << 24 |
515                   next_x << 16 |
516                   y << 8 |
517                   x << 0 |
518                   0);
519     OUT_BCS_BATCH(batch, qp);   /* FIXME: SliceGroupQp */
520     /* bitstream pointer is only loaded once for the first slice of a frame when 
521      * LoadSlicePointerFlag is 0
522      */
523     OUT_BCS_BATCH(batch, mfc_context->mfc_indirect_pak_bse_object.offset);
524     OUT_BCS_BATCH(batch, 0);    /* FIXME: */
525     OUT_BCS_BATCH(batch, 0);    /* FIXME: CorrectPoints */
526     OUT_BCS_BATCH(batch, 0);    /* FIXME: CVxxx */
527
528     ADVANCE_BCS_BATCH(batch);
529 }
530
531 static int
532 gen7_mfc_mpeg2_pak_object_intra(VADriverContextP ctx,
533                                  struct intel_encoder_context *encoder_context,
534                                  int x, int y,
535                                  int first_mb_in_slice,
536                                  int last_mb_in_slice,
537                                  int first_mb_in_slice_group,
538                                  int last_mb_in_slice_group,
539                                  int mb_type,
540                                  int qp_scale_code,
541                                  int coded_block_pattern,
542                                  unsigned char target_size_in_word,
543                                  unsigned char max_size_in_word,
544                                  struct intel_batchbuffer *batch)
545 {
546     int len_in_dwords = 9;
547
548     if (batch == NULL)
549         batch = encoder_context->base.batch;
550
551     BEGIN_BCS_BATCH(batch, len_in_dwords);
552
553     OUT_BCS_BATCH(batch, MFC_MPEG2_PAK_OBJECT | (len_in_dwords - 2));
554     OUT_BCS_BATCH(batch,
555                   0 << 24 |     /* PackedMvNum */
556                   0 << 20 |     /* MvFormat */
557                   7 << 17 |     /* CbpDcY/CbpDcU/CbpDcV */
558                   0 << 15 |     /* TransformFlag: frame DCT */
559                   0 << 14 |     /* FieldMbFlag */
560                   1 << 13 |     /* IntraMbFlag */
561                   mb_type << 8 |   /* MbType: Intra */
562                   0 << 2 |      /* SkipMbFlag */
563                   0 << 0 |      /* InterMbMode */
564                   0);
565     OUT_BCS_BATCH(batch, y << 16 | x);
566     OUT_BCS_BATCH(batch,
567                   max_size_in_word << 24 |
568                   target_size_in_word << 16 |
569                   coded_block_pattern << 6 |      /* CBP */
570                   0);
571     OUT_BCS_BATCH(batch,
572                   last_mb_in_slice << 31 |
573                   first_mb_in_slice << 30 |
574                   0 << 27 |     /* EnableCoeffClamp */
575                   last_mb_in_slice_group << 26 |
576                   0 << 25 |     /* MbSkipConvDisable */
577                   first_mb_in_slice_group << 24 |
578                   0 << 16 |     /* MvFieldSelect */
579                   qp_scale_code << 0 |
580                   0);
581     OUT_BCS_BATCH(batch, 0);    /* MV[0][0] */
582     OUT_BCS_BATCH(batch, 0);    /* MV[1][0] */
583     OUT_BCS_BATCH(batch, 0);    /* MV[0][1] */
584     OUT_BCS_BATCH(batch, 0);    /* MV[1][1] */
585
586     ADVANCE_BCS_BATCH(batch);
587
588     return len_in_dwords;
589 }
590
591 #define MV_OFFSET_IN_WORD       112
592
593 static struct _mv_ranges
594 {
595     int low;    /* in the unit of 1/2 pixel */
596     int high;   /* in the unit of 1/2 pixel */
597 } mv_ranges[] = {
598     {0, 0},
599     {-16, 15},
600     {-32, 31},
601     {-64, 63},
602     {-128, 127},
603     {-256, 255},
604     {-512, 511},
605     {-1024, 1023},
606     {-2048, 2047},
607     {-4096, 4095}
608 };
609
610 static int
611 mpeg2_motion_vector(int mv, int pos, int display_max, int f_code)
612 {
613     if (mv + pos * 16 * 2 < 0 ||
614         mv + (pos + 1) * 16 * 2 > display_max * 2)
615         mv = 0;
616
617     if (f_code > 0 && f_code < 10) {
618         if (mv < mv_ranges[f_code].low)
619             mv = mv_ranges[f_code].low;
620
621         if (mv > mv_ranges[f_code].high)
622             mv = mv_ranges[f_code].high;
623     }
624
625     return mv;
626 }
627
628 static int
629 gen7_mfc_mpeg2_pak_object_inter(VADriverContextP ctx,
630                                  struct encode_state *encode_state,
631                                  struct intel_encoder_context *encoder_context,
632                                  unsigned int *msg,
633                                  int width_in_mbs, int height_in_mbs,
634                                  int x, int y,
635                                  int first_mb_in_slice,
636                                  int last_mb_in_slice,
637                                  int first_mb_in_slice_group,
638                                  int last_mb_in_slice_group,
639                                  int qp_scale_code,
640                                  unsigned char target_size_in_word,
641                                  unsigned char max_size_in_word,
642                                  struct intel_batchbuffer *batch)
643 {
644     VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
645     int len_in_dwords = 9;
646     short *mvptr, mvx0, mvy0, mvx1, mvy1;
647  
648     if (batch == NULL)
649         batch = encoder_context->base.batch;
650
651     mvptr = (short *)msg;
652     mvx0 = mpeg2_motion_vector(mvptr[0] / 2, x, width_in_mbs * 16, pic_param->f_code[0][0]);
653     mvy0 = mpeg2_motion_vector(mvptr[1] / 2, y, height_in_mbs * 16, pic_param->f_code[0][0]);
654     mvx1 = mpeg2_motion_vector(mvptr[2] / 2, x, width_in_mbs * 16, pic_param->f_code[1][0]);
655     mvy1 = mpeg2_motion_vector(mvptr[3] / 2, y, height_in_mbs * 16, pic_param->f_code[1][0]);
656
657     BEGIN_BCS_BATCH(batch, len_in_dwords);
658
659     OUT_BCS_BATCH(batch, MFC_MPEG2_PAK_OBJECT | (len_in_dwords - 2));
660     OUT_BCS_BATCH(batch,
661                   2 << 24 |     /* PackedMvNum */
662                   7 << 20 |     /* MvFormat */
663                   7 << 17 |     /* CbpDcY/CbpDcU/CbpDcV */
664                   0 << 15 |     /* TransformFlag: frame DCT */
665                   0 << 14 |     /* FieldMbFlag */
666                   0 << 13 |     /* IntraMbFlag */
667                   1 << 8 |      /* MbType: Frame-based */
668                   0 << 2 |      /* SkipMbFlag */
669                   0 << 0 |      /* InterMbMode */
670                   0);
671     OUT_BCS_BATCH(batch, y << 16 | x);
672     OUT_BCS_BATCH(batch,
673                   max_size_in_word << 24 |
674                   target_size_in_word << 16 |
675                   0x3f << 6 |   /* CBP */
676                   0);
677     OUT_BCS_BATCH(batch,
678                   last_mb_in_slice << 31 |
679                   first_mb_in_slice << 30 |
680                   0 << 27 |     /* EnableCoeffClamp */
681                   last_mb_in_slice_group << 26 |
682                   0 << 25 |     /* MbSkipConvDisable */
683                   first_mb_in_slice_group << 24 |
684                   0 << 16 |     /* MvFieldSelect */
685                   qp_scale_code << 0 |
686                   0);
687
688     OUT_BCS_BATCH(batch, (mvx0 & 0xFFFF) | mvy0 << 16);    /* MV[0][0] */
689     OUT_BCS_BATCH(batch, (mvx1 & 0xFFFF) | mvy1 << 16);    /* MV[1][0] */
690     OUT_BCS_BATCH(batch, 0);    /* MV[0][1] */
691     OUT_BCS_BATCH(batch, 0);    /* MV[1][1] */
692
693     ADVANCE_BCS_BATCH(batch);
694
695     return len_in_dwords;
696 }
697
698 static void
699 gen7_mfc_mpeg2_pipeline_header_programing(VADriverContextP ctx,
700                                            struct encode_state *encode_state,
701                                            struct intel_encoder_context *encoder_context,
702                                            struct intel_batchbuffer *slice_batch)
703 {
704     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
705     int idx = va_enc_packed_type_to_idx(VAEncPackedHeaderMPEG2_SPS);
706
707     if (encode_state->packed_header_data[idx]) {
708         VAEncPackedHeaderParameterBuffer *param = NULL;
709         unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
710         unsigned int length_in_bits;
711
712         assert(encode_state->packed_header_param[idx]);
713         param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
714         length_in_bits = param->bit_length;
715
716         mfc_context->insert_object(ctx,
717                                    encoder_context,
718                                    header_data,
719                                    ALIGN(length_in_bits, 32) >> 5,
720                                    length_in_bits & 0x1f,
721                                    5,   /* FIXME: check it */
722                                    0,
723                                    0,
724                                    0,   /* Needn't insert emulation bytes for MPEG-2 */
725                                    slice_batch);
726     }
727
728     idx = va_enc_packed_type_to_idx(VAEncPackedHeaderMPEG2_PPS);
729
730     if (encode_state->packed_header_data[idx]) {
731         VAEncPackedHeaderParameterBuffer *param = NULL;
732         unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
733         unsigned int length_in_bits;
734
735         assert(encode_state->packed_header_param[idx]);
736         param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
737         length_in_bits = param->bit_length;
738
739         mfc_context->insert_object(ctx,
740                                    encoder_context,
741                                    header_data,
742                                    ALIGN(length_in_bits, 32) >> 5,
743                                    length_in_bits & 0x1f,
744                                    5,   /* FIXME: check it */
745                                    0,
746                                    0,
747                                    0,   /* Needn't insert emulation bytes for MPEG-2 */
748                                    slice_batch);
749     }
750 }
751
752 static void 
753 gen7_mfc_mpeg2_pipeline_slice_group(VADriverContextP ctx,
754                                      struct encode_state *encode_state,
755                                      struct intel_encoder_context *encoder_context,
756                                      int slice_index,
757                                      VAEncSliceParameterBufferMPEG2 *next_slice_group_param,
758                                      struct intel_batchbuffer *slice_batch)
759 {
760     struct gen6_vme_context *vme_context = encoder_context->vme_context;
761     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
762     VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
763     VAEncSliceParameterBufferMPEG2 *slice_param = NULL;
764     unsigned char tail_delimiter[] = {MPEG2_DELIMITER0, MPEG2_DELIMITER1, MPEG2_DELIMITER2, MPEG2_DELIMITER3, MPEG2_DELIMITER4, 0, 0, 0};
765     unsigned char section_delimiter[] = {0x0, 0x0, 0x0, 0x0};
766     int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
767     int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
768     int i, j;
769     int h_start_pos, v_start_pos, h_next_start_pos, v_next_start_pos;
770     unsigned int *msg = NULL;
771     unsigned char *msg_ptr = NULL;
772
773     slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[slice_index]->buffer;
774     h_start_pos = slice_param->macroblock_address % width_in_mbs;
775     v_start_pos = slice_param->macroblock_address / width_in_mbs;
776     assert(h_start_pos + slice_param->num_macroblocks <= width_in_mbs);
777
778     dri_bo_map(vme_context->vme_output.bo , 0);
779     msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual;
780
781     if (next_slice_group_param) {
782         h_next_start_pos = next_slice_group_param->macroblock_address % width_in_mbs;
783         v_next_start_pos = next_slice_group_param->macroblock_address / width_in_mbs;
784     } else {
785         h_next_start_pos = 0;
786         v_next_start_pos = height_in_mbs;
787     }
788
789     gen7_mfc_mpeg2_slicegroup_state(ctx,
790                                      encoder_context,
791                                      h_start_pos,
792                                      v_start_pos,
793                                      h_next_start_pos,
794                                      v_next_start_pos,
795                                      slice_index == 0,
796                                      next_slice_group_param == NULL,
797                                      slice_param->is_intra_slice,
798                                      slice_param->quantiser_scale_code,
799                                      slice_batch);
800
801     if (slice_index == 0) 
802         gen7_mfc_mpeg2_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
803
804     /* Insert '00' to make sure the header is valid */
805     mfc_context->insert_object(ctx,
806                                encoder_context,
807                                (unsigned int*)section_delimiter,
808                                1,
809                                8,   /* 8bits in the last DWORD */
810                                1,   /* 1 byte */
811                                1,
812                                0,
813                                0,
814                                slice_batch);
815
816     for (i = 0; i < encode_state->slice_params_ext[slice_index]->num_elements; i++) {
817         /* PAK for each macroblocks */
818         for (j = 0; j < slice_param->num_macroblocks; j++) {
819             int h_pos = (slice_param->macroblock_address + j) % width_in_mbs;
820             int v_pos = (slice_param->macroblock_address + j) / width_in_mbs;
821             int first_mb_in_slice = (j == 0);
822             int last_mb_in_slice = (j == slice_param->num_macroblocks - 1);
823             int first_mb_in_slice_group = (i == 0 && j == 0);
824             int last_mb_in_slice_group = (i == encode_state->slice_params_ext[slice_index]->num_elements - 1 &&
825                                           j == slice_param->num_macroblocks - 1);
826
827             if (slice_param->is_intra_slice) {
828                 gen7_mfc_mpeg2_pak_object_intra(ctx,
829                                                  encoder_context,
830                                                  h_pos, v_pos,
831                                                  first_mb_in_slice,
832                                                  last_mb_in_slice,
833                                                  first_mb_in_slice_group,
834                                                  last_mb_in_slice_group,
835                                                  0x1a,
836                                                  slice_param->quantiser_scale_code,
837                                                  0x3f,
838                                                  0,
839                                                  0xff,
840                                                  slice_batch);
841             } else {
842                 msg = (unsigned int *)(msg_ptr + (slice_param->macroblock_address + j) * vme_context->vme_output.size_block);
843
844                 if(msg[32] & INTRA_MB_FLAG_MASK) {
845                      gen7_mfc_mpeg2_pak_object_intra(ctx,
846                                                      encoder_context,
847                                                      h_pos, v_pos,
848                                                      first_mb_in_slice,
849                                                      last_mb_in_slice,
850                                                      first_mb_in_slice_group,
851                                                      last_mb_in_slice_group,
852                                                      0x1a,
853                                                      slice_param->quantiser_scale_code,
854                                                      0x3f,
855                                                      0,
856                                                      0xff,
857                                                      slice_batch);
858                  } else {
859
860                     gen7_mfc_mpeg2_pak_object_inter(ctx,
861                                                     encode_state,
862                                                     encoder_context,
863                                                     msg,
864                                                     width_in_mbs, height_in_mbs,
865                                                     h_pos, v_pos,
866                                                     first_mb_in_slice,
867                                                     last_mb_in_slice,
868                                                     first_mb_in_slice_group,
869                                                     last_mb_in_slice_group,
870                                                     slice_param->quantiser_scale_code,
871                                                     0,
872                                                     0xff,
873                                                     slice_batch);
874               }
875            }
876         }
877
878         slice_param++;
879     }
880
881     dri_bo_unmap(vme_context->vme_output.bo);
882
883     /* tail data */
884     if (next_slice_group_param == NULL) { /* end of a picture */
885         mfc_context->insert_object(ctx,
886                                    encoder_context,
887                                    (unsigned int *)tail_delimiter,
888                                    2,
889                                    8,   /* 8bits in the last DWORD */
890                                    5,   /* 5 bytes */
891                                    1,
892                                    1,
893                                    0,
894                                    slice_batch);
895     } else {        /* end of a lsice group */
896         mfc_context->insert_object(ctx,
897                                    encoder_context,
898                                    (unsigned int *)section_delimiter,
899                                    1,
900                                    8,   /* 8bits in the last DWORD */
901                                    1,   /* 1 byte */
902                                    1,
903                                    1,
904                                    0,
905                                    slice_batch);
906     }
907 }
908
909 /* 
910  * A batch buffer for all slices, including slice state, 
911  * slice insert object and slice pak object commands
912  *
913  */
914 static dri_bo *
915 gen7_mfc_mpeg2_software_slice_batchbuffer(VADriverContextP ctx,
916                                            struct encode_state *encode_state,
917                                            struct intel_encoder_context *encoder_context)
918 {
919     struct i965_driver_data *i965 = i965_driver_data(ctx);
920     struct intel_batchbuffer *batch;
921     VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
922     VAEncSliceParameterBufferMPEG2 *next_slice_group_param = NULL;
923     dri_bo *batch_bo;
924     int i;
925     int buffer_size;
926     int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
927     int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
928
929     buffer_size = width_in_mbs * height_in_mbs * 64;
930     batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD, buffer_size);
931     batch_bo = batch->buffer;
932
933     for (i = 0; i < encode_state->num_slice_params_ext; i++) {
934         if (i == encode_state->num_slice_params_ext - 1)
935             next_slice_group_param = NULL;
936         else
937             next_slice_group_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[i + 1]->buffer;
938
939         gen7_mfc_mpeg2_pipeline_slice_group(ctx, encode_state, encoder_context, i, next_slice_group_param, batch);
940     }
941
942     intel_batchbuffer_align(batch, 8);
943     
944     BEGIN_BCS_BATCH(batch, 2);
945     OUT_BCS_BATCH(batch, 0);
946     OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_END);
947     ADVANCE_BCS_BATCH(batch);
948
949     dri_bo_reference(batch_bo);
950     intel_batchbuffer_free(batch);
951
952     return batch_bo;
953 }
954
955 static void
956 gen7_mfc_mpeg2_pipeline_picture_programing(VADriverContextP ctx,
957                                             struct encode_state *encode_state,
958                                             struct intel_encoder_context *encoder_context)
959 {
960     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
961
962     mfc_context->pipe_mode_select(ctx, MFX_FORMAT_MPEG2, encoder_context);
963     mfc_context->set_surface_state(ctx, encoder_context);
964     mfc_context->ind_obj_base_addr_state(ctx, encoder_context);
965     gen6_mfc_pipe_buf_addr_state(ctx, encoder_context);
966     gen6_mfc_bsp_buf_base_addr_state(ctx, encoder_context);
967     gen7_mfc_mpeg2_pic_state(ctx, encoder_context, encode_state);
968     gen7_mfc_mpeg2_qm_state(ctx, encoder_context);
969     gen7_mfc_mpeg2_fqm_state(ctx, encoder_context);
970 }
971
972 static void
973 gen7_mfc_mpeg2_pipeline_programing(VADriverContextP ctx,
974                                     struct encode_state *encode_state,
975                                     struct intel_encoder_context *encoder_context)
976 {
977     struct intel_batchbuffer *batch = encoder_context->base.batch;
978     dri_bo *slice_batch_bo;
979
980     slice_batch_bo = gen7_mfc_mpeg2_software_slice_batchbuffer(ctx, encode_state, encoder_context);
981
982     // begin programing
983     intel_batchbuffer_start_atomic_bcs(batch, 0x4000); 
984     intel_batchbuffer_emit_mi_flush(batch);
985     
986     // picture level programing
987     gen7_mfc_mpeg2_pipeline_picture_programing(ctx, encode_state, encoder_context);
988
989     BEGIN_BCS_BATCH(batch, 2);
990     OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8));
991     OUT_BCS_RELOC(batch,
992                   slice_batch_bo,
993                   I915_GEM_DOMAIN_COMMAND, 0, 
994                   0);
995     ADVANCE_BCS_BATCH(batch);
996
997     // end programing
998     intel_batchbuffer_end_atomic(batch);
999
1000     dri_bo_unreference(slice_batch_bo);
1001 }
1002
1003 static VAStatus
1004 gen7_mfc_mpeg2_prepare(VADriverContextP ctx,
1005                         struct encode_state *encode_state,
1006                         struct intel_encoder_context *encoder_context)
1007 {
1008     struct i965_driver_data *i965 = i965_driver_data(ctx);
1009     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1010     struct object_surface *obj_surface;
1011     struct object_buffer *obj_buffer;
1012     VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
1013     struct i965_coded_buffer_segment *coded_buffer_segment;
1014     VAStatus vaStatus = VA_STATUS_SUCCESS;
1015     dri_bo *bo;
1016     int i;
1017
1018     /* reconstructed surface */
1019     obj_surface = SURFACE(pic_param->reconstructed_picture);
1020     assert(obj_surface);
1021     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
1022     mfc_context->pre_deblocking_output.bo = obj_surface->bo;
1023     dri_bo_reference(mfc_context->pre_deblocking_output.bo);
1024     mfc_context->surface_state.width = obj_surface->orig_width;
1025     mfc_context->surface_state.height = obj_surface->orig_height;
1026     mfc_context->surface_state.w_pitch = obj_surface->width;
1027     mfc_context->surface_state.h_pitch = obj_surface->height;
1028
1029     /* forward reference */
1030     obj_surface = SURFACE(pic_param->forward_reference_picture);
1031
1032     if (obj_surface && obj_surface->bo) {
1033         mfc_context->reference_surfaces[0].bo = obj_surface->bo;
1034         dri_bo_reference(mfc_context->reference_surfaces[0].bo);
1035     } else
1036         mfc_context->reference_surfaces[0].bo = NULL;
1037
1038     /* backward reference */
1039     obj_surface = SURFACE(pic_param->backward_reference_picture);
1040
1041     if (obj_surface && obj_surface->bo) {
1042         mfc_context->reference_surfaces[1].bo = obj_surface->bo;
1043         dri_bo_reference(mfc_context->reference_surfaces[1].bo);
1044     } else {
1045         mfc_context->reference_surfaces[1].bo = mfc_context->reference_surfaces[0].bo;
1046
1047         if (mfc_context->reference_surfaces[1].bo)
1048             dri_bo_reference(mfc_context->reference_surfaces[1].bo);
1049     }
1050
1051     for (i = 2; i < ARRAY_ELEMS(mfc_context->reference_surfaces); i++) {
1052         mfc_context->reference_surfaces[i].bo = mfc_context->reference_surfaces[i & 1].bo;
1053
1054         if (mfc_context->reference_surfaces[i].bo)
1055             dri_bo_reference(mfc_context->reference_surfaces[i].bo);
1056     }
1057     
1058     /* input YUV surface */
1059     obj_surface = encode_state->input_yuv_object;
1060     mfc_context->uncompressed_picture_source.bo = obj_surface->bo;
1061     dri_bo_reference(mfc_context->uncompressed_picture_source.bo);
1062
1063     /* coded buffer */
1064     obj_buffer = BUFFER(pic_param->coded_buf);
1065     bo = obj_buffer->buffer_store->bo;
1066     assert(bo);
1067     mfc_context->mfc_indirect_pak_bse_object.bo = bo;
1068     mfc_context->mfc_indirect_pak_bse_object.offset = I965_CODEDBUFFER_HEADER_SIZE;
1069     mfc_context->mfc_indirect_pak_bse_object.end_offset = ALIGN(obj_buffer->size_element - 0x1000, 0x1000);
1070     dri_bo_reference(mfc_context->mfc_indirect_pak_bse_object.bo);
1071
1072     /* set the internal flag to 0 to indicate the coded size is unknown */
1073     dri_bo_map(bo, 1);
1074     coded_buffer_segment = (struct i965_coded_buffer_segment *)bo->virtual;
1075     coded_buffer_segment->mapped = 0;
1076     coded_buffer_segment->codec = CODED_MPEG2;
1077     dri_bo_unmap(bo);
1078
1079     return vaStatus;
1080 }
1081
1082 static VAStatus
1083 gen7_mfc_mpeg2_encode_picture(VADriverContextP ctx, 
1084                                struct encode_state *encode_state,
1085                                struct intel_encoder_context *encoder_context)
1086 {
1087     gen6_mfc_init(ctx, encode_state, encoder_context);
1088     gen7_mfc_mpeg2_prepare(ctx, encode_state, encoder_context);
1089     /*Programing bcs pipeline*/
1090     gen7_mfc_mpeg2_pipeline_programing(ctx, encode_state, encoder_context);
1091     gen6_mfc_run(ctx, encode_state, encoder_context);
1092
1093     return VA_STATUS_SUCCESS;
1094 }
1095
1096 VAStatus
1097 gen7_mfc_pipeline(VADriverContextP ctx,
1098                   VAProfile profile,
1099                   struct encode_state *encode_state,
1100                   struct intel_encoder_context *encoder_context)
1101 {
1102     VAStatus vaStatus;
1103
1104     switch (profile) {
1105     case VAProfileH264Baseline:
1106     case VAProfileH264Main:
1107     case VAProfileH264High:
1108         vaStatus = gen6_mfc_avc_encode_picture(ctx, encode_state, encoder_context);
1109         break;
1110
1111     case VAProfileMPEG2Simple:
1112     case VAProfileMPEG2Main:
1113         vaStatus = gen7_mfc_mpeg2_encode_picture(ctx, encode_state, encoder_context);
1114         break;
1115
1116         /* FIXME: add for other profile */
1117     default:
1118         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1119         break;
1120     }
1121
1122     return vaStatus;
1123 }
1124
1125 Bool
1126 gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
1127 {
1128     struct gen6_mfc_context *mfc_context = calloc(1, sizeof(struct gen6_mfc_context));
1129
1130     mfc_context->gpe_context.surface_state_binding_table.length = (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_MEDIA_SURFACES_GEN6;
1131
1132     mfc_context->gpe_context.idrt.max_entries = MAX_GPE_KERNELS;
1133     mfc_context->gpe_context.idrt.entry_size = sizeof(struct gen6_interface_descriptor_data);
1134
1135     mfc_context->gpe_context.curbe.length = 32 * 4;
1136
1137     mfc_context->gpe_context.vfe_state.max_num_threads = 60 - 1;
1138     mfc_context->gpe_context.vfe_state.num_urb_entries = 16;
1139     mfc_context->gpe_context.vfe_state.gpgpu_mode = 0;
1140     mfc_context->gpe_context.vfe_state.urb_entry_size = 59 - 1;
1141     mfc_context->gpe_context.vfe_state.curbe_allocation_size = 37 - 1;
1142
1143     i965_gpe_load_kernels(ctx,
1144                           &mfc_context->gpe_context,
1145                           gen7_mfc_kernels,
1146                           NUM_MFC_KERNEL);
1147
1148     mfc_context->pipe_mode_select = gen7_mfc_pipe_mode_select;
1149     mfc_context->set_surface_state = gen7_mfc_surface_state;
1150     mfc_context->ind_obj_base_addr_state = gen7_mfc_ind_obj_base_addr_state;
1151     mfc_context->avc_img_state = gen7_mfc_avc_img_state;
1152     mfc_context->avc_qm_state = gen7_mfc_avc_qm_state;
1153     mfc_context->avc_fqm_state = gen7_mfc_avc_fqm_state;
1154     mfc_context->insert_object = gen7_mfc_avc_insert_object;
1155     mfc_context->buffer_suface_setup = gen7_gpe_buffer_suface_setup;
1156
1157     encoder_context->mfc_context = mfc_context;
1158     encoder_context->mfc_context_destroy = gen6_mfc_context_destroy;
1159     encoder_context->mfc_pipeline = gen7_mfc_pipeline;
1160     encoder_context->mfc_brc_prepare = intel_mfc_brc_prepare;
1161
1162     return True;
1163 }