[Mesa-dev] [PATCH 2/2] st/vl: use MPEG-2 chroma cositing

Grigori Goronzy greg at chown.ath.cx
Tue Oct 1 12:06:20 PDT 2013


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



More information about the mesa-dev mailing list