vl: improve motion adaptive deinterlacer
authorChristian König <christian.koenig@amd.com>
Tue, 15 Dec 2015 20:21:50 +0000 (21:21 +0100)
committerChristian König <christian.koenig@amd.com>
Tue, 12 Jan 2016 12:28:39 +0000 (13:28 +0100)
Handle other formats than YV12 as well.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
src/gallium/auxiliary/vl/vl_deint_filter.c
src/gallium/auxiliary/vl/vl_deint_filter.h

index 8fa70e84c662ee7fcc6fd8ff1a0b26e95eaa7e6c..f919867cc021d16dbd9a5c13a3760ce348d105d5 100644 (file)
@@ -47,6 +47,7 @@
 #include "util/u_draw.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "util/u_format.h"
 
 #include "vl_types.h"
 #include "vl_video_buffer.h"
@@ -214,8 +215,9 @@ create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field,
             ureg_imm4f(shader, -0.02353f, 0, 0, 0));
    ureg_MUL(shader, ureg_saturate(ureg_writemask(t_diff, TGSI_WRITEMASK_X)),
             ureg_src(t_diff), ureg_imm4f(shader, 31.8750f, 0, 0, 0));
-   ureg_LRP(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_X), ureg_src(t_diff),
+   ureg_LRP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X), ureg_src(t_diff),
             ureg_src(t_linear), ureg_src(t_weave));
+   ureg_MOV(shader, o_fragment, ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X));
 
    ureg_release_temporary(shader, t_tex);
    ureg_release_temporary(shader, t_comp_top);
@@ -271,10 +273,20 @@ vl_deint_filter_init(struct vl_deint_filter *filter, struct pipe_context *pipe,
       goto error_rs_state;
 
    memset(&blend, 0, sizeof blend);
-   blend.rt[0].colormask = PIPE_MASK_RGBA;
-   filter->blend = pipe->create_blend_state(pipe, &blend);
-   if (!filter->blend)
-      goto error_blend;
+   blend.rt[0].colormask = PIPE_MASK_R;
+   filter->blend[0] = pipe->create_blend_state(pipe, &blend);
+   if (!filter->blend[0])
+      goto error_blendR;
+
+   blend.rt[0].colormask = PIPE_MASK_G;
+   filter->blend[1] = pipe->create_blend_state(pipe, &blend);
+   if (!filter->blend[1])
+      goto error_blendG;
+
+   blend.rt[0].colormask = PIPE_MASK_B;
+   filter->blend[2] = pipe->create_blend_state(pipe, &blend);
+   if (!filter->blend[2])
+      goto error_blendB;
 
    memset(&sampler, 0, sizeof(sampler));
    sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -349,9 +361,15 @@ error_quad:
    pipe->delete_sampler_state(pipe, filter->sampler);
 
 error_sampler:
-   pipe->delete_blend_state(pipe, filter->blend);
+   pipe->delete_blend_state(pipe, filter->blend[2]);
+
+error_blendB:
+   pipe->delete_blend_state(pipe, filter->blend[1]);
+
+error_blendG:
+   pipe->delete_blend_state(pipe, filter->blend[0]);
 
-error_blend:
+error_blendR:
    pipe->delete_rasterizer_state(pipe, filter->rs_state);
 
 error_rs_state:
@@ -367,7 +385,9 @@ vl_deint_filter_cleanup(struct vl_deint_filter *filter)
    assert(filter);
 
    filter->pipe->delete_sampler_state(filter->pipe, filter->sampler[0]);
-   filter->pipe->delete_blend_state(filter->pipe, filter->blend);
+   filter->pipe->delete_blend_state(filter->pipe, filter->blend[0]);
+   filter->pipe->delete_blend_state(filter->pipe, filter->blend[1]);
+   filter->pipe->delete_blend_state(filter->pipe, filter->blend[2]);
    filter->pipe->delete_rasterizer_state(filter->pipe, filter->rs_state);
    filter->pipe->delete_vertex_elements_state(filter->pipe, filter->ves);
    pipe_resource_reference(&filter->quad.buffer, NULL);
@@ -420,12 +440,14 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
    struct pipe_sampler_view **next_sv;
    struct pipe_sampler_view *sampler_views[4];
    struct pipe_surface **dst_surfaces;
-   int j;
+   const unsigned *plane_order;
+   int i, j;
 
    assert(filter && prevprev && prev && cur && next && field <= 1);
 
    /* set up destination and source */
    dst_surfaces = filter->video_buffer->get_surfaces(filter->video_buffer);
+   plane_order = vl_video_buffer_plane_order(filter->video_buffer->buffer_format);
    cur_sv = cur->get_sampler_view_components(cur);
    prevprev_sv = prevprev->get_sampler_view_components(prevprev);
    prev_sv = prev->get_sampler_view_components(prev);
@@ -433,7 +455,6 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
 
    /* set up pipe state */
    filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state);
-   filter->pipe->bind_blend_state(filter->pipe, filter->blend);
    filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
    filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
    filter->pipe->bind_vs_state(filter->pipe, filter->vs);
@@ -449,12 +470,13 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
    fb_state.nr_cbufs = 1;
 
    /* process each plane separately */
-   for (j = 0; j < 3; j++) {
-      /* select correct YV12 surfaces */
-      int k = j == 1 ? 2 :
-              j == 2 ? 1 : 0;
-      struct pipe_surface *blit_surf = dst_surfaces[2 * k + field];
-      struct pipe_surface *dst_surf = dst_surfaces[2 * k + 1 - field];
+   for (i = 0, j = 0; i < VL_NUM_COMPONENTS; ++i) {
+      struct pipe_surface *blit_surf = dst_surfaces[field];
+      struct pipe_surface *dst_surf = dst_surfaces[1 - field];
+      int k = plane_order[i];
+
+      /* bind blend state for this component in the plane */
+      filter->pipe->bind_blend_state(filter->pipe, filter->blend[j]);
 
       /* update render target state */
       viewport.scale[0] = blit_surf->texture->width0;
@@ -463,10 +485,10 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
       fb_state.height = blit_surf->texture->height0;
 
       /* update sampler view sources  */
-      sampler_views[0] = prevprev_sv[j];
-      sampler_views[1] = prev_sv[j];
-      sampler_views[2] = cur_sv[j];
-      sampler_views[3] = next_sv[j];
+      sampler_views[0] = prevprev_sv[k];
+      sampler_views[1] = prev_sv[k];
+      sampler_views[2] = cur_sv[k];
+      sampler_views[3] = next_sv[k];
       filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT, 0, 4, sampler_views);
 
       /* blit current field */
@@ -479,11 +501,16 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
       /* blit or interpolate other field */
       fb_state.cbufs[0] = dst_surf;
       filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
-      if (j > 0 && filter->skip_chroma) {
+      if (i > 0 && filter->skip_chroma) {
          util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
       } else {
          filter->pipe->bind_fs_state(filter->pipe, field ? filter->fs_deint_top : filter->fs_deint_bottom);
          util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
       }
+
+      if (++j >= util_format_get_nr_components(dst_surf->format)) {
+         dst_surfaces += 2;
+         j = 0;
+      }
    }
 }
index 3ca378b183d8ca3ca90a5b863380c72c20bc1c65..49cc96c20b9657ec3b5d623f2e0711ecfc6179fb 100644 (file)
@@ -38,7 +38,7 @@ struct vl_deint_filter
    struct pipe_vertex_buffer quad;
 
    void *rs_state;
-   void *blend;
+   void *blend[3];
    void *sampler[4];
    void *ves;
    void *vs;