summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiang, Haihao <haihao.xiang@intel.com>2012-02-07 09:19:03 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2012-02-07 09:19:03 +0800
commite25b3fbce3fc3c13ca054ba9a512bec954642fa8 (patch)
treeaed481be9662d77c4ab61e75b55161fed42d62e7
parent8fe3eccdf7a882aef57390d16cde713a431f106d (diff)
Fix graphics memory allocation for VA surface
Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
-rw-r--r--src/gen6_mfc.c3
-rw-r--r--src/gen6_mfd.c8
-rw-r--r--src/gen7_mfd.c67
-rw-r--r--src/i965_avc_bsd.c4
-rw-r--r--src/i965_defines.h9
-rw-r--r--src/i965_drv_video.c147
-rw-r--r--src/i965_drv_video.h11
-rw-r--r--src/i965_media_mpeg2.c2
-rw-r--r--src/i965_post_processing.c4
-rw-r--r--src/i965_render.c66
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);
}
}