From 1304372a138e2831bbe4e2dd5c84243c67a89c50 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 12 Jul 2011 15:28:29 +0800 Subject: [PATCH] i965_drv_video: update post processing interface Signed-off-by: Xiang, Haihao --- i965_drv_video.c | 3 - i965_drv_video.h | 5 - i965_post_processing.c | 476 +++++++++++++++++++++++++------------------------ i965_post_processing.h | 20 ++- i965_render.c | 41 +++-- 5 files changed, 282 insertions(+), 263 deletions(-) diff --git a/i965_drv_video.c b/i965_drv_video.c index 39ec1ba..26b07a2 100644 --- a/i965_drv_video.c +++ b/i965_drv_video.c @@ -435,8 +435,6 @@ i965_destroy_surface(struct object_heap *heap, struct object_base *obj) dri_bo_unreference(obj_surface->bo); obj_surface->bo = NULL; - dri_bo_unreference(obj_surface->pp_out_bo); - obj_surface->pp_out_bo = NULL; if (obj_surface->free_private_data != NULL) { obj_surface->free_private_data(&obj_surface->private_data); @@ -491,7 +489,6 @@ i965_CreateSurfaces(VADriverContextP ctx, obj_surface->flags = SURFACE_REFERENCED; obj_surface->fourcc = 0; obj_surface->bo = NULL; - obj_surface->pp_out_bo = NULL; obj_surface->locked_image_id = VA_INVALID_ID; obj_surface->private_data = NULL; obj_surface->free_private_data = NULL; diff --git a/i965_drv_video.h b/i965_drv_video.h index 94e7ed3..fd423bc 100644 --- a/i965_drv_video.h +++ b/i965_drv_video.h @@ -156,11 +156,6 @@ struct object_surface int flags; unsigned int fourcc; dri_bo *bo; - int pp_out_width; - int pp_out_height; - int orig_pp_out_width; - int orig_pp_out_height; - dri_bo *pp_out_bo; VAImageID locked_image_id; void (*free_private_data)(void **data); void *private_data; diff --git a/i965_post_processing.c b/i965_post_processing.c index d0ad586..4201d09 100644 --- a/i965_post_processing.c +++ b/i965_post_processing.c @@ -65,21 +65,21 @@ static const uint32_t pp_nv12_dndi_gen5[][4] = { #include "shaders/post_processing/nv12_dndi_nv12.g4b.gen5" }; -static void pp_null_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth); -static void pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth); -static void pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth); -static void pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth); -static void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth); +static void pp_null_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect); +static void pp_nv12_avs_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect); +static void pp_nv12_scaling_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect); +static void pp_nv12_load_save_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect); +static void pp_nv12_dndi_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect); static struct pp_module pp_modules_gen5[] = { { @@ -553,24 +553,12 @@ pp_null_set_block_parameter(struct i965_post_processing_context *pp_context, int } static void -pp_null_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth) +pp_null_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_post_processing_context *pp_context = i965->pp_context; - struct object_surface *obj_surface; - - /* surface */ - obj_surface = SURFACE(surface); - dri_bo_unreference(obj_surface->pp_out_bo); - obj_surface->pp_out_bo = obj_surface->bo; - dri_bo_reference(obj_surface->pp_out_bo); - assert(obj_surface->pp_out_bo); - obj_surface->pp_out_width = obj_surface->width; - obj_surface->pp_out_height = obj_surface->height; - obj_surface->orig_pp_out_width = obj_surface->orig_width; - obj_surface->orig_pp_out_height = obj_surface->orig_height; /* private function & data */ pp_context->pp_x_steps = pp_null_x_steps; @@ -604,9 +592,9 @@ pp_load_save_set_block_parameter(struct i965_post_processing_context *pp_context } static void -pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth) +pp_nv12_load_save_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_post_processing_context *pp_context = i965->pp_context; @@ -618,27 +606,15 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu int orig_w, orig_h; unsigned int tiling, swizzle; - /* surface */ - obj_surface = SURFACE(surface); + /* source surface */ + obj_surface = SURFACE(in_surface_id); orig_w = obj_surface->orig_width; orig_h = obj_surface->orig_height; w = obj_surface->width; h = obj_surface->height; - - dri_bo_unreference(obj_surface->pp_out_bo); - obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr, - "intermediate surface", - SIZE_YUV420(w, h), - 4096); - assert(obj_surface->pp_out_bo); - obj_surface->pp_out_width = obj_surface->width; - obj_surface->pp_out_height = obj_surface->height; - obj_surface->orig_pp_out_width = obj_surface->orig_width; - obj_surface->orig_pp_out_height = obj_surface->orig_height; - - /* source Y surface index 1 */ dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); + /* source Y surface index 1 */ index = 1; pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); @@ -696,9 +672,17 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu pp_context->surfaces[index].s_bo); dri_bo_unmap(bo); + /* destination surface */ + obj_surface = SURFACE(out_surface_id); + orig_w = obj_surface->orig_width; + orig_h = obj_surface->orig_height; + w = obj_surface->width; + h = obj_surface->height; + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); + /* destination Y surface index 7 */ index = 7; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -716,6 +700,7 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu ss->ss2.width = orig_w / 4 - 1; ss->ss2.height = orig_h - 1; ss->ss3.pitch = w - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, @@ -726,7 +711,7 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu /* destination UV surface index 8 */ index = 8; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -744,6 +729,7 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu ss->ss2.width = orig_w / 4 - 1; ss->ss2.height = orig_h / 2 - 1; ss->ss3.pitch = w - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, @@ -780,21 +766,22 @@ pp_scaling_y_steps(void *private_context) static int pp_scaling_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y) { + struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context; float src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step; float src_y_steping = pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step; - pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16; - pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8; - pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16; - pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8; + pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_scaling_context->src_normalized_x; + pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_scaling_context->src_normalized_y; + pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16 + pp_scaling_context->dest_x; + pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8 + pp_scaling_context->dest_y; return 0; } static void -pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth) +pp_nv12_scaling_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_post_processing_context *pp_context = i965->pp_context; @@ -804,37 +791,19 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, struct i965_surface_state *ss; dri_bo *bo; int index; - int w, h; - int orig_w, orig_h; - int pp_out_w, pp_out_h; - int orig_pp_out_w, orig_pp_out_h; + int in_w, in_h, in_wpitch, in_hpitch; + int out_w, out_h, out_wpitch, out_hpitch; unsigned int tiling, swizzle; - /* surface */ - obj_surface = SURFACE(surface); - orig_w = obj_surface->orig_width; - orig_h = obj_surface->orig_height; - w = obj_surface->width; - h = obj_surface->height; - - orig_pp_out_w = destw; - orig_pp_out_h = desth; - pp_out_w = ALIGN(orig_pp_out_w, 16); - pp_out_h = ALIGN(orig_pp_out_h, 16); - dri_bo_unreference(obj_surface->pp_out_bo); - obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr, - "intermediate surface", - SIZE_YUV420(pp_out_w, pp_out_h), - 4096); - assert(obj_surface->pp_out_bo); - obj_surface->orig_pp_out_width = orig_pp_out_w; - obj_surface->orig_pp_out_height = orig_pp_out_h; - obj_surface->pp_out_width = pp_out_w; - obj_surface->pp_out_height = pp_out_h; - - /* source Y surface index 1 */ + /* source surface */ + obj_surface = SURFACE(in_surface_id); + in_w = obj_surface->orig_width; + in_h = obj_surface->orig_height; + in_wpitch = obj_surface->width; + in_hpitch = obj_surface->height; dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); + /* source Y surface index 1 */ index = 1; pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); @@ -851,9 +820,9 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM; ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset; - ss->ss2.width = orig_w - 1; - ss->ss2.height = orig_h - 1; - ss->ss3.pitch = w - 1; + ss->ss2.width = in_w - 1; + ss->ss2.height = in_h - 1; + ss->ss3.pitch = in_wpitch - 1; pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, @@ -879,22 +848,30 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, memset(ss, 0, sizeof(*ss)); ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM; - ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + w * h; - ss->ss2.width = orig_w / 2 - 1; - ss->ss2.height = orig_h / 2 - 1; - ss->ss3.pitch = w - 1; + ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + in_wpitch * in_hpitch; + ss->ss2.width = in_w / 2 - 1; + ss->ss2.height = in_h / 2 - 1; + ss->ss3.pitch = in_wpitch - 1; pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, 0, - w * h, + in_wpitch * in_hpitch, offsetof(struct i965_surface_state, ss1), pp_context->surfaces[index].s_bo); dri_bo_unmap(bo); + /* destination surface */ + obj_surface = SURFACE(out_surface_id); + out_w = obj_surface->orig_width; + out_h = obj_surface->orig_height; + out_wpitch = obj_surface->width; + out_hpitch = obj_surface->height; + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); + /* destination Y surface index 7 */ index = 7; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -909,9 +886,10 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM; ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset; - ss->ss2.width = pp_out_w / 4 - 1; - ss->ss2.height = pp_out_h - 1; - ss->ss3.pitch = pp_out_w - 1; + ss->ss2.width = out_w / 4 - 1; + ss->ss2.height = out_h - 1; + ss->ss3.pitch = out_wpitch - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, @@ -922,7 +900,7 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, /* destination UV surface index 8 */ index = 8; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -936,14 +914,15 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, memset(ss, 0, sizeof(*ss)); ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM; - ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + pp_out_w * pp_out_h; - ss->ss2.width = pp_out_w / 4 - 1; - ss->ss2.height = pp_out_h / 2 - 1; - ss->ss3.pitch = pp_out_w - 1; + ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + out_wpitch * out_hpitch; + ss->ss2.width = out_w / 4 - 1; + ss->ss2.height = out_h / 2 - 1; + ss->ss3.pitch = out_wpitch - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - pp_out_w * pp_out_h, + out_wpitch * out_hpitch, offsetof(struct i965_surface_state, ss1), pp_context->surfaces[index].s_bo); dri_bo_unmap(bo); @@ -974,13 +953,18 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input, pp_context->pp_y_steps = pp_scaling_y_steps; pp_context->pp_set_block_parameter = pp_scaling_set_block_parameter; - pp_scaling_context->dest_w = pp_out_w; - pp_scaling_context->dest_h = pp_out_h; + pp_scaling_context->dest_x = dst_rect->x; + pp_scaling_context->dest_y = dst_rect->y; + pp_scaling_context->dest_w = ALIGN(dst_rect->width, 16); + pp_scaling_context->dest_h = ALIGN(dst_rect->height, 16); + pp_scaling_context->src_normalized_x = (float)src_rect->x / in_w / out_w; + pp_scaling_context->src_normalized_y = (float)src_rect->y / in_h / out_h; + + pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / out_h; - pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) 1.0 / pp_out_h; - pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) 1.0 / pp_out_w; - pp_inline_parameter.grf5.block_count_x = pp_out_w / 16; /* 1 x N */ - pp_inline_parameter.grf5.number_blocks = pp_out_w / 16; + pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / out_w; + pp_inline_parameter.grf5.block_count_x = pp_scaling_context->dest_w / 16; /* 1 x N */ + pp_inline_parameter.grf5.number_blocks = pp_scaling_context->dest_w / 16; pp_inline_parameter.grf5.block_vertical_mask = 0xff; pp_inline_parameter.grf5.block_horizontal_mask = 0xffff; } @@ -1011,7 +995,8 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int pp_inline_parameter.grf6.video_step_delta = 0; if (x == 0) { - pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2; + pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2 + + pp_avs_context->src_normalized_x; } else { src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step; video_step_delta = pp_inline_parameter.grf6.video_step_delta; @@ -1035,7 +1020,7 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int if (x == 0) { pp_inline_parameter.grf5.normalized_video_x_scaling_step = 1.0 / pp_avs_context->dest_w; - pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = 0.0; + pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x; } else { src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step; video_step_delta = pp_inline_parameter.grf6.video_step_delta; @@ -1051,7 +1036,7 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int pp_inline_parameter.grf6.video_step_delta = b; if (x == 0) { - pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = 0.0; + pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x; pp_inline_parameter.grf5.normalized_video_x_scaling_step = a; } else { src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step; @@ -1087,17 +1072,17 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int } src_y_steping = pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step; - pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8; - pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16; - pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8; + pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_avs_context->src_normalized_y; + pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x; + pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8 + pp_avs_context->dest_y; return 0; } static void -pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth) +pp_nv12_avs_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_post_processing_context *pp_context = i965->pp_context; @@ -1107,37 +1092,23 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, struct i965_sampler_8x8 *sampler_8x8; struct i965_sampler_8x8_state *sampler_8x8_state; struct i965_surface_state2 *ss_8x8; - dri_bo *bo, *src_bo; + dri_bo *bo; int index; - int w, h; - int orig_w, orig_h; - int pp_out_w, pp_out_h; - int orig_pp_out_w, orig_pp_out_h; + int in_w, in_h, in_wpitch, in_hpitch; + int out_w, out_h, out_wpitch, out_hpitch; unsigned int tiling, swizzle; /* surface */ - obj_surface = SURFACE(surface); - - if (input == 1) { - orig_w = obj_surface->orig_pp_out_width; - orig_h = obj_surface->orig_pp_out_height; - w = obj_surface->pp_out_width; - h = obj_surface->pp_out_height; - src_bo = obj_surface->pp_out_bo; - } else { - orig_w = obj_surface->orig_width; - orig_h = obj_surface->orig_height; - w = obj_surface->width; - h = obj_surface->height; - src_bo = obj_surface->bo; - } - - assert(src_bo); - dri_bo_get_tiling(src_bo, &tiling, &swizzle); + obj_surface = SURFACE(in_surface_id); + in_w = obj_surface->orig_width; + in_h = obj_surface->orig_height; + in_wpitch = obj_surface->width; + in_hpitch = obj_surface->height; + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); /* source Y surface index 1 */ index = 1; - pp_context->surfaces[index].s_bo = src_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "Y surface state for sample_8x8", @@ -1151,10 +1122,10 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, memset(ss_8x8, 0, sizeof(*ss_8x8)); ss_8x8->ss0.surface_base_address = pp_context->surfaces[index].s_bo->offset; ss_8x8->ss1.cbcr_pixel_offset_v_direction = 0; - ss_8x8->ss1.width = orig_w - 1; - ss_8x8->ss1.height = orig_h - 1; + ss_8x8->ss1.width = in_w - 1; + ss_8x8->ss1.height = in_h - 1; ss_8x8->ss2.half_pitch_for_chroma = 0; - ss_8x8->ss2.pitch = w - 1; + ss_8x8->ss2.pitch = in_wpitch - 1; ss_8x8->ss2.interleave_chroma = 0; ss_8x8->ss2.surface_format = SURFACE_FORMAT_Y8_UNORM; ss_8x8->ss3.x_offset_for_cb = 0; @@ -1170,7 +1141,7 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, /* source UV surface index 2 */ index = 2; - pp_context->surfaces[index].s_bo = src_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "UV surface state for sample_8x8", @@ -1182,12 +1153,12 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, assert(bo->virtual); ss_8x8 = bo->virtual; memset(ss_8x8, 0, sizeof(*ss_8x8)); - ss_8x8->ss0.surface_base_address = pp_context->surfaces[index].s_bo->offset + w * h; + ss_8x8->ss0.surface_base_address = pp_context->surfaces[index].s_bo->offset + in_wpitch * in_hpitch; ss_8x8->ss1.cbcr_pixel_offset_v_direction = 0; - ss_8x8->ss1.width = orig_w - 1; - ss_8x8->ss1.height = orig_h - 1; + ss_8x8->ss1.width = in_w - 1; + ss_8x8->ss1.height = in_h - 1; ss_8x8->ss2.half_pitch_for_chroma = 0; - ss_8x8->ss2.pitch = w - 1; + ss_8x8->ss2.pitch = in_wpitch - 1; ss_8x8->ss2.interleave_chroma = 1; ss_8x8->ss2.surface_format = SURFACE_FORMAT_PLANAR_420_8; ss_8x8->ss3.x_offset_for_cb = 0; @@ -1196,29 +1167,23 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, 0, - w * h, + in_wpitch * in_hpitch, offsetof(struct i965_surface_state2, ss0), pp_context->surfaces[index].s_bo); dri_bo_unmap(bo); - orig_pp_out_w = destw; - orig_pp_out_h = desth; - pp_out_w = ALIGN(orig_pp_out_w, 16); - pp_out_h = ALIGN(orig_pp_out_h, 16); - dri_bo_unreference(obj_surface->pp_out_bo); - obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr, - "intermediate surface", - SIZE_YUV420(pp_out_w, pp_out_h), - 4096); - assert(obj_surface->pp_out_bo); - obj_surface->orig_pp_out_width = orig_pp_out_w; - obj_surface->orig_pp_out_height = orig_pp_out_h; - obj_surface->pp_out_width = pp_out_w; - obj_surface->pp_out_height = pp_out_h; + /* destination surface */ + obj_surface = SURFACE(out_surface_id); + out_w = obj_surface->orig_width; + out_h = obj_surface->orig_height; + out_wpitch = obj_surface->width; + out_hpitch = obj_surface->height; + assert(out_w <= out_wpitch && out_h <= out_hpitch); + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); /* destination Y surface index 7 */ index = 7; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -1233,9 +1198,10 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM; ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset; - ss->ss2.width = pp_out_w / 4 - 1; - ss->ss2.height = pp_out_h - 1; - ss->ss3.pitch = pp_out_w - 1; + ss->ss2.width = out_w / 4 - 1; + ss->ss2.height = out_h - 1; + ss->ss3.pitch = out_wpitch - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, @@ -1246,7 +1212,7 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, /* destination UV surface index 8 */ index = 8; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -1260,14 +1226,15 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, memset(ss, 0, sizeof(*ss)); ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM; - ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + pp_out_w * pp_out_h; - ss->ss2.width = pp_out_w / 4 - 1; - ss->ss2.height = pp_out_h / 2 - 1; - ss->ss3.pitch = pp_out_w - 1; + ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + out_wpitch * out_hpitch; + ss->ss2.width = out_w / 4 - 1; + ss->ss2.height = out_h / 2 - 1; + ss->ss3.pitch = out_wpitch - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - pp_out_w * pp_out_h, + out_wpitch * out_hpitch, offsetof(struct i965_surface_state, ss1), pp_context->surfaces[index].s_bo); dri_bo_unmap(bo); @@ -1436,16 +1403,21 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input, pp_context->pp_y_steps = pp_avs_y_steps; pp_context->pp_set_block_parameter = pp_avs_set_block_parameter; - pp_avs_context->dest_w = pp_out_w; - pp_avs_context->dest_h = pp_out_h; - pp_avs_context->src_w = w; - pp_avs_context->src_h = h; + pp_avs_context->dest_x = dst_rect->x; + pp_avs_context->dest_y = dst_rect->y; + pp_avs_context->dest_w = ALIGN(dst_rect->width, 16); + pp_avs_context->dest_h = ALIGN(dst_rect->height, 16); + pp_avs_context->src_normalized_x = (float)src_rect->x / in_w / out_w; + pp_avs_context->src_normalized_y = (float)src_rect->y / in_h / out_h; + pp_avs_context->src_w = src_rect->width; + pp_avs_context->src_h = src_rect->height; pp_static_parameter.grf4.r4_2.avs.nlas = 1; - pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) 1.0 / pp_out_h; - pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) 1.0 / pp_out_w; + pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / out_h; + + pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / out_w; pp_inline_parameter.grf5.block_count_x = 1; /* M x 1 */ - pp_inline_parameter.grf5.number_blocks = pp_out_h / 8; + pp_inline_parameter.grf5.number_blocks = pp_avs_context->dest_h / 8; pp_inline_parameter.grf5.block_vertical_mask = 0xff; pp_inline_parameter.grf5.block_horizontal_mask = 0xffff; pp_inline_parameter.grf6.video_step_delta = 0.0; @@ -1475,9 +1447,9 @@ pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int } static -void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth) +void pp_nv12_dndi_initialize(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_post_processing_context *pp_context = i965->pp_context; @@ -1493,11 +1465,12 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu unsigned int tiling, swizzle; /* surface */ - obj_surface = SURFACE(surface); + obj_surface = SURFACE(in_surface_id); orig_w = obj_surface->orig_width; orig_h = obj_surface->orig_height; w = obj_surface->width; h = obj_surface->height; + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); if (pp_context->stmm.bo == NULL) { pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr, @@ -1507,18 +1480,6 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu assert(pp_context->stmm.bo); } - dri_bo_unreference(obj_surface->pp_out_bo); - obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr, - "intermediate surface", - SIZE_YUV420(w, h), - 4096); - assert(obj_surface->pp_out_bo); - obj_surface->orig_pp_out_width = orig_w; - obj_surface->orig_pp_out_height = orig_h; - obj_surface->pp_out_width = w; - obj_surface->pp_out_height = h; - - dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); /* source UV surface index 2 */ index = 2; pp_context->surfaces[index].s_bo = obj_surface->bo; @@ -1612,9 +1573,17 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu pp_context->surfaces[index].s_bo); dri_bo_unmap(bo); + /* destination surface */ + obj_surface = SURFACE(out_surface_id); + orig_w = obj_surface->orig_width; + orig_h = obj_surface->orig_height; + w = obj_surface->width; + h = obj_surface->height; + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); + /* destination Y surface index 7 */ index = 7; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -1629,9 +1598,10 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM; ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset; - ss->ss2.width = w / 4 - 1; - ss->ss2.height = h - 1; + ss->ss2.width = orig_w / 4 - 1; + ss->ss2.height = orig_h - 1; ss->ss3.pitch = w - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, @@ -1642,7 +1612,7 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu /* destination UV surface index 8 */ index = 8; - pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo; + pp_context->surfaces[index].s_bo = obj_surface->bo; dri_bo_reference(pp_context->surfaces[index].s_bo); bo = dri_bo_alloc(i965->intel.bufmgr, "surface state", @@ -1657,9 +1627,10 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM; ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + w * h; - ss->ss2.width = w / 4 - 1; - ss->ss2.height = h / 2 - 1; + ss->ss2.width = orig_w / 4 - 1; + ss->ss2.height = orig_h / 2 - 1; ss->ss3.pitch = w - 1; + pp_set_surface_tiling(ss, tiling); dri_bo_emit_reloc(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, @@ -1750,8 +1721,8 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu static void ironlake_pp_initialize( VADriverContextP ctx, - VASurfaceID surface, - int input, + VASurfaceID in_surface_id, + VASurfaceID out_surface_id, const VARectangle *src_rect, const VARectangle *dst_rect, int pp_index @@ -1838,22 +1809,21 @@ ironlake_pp_initialize( pp_module = &pp_context->pp_modules[pp_index]; if (pp_module->initialize) - pp_module->initialize(ctx, surface, input, - src_rect->width, src_rect->height, - dst_rect->width, dst_rect->height); + pp_module->initialize(ctx, in_surface_id, out_surface_id, + src_rect, dst_rect); } static void ironlake_post_processing( VADriverContextP ctx, - VASurfaceID surface, - int input, + VASurfaceID in_surface_id, + VASurfaceID out_surface_id, const VARectangle *src_rect, const VARectangle *dst_rect, int pp_index ) { - ironlake_pp_initialize(ctx, surface, input, src_rect, dst_rect, pp_index); + ironlake_pp_initialize(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index); ironlake_pp_states_setup(ctx); ironlake_pp_pipeline_setup(ctx); } @@ -1861,8 +1831,8 @@ ironlake_post_processing( static void gen6_pp_initialize( VADriverContextP ctx, - VASurfaceID surface, - int input, + VASurfaceID in_surface_id, + VASurfaceID out_surface_id, const VARectangle *src_rect, const VARectangle *dst_rect, int pp_index @@ -1949,9 +1919,8 @@ gen6_pp_initialize( pp_module = &pp_context->pp_modules[pp_index]; if (pp_module->initialize) - pp_module->initialize(ctx, surface, input, - src_rect->width, src_rect->height, - dst_rect->width, dst_rect->height); + pp_module->initialize(ctx, in_surface_id, out_surface_id, + src_rect, dst_rect); } static void @@ -2197,14 +2166,14 @@ gen6_pp_pipeline_setup(VADriverContextP ctx) static void gen6_post_processing( VADriverContextP ctx, - VASurfaceID surface, - int input, + VASurfaceID in_surface_id, + VASurfaceID out_surface_id, const VARectangle *src_rect, const VARectangle *dst_rect, int pp_index ) { - gen6_pp_initialize(ctx, surface, input, src_rect, dst_rect, pp_index); + gen6_pp_initialize(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index); gen6_pp_states_setup(ctx); gen6_pp_pipeline_setup(ctx); } @@ -2212,8 +2181,8 @@ gen6_post_processing( static void i965_post_processing_internal( VADriverContextP ctx, - VASurfaceID surface, - int input, + VASurfaceID in_surface_id, + VASurfaceID out_surface_id, const VARectangle *src_rect, const VARectangle *dst_rect, int pp_index @@ -2223,42 +2192,89 @@ i965_post_processing_internal( if (IS_GEN6(i965->intel.device_id) || IS_GEN7(i965->intel.device_id)) - gen6_post_processing(ctx, surface, input, src_rect, dst_rect, pp_index); + gen6_post_processing(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index); else - ironlake_post_processing(ctx, surface, input, src_rect, dst_rect, - pp_index); + ironlake_post_processing(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index); } -void +VAStatus +i965_DestroySurfaces(VADriverContextP ctx, + VASurfaceID *surface_list, + int num_surfaces); +VAStatus +i965_CreateSurfaces(VADriverContextP ctx, + int width, + int height, + int format, + int num_surfaces, + VASurfaceID *surfaces); +VASurfaceID i965_post_processing( VADriverContextP ctx, VASurfaceID surface, const VARectangle *src_rect, const VARectangle *dst_rect, - unsigned int flags + unsigned int flags, + int *has_done_scaling ) { struct i965_driver_data *i965 = i965_driver_data(ctx); + VASurfaceID in_surface_id = surface; + VASurfaceID out_surface_id = VA_INVALID_ID; if (HAS_PP(i965)) { /* Currently only support post processing for NV12 surface */ if (i965->render_state.interleaved_uv) { - int internal_input = 0; + struct object_surface *obj_surface; + VAStatus status; if (flags & I965_PP_FLAG_DEINTERLACING) { - i965_post_processing_internal(ctx, surface, internal_input, + obj_surface = SURFACE(in_surface_id); + status = i965_CreateSurfaces(ctx, + obj_surface->orig_width, + obj_surface->orig_height, + VA_RT_FORMAT_YUV420, + 1, + &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_post_processing_internal(ctx, + in_surface_id, out_surface_id, src_rect, dst_rect, PP_NV12_DNDI); - internal_input = 1; } if (flags & I965_PP_FLAG_AVS) { - i965_post_processing_internal(ctx, surface, internal_input, + struct i965_render_state *render_state = &i965->render_state; + struct intel_region *dest_region = render_state->draw_region; + + if (out_surface_id != VA_INVALID_ID) + in_surface_id = out_surface_id; + + status = i965_CreateSurfaces(ctx, + dest_region->width, + dest_region->height, + VA_RT_FORMAT_YUV420, + 1, + &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_post_processing_internal(ctx, + in_surface_id, out_surface_id, src_rect, dst_rect, PP_NV12_AVS); + + if (in_surface_id != surface) + i965_DestroySurfaces(ctx, &in_surface_id, 1); + + *has_done_scaling = 1; } } } + + return out_surface_id; } Bool diff --git a/i965_post_processing.h b/i965_post_processing.h index 0982410..0981854 100644 --- a/i965_post_processing.h +++ b/i965_post_processing.h @@ -53,14 +53,22 @@ struct pp_load_save_context struct pp_scaling_context { + int dest_x; /* in pixel */ + int dest_y; /* in pixel */ int dest_w; int dest_h; + int src_normalized_x; + int src_normalized_y; }; struct pp_avs_context { + int dest_x; /* in pixel */ + int dest_y; /* in pixel */ int dest_w; int dest_h; + int src_normalized_x; + int src_normalized_y; int src_w; int src_h; }; @@ -69,7 +77,6 @@ struct pp_dndi_context { int dest_w; int dest_h; - }; struct pp_module @@ -77,9 +84,9 @@ struct pp_module struct i965_kernel kernel; /* others */ - void (*initialize)(VADriverContextP ctx, VASurfaceID surface, int input, - unsigned short srcw, unsigned short srch, - unsigned short destw, unsigned short desth); + void (*initialize)(VADriverContextP ctx, + VASurfaceID in_surface_id, VASurfaceID out_surface_id, + const VARectangle *src_rect, const VARectangle *dst_rect); }; struct pp_static_parameter @@ -350,13 +357,14 @@ struct i965_post_processing_context int (*pp_set_block_parameter)(struct i965_post_processing_context *pp_context, int x, int y); }; -void +VASurfaceID i965_post_processing( VADriverContextP ctx, VASurfaceID surface, const VARectangle *src_rect, const VARectangle *dst_rect, - unsigned int flags + unsigned int flags, + int *has_done_scaling ); Bool diff --git a/i965_render.c b/i965_render.c index e86464c..fee7109 100644 --- a/i965_render.c +++ b/i965_render.c @@ -757,7 +757,6 @@ i965_render_src_surfaces_state(VADriverContextP ctx, VASurfaceID surface) { struct i965_driver_data *i965 = i965_driver_data(ctx); - struct i965_render_state *render_state = &i965->render_state; struct object_surface *obj_surface; int w, h; int rw, rh; @@ -766,19 +765,11 @@ i965_render_src_surfaces_state(VADriverContextP ctx, obj_surface = SURFACE(surface); assert(obj_surface); - if (obj_surface->pp_out_bo) { - w = obj_surface->pp_out_width; - h = obj_surface->pp_out_height; - rw = obj_surface->orig_pp_out_width; - rh = obj_surface->orig_pp_out_height; - region = obj_surface->pp_out_bo; - } else { - w = obj_surface->width; - h = obj_surface->height; - rw = obj_surface->orig_width; - rh = obj_surface->orig_height; - region = obj_surface->bo; - } + w = obj_surface->width; + h = obj_surface->height; + 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); @@ -2901,7 +2892,10 @@ gen7_render_put_subpicture( /* * global functions */ - +VAStatus +i965_DestroySurfaces(VADriverContextP ctx, + VASurfaceID *surface_list, + int num_surfaces); void intel_render_put_surface( VADriverContextP ctx, @@ -2912,15 +2906,24 @@ intel_render_put_surface( ) { struct i965_driver_data *i965 = i965_driver_data(ctx); + int has_done_scaling = 0; + VASurfaceID in_surface_id = surface; + VASurfaceID out_surface_id = i965_post_processing(ctx, surface, src_rect, dst_rect, flags, &has_done_scaling); - i965_post_processing(ctx, surface, src_rect, dst_rect, flags); + assert((!has_done_scaling) || (out_surface_id != VA_INVALID_ID)); + + if (out_surface_id != VA_INVALID_ID) + in_surface_id = out_surface_id; if (IS_GEN7(i965->intel.device_id)) - gen7_render_put_surface(ctx, surface, src_rect, dst_rect, flags); + gen7_render_put_surface(ctx, in_surface_id, has_done_scaling ? dst_rect : src_rect, dst_rect, flags); else if (IS_GEN6(i965->intel.device_id)) - gen6_render_put_surface(ctx, surface, src_rect, dst_rect, flags); + gen6_render_put_surface(ctx, in_surface_id, has_done_scaling ? dst_rect : src_rect, dst_rect, flags); else - i965_render_put_surface(ctx, surface, src_rect, dst_rect, flags); + i965_render_put_surface(ctx, in_surface_id, has_done_scaling ? dst_rect : src_rect, dst_rect, flags); + + if (in_surface_id != surface) + i965_DestroySurfaces(ctx, &in_surface_id, 1); } void -- 2.11.0