[Mesa-dev] [PATCH 2/2] u_blit, u_simple_shaders: add shader to convert from xrbias format

Jose Fonseca jfonseca at vmware.com
Wed Feb 7 10:25:25 UTC 2018


On 07/02/18 04:20, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
> 
> We need this to handle some oddball dx10 format
> (DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM). What you can do with this
> format is very limited, hence we don't want to add it as a gallium
> format (we could not express the properties of this format as
> ordinary format properties neither, so like all special formats
> it would need specific code for handling it in any case).
> While here, also nuke the array for different shaders for different
> writemasks, as it was not actually used (always full masks are
> passed in for generating shaders).
> ---
>   src/gallium/auxiliary/util/u_blit.c           | 40 +++++++++++++---------
>   src/gallium/auxiliary/util/u_blit.h           |  3 +-
>   src/gallium/auxiliary/util/u_simple_shaders.c | 48 +++++++++++++++++++++++++++
>   src/gallium/auxiliary/util/u_simple_shaders.h |  4 +++
>   4 files changed, 79 insertions(+), 16 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
> index 3f92476..bf1dea7 100644
> --- a/src/gallium/auxiliary/util/u_blit.c
> +++ b/src/gallium/auxiliary/util/u_blit.c
> @@ -65,7 +65,7 @@ struct blit_state
>      struct pipe_vertex_element velem[2];
>   
>      void *vs;
> -   void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1][3];
> +   void *fs[PIPE_MAX_TEXTURE_TYPES][4];
>   
>      struct pipe_resource *vbuf;  /**< quad vertices */
>      unsigned vbuf_slot;
> @@ -135,17 +135,15 @@ void
>   util_destroy_blit(struct blit_state *ctx)
>   {
>      struct pipe_context *pipe = ctx->pipe;
> -   unsigned i, j, k;
> +   unsigned i, j;
>   
>      if (ctx->vs)
>         pipe->delete_vs_state(pipe, ctx->vs);
>   
>      for (i = 0; i < ARRAY_SIZE(ctx->fs); i++) {
>         for (j = 0; j < ARRAY_SIZE(ctx->fs[i]); j++) {
> -         for (k = 0; k < ARRAY_SIZE(ctx->fs[i][j]); k++) {
> -            if (ctx->fs[i][j][k])
> -               pipe->delete_fs_state(pipe, ctx->fs[i][j][k]);
> -         }
> +         if (ctx->fs[i][j])
> +            pipe->delete_fs_state(pipe, ctx->fs[i][j]);
>         }
>      }
>   
> @@ -159,8 +157,9 @@ util_destroy_blit(struct blit_state *ctx)
>    * Helper function to set the fragment shaders.
>    */
>   static inline void
> -set_fragment_shader(struct blit_state *ctx, uint writemask,
> +set_fragment_shader(struct blit_state *ctx,
>                       enum pipe_format format,
> +                    boolean src_xrbias,
>                       enum pipe_texture_target pipe_tex)
>   {
>      enum tgsi_return_type stype;
> @@ -177,19 +176,29 @@ set_fragment_shader(struct blit_state *ctx, uint writemask,
>         idx = 2;
>      }
>   
> -   if (!ctx->fs[pipe_tex][writemask][idx]) {
> +   if (src_xrbias) {
> +      assert(stype == TGSI_RETURN_TYPE_FLOAT);
> +      idx = 3;
> +      if (!ctx->fs[pipe_tex][idx]) {
> +         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
> +         ctx->fs[pipe_tex][idx] =
> +            util_make_fragment_tex_shader_xrbias(ctx->pipe, tgsi_tex);
> +      }
> +   }
> +
> +   else if (!ctx->fs[pipe_tex][idx]) {
>         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
>   
>         /* OpenGL does not allow blits from signed to unsigned integer
>          * or vice versa. */
> -      ctx->fs[pipe_tex][writemask][idx] =
> +      ctx->fs[pipe_tex][idx] =
>            util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex,
>                                                    TGSI_INTERPOLATE_LINEAR,
> -                                                 writemask,
> +                                                 TGSI_WRITEMASK_XYZW,
>                                                    stype, stype, false, false);
>      }
>   
> -   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask][idx]);
> +   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][idx]);
>   }
>   
>   
> @@ -491,8 +500,8 @@ util_blit_pixels(struct blit_state *ctx,
>    * The sampler view's first_layer indicate the layer to use, but for
>    * cube maps it must point to the first face.  Face is passed in src_face.
>    *
> - * The main advantage over util_blit_pixels is that it allows to specify swizzles in
> - * pipe_sampler_view::swizzle_?.
> + * The main advantage over util_blit_pixels is that it allows to specify
> + * swizzles in pipe_sampler_view::swizzle_?.
>    *
>    * But there is no control over blitting Z and/or stencil.
>    */
> @@ -505,7 +514,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
>                        struct pipe_surface *dst,
>                        int dstX0, int dstY0,
>                        int dstX1, int dstY1,
> -                     float z, uint filter)
> +                     float z, uint filter,
> +                     boolean src_xrbias)
>   {
>      boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT;
>      struct pipe_framebuffer_state fb;
> @@ -593,7 +603,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
>      cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view);
>   
>      /* shaders */
> -   set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW,
> +   set_fragment_shader(ctx, src_xrbias,
>                          src_sampler_view->format,
>                          src_sampler_view->texture->target);
>      set_vertex_shader(ctx);
> diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
> index b50edab..e2934d0 100644
> --- a/src/gallium/auxiliary/util/u_blit.h
> +++ b/src/gallium/auxiliary/util/u_blit.h
> @@ -72,7 +72,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
>                        struct pipe_surface *dst,
>                        int dstX0, int dstY0,
>                        int dstX1, int dstY1,
> -                     float z, uint filter);
> +                     float z, uint filter,
> +                     boolean src_xrbias);
>   
>   #ifdef __cplusplus
>   }
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
> index a301c05..584d915 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.c
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.c
> @@ -222,6 +222,54 @@ ureg_load_tex(struct ureg_program *ureg, struct ureg_dst out,
>   }
>   
>   /**
> + * Make simple fragment texture shader, with xrbias->float conversion:
> + *  IMM {1023/510, -384/510, 0, 1}
> + *  TEX TEMP[0], IN[0], SAMP[0], 2D;
> + *  MAD TEMP[0].xyz TEMP[0], IMM[0].xxxx, IMM[0].yyyy
> + *  MOV OUT[0], TEMP[0]
> + *  END;
> + *
> + * \param tex_target  one of PIPE_TEXTURE_x
> + */
> +void *
> +util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe,
> +                                     unsigned tex_target)
> +{
> +   struct ureg_program *ureg;
> +   struct ureg_src sampler;
> +   struct ureg_src coord;
> +   struct ureg_dst temp;
> +   struct ureg_dst out;
> +   struct ureg_src imm;
> +   enum tgsi_return_type stype = TGSI_RETURN_TYPE_FLOAT;
> +
> +   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
> +   if (!ureg)
> +      return NULL;
> +
> +   imm = ureg_imm4f(ureg, 1023.0f/510.0f,
> +                    -384.0f/510.0f, 0.0f, 1.0f);
> +   sampler = ureg_DECL_sampler(ureg, 0);
> +   ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype);
> +   coord = ureg_DECL_fs_input(ureg,
> +                              TGSI_SEMANTIC_GENERIC, 0,
> +                              TGSI_INTERPOLATE_LINEAR);
> +   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
> +   temp = ureg_DECL_temporary(ureg);
> +
> +   ureg_TEX(ureg, temp, tex_target, coord, sampler);
> +   ureg_MAD(ureg, ureg_writemask(temp, TGSI_WRITEMASK_XYZ),
> +            ureg_src(temp),
> +            ureg_scalar(imm, TGSI_SWIZZLE_X),
> +            ureg_scalar(imm, TGSI_SWIZZLE_Y));
> +   ureg_MOV(ureg, out, ureg_src(temp));
> +   ureg_END(ureg);
> +
> +   return ureg_create_shader_and_destroy(ureg, pipe);
> +}
> +
> +
> +/**
>    * Make simple fragment texture shader:
>    *  IMM {0,0,0,1}                         // (if writemask != 0xf)
>    *  MOV TEMP[0], IMM[0]                   // (if writemask != 0xf)
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
> index a281f57..5e53313 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.h
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.h
> @@ -68,6 +68,10 @@ util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe);
>   extern void *
>   util_make_layered_clear_geometry_shader(struct pipe_context *pipe);
>   
> +void *
> +util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe,
> +                                     unsigned tex_target);
> +
>   extern void *
>   util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
>                                           unsigned tex_target,
> 

LGTM.

Reviwed-by: Jose Fonseca <jfonseca at vmware.com>


More information about the mesa-dev mailing list