diff options
author | Xiang, Haihao <haihao.xiang@intel.com> | 2011-09-07 16:18:19 +0800 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2012-02-07 08:44:44 +0800 |
commit | fb15cc581511f942c8e23a4d6300b8b36848f0f5 (patch) | |
tree | 0f270ad0c32867fae06e56e83a60516b11120e15 | |
parent | 452a8a5d0db34e3cea1a69cc30efbf3c46b02a9f (diff) | |
download | libva-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.c | 4 | ||||
-rw-r--r-- | src/gen7_mfd.c | 325 | ||||
-rw-r--r-- | src/gen7_mfd.h | 14 | ||||
-rw-r--r-- | src/i965_avc_bsd.c | 2 | ||||
-rw-r--r-- | src/i965_defines.h | 9 | ||||
-rw-r--r-- | src/i965_drv_video.c | 49 | ||||
-rw-r--r-- | src/i965_drv_video.h | 1 | ||||
-rw-r--r-- | src/i965_render.c | 34 |
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); } } |