OSDN Git Service

i965_drv: fix building with --enable-static
[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 {
610     int low;    /* in the unit of 1/2 pixel */
611     int high;   /* in the unit of 1/2 pixel */
612 } mv_ranges[] = {
613     {0, 0},
614     {-16, 15},
615     {-32, 31},
616     {-64, 63},
617     {-128, 127},
618     {-256, 255},
619     {-512, 511},
620     {-1024, 1023},
621     {-2048, 2047},
622     {-4096, 4095}
623 };
624
625 static int
626 mpeg2_motion_vector(int mv, int pos, int display_max, int f_code)
627 {
628     if (mv + pos * 16 * 2 < 0 ||
629         mv + (pos + 1) * 16 * 2 > display_max * 2)
630         mv = 0;
631
632     if (f_code > 0 && f_code < 10) {
633         if (mv < mv_ranges[f_code].low)
634             mv = mv_ranges[f_code].low;
635
636         if (mv > mv_ranges[f_code].high)
637             mv = mv_ranges[f_code].high;
638     }
639
640     return mv;
641 }
642
643 static int
644 gen7_mfc_mpeg2_pak_object_inter(VADriverContextP ctx,
645                                 struct encode_state *encode_state,
646                                 struct intel_encoder_context *encoder_context,
647                                 unsigned int *msg,
648                                 int width_in_mbs, int height_in_mbs,
649                                 int x, int y,
650                                 int first_mb_in_slice,
651                                 int last_mb_in_slice,
652                                 int first_mb_in_slice_group,
653                                 int last_mb_in_slice_group,
654                                 int qp_scale_code,
655                                 unsigned char target_size_in_word,
656                                 unsigned char max_size_in_word,
657                                 struct intel_batchbuffer *batch)
658 {
659     VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
660     int len_in_dwords = 9;
661     short *mvptr, mvx0, mvy0, mvx1, mvy1;
662  
663     if (batch == NULL)
664         batch = encoder_context->base.batch;
665
666     mvptr = (short *)msg;
667     mvx0 = mpeg2_motion_vector(mvptr[0] / 2, x, width_in_mbs * 16, pic_param->f_code[0][0]);
668     mvy0 = mpeg2_motion_vector(mvptr[1] / 2, y, height_in_mbs * 16, pic_param->f_code[0][0]);
669     mvx1 = mpeg2_motion_vector(mvptr[2] / 2, x, width_in_mbs * 16, pic_param->f_code[1][0]);
670     mvy1 = mpeg2_motion_vector(mvptr[3] / 2, y, height_in_mbs * 16, pic_param->f_code[1][0]);
671
672     BEGIN_BCS_BATCH(batch, len_in_dwords);
673
674     OUT_BCS_BATCH(batch, MFC_MPEG2_PAK_OBJECT | (len_in_dwords - 2));
675     OUT_BCS_BATCH(batch,
676                   2 << 24 |     /* PackedMvNum */
677                   7 << 20 |     /* MvFormat */
678                   7 << 17 |     /* CbpDcY/CbpDcU/CbpDcV */
679                   0 << 15 |     /* TransformFlag: frame DCT */
680                   0 << 14 |     /* FieldMbFlag */
681                   0 << 13 |     /* IntraMbFlag */
682                   1 << 8 |      /* MbType: Frame-based */
683                   0 << 2 |      /* SkipMbFlag */
684                   0 << 0 |      /* InterMbMode */
685                   0);
686     OUT_BCS_BATCH(batch, y << 16 | x);
687     OUT_BCS_BATCH(batch,
688                   max_size_in_word << 24 |
689                   target_size_in_word << 16 |
690                   0x3f << 6 |   /* CBP */
691                   0);
692     OUT_BCS_BATCH(batch,
693                   last_mb_in_slice << 31 |
694                   first_mb_in_slice << 30 |
695                   0 << 27 |     /* EnableCoeffClamp */
696                   last_mb_in_slice_group << 26 |
697                   0 << 25 |     /* MbSkipConvDisable */
698                   first_mb_in_slice_group << 24 |
699                   0 << 16 |     /* MvFieldSelect */
700                   qp_scale_code << 0 |
701                   0);
702
703     OUT_BCS_BATCH(batch, (mvx0 & 0xFFFF) | mvy0 << 16);    /* MV[0][0] */
704     OUT_BCS_BATCH(batch, (mvx1 & 0xFFFF) | mvy1 << 16);    /* MV[1][0] */
705     OUT_BCS_BATCH(batch, 0);    /* MV[0][1] */
706     OUT_BCS_BATCH(batch, 0);    /* MV[1][1] */
707
708     ADVANCE_BCS_BATCH(batch);
709
710     return len_in_dwords;
711 }
712
713 static void
714 gen7_mfc_mpeg2_pipeline_header_programing(VADriverContextP ctx,
715                                           struct encode_state *encode_state,
716                                           struct intel_encoder_context *encoder_context,
717                                           struct intel_batchbuffer *slice_batch)
718 {
719     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
720     int idx = va_enc_packed_type_to_idx(VAEncPackedHeaderMPEG2_SPS);
721
722     if (encode_state->packed_header_data[idx]) {
723         VAEncPackedHeaderParameterBuffer *param = NULL;
724         unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
725         unsigned int length_in_bits;
726
727         assert(encode_state->packed_header_param[idx]);
728         param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
729         length_in_bits = param->bit_length;
730
731         mfc_context->insert_object(ctx,
732                                    encoder_context,
733                                    header_data,
734                                    ALIGN(length_in_bits, 32) >> 5,
735                                    length_in_bits & 0x1f,
736                                    5,   /* FIXME: check it */
737                                    0,
738                                    0,
739                                    0,   /* Needn't insert emulation bytes for MPEG-2 */
740                                    slice_batch);
741     }
742
743     idx = va_enc_packed_type_to_idx(VAEncPackedHeaderMPEG2_PPS);
744
745     if (encode_state->packed_header_data[idx]) {
746         VAEncPackedHeaderParameterBuffer *param = NULL;
747         unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
748         unsigned int length_in_bits;
749
750         assert(encode_state->packed_header_param[idx]);
751         param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
752         length_in_bits = param->bit_length;
753
754         mfc_context->insert_object(ctx,
755                                    encoder_context,
756                                    header_data,
757                                    ALIGN(length_in_bits, 32) >> 5,
758                                    length_in_bits & 0x1f,
759                                    5,   /* FIXME: check it */
760                                    0,
761                                    0,
762                                    0,   /* Needn't insert emulation bytes for MPEG-2 */
763                                    slice_batch);
764     }
765 }
766
767 static void 
768 gen7_mfc_mpeg2_pipeline_slice_group(VADriverContextP ctx,
769                                     struct encode_state *encode_state,
770                                     struct intel_encoder_context *encoder_context,
771                                     int slice_index,
772                                     VAEncSliceParameterBufferMPEG2 *next_slice_group_param,
773                                     struct intel_batchbuffer *slice_batch)
774 {
775     struct gen6_vme_context *vme_context = encoder_context->vme_context;
776     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
777     VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
778     VAEncSliceParameterBufferMPEG2 *slice_param = NULL;
779     unsigned char tail_delimiter[] = {MPEG2_DELIMITER0, MPEG2_DELIMITER1, MPEG2_DELIMITER2, MPEG2_DELIMITER3, MPEG2_DELIMITER4, 0, 0, 0};
780     unsigned char section_delimiter[] = {0x0, 0x0, 0x0, 0x0};
781     int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
782     int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
783     int i, j;
784     int h_start_pos, v_start_pos, h_next_start_pos, v_next_start_pos;
785     unsigned int *msg = NULL;
786     unsigned char *msg_ptr = NULL;
787
788     slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[slice_index]->buffer;
789     h_start_pos = slice_param->macroblock_address % width_in_mbs;
790     v_start_pos = slice_param->macroblock_address / width_in_mbs;
791     assert(h_start_pos + slice_param->num_macroblocks <= width_in_mbs);
792
793     dri_bo_map(vme_context->vme_output.bo , 0);
794     msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual;
795
796     if (next_slice_group_param) {
797         h_next_start_pos = next_slice_group_param->macroblock_address % width_in_mbs;
798         v_next_start_pos = next_slice_group_param->macroblock_address / width_in_mbs;
799     } else {
800         h_next_start_pos = 0;
801         v_next_start_pos = height_in_mbs;
802     }
803
804     gen7_mfc_mpeg2_slicegroup_state(ctx,
805                                     encoder_context,
806                                     h_start_pos,
807                                     v_start_pos,
808                                     h_next_start_pos,
809                                     v_next_start_pos,
810                                     slice_index == 0,
811                                     next_slice_group_param == NULL,
812                                     slice_param->is_intra_slice,
813                                     slice_param->quantiser_scale_code,
814                                     slice_batch);
815
816     if (slice_index == 0) 
817         gen7_mfc_mpeg2_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
818
819     /* Insert '00' to make sure the header is valid */
820     mfc_context->insert_object(ctx,
821                                encoder_context,
822                                (unsigned int*)section_delimiter,
823                                1,
824                                8,   /* 8bits in the last DWORD */
825                                1,   /* 1 byte */
826                                1,
827                                0,
828                                0,
829                                slice_batch);
830
831     for (i = 0; i < encode_state->slice_params_ext[slice_index]->num_elements; i++) {
832         /* PAK for each macroblocks */
833         for (j = 0; j < slice_param->num_macroblocks; j++) {
834             int h_pos = (slice_param->macroblock_address + j) % width_in_mbs;
835             int v_pos = (slice_param->macroblock_address + j) / width_in_mbs;
836             int first_mb_in_slice = (j == 0);
837             int last_mb_in_slice = (j == slice_param->num_macroblocks - 1);
838             int first_mb_in_slice_group = (i == 0 && j == 0);
839             int last_mb_in_slice_group = (i == encode_state->slice_params_ext[slice_index]->num_elements - 1 &&
840                                           j == slice_param->num_macroblocks - 1);
841
842             if (slice_param->is_intra_slice) {
843                 gen7_mfc_mpeg2_pak_object_intra(ctx,
844                                                 encoder_context,
845                                                 h_pos, v_pos,
846                                                 first_mb_in_slice,
847                                                 last_mb_in_slice,
848                                                 first_mb_in_slice_group,
849                                                 last_mb_in_slice_group,
850                                                 0x1a,
851                                                 slice_param->quantiser_scale_code,
852                                                 0x3f,
853                                                 0,
854                                                 0xff,
855                                                 slice_batch);
856             } else {
857                 msg = (unsigned int *)(msg_ptr + (slice_param->macroblock_address + j) * vme_context->vme_output.size_block);
858
859                 if(msg[32] & INTRA_MB_FLAG_MASK) {
860                     gen7_mfc_mpeg2_pak_object_intra(ctx,
861                                                     encoder_context,
862                                                     h_pos, v_pos,
863                                                     first_mb_in_slice,
864                                                     last_mb_in_slice,
865                                                     first_mb_in_slice_group,
866                                                     last_mb_in_slice_group,
867                                                     0x1a,
868                                                     slice_param->quantiser_scale_code,
869                                                     0x3f,
870                                                     0,
871                                                     0xff,
872                                                     slice_batch);
873                 } else {
874
875                     gen7_mfc_mpeg2_pak_object_inter(ctx,
876                                                     encode_state,
877                                                     encoder_context,
878                                                     msg,
879                                                     width_in_mbs, height_in_mbs,
880                                                     h_pos, v_pos,
881                                                     first_mb_in_slice,
882                                                     last_mb_in_slice,
883                                                     first_mb_in_slice_group,
884                                                     last_mb_in_slice_group,
885                                                     slice_param->quantiser_scale_code,
886                                                     0,
887                                                     0xff,
888                                                     slice_batch);
889                 }
890             }
891         }
892
893         slice_param++;
894     }
895
896     dri_bo_unmap(vme_context->vme_output.bo);
897
898     /* tail data */
899     if (next_slice_group_param == NULL) { /* end of a picture */
900         mfc_context->insert_object(ctx,
901                                    encoder_context,
902                                    (unsigned int *)tail_delimiter,
903                                    2,
904                                    8,   /* 8bits in the last DWORD */
905                                    5,   /* 5 bytes */
906                                    1,
907                                    1,
908                                    0,
909                                    slice_batch);
910     } else {        /* end of a lsice group */
911         mfc_context->insert_object(ctx,
912                                    encoder_context,
913                                    (unsigned int *)section_delimiter,
914                                    1,
915                                    8,   /* 8bits in the last DWORD */
916                                    1,   /* 1 byte */
917                                    1,
918                                    1,
919                                    0,
920                                    slice_batch);
921     }
922 }
923
924 /* 
925  * A batch buffer for all slices, including slice state, 
926  * slice insert object and slice pak object commands
927  *
928  */
929 static dri_bo *
930 gen7_mfc_mpeg2_software_slice_batchbuffer(VADriverContextP ctx,
931                                           struct encode_state *encode_state,
932                                           struct intel_encoder_context *encoder_context)
933 {
934     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
935     struct intel_batchbuffer *batch;
936     VAEncSliceParameterBufferMPEG2 *next_slice_group_param = NULL;
937     dri_bo *batch_bo;
938     int i;
939
940     batch = mfc_context->aux_batchbuffer;
941     batch_bo = batch->buffer;
942
943     for (i = 0; i < encode_state->num_slice_params_ext; i++) {
944         if (i == encode_state->num_slice_params_ext - 1)
945             next_slice_group_param = NULL;
946         else
947             next_slice_group_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[i + 1]->buffer;
948
949         gen7_mfc_mpeg2_pipeline_slice_group(ctx, encode_state, encoder_context, i, next_slice_group_param, batch);
950     }
951
952     intel_batchbuffer_align(batch, 8);
953     
954     BEGIN_BCS_BATCH(batch, 2);
955     OUT_BCS_BATCH(batch, 0);
956     OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_END);
957     ADVANCE_BCS_BATCH(batch);
958
959     dri_bo_reference(batch_bo);
960     intel_batchbuffer_free(batch);
961     mfc_context->aux_batchbuffer = NULL;
962
963     return batch_bo;
964 }
965
966 static void
967 gen7_mfc_mpeg2_pipeline_picture_programing(VADriverContextP ctx,
968                                            struct encode_state *encode_state,
969                                            struct intel_encoder_context *encoder_context)
970 {
971     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
972
973     mfc_context->pipe_mode_select(ctx, MFX_FORMAT_MPEG2, encoder_context);
974     mfc_context->set_surface_state(ctx, encoder_context);
975     mfc_context->ind_obj_base_addr_state(ctx, encoder_context);
976     gen6_mfc_pipe_buf_addr_state(ctx, encoder_context);
977     gen6_mfc_bsp_buf_base_addr_state(ctx, encoder_context);
978     gen7_mfc_mpeg2_pic_state(ctx, encoder_context, encode_state);
979     gen7_mfc_mpeg2_qm_state(ctx, encoder_context);
980     gen7_mfc_mpeg2_fqm_state(ctx, encoder_context);
981 }
982
983 static void
984 gen7_mfc_mpeg2_pipeline_programing(VADriverContextP ctx,
985                                    struct encode_state *encode_state,
986                                    struct intel_encoder_context *encoder_context)
987 {
988     struct intel_batchbuffer *batch = encoder_context->base.batch;
989     dri_bo *slice_batch_bo;
990
991     slice_batch_bo = gen7_mfc_mpeg2_software_slice_batchbuffer(ctx, encode_state, encoder_context);
992
993     // begin programing
994     intel_batchbuffer_start_atomic_bcs(batch, 0x4000); 
995     intel_batchbuffer_emit_mi_flush(batch);
996     
997     // picture level programing
998     gen7_mfc_mpeg2_pipeline_picture_programing(ctx, encode_state, encoder_context);
999
1000     BEGIN_BCS_BATCH(batch, 2);
1001     OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8));
1002     OUT_BCS_RELOC(batch,
1003                   slice_batch_bo,
1004                   I915_GEM_DOMAIN_COMMAND, 0, 
1005                   0);
1006     ADVANCE_BCS_BATCH(batch);
1007
1008     // end programing
1009     intel_batchbuffer_end_atomic(batch);
1010
1011     dri_bo_unreference(slice_batch_bo);
1012 }
1013
1014 static VAStatus
1015 gen7_mfc_mpeg2_prepare(VADriverContextP ctx,
1016                        struct encode_state *encode_state,
1017                        struct intel_encoder_context *encoder_context)
1018 {
1019     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1020     struct object_surface *obj_surface;
1021     struct object_buffer *obj_buffer;
1022     struct i965_coded_buffer_segment *coded_buffer_segment;
1023     VAStatus vaStatus = VA_STATUS_SUCCESS;
1024     dri_bo *bo;
1025     int i;
1026
1027     /* reconstructed surface */
1028     obj_surface = encode_state->reconstructed_object;
1029     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1030     mfc_context->pre_deblocking_output.bo = obj_surface->bo;
1031     dri_bo_reference(mfc_context->pre_deblocking_output.bo);
1032     mfc_context->surface_state.width = obj_surface->orig_width;
1033     mfc_context->surface_state.height = obj_surface->orig_height;
1034     mfc_context->surface_state.w_pitch = obj_surface->width;
1035     mfc_context->surface_state.h_pitch = obj_surface->height;
1036
1037     /* forward reference */
1038     obj_surface = encode_state->reference_objects[0];
1039
1040     if (obj_surface && obj_surface->bo) {
1041         mfc_context->reference_surfaces[0].bo = obj_surface->bo;
1042         dri_bo_reference(mfc_context->reference_surfaces[0].bo);
1043     } else
1044         mfc_context->reference_surfaces[0].bo = NULL;
1045
1046     /* backward reference */
1047     obj_surface = encode_state->reference_objects[1];
1048
1049     if (obj_surface && obj_surface->bo) {
1050         mfc_context->reference_surfaces[1].bo = obj_surface->bo;
1051         dri_bo_reference(mfc_context->reference_surfaces[1].bo);
1052     } else {
1053         mfc_context->reference_surfaces[1].bo = mfc_context->reference_surfaces[0].bo;
1054
1055         if (mfc_context->reference_surfaces[1].bo)
1056             dri_bo_reference(mfc_context->reference_surfaces[1].bo);
1057     }
1058
1059     for (i = 2; i < ARRAY_ELEMS(mfc_context->reference_surfaces); i++) {
1060         mfc_context->reference_surfaces[i].bo = mfc_context->reference_surfaces[i & 1].bo;
1061
1062         if (mfc_context->reference_surfaces[i].bo)
1063             dri_bo_reference(mfc_context->reference_surfaces[i].bo);
1064     }
1065     
1066     /* input YUV surface */
1067     obj_surface = encode_state->input_yuv_object;
1068     mfc_context->uncompressed_picture_source.bo = obj_surface->bo;
1069     dri_bo_reference(mfc_context->uncompressed_picture_source.bo);
1070
1071     /* coded buffer */
1072     obj_buffer = encode_state->coded_buf_object;
1073     bo = obj_buffer->buffer_store->bo;
1074     mfc_context->mfc_indirect_pak_bse_object.bo = bo;
1075     mfc_context->mfc_indirect_pak_bse_object.offset = I965_CODEDBUFFER_HEADER_SIZE;
1076     mfc_context->mfc_indirect_pak_bse_object.end_offset = ALIGN(obj_buffer->size_element - 0x1000, 0x1000);
1077     dri_bo_reference(mfc_context->mfc_indirect_pak_bse_object.bo);
1078
1079     /* set the internal flag to 0 to indicate the coded size is unknown */
1080     dri_bo_map(bo, 1);
1081     coded_buffer_segment = (struct i965_coded_buffer_segment *)bo->virtual;
1082     coded_buffer_segment->mapped = 0;
1083     coded_buffer_segment->codec = encoder_context->codec;
1084     dri_bo_unmap(bo);
1085
1086     return vaStatus;
1087 }
1088
1089 static VAStatus
1090 gen7_mfc_mpeg2_encode_picture(VADriverContextP ctx, 
1091                               struct encode_state *encode_state,
1092                               struct intel_encoder_context *encoder_context)
1093 {
1094     gen6_mfc_init(ctx, encode_state, encoder_context);
1095     gen7_mfc_mpeg2_prepare(ctx, encode_state, encoder_context);
1096     /*Programing bcs pipeline*/
1097     gen7_mfc_mpeg2_pipeline_programing(ctx, encode_state, encoder_context);
1098     gen6_mfc_run(ctx, encode_state, encoder_context);
1099
1100     return VA_STATUS_SUCCESS;
1101 }
1102
1103 VAStatus
1104 gen7_mfc_pipeline(VADriverContextP ctx,
1105                   VAProfile profile,
1106                   struct encode_state *encode_state,
1107                   struct intel_encoder_context *encoder_context)
1108 {
1109     VAStatus vaStatus;
1110
1111     switch (profile) {
1112     case VAProfileH264ConstrainedBaseline:
1113     case VAProfileH264Main:
1114     case VAProfileH264High:
1115         vaStatus = gen6_mfc_avc_encode_picture(ctx, encode_state, encoder_context);
1116         break;
1117
1118     case VAProfileMPEG2Simple:
1119     case VAProfileMPEG2Main:
1120         vaStatus = gen7_mfc_mpeg2_encode_picture(ctx, encode_state, encoder_context);
1121         break;
1122
1123         /* FIXME: add for other profile */
1124     default:
1125         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1126         break;
1127     }
1128
1129     return vaStatus;
1130 }
1131
1132 Bool
1133 gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
1134 {
1135     struct gen6_mfc_context *mfc_context = calloc(1, sizeof(struct gen6_mfc_context));
1136
1137     if (!mfc_context)
1138         return False;
1139
1140     mfc_context->gpe_context.surface_state_binding_table.length = (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_MEDIA_SURFACES_GEN6;
1141
1142     mfc_context->gpe_context.idrt.max_entries = MAX_GPE_KERNELS;
1143     mfc_context->gpe_context.idrt.entry_size = sizeof(struct gen6_interface_descriptor_data);
1144
1145     mfc_context->gpe_context.curbe.length = 32 * 4;
1146
1147     mfc_context->gpe_context.vfe_state.max_num_threads = 60 - 1;
1148     mfc_context->gpe_context.vfe_state.num_urb_entries = 16;
1149     mfc_context->gpe_context.vfe_state.gpgpu_mode = 0;
1150     mfc_context->gpe_context.vfe_state.urb_entry_size = 59 - 1;
1151     mfc_context->gpe_context.vfe_state.curbe_allocation_size = 37 - 1;
1152
1153     i965_gpe_load_kernels(ctx,
1154                           &mfc_context->gpe_context,
1155                           gen7_mfc_kernels,
1156                           NUM_MFC_KERNEL);
1157
1158     mfc_context->pipe_mode_select = gen7_mfc_pipe_mode_select;
1159     mfc_context->set_surface_state = gen7_mfc_surface_state;
1160     mfc_context->ind_obj_base_addr_state = gen7_mfc_ind_obj_base_addr_state;
1161     mfc_context->avc_img_state = gen7_mfc_avc_img_state;
1162     mfc_context->avc_qm_state = gen7_mfc_avc_qm_state;
1163     mfc_context->avc_fqm_state = gen7_mfc_avc_fqm_state;
1164     mfc_context->insert_object = gen7_mfc_avc_insert_object;
1165     mfc_context->buffer_suface_setup = gen7_gpe_buffer_suface_setup;
1166
1167     encoder_context->mfc_context = mfc_context;
1168     encoder_context->mfc_context_destroy = gen6_mfc_context_destroy;
1169     encoder_context->mfc_pipeline = gen7_mfc_pipeline;
1170     encoder_context->mfc_brc_prepare = intel_mfc_brc_prepare;
1171
1172     return True;
1173 }