[Libva] [PATCH] render: fix rendering of interlaced surfaces.

Gwenole Beauchesne gb.devel at gmail.com
Mon Mar 12 09:33:07 PDT 2012


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 at intel.com>
---
 NEWS                       |    1 +
 src/i965_drv_video.c       |    6 ++-
 src/i965_post_processing.h |    6 ++-
 src/i965_render.c          |  125 ++++++++++++++++++++++++++++++--------------
 4 files changed, 95 insertions(+), 43 deletions(-)

diff --git a/NEWS b/NEWS
index 1b4809a..2fc1bd8 100644
--- 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 MFX_QM_STATE for H.264 flat scaling lists (IVB)
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 443b597..c332774 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -2512,8 +2512,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;
diff --git a/src/i965_post_processing.h b/src/i965_post_processing.h
index 0981854..5f4e949 100644
--- a/src/i965_post_processing.h
+++ b/src/i965_post_processing.h
@@ -31,8 +31,10 @@
 
 #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
 {
diff --git a/src/i965_render.c b/src/i965_render.c
index fada70b..d649a3d 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -637,15 +637,33 @@ 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));
+
+    flags &= I965_PP_FLAG_TOP_FIELD|I965_PP_FLAG_BOTTOM_FIELD;
+    switch (flags) {
+    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 +699,33 @@ 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));
 
+    flags &= I965_PP_FLAG_TOP_FIELD|I965_PP_FLAG_BOTTOM_FIELD;
+    switch (flags) {
+    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 +741,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 +768,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 +778,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 +792,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 +812,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 +862,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 +891,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 +901,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 +1054,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 +1069,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 +1586,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 +1740,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 +2111,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 +2333,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 +2877,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);
-- 
1.7.5.4



More information about the Libva mailing list