MPEG-2 and later video standards align the chroma sample position horizontally with the leftmost luma sample position. Add a half-texel offset to the chroma texture sampling coordinate to sample at the this position instead of sampling in the center between the luma texels. This avoids minor color smearing and blurriness with most video content. --- src/gallium/auxiliary/vl/vl_compositor.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 4b83087..dac2c61 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -129,6 +129,7 @@ create_frag_shader_video_buffer(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src tc; + struct ureg_dst tc_chroma; struct ureg_src csc[3]; struct ureg_src sampler[3]; struct ureg_dst texel; @@ -146,13 +147,18 @@ create_frag_shader_video_buffer(struct vl_compositor *c) } texel = ureg_DECL_temporary(shader); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); + tc_chroma = ureg_DECL_temporary(shader); + + /* chroma offset */ + ureg_MOV(shader, ureg_writemask(tc_chroma, TGSI_WRITEMASK_XYZW), tc); + ureg_ADD(shader, ureg_writemask(tc_chroma, TGSI_WRITEMASK_X), ureg_src(tc_chroma), ureg_scalar(tc, TGSI_SWIZZLE_Z)); /* * texel.xyz = tex(tc, sampler[i]) * fragment = csc * texel */ for (i = 0; i < 3; ++i) - ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D_ARRAY, tc, sampler[i]); + ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D_ARRAY, i ? ureg_src(tc_chroma) : tc, sampler[i]); ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); @@ -171,10 +177,12 @@ static void * create_frag_shader_weave(struct vl_compositor *c) { struct ureg_program *shader; + struct ureg_src tc; struct ureg_src i_tc[2]; struct ureg_src csc[3]; struct ureg_src sampler[3]; struct ureg_dst t_tc[2]; + struct ureg_dst t_tc_chroma[2]; struct ureg_dst t_texel[2]; struct ureg_dst o_fragment; unsigned i, j; @@ -183,6 +191,7 @@ create_frag_shader_weave(struct vl_compositor *c) if (!shader) return false; + tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); i_tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); i_tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); @@ -194,6 +203,7 @@ create_frag_shader_weave(struct vl_compositor *c) for (i = 0; i < 2; ++i) { t_tc[i] = ureg_DECL_temporary(shader); t_texel[i] = ureg_DECL_temporary(shader); + t_tc_chroma[i] = ureg_DECL_temporary(shader); } o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); @@ -214,6 +224,8 @@ create_frag_shader_weave(struct vl_compositor *c) ureg_src(t_tc[i]), ureg_scalar(i_tc[0], TGSI_SWIZZLE_W)); ureg_MUL(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_Z), ureg_src(t_tc[i]), ureg_scalar(i_tc[1], TGSI_SWIZZLE_W)); + ureg_MOV(shader, ureg_writemask(t_tc_chroma[i], TGSI_WRITEMASK_XYZW), ureg_src(t_tc[i])); + ureg_ADD(shader, ureg_writemask(t_tc_chroma[i], TGSI_WRITEMASK_X), ureg_src(t_tc_chroma[i]), ureg_scalar(tc, TGSI_SWIZZLE_Z)); } /* fetch the texels @@ -223,7 +235,7 @@ create_frag_shader_weave(struct vl_compositor *c) */ for (i = 0; i < 2; ++i) for (j = 0; j < 3; ++j) { - struct ureg_src src = ureg_swizzle(ureg_src(t_tc[i]), + struct ureg_src src = ureg_swizzle(j ? ureg_src(t_tc_chroma[i]) : ureg_src(t_tc[i]), TGSI_SWIZZLE_X, j ? TGSI_SWIZZLE_Z : TGSI_SWIZZLE_Y, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W); ureg_TEX(shader, ureg_writemask(t_texel[i], TGSI_WRITEMASK_X << j), @@ -586,7 +598,7 @@ calc_src_and_dst(struct vl_compositor_layer *layer, unsigned width, unsigned hei layer->src.br = calc_bottomright(size, src); layer->dst.tl = calc_topleft(size, dst); layer->dst.br = calc_bottomright(size, dst); - layer->zw.x = 0.0f; + layer->zw.x = 0.5f / size.x; /* half a texel */ layer->zw.y = size.y; } -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev