summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gen7_mfd.h1
-rw-r--r--src/gen8_mfd.c35
-rw-r--r--src/i965_decoder_utils.c24
-rw-r--r--src/i965_decoder_utils.h4
4 files changed, 59 insertions, 5 deletions
diff --git a/src/gen7_mfd.h b/src/gen7_mfd.h
index e3111abe..02002164 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 72b26403..1742beaa 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 e80749c5..2533381c 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 8f64dfb7..b7b72b3e 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 */