diff --git a/packages/multimedia/libva-intel-driver/patches/libva-intel-driver-FD81447.patch b/packages/multimedia/libva-intel-driver/patches/libva-intel-driver-FD81447.patch index 3116c46810..e7e3017678 100644 --- a/packages/multimedia/libva-intel-driver/patches/libva-intel-driver-FD81447.patch +++ b/packages/multimedia/libva-intel-driver/patches/libva-intel-driver-FD81447.patch @@ -1,36 +1,306 @@ -From a8127c6e60225b0ccad670ecd296860f15efafd5 Mon Sep 17 00:00:00 2001 -From: Zhong Li -Date: Tue, 5 Aug 2014 15:58:10 +0800 -Subject: [PATCH] Check first_mb_in_slice of the first slice -Cc: zhong.li@intel.com - -Check of first_mb_in_slice of the first slice to avoid GPU hang. -FirstMbY and FirstMbX must be 0 if phantom slice is not added. -This is to fix the GPU hang bug: https://bugs.freedesktop.org/show_bug.cgi?id=81447 +HW requires driver to add a phantom slice when FirstMbX and FirstMbY are +not 0, in order to avc decoding error concealment. Otherwise, GPU may hang. +This patch is a workround for bug: https://bugs.freedesktop.org/show_bug.cgi?id=81447 Signed-off-by: Zhong Li --- - src/i965_decoder_utils.c | 7 +++++++ - 1 file changed, 7 insertions(+) + src/gen75_mfd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/gen7_mfd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/gen8_mfd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 240 insertions(+) -diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c -index 0af46cb..c861abb 100644 ---- a/src/i965_decoder_utils.c -+++ b/src/i965_decoder_utils.c -@@ -824,6 +824,13 @@ intel_decoder_check_avc_parameter(VADriverContextP ctx, - decode_state->reference_objects[i] = obj_surface; - } +diff --git a/src/gen75_mfd.c b/src/gen75_mfd.c +index b14db61..27ecbd9 100644 +--- a/src/gen75_mfd.c ++++ b/src/gen75_mfd.c +@@ -812,6 +812,83 @@ gen75_mfd_avc_directmode_state(VADriverContextP ctx, + } -+ /* As phantom slice is not supported right now, -+ * discard this frame if first_mb_in_slice of the first slice is not 0 -+ */ -+ slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[0]->buffer; -+ if (slice_param->first_mb_in_slice != 0) -+ goto error; + static void ++gen75_mfd_avc_phantom_slice_state(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ VASliceParameterBufferH264 *next_slice_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; ++ int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1; ++ int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */ ++ int slice_hor_pos, slice_ver_pos, slice_start_mb_num, next_slice_hor_pos, next_slice_ver_pos; ++ int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag && ++ pic_param->seq_fields.bits.mb_adaptive_frame_field_flag); + - for (j = 0; j < decode_state->num_slice_params; j++) { - assert(decode_state->slice_params && decode_state->slice_params[j]->buffer); - slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j]->buffer; --- -1.7.9.5 - ++ if (next_slice_param) { ++ int first_mb_in_next_slice; ++ ++ slice_hor_pos = 0; ++ slice_ver_pos = 0; ++ slice_start_mb_num = 0; ++ first_mb_in_next_slice = next_slice_param->first_mb_in_slice << mbaff_picture; ++ next_slice_hor_pos = first_mb_in_next_slice % width_in_mbs; ++ next_slice_ver_pos = first_mb_in_next_slice / width_in_mbs; ++ } else { ++ slice_hor_pos = 0; ++ slice_ver_pos = height_in_mbs; ++ slice_start_mb_num = width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag); ++ next_slice_hor_pos = 0; ++ next_slice_ver_pos = 0; ++ } ++ ++ BEGIN_BCS_BATCH(batch, 11); /* FIXME: is it 10??? */ ++ OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2)); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, ++ slice_ver_pos << 24 | ++ slice_hor_pos << 16 | ++ slice_start_mb_num << 0); ++ OUT_BCS_BATCH(batch, ++ next_slice_ver_pos << 16 | ++ next_slice_hor_pos << 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ ADVANCE_BCS_BATCH(batch); ++} ++ ++static void ++gen75_mfd_avc_phantom_slice_bsd_object(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; ++ ++ BEGIN_BCS_BATCH(batch, 6); ++ OUT_BCS_BATCH(batch, MFD_AVC_BSD_OBJECT | (6 - 2)); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ ADVANCE_BCS_BATCH(batch); ++} ++ ++static void ++gen75_mfd_avc_phantom_slice_first(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ VASliceParameterBufferH264 *next_slice_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ gen75_mfd_avc_phantom_slice_state(ctx, pic_param, next_slice_param, gen7_mfd_context); ++ gen75_mfd_avc_phantom_slice_bsd_object(ctx, pic_param, gen7_mfd_context); ++} ++ ++static void + gen75_mfd_avc_slice_state(VADriverContextP ctx, + VAPictureParameterBufferH264 *pic_param, + VASliceParameterBufferH264 *slice_param, +@@ -1145,6 +1222,9 @@ gen75_mfd_avc_decode_picture(VADriverContextP ctx, + else + next_slice_group_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j + 1]->buffer; + ++ if (j == 0 && slice_param->first_mb_in_slice) ++ gen75_mfd_avc_phantom_slice_first(ctx, pic_param, slice_param, gen7_mfd_context); ++ + for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { + assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); + assert((slice_param->slice_type == SLICE_TYPE_I) || +diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c +index 46a07a0..e50c83b 100755 +--- a/src/gen7_mfd.c ++++ b/src/gen7_mfd.c +@@ -506,6 +506,83 @@ gen7_mfd_avc_directmode_state(VADriverContextP ctx, + } + + static void ++gen7_mfd_avc_phantom_slice_state(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ VASliceParameterBufferH264 *next_slice_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; ++ int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1; ++ int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */ ++ int slice_hor_pos, slice_ver_pos, slice_start_mb_num, next_slice_hor_pos, next_slice_ver_pos; ++ int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag && ++ pic_param->seq_fields.bits.mb_adaptive_frame_field_flag); ++ ++ if (next_slice_param) { ++ int first_mb_in_next_slice; ++ ++ slice_hor_pos = 0; ++ slice_ver_pos = 0; ++ slice_start_mb_num = 0; ++ first_mb_in_next_slice = next_slice_param->first_mb_in_slice << mbaff_picture; ++ next_slice_hor_pos = first_mb_in_next_slice % width_in_mbs; ++ next_slice_ver_pos = first_mb_in_next_slice / width_in_mbs; ++ } else { ++ slice_hor_pos = 0; ++ slice_ver_pos = height_in_mbs; ++ slice_start_mb_num = width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag); ++ next_slice_hor_pos = 0; ++ next_slice_ver_pos = 0; ++ } ++ ++ BEGIN_BCS_BATCH(batch, 11); /* FIXME: is it 10??? */ ++ OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2)); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, ++ slice_ver_pos << 24 | ++ slice_hor_pos << 16 | ++ slice_start_mb_num << 0); ++ OUT_BCS_BATCH(batch, ++ next_slice_ver_pos << 16 | ++ next_slice_hor_pos << 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ ADVANCE_BCS_BATCH(batch); ++} ++ ++static void ++gen7_mfd_avc_phantom_slice_bsd_object(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; ++ ++ BEGIN_BCS_BATCH(batch, 6); ++ OUT_BCS_BATCH(batch, MFD_AVC_BSD_OBJECT | (6 - 2)); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ ADVANCE_BCS_BATCH(batch); ++} ++ ++static void ++gen7_mfd_avc_phantom_slice_first(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ VASliceParameterBufferH264 *next_slice_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ gen7_mfd_avc_phantom_slice_state(ctx, pic_param, next_slice_param, gen7_mfd_context); ++ gen7_mfd_avc_phantom_slice_bsd_object(ctx, pic_param, gen7_mfd_context); ++} ++ ++static void + gen7_mfd_avc_slice_state(VADriverContextP ctx, + VAPictureParameterBufferH264 *pic_param, + VASliceParameterBufferH264 *slice_param, +@@ -842,6 +919,9 @@ gen7_mfd_avc_decode_picture(VADriverContextP ctx, + else + next_slice_group_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j + 1]->buffer; + ++ if (j == 0 && slice_param->first_mb_in_slice) ++ gen7_mfd_avc_phantom_slice_first(ctx, pic_param, slice_param, gen7_mfd_context); ++ + for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { + assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); + assert((slice_param->slice_type == SLICE_TYPE_I) || +diff --git a/src/gen8_mfd.c b/src/gen8_mfd.c +index d08dd43..b8e7af4 100644 +--- a/src/gen8_mfd.c ++++ b/src/gen8_mfd.c +@@ -575,6 +575,83 @@ gen8_mfd_avc_directmode_state(VADriverContextP ctx, + } + + static void ++gen8_mfd_avc_phantom_slice_state(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ VASliceParameterBufferH264 *next_slice_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; ++ int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1; ++ int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */ ++ int slice_hor_pos, slice_ver_pos, slice_start_mb_num, next_slice_hor_pos, next_slice_ver_pos; ++ int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag && ++ pic_param->seq_fields.bits.mb_adaptive_frame_field_flag); ++ ++ if (next_slice_param) { ++ int first_mb_in_next_slice; ++ ++ slice_hor_pos = 0; ++ slice_ver_pos = 0; ++ slice_start_mb_num = 0; ++ first_mb_in_next_slice = next_slice_param->first_mb_in_slice << mbaff_picture; ++ next_slice_hor_pos = first_mb_in_next_slice % width_in_mbs; ++ next_slice_ver_pos = first_mb_in_next_slice / width_in_mbs; ++ } else { ++ slice_hor_pos = 0; ++ slice_ver_pos = height_in_mbs; ++ slice_start_mb_num = width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag); ++ next_slice_hor_pos = 0; ++ next_slice_ver_pos = 0; ++ } ++ ++ BEGIN_BCS_BATCH(batch, 11); /* FIXME: is it 10??? */ ++ OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2)); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, ++ slice_ver_pos << 24 | ++ slice_hor_pos << 16 | ++ slice_start_mb_num << 0); ++ OUT_BCS_BATCH(batch, ++ next_slice_ver_pos << 16 | ++ next_slice_hor_pos << 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ ADVANCE_BCS_BATCH(batch); ++} ++ ++static void ++gen8_mfd_avc_phantom_slice_bsd_object(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; ++ ++ BEGIN_BCS_BATCH(batch, 6); ++ OUT_BCS_BATCH(batch, MFD_AVC_BSD_OBJECT | (6 - 2)); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ OUT_BCS_BATCH(batch, 0); ++ ADVANCE_BCS_BATCH(batch); ++} ++ ++static void ++gen8_mfd_avc_phantom_slice_first(VADriverContextP ctx, ++ VAPictureParameterBufferH264 *pic_param, ++ VASliceParameterBufferH264 *next_slice_param, ++ struct gen7_mfd_context *gen7_mfd_context) ++{ ++ gen8_mfd_avc_phantom_slice_state(ctx, pic_param, next_slice_param, gen7_mfd_context); ++ gen8_mfd_avc_phantom_slice_bsd_object(ctx, pic_param, gen7_mfd_context); ++} ++ ++static void + gen8_mfd_avc_slice_state(VADriverContextP ctx, + VAPictureParameterBufferH264 *pic_param, + VASliceParameterBufferH264 *slice_param, +@@ -908,6 +985,9 @@ gen8_mfd_avc_decode_picture(VADriverContextP ctx, + else + next_slice_group_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j + 1]->buffer; + ++ if (j == 0 && slice_param->first_mb_in_slice) ++ gen8_mfd_avc_phantom_slice_first(ctx, pic_param, slice_param, gen7_mfd_context); ++ + for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { + assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); + assert((slice_param->slice_type == SLICE_TYPE_I) || +-- 1.7.9.5