2 * Copyright © 2010-2012 Intel Corporation
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
25 * Zhao Yakui <yakui.zhao@intel.com>
26 * Xiang Haihao <haihao.xiang@intel.com>
36 #include "intel_batchbuffer.h"
37 #include "i965_defines.h"
38 #include "i965_structs.h"
39 #include "i965_drv_video.h"
40 #include "i965_encoder.h"
41 #include "i965_encoder_utils.h"
44 #include "intel_media.h"
46 #define AVC_INTRA_RDO_OFFSET 4
47 #define AVC_INTER_RDO_OFFSET 10
48 #define AVC_INTER_MSG_OFFSET 8
49 #define AVC_INTER_MV_OFFSET 48
50 #define AVC_RDO_MASK 0xFFFF
52 #define MFC_SOFTWARE_HASWELL 0
54 #define SURFACE_STATE_PADDED_SIZE MAX(SURFACE_STATE_PADDED_SIZE_GEN6, SURFACE_STATE_PADDED_SIZE_GEN7)
55 #define SURFACE_STATE_OFFSET(index) (SURFACE_STATE_PADDED_SIZE * index)
56 #define BINDING_TABLE_OFFSET(index) (SURFACE_STATE_OFFSET(MAX_MEDIA_SURFACES_GEN6) + sizeof(unsigned int) * index)
59 #define IS_STEPPING_BPLUS(i965) ((i965->intel.revision) >= B0_STEP_REV)
61 static const uint32_t gen75_mfc_batchbuffer_avc[][4] = {
62 #include "shaders/utils/mfc_batchbuffer_hsw.g75b"
65 static struct i965_kernel gen75_mfc_kernels[] = {
67 "MFC AVC INTRA BATCHBUFFER ",
68 MFC_BATCHBUFFER_AVC_INTRA,
69 gen75_mfc_batchbuffer_avc,
70 sizeof(gen75_mfc_batchbuffer_avc),
75 #define INTER_MODE_MASK 0x03
76 #define INTER_8X8 0x03
77 #define INTER_16X8 0x01
78 #define INTER_8X16 0x02
79 #define SUBMB_SHAPE_MASK 0x00FF00
81 #define INTER_MV8 (4 << 20)
82 #define INTER_MV32 (6 << 20)
86 gen75_mfc_pipe_mode_select(VADriverContextP ctx,
88 struct intel_encoder_context *encoder_context)
90 struct intel_batchbuffer *batch = encoder_context->base.batch;
91 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
92 assert(standard_select == MFX_FORMAT_MPEG2 ||
93 standard_select == MFX_FORMAT_AVC);
95 BEGIN_BCS_BATCH(batch, 5);
97 OUT_BCS_BATCH(batch, MFX_PIPE_MODE_SELECT | (5 - 2));
99 (MFX_LONG_MODE << 17) | /* Must be long format for encoder */
100 (MFD_MODE_VLD << 15) | /* VLD mode */
101 (0 << 10) | /* Stream-Out Enable */
102 ((!!mfc_context->post_deblocking_output.bo) << 9) | /* Post Deblocking Output */
103 ((!!mfc_context->pre_deblocking_output.bo) << 8) | /* Pre Deblocking Output */
104 (0 << 5) | /* not in stitch mode */
105 (1 << 4) | /* encoding mode */
106 (standard_select << 0)); /* standard select: avc or mpeg2 */
108 (0 << 7) | /* expand NOA bus flag */
109 (0 << 6) | /* disable slice-level clock gating */
110 (0 << 5) | /* disable clock gating for NOA */
111 (0 << 4) | /* terminate if AVC motion and POC table error occurs */
112 (0 << 3) | /* terminate if AVC mbdata error occurs */
113 (0 << 2) | /* terminate if AVC CABAC/CAVLC decode error occurs */
116 OUT_BCS_BATCH(batch, 0);
117 OUT_BCS_BATCH(batch, 0);
119 ADVANCE_BCS_BATCH(batch);
123 gen75_mfc_surface_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
125 struct intel_batchbuffer *batch = encoder_context->base.batch;
126 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
128 BEGIN_BCS_BATCH(batch, 6);
130 OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
131 OUT_BCS_BATCH(batch, 0);
133 ((mfc_context->surface_state.height - 1) << 18) |
134 ((mfc_context->surface_state.width - 1) << 4));
136 (MFX_SURFACE_PLANAR_420_8 << 28) | /* 420 planar YUV surface */
137 (1 << 27) | /* must be 1 for interleave U/V, hardware requirement */
138 (0 << 22) | /* surface object control state, FIXME??? */
139 ((mfc_context->surface_state.w_pitch - 1) << 3) | /* pitch */
140 (0 << 2) | /* must be 0 for interleave U/V */
141 (1 << 1) | /* must be tiled */
142 (I965_TILEWALK_YMAJOR << 0)); /* tile walk, TILEWALK_YMAJOR */
144 (0 << 16) | /* must be 0 for interleave U/V */
145 (mfc_context->surface_state.h_pitch)); /* y offset for U(cb) */
146 OUT_BCS_BATCH(batch, 0);
148 ADVANCE_BCS_BATCH(batch);
152 gen75_mfc_ind_obj_base_addr_state_bplus(VADriverContextP ctx,
153 struct intel_encoder_context *encoder_context)
155 struct intel_batchbuffer *batch = encoder_context->base.batch;
156 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
157 struct gen6_vme_context *vme_context = encoder_context->vme_context;
159 BEGIN_BCS_BATCH(batch, 26);
161 OUT_BCS_BATCH(batch, MFX_IND_OBJ_BASE_ADDR_STATE | (26 - 2));
162 /* the DW1-3 is for the MFX indirect bistream offset */
163 OUT_BCS_BATCH(batch, 0);
164 OUT_BCS_BATCH(batch, 0);
165 OUT_BCS_BATCH(batch, 0);
166 /* the DW4-5 is the MFX upper bound */
167 OUT_BCS_BATCH(batch, 0);
168 OUT_BCS_BATCH(batch, 0);
170 /* the DW6-10 is for MFX Indirect MV Object Base Address */
171 OUT_BCS_RELOC(batch, vme_context->vme_output.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
172 OUT_BCS_BATCH(batch, 0);
173 OUT_BCS_BATCH(batch, 0);
174 OUT_BCS_BATCH(batch, 0x80000000); /* must set, up to 2G */
175 OUT_BCS_BATCH(batch, 0);
177 /* the DW11-15 is for MFX IT-COFF. Not used on encoder */
178 OUT_BCS_BATCH(batch, 0);
179 OUT_BCS_BATCH(batch, 0);
180 OUT_BCS_BATCH(batch, 0);
181 OUT_BCS_BATCH(batch, 0);
182 OUT_BCS_BATCH(batch, 0);
184 /* the DW16-20 is for MFX indirect DBLK. Not used on encoder */
185 OUT_BCS_BATCH(batch, 0);
186 OUT_BCS_BATCH(batch, 0);
187 OUT_BCS_BATCH(batch, 0);
188 OUT_BCS_BATCH(batch, 0);
189 OUT_BCS_BATCH(batch, 0);
191 /* the DW21-25 is for MFC Indirect PAK-BSE Object Base Address for Encoder*/
193 mfc_context->mfc_indirect_pak_bse_object.bo,
194 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
196 OUT_BCS_BATCH(batch, 0);
197 OUT_BCS_BATCH(batch, 0);
200 mfc_context->mfc_indirect_pak_bse_object.bo,
201 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
202 mfc_context->mfc_indirect_pak_bse_object.end_offset);
203 OUT_BCS_BATCH(batch, 0);
205 ADVANCE_BCS_BATCH(batch);
209 gen75_mfc_ind_obj_base_addr_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
211 struct intel_batchbuffer *batch = encoder_context->base.batch;
212 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
213 struct gen6_vme_context *vme_context = encoder_context->vme_context;
214 struct i965_driver_data *i965 = i965_driver_data(ctx);
216 if (IS_STEPPING_BPLUS(i965)) {
217 gen75_mfc_ind_obj_base_addr_state_bplus(ctx, encoder_context);
221 BEGIN_BCS_BATCH(batch, 11);
223 OUT_BCS_BATCH(batch, MFX_IND_OBJ_BASE_ADDR_STATE | (11 - 2));
224 OUT_BCS_BATCH(batch, 0);
225 OUT_BCS_BATCH(batch, 0);
226 /* MFX Indirect MV Object Base Address */
227 OUT_BCS_RELOC(batch, vme_context->vme_output.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
228 OUT_BCS_BATCH(batch, 0x80000000); /* must set, up to 2G */
229 OUT_BCS_BATCH(batch, 0);
230 OUT_BCS_BATCH(batch, 0);
231 OUT_BCS_BATCH(batch, 0);
232 OUT_BCS_BATCH(batch, 0);
233 /*MFC Indirect PAK-BSE Object Base Address for Encoder*/
235 mfc_context->mfc_indirect_pak_bse_object.bo,
236 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
239 mfc_context->mfc_indirect_pak_bse_object.bo,
240 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
241 mfc_context->mfc_indirect_pak_bse_object.end_offset);
243 ADVANCE_BCS_BATCH(batch);
247 gen75_mfc_avc_img_state(VADriverContextP ctx, struct encode_state *encode_state,
248 struct intel_encoder_context *encoder_context)
250 struct intel_batchbuffer *batch = encoder_context->base.batch;
251 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
252 VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
254 int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
255 int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
257 BEGIN_BCS_BATCH(batch, 16);
259 OUT_BCS_BATCH(batch, MFX_AVC_IMG_STATE | (16 - 2));
260 /*DW1. MB setting of frame */
262 ((width_in_mbs * height_in_mbs - 1) & 0xFFFF));
264 ((height_in_mbs - 1) << 16) |
265 ((width_in_mbs - 1) << 0));
268 (0 << 24) | /* Second Chroma QP Offset */
269 (0 << 16) | /* Chroma QP Offset */
270 (0 << 14) | /* Max-bit conformance Intra flag */
271 (0 << 13) | /* Max Macroblock size conformance Inter flag */
272 (pPicParameter->pic_fields.bits.weighted_pred_flag << 12) | /*Weighted_Pred_Flag */
273 (pPicParameter->pic_fields.bits.weighted_bipred_idc << 10) | /* Weighted_BiPred_Idc */
274 (0 << 8) | /* FIXME: Image Structure */
275 (0 << 0) ); /* Current Decoed Image Frame Store ID, reserved in Encode mode */
277 (0 << 16) | /* Mininum Frame size */
278 (0 << 15) | /* Disable reading of Macroblock Status Buffer */
279 (0 << 14) | /* Load BitStream Pointer only once, 1 slic 1 frame */
280 (0 << 13) | /* CABAC 0 word insertion test enable */
281 (1 << 12) | /* MVUnpackedEnable,compliant to DXVA */
282 (1 << 10) | /* Chroma Format IDC, 4:2:0 */
283 (0 << 8) | /* FIXME: MbMvFormatFlag */
284 (pPicParameter->pic_fields.bits.entropy_coding_mode_flag << 7) | /*0:CAVLC encoding mode,1:CABAC*/
285 (0 << 6) | /* Only valid for VLD decoding mode */
286 (0 << 5) | /* Constrained Intra Predition Flag, from PPS */
287 (0 << 4) | /* Direct 8x8 inference flag */
288 (pPicParameter->pic_fields.bits.transform_8x8_mode_flag << 3) | /*8x8 or 4x4 IDCT Transform Mode Flag*/
289 (1 << 2) | /* Frame MB only flag */
290 (0 << 1) | /* MBAFF mode is in active */
291 (0 << 0)); /* Field picture flag */
292 /* DW5 Trellis quantization */
293 OUT_BCS_BATCH(batch, 0); /* Mainly about MB rate control and debug, just ignoring */
294 OUT_BCS_BATCH(batch, /* Inter and Intra Conformance Max size limit */
295 (0xBB8 << 16) | /* InterMbMaxSz */
296 (0xEE8) ); /* IntraMbMaxSz */
297 OUT_BCS_BATCH(batch, 0); /* Reserved */
299 OUT_BCS_BATCH(batch, 0); /* Slice QP Delta for bitrate control */
300 OUT_BCS_BATCH(batch, 0); /* Slice QP Delta for bitrate control */
301 /* DW10. Bit setting for MB */
302 OUT_BCS_BATCH(batch, 0x8C000000);
303 OUT_BCS_BATCH(batch, 0x00010000);
305 OUT_BCS_BATCH(batch, 0);
306 OUT_BCS_BATCH(batch, 0x02010100);
307 /* DW14. For short format */
308 OUT_BCS_BATCH(batch, 0);
309 OUT_BCS_BATCH(batch, 0);
311 ADVANCE_BCS_BATCH(batch);
315 gen75_mfc_qm_state(VADriverContextP ctx,
319 struct intel_encoder_context *encoder_context)
321 struct intel_batchbuffer *batch = encoder_context->base.batch;
322 unsigned int qm_buffer[16];
324 assert(qm_length <= 16);
325 assert(sizeof(*qm) == 4);
326 memcpy(qm_buffer, qm, qm_length * 4);
328 BEGIN_BCS_BATCH(batch, 18);
329 OUT_BCS_BATCH(batch, MFX_QM_STATE | (18 - 2));
330 OUT_BCS_BATCH(batch, qm_type << 0);
331 intel_batchbuffer_data(batch, qm_buffer, 16 * 4);
332 ADVANCE_BCS_BATCH(batch);
336 gen75_mfc_avc_qm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
338 unsigned int qm[16] = {
339 0x10101010, 0x10101010, 0x10101010, 0x10101010,
340 0x10101010, 0x10101010, 0x10101010, 0x10101010,
341 0x10101010, 0x10101010, 0x10101010, 0x10101010,
342 0x10101010, 0x10101010, 0x10101010, 0x10101010
345 gen75_mfc_qm_state(ctx, MFX_QM_AVC_4X4_INTRA_MATRIX, qm, 12, encoder_context);
346 gen75_mfc_qm_state(ctx, MFX_QM_AVC_4X4_INTER_MATRIX, qm, 12, encoder_context);
347 gen75_mfc_qm_state(ctx, MFX_QM_AVC_8x8_INTRA_MATRIX, qm, 16, encoder_context);
348 gen75_mfc_qm_state(ctx, MFX_QM_AVC_8x8_INTER_MATRIX, qm, 16, encoder_context);
352 gen75_mfc_fqm_state(VADriverContextP ctx,
356 struct intel_encoder_context *encoder_context)
358 struct intel_batchbuffer *batch = encoder_context->base.batch;
359 unsigned int fqm_buffer[32];
361 assert(fqm_length <= 32);
362 assert(sizeof(*fqm) == 4);
363 memcpy(fqm_buffer, fqm, fqm_length * 4);
365 BEGIN_BCS_BATCH(batch, 34);
366 OUT_BCS_BATCH(batch, MFX_FQM_STATE | (34 - 2));
367 OUT_BCS_BATCH(batch, fqm_type << 0);
368 intel_batchbuffer_data(batch, fqm_buffer, 32 * 4);
369 ADVANCE_BCS_BATCH(batch);
373 gen75_mfc_avc_fqm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
375 unsigned int qm[32] = {
376 0x10001000, 0x10001000, 0x10001000, 0x10001000,
377 0x10001000, 0x10001000, 0x10001000, 0x10001000,
378 0x10001000, 0x10001000, 0x10001000, 0x10001000,
379 0x10001000, 0x10001000, 0x10001000, 0x10001000,
380 0x10001000, 0x10001000, 0x10001000, 0x10001000,
381 0x10001000, 0x10001000, 0x10001000, 0x10001000,
382 0x10001000, 0x10001000, 0x10001000, 0x10001000,
383 0x10001000, 0x10001000, 0x10001000, 0x10001000
386 gen75_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTRA_MATRIX, qm, 24, encoder_context);
387 gen75_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTER_MATRIX, qm, 24, encoder_context);
388 gen75_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTRA_MATRIX, qm, 32, encoder_context);
389 gen75_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTER_MATRIX, qm, 32, encoder_context);
393 gen75_mfc_avc_insert_object(VADriverContextP ctx, struct intel_encoder_context *encoder_context,
394 unsigned int *insert_data, int lenght_in_dws, int data_bits_in_last_dw,
395 int skip_emul_byte_count, int is_last_header, int is_end_of_slice, int emulation_flag,
396 struct intel_batchbuffer *batch)
399 batch = encoder_context->base.batch;
401 BEGIN_BCS_BATCH(batch, lenght_in_dws + 2);
403 OUT_BCS_BATCH(batch, MFX_INSERT_OBJECT | (lenght_in_dws + 2 - 2));
405 (0 << 16) | /* always start at offset 0 */
406 (data_bits_in_last_dw << 8) |
407 (skip_emul_byte_count << 4) |
408 (!!emulation_flag << 3) |
409 ((!!is_last_header) << 2) |
410 ((!!is_end_of_slice) << 1) |
411 (0 << 0)); /* FIXME: ??? */
412 intel_batchbuffer_data(batch, insert_data, lenght_in_dws * 4);
414 ADVANCE_BCS_BATCH(batch);
418 static void gen75_mfc_init(VADriverContextP ctx,
419 struct encode_state *encode_state,
420 struct intel_encoder_context *encoder_context)
422 struct i965_driver_data *i965 = i965_driver_data(ctx);
423 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
426 int width_in_mbs = 0;
427 int height_in_mbs = 0;
428 int slice_batchbuffer_size;
430 if (encoder_context->codec == CODEC_H264 ||
431 encoder_context->codec == CODEC_H264_MVC) {
432 VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
433 width_in_mbs = pSequenceParameter->picture_width_in_mbs;
434 height_in_mbs = pSequenceParameter->picture_height_in_mbs;
436 VAEncSequenceParameterBufferMPEG2 *pSequenceParameter = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
438 assert(encoder_context->codec == CODEC_MPEG2);
440 width_in_mbs = ALIGN(pSequenceParameter->picture_width, 16) / 16;
441 height_in_mbs = ALIGN(pSequenceParameter->picture_height, 16) / 16;
444 slice_batchbuffer_size = 64 * width_in_mbs * height_in_mbs + 4096 +
445 (SLICE_HEADER + SLICE_TAIL) * encode_state->num_slice_params_ext;
447 /*Encode common setup for MFC*/
448 dri_bo_unreference(mfc_context->post_deblocking_output.bo);
449 mfc_context->post_deblocking_output.bo = NULL;
451 dri_bo_unreference(mfc_context->pre_deblocking_output.bo);
452 mfc_context->pre_deblocking_output.bo = NULL;
454 dri_bo_unreference(mfc_context->uncompressed_picture_source.bo);
455 mfc_context->uncompressed_picture_source.bo = NULL;
457 dri_bo_unreference(mfc_context->mfc_indirect_pak_bse_object.bo);
458 mfc_context->mfc_indirect_pak_bse_object.bo = NULL;
460 for (i = 0; i < NUM_MFC_DMV_BUFFERS; i++){
461 if ( mfc_context->direct_mv_buffers[i].bo != NULL);
462 dri_bo_unreference(mfc_context->direct_mv_buffers[i].bo);
463 mfc_context->direct_mv_buffers[i].bo = NULL;
466 for (i = 0; i < MAX_MFC_REFERENCE_SURFACES; i++){
467 if (mfc_context->reference_surfaces[i].bo != NULL)
468 dri_bo_unreference(mfc_context->reference_surfaces[i].bo);
469 mfc_context->reference_surfaces[i].bo = NULL;
472 dri_bo_unreference(mfc_context->intra_row_store_scratch_buffer.bo);
473 bo = dri_bo_alloc(i965->intel.bufmgr,
478 mfc_context->intra_row_store_scratch_buffer.bo = bo;
480 dri_bo_unreference(mfc_context->macroblock_status_buffer.bo);
481 bo = dri_bo_alloc(i965->intel.bufmgr,
483 width_in_mbs * height_in_mbs * 16,
486 mfc_context->macroblock_status_buffer.bo = bo;
488 dri_bo_unreference(mfc_context->deblocking_filter_row_store_scratch_buffer.bo);
489 bo = dri_bo_alloc(i965->intel.bufmgr,
491 4 * width_in_mbs * 64, /* 4 * width_in_mbs * 64 */
494 mfc_context->deblocking_filter_row_store_scratch_buffer.bo = bo;
496 dri_bo_unreference(mfc_context->bsd_mpc_row_store_scratch_buffer.bo);
497 bo = dri_bo_alloc(i965->intel.bufmgr,
499 2 * width_in_mbs * 64, /* 2 * width_in_mbs * 64 */
502 mfc_context->bsd_mpc_row_store_scratch_buffer.bo = bo;
504 dri_bo_unreference(mfc_context->mfc_batchbuffer_surface.bo);
505 mfc_context->mfc_batchbuffer_surface.bo = NULL;
507 dri_bo_unreference(mfc_context->aux_batchbuffer_surface.bo);
508 mfc_context->aux_batchbuffer_surface.bo = NULL;
510 if (mfc_context->aux_batchbuffer)
511 intel_batchbuffer_free(mfc_context->aux_batchbuffer);
513 mfc_context->aux_batchbuffer = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD,
514 slice_batchbuffer_size);
515 mfc_context->aux_batchbuffer_surface.bo = mfc_context->aux_batchbuffer->buffer;
516 dri_bo_reference(mfc_context->aux_batchbuffer_surface.bo);
517 mfc_context->aux_batchbuffer_surface.pitch = 16;
518 mfc_context->aux_batchbuffer_surface.num_blocks = mfc_context->aux_batchbuffer->size / 16;
519 mfc_context->aux_batchbuffer_surface.size_block = 16;
521 i965_gpe_context_init(ctx, &mfc_context->gpe_context);
525 gen75_mfc_pipe_buf_addr_state_bplus(VADriverContextP ctx,
526 struct intel_encoder_context *encoder_context)
528 struct intel_batchbuffer *batch = encoder_context->base.batch;
529 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
532 BEGIN_BCS_BATCH(batch, 61);
534 OUT_BCS_BATCH(batch, MFX_PIPE_BUF_ADDR_STATE | (61 - 2));
536 /* the DW1-3 is for pre_deblocking */
537 if (mfc_context->pre_deblocking_output.bo)
538 OUT_BCS_RELOC(batch, mfc_context->pre_deblocking_output.bo,
539 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
542 OUT_BCS_BATCH(batch, 0); /* pre output addr */
544 OUT_BCS_BATCH(batch, 0);
545 OUT_BCS_BATCH(batch, 0);
546 /* the DW4-6 is for the post_deblocking */
548 if (mfc_context->post_deblocking_output.bo)
549 OUT_BCS_RELOC(batch, mfc_context->post_deblocking_output.bo,
550 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
551 0); /* post output addr */
553 OUT_BCS_BATCH(batch, 0);
554 OUT_BCS_BATCH(batch, 0);
555 OUT_BCS_BATCH(batch, 0);
557 /* the DW7-9 is for the uncompressed_picture */
558 OUT_BCS_RELOC(batch, mfc_context->uncompressed_picture_source.bo,
559 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
560 0); /* uncompressed data */
562 OUT_BCS_BATCH(batch, 0);
563 OUT_BCS_BATCH(batch, 0);
565 /* the DW10-12 is for the mb status */
566 OUT_BCS_RELOC(batch, mfc_context->macroblock_status_buffer.bo,
567 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
568 0); /* StreamOut data*/
569 OUT_BCS_BATCH(batch, 0);
570 OUT_BCS_BATCH(batch, 0);
572 /* the DW13-15 is for the intra_row_store_scratch */
573 OUT_BCS_RELOC(batch, mfc_context->intra_row_store_scratch_buffer.bo,
574 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
576 OUT_BCS_BATCH(batch, 0);
577 OUT_BCS_BATCH(batch, 0);
579 /* the DW16-18 is for the deblocking filter */
580 OUT_BCS_RELOC(batch, mfc_context->deblocking_filter_row_store_scratch_buffer.bo,
581 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
583 OUT_BCS_BATCH(batch, 0);
584 OUT_BCS_BATCH(batch, 0);
586 /* the DW 19-50 is for Reference pictures*/
587 for (i = 0; i < ARRAY_ELEMS(mfc_context->reference_surfaces); i++) {
588 if ( mfc_context->reference_surfaces[i].bo != NULL) {
589 OUT_BCS_RELOC(batch, mfc_context->reference_surfaces[i].bo,
590 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
593 OUT_BCS_BATCH(batch, 0);
595 OUT_BCS_BATCH(batch, 0);
597 OUT_BCS_BATCH(batch, 0);
599 /* The DW 52-54 is for the MB status buffer */
600 OUT_BCS_RELOC(batch, mfc_context->macroblock_status_buffer.bo,
601 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
602 0); /* Macroblock status buffer*/
604 OUT_BCS_BATCH(batch, 0);
605 OUT_BCS_BATCH(batch, 0);
607 /* the DW 55-57 is the ILDB buffer */
608 OUT_BCS_BATCH(batch, 0);
609 OUT_BCS_BATCH(batch, 0);
610 OUT_BCS_BATCH(batch, 0);
612 /* the DW 58-60 is the second ILDB buffer */
613 OUT_BCS_BATCH(batch, 0);
614 OUT_BCS_BATCH(batch, 0);
615 OUT_BCS_BATCH(batch, 0);
616 ADVANCE_BCS_BATCH(batch);
620 gen75_mfc_pipe_buf_addr_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
622 struct intel_batchbuffer *batch = encoder_context->base.batch;
623 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
624 struct i965_driver_data *i965 = i965_driver_data(ctx);
627 if (IS_STEPPING_BPLUS(i965)) {
628 gen75_mfc_pipe_buf_addr_state_bplus(ctx, encoder_context);
632 BEGIN_BCS_BATCH(batch, 25);
634 OUT_BCS_BATCH(batch, MFX_PIPE_BUF_ADDR_STATE | (25 - 2));
636 if (mfc_context->pre_deblocking_output.bo)
637 OUT_BCS_RELOC(batch, mfc_context->pre_deblocking_output.bo,
638 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
641 OUT_BCS_BATCH(batch, 0); /* pre output addr */
643 if (mfc_context->post_deblocking_output.bo)
644 OUT_BCS_RELOC(batch, mfc_context->post_deblocking_output.bo,
645 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
646 0); /* post output addr */
648 OUT_BCS_BATCH(batch, 0);
650 OUT_BCS_RELOC(batch, mfc_context->uncompressed_picture_source.bo,
651 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
652 0); /* uncompressed data */
653 OUT_BCS_RELOC(batch, mfc_context->macroblock_status_buffer.bo,
654 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
655 0); /* StreamOut data*/
656 OUT_BCS_RELOC(batch, mfc_context->intra_row_store_scratch_buffer.bo,
657 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
659 OUT_BCS_RELOC(batch, mfc_context->deblocking_filter_row_store_scratch_buffer.bo,
660 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
662 /* 7..22 Reference pictures*/
663 for (i = 0; i < ARRAY_ELEMS(mfc_context->reference_surfaces); i++) {
664 if ( mfc_context->reference_surfaces[i].bo != NULL) {
665 OUT_BCS_RELOC(batch, mfc_context->reference_surfaces[i].bo,
666 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
669 OUT_BCS_BATCH(batch, 0);
672 OUT_BCS_RELOC(batch, mfc_context->macroblock_status_buffer.bo,
673 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
674 0); /* Macroblock status buffer*/
676 OUT_BCS_BATCH(batch, 0);
678 ADVANCE_BCS_BATCH(batch);
682 gen75_mfc_avc_directmode_state_bplus(VADriverContextP ctx,
683 struct intel_encoder_context *encoder_context)
685 struct intel_batchbuffer *batch = encoder_context->base.batch;
686 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
690 BEGIN_BCS_BATCH(batch, 71);
692 OUT_BCS_BATCH(batch, MFX_AVC_DIRECTMODE_STATE | (71 - 2));
694 /* Reference frames and Current frames */
695 /* the DW1-32 is for the direct MV for reference */
696 for(i = 0; i < NUM_MFC_DMV_BUFFERS - 2; i += 2) {
697 if ( mfc_context->direct_mv_buffers[i].bo != NULL) {
698 OUT_BCS_RELOC(batch, mfc_context->direct_mv_buffers[i].bo,
699 I915_GEM_DOMAIN_INSTRUCTION, 0,
701 OUT_BCS_BATCH(batch, 0);
703 OUT_BCS_BATCH(batch, 0);
704 OUT_BCS_BATCH(batch, 0);
707 OUT_BCS_BATCH(batch, 0);
709 /* the DW34-36 is the MV for the current reference */
710 OUT_BCS_RELOC(batch, mfc_context->direct_mv_buffers[NUM_MFC_DMV_BUFFERS - 2].bo,
711 I915_GEM_DOMAIN_INSTRUCTION, 0,
714 OUT_BCS_BATCH(batch, 0);
715 OUT_BCS_BATCH(batch, 0);
718 for(i = 0; i < 32; i++) {
719 OUT_BCS_BATCH(batch, i/2);
721 OUT_BCS_BATCH(batch, 0);
722 OUT_BCS_BATCH(batch, 0);
724 ADVANCE_BCS_BATCH(batch);
728 gen75_mfc_avc_directmode_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
730 struct intel_batchbuffer *batch = encoder_context->base.batch;
731 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
732 struct i965_driver_data *i965 = i965_driver_data(ctx);
735 if (IS_STEPPING_BPLUS(i965)) {
736 gen75_mfc_avc_directmode_state_bplus(ctx, encoder_context);
740 BEGIN_BCS_BATCH(batch, 69);
742 OUT_BCS_BATCH(batch, MFX_AVC_DIRECTMODE_STATE | (69 - 2));
744 /* Reference frames and Current frames */
745 for(i = 0; i < NUM_MFC_DMV_BUFFERS; i++) {
746 if ( mfc_context->direct_mv_buffers[i].bo != NULL) {
747 OUT_BCS_RELOC(batch, mfc_context->direct_mv_buffers[i].bo,
748 I915_GEM_DOMAIN_INSTRUCTION, 0,
751 OUT_BCS_BATCH(batch, 0);
756 for(i = 0; i < 32; i++) {
757 OUT_BCS_BATCH(batch, i/2);
759 OUT_BCS_BATCH(batch, 0);
760 OUT_BCS_BATCH(batch, 0);
762 ADVANCE_BCS_BATCH(batch);
767 gen75_mfc_bsp_buf_base_addr_state_bplus(VADriverContextP ctx,
768 struct intel_encoder_context *encoder_context)
770 struct intel_batchbuffer *batch = encoder_context->base.batch;
771 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
773 BEGIN_BCS_BATCH(batch, 10);
775 OUT_BCS_BATCH(batch, MFX_BSP_BUF_BASE_ADDR_STATE | (10 - 2));
776 OUT_BCS_RELOC(batch, mfc_context->bsd_mpc_row_store_scratch_buffer.bo,
777 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
779 OUT_BCS_BATCH(batch, 0);
780 OUT_BCS_BATCH(batch, 0);
782 /* the DW4-6 is for MPR Row Store Scratch Buffer Base Address */
783 OUT_BCS_BATCH(batch, 0);
784 OUT_BCS_BATCH(batch, 0);
785 OUT_BCS_BATCH(batch, 0);
787 /* the DW7-9 is for Bitplane Read Buffer Base Address */
788 OUT_BCS_BATCH(batch, 0);
789 OUT_BCS_BATCH(batch, 0);
790 OUT_BCS_BATCH(batch, 0);
792 ADVANCE_BCS_BATCH(batch);
796 gen75_mfc_bsp_buf_base_addr_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
798 struct intel_batchbuffer *batch = encoder_context->base.batch;
799 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
800 struct i965_driver_data *i965 = i965_driver_data(ctx);
802 if (IS_STEPPING_BPLUS(i965)) {
803 gen75_mfc_bsp_buf_base_addr_state_bplus(ctx, encoder_context);
807 BEGIN_BCS_BATCH(batch, 4);
809 OUT_BCS_BATCH(batch, MFX_BSP_BUF_BASE_ADDR_STATE | (4 - 2));
810 OUT_BCS_RELOC(batch, mfc_context->bsd_mpc_row_store_scratch_buffer.bo,
811 I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
813 OUT_BCS_BATCH(batch, 0);
814 OUT_BCS_BATCH(batch, 0);
816 ADVANCE_BCS_BATCH(batch);
820 static void gen75_mfc_avc_pipeline_picture_programing( VADriverContextP ctx,
821 struct encode_state *encode_state,
822 struct intel_encoder_context *encoder_context)
824 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
826 mfc_context->pipe_mode_select(ctx, MFX_FORMAT_AVC, encoder_context);
827 mfc_context->set_surface_state(ctx, encoder_context);
828 mfc_context->ind_obj_base_addr_state(ctx, encoder_context);
829 gen75_mfc_pipe_buf_addr_state(ctx, encoder_context);
830 gen75_mfc_bsp_buf_base_addr_state(ctx, encoder_context);
831 mfc_context->avc_img_state(ctx, encode_state, encoder_context);
832 mfc_context->avc_qm_state(ctx, encoder_context);
833 mfc_context->avc_fqm_state(ctx, encoder_context);
834 gen75_mfc_avc_directmode_state(ctx, encoder_context);
835 intel_mfc_avc_ref_idx_state(ctx, encode_state, encoder_context);
839 static VAStatus gen75_mfc_run(VADriverContextP ctx,
840 struct encode_state *encode_state,
841 struct intel_encoder_context *encoder_context)
843 struct intel_batchbuffer *batch = encoder_context->base.batch;
845 intel_batchbuffer_flush(batch); //run the pipeline
847 return VA_STATUS_SUCCESS;
852 gen75_mfc_stop(VADriverContextP ctx,
853 struct encode_state *encode_state,
854 struct intel_encoder_context *encoder_context,
855 int *encoded_bits_size)
857 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
858 VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
859 VACodedBufferSegment *coded_buffer_segment;
861 vaStatus = i965_MapBuffer(ctx, pPicParameter->coded_buf, (void **)&coded_buffer_segment);
862 assert(vaStatus == VA_STATUS_SUCCESS);
863 *encoded_bits_size = coded_buffer_segment->size * 8;
864 i965_UnmapBuffer(ctx, pPicParameter->coded_buf);
866 return VA_STATUS_SUCCESS;
871 gen75_mfc_avc_slice_state(VADriverContextP ctx,
872 VAEncPictureParameterBufferH264 *pic_param,
873 VAEncSliceParameterBufferH264 *slice_param,
874 struct encode_state *encode_state,
875 struct intel_encoder_context *encoder_context,
876 int rate_control_enable,
878 struct intel_batchbuffer *batch)
880 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
881 int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
882 int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
883 int beginmb = slice_param->macroblock_address;
884 int endmb = beginmb + slice_param->num_macroblocks;
885 int beginx = beginmb % width_in_mbs;
886 int beginy = beginmb / width_in_mbs;
887 int nextx = endmb % width_in_mbs;
888 int nexty = endmb / width_in_mbs;
889 int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
890 int last_slice = (endmb == (width_in_mbs * height_in_mbs));
892 unsigned char correct[6], grow, shrink;
894 int weighted_pred_idc = 0;
895 unsigned int luma_log2_weight_denom = slice_param->luma_log2_weight_denom;
896 unsigned int chroma_log2_weight_denom = slice_param->chroma_log2_weight_denom;
897 int num_ref_l0 = 0, num_ref_l1 = 0;
900 batch = encoder_context->base.batch;
902 if (slice_type == SLICE_TYPE_I) {
903 luma_log2_weight_denom = 0;
904 chroma_log2_weight_denom = 0;
905 } else if (slice_type == SLICE_TYPE_P) {
906 weighted_pred_idc = pic_param->pic_fields.bits.weighted_pred_flag;
907 num_ref_l0 = pic_param->num_ref_idx_l0_active_minus1 + 1;
909 if (slice_param->num_ref_idx_active_override_flag)
910 num_ref_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
911 } else if (slice_type == SLICE_TYPE_B) {
912 weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc;
913 num_ref_l0 = pic_param->num_ref_idx_l0_active_minus1 + 1;
914 num_ref_l1 = pic_param->num_ref_idx_l1_active_minus1 + 1;
916 if (slice_param->num_ref_idx_active_override_flag) {
917 num_ref_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
918 num_ref_l1 = slice_param->num_ref_idx_l1_active_minus1 + 1;
921 if (weighted_pred_idc == 2) {
922 /* 8.4.3 - Derivation process for prediction weights (8-279) */
923 luma_log2_weight_denom = 5;
924 chroma_log2_weight_denom = 5;
928 maxQpN = mfc_context->bit_rate_control_context[slice_type].MaxQpNegModifier;
929 maxQpP = mfc_context->bit_rate_control_context[slice_type].MaxQpPosModifier;
931 for (i = 0; i < 6; i++)
932 correct[i] = mfc_context->bit_rate_control_context[slice_type].Correct[i];
934 grow = mfc_context->bit_rate_control_context[slice_type].GrowInit +
935 (mfc_context->bit_rate_control_context[slice_type].GrowResistance << 4);
936 shrink = mfc_context->bit_rate_control_context[slice_type].ShrinkInit +
937 (mfc_context->bit_rate_control_context[slice_type].ShrinkResistance << 4);
939 BEGIN_BCS_BATCH(batch, 11);;
941 OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2) );
942 OUT_BCS_BATCH(batch, slice_type); /*Slice Type: I:P:B Slice*/
947 (chroma_log2_weight_denom << 8) |
948 (luma_log2_weight_denom << 0));
951 (weighted_pred_idc << 30) |
952 (slice_param->direct_spatial_mv_pred_flag<<29) | /*Direct Prediction Type*/
953 (slice_param->disable_deblocking_filter_idc << 27) |
954 (slice_param->cabac_init_idc << 24) |
955 (qp<<16) | /*Slice Quantization Parameter*/
956 ((slice_param->slice_beta_offset_div2 & 0xf) << 8) |
957 ((slice_param->slice_alpha_c0_offset_div2 & 0xf) << 0));
959 (beginy << 24) | /*First MB X&Y , the begin postion of current slice*/
961 slice_param->macroblock_address );
962 OUT_BCS_BATCH(batch, (nexty << 16) | nextx); /*Next slice first MB X&Y*/
964 (0/*rate_control_enable*/ << 31) | /*in CBR mode RateControlCounterEnable = enable*/
965 (1 << 30) | /*ResetRateControlCounter*/
966 (0 << 28) | /*RC Triggle Mode = Always Rate Control*/
967 (4 << 24) | /*RC Stable Tolerance, middle level*/
968 (0/*rate_control_enable*/ << 23) | /*RC Panic Enable*/
969 (0 << 22) | /*QP mode, don't modfiy CBP*/
970 (0 << 21) | /*MB Type Direct Conversion Enabled*/
971 (0 << 20) | /*MB Type Skip Conversion Enabled*/
972 (last_slice << 19) | /*IsLastSlice*/
973 (0 << 18) | /*BitstreamOutputFlag Compressed BitStream Output Disable Flag 0:enable 1:disable*/
974 (1 << 17) | /*HeaderPresentFlag*/
975 (1 << 16) | /*SliceData PresentFlag*/
976 (1 << 15) | /*TailPresentFlag*/
977 (1 << 13) | /*RBSP NAL TYPE*/
978 (0 << 12) ); /*CabacZeroWordInsertionEnable*/
979 OUT_BCS_BATCH(batch, mfc_context->mfc_indirect_pak_bse_object.offset);
981 (maxQpN << 24) | /*Target QP - 24 is lowest QP*/
982 (maxQpP << 16) | /*Target QP + 20 is highest QP*/
992 OUT_BCS_BATCH(batch, 0);
994 ADVANCE_BCS_BATCH(batch);
998 #if MFC_SOFTWARE_HASWELL
1001 gen75_mfc_avc_pak_object_intra(VADriverContextP ctx, int x, int y, int end_mb,
1002 int qp,unsigned int *msg,
1003 struct intel_encoder_context *encoder_context,
1004 unsigned char target_mb_size, unsigned char max_mb_size,
1005 struct intel_batchbuffer *batch)
1007 int len_in_dwords = 12;
1008 unsigned int intra_msg;
1009 #define INTRA_MSG_FLAG (1 << 13)
1010 #define INTRA_MBTYPE_MASK (0x1F0000)
1012 batch = encoder_context->base.batch;
1014 BEGIN_BCS_BATCH(batch, len_in_dwords);
1016 intra_msg = msg[0] & 0xC0FF;
1017 intra_msg |= INTRA_MSG_FLAG;
1018 intra_msg |= ((msg[0] & INTRA_MBTYPE_MASK) >> 8);
1019 OUT_BCS_BATCH(batch, MFC_AVC_PAK_OBJECT | (len_in_dwords - 2));
1020 OUT_BCS_BATCH(batch, 0);
1021 OUT_BCS_BATCH(batch, 0);
1022 OUT_BCS_BATCH(batch,
1023 (0 << 24) | /* PackedMvNum, Debug*/
1024 (0 << 20) | /* No motion vector */
1025 (1 << 19) | /* CbpDcY */
1026 (1 << 18) | /* CbpDcU */
1027 (1 << 17) | /* CbpDcV */
1030 OUT_BCS_BATCH(batch, (0xFFFF << 16) | (y << 8) | x); /* Code Block Pattern for Y*/
1031 OUT_BCS_BATCH(batch, 0x000F000F); /* Code Block Pattern */
1032 OUT_BCS_BATCH(batch, (0 << 27) | (end_mb << 26) | qp); /* Last MB */
1034 /*Stuff for Intra MB*/
1035 OUT_BCS_BATCH(batch, msg[1]); /* We using Intra16x16 no 4x4 predmode*/
1036 OUT_BCS_BATCH(batch, msg[2]);
1037 OUT_BCS_BATCH(batch, msg[3]&0xFF);
1039 /*MaxSizeInWord and TargetSzieInWord*/
1040 OUT_BCS_BATCH(batch, (max_mb_size << 24) |
1041 (target_mb_size << 16) );
1043 OUT_BCS_BATCH(batch, 0);
1045 ADVANCE_BCS_BATCH(batch);
1047 return len_in_dwords;
1051 gen75_mfc_avc_pak_object_inter(VADriverContextP ctx, int x, int y, int end_mb, int qp,
1052 unsigned int *msg, unsigned int offset,
1053 struct intel_encoder_context *encoder_context,
1054 unsigned char target_mb_size,unsigned char max_mb_size, int slice_type,
1055 struct intel_batchbuffer *batch)
1057 struct gen6_vme_context *vme_context = encoder_context->vme_context;
1058 int len_in_dwords = 12;
1059 unsigned int inter_msg = 0;
1061 batch = encoder_context->base.batch;
1063 #define MSG_MV_OFFSET 4
1064 unsigned int *mv_ptr;
1065 mv_ptr = msg + MSG_MV_OFFSET;
1066 /* MV of VME output is based on 16 sub-blocks. So it is necessary
1067 * to convert them to be compatible with the format of AVC_PAK
1070 if ((msg[0] & INTER_MODE_MASK) == INTER_8X16) {
1071 /* MV[0] and MV[2] are replicated */
1072 mv_ptr[4] = mv_ptr[0];
1073 mv_ptr[5] = mv_ptr[1];
1074 mv_ptr[2] = mv_ptr[8];
1075 mv_ptr[3] = mv_ptr[9];
1076 mv_ptr[6] = mv_ptr[8];
1077 mv_ptr[7] = mv_ptr[9];
1078 } else if ((msg[0] & INTER_MODE_MASK) == INTER_16X8) {
1079 /* MV[0] and MV[1] are replicated */
1080 mv_ptr[2] = mv_ptr[0];
1081 mv_ptr[3] = mv_ptr[1];
1082 mv_ptr[4] = mv_ptr[16];
1083 mv_ptr[5] = mv_ptr[17];
1084 mv_ptr[6] = mv_ptr[24];
1085 mv_ptr[7] = mv_ptr[25];
1086 } else if (((msg[0] & INTER_MODE_MASK) == INTER_8X8) &&
1087 !(msg[1] & SUBMB_SHAPE_MASK)) {
1088 /* Don't touch MV[0] or MV[1] */
1089 mv_ptr[2] = mv_ptr[8];
1090 mv_ptr[3] = mv_ptr[9];
1091 mv_ptr[4] = mv_ptr[16];
1092 mv_ptr[5] = mv_ptr[17];
1093 mv_ptr[6] = mv_ptr[24];
1094 mv_ptr[7] = mv_ptr[25];
1098 BEGIN_BCS_BATCH(batch, len_in_dwords);
1100 OUT_BCS_BATCH(batch, MFC_AVC_PAK_OBJECT | (len_in_dwords - 2));
1104 if ((msg[0] & INTER_MODE_MASK) == INTER_8X8) {
1105 if (msg[1] & SUBMB_SHAPE_MASK)
1108 OUT_BCS_BATCH(batch, inter_msg); /* 32 MV*/
1109 OUT_BCS_BATCH(batch, offset);
1110 inter_msg = msg[0] & (0x1F00FFFF);
1111 inter_msg |= INTER_MV8;
1112 inter_msg |= ((1 << 19) | (1 << 18) | (1 << 17));
1113 if (((msg[0] & INTER_MODE_MASK) == INTER_8X8) &&
1114 (msg[1] & SUBMB_SHAPE_MASK)) {
1115 inter_msg |= INTER_MV32;
1118 OUT_BCS_BATCH(batch, inter_msg);
1120 OUT_BCS_BATCH(batch, (0xFFFF<<16) | (y << 8) | x); /* Code Block Pattern for Y*/
1121 OUT_BCS_BATCH(batch, 0x000F000F); /* Code Block Pattern */
1123 if ( slice_type == SLICE_TYPE_B) {
1124 OUT_BCS_BATCH(batch, (0xF<<28) | (end_mb << 26) | qp); /* Last MB */
1126 OUT_BCS_BATCH(batch, (end_mb << 26) | qp); /* Last MB */
1129 OUT_BCS_BATCH(batch, (end_mb << 26) | qp); /* Last MB */
1132 inter_msg = msg[1] >> 8;
1133 /*Stuff for Inter MB*/
1134 OUT_BCS_BATCH(batch, inter_msg);
1135 OUT_BCS_BATCH(batch, vme_context->ref_index_in_mb[0]);
1136 OUT_BCS_BATCH(batch, vme_context->ref_index_in_mb[1]);
1138 /*MaxSizeInWord and TargetSzieInWord*/
1139 OUT_BCS_BATCH(batch, (max_mb_size << 24) |
1140 (target_mb_size << 16) );
1142 OUT_BCS_BATCH(batch, 0x0);
1144 ADVANCE_BCS_BATCH(batch);
1146 return len_in_dwords;
1150 gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
1151 struct encode_state *encode_state,
1152 struct intel_encoder_context *encoder_context,
1154 struct intel_batchbuffer *slice_batch)
1156 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1157 struct gen6_vme_context *vme_context = encoder_context->vme_context;
1158 VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
1159 VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
1160 VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[slice_index]->buffer;
1161 unsigned int *msg = NULL, offset = 0;
1162 unsigned char *msg_ptr = NULL;
1163 int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
1164 int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
1165 int last_slice = (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks) == (width_in_mbs * height_in_mbs);
1167 int qp = pPicParameter->pic_init_qp + pSliceParameter->slice_qp_delta;
1168 unsigned int rate_control_mode = encoder_context->rate_control_mode;
1169 unsigned int tail_data[] = { 0x0, 0x0 };
1170 int slice_type = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
1171 int is_intra = slice_type == SLICE_TYPE_I;
1175 if (rate_control_mode == VA_RC_CBR) {
1176 qp = mfc_context->bit_rate_control_context[slice_type].QpPrimeY;
1177 if (encode_state->slice_header_index[slice_index] == 0) {
1178 pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
1183 /* only support for 8-bit pixel bit-depth */
1184 assert(pSequenceParameter->bit_depth_luma_minus8 == 0);
1185 assert(pSequenceParameter->bit_depth_chroma_minus8 == 0);
1186 assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52);
1187 assert(qp >= 0 && qp < 52);
1189 gen75_mfc_avc_slice_state(ctx,
1192 encode_state, encoder_context,
1193 (rate_control_mode == VA_RC_CBR), qp_slice, slice_batch);
1195 if ( slice_index == 0)
1196 intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
1198 intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
1200 dri_bo_map(vme_context->vme_output.bo , 1);
1201 msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual;
1204 msg = (unsigned int *) (msg_ptr + pSliceParameter->macroblock_address * vme_context->vme_output.size_block);
1206 msg = (unsigned int *) (msg_ptr + pSliceParameter->macroblock_address * vme_context->vme_output.size_block);
1209 for (i = pSliceParameter->macroblock_address;
1210 i < pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks; i++) {
1211 int last_mb = (i == (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks - 1) );
1212 x = i % width_in_mbs;
1213 y = i / width_in_mbs;
1214 msg = (unsigned int *) (msg_ptr + i * vme_context->vme_output.size_block);
1218 gen75_mfc_avc_pak_object_intra(ctx, x, y, last_mb, qp, msg, encoder_context, 0, 0, slice_batch);
1220 int inter_rdo, intra_rdo;
1221 inter_rdo = msg[AVC_INTER_RDO_OFFSET] & AVC_RDO_MASK;
1222 intra_rdo = msg[AVC_INTRA_RDO_OFFSET] & AVC_RDO_MASK;
1223 offset = i * vme_context->vme_output.size_block + AVC_INTER_MV_OFFSET;
1224 if (intra_rdo < inter_rdo) {
1225 gen75_mfc_avc_pak_object_intra(ctx, x, y, last_mb, qp, msg, encoder_context, 0, 0, slice_batch);
1227 msg += AVC_INTER_MSG_OFFSET;
1228 gen75_mfc_avc_pak_object_inter(ctx, x, y, last_mb, qp, msg, offset, encoder_context, 0, 0, slice_type, slice_batch);
1233 dri_bo_unmap(vme_context->vme_output.bo);
1236 mfc_context->insert_object(ctx, encoder_context,
1238 2, 1, 1, 0, slice_batch);
1240 mfc_context->insert_object(ctx, encoder_context,
1242 1, 1, 1, 0, slice_batch);
1247 gen75_mfc_avc_software_batchbuffer(VADriverContextP ctx,
1248 struct encode_state *encode_state,
1249 struct intel_encoder_context *encoder_context)
1251 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1252 struct i965_driver_data *i965 = i965_driver_data(ctx);
1253 struct intel_batchbuffer *batch;
1258 batch = mfc_context->aux_batchbuffer;
1259 batch_bo = batch->buffer;
1260 for (i = 0; i < encode_state->num_slice_params_ext; i++) {
1261 gen75_mfc_avc_pipeline_slice_programing(ctx, encode_state, encoder_context, i, batch);
1264 intel_batchbuffer_align(batch, 8);
1266 BEGIN_BCS_BATCH(batch, 2);
1267 OUT_BCS_BATCH(batch, 0);
1268 OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_END);
1269 ADVANCE_BCS_BATCH(batch);
1271 dri_bo_reference(batch_bo);
1273 intel_batchbuffer_free(batch);
1274 mfc_context->aux_batchbuffer = NULL;
1282 gen75_mfc_batchbuffer_surfaces_input(VADriverContextP ctx,
1283 struct encode_state *encode_state,
1284 struct intel_encoder_context *encoder_context)
1287 struct gen6_vme_context *vme_context = encoder_context->vme_context;
1288 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1290 assert(vme_context->vme_output.bo);
1291 mfc_context->buffer_suface_setup(ctx,
1292 &mfc_context->gpe_context,
1293 &vme_context->vme_output,
1294 BINDING_TABLE_OFFSET(BIND_IDX_VME_OUTPUT),
1295 SURFACE_STATE_OFFSET(BIND_IDX_VME_OUTPUT));
1299 gen75_mfc_batchbuffer_surfaces_output(VADriverContextP ctx,
1300 struct encode_state *encode_state,
1301 struct intel_encoder_context *encoder_context)
1304 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1305 assert(mfc_context->aux_batchbuffer_surface.bo);
1306 mfc_context->buffer_suface_setup(ctx,
1307 &mfc_context->gpe_context,
1308 &mfc_context->aux_batchbuffer_surface,
1309 BINDING_TABLE_OFFSET(BIND_IDX_MFC_BATCHBUFFER),
1310 SURFACE_STATE_OFFSET(BIND_IDX_MFC_BATCHBUFFER));
1314 gen75_mfc_batchbuffer_surfaces_setup(VADriverContextP ctx,
1315 struct encode_state *encode_state,
1316 struct intel_encoder_context *encoder_context)
1318 gen75_mfc_batchbuffer_surfaces_input(ctx, encode_state, encoder_context);
1319 gen75_mfc_batchbuffer_surfaces_output(ctx, encode_state, encoder_context);
1323 gen75_mfc_batchbuffer_idrt_setup(VADriverContextP ctx,
1324 struct encode_state *encode_state,
1325 struct intel_encoder_context *encoder_context)
1327 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1328 struct gen6_interface_descriptor_data *desc;
1332 bo = mfc_context->gpe_context.idrt.bo;
1334 assert(bo->virtual);
1337 for (i = 0; i < mfc_context->gpe_context.num_kernels; i++) {
1338 struct i965_kernel *kernel;
1340 kernel = &mfc_context->gpe_context.kernels[i];
1341 assert(sizeof(*desc) == 32);
1343 /*Setup the descritor table*/
1344 memset(desc, 0, sizeof(*desc));
1345 desc->desc0.kernel_start_pointer = (kernel->bo->offset >> 6);
1346 desc->desc2.sampler_count = 0;
1347 desc->desc2.sampler_state_pointer = 0;
1348 desc->desc3.binding_table_entry_count = 2;
1349 desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET(0) >> 5);
1350 desc->desc4.constant_urb_entry_read_offset = 0;
1351 desc->desc4.constant_urb_entry_read_length = 4;
1354 dri_bo_emit_reloc(bo,
1355 I915_GEM_DOMAIN_INSTRUCTION, 0,
1357 i * sizeof(*desc) + offsetof(struct gen6_interface_descriptor_data, desc0),
1366 gen75_mfc_batchbuffer_constant_setup(VADriverContextP ctx,
1367 struct encode_state *encode_state,
1368 struct intel_encoder_context *encoder_context)
1370 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1375 #define AVC_PAK_LEN_IN_BYTE 48
1376 #define AVC_PAK_LEN_IN_OWORD 3
1379 gen75_mfc_batchbuffer_emit_object_command(struct intel_batchbuffer *batch,
1380 uint32_t intra_flag,
1392 uint32_t temp_value;
1393 BEGIN_BATCH(batch, 14);
1395 OUT_BATCH(batch, CMD_MEDIA_OBJECT | (14 - 2));
1396 OUT_BATCH(batch, 0);
1397 OUT_BATCH(batch, 0);
1398 OUT_BATCH(batch, 0);
1399 OUT_BATCH(batch, 0);
1400 OUT_BATCH(batch, 0);
1403 OUT_BATCH(batch, head_offset / 16);
1404 OUT_BATCH(batch, (intra_flag) | (qp << 16));
1405 temp_value = (mb_x | (mb_y << 8) | (width_in_mbs << 16));
1406 OUT_BATCH(batch, temp_value);
1408 OUT_BATCH(batch, number_mb_cmds);
1411 ((slice_end_y << 8) | (slice_end_x)));
1412 OUT_BATCH(batch, fwd_ref);
1413 OUT_BATCH(batch, bwd_ref);
1415 OUT_BATCH(batch, MI_NOOP);
1417 ADVANCE_BATCH(batch);
1421 gen75_mfc_avc_batchbuffer_slice_command(VADriverContextP ctx,
1422 struct intel_encoder_context *encoder_context,
1423 VAEncSliceParameterBufferH264 *slice_param,
1428 struct intel_batchbuffer *batch = encoder_context->base.batch;
1429 struct gen6_vme_context *vme_context = encoder_context->vme_context;
1430 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1431 int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
1432 int total_mbs = slice_param->num_macroblocks;
1433 int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
1434 int number_mb_cmds = 128;
1435 int starting_offset = 0;
1437 int last_mb, slice_end_x, slice_end_y;
1438 int remaining_mb = total_mbs;
1439 uint32_t fwd_ref , bwd_ref, mb_flag;
1441 last_mb = slice_param->macroblock_address + total_mbs - 1;
1442 slice_end_x = last_mb % width_in_mbs;
1443 slice_end_y = last_mb / width_in_mbs;
1445 if (slice_type == SLICE_TYPE_I) {
1450 fwd_ref = vme_context->ref_index_in_mb[0];
1451 bwd_ref = vme_context->ref_index_in_mb[1];
1455 if (width_in_mbs >= 100) {
1456 number_mb_cmds = width_in_mbs / 5;
1457 } else if (width_in_mbs >= 80) {
1458 number_mb_cmds = width_in_mbs / 4;
1459 } else if (width_in_mbs >= 60) {
1460 number_mb_cmds = width_in_mbs / 3;
1461 } else if (width_in_mbs >= 40) {
1462 number_mb_cmds = width_in_mbs / 2;
1464 number_mb_cmds = width_in_mbs;
1468 if (number_mb_cmds >= remaining_mb) {
1469 number_mb_cmds = remaining_mb;
1471 mb_x = (slice_param->macroblock_address + starting_offset) % width_in_mbs;
1472 mb_y = (slice_param->macroblock_address + starting_offset) / width_in_mbs;
1474 gen75_mfc_batchbuffer_emit_object_command(batch,
1487 head_offset += (number_mb_cmds * AVC_PAK_LEN_IN_BYTE);
1488 remaining_mb -= number_mb_cmds;
1489 starting_offset += number_mb_cmds;
1490 } while (remaining_mb > 0);
1494 * return size in Owords (16bytes)
1497 gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
1498 struct encode_state *encode_state,
1499 struct intel_encoder_context *encoder_context,
1502 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1503 struct intel_batchbuffer *slice_batch = mfc_context->aux_batchbuffer;
1504 VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
1505 VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
1506 VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[slice_index]->buffer;
1507 int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
1508 int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
1509 int last_slice = (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks) == (width_in_mbs * height_in_mbs);
1510 int qp = pPicParameter->pic_init_qp + pSliceParameter->slice_qp_delta;
1511 unsigned int rate_control_mode = encoder_context->rate_control_mode;
1512 unsigned int tail_data[] = { 0x0, 0x0 };
1514 int slice_type = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
1518 if (rate_control_mode == VA_RC_CBR) {
1519 qp = mfc_context->bit_rate_control_context[slice_type].QpPrimeY;
1520 if (encode_state->slice_header_index[slice_index] == 0) {
1521 pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
1526 /* only support for 8-bit pixel bit-depth */
1527 assert(pSequenceParameter->bit_depth_luma_minus8 == 0);
1528 assert(pSequenceParameter->bit_depth_chroma_minus8 == 0);
1529 assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52);
1530 assert(qp >= 0 && qp < 52);
1532 gen75_mfc_avc_slice_state(ctx,
1537 (rate_control_mode == VA_RC_CBR),
1541 if (slice_index == 0)
1542 intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
1544 intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
1546 intel_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */
1547 head_offset = intel_batchbuffer_used_size(slice_batch);
1549 slice_batch->ptr += pSliceParameter->num_macroblocks * AVC_PAK_LEN_IN_BYTE;
1551 gen75_mfc_avc_batchbuffer_slice_command(ctx,
1559 /* Aligned for tail */
1560 intel_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */
1562 mfc_context->insert_object(ctx,
1573 mfc_context->insert_object(ctx,
1589 gen75_mfc_avc_batchbuffer_pipeline(VADriverContextP ctx,
1590 struct encode_state *encode_state,
1591 struct intel_encoder_context *encoder_context)
1593 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1594 struct intel_batchbuffer *batch = encoder_context->base.batch;
1596 intel_batchbuffer_start_atomic(batch, 0x4000);
1597 gen6_gpe_pipeline_setup(ctx, &mfc_context->gpe_context, batch);
1599 for ( i = 0; i < encode_state->num_slice_params_ext; i++) {
1600 gen75_mfc_avc_batchbuffer_slice(ctx, encode_state, encoder_context, i);
1603 struct intel_batchbuffer *slice_batch = mfc_context->aux_batchbuffer;
1604 intel_batchbuffer_align(slice_batch, 8);
1605 BEGIN_BCS_BATCH(slice_batch, 2);
1606 OUT_BCS_BATCH(slice_batch, 0);
1607 OUT_BCS_BATCH(slice_batch, MI_BATCH_BUFFER_END);
1608 ADVANCE_BCS_BATCH(slice_batch);
1609 mfc_context->aux_batchbuffer = NULL;
1610 intel_batchbuffer_free(slice_batch);
1612 intel_batchbuffer_end_atomic(batch);
1613 intel_batchbuffer_flush(batch);
1617 gen75_mfc_build_avc_batchbuffer(VADriverContextP ctx,
1618 struct encode_state *encode_state,
1619 struct intel_encoder_context *encoder_context)
1621 gen75_mfc_batchbuffer_surfaces_setup(ctx, encode_state, encoder_context);
1622 gen75_mfc_batchbuffer_idrt_setup(ctx, encode_state, encoder_context);
1623 gen75_mfc_batchbuffer_constant_setup(ctx, encode_state, encoder_context);
1624 gen75_mfc_avc_batchbuffer_pipeline(ctx, encode_state, encoder_context);
1628 gen75_mfc_avc_hardware_batchbuffer(VADriverContextP ctx,
1629 struct encode_state *encode_state,
1630 struct intel_encoder_context *encoder_context)
1632 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1634 dri_bo_reference(mfc_context->aux_batchbuffer_surface.bo);
1635 gen75_mfc_build_avc_batchbuffer(ctx, encode_state, encoder_context);
1637 return mfc_context->aux_batchbuffer_surface.bo;
1643 gen75_mfc_avc_pipeline_programing(VADriverContextP ctx,
1644 struct encode_state *encode_state,
1645 struct intel_encoder_context *encoder_context)
1647 struct intel_batchbuffer *batch = encoder_context->base.batch;
1648 dri_bo *slice_batch_bo;
1650 if ( intel_mfc_interlace_check(ctx, encode_state, encoder_context) ) {
1651 fprintf(stderr, "Current VA driver don't support interlace mode!\n");
1656 #if MFC_SOFTWARE_HASWELL
1657 slice_batch_bo = gen75_mfc_avc_software_batchbuffer(ctx, encode_state, encoder_context);
1659 slice_batch_bo = gen75_mfc_avc_hardware_batchbuffer(ctx, encode_state, encoder_context);
1663 intel_batchbuffer_start_atomic_bcs(batch, 0x4000);
1664 intel_batchbuffer_emit_mi_flush(batch);
1666 // picture level programing
1667 gen75_mfc_avc_pipeline_picture_programing(ctx, encode_state, encoder_context);
1669 BEGIN_BCS_BATCH(batch, 2);
1670 OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8));
1671 OUT_BCS_RELOC(batch,
1673 I915_GEM_DOMAIN_COMMAND, 0,
1675 ADVANCE_BCS_BATCH(batch);
1678 intel_batchbuffer_end_atomic(batch);
1680 dri_bo_unreference(slice_batch_bo);
1685 gen75_mfc_avc_encode_picture(VADriverContextP ctx,
1686 struct encode_state *encode_state,
1687 struct intel_encoder_context *encoder_context)
1689 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1690 unsigned int rate_control_mode = encoder_context->rate_control_mode;
1691 int current_frame_bits_size;
1695 gen75_mfc_init(ctx, encode_state, encoder_context);
1696 intel_mfc_avc_prepare(ctx, encode_state, encoder_context);
1697 /*Programing bcs pipeline*/
1698 gen75_mfc_avc_pipeline_programing(ctx, encode_state, encoder_context); //filling the pipeline
1699 gen75_mfc_run(ctx, encode_state, encoder_context);
1700 if (rate_control_mode == VA_RC_CBR /*|| rate_control_mode == VA_RC_VBR*/) {
1701 gen75_mfc_stop(ctx, encode_state, encoder_context, ¤t_frame_bits_size);
1702 sts = intel_mfc_brc_postpack(encode_state, mfc_context, current_frame_bits_size);
1703 if (sts == BRC_NO_HRD_VIOLATION) {
1704 intel_mfc_hrd_context_update(encode_state, mfc_context);
1707 else if (sts == BRC_OVERFLOW_WITH_MIN_QP || sts == BRC_UNDERFLOW_WITH_MAX_QP) {
1708 if (!mfc_context->hrd.violation_noted) {
1709 fprintf(stderr, "Unrepairable %s!\n", (sts == BRC_OVERFLOW_WITH_MIN_QP)? "overflow": "underflow");
1710 mfc_context->hrd.violation_noted = 1;
1712 return VA_STATUS_SUCCESS;
1719 return VA_STATUS_SUCCESS;
1727 va_to_gen75_mpeg2_picture_type[3] = {
1734 gen75_mfc_mpeg2_pic_state(VADriverContextP ctx,
1735 struct intel_encoder_context *encoder_context,
1736 struct encode_state *encode_state)
1738 struct intel_batchbuffer *batch = encoder_context->base.batch;
1739 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1740 VAEncPictureParameterBufferMPEG2 *pic_param;
1741 int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
1742 int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
1743 VAEncSliceParameterBufferMPEG2 *slice_param = NULL;
1745 assert(encode_state->pic_param_ext && encode_state->pic_param_ext->buffer);
1746 pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
1747 slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[0]->buffer;
1749 BEGIN_BCS_BATCH(batch, 13);
1750 OUT_BCS_BATCH(batch, MFX_MPEG2_PIC_STATE | (13 - 2));
1751 OUT_BCS_BATCH(batch,
1752 (pic_param->f_code[1][1] & 0xf) << 28 | /* f_code[1][1] */
1753 (pic_param->f_code[1][0] & 0xf) << 24 | /* f_code[1][0] */
1754 (pic_param->f_code[0][1] & 0xf) << 20 | /* f_code[0][1] */
1755 (pic_param->f_code[0][0] & 0xf) << 16 | /* f_code[0][0] */
1756 pic_param->picture_coding_extension.bits.intra_dc_precision << 14 |
1757 pic_param->picture_coding_extension.bits.picture_structure << 12 |
1758 pic_param->picture_coding_extension.bits.top_field_first << 11 |
1759 pic_param->picture_coding_extension.bits.frame_pred_frame_dct << 10 |
1760 pic_param->picture_coding_extension.bits.concealment_motion_vectors << 9 |
1761 pic_param->picture_coding_extension.bits.q_scale_type << 8 |
1762 pic_param->picture_coding_extension.bits.intra_vlc_format << 7 |
1763 pic_param->picture_coding_extension.bits.alternate_scan << 6);
1764 OUT_BCS_BATCH(batch,
1765 0 << 14 | /* LoadSlicePointerFlag, 0 means only loading bitstream pointer once */
1766 va_to_gen75_mpeg2_picture_type[pic_param->picture_type] << 9 |
1768 OUT_BCS_BATCH(batch,
1769 1 << 31 | /* slice concealment */
1770 (height_in_mbs - 1) << 16 |
1771 (width_in_mbs - 1));
1772 if (slice_param && slice_param->quantiser_scale_code >= 14)
1773 OUT_BCS_BATCH(batch, (3 << 1) | (1 << 4) | (5 << 8) | (1 << 12));
1775 OUT_BCS_BATCH(batch, 0);
1777 OUT_BCS_BATCH(batch, 0);
1778 OUT_BCS_BATCH(batch,
1779 0xFFF << 16 | /* InterMBMaxSize */
1780 0xFFF << 0 | /* IntraMBMaxSize */
1782 OUT_BCS_BATCH(batch, 0);
1783 OUT_BCS_BATCH(batch, 0);
1784 OUT_BCS_BATCH(batch, 0);
1785 OUT_BCS_BATCH(batch, 0);
1786 OUT_BCS_BATCH(batch, 0);
1787 OUT_BCS_BATCH(batch, 0);
1788 ADVANCE_BCS_BATCH(batch);
1792 gen75_mfc_mpeg2_qm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
1794 unsigned char intra_qm[64] = {
1795 8, 16, 19, 22, 26, 27, 29, 34,
1796 16, 16, 22, 24, 27, 29, 34, 37,
1797 19, 22, 26, 27, 29, 34, 34, 38,
1798 22, 22, 26, 27, 29, 34, 37, 40,
1799 22, 26, 27, 29, 32, 35, 40, 48,
1800 26, 27, 29, 32, 35, 40, 48, 58,
1801 26, 27, 29, 34, 38, 46, 56, 69,
1802 27, 29, 35, 38, 46, 56, 69, 83
1805 unsigned char non_intra_qm[64] = {
1806 16, 16, 16, 16, 16, 16, 16, 16,
1807 16, 16, 16, 16, 16, 16, 16, 16,
1808 16, 16, 16, 16, 16, 16, 16, 16,
1809 16, 16, 16, 16, 16, 16, 16, 16,
1810 16, 16, 16, 16, 16, 16, 16, 16,
1811 16, 16, 16, 16, 16, 16, 16, 16,
1812 16, 16, 16, 16, 16, 16, 16, 16,
1813 16, 16, 16, 16, 16, 16, 16, 16
1816 gen75_mfc_qm_state(ctx, MFX_QM_MPEG_INTRA_QUANTIZER_MATRIX, (unsigned int *)intra_qm, 16, encoder_context);
1817 gen75_mfc_qm_state(ctx, MFX_QM_MPEG_NON_INTRA_QUANTIZER_MATRIX, (unsigned int *)non_intra_qm, 16,encoder_context);
1821 gen75_mfc_mpeg2_fqm_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
1823 unsigned short intra_fqm[64] = {
1824 65536/0x8, 65536/0x10, 65536/0x13, 65536/0x16, 65536/0x16, 65536/0x1a, 65536/0x1a, 65536/0x1b,
1825 65536/0x10, 65536/0x10, 65536/0x16, 65536/0x16, 65536/0x1a, 65536/0x1b, 65536/0x1b, 65536/0x1d,
1826 65536/0x13, 65536/0x16, 65536/0x1a, 65536/0x1a, 65536/0x1b, 65536/0x1d, 65536/0x1d, 65536/0x23,
1827 65536/0x16, 65536/0x18, 65536/0x1b, 65536/0x1b, 65536/0x13, 65536/0x20, 65536/0x22, 65536/0x26,
1828 65536/0x1a, 65536/0x1b, 65536/0x13, 65536/0x13, 65536/0x20, 65536/0x23, 65536/0x26, 65536/0x2e,
1829 65536/0x1b, 65536/0x1d, 65536/0x22, 65536/0x22, 65536/0x23, 65536/0x28, 65536/0x2e, 65536/0x38,
1830 65536/0x1d, 65536/0x22, 65536/0x22, 65536/0x25, 65536/0x28, 65536/0x30, 65536/0x38, 65536/0x45,
1831 65536/0x22, 65536/0x25, 65536/0x26, 65536/0x28, 65536/0x30, 65536/0x3a, 65536/0x45, 65536/0x53,
1834 unsigned short non_intra_fqm[64] = {
1835 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1836 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1837 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1838 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1839 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1840 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1841 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1842 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
1845 gen75_mfc_fqm_state(ctx, MFX_QM_MPEG_INTRA_QUANTIZER_MATRIX, (unsigned int *)intra_fqm, 32, encoder_context);
1846 gen75_mfc_fqm_state(ctx, MFX_QM_MPEG_NON_INTRA_QUANTIZER_MATRIX, (unsigned int *)non_intra_fqm, 32, encoder_context);
1850 gen75_mfc_mpeg2_slicegroup_state(VADriverContextP ctx,
1851 struct intel_encoder_context *encoder_context,
1853 int next_x, int next_y,
1854 int is_fisrt_slice_group,
1855 int is_last_slice_group,
1858 struct intel_batchbuffer *batch)
1860 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
1863 batch = encoder_context->base.batch;
1865 BEGIN_BCS_BATCH(batch, 8);
1867 OUT_BCS_BATCH(batch, MFC_MPEG2_SLICEGROUP_STATE | (8 - 2));
1868 OUT_BCS_BATCH(batch,
1869 0 << 31 | /* MbRateCtrlFlag */
1870 !!is_last_slice_group << 19 | /* IsLastSliceGrp */
1871 1 << 17 | /* Insert Header before the first slice group data */
1872 1 << 16 | /* SliceData PresentFlag: always 1 */
1873 1 << 15 | /* TailPresentFlag: always 1 */
1874 0 << 14 | /* FirstSliceHdrDisabled: slice header for each slice */
1875 !!intra_slice << 13 | /* IntraSlice */
1876 !!intra_slice << 12 | /* IntraSliceFlag */
1878 OUT_BCS_BATCH(batch,
1884 OUT_BCS_BATCH(batch, qp); /* FIXME: SliceGroupQp */
1885 /* bitstream pointer is only loaded once for the first slice of a frame when
1886 * LoadSlicePointerFlag is 0
1888 OUT_BCS_BATCH(batch, mfc_context->mfc_indirect_pak_bse_object.offset);
1889 OUT_BCS_BATCH(batch, 0); /* FIXME: */
1890 OUT_BCS_BATCH(batch, 0); /* FIXME: CorrectPoints */
1891 OUT_BCS_BATCH(batch, 0); /* FIXME: CVxxx */
1893 ADVANCE_BCS_BATCH(batch);
1897 gen75_mfc_mpeg2_pak_object_intra(VADriverContextP ctx,
1898 struct intel_encoder_context *encoder_context,
1900 int first_mb_in_slice,
1901 int last_mb_in_slice,
1902 int first_mb_in_slice_group,
1903 int last_mb_in_slice_group,
1906 int coded_block_pattern,
1907 unsigned char target_size_in_word,
1908 unsigned char max_size_in_word,
1909 struct intel_batchbuffer *batch)
1911 int len_in_dwords = 9;
1914 batch = encoder_context->base.batch;
1916 BEGIN_BCS_BATCH(batch, len_in_dwords);
1918 OUT_BCS_BATCH(batch, MFC_MPEG2_PAK_OBJECT | (len_in_dwords - 2));
1919 OUT_BCS_BATCH(batch,
1920 0 << 24 | /* PackedMvNum */
1921 0 << 20 | /* MvFormat */
1922 7 << 17 | /* CbpDcY/CbpDcU/CbpDcV */
1923 0 << 15 | /* TransformFlag: frame DCT */
1924 0 << 14 | /* FieldMbFlag */
1925 1 << 13 | /* IntraMbFlag */
1926 mb_type << 8 | /* MbType: Intra */
1927 0 << 2 | /* SkipMbFlag */
1928 0 << 0 | /* InterMbMode */
1930 OUT_BCS_BATCH(batch, y << 16 | x);
1931 OUT_BCS_BATCH(batch,
1932 max_size_in_word << 24 |
1933 target_size_in_word << 16 |
1934 coded_block_pattern << 6 | /* CBP */
1936 OUT_BCS_BATCH(batch,
1937 last_mb_in_slice << 31 |
1938 first_mb_in_slice << 30 |
1939 0 << 27 | /* EnableCoeffClamp */
1940 last_mb_in_slice_group << 26 |
1941 0 << 25 | /* MbSkipConvDisable */
1942 first_mb_in_slice_group << 24 |
1943 0 << 16 | /* MvFieldSelect */
1944 qp_scale_code << 0 |
1946 OUT_BCS_BATCH(batch, 0); /* MV[0][0] */
1947 OUT_BCS_BATCH(batch, 0); /* MV[1][0] */
1948 OUT_BCS_BATCH(batch, 0); /* MV[0][1] */
1949 OUT_BCS_BATCH(batch, 0); /* MV[1][1] */
1951 ADVANCE_BCS_BATCH(batch);
1953 return len_in_dwords;
1956 #define MPEG2_INTER_MV_OFFSET 12
1958 static struct _mv_ranges
1960 int low; /* in the unit of 1/2 pixel */
1961 int high; /* in the unit of 1/2 pixel */
1976 mpeg2_motion_vector(int mv, int pos, int display_max, int f_code)
1978 if (mv + pos * 16 * 2 < 0 ||
1979 mv + (pos + 1) * 16 * 2 > display_max * 2)
1982 if (f_code > 0 && f_code < 10) {
1983 if (mv < mv_ranges[f_code].low)
1984 mv = mv_ranges[f_code].low;
1986 if (mv > mv_ranges[f_code].high)
1987 mv = mv_ranges[f_code].high;
1994 gen75_mfc_mpeg2_pak_object_inter(VADriverContextP ctx,
1995 struct encode_state *encode_state,
1996 struct intel_encoder_context *encoder_context,
1998 int width_in_mbs, int height_in_mbs,
2000 int first_mb_in_slice,
2001 int last_mb_in_slice,
2002 int first_mb_in_slice_group,
2003 int last_mb_in_slice_group,
2005 unsigned char target_size_in_word,
2006 unsigned char max_size_in_word,
2007 struct intel_batchbuffer *batch)
2009 VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
2010 int len_in_dwords = 9;
2011 short *mvptr, mvx0, mvy0, mvx1, mvy1;
2014 batch = encoder_context->base.batch;
2016 mvptr = (short *)(msg + MPEG2_INTER_MV_OFFSET);
2017 mvx0 = mpeg2_motion_vector(mvptr[0] / 2, x, width_in_mbs * 16, pic_param->f_code[0][0]);
2018 mvy0 = mpeg2_motion_vector(mvptr[1] / 2, y, height_in_mbs * 16, pic_param->f_code[0][0]);
2019 mvx1 = mpeg2_motion_vector(mvptr[2] / 2, x, width_in_mbs * 16, pic_param->f_code[1][0]);
2020 mvy1 = mpeg2_motion_vector(mvptr[3] / 2, y, height_in_mbs * 16, pic_param->f_code[1][0]);
2022 BEGIN_BCS_BATCH(batch, len_in_dwords);
2024 OUT_BCS_BATCH(batch, MFC_MPEG2_PAK_OBJECT | (len_in_dwords - 2));
2025 OUT_BCS_BATCH(batch,
2026 2 << 24 | /* PackedMvNum */
2027 7 << 20 | /* MvFormat */
2028 7 << 17 | /* CbpDcY/CbpDcU/CbpDcV */
2029 0 << 15 | /* TransformFlag: frame DCT */
2030 0 << 14 | /* FieldMbFlag */
2031 0 << 13 | /* IntraMbFlag */
2032 1 << 8 | /* MbType: Frame-based */
2033 0 << 2 | /* SkipMbFlag */
2034 0 << 0 | /* InterMbMode */
2036 OUT_BCS_BATCH(batch, y << 16 | x);
2037 OUT_BCS_BATCH(batch,
2038 max_size_in_word << 24 |
2039 target_size_in_word << 16 |
2040 0x3f << 6 | /* CBP */
2042 OUT_BCS_BATCH(batch,
2043 last_mb_in_slice << 31 |
2044 first_mb_in_slice << 30 |
2045 0 << 27 | /* EnableCoeffClamp */
2046 last_mb_in_slice_group << 26 |
2047 0 << 25 | /* MbSkipConvDisable */
2048 first_mb_in_slice_group << 24 |
2049 0 << 16 | /* MvFieldSelect */
2050 qp_scale_code << 0 |
2053 OUT_BCS_BATCH(batch, (mvx0 & 0xFFFF) | mvy0 << 16); /* MV[0][0] */
2054 OUT_BCS_BATCH(batch, (mvx1 & 0xFFFF) | mvy1 << 16); /* MV[1][0] */
2055 OUT_BCS_BATCH(batch, 0); /* MV[0][1] */
2056 OUT_BCS_BATCH(batch, 0); /* MV[1][1] */
2058 ADVANCE_BCS_BATCH(batch);
2060 return len_in_dwords;
2064 intel_mfc_mpeg2_pipeline_header_programing(VADriverContextP ctx,
2065 struct encode_state *encode_state,
2066 struct intel_encoder_context *encoder_context,
2067 struct intel_batchbuffer *slice_batch)
2069 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
2070 int idx = va_enc_packed_type_to_idx(VAEncPackedHeaderMPEG2_SPS);
2072 if (encode_state->packed_header_data[idx]) {
2073 VAEncPackedHeaderParameterBuffer *param = NULL;
2074 unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
2075 unsigned int length_in_bits;
2077 assert(encode_state->packed_header_param[idx]);
2078 param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
2079 length_in_bits = param->bit_length;
2081 mfc_context->insert_object(ctx,
2084 ALIGN(length_in_bits, 32) >> 5,
2085 length_in_bits & 0x1f,
2086 5, /* FIXME: check it */
2089 0, /* Needn't insert emulation bytes for MPEG-2 */
2093 idx = va_enc_packed_type_to_idx(VAEncPackedHeaderMPEG2_PPS);
2095 if (encode_state->packed_header_data[idx]) {
2096 VAEncPackedHeaderParameterBuffer *param = NULL;
2097 unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
2098 unsigned int length_in_bits;
2100 assert(encode_state->packed_header_param[idx]);
2101 param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
2102 length_in_bits = param->bit_length;
2104 mfc_context->insert_object(ctx,
2107 ALIGN(length_in_bits, 32) >> 5,
2108 length_in_bits & 0x1f,
2109 5, /* FIXME: check it */
2112 0, /* Needn't insert emulation bytes for MPEG-2 */
2118 gen75_mfc_mpeg2_pipeline_slice_group(VADriverContextP ctx,
2119 struct encode_state *encode_state,
2120 struct intel_encoder_context *encoder_context,
2122 VAEncSliceParameterBufferMPEG2 *next_slice_group_param,
2123 struct intel_batchbuffer *slice_batch)
2125 struct gen6_vme_context *vme_context = encoder_context->vme_context;
2126 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
2127 VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
2128 VAEncSliceParameterBufferMPEG2 *slice_param = NULL;
2129 unsigned char tail_delimiter[] = {MPEG2_DELIMITER0, MPEG2_DELIMITER1, MPEG2_DELIMITER2, MPEG2_DELIMITER3, MPEG2_DELIMITER4, 0, 0, 0};
2130 unsigned char section_delimiter[] = {0x0, 0x0, 0x0, 0x0};
2131 int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
2132 int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
2134 int h_start_pos, v_start_pos, h_next_start_pos, v_next_start_pos;
2135 unsigned int *msg = NULL;
2136 unsigned char *msg_ptr = NULL;
2138 slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[slice_index]->buffer;
2139 h_start_pos = slice_param->macroblock_address % width_in_mbs;
2140 v_start_pos = slice_param->macroblock_address / width_in_mbs;
2141 assert(h_start_pos + slice_param->num_macroblocks <= width_in_mbs);
2143 dri_bo_map(vme_context->vme_output.bo , 0);
2144 msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual;
2146 if (next_slice_group_param) {
2147 h_next_start_pos = next_slice_group_param->macroblock_address % width_in_mbs;
2148 v_next_start_pos = next_slice_group_param->macroblock_address / width_in_mbs;
2150 h_next_start_pos = 0;
2151 v_next_start_pos = height_in_mbs;
2154 gen75_mfc_mpeg2_slicegroup_state(ctx,
2161 next_slice_group_param == NULL,
2162 slice_param->is_intra_slice,
2163 slice_param->quantiser_scale_code,
2166 if (slice_index == 0)
2167 intel_mfc_mpeg2_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
2169 /* Insert '00' to make sure the header is valid */
2170 mfc_context->insert_object(ctx,
2172 (unsigned int*)section_delimiter,
2174 8, /* 8bits in the last DWORD */
2181 for (i = 0; i < encode_state->slice_params_ext[slice_index]->num_elements; i++) {
2182 /* PAK for each macroblocks */
2183 for (j = 0; j < slice_param->num_macroblocks; j++) {
2184 int h_pos = (slice_param->macroblock_address + j) % width_in_mbs;
2185 int v_pos = (slice_param->macroblock_address + j) / width_in_mbs;
2186 int first_mb_in_slice = (j == 0);
2187 int last_mb_in_slice = (j == slice_param->num_macroblocks - 1);
2188 int first_mb_in_slice_group = (i == 0 && j == 0);
2189 int last_mb_in_slice_group = (i == encode_state->slice_params_ext[slice_index]->num_elements - 1 &&
2190 j == slice_param->num_macroblocks - 1);
2192 msg = (unsigned int *)(msg_ptr + (slice_param->macroblock_address + j) * vme_context->vme_output.size_block);
2194 if (slice_param->is_intra_slice) {
2195 gen75_mfc_mpeg2_pak_object_intra(ctx,
2200 first_mb_in_slice_group,
2201 last_mb_in_slice_group,
2203 slice_param->quantiser_scale_code,
2209 int inter_rdo, intra_rdo;
2210 inter_rdo = msg[AVC_INTER_RDO_OFFSET] & AVC_RDO_MASK;
2211 intra_rdo = msg[AVC_INTRA_RDO_OFFSET] & AVC_RDO_MASK;
2213 if (intra_rdo < inter_rdo)
2214 gen75_mfc_mpeg2_pak_object_intra(ctx,
2219 first_mb_in_slice_group,
2220 last_mb_in_slice_group,
2222 slice_param->quantiser_scale_code,
2228 gen75_mfc_mpeg2_pak_object_inter(ctx,
2232 width_in_mbs, height_in_mbs,
2236 first_mb_in_slice_group,
2237 last_mb_in_slice_group,
2238 slice_param->quantiser_scale_code,
2248 dri_bo_unmap(vme_context->vme_output.bo);
2251 if (next_slice_group_param == NULL) { /* end of a picture */
2252 mfc_context->insert_object(ctx,
2254 (unsigned int *)tail_delimiter,
2256 8, /* 8bits in the last DWORD */
2262 } else { /* end of a lsice group */
2263 mfc_context->insert_object(ctx,
2265 (unsigned int *)section_delimiter,
2267 8, /* 8bits in the last DWORD */
2277 * A batch buffer for all slices, including slice state,
2278 * slice insert object and slice pak object commands
2282 gen75_mfc_mpeg2_software_slice_batchbuffer(VADriverContextP ctx,
2283 struct encode_state *encode_state,
2284 struct intel_encoder_context *encoder_context)
2286 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
2287 struct intel_batchbuffer *batch;
2288 VAEncSliceParameterBufferMPEG2 *next_slice_group_param = NULL;
2292 batch = mfc_context->aux_batchbuffer;
2293 batch_bo = batch->buffer;
2295 for (i = 0; i < encode_state->num_slice_params_ext; i++) {
2296 if (i == encode_state->num_slice_params_ext - 1)
2297 next_slice_group_param = NULL;
2299 next_slice_group_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[i + 1]->buffer;
2301 gen75_mfc_mpeg2_pipeline_slice_group(ctx, encode_state, encoder_context, i, next_slice_group_param, batch);
2304 intel_batchbuffer_align(batch, 8);
2306 BEGIN_BCS_BATCH(batch, 2);
2307 OUT_BCS_BATCH(batch, 0);
2308 OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_END);
2309 ADVANCE_BCS_BATCH(batch);
2311 dri_bo_reference(batch_bo);
2312 intel_batchbuffer_free(batch);
2313 mfc_context->aux_batchbuffer = NULL;
2319 gen75_mfc_mpeg2_pipeline_picture_programing(VADriverContextP ctx,
2320 struct encode_state *encode_state,
2321 struct intel_encoder_context *encoder_context)
2323 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
2325 mfc_context->pipe_mode_select(ctx, MFX_FORMAT_MPEG2, encoder_context);
2326 mfc_context->set_surface_state(ctx, encoder_context);
2327 mfc_context->ind_obj_base_addr_state(ctx, encoder_context);
2328 gen75_mfc_pipe_buf_addr_state(ctx, encoder_context);
2329 gen75_mfc_bsp_buf_base_addr_state(ctx, encoder_context);
2330 gen75_mfc_mpeg2_pic_state(ctx, encoder_context, encode_state);
2331 gen75_mfc_mpeg2_qm_state(ctx, encoder_context);
2332 gen75_mfc_mpeg2_fqm_state(ctx, encoder_context);
2336 gen75_mfc_mpeg2_pipeline_programing(VADriverContextP ctx,
2337 struct encode_state *encode_state,
2338 struct intel_encoder_context *encoder_context)
2340 struct intel_batchbuffer *batch = encoder_context->base.batch;
2341 dri_bo *slice_batch_bo;
2343 slice_batch_bo = gen75_mfc_mpeg2_software_slice_batchbuffer(ctx, encode_state, encoder_context);
2346 intel_batchbuffer_start_atomic_bcs(batch, 0x4000);
2347 intel_batchbuffer_emit_mi_flush(batch);
2349 // picture level programing
2350 gen75_mfc_mpeg2_pipeline_picture_programing(ctx, encode_state, encoder_context);
2352 BEGIN_BCS_BATCH(batch, 2);
2353 OUT_BCS_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8));
2354 OUT_BCS_RELOC(batch,
2356 I915_GEM_DOMAIN_COMMAND, 0,
2358 ADVANCE_BCS_BATCH(batch);
2361 intel_batchbuffer_end_atomic(batch);
2363 dri_bo_unreference(slice_batch_bo);
2367 intel_mfc_mpeg2_prepare(VADriverContextP ctx,
2368 struct encode_state *encode_state,
2369 struct intel_encoder_context *encoder_context)
2371 struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
2372 struct object_surface *obj_surface;
2373 struct object_buffer *obj_buffer;
2374 struct i965_coded_buffer_segment *coded_buffer_segment;
2375 VAStatus vaStatus = VA_STATUS_SUCCESS;
2379 /* reconstructed surface */
2380 obj_surface = encode_state->reconstructed_object;
2381 i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
2382 mfc_context->pre_deblocking_output.bo = obj_surface->bo;
2383 dri_bo_reference(mfc_context->pre_deblocking_output.bo);
2384 mfc_context->surface_state.width = obj_surface->orig_width;
2385 mfc_context->surface_state.height = obj_surface->orig_height;
2386 mfc_context->surface_state.w_pitch = obj_surface->width;
2387 mfc_context->surface_state.h_pitch = obj_surface->height;
2389 /* forward reference */
2390 obj_surface = encode_state->reference_objects[0];
2392 if (obj_surface && obj_surface->bo) {
2393 mfc_context->reference_surfaces[0].bo = obj_surface->bo;
2394 dri_bo_reference(mfc_context->reference_surfaces[0].bo);
2396 mfc_context->reference_surfaces[0].bo = NULL;
2398 /* backward reference */
2399 obj_surface = encode_state->reference_objects[1];
2401 if (obj_surface && obj_surface->bo) {
2402 mfc_context->reference_surfaces[1].bo = obj_surface->bo;
2403 dri_bo_reference(mfc_context->reference_surfaces[1].bo);
2405 mfc_context->reference_surfaces[1].bo = mfc_context->reference_surfaces[0].bo;
2407 if (mfc_context->reference_surfaces[1].bo)
2408 dri_bo_reference(mfc_context->reference_surfaces[1].bo);
2411 for (i = 2; i < ARRAY_ELEMS(mfc_context->reference_surfaces); i++) {
2412 mfc_context->reference_surfaces[i].bo = mfc_context->reference_surfaces[i & 1].bo;
2414 if (mfc_context->reference_surfaces[i].bo)
2415 dri_bo_reference(mfc_context->reference_surfaces[i].bo);
2418 /* input YUV surface */
2419 obj_surface = encode_state->input_yuv_object;
2420 mfc_context->uncompressed_picture_source.bo = obj_surface->bo;
2421 dri_bo_reference(mfc_context->uncompressed_picture_source.bo);
2424 obj_buffer = encode_state->coded_buf_object;
2425 bo = obj_buffer->buffer_store->bo;
2426 mfc_context->mfc_indirect_pak_bse_object.bo = bo;
2427 mfc_context->mfc_indirect_pak_bse_object.offset = I965_CODEDBUFFER_HEADER_SIZE;
2428 mfc_context->mfc_indirect_pak_bse_object.end_offset = ALIGN(obj_buffer->size_element - 0x1000, 0x1000);
2429 dri_bo_reference(mfc_context->mfc_indirect_pak_bse_object.bo);
2431 /* set the internal flag to 0 to indicate the coded size is unknown */
2433 coded_buffer_segment = (struct i965_coded_buffer_segment *)bo->virtual;
2434 coded_buffer_segment->mapped = 0;
2435 coded_buffer_segment->codec = encoder_context->codec;
2442 gen75_mfc_mpeg2_encode_picture(VADriverContextP ctx,
2443 struct encode_state *encode_state,
2444 struct intel_encoder_context *encoder_context)
2446 gen75_mfc_init(ctx, encode_state, encoder_context);
2447 intel_mfc_mpeg2_prepare(ctx, encode_state, encoder_context);
2448 /*Programing bcs pipeline*/
2449 gen75_mfc_mpeg2_pipeline_programing(ctx, encode_state, encoder_context);
2450 gen75_mfc_run(ctx, encode_state, encoder_context);
2452 return VA_STATUS_SUCCESS;
2456 gen75_mfc_context_destroy(void *context)
2458 struct gen6_mfc_context *mfc_context = context;
2461 dri_bo_unreference(mfc_context->post_deblocking_output.bo);
2462 mfc_context->post_deblocking_output.bo = NULL;
2464 dri_bo_unreference(mfc_context->pre_deblocking_output.bo);
2465 mfc_context->pre_deblocking_output.bo = NULL;
2467 dri_bo_unreference(mfc_context->uncompressed_picture_source.bo);
2468 mfc_context->uncompressed_picture_source.bo = NULL;
2470 dri_bo_unreference(mfc_context->mfc_indirect_pak_bse_object.bo);
2471 mfc_context->mfc_indirect_pak_bse_object.bo = NULL;
2473 for (i = 0; i < NUM_MFC_DMV_BUFFERS; i++){
2474 dri_bo_unreference(mfc_context->direct_mv_buffers[i].bo);
2475 mfc_context->direct_mv_buffers[i].bo = NULL;
2478 dri_bo_unreference(mfc_context->intra_row_store_scratch_buffer.bo);
2479 mfc_context->intra_row_store_scratch_buffer.bo = NULL;
2481 dri_bo_unreference(mfc_context->macroblock_status_buffer.bo);
2482 mfc_context->macroblock_status_buffer.bo = NULL;
2484 dri_bo_unreference(mfc_context->deblocking_filter_row_store_scratch_buffer.bo);
2485 mfc_context->deblocking_filter_row_store_scratch_buffer.bo = NULL;
2487 dri_bo_unreference(mfc_context->bsd_mpc_row_store_scratch_buffer.bo);
2488 mfc_context->bsd_mpc_row_store_scratch_buffer.bo = NULL;
2490 for (i = 0; i < MAX_MFC_REFERENCE_SURFACES; i++){
2491 dri_bo_unreference(mfc_context->reference_surfaces[i].bo);
2492 mfc_context->reference_surfaces[i].bo = NULL;
2495 i965_gpe_context_destroy(&mfc_context->gpe_context);
2497 dri_bo_unreference(mfc_context->mfc_batchbuffer_surface.bo);
2498 mfc_context->mfc_batchbuffer_surface.bo = NULL;
2500 dri_bo_unreference(mfc_context->aux_batchbuffer_surface.bo);
2501 mfc_context->aux_batchbuffer_surface.bo = NULL;
2503 if (mfc_context->aux_batchbuffer)
2504 intel_batchbuffer_free(mfc_context->aux_batchbuffer);
2506 mfc_context->aux_batchbuffer = NULL;
2511 static VAStatus gen75_mfc_pipeline(VADriverContextP ctx,
2513 struct encode_state *encode_state,
2514 struct intel_encoder_context *encoder_context)
2519 case VAProfileH264ConstrainedBaseline:
2520 case VAProfileH264Main:
2521 case VAProfileH264High:
2522 case VAProfileH264MultiviewHigh:
2523 case VAProfileH264StereoHigh:
2524 vaStatus = gen75_mfc_avc_encode_picture(ctx, encode_state, encoder_context);
2527 /* FIXME: add for other profile */
2528 case VAProfileMPEG2Simple:
2529 case VAProfileMPEG2Main:
2530 vaStatus = gen75_mfc_mpeg2_encode_picture(ctx, encode_state, encoder_context);
2534 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
2541 Bool gen75_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
2543 struct gen6_mfc_context *mfc_context = calloc(1, sizeof(struct gen6_mfc_context));
2545 mfc_context->gpe_context.surface_state_binding_table.length = (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_MEDIA_SURFACES_GEN6;
2547 mfc_context->gpe_context.idrt.max_entries = MAX_GPE_KERNELS;
2548 mfc_context->gpe_context.idrt.entry_size = sizeof(struct gen6_interface_descriptor_data);
2550 mfc_context->gpe_context.curbe.length = 32 * 4;
2552 mfc_context->gpe_context.vfe_state.max_num_threads = 60 - 1;
2553 mfc_context->gpe_context.vfe_state.num_urb_entries = 16;
2554 mfc_context->gpe_context.vfe_state.gpgpu_mode = 0;
2555 mfc_context->gpe_context.vfe_state.urb_entry_size = 59 - 1;
2556 mfc_context->gpe_context.vfe_state.curbe_allocation_size = 37 - 1;
2558 i965_gpe_load_kernels(ctx,
2559 &mfc_context->gpe_context,
2563 mfc_context->pipe_mode_select = gen75_mfc_pipe_mode_select;
2564 mfc_context->set_surface_state = gen75_mfc_surface_state;
2565 mfc_context->ind_obj_base_addr_state = gen75_mfc_ind_obj_base_addr_state;
2566 mfc_context->avc_img_state = gen75_mfc_avc_img_state;
2567 mfc_context->avc_qm_state = gen75_mfc_avc_qm_state;
2568 mfc_context->avc_fqm_state = gen75_mfc_avc_fqm_state;
2569 mfc_context->insert_object = gen75_mfc_avc_insert_object;
2570 mfc_context->buffer_suface_setup = gen7_gpe_buffer_suface_setup;
2572 encoder_context->mfc_context = mfc_context;
2573 encoder_context->mfc_context_destroy = gen75_mfc_context_destroy;
2574 encoder_context->mfc_pipeline = gen75_mfc_pipeline;
2575 encoder_context->mfc_brc_prepare = intel_mfc_brc_prepare;