Module: Mesa
Branch: main
Commit: b07a58157d0b110dbc09a42cffe7046c3200dd3b
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=b07a58157d0b110dbc09a42cffe7046c3200dd3b

Author: Marek Olšák <marek.ol...@amd.com>
Date:   Sun Nov 19 01:09:25 2023 -0500

radeonsi: remove the LAYER output if the framebuffer state has only 1 layer

Reviewed-by: Qiang Yu <yuq...@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26274>

---

 src/gallium/drivers/radeonsi/si_shader.c          | 14 ++++++++++----
 src/gallium/drivers/radeonsi/si_shader.h          |  1 +
 src/gallium/drivers/radeonsi/si_state.c           |  2 ++
 src/gallium/drivers/radeonsi/si_state_shaders.cpp |  9 ++++++---
 4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index c97256d6620..1f24c78a57e 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1543,6 +1543,7 @@ static void si_dump_shader_key(const struct si_shader 
*shader, FILE *f)
        !key->ge.as_es && !key->ge.as_ls) {
       fprintf(f, "  opt.kill_outputs = 0x%" PRIx64 "\n", 
key->ge.opt.kill_outputs);
       fprintf(f, "  opt.kill_pointsize = 0x%x\n", key->ge.opt.kill_pointsize);
+      fprintf(f, "  opt.kill_layer = 0x%x\n", key->ge.opt.kill_layer);
       fprintf(f, "  opt.kill_clip_distances = 0x%x\n", 
key->ge.opt.kill_clip_distances);
       fprintf(f, "  opt.ngg_culling = 0x%x\n", key->ge.opt.ngg_culling);
       fprintf(f, "  opt.remove_streamout = 0x%x\n", 
key->ge.opt.remove_streamout);
@@ -1643,6 +1644,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const 
union si_shader_key *key)
 
    if (!key->ge.opt.kill_outputs &&
        !key->ge.opt.kill_pointsize &&
+       !key->ge.opt.kill_layer &&
        !key->ge.opt.kill_clip_distances &&
        !(nir->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_LAYER))) {
       nir_metadata_preserve(impl, nir_metadata_all);
@@ -1702,6 +1704,9 @@ static bool si_nir_kill_outputs(nir_shader *nir, const 
union si_shader_key *key)
          case VARYING_SLOT_LAYER:
             /* LAYER is never passed to FS. Instead, we load it there as a 
system value. */
             progress |= nir_remove_varying(intr, MESA_SHADER_FRAGMENT);
+
+            if (key->ge.opt.kill_layer)
+               progress |= nir_remove_sysval_output(intr);
             break;
          }
       }
@@ -1841,6 +1846,7 @@ static void si_lower_ngg(struct si_shader *shader, 
nir_shader *nir)
       .has_param_exports = shader->info.nr_param_exports,
       .clipdist_enable_mask = clipdist_mask,
       .kill_pointsize = key->ge.opt.kill_pointsize,
+      .kill_layer = key->ge.opt.kill_layer,
       .force_vrs = sel->screen->options.vrs2x2,
    };
 
@@ -2006,8 +2012,8 @@ static unsigned si_get_nr_pos_exports(const struct 
si_shader_selector *sel,
 
    if ((info->writes_psize && !key->ge.opt.kill_pointsize) ||
        (info->writes_edgeflag && !key->ge.as_ngg) ||
-       info->writes_viewport_index || info->writes_layer ||
-       sel->screen->options.vrs2x2) {
+       (info->writes_layer && !key->ge.opt.kill_layer) ||
+       info->writes_viewport_index || sel->screen->options.vrs2x2) {
       nr_pos_exports++;
    }
 
@@ -2337,7 +2343,7 @@ struct nir_shader *si_get_nir_shader(struct si_shader 
*shader,
                     shader->key.ge.mono.u.vs_export_prim_id,
                     !si_shader_uses_streamout(shader),
                     key->ge.opt.kill_pointsize,
-                    false,
+                    key->ge.opt.kill_layer,
                     sel->screen->options.vrs2x2);
       }
    } else if (is_legacy_gs) {
@@ -2491,7 +2497,7 @@ si_nir_generate_gs_copy_shader(struct si_screen *sscreen,
                                    shader->info.nr_param_exports,
                                    !si_shader_uses_streamout(gs_shader),
                                    gskey->ge.opt.kill_pointsize,
-                                   false,
+                                   gskey->ge.opt.kill_layer,
                                    sscreen->options.vrs2x2,
                                    output_info);
 
diff --git a/src/gallium/drivers/radeonsi/si_shader.h 
b/src/gallium/drivers/radeonsi/si_shader.h
index 51c41faab85..edf054999be 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -743,6 +743,7 @@ struct si_shader_key_ge {
       uint64_t kill_outputs; /* "get_unique_index" bits */
       unsigned kill_clip_distances : 8;
       unsigned kill_pointsize : 1;
+      unsigned kill_layer : 1;
       unsigned remove_streamout : 1;
 
       /* For NGG VS and TES. */
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index 5ecfe4782c7..063f2e805d5 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2992,6 +2992,8 @@ static void si_set_framebuffer_state(struct pipe_context 
*ctx,
 
    si_dec_framebuffer_counters(&sctx->framebuffer.state);
    util_copy_framebuffer_state(&sctx->framebuffer.state, state);
+   /* Recompute layers because frontends and utils might not set it. */
+   sctx->framebuffer.state.layers = util_framebuffer_get_num_layers(state);
 
    sctx->framebuffer.colorbuf_enabled_4bit = 0;
    sctx->framebuffer.spi_shader_col_format = 0;
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp 
b/src/gallium/drivers/radeonsi/si_state_shaders.cpp
index 467b478f025..c9c7a02197c 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp
@@ -1318,16 +1318,17 @@ static unsigned si_get_vs_out_cntl(const struct 
si_shader_selector *sel,
    unsigned clipcull_mask = (sel->info.clipdist_mask & 
~shader->key.ge.opt.kill_clip_distances) |
                             sel->info.culldist_mask;
    bool writes_psize = sel->info.writes_psize && 
!shader->key.ge.opt.kill_pointsize;
+   bool writes_layer = sel->info.writes_layer && 
!shader->key.ge.opt.kill_layer;
    bool misc_vec_ena = writes_psize || (sel->info.writes_edgeflag && !ngg) ||
-                       sel->screen->options.vrs2x2 ||
-                       sel->info.writes_layer || 
sel->info.writes_viewport_index;
+                       writes_layer || sel->info.writes_viewport_index ||
+                       sel->screen->options.vrs2x2;
 
    return S_02881C_VS_OUT_CCDIST0_VEC_ENA((clipcull_mask & 0x0F) != 0) |
           S_02881C_VS_OUT_CCDIST1_VEC_ENA((clipcull_mask & 0xF0) != 0) |
           S_02881C_USE_VTX_POINT_SIZE(writes_psize) |
           S_02881C_USE_VTX_EDGE_FLAG(sel->info.writes_edgeflag && !ngg) |
           S_02881C_USE_VTX_VRS_RATE(sel->screen->options.vrs2x2) |
-          S_02881C_USE_VTX_RENDER_TARGET_INDX(sel->info.writes_layer) |
+          S_02881C_USE_VTX_RENDER_TARGET_INDX(writes_layer) |
           S_02881C_USE_VTX_VIEWPORT_INDX(sel->info.writes_viewport_index) |
           S_02881C_VS_OUT_MISC_VEC_ENA(misc_vec_ena) |
           S_02881C_VS_OUT_MISC_SIDE_BUS_ENA(misc_vec_ena ||
@@ -2244,6 +2245,8 @@ static void si_get_vs_key_outputs(struct si_context 
*sctx, struct si_shader_sele
    key->ge.opt.kill_pointsize = vs->info.writes_psize &&
                                 sctx->current_rast_prim != MESA_PRIM_POINTS &&
                                 
!sctx->queued.named.rasterizer->polygon_mode_is_points;
+   key->ge.opt.kill_layer = vs->info.writes_layer &&
+                            sctx->framebuffer.state.layers <= 1;
    key->ge.opt.remove_streamout = vs->info.enabled_streamout_buffer_mask &&
                                   !sctx->streamout.enabled_mask;
 }

Reply via email to