From c005b2cd4be39a9479dd73f45aff73b5b37438f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 10 Aug 2021 00:55:52 -0400 Subject: [PATCH] radeonsi: move as_ls/es/ngg setting out of si_shader_selector_key Do it when we bind shaders. The advantages are: - no need to memset the fields when any shader variant state is changed (e.g. culling on/off) - no need to recompute the fields every time that happens Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/drivers/radeonsi/si_descriptors.c | 30 +++++++++++++++++++ src/gallium/drivers/radeonsi/si_pipe.c | 1 + src/gallium/drivers/radeonsi/si_pipe.h | 2 ++ src/gallium/drivers/radeonsi/si_shader.h | 7 +++-- .../drivers/radeonsi/si_state_shaders.c | 27 +++++------------ 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index ebf555d74e0..77bb136c42b 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -1985,6 +1985,36 @@ void si_shader_change_notify(struct si_context *sctx) sctx->shader.gs.cso ? GS_ON : GS_OFF, sctx->ngg ? NGG_ON : NGG_OFF, PIPE_SHADER_TESS_EVAL)); + + /* Update as_* flags in shader keys. Ignore disabled shader stages. + * as_ls = VS before TCS + * as_es = VS before GS or TES before GS + * as_ngg = NGG enabled for the last geometry stage. + * If GS sets as_ngg, the previous stage must set as_ngg too. + */ + if (sctx->shader.tes.cso) { + sctx->shader.vs.key.as_ls = 1; + sctx->shader.vs.key.as_es = 0; + sctx->shader.vs.key.as_ngg = 0; + + if (sctx->shader.gs.cso) { + sctx->shader.tes.key.as_es = 1; + sctx->shader.tes.key.as_ngg = sctx->ngg; + sctx->shader.gs.key.as_ngg = sctx->ngg; + } else { + sctx->shader.tes.key.as_es = 0; + sctx->shader.tes.key.as_ngg = sctx->ngg; + } + } else if (sctx->shader.gs.cso) { + sctx->shader.vs.key.as_ls = 0; + sctx->shader.vs.key.as_es = 1; + sctx->shader.vs.key.as_ngg = sctx->ngg; + sctx->shader.gs.key.as_ngg = sctx->ngg; + } else { + sctx->shader.vs.key.as_ls = 0; + sctx->shader.vs.key.as_es = 0; + sctx->shader.vs.key.as_ngg = sctx->ngg; + } } #define si_emit_consecutive_shader_pointers(sctx, pointer_mask, sh_base) do { \ diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index ce0755413cf..14930725931 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -539,6 +539,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign } sctx->ngg = sscreen->use_ngg; + si_shader_change_notify(sctx); /* Initialize context functions used by graphics and compute. */ if (sctx->chip_class >= GFX10) diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 01bc15ae3fc..c7d8de417f6 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -804,6 +804,8 @@ struct si_streamout { struct si_shader_ctx_state { struct si_shader_selector *cso; struct si_shader *current; + /* The shader variant key representing the current state. */ + struct si_shader_key key; }; #define SI_NUM_VGT_PARAM_KEY_BITS 12 diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 940c05c9be1..22058be928e 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -640,9 +640,10 @@ struct si_shader_key { /* These three are initially set according to the NEXT_SHADER property, * or guessed if the property doesn't seem correct. */ - unsigned as_es : 1; /* export shader, which precedes GS */ - unsigned as_ls : 1; /* local shader, which precedes TCS */ - unsigned as_ngg : 1; /* VS, TES, or GS compiled as NGG primitive shader */ + unsigned as_es : 1; /* whether it's a shader before GS */ + unsigned as_ls : 1; /* whether it's VS before TCS */ + unsigned as_ngg : 1; /* whether it's the last GE stage and NGG is enabled, + also set for the stage right before GS */ /* Flags for monolithic compilation only. */ struct { diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 8eae7e7c179..f178dfe578b 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1882,7 +1882,9 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh { struct si_context *sctx = (struct si_context *)ctx; - memset(key, 0, sizeof(*key)); + memset(&key->part, 0, sizeof(key->part)); + memset(&key->mono, 0, sizeof(key->mono)); + memset(&key->opt, 0, sizeof(key->opt)); unsigned num_inlinable_uniforms = sel->info.base.num_inlinable_uniforms; if (num_inlinable_uniforms && @@ -1897,15 +1899,8 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh case MESA_SHADER_VERTEX: si_shader_selector_key_vs(sctx, sel, key, &key->part.vs.prolog); - if (sctx->shader.tes.cso) - key->as_ls = 1; - else if (sctx->shader.gs.cso) { - key->as_es = 1; - key->as_ngg = sctx->ngg; - } else { - key->as_ngg = sctx->ngg; + if (!sctx->shader.tes.cso && !sctx->shader.gs.cso) si_shader_selector_key_hw_vs(sctx, sel, key); - } break; case MESA_SHADER_TESS_CTRL: if (sctx->chip_class >= GFX9) { @@ -1938,13 +1933,8 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh key->mono.u.ff_tcs_inputs_to_copy = sctx->shader.vs.cso->outputs_written; break; case MESA_SHADER_TESS_EVAL: - key->as_ngg = sctx->ngg; - - if (sctx->shader.gs.cso) - key->as_es = 1; - else { + if (!sctx->shader.gs.cso) si_shader_selector_key_hw_vs(sctx, sel, key); - } break; case MESA_SHADER_GEOMETRY: if (sctx->chip_class >= GFX9) { @@ -1955,8 +1945,6 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh key->part.gs.es = sctx->shader.vs.cso; } - key->as_ngg = sctx->ngg; - /* Only NGG can eliminate GS outputs, because the code is shared with VS. */ if (sctx->ngg) si_shader_selector_key_hw_vs(sctx, sel, key); @@ -2439,10 +2427,9 @@ static int si_shader_select(struct pipe_context *ctx, struct si_shader_ctx_state struct si_compiler_ctx_state *compiler_state) { struct si_context *sctx = (struct si_context *)ctx; - struct si_shader_key key; - si_shader_selector_key(ctx, state->cso, &key); - return si_shader_select_with_key(sctx->screen, state, compiler_state, &key, -1, false); + si_shader_selector_key(ctx, state->cso, &state->key); + return si_shader_select_with_key(sctx->screen, state, compiler_state, &state->key, -1, false); } static void si_parse_next_shader_property(const struct si_shader_info *info, bool streamout,