summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiang, Haihao <haihao.xiang@intel.com>2011-09-07 16:18:19 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2012-02-07 08:44:44 +0800
commitfb15cc581511f942c8e23a4d6300b8b36848f0f5 (patch)
tree0f270ad0c32867fae06e56e83a60516b11120e15
parent452a8a5d0db34e3cea1a69cc30efbf3c46b02a9f (diff)
downloadlibva-intel-driver-fb15cc581511f942c8e23a4d6300b8b36848f0f5.tar.gz
i965_drv_video: support JPEG decoding on Ivybridge
Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
-rw-r--r--src/gen6_mfd.c4
-rw-r--r--src/gen7_mfd.c325
-rw-r--r--src/gen7_mfd.h14
-rw-r--r--src/i965_avc_bsd.c2
-rw-r--r--src/i965_defines.h9
-rw-r--r--src/i965_drv_video.c49
-rw-r--r--src/i965_drv_video.h1
-rw-r--r--src/i965_render.c34
8 files changed, 411 insertions, 27 deletions
diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
index dd8fda1b..1dec16d8 100644
--- a/src/gen6_mfd.c
+++ b/src/gen6_mfd.c
@@ -975,8 +975,8 @@ gen6_mfd_avc_decode_init(VADriverContextP ctx,
assert(obj_surface);
obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
- gen6_mfd_init_avc_surface(ctx, pic_param, obj_surface);
i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+ gen6_mfd_init_avc_surface(ctx, pic_param, obj_surface);
dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo);
gen6_mfd_context->post_deblocking_output.bo = obj_surface->bo;
@@ -1445,8 +1445,8 @@ gen6_mfd_vc1_decode_init(VADriverContextP ctx,
/* Current decoded picture */
obj_surface = SURFACE(decode_state->current_render_target);
assert(obj_surface);
- gen6_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+ gen6_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo);
gen6_mfd_context->post_deblocking_output.bo = obj_surface->bo;
diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c
index c04f5781..3d946b89 100644
--- a/src/gen7_mfd.c
+++ b/src/gen7_mfd.c
@@ -234,7 +234,7 @@ gen7_mfd_pipe_mode_select(VADriverContextP ctx,
standard_select == MFX_FORMAT_VC1 ||
standard_select == MFX_FORMAT_JPEG);
- BEGIN_BCS_BATCH(batch, 5); /* FIXME: 5 ??? */
+ BEGIN_BCS_BATCH(batch, 5);
OUT_BCS_BATCH(batch, MFX_PIPE_MODE_SELECT | (5 - 2));
OUT_BCS_BATCH(batch,
(MFX_LONG_MODE << 17) | /* Currently only support long format */
@@ -265,7 +265,21 @@ gen7_mfd_surface_state(VADriverContextP ctx,
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_surface *obj_surface = SURFACE(decode_state->current_render_target);
+ unsigned int y_cb_offset;
+ unsigned int y_cr_offset;
+
assert(obj_surface);
+
+ if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
+ y_cb_offset = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
+ y_cr_offset = ALIGN(obj_surface->height, 32);
+ } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
+ y_cb_offset = ALIGN(obj_surface->height, 32);
+ y_cr_offset = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
+ } else {
+ y_cb_offset = ALIGN(obj_surface->height, 32);
+ y_cr_offset = 0;
+ }
BEGIN_BCS_BATCH(batch, 6);
OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
@@ -275,16 +289,18 @@ gen7_mfd_surface_state(VADriverContextP ctx,
((obj_surface->orig_width - 1) << 4));
OUT_BCS_BATCH(batch,
(MFX_SURFACE_PLANAR_420_8 << 28) | /* 420 planar YUV surface */
- (1 << 27) | /* FIXME: set to 0 for JPEG */
- (0 << 22) | /* surface object control state, FIXME??? */
+ ((standard_select != MFX_FORMAT_JPEG) << 27) | /* interleave chroma, set to 0 for JPEG */
+ (0 << 22) | /* surface object control state, ignored */
((obj_surface->width - 1) << 3) | /* pitch */
- (0 << 2) | /* must be 0 for interleave U/V */
+ (0 << 2) | /* must be 0 */
(1 << 1) | /* must be tiled */
(I965_TILEWALK_YMAJOR << 0)); /* tile walk, must be 1 */
OUT_BCS_BATCH(batch,
- (0 << 16) | /* FIXME: fix it for JPEG */
- (obj_surface->height)); /* FIXME: fix it for JPEG */
- OUT_BCS_BATCH(batch, 0); /* FIXME: fix it for JPEG */
+ (0 << 16) | /* X offset for U(Cb), must be 0 */
+ (y_cb_offset << 0)); /* Y offset for U(Cb) */
+ OUT_BCS_BATCH(batch,
+ (0 << 16) | /* X offset for V(Cr), must be 0 */
+ (y_cr_offset << 0)); /* Y offset for V(Cr), must be 0 for video codec, non-zoro for JPEG */
ADVANCE_BCS_BATCH(batch);
}
@@ -922,8 +938,8 @@ gen7_mfd_avc_decode_init(VADriverContextP ctx,
assert(obj_surface);
obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
- gen7_mfd_init_avc_surface(ctx, pic_param, obj_surface);
i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+ gen7_mfd_init_avc_surface(ctx, pic_param, obj_surface);
dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
gen7_mfd_context->post_deblocking_output.bo = obj_surface->bo;
@@ -1400,8 +1416,8 @@ gen7_mfd_vc1_decode_init(VADriverContextP ctx,
/* Current decoded picture */
obj_surface = SURFACE(decode_state->current_render_target);
assert(obj_surface);
- gen7_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+ gen7_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
gen7_mfd_context->post_deblocking_output.bo = obj_surface->bo;
@@ -1915,6 +1931,293 @@ gen7_mfd_vc1_decode_picture(VADriverContextP ctx,
intel_batchbuffer_flush(batch);
}
+static void
+gen7_mfd_jpeg_decode_init(VADriverContextP ctx,
+ struct decode_state *decode_state,
+ struct gen7_mfd_context *gen7_mfd_context)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct object_surface *obj_surface;
+
+ /* Current decoded picture */
+ obj_surface = SURFACE(decode_state->current_render_target);
+ assert(obj_surface);
+ i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('I','M','C','1'));
+
+ dri_bo_unreference(gen7_mfd_context->pre_deblocking_output.bo);
+ gen7_mfd_context->pre_deblocking_output.bo = obj_surface->bo;
+ dri_bo_reference(gen7_mfd_context->pre_deblocking_output.bo);
+ gen7_mfd_context->pre_deblocking_output.valid = 1;
+
+ gen7_mfd_context->post_deblocking_output.bo = NULL;
+ gen7_mfd_context->post_deblocking_output.valid = 0;
+
+ gen7_mfd_context->intra_row_store_scratch_buffer.bo = NULL;
+ gen7_mfd_context->intra_row_store_scratch_buffer.valid = 0;
+
+ gen7_mfd_context->deblocking_filter_row_store_scratch_buffer.bo = NULL;
+ gen7_mfd_context->deblocking_filter_row_store_scratch_buffer.valid = 0;
+
+ gen7_mfd_context->bsd_mpc_row_store_scratch_buffer.bo = NULL;
+ gen7_mfd_context->bsd_mpc_row_store_scratch_buffer.valid = 0;
+
+ gen7_mfd_context->mpr_row_store_scratch_buffer.bo = NULL;
+ gen7_mfd_context->mpr_row_store_scratch_buffer.valid = 0;
+
+ gen7_mfd_context->bitplane_read_buffer.bo = NULL;
+ gen7_mfd_context->bitplane_read_buffer.valid = 0;
+}
+
+static const int va_to_gen7_jpeg_rotation[4] = {
+ GEN7_JPEG_ROTATION_0,
+ GEN7_JPEG_ROTATION_90,
+ GEN7_JPEG_ROTATION_180,
+ GEN7_JPEG_ROTATION_270
+};
+
+static void
+gen7_mfd_jpeg_pic_state(VADriverContextP ctx,
+ struct decode_state *decode_state,
+ struct gen7_mfd_context *gen7_mfd_context)
+{
+ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+ VAPictureParameterBufferJPEG *pic_param;
+ int chroma_type = GEN7_YUV400;
+ int frame_width_in_blks;
+ int frame_height_in_blks;
+
+ assert(decode_state->pic_param && decode_state->pic_param->buffer);
+ pic_param = (VAPictureParameterBufferJPEG *)decode_state->pic_param->buffer;
+
+ assert(pic_param->type == VA_JPEG_SOF0); /* only support BASELINE on Ivybridge */
+
+ if (pic_param->num_components == 1)
+ chroma_type = GEN7_YUV400;
+ else if (pic_param->num_components == 3) {
+ int h1 = pic_param->components[0].h_sampling_factor;
+ int h2 = pic_param->components[1].h_sampling_factor;
+ int h3 = pic_param->components[2].h_sampling_factor;
+ int v1 = pic_param->components[0].v_sampling_factor;
+ int v2 = pic_param->components[1].v_sampling_factor;
+ int v3 = pic_param->components[2].v_sampling_factor;
+
+ if (h1 == 2 && h2 == 1 && h3 == 1 &&
+ v1 == 2 && v2 == 1 && v3 == 1)
+ chroma_type = GEN7_YUV420;
+ else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+ v1 == 1 && v2 == 1 && v3 == 1)
+ chroma_type = GEN7_YUV422H_2Y;
+ else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+ v1 == 1 && v2 == 1 && v3 == 1)
+ chroma_type = GEN7_YUV444;
+ else if (h1 == 4 && h2 == 1 && h3 == 1 &&
+ v1 == 1 && v2 == 1 && v3 == 1)
+ chroma_type = GEN7_YUV411;
+ else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+ v1 == 2 && v2 == 1 && v3 == 1)
+ chroma_type = GEN7_YUV422V_2Y;
+ else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+ v1 == 2 && v2 == 2 && v3 == 2)
+ chroma_type = GEN7_YUV422H_4Y;
+ else if (h2 == 2 && h2 == 2 && h3 == 2 &&
+ v1 == 2 && v2 == 1 && v3 == 1)
+ chroma_type = GEN7_YUV422V_4Y;
+ else
+ assert(0);
+ }
+
+ if (chroma_type == GEN7_YUV400 &&
+ chroma_type == GEN7_YUV444 &&
+ chroma_type == GEN7_YUV422V_2Y) {
+ frame_width_in_blks = ((pic_param->image_width + 7) / 8);
+ frame_height_in_blks = ((pic_param->image_height + 7) / 8);
+ } else if (chroma_type == GEN7_YUV411) {
+ frame_width_in_blks = ((pic_param->image_width + 31) / 32) * 4;
+ frame_height_in_blks = ((pic_param->image_height + 31) / 32) * 4;
+ } else {
+ frame_width_in_blks = ((pic_param->image_width + 15) / 16) * 2;
+ frame_height_in_blks = ((pic_param->image_height + 15) / 16) * 2;
+ }
+
+ BEGIN_BCS_BATCH(batch, 3);
+ OUT_BCS_BATCH(batch, MFX_JPEG_PIC_STATE | (3 - 2));
+ OUT_BCS_BATCH(batch,
+ (va_to_gen7_jpeg_rotation[pic_param->rotation] << 4) | /* rotation */
+ (chroma_type << 0));
+ OUT_BCS_BATCH(batch,
+ ((frame_height_in_blks - 1) << 16) | /* FrameHeightInBlks */
+ ((frame_width_in_blks - 1) << 0)); /* FrameWidthInBlks */
+ ADVANCE_BCS_BATCH(batch);
+}
+
+static const int va_to_gen7_jpeg_hufftable[2] = {
+ MFX_HUFFTABLE_ID_Y,
+ MFX_HUFFTABLE_ID_UV
+};
+
+static void
+gen7_mfd_jpeg_huff_table_state(VADriverContextP ctx,
+ struct decode_state *decode_state,
+ struct gen7_mfd_context *gen7_mfd_context)
+{
+ VAHuffmanTableBufferJPEG *huffman_table;
+ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+ int index;
+
+ if (!decode_state->huffman_table || !decode_state->huffman_table->buffer)
+ return;
+
+ huffman_table = (VAHuffmanTableBufferJPEG *)decode_state->huffman_table->buffer;
+
+ for (index = 0; index < 2; index++) {
+ if (huffman_table->huffman_table_mask & (1 << index)) {
+ int id = va_to_gen7_jpeg_hufftable[index];
+ BEGIN_BCS_BATCH(batch, 53);
+ OUT_BCS_BATCH(batch, MFX_JPEG_HUFF_TABLE_STATE | (53 - 2));
+ OUT_BCS_BATCH(batch, id);
+ intel_batchbuffer_data(batch, huffman_table->huffman_table[index].dc_bits, 12);
+ intel_batchbuffer_data(batch, huffman_table->huffman_table[index].dc_huffval, 12);
+ intel_batchbuffer_data(batch, huffman_table->huffman_table[index].ac_bits, 16);
+ intel_batchbuffer_data(batch, huffman_table->huffman_table[index].ac_huffval, 164);
+ ADVANCE_BCS_BATCH(batch);
+ }
+ }
+}
+
+static const int va_to_gen7_jpeg_qm[4] = {
+ MFX_QM_JPEG_LUMA_Y_QUANTIZER_MATRIX,
+ MFX_QM_JPEG_CHROMA_CB_QUANTIZER_MATRIX,
+ MFX_QM_JPEG_CHROMA_CR_QUANTIZER_MATRIX,
+ MFX_QM_JPEG_ALPHA_QUANTIZER_MATRIX
+};
+
+static void
+gen7_mfd_jpeg_qm_state(VADriverContextP ctx,
+ struct decode_state *decode_state,
+ struct gen7_mfd_context *gen7_mfd_context)
+{
+ VAIQMatrixBufferJPEG *iq_matrix;
+ int index;
+
+ if (!decode_state->iq_matrix || !decode_state->iq_matrix->buffer)
+ return;
+
+ iq_matrix = (VAIQMatrixBufferJPEG *)decode_state->iq_matrix->buffer;
+
+ for (index = 0; index < 3; index++) {
+ if (iq_matrix->quantizer_matrix_mask & (1 << index)) {
+ int qm_type = va_to_gen7_jpeg_qm[index];
+ unsigned char *qm = iq_matrix->quantizer_matrix[index];
+
+ gen7_mfd_qm_state(ctx, qm_type, qm, 64, gen7_mfd_context);
+ }
+ }
+}
+
+static void
+gen7_mfd_jpeg_bsd_object(VADriverContextP ctx,
+ VAPictureParameterBufferJPEG *pic_param,
+ VASliceParameterBufferJPEG *slice_param,
+ VASliceParameterBufferJPEG *next_slice_param,
+ dri_bo *slice_data_bo,
+ struct gen7_mfd_context *gen7_mfd_context)
+{
+ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+ int scan_component_mask = 0;
+ int i;
+
+ assert(slice_param->num_components > 0);
+ assert(slice_param->num_components < 4);
+ assert(slice_param->num_components <= pic_param->num_components);
+
+ for (i = 0; i < slice_param->num_components; i++) {
+ switch (pic_param->components[slice_param->components[i].index].component_id) {
+ case VA_JPEG_COMPONENT_ID_Y:
+ scan_component_mask |= (1 << 0);
+ break;
+ case VA_JPEG_COMPONENT_ID_U:
+ scan_component_mask |= (1 << 1);
+ break;
+ case VA_JPEG_COMPONENT_ID_V:
+ scan_component_mask |= (1 << 2);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ BEGIN_BCS_BATCH(batch, 6);
+ OUT_BCS_BATCH(batch, MFD_JPEG_BSD_OBJECT | (6 - 2));
+ OUT_BCS_BATCH(batch,
+ slice_param->slice_data_size);
+ OUT_BCS_BATCH(batch,
+ slice_param->slice_data_offset);
+ OUT_BCS_BATCH(batch,
+ slice_param->slice_horizontal_position << 16 |
+ slice_param->slice_vertical_position << 0);
+ OUT_BCS_BATCH(batch,
+ ((slice_param->num_components != 1) << 30) | /* interleaved */
+ (scan_component_mask << 27) | /* scan components */
+ (0 << 26) | /* disable interrupt allowed */
+ (slice_param->count_in_mcus << 0)); /* MCU count */
+ OUT_BCS_BATCH(batch,
+ (slice_param->restart_interval << 0)); /* RestartInterval */
+ ADVANCE_BCS_BATCH(batch);
+}
+
+static void
+gen7_mfd_jpeg_decode_picture(VADriverContextP ctx,
+ struct decode_state *decode_state,
+ struct gen7_mfd_context *gen7_mfd_context)
+{
+ struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+ VAPictureParameterBufferJPEG *pic_param;
+ VASliceParameterBufferJPEG *slice_param, *next_slice_param, *next_slice_group_param;
+ dri_bo *slice_data_bo;
+ int i, j;
+
+ assert(decode_state->pic_param && decode_state->pic_param->buffer);
+ pic_param = (VAPictureParameterBufferJPEG *)decode_state->pic_param->buffer;
+
+ gen7_mfd_jpeg_decode_init(ctx, decode_state, gen7_mfd_context);
+ intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
+ intel_batchbuffer_emit_mi_flush(batch);
+ gen7_mfd_pipe_mode_select(ctx, decode_state, MFX_FORMAT_JPEG, gen7_mfd_context);
+ gen7_mfd_surface_state(ctx, decode_state, MFX_FORMAT_JPEG, gen7_mfd_context);
+ gen7_mfd_pipe_buf_addr_state(ctx, decode_state, MFX_FORMAT_JPEG, gen7_mfd_context);
+ gen7_mfd_jpeg_pic_state(ctx, decode_state, gen7_mfd_context);
+ gen7_mfd_jpeg_qm_state(ctx, decode_state, gen7_mfd_context);
+ gen7_mfd_jpeg_huff_table_state(ctx, decode_state, gen7_mfd_context);
+
+ for (j = 0; j < decode_state->num_slice_params; j++) {
+ assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
+ slice_param = (VASliceParameterBufferJPEG *)decode_state->slice_params[j]->buffer;
+ slice_data_bo = decode_state->slice_datas[j]->bo;
+ gen7_mfd_ind_obj_base_addr_state(ctx, slice_data_bo, MFX_FORMAT_JPEG, gen7_mfd_context);
+
+ if (j == decode_state->num_slice_params - 1)
+ next_slice_group_param = NULL;
+ else
+ next_slice_group_param = (VASliceParameterBufferJPEG *)decode_state->slice_params[j + 1]->buffer;
+
+ for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
+ assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
+
+ if (i < decode_state->slice_params[j]->num_elements - 1)
+ next_slice_param = slice_param + 1;
+ else
+ next_slice_param = next_slice_group_param;
+
+ gen7_mfd_jpeg_bsd_object(ctx, pic_param, slice_param, next_slice_param, slice_data_bo, gen7_mfd_context);
+ slice_param++;
+ }
+ }
+
+ intel_batchbuffer_end_atomic(batch);
+ intel_batchbuffer_flush(batch);
+}
+
static void
gen7_mfd_decode_picture(VADriverContextP ctx,
VAProfile profile,
@@ -1945,6 +2248,10 @@ gen7_mfd_decode_picture(VADriverContextP ctx,
gen7_mfd_vc1_decode_picture(ctx, decode_state, gen7_mfd_context);
break;
+ case VAProfileJPEGBaseline:
+ gen7_mfd_jpeg_decode_picture(ctx, decode_state, gen7_mfd_context);
+ break;
+
default:
assert(0);
break;
diff --git a/src/gen7_mfd.h b/src/gen7_mfd.h
index 08658f47..8eb7ab26 100644
--- a/src/gen7_mfd.h
+++ b/src/gen7_mfd.h
@@ -53,6 +53,20 @@ struct gen7_avc_surface
#define GEN7_VC1_ADVANCED_PROFILE 2
#define GEN7_VC1_RESERVED_PROFILE 3
+#define GEN7_JPEG_ROTATION_0 0
+#define GEN7_JPEG_ROTATION_90 1
+#define GEN7_JPEG_ROTATION_270 2
+#define GEN7_JPEG_ROTATION_180 3
+
+#define GEN7_YUV400 0
+#define GEN7_YUV420 1
+#define GEN7_YUV422H_2Y 2
+#define GEN7_YUV444 3
+#define GEN7_YUV411 4
+#define GEN7_YUV422V_2Y 5
+#define GEN7_YUV422H_4Y 6
+#define GEN7_YUV422V_4Y 7
+
struct gen7_vc1_surface
{
dri_bo *dmv;
diff --git a/src/i965_avc_bsd.c b/src/i965_avc_bsd.c
index 6f133a35..4cc20954 100644
--- a/src/i965_avc_bsd.c
+++ b/src/i965_avc_bsd.c
@@ -482,9 +482,9 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
assert(obj_surface);
obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
+ i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
i965_avc_bsd_init_avc_bsd_surface(ctx, obj_surface, pic_param, i965_h264_context);
avc_bsd_surface = obj_surface->private_data;
- i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_top,
I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
diff --git a/src/i965_defines.h b/src/i965_defines.h
index 509ae9e8..13f6ed89 100644
--- a/src/i965_defines.h
+++ b/src/i965_defines.h
@@ -314,6 +314,11 @@
#define MFD_VC1_BSD_OBJECT MFX(2, 2, 1, 8)
+#define MFX_JPEG_PIC_STATE MFX(2, 7, 0, 0)
+#define MFX_JPEG_HUFF_TABLE_STATE MFX(2, 7, 0, 2)
+
+#define MFD_JPEG_BSD_OBJECT MFX(2, 7, 1, 8)
+
#define I965_DEPTHFORMAT_D32_FLOAT 1
#define BASE_ADDRESS_MODIFY (1 << 0)
@@ -689,6 +694,10 @@
#define MFX_QM_JPEG_LUMA_Y_QUANTIZER_MATRIX 0
#define MFX_QM_JPEG_CHROMA_CB_QUANTIZER_MATRIX 1
#define MFX_QM_JPEG_CHROMA_CR_QUANTIZER_MATRIX 2
+#define MFX_QM_JPEG_ALPHA_QUANTIZER_MATRIX 3 /* for new device */
+
+#define MFX_HUFFTABLE_ID_Y 0
+#define MFX_HUFFTABLE_ID_UV 1 /* UV on Ivybridge */
#define MFD_MODE_VLD 0
#define MFD_MODE_IT 1
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index e1e81c71..abfd02e8 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -71,6 +71,9 @@
IS_GEN6((ctx)->intel.device_id)) && \
(ctx)->intel.has_bsd)
+#define HAS_JPEG(ctx) (IS_GEN7((ctx)->intel.device_id) && \
+ (ctx)->intel.has_bsd)
+
enum {
I965_SURFACETYPE_RGBA = 1,
I965_SURFACETYPE_YUV,
@@ -187,6 +190,10 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
profile_list[i++] = VAProfileVC1Advanced;
}
+ if (HAS_JPEG(i965)) {
+ profile_list[i++] = VAProfileJPEGBaseline;
+ }
+
/* If the assert fails then I965_MAX_PROFILES needs to be bigger */
assert(i <= I965_MAX_PROFILES);
*num_profiles = i;
@@ -228,6 +235,11 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
entrypoint_list[n++] = VAEntrypointVLD;
break;
+ case VAProfileJPEGBaseline:
+ if (HAS_JPEG(i965))
+ entrypoint_list[n++] = VAEntrypointVLD;
+ break;
+
default:
break;
}
@@ -348,6 +360,15 @@ i965_CreateConfig(VADriverContextP ctx,
break;
+ case VAProfileJPEGBaseline:
+ if (HAS_JPEG(i965) && VAEntrypointVLD == entrypoint) {
+ vaStatus = VA_STATUS_SUCCESS;
+ } else {
+ vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+ }
+
+ break;
+
default:
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
break;
@@ -486,7 +507,6 @@ i965_CreateSurfaces(VADriverContextP ctx,
obj_surface->height = ALIGN(obj_surface->orig_height, 16);
}
- obj_surface->size = SIZE_YUV420(obj_surface->width, obj_surface->height);
obj_surface->flags = SURFACE_REFERENCED;
obj_surface->fourcc = 0;
obj_surface->bo = NULL;
@@ -956,6 +976,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
case VAEncSequenceParameterBufferType:
case VAEncPictureParameterBufferType:
case VAEncSliceParameterBufferType:
+ case VAHuffmanTableBufferType:
/* Ok */
break;
@@ -1256,6 +1277,7 @@ i965_BeginPicture(VADriverContextP ctx,
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
+DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
#define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
@@ -1297,6 +1319,10 @@ i965_decoder_render_picture(VADriverContextP ctx,
vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
break;
+ case VAHuffmanTableBufferType:
+ vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
+ break;
+
default:
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
break;
@@ -1703,17 +1729,32 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
- if (obj_surface->bo)
+ if (obj_surface->bo) {
+ assert(obj_surface->fourcc);
+ assert(obj_surface->fourcc == fourcc);
return;
+ if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
+ fourcc == VA_FOURCC('I', 'M', 'C', '3'))
+ obj_surface->size = ALIGN(obj_surface->width * obj_surface->height * 2, 0x1000);
+ else
+ obj_surface->size = ALIGN(obj_surface->width * obj_surface->height * 3 / 2, 0x1000);
+
if (tiled) {
uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
unsigned long pitch;
+ unsigned long height;
+
+ if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
+ fourcc == VA_FOURCC('I', 'M', 'C', '3'))
+ height = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32) * 2;
+ else
+ height = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
"vaapi surface",
- obj_surface->width,
- obj_surface->height + obj_surface->height / 2,
+ obj_surface->width,
+ height,
1,
&tiling_mode,
&pitch,
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 67ca6f69..146438be 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -81,6 +81,7 @@ struct decode_state
struct buffer_store **slice_params;
struct buffer_store *iq_matrix;
struct buffer_store *bit_plane;
+ struct buffer_store *huffman_table;
struct buffer_store **slice_datas;
VASurfaceID current_render_target;
int max_slice_params;
diff --git a/src/i965_render.c b/src/i965_render.c
index 0fa76d2d..99ab159c 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -780,18 +780,30 @@ i965_render_src_surfaces_state(VADriverContextP ctx,
i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* V */
i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
+ } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
+ int u3 = 5, u4 = 6, v5 = 3, v6 = 4;
+
+ i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* U */
+ i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+ i965_render_src_surface_state(ctx, v5, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* V */
+ i965_render_src_surface_state(ctx, v6, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+ } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
+ int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
+
+ i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* U */
+ i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+ i965_render_src_surface_state(ctx, v5, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* V */
+ i965_render_src_surface_state(ctx, v6, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+ } else if (obj_surface->fourcc == VA_FOURCC('N','V','1','2')) {
+ i965_render_src_surface_state(ctx, 3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM); /* UV */
+ i965_render_src_surface_state(ctx, 4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM);
} else {
- if (obj_surface->fourcc == VA_FOURCC('N','V','1','2')) {
- i965_render_src_surface_state(ctx, 3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM); /* UV */
- i965_render_src_surface_state(ctx, 4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM);
- } else {
- int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
-
- i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* U */
- i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
- i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* V */
- i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
- }
+ int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
+
+ i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* U */
+ i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
+ i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* V */
+ i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
}
}