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, 4 Apr 2012 11:39:32 +0000 (13:39 +0200)
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>
src/i965_drv_video.c
src/i965_post_processing.c
src/i965_post_processing.h
src/i965_render.c

index 55f5e38..c7892cd 100644 (file)
@@ -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;
index 8cb2b39..f72fd90 100644 (file)
@@ -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;
index 19ddb40..1a83e65 100644 (file)
 
 #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
 {
index 626b1e6..7db0946 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);
     }
 }
 
@@ -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);