From ae0aff6dfaa0446e6ba0636868576f7f596aa7fd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Mar 2012 15:30:13 +0100 Subject: [PATCH] render: fix rendering of interlaced surfaces. Handle bob-deinterlacing flags passed to vaPutSurface(). i.e. VA_TOP_FIELD|VA_BOTTOM_FIELD. Avoid advanced deinterlacing kernels as they allocate extra temporary surfaces, which are useless for such simple tasks. i.e. display either field of an interlaced surface. Signed-off-by: Gwenole Beauchesne --- src/i965_drv_video.c | 4 +- src/i965_post_processing.c | 4 +- src/i965_post_processing.h | 9 ++-- src/i965_render.c | 123 +++++++++++++++++++++++++++++++-------------- 4 files changed, 92 insertions(+), 48 deletions(-) diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index 55f5e38..c7892cd 100644 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -3092,9 +3092,9 @@ i965_PutSurface(VADriverContextP ctx, pp_flag |= I965_PP_FLAG_AVS; if (flags & VA_TOP_FIELD) - pp_flag |= I965_PP_FLAG_DEINTERLACING_TOP_FISRT; + pp_flag |= I965_PP_FLAG_TOP_FIELD; else if (flags & VA_BOTTOM_FIELD) - pp_flag |= I965_PP_FLAG_DEINTERLACING_BOTTOM_FIRST; + pp_flag |= I965_PP_FLAG_BOTTOM_FIELD; src_rect.x = srcx; src_rect.y = srcy; diff --git a/src/i965_post_processing.c b/src/i965_post_processing.c index 8cb2b39..f72fd90 100644 --- a/src/i965_post_processing.c +++ b/src/i965_post_processing.c @@ -3592,7 +3592,7 @@ i965_post_processing( _i965LockMutex(&i965->pp_mutex); - if (flags & I965_PP_FLAG_DEINTERLACING) { + if (flags & I965_PP_FLAG_MCDI) { status = i965_CreateSurfaces(ctx, obj_surface->orig_width, obj_surface->orig_height, @@ -3605,7 +3605,7 @@ i965_post_processing( i965_vpp_clear_surface(ctx, i965->pp_context, out_surface_id, 0); src_surface.id = in_surface_id; src_surface.type = I965_SURFACE_TYPE_SURFACE; - src_surface.flags = (flags & I965_PP_FLAG_DEINTERLACING_TOP_FISRT) ? + src_surface.flags = (flags & I965_PP_FLAG_TOP_FIELD) ? I965_SURFACE_FLAG_TOP_FIELD_FIRST : I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST; dst_surface.id = out_surface_id; dst_surface.type = I965_SURFACE_TYPE_SURFACE; diff --git a/src/i965_post_processing.h b/src/i965_post_processing.h index 19ddb40..1a83e65 100644 --- a/src/i965_post_processing.h +++ b/src/i965_post_processing.h @@ -31,11 +31,10 @@ #define MAX_PP_SURFACES 48 -#define I965_PP_FLAG_DEINTERLACING_TOP_FISRT 1 -#define I965_PP_FLAG_DEINTERLACING_BOTTOM_FIRST 2 -#define I965_PP_FLAG_AVS 4 - -#define I965_PP_FLAG_DEINTERLACING (I965_PP_FLAG_DEINTERLACING_TOP_FISRT | I965_PP_FLAG_DEINTERLACING_BOTTOM_FIRST) +#define I965_PP_FLAG_TOP_FIELD 1 +#define I965_PP_FLAG_BOTTOM_FIELD 2 +#define I965_PP_FLAG_MCDI 4 +#define I965_PP_FLAG_AVS 8 enum { diff --git a/src/i965_render.c b/src/i965_render.c index 626b1e6..7db0946 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -637,15 +637,32 @@ i965_render_set_surface_tiling(struct i965_surface_state *ss, unsigned int tilin } static void -i965_render_set_surface_state(struct i965_surface_state *ss, - dri_bo *bo, unsigned long offset, - int width, int height, - int pitch, int format) +i965_render_set_surface_state( + struct i965_surface_state *ss, + dri_bo *bo, + unsigned long offset, + unsigned int width, + unsigned int height, + unsigned int pitch, + unsigned int format, + unsigned int flags +) { unsigned int tiling; unsigned int swizzle; memset(ss, 0, sizeof(*ss)); + + switch (flags & (I965_PP_FLAG_TOP_FIELD|I965_PP_FLAG_BOTTOM_FIELD)) { + case I965_PP_FLAG_BOTTOM_FIELD: + ss->ss0.vert_line_stride_ofs = 1; + /* fall-through */ + case I965_PP_FLAG_TOP_FIELD: + ss->ss0.vert_line_stride = 1; + height /= 2; + break; + } + ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = format; ss->ss0.color_blend = 1; @@ -681,16 +698,32 @@ gen7_render_set_surface_tiling(struct gen7_surface_state *ss, uint32_t tiling) } static void -gen7_render_set_surface_state(struct gen7_surface_state *ss, - dri_bo *bo, unsigned long offset, - int width, int height, - int pitch, int format) +gen7_render_set_surface_state( + struct gen7_surface_state *ss, + dri_bo *bo, + unsigned long offset, + int width, + int height, + int pitch, + int format, + unsigned int flags +) { unsigned int tiling; unsigned int swizzle; memset(ss, 0, sizeof(*ss)); + switch (flags & (I965_PP_FLAG_TOP_FIELD|I965_PP_FLAG_BOTTOM_FIELD)) { + case I965_PP_FLAG_BOTTOM_FIELD: + ss->ss0.vert_line_stride_ofs = 1; + /* fall-through */ + case I965_PP_FLAG_TOP_FIELD: + ss->ss0.vert_line_stride = 1; + height /= 2; + break; + } + ss->ss0.surface_type = I965_SURFACE_2D; ss->ss0.surface_format = format; @@ -706,12 +739,17 @@ gen7_render_set_surface_state(struct gen7_surface_state *ss, } static void -i965_render_src_surface_state(VADriverContextP ctx, - int index, - dri_bo *region, - unsigned long offset, - int w, int h, - int pitch, int format) +i965_render_src_surface_state( + VADriverContextP ctx, + int index, + dri_bo *region, + unsigned long offset, + int w, + int h, + int pitch, + int format, + unsigned int flags +) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_render_state *render_state = &i965->render_state; @@ -728,7 +766,7 @@ i965_render_src_surface_state(VADriverContextP ctx, gen7_render_set_surface_state(ss, region, offset, w, h, - pitch, format); + pitch, format, flags); dri_bo_emit_reloc(ss_bo, I915_GEM_DOMAIN_SAMPLER, 0, offset, @@ -738,7 +776,7 @@ i965_render_src_surface_state(VADriverContextP ctx, i965_render_set_surface_state(ss, region, offset, w, h, - pitch, format); + pitch, format, flags); dri_bo_emit_reloc(ss_bo, I915_GEM_DOMAIN_SAMPLER, 0, offset, @@ -752,8 +790,11 @@ i965_render_src_surface_state(VADriverContextP ctx, } static void -i965_render_src_surfaces_state(VADriverContextP ctx, - VASurfaceID surface) +i965_render_src_surfaces_state( + VADriverContextP ctx, + VASurfaceID surface, + unsigned int flags +) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct object_surface *obj_surface; @@ -769,35 +810,35 @@ i965_render_src_surfaces_state(VADriverContextP ctx, rh = obj_surface->orig_height; region = obj_surface->bo; - 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); + i965_render_src_surface_state(ctx, 1, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM, flags); /* Y */ + i965_render_src_surface_state(ctx, 2, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM, flags); 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_SURFACEFORMAT_R8G8_UNORM, flags); /* 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); + I965_SURFACEFORMAT_R8G8_UNORM, flags); } else { 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_SURFACEFORMAT_R8_UNORM, flags); /* 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_SURFACEFORMAT_R8_UNORM, flags); 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_SURFACEFORMAT_R8_UNORM, flags); /* 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); + I965_SURFACEFORMAT_R8_UNORM, flags); } } @@ -814,8 +855,8 @@ i965_subpic_render_src_surfaces_state(VADriverContextP ctx, assert(obj_surface->bo); subpic_region = obj_image->bo; /*subpicture surface*/ - i965_render_src_surface_state(ctx, 1, subpic_region, 0, obj_subpic->width, obj_subpic->height, obj_subpic->pitch, obj_subpic->format); - i965_render_src_surface_state(ctx, 2, subpic_region, 0, obj_subpic->width, obj_subpic->height, obj_subpic->pitch, obj_subpic->format); + i965_render_src_surface_state(ctx, 1, subpic_region, 0, obj_subpic->width, obj_subpic->height, obj_subpic->pitch, obj_subpic->format, 0); + i965_render_src_surface_state(ctx, 2, subpic_region, 0, obj_subpic->width, obj_subpic->height, obj_subpic->pitch, obj_subpic->format, 0); } static void @@ -843,7 +884,7 @@ i965_render_dest_surface_state(VADriverContextP ctx, int index) gen7_render_set_surface_state(ss, dest_region->bo, 0, dest_region->width, dest_region->height, - dest_region->pitch, format); + dest_region->pitch, format, 0); dri_bo_emit_reloc(ss_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0, @@ -853,7 +894,7 @@ i965_render_dest_surface_state(VADriverContextP ctx, int index) i965_render_set_surface_state(ss, dest_region->bo, 0, dest_region->width, dest_region->height, - dest_region->pitch, format); + dest_region->pitch, format, 0); dri_bo_emit_reloc(ss_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0, @@ -1006,13 +1047,14 @@ i965_surface_render_state_setup( VADriverContextP ctx, VASurfaceID surface, const VARectangle *src_rect, - const VARectangle *dst_rect + const VARectangle *dst_rect, + unsigned int flags ) { i965_render_vs_unit(ctx); i965_render_sf_unit(ctx); i965_render_dest_surface_state(ctx, 0); - i965_render_src_surfaces_state(ctx, surface); + i965_render_src_surfaces_state(ctx, surface, flags); i965_render_sampler(ctx); i965_render_wm_unit(ctx); i965_render_cc_viewport(ctx); @@ -1020,6 +1062,7 @@ i965_surface_render_state_setup( i965_render_upload_vertex(ctx, surface, src_rect, dst_rect); i965_render_upload_constants(ctx, surface); } + static void i965_subpic_render_state_setup( VADriverContextP ctx, @@ -1536,7 +1579,7 @@ i965_render_put_surface( struct intel_batchbuffer *batch = i965->batch; i965_render_initialize(ctx); - i965_surface_render_state_setup(ctx, surface, src_rect, dst_rect); + i965_surface_render_state_setup(ctx, surface, src_rect, dst_rect, flags); i965_surface_render_pipeline_setup(ctx); intel_batchbuffer_flush(batch); } @@ -1690,11 +1733,12 @@ gen6_render_setup_states( VADriverContextP ctx, VASurfaceID surface, const VARectangle *src_rect, - const VARectangle *dst_rect + const VARectangle *dst_rect, + unsigned int flags ) { i965_render_dest_surface_state(ctx, 0); - i965_render_src_surfaces_state(ctx, surface); + i965_render_src_surfaces_state(ctx, surface, flags); i965_render_sampler(ctx); i965_render_cc_viewport(ctx); gen6_render_color_calc_state(ctx); @@ -2060,7 +2104,7 @@ gen6_render_put_surface( struct intel_batchbuffer *batch = i965->batch; gen6_render_initialize(ctx); - gen6_render_setup_states(ctx, surface, src_rect, dst_rect); + gen6_render_setup_states(ctx, surface, src_rect, dst_rect, flags); i965_clear_dest_region(ctx); gen6_render_emit_states(ctx, PS_KERNEL); intel_batchbuffer_flush(batch); @@ -2282,11 +2326,12 @@ gen7_render_setup_states( VADriverContextP ctx, VASurfaceID surface, const VARectangle *src_rect, - const VARectangle *dst_rect + const VARectangle *dst_rect, + unsigned int flags ) { i965_render_dest_surface_state(ctx, 0); - i965_render_src_surfaces_state(ctx, surface); + i965_render_src_surfaces_state(ctx, surface, flags); gen7_render_sampler(ctx); i965_render_cc_viewport(ctx); gen7_render_color_calc_state(ctx); @@ -2825,7 +2870,7 @@ gen7_render_put_surface( struct intel_batchbuffer *batch = i965->batch; gen7_render_initialize(ctx); - gen7_render_setup_states(ctx, surface, src_rect, dst_rect); + gen7_render_setup_states(ctx, surface, src_rect, dst_rect, flags); i965_clear_dest_region(ctx); gen7_render_emit_states(ctx, PS_KERNEL); intel_batchbuffer_flush(batch); -- 2.7.4