From fcd8f475be6d1980c5b5e0d56ab7b0bf6e7a15c6 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Sat, 2 Apr 2011 13:54:53 +0800 Subject: [PATCH] Workaround for 720p/1080p encoding Signed-off-by: Xiang, Haihao --- i965_drv_video/gen6_mfc.c | 54 +++++++++++++++++++++------------ i965_drv_video/gen6_vme.c | 61 ++++++++++++++++++++++++-------------- i965_drv_video/intel_batchbuffer.c | 16 ++++++++++ i965_drv_video/intel_batchbuffer.h | 3 ++ 4 files changed, 92 insertions(+), 42 deletions(-) diff --git a/i965_drv_video/gen6_mfc.c b/i965_drv_video/gen6_mfc.c index 602d0d2..52b8bc3 100644 --- a/i965_drv_video/gen6_mfc.c +++ b/i965_drv_video/gen6_mfc.c @@ -409,13 +409,14 @@ gen6_mfc_avc_insert_object(VADriverContextP ctx, int flush_data) ADVANCE_BCS_BATCH(ctx); } -static void +static int gen6_mfc_avc_pak_object(VADriverContextP ctx, int x, int y, int end_mb, int qp,unsigned int *msg) { - BEGIN_BCS_BATCH(ctx, 11); + int len_in_dowrds = 11; - OUT_BCS_BATCH(ctx, MFC_AVC_PAK_OBJECT | (11 -2 ) ); + BEGIN_BCS_BATCH(ctx, len_in_dowrds); + OUT_BCS_BATCH(ctx, MFC_AVC_PAK_OBJECT | (len_in_dowrds - 2)); OUT_BCS_BATCH(ctx, 0); OUT_BCS_BATCH(ctx, 0); OUT_BCS_BATCH(ctx, @@ -439,6 +440,7 @@ gen6_mfc_avc_pak_object(VADriverContextP ctx, int x, int y, int end_mb, int qp,u ADVANCE_BCS_BATCH(ctx); + return len_in_dowrds * 4; } static void gen6_mfc_init(VADriverContextP ctx) @@ -506,30 +508,44 @@ void gen6_mfc_avc_pipeline_programing(VADriverContextP ctx, void *obj) struct gen6_media_state *media_state = &i965->gen6_media_state; VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param->buffer; unsigned int *msg; + int emit_new_state = 1, object_len_in_bytes; intel_batchbuffer_start_atomic_bcs(ctx, 0x1000); - intel_batchbuffer_emit_mi_flush_bcs(ctx); - gen6_mfc_pipe_mode_select(ctx); - gen6_mfc_surface_state(ctx); - gen6_mfc_pipe_buf_addr_state(ctx); - gen6_mfc_ind_obj_base_addr_state(ctx); - gen6_mfc_bsp_buf_base_addr_state(ctx); - gen6_mfc_avc_img_state(ctx); - gen6_mfc_avc_qm_state(ctx); - gen6_mfc_avc_directmode_state(ctx); - gen6_mfc_avc_slice_state(ctx); - gen6_mfc_avc_fqm_state(ctx); - /*gen6_mfc_avc_ref_idx_state(ctx);*/ - /*gen6_mfc_avc_insert_object(ctx, 0);*/ dri_bo_map(media_state->vme_output.bo , 1); msg = (unsigned int *)media_state->vme_output.bo->virtual; - for( y = 0; y < height_in_mbs; y++) { - for( x = 0; x < width_in_mbs; x++) { + + for (y = 0; y < height_in_mbs; y++) { + for (x = 0; x < width_in_mbs; x++) { int last_mb = (y == (height_in_mbs-1)) && ( x == (width_in_mbs-1) ); int qp = pSequenceParameter->initial_qp; - gen6_mfc_avc_pak_object(ctx, x, y, last_mb, qp, msg); + + if (emit_new_state) { + intel_batchbuffer_emit_mi_flush_bcs(ctx); + gen6_mfc_pipe_mode_select(ctx); + gen6_mfc_surface_state(ctx); + gen6_mfc_pipe_buf_addr_state(ctx); + gen6_mfc_ind_obj_base_addr_state(ctx); + gen6_mfc_bsp_buf_base_addr_state(ctx); + gen6_mfc_avc_img_state(ctx); + gen6_mfc_avc_qm_state(ctx); + gen6_mfc_avc_directmode_state(ctx); + gen6_mfc_avc_slice_state(ctx); + gen6_mfc_avc_fqm_state(ctx); + /*gen6_mfc_avc_ref_idx_state(ctx);*/ + /*gen6_mfc_avc_insert_object(ctx, 0);*/ + emit_new_state = 0; + } + + object_len_in_bytes = gen6_mfc_avc_pak_object(ctx, x, y, last_mb, qp, msg); msg += 4; + + if (intel_batchbuffer_check_free_space_bcs(ctx, object_len_in_bytes) == 0) { + intel_batchbuffer_end_atomic_bcs(ctx); + intel_batchbuffer_flush_bcs(ctx); + emit_new_state = 1; + intel_batchbuffer_start_atomic_bcs(ctx, 0x1000); + } } } diff --git a/i965_drv_video/gen6_vme.c b/i965_drv_video/gen6_vme.c index b62e1f8..a12bbea 100644 --- a/i965_drv_video/gen6_vme.c +++ b/i965_drv_video/gen6_vme.c @@ -424,7 +424,7 @@ static void gen6_vme_idrt(VADriverContextP ctx) ADVANCE_BATCH(ctx); } -static void gen6_vme_media_object(VADriverContextP ctx, +static int gen6_vme_media_object(VADriverContextP ctx, VAContextID context, struct mfc_encode_state *encode_state, int mb_x, int mb_y) @@ -435,10 +435,11 @@ static void gen6_vme_media_object(VADriverContextP ctx, unsigned char *pPixel[17]; int pitch = obj_surface->width; int mb_width = ALIGN(obj_surface->orig_width, 16) / 16; + int len_in_dowrds = 6 + 32 + 8; - BEGIN_BATCH(ctx, 6 + 32 + 8); + BEGIN_BATCH(ctx, len_in_dowrds); - OUT_BATCH(ctx, CMD_MEDIA_OBJECT | 44); + OUT_BATCH(ctx, CMD_MEDIA_OBJECT | (len_in_dowrds - 2)); OUT_BATCH(ctx, VME_INTRA_SHADER); /*Interface Descriptor Offset*/ OUT_BATCH(ctx, 0); OUT_BATCH(ctx, 0); @@ -552,6 +553,8 @@ static void gen6_vme_media_object(VADriverContextP ctx, drm_intel_gem_bo_unmap_gtt( obj_surface->bo ); ADVANCE_BATCH(ctx); + + return len_in_dowrds * 4; } static void gen6_vme_media_init(VADriverContextP ctx) @@ -616,34 +619,46 @@ static void gen6_vme_pipeline_programing(VADriverContextP ctx, { struct i965_driver_data *i965 = i965_driver_data(ctx); struct object_context *obj_context = CONTEXT(context); - int width_in_mbs = (obj_context->picture_width + 15) / 16; int height_in_mbs = (obj_context->picture_height + 15) / 16; - int x,y; + int x, y; + int emit_new_state = 1, object_len_in_bytes; intel_batchbuffer_start_atomic(ctx, 0x1000); - - /*Step1: MI_FLUSH/PIPE_CONTROL*/ - BEGIN_BATCH(ctx, 4); - OUT_BATCH(ctx, CMD_PIPE_CONTROL | 0x02); - OUT_BATCH(ctx, 0); - OUT_BATCH(ctx, 0); - OUT_BATCH(ctx, 0); - ADVANCE_BATCH(ctx); - - /*Step2: State command PIPELINE_SELECT*/ - gen6_vme_pipeline_select(ctx); - - /*Step3: State commands configuring pipeline states*/ - gen6_vme_state_base_address(ctx); - gen6_vme_vfe_state(ctx); - gen6_vme_curbe_load(ctx); - gen6_vme_idrt(ctx); for(y = 0; y < height_in_mbs; y++){ for(x = 0; x < width_in_mbs; x++){ + + if (emit_new_state) { + /*Step1: MI_FLUSH/PIPE_CONTROL*/ + BEGIN_BATCH(ctx, 4); + OUT_BATCH(ctx, CMD_PIPE_CONTROL | 0x02); + OUT_BATCH(ctx, 0); + OUT_BATCH(ctx, 0); + OUT_BATCH(ctx, 0); + ADVANCE_BATCH(ctx); + + /*Step2: State command PIPELINE_SELECT*/ + gen6_vme_pipeline_select(ctx); + + /*Step3: State commands configuring pipeline states*/ + gen6_vme_state_base_address(ctx); + gen6_vme_vfe_state(ctx); + gen6_vme_curbe_load(ctx); + gen6_vme_idrt(ctx); + + emit_new_state = 0; + } + /*Step4: Primitive commands*/ - gen6_vme_media_object(ctx, context, encode_state, x, y); + object_len_in_bytes = gen6_vme_media_object(ctx, context, encode_state, x, y); + + if (intel_batchbuffer_check_free_space(ctx, object_len_in_bytes) == 0) { + intel_batchbuffer_end_atomic(ctx); + intel_batchbuffer_flush(ctx); + emit_new_state = 1; + intel_batchbuffer_start_atomic(ctx, 0x1000); + } } } diff --git a/i965_drv_video/intel_batchbuffer.c b/i965_drv_video/intel_batchbuffer.c index 9d623f1..f4e629a 100644 --- a/i965_drv_video/intel_batchbuffer.c +++ b/i965_drv_video/intel_batchbuffer.c @@ -431,3 +431,19 @@ intel_batchbuffer_check_batchbuffer_flag(VADriverContextP ctx, int flag) intel_batchbuffer_flush_helper(ctx, intel->batch); intel->batch->flag = flag; } + +int +intel_batchbuffer_check_free_space(VADriverContextP ctx, int size) +{ + struct intel_driver_data *intel = intel_driver_data(ctx); + + return intel_batchbuffer_space_helper(intel->batch) >= size; +} + +int +intel_batchbuffer_check_free_space_bcs(VADriverContextP ctx, int size) +{ + struct intel_driver_data *intel = intel_driver_data(ctx); + + return intel_batchbuffer_space_helper(intel->batch_bcs) >= size; +} diff --git a/i965_drv_video/intel_batchbuffer.h b/i965_drv_video/intel_batchbuffer.h index 25652e1..77174fe 100644 --- a/i965_drv_video/intel_batchbuffer.h +++ b/i965_drv_video/intel_batchbuffer.h @@ -59,6 +59,9 @@ void intel_batchbuffer_advance_batch_bcs(VADriverContextP ctx); void intel_batchbuffer_check_batchbuffer_flag(VADriverContextP ctx, int flag); +int intel_batchbuffer_check_free_space(VADriverContextP ctx, int size); +int intel_batchbuffer_check_free_space_bcs(VADriverContextP ctx, int size); + #define __BEGIN_BATCH(ctx, n, flag) do { \ intel_batchbuffer_check_batchbuffer_flag(ctx, flag); \ intel_batchbuffer_require_space(ctx, (n) * 4); \ -- 2.7.4