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

Brian Paul brianp at vmware.com
Thu Jun 11 07:44:07 PDT 2015


On 06/10/2015 06:14 PM, Rob Clark wrote:
> 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.

Yeah, I think a single return type parameter would be much cleaner.


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