[Mesa-dev] [PATCH 5/7] util/blitter (and friends): generate appropriate SVIEW decls

Roland Scheidegger sroland at vmware.com
Thu Jun 11 07:53:16 PDT 2015


For 1-4/7, 6/7:
Reviewed-by: Roland Scheidegger <sroland at vmware.com>

I think though using two exclusive booleans is really ugly. Probably
should just use a tgsi_return_type enum instead indeed, and treat the
unorm/snorm cases as float. I'm not entirely sure what the unorm/snorm
types are for neither, this is a d3d10-ism but I'm not sure it serves
much purpose (since, of course, for the purposes of the shader, the
results indeed are floats). At least for now llvmpipe actually doesn't
use that information (as we recompile the shader anyway if the texture
"type" changes in the actually bound sampler views we get all the
information from there).


(FWIW I believe there's a slight catch with the
util_format_is_pure_uint/sint functions - because right now in gallium
it is sort of ok to sample from things like D24S8 textures, which means
the depth component is sampled (so same as D24X8, opposed to X24S8), and
depending if the D or S channel is first the answer may not quite be
right...)

Roland

Am 11.06.2015 um 02:14 schrieb Rob Clark:
> From: Rob Clark <robclark at freedesktop.org>
> 
> Some hardware needs to know the sampler type.  Update the blit related
> shaders to include SVIEW decl.
> 
> Signed-off-by: Rob Clark <robclark at freedesktop.org>
> ---
> Possibly I should have refactored the existing code to pass around a
> return_type rather than doing the is_uint/is_sint thing everywhere.
> And this does kind of ignore UNORM/SNORM.. although I'm not really
> sure that we need shader variants for UNORM/SNORM (we don't have this
> information in GLSL IR or NIR IR, and I don't know any hw that doesn't
> just treat those as FLOAT in the shader compiler).  Anyways, sending
> it out as-is for comments.
> 
>  src/gallium/auxiliary/util/u_blit.c           | 32 +++++++++----
>  src/gallium/auxiliary/util/u_blitter.c        | 42 ++++++++++++----
>  src/gallium/auxiliary/util/u_simple_shaders.c | 69 +++++++++++++++++++++++----
>  src/gallium/auxiliary/util/u_simple_shaders.h | 15 ++++--
>  src/gallium/auxiliary/util/u_tests.c          |  3 +-
>  src/gallium/tests/trivial/quad-tex.c          |  2 +-
>  6 files changed, 132 insertions(+), 31 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
> index 3f3b5fe..0062d96 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];
> +   void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1][3];
>  
>     struct pipe_resource *vbuf;  /**< quad vertices */
>     unsigned vbuf_slot;
> @@ -135,15 +135,17 @@ void
>  util_destroy_blit(struct blit_state *ctx)
>  {
>     struct pipe_context *pipe = ctx->pipe;
> -   unsigned i, j;
> +   unsigned i, j, k;
>  
>     if (ctx->vs)
>        pipe->delete_vs_state(pipe, ctx->vs);
>  
>     for (i = 0; i < Elements(ctx->fs); i++) {
>        for (j = 0; j < Elements(ctx->fs[i]); j++) {
> -         if (ctx->fs[i][j])
> -            pipe->delete_fs_state(pipe, ctx->fs[i][j]);
> +         for (k = 0; k < Elements(ctx->fs[i][j]); k++) {
> +            if (ctx->fs[i][j][k])
> +               pipe->delete_fs_state(pipe, ctx->fs[i][j][k]);
> +         }
>        }
>     }
>  
> @@ -158,18 +160,31 @@ util_destroy_blit(struct blit_state *ctx)
>   */
>  static INLINE void
>  set_fragment_shader(struct blit_state *ctx, uint writemask,
> +                    enum pipe_format format,
>                      enum pipe_texture_target pipe_tex)
>  {
> -   if (!ctx->fs[pipe_tex][writemask]) {
> +   boolean is_uint = util_format_is_pure_uint(format);
> +   boolean is_sint = util_format_is_pure_sint(format);
> +   unsigned type;
> +
> +   if (is_uint)
> +      type = 0;
> +   else if (is_sint)
> +      type = 1;
> +   else
> +      type = 2;
> +
> +   if (!ctx->fs[pipe_tex][writemask][type]) {
>        unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
>  
> -      ctx->fs[pipe_tex][writemask] =
> +      ctx->fs[pipe_tex][writemask][type] =
>           util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex,
>                                                   TGSI_INTERPOLATE_LINEAR,
> -                                                 writemask);
> +                                                 writemask,
> +                                                 is_uint, is_sint);
>     }
>  
> -   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask]);
> +   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask][type]);
>  }
>  
>  
> @@ -571,6 +586,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
>  
>     /* shaders */
>     set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW,
> +                       src_sampler_view->format,
>                         src_sampler_view->texture->target);
>     set_vertex_shader(ctx);
>     cso_set_tessctrl_shader_handle(ctx->cso, NULL);
> diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
> index 16bf90f..27e0d10 100644
> --- a/src/gallium/auxiliary/util/u_blitter.c
> +++ b/src/gallium/auxiliary/util/u_blitter.c
> @@ -81,6 +81,8 @@ struct blitter_context_priv
>     /* FS which outputs a color from a texture,
>        where the index is PIPE_TEXTURE_* to be sampled. */
>     void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
> +   void *fs_texfetch_col_uint[PIPE_MAX_TEXTURE_TYPES];
> +   void *fs_texfetch_col_sint[PIPE_MAX_TEXTURE_TYPES];
>  
>     /* FS which outputs a depth from a texture,
>        where the index is PIPE_TEXTURE_* to be sampled. */
> @@ -90,6 +92,8 @@ struct blitter_context_priv
>  
>     /* FS which outputs one sample from a multisample texture. */
>     void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES];
> +   void *fs_texfetch_col_msaa_uint[PIPE_MAX_TEXTURE_TYPES];
> +   void *fs_texfetch_col_msaa_sint[PIPE_MAX_TEXTURE_TYPES];
>     void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES];
>     void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES];
>     void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES];
> @@ -438,6 +442,10 @@ void util_blitter_destroy(struct blitter_context *blitter)
>     for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
>        if (ctx->fs_texfetch_col[i])
>           ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
> +      if (ctx->fs_texfetch_col_sint[i])
> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_sint[i]);
> +      if (ctx->fs_texfetch_col_uint[i])
> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_uint[i]);
>        if (ctx->fs_texfetch_depth[i])
>           ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
>        if (ctx->fs_texfetch_depthstencil[i])
> @@ -447,6 +455,10 @@ void util_blitter_destroy(struct blitter_context *blitter)
>  
>        if (ctx->fs_texfetch_col_msaa[i])
>           ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[i]);
> +      if (ctx->fs_texfetch_col_msaa_sint[i])
> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa_sint[i]);
> +      if (ctx->fs_texfetch_col_msaa_uint[i])
> +         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa_uint[i]);
>        if (ctx->fs_texfetch_depth_msaa[i])
>           ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i]);
>        if (ctx->fs_texfetch_depthstencil_msaa[i])
> @@ -844,20 +856,20 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
>  {
>     struct pipe_context *pipe = ctx->base.pipe;
>     unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_nr_samples);
> +   boolean is_uint, is_sint;
>  
>     assert(target < PIPE_MAX_TEXTURE_TYPES);
>  
> +   is_uint = util_format_is_pure_uint(format);
> +   is_sint = util_format_is_pure_sint(format);
> +
>     if (src_nr_samples > 1) {
>        void **shader;
>  
>        if (dst_nr_samples <= 1) {
>           /* The destination has one sample, so we'll do color resolve. */
> -         boolean is_uint, is_sint;
>           unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples);
>  
> -         is_uint = util_format_is_pure_uint(format);
> -         is_sint = util_format_is_pure_sint(format);
> -
>           assert(filter < 2);
>  
>           if (is_uint)
> @@ -885,24 +897,38 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
>           /* The destination has multiple samples, we'll do
>            * an MSAA->MSAA copy.
>            */
> -         shader = &ctx->fs_texfetch_col_msaa[target];
> +          if (is_uint)
> +             shader = &ctx->fs_texfetch_col_msaa_uint[target];
> +          else if (is_sint)
> +             shader = &ctx->fs_texfetch_col_msaa_sint[target];
> +          else
> +             shader = &ctx->fs_texfetch_col_msaa[target];
>  
>           /* Create the fragment shader on-demand. */
>           if (!*shader) {
>              assert(!ctx->cached_all_shaders);
> -            *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex);
> +            *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex,
> +                                                   is_uint, is_sint);
>           }
>        }
>  
>        return *shader;
>     } else {
> -      void **shader = &ctx->fs_texfetch_col[target];
> +      void **shader;
> +
> +      if (is_uint)
> +         shader = &ctx->fs_texfetch_col_uint[target];
> +      else if (is_sint)
> +         shader = &ctx->fs_texfetch_col_sint[target];
> +      else
> +         shader = &ctx->fs_texfetch_col[target];
>  
>        /* Create the fragment shader on-demand. */
>        if (!*shader) {
>           assert(!ctx->cached_all_shaders);
>           *shader = util_make_fragment_tex_shader(pipe, tgsi_tex,
> -                                                 TGSI_INTERPOLATE_LINEAR);
> +                                                 TGSI_INTERPOLATE_LINEAR,
> +                                                 is_uint, is_sint);
>        }
>  
>        return *shader;
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
> index c612b67..8b6b8a6 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.c
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.c
> @@ -201,6 +201,27 @@ void *util_make_layered_clear_geometry_shader(struct pipe_context *pipe)
>     return pipe->create_gs_state(pipe, &state);
>  }
>  
> +static struct ureg_src
> +decl_sampler_view(struct ureg_program *ureg,
> +                  unsigned nr,
> +                  unsigned target,
> +                  boolean is_uint,
> +                  boolean is_sint)
> +{
> +   unsigned type;
> +
> +   assert(!(is_uint && is_sint));
> +
> +   if (is_uint)
> +      type = TGSI_RETURN_TYPE_UINT;
> +   else if (is_sint)
> +      type = TGSI_RETURN_TYPE_SINT;
> +   else
> +      type = TGSI_RETURN_TYPE_FLOAT;
> +
> +   return ureg_DECL_sampler_view(ureg, nr, target, type, type, type, type);
> +}
> +
>  /**
>   * Make simple fragment texture shader:
>   *  IMM {0,0,0,1}                         // (if writemask != 0xf)
> @@ -216,7 +237,9 @@ void *
>  util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
>                                          unsigned tex_target,
>                                          unsigned interp_mode,
> -                                        unsigned writemask )
> +                                        unsigned writemask,
> +                                        boolean is_uint,
> +                                        boolean is_sint)
>  {
>     struct ureg_program *ureg;
>     struct ureg_src sampler;
> @@ -232,6 +255,8 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
>     
>     sampler = ureg_DECL_sampler( ureg, 0 );
>  
> +   decl_sampler_view(ureg, 0, tex_target, is_uint, is_sint);
> +
>     tex = ureg_DECL_fs_input( ureg, 
>                               TGSI_SEMANTIC_GENERIC, 0, 
>                               interp_mode );
> @@ -268,12 +293,16 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
>   */
>  void *
>  util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
> -                              unsigned interp_mode)
> +                              unsigned interp_mode,
> +                              boolean is_uint,
> +                              boolean is_sint)
>  {
>     return util_make_fragment_tex_shader_writemask( pipe,
>                                                     tex_target,
>                                                     interp_mode,
> -                                                   TGSI_WRITEMASK_XYZW );
> +                                                   TGSI_WRITEMASK_XYZW,
> +                                                   is_uint,
> +                                                   is_sint );
>  }
>  
>  
> @@ -298,6 +327,8 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
>  
>     sampler = ureg_DECL_sampler( ureg, 0 );
>  
> +   decl_sampler_view(ureg, 0, tex_target, FALSE, FALSE);
> +
>     tex = ureg_DECL_fs_input( ureg,
>                               TGSI_SEMANTIC_GENERIC, 0,
>                               interp_mode );
> @@ -343,7 +374,9 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe,
>        return NULL;
>  
>     depth_sampler = ureg_DECL_sampler( ureg, 0 );
> +   decl_sampler_view(ureg, 0, tex_target, FALSE, FALSE);
>     stencil_sampler = ureg_DECL_sampler( ureg, 1 );
> +   decl_sampler_view(ureg, 1, tex_target, TRUE, FALSE);
>  
>     tex = ureg_DECL_fs_input( ureg,
>                               TGSI_SEMANTIC_GENERIC, 0,
> @@ -398,6 +431,8 @@ util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
>  
>     stencil_sampler = ureg_DECL_sampler( ureg, 0 );
>  
> +   decl_sampler_view(ureg, 0, tex_target, TRUE, FALSE);
> +
>     tex = ureg_DECL_fs_input( ureg,
>                               TGSI_SEMANTIC_GENERIC, 0,
>                               interp_mode );
> @@ -512,6 +547,7 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
>  static void *
>  util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
>                             unsigned tgsi_tex,
> +                           const char *samp_type,
>                             const char *output_semantic,
>                             const char *output_mask)
>  {
> @@ -519,6 +555,7 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
>           "FRAG\n"
>           "DCL IN[0], GENERIC[0], LINEAR\n"
>           "DCL SAMP[0]\n"
> +         "DCL SVIEW[0], %s, %s\n"
>           "DCL OUT[0], %s\n"
>           "DCL TEMP[0]\n"
>  
> @@ -534,7 +571,8 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
>     assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
>            tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);
>  
> -   sprintf(text, shader_templ, output_semantic, output_mask, type);
> +   sprintf(text, shader_templ, type, samp_type,
> +           output_semantic, output_mask, type);
>  
>     if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
>        puts(text);
> @@ -556,9 +594,22 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
>   */
>  void *
>  util_make_fs_blit_msaa_color(struct pipe_context *pipe,
> -                             unsigned tgsi_tex)
> +                             unsigned tgsi_tex,
> +                             boolean is_uint,
> +                             boolean is_sint)
>  {
> -   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex,
> +   const char *samp_type;
> +
> +   assert(!(is_uint && is_sint));
> +
> +   if (is_uint)
> +      samp_type = "UINT";
> +   else if (is_sint)
> +      samp_type = "SINT";
> +   else
> +      samp_type = "FLOAT";
> +
> +   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, samp_type,
>                                       "COLOR[0]", "");
>  }
>  
> @@ -572,7 +623,7 @@ void *
>  util_make_fs_blit_msaa_depth(struct pipe_context *pipe,
>                               unsigned tgsi_tex)
>  {
> -   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex,
> +   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "FLOAT",
>                                       "POSITION", ".z");
>  }
>  
> @@ -586,7 +637,7 @@ void *
>  util_make_fs_blit_msaa_stencil(struct pipe_context *pipe,
>                                 unsigned tgsi_tex)
>  {
> -   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex,
> +   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "UINT",
>                                       "STENCIL", ".y");
>  }
>  
> @@ -653,6 +704,7 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe,
>  
>     /* Declarations. */
>     sampler = ureg_DECL_sampler(ureg, 0);
> +   decl_sampler_view(ureg, 0, tgsi_tex, is_uint, is_sint);
>     coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
>                                TGSI_INTERPOLATE_LINEAR);
>     out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
> @@ -713,6 +765,7 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
>  
>     /* Declarations. */
>     sampler = ureg_DECL_sampler(ureg, 0);
> +   decl_sampler_view(ureg, 0, tgsi_tex, is_uint, is_sint);
>     coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
>                                TGSI_INTERPOLATE_LINEAR);
>     out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
> index dd282e0..89cb3570 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.h
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.h
> @@ -68,15 +68,18 @@ extern void *
>  util_make_layered_clear_geometry_shader(struct pipe_context *pipe);
>  
>  extern void *
> -util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, 
> +util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
>                                          unsigned tex_target,
>                                          unsigned interp_mode,
> -                                        unsigned writemask);
> +                                        unsigned writemask,
> +                                        boolean is_uint,
> +                                        boolean is_sint);
>  
>  extern void *
>  util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
> -                              unsigned interp_mode);
> -
> +                              unsigned interp_mode,
> +                              boolean is_uint,
> +                              boolean is_sint);
>  
>  extern void *
>  util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
> @@ -115,7 +118,9 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
>  
>  extern void *
>  util_make_fs_blit_msaa_color(struct pipe_context *pipe,
> -                             unsigned tgsi_tex);
> +                             unsigned tgsi_tex,
> +                             boolean is_uint,
> +                             boolean is_sint);
>  
>  
>  extern void *
> diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c
> index fe54972..e30ae55 100644
> --- a/src/gallium/auxiliary/util/u_tests.c
> +++ b/src/gallium/auxiliary/util/u_tests.c
> @@ -373,7 +373,8 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target)
>  
>     /* Fragment shader. */
>     fs = util_make_fragment_tex_shader(ctx, tgsi_tex_target,
> -                                      TGSI_INTERPOLATE_LINEAR);
> +                                      TGSI_INTERPOLATE_LINEAR,
> +                                      FALSE, FALSE);
>     cso_set_fragment_shader_handle(cso, fs);
>  
>     /* Vertex shader. */
> diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c
> index abecedb..946dbec 100644
> --- a/src/gallium/tests/trivial/quad-tex.c
> +++ b/src/gallium/tests/trivial/quad-tex.c
> @@ -270,7 +270,7 @@ static void init_prog(struct program *p)
>  	}
>  
>  	/* fragment shader */
> -	p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
> +	p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR, FALSE, FALSE);
>  }
>  
>  static void close_prog(struct program *p)
> 



More information about the mesa-dev mailing list