[Mesa-dev] [PATCH 1/3] gallium/util: rewrite depth-stencil blit shaders

Marek Olšák maraeo at gmail.com
Fri Jun 21 17:02:48 UTC 2019


From: Marek Olšák <marek.olsak at amd.com>

- merge all 3 functions (Z, S, ZS)
- don't write the color output
- read the value from texel.x, then write it to position.z or stencil.y
  (don't use the value from texel.y or texel.z)
---
 src/gallium/auxiliary/util/u_blitter.c        |  19 +-
 src/gallium/auxiliary/util/u_simple_shaders.c | 185 ++++--------------
 src/gallium/auxiliary/util/u_simple_shaders.h |  25 +--
 3 files changed, 46 insertions(+), 183 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 3dc49cd0958..8e4807ec670 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -1010,24 +1010,22 @@ void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
       if (use_txf)
          shader = &ctx->fs_texfetch_depth[target][1];
       else
          shader = &ctx->fs_texfetch_depth[target][0];
 
       /* Create the fragment shader on-demand. */
       if (!*shader) {
          enum tgsi_texture_type tgsi_tex;
          assert(!ctx->cached_all_shaders);
          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
-         *shader =
-            util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
-                                                     TGSI_INTERPOLATE_LINEAR,
-                                                     ctx->has_tex_lz, use_txf);
+         *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_Z, tgsi_tex,
+                                        ctx->has_tex_lz, use_txf);
       }
 
       return *shader;
    }
 }
 
 static inline
 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
                                            enum pipe_texture_target target,
                                            unsigned nr_samples,
@@ -1055,25 +1053,22 @@ void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
       if (use_txf)
          shader = &ctx->fs_texfetch_depthstencil[target][1];
       else
          shader = &ctx->fs_texfetch_depthstencil[target][0];
 
       /* Create the fragment shader on-demand. */
       if (!*shader) {
          enum tgsi_texture_type tgsi_tex;
          assert(!ctx->cached_all_shaders);
          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
-         *shader =
-            util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex,
-                                                            TGSI_INTERPOLATE_LINEAR,
-                                                            ctx->has_tex_lz,
-                                                            use_txf);
+         *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_ZS, tgsi_tex,
+                                        ctx->has_tex_lz, use_txf);
       }
 
       return *shader;
    }
 }
 
 static inline
 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
                                       enum pipe_texture_target target,
                                       unsigned nr_samples,
@@ -1101,24 +1096,22 @@ void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
       if (use_txf)
          shader = &ctx->fs_texfetch_stencil[target][1];
       else
          shader = &ctx->fs_texfetch_stencil[target][0];
 
       /* Create the fragment shader on-demand. */
       if (!*shader) {
          enum tgsi_texture_type tgsi_tex;
          assert(!ctx->cached_all_shaders);
          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
-         *shader =
-            util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex,
-                                                       TGSI_INTERPOLATE_LINEAR,
-                                                       ctx->has_tex_lz, use_txf);
+         *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_S, tgsi_tex,
+                                        ctx->has_tex_lz, use_txf);
       }
 
       return *shader;
    }
 }
 
 
 /**
  * Generate and save all fragment shaders that we will ever need for
  * blitting.  Drivers which use the 'draw' fallbacks will typically use
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index d62a65579ae..c111eaf1db5 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -371,187 +371,76 @@ util_make_fragment_tex_shader(struct pipe_context *pipe,
 {
    return util_make_fragment_tex_shader_writemask( pipe,
                                                    tex_target,
                                                    interp_mode,
                                                    TGSI_WRITEMASK_XYZW,
                                                    stype, dtype, load_level_zero,
                                                    use_txf);
 }
 
 
-/**
- * Make a simple fragment texture shader which reads an X component from
- * a texture and writes it as depth.
- */
-void *
-util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
-                                         enum tgsi_texture_type tex_target,
-                                         enum tgsi_interpolate_mode interp_mode,
-                                         bool load_level_zero,
-                                         bool use_txf)
-{
-   struct ureg_program *ureg;
-   struct ureg_src sampler;
-   struct ureg_src tex;
-   struct ureg_dst out, depth;
-   struct ureg_src imm;
-
-   ureg = ureg_create( PIPE_SHADER_FRAGMENT );
-   if (!ureg)
-      return NULL;
-
-   sampler = ureg_DECL_sampler( ureg, 0 );
-
-   ureg_DECL_sampler_view(ureg, 0, tex_target,
-                          TGSI_RETURN_TYPE_FLOAT,
-                          TGSI_RETURN_TYPE_FLOAT,
-                          TGSI_RETURN_TYPE_FLOAT,
-                          TGSI_RETURN_TYPE_FLOAT);
-
-   tex = ureg_DECL_fs_input( ureg,
-                             TGSI_SEMANTIC_GENERIC, 0,
-                             interp_mode );
-
-   out = ureg_DECL_output( ureg,
-                           TGSI_SEMANTIC_COLOR,
-                           0 );
-
-   depth = ureg_DECL_output( ureg,
-                             TGSI_SEMANTIC_POSITION,
-                             0 );
-
-   imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
-
-   ureg_MOV( ureg, out, imm );
-
-   ureg_load_tex(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z), tex, sampler,
-                 tex_target, load_level_zero, use_txf);
-   ureg_END( ureg );
-
-   return ureg_create_shader_and_destroy( ureg, pipe );
-}
-
-
 /**
  * Make a simple fragment texture shader which reads the texture unit 0 and 1
  * and writes it as depth and stencil, respectively.
  */
 void *
-util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe,
-                                         enum tgsi_texture_type tex_target,
-                                         enum tgsi_interpolate_mode interp_mode,
-                                         bool load_level_zero,
-                                         bool use_txf)
+util_make_fs_blit_zs(struct pipe_context *pipe, unsigned zs_mask,
+                     enum tgsi_texture_type tex_target,
+                     bool load_level_zero, bool use_txf)
 {
    struct ureg_program *ureg;
-   struct ureg_src depth_sampler, stencil_sampler;
-   struct ureg_src tex;
-   struct ureg_dst out, depth, stencil;
-   struct ureg_src imm;
+   struct ureg_src depth_sampler, stencil_sampler, coord;
+   struct ureg_dst depth, stencil, tmp;
 
-   ureg = ureg_create( PIPE_SHADER_FRAGMENT );
-   if (!ureg)
-      return NULL;
-
-   depth_sampler = ureg_DECL_sampler( ureg, 0 );
-   ureg_DECL_sampler_view(ureg, 0, tex_target,
-                          TGSI_RETURN_TYPE_FLOAT,
-                          TGSI_RETURN_TYPE_FLOAT,
-                          TGSI_RETURN_TYPE_FLOAT,
-                          TGSI_RETURN_TYPE_FLOAT);
-   stencil_sampler = ureg_DECL_sampler( ureg, 1 );
-   ureg_DECL_sampler_view(ureg, 0, tex_target,
-                          TGSI_RETURN_TYPE_UINT,
-                          TGSI_RETURN_TYPE_UINT,
-                          TGSI_RETURN_TYPE_UINT,
-                          TGSI_RETURN_TYPE_UINT);
-
-   tex = ureg_DECL_fs_input( ureg,
-                             TGSI_SEMANTIC_GENERIC, 0,
-                             interp_mode );
-
-   out = ureg_DECL_output( ureg,
-                           TGSI_SEMANTIC_COLOR,
-                           0 );
-
-   depth = ureg_DECL_output( ureg,
-                             TGSI_SEMANTIC_POSITION,
-                             0 );
-
-   stencil = ureg_DECL_output( ureg,
-                             TGSI_SEMANTIC_STENCIL,
-                             0 );
-
-   imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
-
-   ureg_MOV( ureg, out, imm );
-
-   ureg_load_tex(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z), tex,
-                 depth_sampler, tex_target, load_level_zero, use_txf);
-   ureg_load_tex(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y), tex,
-                 stencil_sampler, tex_target, load_level_zero, use_txf);
-   ureg_END( ureg );
-
-   return ureg_create_shader_and_destroy( ureg, pipe );
-}
-
-
-/**
- * Make a simple fragment texture shader which reads a texture and writes it
- * as stencil.
- */
-void *
-util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
-                                         enum tgsi_texture_type tex_target,
-                                         enum tgsi_interpolate_mode interp_mode,
-                                         bool load_level_zero,
-                                         bool use_txf)
-{
-   struct ureg_program *ureg;
-   struct ureg_src stencil_sampler;
-   struct ureg_src tex;
-   struct ureg_dst out, stencil;
-   struct ureg_src imm;
-
-   ureg = ureg_create( PIPE_SHADER_FRAGMENT );
+   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
    if (!ureg)
       return NULL;
 
-   stencil_sampler = ureg_DECL_sampler( ureg, 0 );
+   coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
+                              TGSI_INTERPOLATE_LINEAR);
+   tmp = ureg_DECL_temporary(ureg);
 
-   ureg_DECL_sampler_view(ureg, 0, tex_target,
-                          TGSI_RETURN_TYPE_UINT,
-                          TGSI_RETURN_TYPE_UINT,
-                          TGSI_RETURN_TYPE_UINT,
-                          TGSI_RETURN_TYPE_UINT);
+   if (zs_mask & PIPE_MASK_Z) {
+      depth_sampler = ureg_DECL_sampler(ureg, 0);
+      ureg_DECL_sampler_view(ureg, 0, tex_target,
+                             TGSI_RETURN_TYPE_FLOAT,
+                             TGSI_RETURN_TYPE_FLOAT,
+                             TGSI_RETURN_TYPE_FLOAT,
+                             TGSI_RETURN_TYPE_FLOAT);
 
-   tex = ureg_DECL_fs_input( ureg,
-                             TGSI_SEMANTIC_GENERIC, 0,
-                             interp_mode );
+      ureg_load_tex(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), coord,
+                    depth_sampler, tex_target, load_level_zero, use_txf);
 
-   out = ureg_DECL_output( ureg,
-                           TGSI_SEMANTIC_COLOR,
-                           0 );
+      depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
+      ureg_MOV(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z),
+               ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
+   }
 
-   stencil = ureg_DECL_output( ureg,
-                             TGSI_SEMANTIC_STENCIL,
-                             0 );
+   if (zs_mask & PIPE_MASK_S) {
+      stencil_sampler = ureg_DECL_sampler(ureg, zs_mask & PIPE_MASK_Z ? 1 : 0);
+      ureg_DECL_sampler_view(ureg, 0, tex_target,
+                             TGSI_RETURN_TYPE_UINT,
+                             TGSI_RETURN_TYPE_UINT,
+                             TGSI_RETURN_TYPE_UINT,
+                             TGSI_RETURN_TYPE_UINT);
 
-   imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
+      ureg_load_tex(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), coord,
+                    stencil_sampler, tex_target, load_level_zero, use_txf);
 
-   ureg_MOV( ureg, out, imm );
+      stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0);
+      ureg_MOV(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y),
+               ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
+   }
 
-   ureg_load_tex(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y), tex,
-                 stencil_sampler, tex_target, load_level_zero, use_txf);
-   ureg_END( ureg );
+   ureg_END(ureg);
 
-   return ureg_create_shader_and_destroy( ureg, pipe );
+   return ureg_create_shader_and_destroy(ureg, pipe);
 }
 
 
 /**
  * Make simple fragment color pass-through shader that replicates OUT[0]
  * to all bound colorbuffers.
  */
 void *
 util_make_fragment_passthrough_shader(struct pipe_context *pipe,
                                       int input_semantic,
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index 3afe4cc050b..4d4f5e97f5b 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -85,42 +85,23 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
 extern void *
 util_make_fragment_tex_shader(struct pipe_context *pipe,
                               enum tgsi_texture_type tex_target,
                               enum tgsi_interpolate_mode interp_mode,
                               enum tgsi_return_type stype,
                               enum tgsi_return_type dtype,
                               bool load_level_zero,
                               bool use_txf);
 
 extern void *
-util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
-                                         enum tgsi_texture_type tex_target,
-                                         enum tgsi_interpolate_mode interp_mode,
-                                         bool load_level_zero,
-                                         bool use_txf);
-
-
-extern void *
-util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe,
-                                         enum tgsi_texture_type tex_target,
-                                         enum tgsi_interpolate_mode interp_mode,
-                                         bool load_level_zero,
-                                         bool use_txf);
-
-
-extern void *
-util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
-                                         enum tgsi_texture_type tex_target,
-                                         enum tgsi_interpolate_mode interp_mode,
-                                         bool load_level_zero,
-                                         bool use_txf);
-
+util_make_fs_blit_zs(struct pipe_context *pipe, unsigned zs_mask,
+                     enum tgsi_texture_type tex_target,
+                     bool load_level_zero, bool use_txf);
 
 extern void *
 util_make_fragment_passthrough_shader(struct pipe_context *pipe,
                                       int input_semantic,
                                       int input_interpolate,
                                       boolean write_all_cbufs);
 
 
 extern void *
 util_make_empty_fragment_shader(struct pipe_context *pipe);
-- 
2.17.1



More information about the mesa-dev mailing list