OSDN Git Service

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