On 06/10/2015 06:14 PM, Rob Clark wrote:
From: Rob Clark <robcl...@freedesktop.org>

Some hardware needs to know the sampler type.  Update the blit related
shaders to include SVIEW decl.

Signed-off-by: Rob Clark <robcl...@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)


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to