summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <[email protected]>2015-12-15 21:21:50 +0100
committerChristian König <[email protected]>2016-01-12 13:28:39 +0100
commit5fdd4a5aef122a8aa1da91ac0555a817af0d1b06 (patch)
treefca17229e540c9b38cc9f918a328051f6a96801d
parente945235aed86f473f27362bae902fbe67d5f0f20 (diff)
vl: improve motion adaptive deinterlacer
Handle other formats than YV12 as well. Signed-off-by: Christian König <[email protected]> Reviewed-by: Emil Velikov <[email protected]>
-rw-r--r--src/gallium/auxiliary/vl/vl_deint_filter.c69
-rw-r--r--src/gallium/auxiliary/vl/vl_deint_filter.h2
2 files changed, 49 insertions, 22 deletions
diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.c b/src/gallium/auxiliary/vl/vl_deint_filter.c
index 8fa70e84c66..f919867cc02 100644
--- a/src/gallium/auxiliary/vl/vl_deint_filter.c
+++ b/src/gallium/auxiliary/vl/vl_deint_filter.c
@@ -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;
+ }
}
}
diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.h b/src/gallium/auxiliary/vl/vl_deint_filter.h
index 3ca378b183d..49cc96c20b9 100644
--- a/src/gallium/auxiliary/vl/vl_deint_filter.h
+++ b/src/gallium/auxiliary/vl/vl_deint_filter.h
@@ -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;