summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2013-08-12 15:13:23 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2013-09-06 15:32:29 +0800
commit19c32cefd707c0b547be5da5123160eaf22411bb (patch)
tree619b15b2b581af3fe9dea6c8a4fa344779fe7ba9
parentfe782daf315bf491780dc61a6b866f13ec190762 (diff)
Use the scoreboard/walker to assure MB dependency for MPEG2 encoding
If MVP is added for MPEG2 encoding, it must be assured that the left macroblock should be already finished before processing the current macroblock. And this needs the scoreboard/walker mechanism to assure MB dependency. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> (cherry picked from commit 5d2163d02d395fc0a794d834979a06c287bf9ba5)
-rw-r--r--src/gen6_mfc_common.c124
-rw-r--r--src/gen6_vme.h7
-rw-r--r--src/gen75_vme.c37
3 files changed, 166 insertions, 2 deletions
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index ac28d23..469bf64 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -1186,3 +1186,127 @@ void intel_vme_mpeg2_state_setup(VADriverContextP ctx,
vme_state_message[MPEG2_PIC_WIDTH_HEIGHT] = (height_in_mbs << 16) |
width_in_mbs;
}
+
+void
+gen7_vme_mpeg2_walker_fill_vme_batchbuffer(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ int mb_width, int mb_height,
+ int kernel,
+ struct intel_encoder_context *encoder_context)
+{
+ struct gen6_vme_context *vme_context = encoder_context->vme_context;
+ unsigned int *command_ptr;
+
+#define MPEG2_SCOREBOARD (1 << 21)
+
+ dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
+ command_ptr = vme_context->vme_batchbuffer.bo->virtual;
+
+ {
+ unsigned int mb_intra_ub, score_dep;
+ int x_outer, y_outer, x_inner, y_inner;
+ int xtemp_outer = 0;
+ int first_mb = 0;
+ int num_mb = mb_width * mb_height;
+
+ x_outer = 0;
+ y_outer = 0;
+
+
+ for (; x_outer < (mb_width -2 ) && !loop_in_bounds(x_outer, y_outer, first_mb, num_mb, mb_width, mb_height); ) {
+ x_inner = x_outer;
+ y_inner = y_outer;
+ for (; !loop_in_bounds(x_inner, y_inner, first_mb, num_mb, mb_width, mb_height);) {
+ mb_intra_ub = 0;
+ score_dep = 0;
+ if (x_inner != 0) {
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
+ score_dep |= MB_SCOREBOARD_A;
+ }
+ if (y_inner != 0) {
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
+ score_dep |= MB_SCOREBOARD_B;
+
+ if (x_inner != 0)
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
+
+ if (x_inner != (mb_width -1)) {
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
+ score_dep |= MB_SCOREBOARD_C;
+ }
+ }
+
+ *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
+ *command_ptr++ = kernel;
+ *command_ptr++ = MPEG2_SCOREBOARD;
+ /* Indirect data */
+ *command_ptr++ = 0;
+ /* the (X, Y) term of scoreboard */
+ *command_ptr++ = ((y_inner << 16) | x_inner);
+ *command_ptr++ = score_dep;
+ /*inline data */
+ *command_ptr++ = (mb_width << 16 | y_inner << 8 | x_inner);
+ *command_ptr++ = ((1 << 18) | (1 << 16) | (mb_intra_ub << 8));
+ x_inner -= 2;
+ y_inner += 1;
+ }
+ x_outer += 1;
+ }
+
+ xtemp_outer = mb_width - 2;
+ if (xtemp_outer < 0)
+ xtemp_outer = 0;
+ x_outer = xtemp_outer;
+ y_outer = 0;
+ for (;!loop_in_bounds(x_outer, y_outer, first_mb, num_mb, mb_width, mb_height); ) {
+ y_inner = y_outer;
+ x_inner = x_outer;
+ for (; !loop_in_bounds(x_inner, y_inner, first_mb, num_mb, mb_width, mb_height);) {
+ mb_intra_ub = 0;
+ score_dep = 0;
+ if (x_inner != 0) {
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_AE;
+ score_dep |= MB_SCOREBOARD_A;
+ }
+ if (y_inner != 0) {
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_B;
+ score_dep |= MB_SCOREBOARD_B;
+
+ if (x_inner != 0)
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_D;
+
+ if (x_inner != (mb_width -1)) {
+ mb_intra_ub |= INTRA_PRED_AVAIL_FLAG_C;
+ score_dep |= MB_SCOREBOARD_C;
+ }
+ }
+
+ *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
+ *command_ptr++ = kernel;
+ *command_ptr++ = MPEG2_SCOREBOARD;
+ /* Indirect data */
+ *command_ptr++ = 0;
+ /* the (X, Y) term of scoreboard */
+ *command_ptr++ = ((y_inner << 16) | x_inner);
+ *command_ptr++ = score_dep;
+ /*inline data */
+ *command_ptr++ = (mb_width << 16 | y_inner << 8 | x_inner);
+ *command_ptr++ = ((1 << 18) | (1 << 16) | (mb_intra_ub << 8));
+
+ x_inner -= 2;
+ y_inner += 1;
+ }
+ x_outer++;
+ if (x_outer >= mb_width) {
+ y_outer += 1;
+ x_outer = xtemp_outer;
+ }
+ }
+ }
+
+ *command_ptr++ = 0;
+ *command_ptr++ = MI_BATCH_BUFFER_END;
+
+ dri_bo_unmap(vme_context->vme_batchbuffer.bo);
+ return;
+}
diff --git a/src/gen6_vme.h b/src/gen6_vme.h
index ab0ff3b..b130b58 100644
--- a/src/gen6_vme.h
+++ b/src/gen6_vme.h
@@ -151,4 +151,11 @@ intel_vme_mpeg2_state_setup(VADriverContextP ctx,
struct encode_state *encode_state,
struct intel_encoder_context *encoder_context);
+extern void
+gen7_vme_mpeg2_walker_fill_vme_batchbuffer(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ int mb_width, int mb_height,
+ int kernel,
+ struct intel_encoder_context *encoder_context);
+
#endif /* _GEN6_VME_H_ */
diff --git a/src/gen75_vme.c b/src/gen75_vme.c
index 3935528..3e769ed 100644
--- a/src/gen75_vme.c
+++ b/src/gen75_vme.c
@@ -916,14 +916,47 @@ gen75_vme_mpeg2_pipeline_programing(VADriverContextP ctx,
{
struct gen6_vme_context *vme_context = encoder_context->vme_context;
struct intel_batchbuffer *batch = encoder_context->base.batch;
+ VAEncPictureParameterBufferMPEG2 *pic_param = NULL;
VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16;
int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16;
+ bool allow_hwscore = true;
+ int s;
+ int kernel_shader;
- gen75_vme_mpeg2_fill_vme_batchbuffer(ctx,
+ pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
+
+ for (s = 0; s < encode_state->num_slice_params_ext; s++) {
+ int j;
+ VAEncSliceParameterBufferMPEG2 *slice_param = (VAEncSliceParameterBufferMPEG2 *)encode_state->slice_params_ext[s]->buffer;
+
+ for (j = 0; j < encode_state->slice_params_ext[s]->num_elements; j++) {
+ if (slice_param->macroblock_address % width_in_mbs) {
+ allow_hwscore = false;
+ break;
+ }
+ }
+ }
+
+ pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
+ if (pic_param->picture_type == VAEncPictureTypeIntra) {
+ allow_hwscore = false;
+ kernel_shader = VME_INTRA_SHADER;
+ } else {
+ kernel_shader = VME_INTER_SHADER;
+ }
+
+ if (allow_hwscore)
+ gen7_vme_mpeg2_walker_fill_vme_batchbuffer(ctx,
+ encode_state,
+ width_in_mbs, height_in_mbs,
+ kernel_shader,
+ encoder_context);
+ else
+ gen75_vme_mpeg2_fill_vme_batchbuffer(ctx,
encode_state,
width_in_mbs, height_in_mbs,
- is_intra ? VME_INTRA_SHADER : VME_INTER_SHADER,
+ kernel_shader,
0,
encoder_context);