Mesa (master): radeonsi: take color interpolation into account for shader variants

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 5 03:04:53 UTC 2021


Module: Mesa
Branch: master
Commit: 76eb3478cf9b47c23ebe0741508d71d4fb03c8fa
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=76eb3478cf9b47c23ebe0741508d71d4fb03c8fa

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Thu Dec 24 07:42:12 2020 -0500

radeonsi: take color interpolation into account for shader variants

Fixes:
- Sample shading now uses per-sample interpolation for colors if colors
  are the only inputs. (this is the only case that was broken)

Optimizations:
- BC_OPTIMIZE (barycentric optimization) is now enabled with MSAA if colors
  are qualified with both center and centroid. (BC_OPTIMIZE means that
  the hardware skips initializing centroid (i,j) if they are equal to
  center (i,j))
- If MSAA is disabled and at least 2 out of (center, centroid, sample) are
  used by all inputs now including colors, center is forced for all inputs.
- If INTERP_MODE_COLOR is not used and the legacy GL shade model is flat,
  the shader variant for flat shading is not generated.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8225>

---

 src/gallium/drivers/radeonsi/si_shader.h        |  4 ++++
 src/gallium/drivers/radeonsi/si_shader_nir.c    | 31 +++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/si_state_shaders.c | 25 ++++++++++++--------
 3 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index b635b696569..ec62ad0830a 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -363,6 +363,10 @@ struct si_shader_info {
    bool writes_stencil;     /**< does fragment shader write stencil value? */
    bool writes_samplemask;  /**< does fragment shader write sample mask? */
    bool writes_edgeflag;    /**< vertex shader outputs edgeflag */
+   bool uses_interp_color;
+   bool uses_persp_center_color;
+   bool uses_persp_centroid_color;
+   bool uses_persp_sample_color;
    bool uses_persp_center;
    bool uses_persp_centroid;
    bool uses_persp_sample;
diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
index ae190b2de59..3ad56baf2cd 100644
--- a/src/gallium/drivers/radeonsi/si_shader_nir.c
+++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
@@ -266,6 +266,37 @@ static void scan_instruction(const struct nir_shader *nir, struct si_shader_info
          unsigned index = intr->intrinsic == nir_intrinsic_load_color1;
          uint8_t mask = nir_ssa_def_components_read(&intr->dest.ssa);
          info->colors_read |= mask << (index * 4);
+
+         switch (info->color_interpolate[index]) {
+         case INTERP_MODE_SMOOTH:
+            if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_SAMPLE)
+               info->uses_persp_sample = true;
+            else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTROID)
+               info->uses_persp_centroid = true;
+            else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTER)
+               info->uses_persp_center = true;
+            break;
+         case INTERP_MODE_NOPERSPECTIVE:
+            if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_SAMPLE)
+               info->uses_linear_sample = true;
+            else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTROID)
+               info->uses_linear_centroid = true;
+            else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTER)
+               info->uses_linear_center = true;
+            break;
+         case INTERP_MODE_COLOR:
+            /* We don't know the final value. This will be FLAT if flatshading is enabled
+             * in the rasterizer state, otherwise it will be SMOOTH.
+             */
+            info->uses_interp_color = true;
+            if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_SAMPLE)
+               info->uses_persp_sample_color = true;
+            else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTROID)
+               info->uses_persp_centroid_color = true;
+            else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTER)
+               info->uses_persp_center_color = true;
+            break;
+         }
          break;
       }
       case nir_intrinsic_load_barycentric_at_offset:   /* uses center */
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 1119fb387af..661147f90d7 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -2009,7 +2009,7 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh
       bool is_line = util_prim_is_lines(sctx->current_rast_prim);
 
       key->part.ps.prolog.color_two_side = rs->two_side && sel->info.colors_read;
-      key->part.ps.prolog.flatshade_colors = rs->flatshade && sel->info.colors_read;
+      key->part.ps.prolog.flatshade_colors = rs->flatshade && sel->info.uses_interp_color;
 
       key->part.ps.epilog.alpha_to_one = blend->alpha_to_one && rs->multisample_enable;
 
@@ -2023,30 +2023,35 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh
          key->part.ps.prolog.samplemask_log_ps_iter = util_logbase2(sctx->ps_iter_samples);
       }
 
+      bool uses_persp_center = sel->info.uses_persp_center ||
+                               (!rs->flatshade && sel->info.uses_persp_center_color);
+      bool uses_persp_centroid = sel->info.uses_persp_centroid ||
+                                 (!rs->flatshade && sel->info.uses_persp_centroid_color);
+      bool uses_persp_sample = sel->info.uses_persp_sample ||
+                               (!rs->flatshade && sel->info.uses_persp_sample_color);
+
       if (rs->force_persample_interp && rs->multisample_enable &&
           sctx->framebuffer.nr_samples > 1 && sctx->ps_iter_samples > 1) {
          key->part.ps.prolog.force_persp_sample_interp =
-            sel->info.uses_persp_center || sel->info.uses_persp_centroid;
+            uses_persp_center || uses_persp_centroid;
 
          key->part.ps.prolog.force_linear_sample_interp =
             sel->info.uses_linear_center || sel->info.uses_linear_centroid;
       } else if (rs->multisample_enable && sctx->framebuffer.nr_samples > 1) {
          key->part.ps.prolog.bc_optimize_for_persp =
-            sel->info.uses_persp_center && sel->info.uses_persp_centroid;
+            uses_persp_center && uses_persp_centroid;
          key->part.ps.prolog.bc_optimize_for_linear =
             sel->info.uses_linear_center && sel->info.uses_linear_centroid;
       } else {
          /* Make sure SPI doesn't compute more than 1 pair
           * of (i,j), which is the optimization here. */
-         key->part.ps.prolog.force_persp_center_interp = sel->info.uses_persp_center +
-                                                            sel->info.uses_persp_centroid +
-                                                            sel->info.uses_persp_sample >
-                                                         1;
+         key->part.ps.prolog.force_persp_center_interp = uses_persp_center +
+                                                         uses_persp_centroid +
+                                                         uses_persp_sample > 1;
 
          key->part.ps.prolog.force_linear_center_interp = sel->info.uses_linear_center +
-                                                             sel->info.uses_linear_centroid +
-                                                             sel->info.uses_linear_sample >
-                                                          1;
+                                                          sel->info.uses_linear_centroid +
+                                                          sel->info.uses_linear_sample > 1;
 
          if (sel->info.uses_interp_at_sample)
             key->mono.u.ps.interpolate_at_sample_force_center = 1;



More information about the mesa-commit mailing list