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 <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12656>
This commit is contained in:
Marek Olšák 2021-08-10 00:55:52 -04:00 committed by Marge Bot
parent 5a8a716168
commit c005b2cd4b
5 changed files with 44 additions and 23 deletions

View File

@ -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 { \

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -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,