render: fix rendering of interlaced surfaces.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 12 Mar 2012 14:30:13 +0000 (15:30 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 14 Mar 2012 15:58:28 +0000 (16:58 +0100)
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 <gwenole.beauchesne@intel.com>
NEWS
src/i965_drv_video.c
src/i965_post_processing.h
src/i965_render.c

diff --git a/NEWS b/NEWS
index 7cefa20..8e84640 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ libva-driver-intel NEWS -- summary of changes.  2012-02-DD
 Copyright (C) 2009-2011 Intel Corporation
 
 Version 1.0.16 - DD.Feb.2012
+* Fix rendering of interlaced surfaces
 * Fix VC-1 bitplane buffer size (SNB, IVB)
 * Fix VC-1 motion vector modes for Ivy Bridge
 * Fix weighted prediction indicator for Sandy Bridge
index 9dc66f0..ffed364 100644 (file)
@@ -2327,8 +2327,10 @@ i965_PutSurface(VADriverContextP ctx,
     if ((flags & VA_FILTER_SCALING_MASK) == VA_FILTER_SCALING_NL_ANAMORPHIC)
         pp_flag |= I965_PP_FLAG_AVS;
 
-    if (flags & (VA_BOTTOM_FIELD | VA_TOP_FIELD))
-        pp_flag |= I965_PP_FLAG_DEINTERLACING;
+    if (flags & VA_TOP_FIELD)
+        pp_flag |= I965_PP_FLAG_TOP_FIELD;
+    else if (flags & VA_BOTTOM_FIELD)
+        pp_flag |= I965_PP_FLAG_BOTTOM_FIELD;
 
     src_rect.x      = srcx;
     src_rect.y      = srcy;
index 0981854..5f4e949 100644 (file)
 
 #define MAX_PP_SURFACES 32
 
-#define I965_PP_FLAG_DEINTERLACING      1
-#define I965_PP_FLAG_AVS                2
+#define I965_PP_FLAG_TOP_FIELD          1
+#define I965_PP_FLAG_BOTTOM_FIELD       2
+#define I965_PP_FLAG_DEINTERLACING      4 /* XXX: don't support MCDI yet */
+#define I965_PP_FLAG_AVS                8
 
 enum
 {
index fada70b..f6b6dde 100644 (file)
@@ -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);
     }
 }
 
@@ -819,8 +860,8 @@ i965_subpic_render_src_surfaces_state(VADriverContextP ctx,
     region = 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
@@ -848,7 +889,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,
@@ -858,7 +899,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,
@@ -1011,13 +1052,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);
@@ -1025,6 +1067,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,
@@ -1541,7 +1584,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);
 }
@@ -1695,11 +1738,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);
@@ -2065,7 +2109,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);
@@ -2287,11 +2331,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);
@@ -2830,7 +2875,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);