diff options
-rw-r--r-- | src/gen7_mfd.h | 1 | ||||
-rw-r--r-- | src/gen8_mfd.c | 35 | ||||
-rw-r--r-- | src/i965_decoder_utils.c | 24 | ||||
-rw-r--r-- | src/i965_decoder_utils.h | 4 |
4 files changed, 59 insertions, 5 deletions
diff --git a/src/gen7_mfd.h b/src/gen7_mfd.h index e3111ab..0200216 100644 --- a/src/gen7_mfd.h +++ b/src/gen7_mfd.h @@ -85,6 +85,7 @@ struct gen7_mfd_context GenBuffer bsd_mpc_row_store_scratch_buffer; GenBuffer mpr_row_store_scratch_buffer; GenBuffer bitplane_read_buffer; + GenBuffer segmentation_buffer; VASurfaceID jpeg_wa_surface_id; struct object_surface *jpeg_wa_surface_object; diff --git a/src/gen8_mfd.c b/src/gen8_mfd.c index 72b2640..1742bea 100644 --- a/src/gen8_mfd.c +++ b/src/gen8_mfd.c @@ -2785,6 +2785,9 @@ gen8_mfd_vp8_decode_init(VADriverContextP ctx, dri_bo_reference(gen7_mfd_context->pre_deblocking_output.bo); gen7_mfd_context->pre_deblocking_output.valid = pic_param->pic_fields.bits.loop_filter_disable; + intel_ensure_vp8_segmentation_buffer(ctx, + &gen7_mfd_context->segmentation_buffer, width_in_mbs, height_in_mbs); + /* The same as AVC */ dri_bo_unreference(gen7_mfd_context->intra_row_store_scratch_buffer.bo); bo = dri_bo_alloc(i965->intel.bufmgr, @@ -2838,6 +2841,13 @@ gen8_mfd_vp8_pic_state(VADriverContextP ctx, int i, j,log2num; unsigned int quantization_value[4][6]; + /* There is no safe way to error out if the segmentation buffer + could not be allocated. So, instead of aborting, simply decode + something even if the result may look totally inacurate */ + const unsigned int enable_segmentation = + pic_param->pic_fields.bits.segmentation_enabled && + gen7_mfd_context->segmentation_buffer.valid; + log2num = (int)log2(slice_param->num_of_partitions - 1); BEGIN_BCS_BATCH(batch, 38); @@ -2854,8 +2864,10 @@ gen8_mfd_vp8_pic_state(VADriverContextP ctx, pic_param->pic_fields.bits.mb_no_coeff_skip << 10 | pic_param->pic_fields.bits.update_mb_segmentation_map << 9 | pic_param->pic_fields.bits.segmentation_enabled << 8 | - 0 << 7 | /* segmentation id streamin disabled */ - 0 << 6 | /* segmentation id streamout disabled */ + (enable_segmentation && + !pic_param->pic_fields.bits.update_mb_segmentation_map) << 7 | + (enable_segmentation && + pic_param->pic_fields.bits.update_mb_segmentation_map) << 6 | (pic_param->pic_fields.bits.key_frame == 0 ? 1 : 0) << 5 | /* 0 indicate an intra frame in VP8 stream/spec($9.1)*/ pic_param->pic_fields.bits.filter_type << 4 | (pic_param->pic_fields.bits.version == 3) << 1 | /* full pixel mode for version 3 */ @@ -2950,9 +2962,18 @@ gen8_mfd_vp8_pic_state(VADriverContextP ctx, (pic_param->loop_filter_deltas_mode[0] & 0x7f) << 0); /* segmentation id stream base address, DW35-DW37 */ - OUT_BCS_BATCH(batch, 0); - OUT_BCS_BATCH(batch, 0); - OUT_BCS_BATCH(batch, 0); + if (enable_segmentation) { + OUT_BCS_RELOC(batch, gen7_mfd_context->segmentation_buffer.bo, + 0, I915_GEM_DOMAIN_INSTRUCTION, + 0); + OUT_BCS_BATCH(batch, 0); + OUT_BCS_BATCH(batch, 0); + } + else { + OUT_BCS_BATCH(batch, 0); + OUT_BCS_BATCH(batch, 0); + OUT_BCS_BATCH(batch, 0); + } ADVANCE_BCS_BATCH(batch); } @@ -3142,6 +3163,9 @@ gen8_mfd_context_destroy(void *hw_context) dri_bo_unreference(gen7_mfd_context->bitplane_read_buffer.bo); gen7_mfd_context->bitplane_read_buffer.bo = NULL; + dri_bo_unreference(gen7_mfd_context->segmentation_buffer.bo); + gen7_mfd_context->segmentation_buffer.bo = NULL; + dri_bo_unreference(gen7_mfd_context->jpeg_wa_slice_data_bo); intel_batchbuffer_free(gen7_mfd_context->base.batch); @@ -3174,6 +3198,7 @@ gen8_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config) } gen7_mfd_context->jpeg_wa_surface_id = VA_INVALID_SURFACE; + gen7_mfd_context->segmentation_buffer.valid = 0; switch (obj_config->profile) { case VAProfileMPEG2Simple: diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c index e80749c..2533381 100644 --- a/src/i965_decoder_utils.c +++ b/src/i965_decoder_utils.c @@ -827,3 +827,27 @@ intel_mpeg2_find_next_slice(struct decode_state *decode_state, return NULL; } + +/* Ensure the segmentation buffer is large enough for the supplied + number of MBs, or re-allocate it */ +bool +intel_ensure_vp8_segmentation_buffer(VADriverContextP ctx, GenBuffer *buf, + unsigned int mb_width, unsigned int mb_height) +{ + struct i965_driver_data * const i965 = i965_driver_data(ctx); + /* The segmentation map is a 64-byte aligned linear buffer, with + each cache line holding only 8 bits for 4 continuous MBs */ + const unsigned int buf_size = ((mb_width + 3) / 4) * 64 * mb_height; + + if (buf->valid) { + if (buf->bo && buf->bo->size >= buf_size) + return true; + drm_intel_bo_unreference(buf->bo); + buf->valid = false; + } + + buf->bo = drm_intel_bo_alloc(i965->intel.bufmgr, "segmentation map", + buf_size, 0x1000); + buf->valid = buf->bo != NULL; + return buf->valid; +} diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h index 8f64dfb..b7b72b3 100644 --- a/src/i965_decoder_utils.h +++ b/src/i965_decoder_utils.h @@ -106,4 +106,8 @@ intel_update_vp8_frame_store_index(VADriverContextP ctx, VAPictureParameterBufferVP8 *pic_param, GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]); +bool +intel_ensure_vp8_segmentation_buffer(VADriverContextP ctx, GenBuffer *buf, + unsigned int mb_width, unsigned int mb_height); + #endif /* I965_DECODER_UTILS_H */ |