struct si_shader *main_shader_part;
struct si_shader *main_shader_part_ls; /* as_ls is set in the key */
struct si_shader *main_shader_part_es; /* as_es is set in the key */
+ struct si_shader *main_shader_part_ngg; /* as_ngg is set in the key */
struct si_shader *gs_copy_shader;
unsigned last_input:4;
unsigned as_ls:1;
unsigned as_es:1;
+ unsigned as_ngg:1;
/* Prologs for monolithic shaders shouldn't set EXEC. */
unsigned is_monolithic:1;
} vs_prolog;
} ps;
} part;
- /* These two are initially set according to the NEXT_SHADER property,
+ /* 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 */
/* Flags for monolithic compilation only. */
struct {
return &sel->main_shader_part_ls;
if (key->as_es)
return &sel->main_shader_part_es;
+ if (key->as_ngg)
+ return &sel->main_shader_part_ngg;
return &sel->main_shader_part;
}
/* Compute the key for the hw shader variant */
static inline void si_shader_selector_key(struct pipe_context *ctx,
struct si_shader_selector *sel,
+ union si_vgt_stages_key stages_key,
struct si_shader_key *key)
{
struct si_context *sctx = (struct si_context *)ctx;
else if (sctx->gs_shader.cso)
key->as_es = 1;
else {
+ key->as_ngg = stages_key.u.ngg;
si_shader_selector_key_hw_vs(sctx, sel, key);
if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid)
if (sctx->gs_shader.cso)
key->as_es = 1;
else {
+ key->as_ngg = stages_key.u.ngg;
si_shader_selector_key_hw_vs(sctx, sel, key);
if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid)
key->part.gs.prolog.gfx9_prev_is_vs = 1;
}
+ key->as_ngg = stages_key.u.ngg;
+
/* Merged ES-GS can have unbalanced wave usage.
*
* ES threads are per-vertex, while GS threads are
main_part->selector = sel;
main_part->key.as_es = key->as_es;
main_part->key.as_ls = key->as_ls;
+ main_part->key.as_ngg = key->as_ngg;
main_part->is_monolithic = false;
if (si_compile_tgsi_shader(sscreen, compiler_state->compiler,
*/
if (!is_pure_monolithic &&
!key->opt.vs_as_prim_discard_cs) {
- bool ok;
+ bool ok = true;
/* Make sure the main shader part is present. This is needed
* for shaders that can be compiled as VS, LS, or ES, and only
* one of them is compiled at creation.
*
+ * It is also needed for GS, which can be compiled as non-NGG
+ * and NGG.
+ *
* For merged shaders, check that the starting shader's main
* part is present.
*/
previous_stage_sel,
compiler_state, &shader1_key);
mtx_unlock(&previous_stage_sel->mutex);
- } else {
+ }
+
+ if (ok) {
ok = si_check_missing_main_part(sscreen, sel,
compiler_state, key);
}
+
if (!ok) {
FREE(shader);
mtx_unlock(&sel->mutex);
static int si_shader_select(struct pipe_context *ctx,
struct si_shader_ctx_state *state,
+ union si_vgt_stages_key stages_key,
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);
+ si_shader_selector_key(ctx, state->cso, stages_key, &key);
return si_shader_select_with_key(sctx->screen, state, compiler_state,
&key, -1, false);
}
si_parse_next_shader_property(&sel->info,
sel->so.num_outputs != 0,
&shader->key);
+ if (sscreen->info.chip_class >= GFX10 &&
+ !sscreen->options.disable_ngg &&
+ (((sel->type == PIPE_SHADER_VERTEX ||
+ sel->type == PIPE_SHADER_TESS_EVAL) &&
+ !shader->key.as_ls && !shader->key.as_es) ||
+ sel->type == PIPE_SHADER_GEOMETRY))
+ shader->key.as_ngg = 1;
if (sel->tokens || sel->nir)
ir_binary = si_get_ir_binary(sel);
si_delete_shader(sctx, sel->main_shader_part_ls);
if (sel->main_shader_part_es)
si_delete_shader(sctx, sel->main_shader_part_es);
+ if (sel->main_shader_part_ngg)
+ si_delete_shader(sctx, sel->main_shader_part_ngg);
if (sel->gs_copy_shader)
si_delete_shader(sctx, sel->gs_copy_shader);
}
if (sctx->tcs_shader.cso) {
- r = si_shader_select(ctx, &sctx->tcs_shader,
+ r = si_shader_select(ctx, &sctx->tcs_shader, key,
&compiler_state);
if (r)
return false;
}
r = si_shader_select(ctx, &sctx->fixed_func_tcs_shader,
- &compiler_state);
+ key, &compiler_state);
if (r)
return false;
si_pm4_bind_state(sctx, hs,
}
if (!sctx->gs_shader.cso || sctx->chip_class <= GFX8) {
- r = si_shader_select(ctx, &sctx->tes_shader, &compiler_state);
+ r = si_shader_select(ctx, &sctx->tes_shader, key, &compiler_state);
if (r)
return false;
/* Update GS. */
if (sctx->gs_shader.cso) {
- r = si_shader_select(ctx, &sctx->gs_shader, &compiler_state);
+ r = si_shader_select(ctx, &sctx->gs_shader, key, &compiler_state);
if (r)
return false;
si_pm4_bind_state(sctx, gs, sctx->gs_shader.current->pm4);
/* Update VS. */
if ((!key.u.tess && !key.u.gs) || sctx->chip_class <= GFX8) {
- r = si_shader_select(ctx, &sctx->vs_shader, &compiler_state);
+ r = si_shader_select(ctx, &sctx->vs_shader, key, &compiler_state);
if (r)
return false;
if (sctx->ps_shader.cso) {
unsigned db_shader_control;
- r = si_shader_select(ctx, &sctx->ps_shader, &compiler_state);
+ r = si_shader_select(ctx, &sctx->ps_shader, key, &compiler_state);
if (r)
return false;
si_pm4_bind_state(sctx, ps, sctx->ps_shader.current->pm4);