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

Christian König deathsimple at vodafone.de
Mon Oct 7 02:47:31 PDT 2013


Am 01.10.2013 21:06, schrieb Grigori Goronzy:
> 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.

Overall looks good to me, but one minor thing below that needs to be 
fixed first.

> ---
>   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;

That only works in the case of the weave and progressive shaders, cause 
I already used (abused) zw.x to selected between top/bottom bobbing in 
vl_compositor_set_buffer_layer.

Do me a favor and clean that up by renaming "zw" to "size" and adding an 
extra attribute to select between top/bottom bobbing.

Cheers,
Christian.

>   }
>   



More information about the mesa-dev mailing list