From e25b3fbce3fc3c13ca054ba9a512bec954642fa8 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 7 Feb 2012 09:19:03 +0800 Subject: [PATCH] Fix graphics memory allocation for VA surface Signed-off-by: Xiang, Haihao --- src/gen6_mfc.c | 3 +- src/gen6_mfd.c | 8 +-- src/gen7_mfd.c | 67 +++++++++++++++------ src/i965_avc_bsd.c | 4 +- src/i965_defines.h | 9 +++ src/i965_drv_video.c | 147 +++++++++++++++++++++++++++++++++++++-------- src/i965_drv_video.h | 11 +++- src/i965_media_mpeg2.c | 2 +- src/i965_post_processing.c | 4 +- src/i965_render.c | 66 +++++++++----------- 10 files changed, 231 insertions(+), 90 deletions(-) diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c index 34de745..863d4ec 100644 --- a/src/gen6_mfc.c +++ b/src/gen6_mfc.c @@ -851,8 +851,7 @@ static VAStatus gen6_mfc_avc_prepare(VADriverContextP ctx, /*Setup all the input&output object*/ obj_surface = SURFACE(pPicParameter->reconstructed_picture); assert(obj_surface); - i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2')); - + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); mfc_context->post_deblocking_output.bo = obj_surface->bo; dri_bo_reference(mfc_context->post_deblocking_output.bo); diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c index 1dec16d..8280771 100644 --- a/src/gen6_mfd.c +++ b/src/gen6_mfd.c @@ -120,7 +120,7 @@ gen6_mfd_avc_frame_store_index(VADriverContextP ctx, struct object_surface *obj_surface = SURFACE(ref_pic->picture_id); assert(obj_surface); - i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420); for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen6_mfd_context->reference_surface); frame_idx++) { for (j = 0; j < ARRAY_ELEMS(gen6_mfd_context->reference_surface); j++) { @@ -975,7 +975,7 @@ 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); - i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); gen6_mfd_init_avc_surface(ctx, pic_param, obj_surface); dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo); @@ -1125,7 +1125,7 @@ gen6_mfd_mpeg2_decode_init(VADriverContextP ctx, /* 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('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); dri_bo_unreference(gen6_mfd_context->pre_deblocking_output.bo); gen6_mfd_context->pre_deblocking_output.bo = obj_surface->bo; @@ -1445,7 +1445,7 @@ gen6_mfd_vc1_decode_init(VADriverContextP ctx, /* 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('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); gen6_mfd_init_vc1_surface(ctx, pic_param, obj_surface); dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo); diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c index 4120745..0e05f72 100644 --- a/src/gen7_mfd.c +++ b/src/gen7_mfd.c @@ -120,7 +120,7 @@ gen7_mfd_avc_frame_store_index(VADriverContextP ctx, struct object_surface *obj_surface = SURFACE(ref_pic->picture_id); assert(obj_surface); - i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen7_mfd_context->reference_surface); frame_idx++) { for (j = 0; j < ARRAY_ELEMS(gen7_mfd_context->reference_surface); j++) { @@ -270,17 +270,9 @@ gen7_mfd_surface_state(VADriverContextP ctx, 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; - } - + y_cb_offset = obj_surface->y_cb_offset; + y_cr_offset = obj_surface->y_cr_offset; + BEGIN_BCS_BATCH(batch, 6); OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2)); OUT_BCS_BATCH(batch, 0); @@ -938,7 +930,7 @@ 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); - i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); gen7_mfd_init_avc_surface(ctx, pic_param, obj_surface); dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo); @@ -1087,7 +1079,7 @@ gen7_mfd_mpeg2_decode_init(VADriverContextP ctx, /* 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('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); dri_bo_unreference(gen7_mfd_context->pre_deblocking_output.bo); gen7_mfd_context->pre_deblocking_output.bo = obj_surface->bo; @@ -1416,7 +1408,7 @@ gen7_mfd_vc1_decode_init(VADriverContextP ctx, /* 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('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); gen7_mfd_init_vc1_surface(ctx, pic_param, obj_surface); dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo); @@ -1938,11 +1930,52 @@ gen7_mfd_jpeg_decode_init(VADriverContextP ctx, { struct i965_driver_data *i965 = i965_driver_data(ctx); struct object_surface *obj_surface; + VAPictureParameterBufferJPEG *pic_param; + int subsampling = SUBSAMPLE_YUV420; + + pic_param = (VAPictureParameterBufferJPEG *)decode_state->pic_param->buffer; + + if (pic_param->num_components == 1) + subsampling = SUBSAMPLE_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) + subsampling = SUBSAMPLE_YUV420; + else if (h1 == 2 && h2 == 1 && h3 == 1 && + v1 == 1 && v2 == 1 && v3 == 1) + subsampling = SUBSAMPLE_YUV422H; + else if (h1 == 1 && h2 == 1 && h3 == 1 && + v1 == 1 && v2 == 1 && v3 == 1) + subsampling = SUBSAMPLE_YUV444; + else if (h1 == 4 && h2 == 1 && h3 == 1 && + v1 == 1 && v2 == 1 && v3 == 1) + subsampling = SUBSAMPLE_YUV411; + else if (h1 == 1 && h2 == 1 && h3 == 1 && + v1 == 2 && v2 == 1 && v3 == 1) + subsampling = SUBSAMPLE_YUV422V; + else if (h1 == 2 && h2 == 1 && h3 == 1 && + v1 == 2 && v2 == 2 && v3 == 2) + subsampling = SUBSAMPLE_YUV422H; + else if (h2 == 2 && h2 == 2 && h3 == 2 && + v1 == 2 && v2 == 1 && v3 == 1) + subsampling = SUBSAMPLE_YUV422V; + else + assert(0); + } else { + assert(0); + } /* 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')); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('I','M','C','1'), subsampling); dri_bo_unreference(gen7_mfd_context->pre_deblocking_output.bo); gen7_mfd_context->pre_deblocking_output.bo = obj_surface->bo; @@ -1982,7 +2015,7 @@ gen7_mfd_jpeg_pic_state(VADriverContextP ctx, { struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; VAPictureParameterBufferJPEG *pic_param; - int chroma_type = GEN7_YUV400; + int chroma_type = GEN7_YUV420; int frame_width_in_blks; int frame_height_in_blks; diff --git a/src/i965_avc_bsd.c b/src/i965_avc_bsd.c index 4cc2095..612d0ee 100644 --- a/src/i965_avc_bsd.c +++ b/src/i965_avc_bsd.c @@ -482,7 +482,7 @@ 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_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); i965_avc_bsd_init_avc_bsd_surface(ctx, obj_surface, pic_param, i965_h264_context); avc_bsd_surface = obj_surface->private_data; @@ -927,7 +927,7 @@ i965_avc_bsd_frame_store_index(VADriverContextP ctx, int frame_idx; struct object_surface *obj_surface = SURFACE(ref_pic->picture_id); assert(obj_surface); - i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); for (frame_idx = 0; frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list); frame_idx++) { for (j = 0; j < ARRAY_ELEMS(i965_h264_context->fsid_list); j++) { diff --git a/src/i965_defines.h b/src/i965_defines.h index 13f6ed8..d530a5b 100644 --- a/src/i965_defines.h +++ b/src/i965_defines.h @@ -703,12 +703,21 @@ #define MFD_MODE_IT 1 #define MFX_SURFACE_PLANAR_420_8 4 +#define MFX_SURFACE_PLANAR_411_8 5 +#define MFX_SURFACE_PLANAR_422_8 6 #define MFX_SURFACE_MONOCHROME 12 #define MPEG_TOP_FIELD 1 #define MPEG_BOTTOM_FIELD 2 #define MPEG_FRAME 3 +#define SUBSAMPLE_YUV400 0 +#define SUBSAMPLE_YUV420 1 +#define SUBSAMPLE_YUV422H 2 +#define SUBSAMPLE_YUV422V 3 +#define SUBSAMPLE_YUV444 4 +#define SUBSAMPLE_YUV411 5 + #define URB_SIZE(intel) (IS_GEN7(intel->device_id) ? 4096 : \ IS_GEN6(intel->device_id) ? 1024 : \ IS_IRONLAKE(intel->device_id) ? 1024 : \ diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index 665f3f5..f4ff879 100644 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -498,21 +498,15 @@ i965_CreateSurfaces(VADriverContextP ctx, obj_surface->orig_width = width; obj_surface->orig_height = height; - if (IS_GEN6(i965->intel.device_id) || - IS_GEN7(i965->intel.device_id)) { - obj_surface->width = ALIGN(obj_surface->orig_width, 128); - obj_surface->height = ALIGN(obj_surface->orig_height, 32); - } else { - obj_surface->width = ALIGN(obj_surface->orig_width, 16); - obj_surface->height = ALIGN(obj_surface->orig_height, 16); - } - + obj_surface->width = ALIGN(width, 16); + obj_surface->height = ALIGN(height, 16); obj_surface->flags = SURFACE_REFERENCED; obj_surface->fourcc = 0; obj_surface->bo = NULL; obj_surface->locked_image_id = VA_INVALID_ID; obj_surface->private_data = NULL; obj_surface->free_private_data = NULL; + obj_surface->subsampling = SUBSAMPLE_YUV420; } /* Error recovery */ @@ -1729,36 +1723,138 @@ void i965_check_alloc_surface_bo(VADriverContextP ctx, struct object_surface *obj_surface, int tiled, - unsigned int fourcc) + unsigned int fourcc, + unsigned int subsampling) { struct i965_driver_data *i965 = i965_driver_data(ctx); + int region_width, region_height; if (obj_surface->bo) { assert(obj_surface->fourcc); assert(obj_surface->fourcc == fourcc); + assert(obj_surface->subsampling == subsampling); 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); + obj_surface->x_cb_offset = 0; /* X offset is always 0 */ + obj_surface->x_cr_offset = 0; + + if (tiled) { + assert(fourcc == VA_FOURCC('N', 'V', '1', '2') || + fourcc == VA_FOURCC('I', 'M', 'C', '1') || + fourcc == VA_FOURCC('I', 'M', 'C', '3')); + + obj_surface->width = ALIGN(obj_surface->orig_width, 128); + obj_surface->height = ALIGN(obj_surface->orig_height, 32); + obj_surface->cb_cr_pitch = obj_surface->width; + region_width = obj_surface->width; + region_height = obj_surface->height; + + if (fourcc == VA_FOURCC('N', 'V', '1', '2')) { + assert(subsampling == SUBSAMPLE_YUV420); + obj_surface->y_cb_offset = obj_surface->height; + obj_surface->y_cr_offset = obj_surface->height; + obj_surface->cb_cr_width = obj_surface->orig_width / 2; + obj_surface->cb_cr_height = obj_surface->orig_height / 2; + region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32); + } else if (fourcc == VA_FOURCC('I', 'M', 'C', '1') || + fourcc == VA_FOURCC('I', 'M', 'C', '3')) { + switch (subsampling) { + case SUBSAMPLE_YUV400: + obj_surface->cb_cr_width = 0; + obj_surface->cb_cr_height = 0; + break; + + case SUBSAMPLE_YUV420: + obj_surface->cb_cr_width = obj_surface->orig_width / 2; + obj_surface->cb_cr_height = obj_surface->orig_height / 2; + break; + + case SUBSAMPLE_YUV422H: + obj_surface->cb_cr_width = obj_surface->orig_width / 2; + obj_surface->cb_cr_height = obj_surface->orig_height; + break; + + case SUBSAMPLE_YUV422V: + obj_surface->cb_cr_width = obj_surface->orig_width; + obj_surface->cb_cr_height = obj_surface->orig_height / 2; + break; + + case SUBSAMPLE_YUV444: + obj_surface->cb_cr_width = obj_surface->orig_width; + obj_surface->cb_cr_height = obj_surface->orig_height; + break; + + case SUBSAMPLE_YUV411: + obj_surface->cb_cr_width = obj_surface->orig_width / 4; + obj_surface->cb_cr_height = obj_surface->orig_height; + break; + + default: + assert(0); + break; + } + + region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2; + + if (fourcc == VA_FOURCC('I', 'M', 'C', '1')) { + obj_surface->y_cb_offset = obj_surface->height; + obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32); + } else { + obj_surface->y_cb_offset = obj_surface->height; + obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32); + } + } + } else { + assert(fourcc != VA_FOURCC('I', 'M', 'C', '1') && + fourcc != VA_FOURCC('I', 'M', 'C', '3')); + assert(subsampling == SUBSAMPLE_YUV420); + + region_width = obj_surface->width; + region_height = obj_surface->height; + + switch (fourcc) { + case VA_FOURCC('N', 'V', '1', '2'): + obj_surface->y_cb_offset = obj_surface->height; + obj_surface->y_cr_offset = obj_surface->height; + obj_surface->cb_cr_width = obj_surface->orig_width / 2; + obj_surface->cb_cr_height = obj_surface->orig_height / 2; + obj_surface->cb_cr_pitch = obj_surface->width; + region_height = obj_surface->height + obj_surface->height / 2; + break; + + case VA_FOURCC('Y', 'V', '1', '2'): + case VA_FOURCC('I', '4', '2', '0'): + if (fourcc == VA_FOURCC('Y', 'V', '1', '2')) { + obj_surface->y_cr_offset = obj_surface->height; + obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4; + } else { + obj_surface->y_cb_offset = obj_surface->height; + obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4; + } + + obj_surface->cb_cr_width = obj_surface->orig_width / 2; + obj_surface->cb_cr_height = obj_surface->orig_height / 2; + obj_surface->cb_cr_pitch = obj_surface->width / 2; + region_height = obj_surface->height + obj_surface->height / 2; + break; + + default: + assert(0); + break; + } + } + + obj_surface->size = ALIGN(region_width * region_height, 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, - height, + region_width, + region_height, 1, &tiling_mode, &pitch, @@ -1773,6 +1869,7 @@ i965_check_alloc_surface_bo(VADriverContextP ctx, } obj_surface->fourcc = fourcc; + obj_surface->subsampling = subsampling; assert(obj_surface->bo); } @@ -1857,7 +1954,7 @@ VAStatus i965_DeriveImage(VADriverContextP ctx, } } - i965_check_alloc_surface_bo(ctx, obj_surface, HAS_TILED_SURFACE(i965), image->format.fourcc); + i965_check_alloc_surface_bo(ctx, obj_surface, HAS_TILED_SURFACE(i965), image->format.fourcc, SUBSAMPLE_YUV420); va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType, obj_surface->size, 1, NULL, obj_surface->bo, &image->buf); if (va_status != VA_STATUS_SUCCESS) diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h index 146438b..03b4c5d 100644 --- a/src/i965_drv_video.h +++ b/src/i965_drv_video.h @@ -162,6 +162,14 @@ struct object_surface VAImageID locked_image_id; void (*free_private_data)(void **data); void *private_data; + unsigned int subsampling; + int x_cb_offset; + int y_cb_offset; + int x_cr_offset; + int y_cr_offset; + int cb_cr_width; + int cb_cr_height; + int cb_cr_pitch; }; struct object_buffer @@ -254,6 +262,7 @@ void i965_check_alloc_surface_bo(VADriverContextP ctx, struct object_surface *obj_surface, int tiled, - unsigned int fourcc); + unsigned int fourcc, + unsigned int subsampling); #endif /* _I965_DRV_VIDEO_H_ */ diff --git a/src/i965_media_mpeg2.c b/src/i965_media_mpeg2.c index 1d87d9b..9278ab7 100644 --- a/src/i965_media_mpeg2.c +++ b/src/i965_media_mpeg2.c @@ -514,7 +514,7 @@ i965_media_mpeg2_surface_setup(VADriverContextP ctx, int w = obj_surface->width; int h = obj_surface->height; - i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('I','4','2','0')); + i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('I','4','2','0'), SUBSAMPLE_YUV420); if (picture_structure == MPEG_FRAME) { i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface, diff --git a/src/i965_post_processing.c b/src/i965_post_processing.c index 090403c..6e238b4 100644 --- a/src/i965_post_processing.c +++ b/src/i965_post_processing.c @@ -2236,7 +2236,7 @@ i965_post_processing( &out_surface_id); assert(status == VA_STATUS_SUCCESS); obj_surface = SURFACE(out_surface_id); - i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); i965_post_processing_internal(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, @@ -2258,7 +2258,7 @@ i965_post_processing( &out_surface_id); assert(status == VA_STATUS_SUCCESS); obj_surface = SURFACE(out_surface_id); - i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2')); + i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420); i965_post_processing_internal(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, diff --git a/src/i965_render.c b/src/i965_render.c index 99ab159..19edbf3 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -757,53 +757,47 @@ i965_render_src_surfaces_state(VADriverContextP ctx, { struct i965_driver_data *i965 = i965_driver_data(ctx); struct object_surface *obj_surface; - int w, h; + int region_pitch; int rw, rh; dri_bo *region; obj_surface = SURFACE(surface); assert(obj_surface); - w = obj_surface->width; - h = obj_surface->height; + region_pitch = obj_surface->width; rw = obj_surface->orig_width; rh = obj_surface->orig_height; region = obj_surface->bo; - i965_render_src_surface_state(ctx, 1, region, 0, rw, rh, w, I965_SURFACEFORMAT_R8_UNORM); /* Y */ - i965_render_src_surface_state(ctx, 2, region, 0, rw, rh, w, I965_SURFACEFORMAT_R8_UNORM); - - if (obj_surface->fourcc == VA_FOURCC('Y','V','1','2')) { - int u3 = 5, u4 = 6, v5 = 3, v6 = 4; - - 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); - } 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); + i965_render_src_surface_state(ctx, 1, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM); /* Y */ + i965_render_src_surface_state(ctx, 2, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM); + + if (obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2')) { + i965_render_src_surface_state(ctx, 3, region, + region_pitch * obj_surface->y_cb_offset, + obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch, + I965_SURFACEFORMAT_R8G8_UNORM); /* UV */ + i965_render_src_surface_state(ctx, 4, region, + region_pitch * obj_surface->y_cb_offset, + obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch, + 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); + i965_render_src_surface_state(ctx, 3, region, + region_pitch * obj_surface->y_cb_offset, + obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch, + I965_SURFACEFORMAT_R8_UNORM); /* U */ + i965_render_src_surface_state(ctx, 4, region, + region_pitch * obj_surface->y_cb_offset, + obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch, + I965_SURFACEFORMAT_R8_UNORM); + i965_render_src_surface_state(ctx, 5, region, + region_pitch * obj_surface->y_cr_offset, + obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch, + I965_SURFACEFORMAT_R8_UNORM); /* V */ + i965_render_src_surface_state(ctx, 6, region, + region_pitch * obj_surface->y_cr_offset, + obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch, + I965_SURFACEFORMAT_R8_UNORM); } } -- 2.7.4