radeonsi/gfx10: keep track of whether NGG is used
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Tue, 7 May 2019 21:00:43 +0000 (23:00 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 3 Jul 2019 19:51:12 +0000 (15:51 -0400)
We always use NGG by default, except when tessellation is enabled with
extreme geometry shader amplification.

Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/gallium/drivers/radeonsi/si_debug_options.h
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index d6cb315763250328e332e739957fe0fdf29d9a05..9fdb0bc5dadaa6e41d7225ac01acbaeff55dc458 100644 (file)
@@ -7,5 +7,6 @@ OPT_BOOL(debug_disassembly, false, "Report shader disassembly as part of driver
 OPT_BOOL(halt_shaders, false, "Halt shaders at the start (will hang)")
 OPT_BOOL(vs_fetch_always_opencode, false, "Always open code vertex fetches (less efficient, purely for testing)")
 OPT_BOOL(prim_restart_tri_strips_only, false, "Only enable primitive restart for triangle strips")
+OPT_BOOL(disable_ngg, false, "Unconditionally disable NGG (gfx10+)")
 
 #undef OPT_BOOL
index a290d16b02d3aaffdb11dce1c0c70dc9ff561307..9ea08c8fb260b6c9a1509d01694c476cc0c6d764 100644 (file)
@@ -486,6 +486,9 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen,
        if (!sctx->border_color_map)
                goto fail;
 
+       if (sctx->chip_class >= GFX10)
+               sctx->ngg = !sscreen->options.disable_ngg;
+
        /* Initialize context functions used by graphics and compute. */
        if (sctx->chip_class >= GFX10)
                sctx->emit_cache_flush = gfx10_emit_cache_flush;
index 588de59e0cd2c85b7d982eeeaf3ef8247a912c97..d7edc7be9ae1639cd879b9f021fff6dc139f0f13 100644 (file)
@@ -1041,6 +1041,7 @@ struct si_context {
        bool                    gs_tri_strip_adj_fix:1;
        bool                    ls_vgpr_fix:1;
        bool                    prim_discard_cs_instancing:1;
+       bool                    ngg:1;
        int                     last_index_size;
        int                     last_base_vertex;
        int                     last_start_instance;
index 7a82126a0adbf2a5f9aed5ee6cd6ea07af0c6832..a55a6d139d4c845682189c1177f2b72d79741f36 100644 (file)
@@ -2588,6 +2588,27 @@ static void si_update_tess_uses_prim_id(struct si_context *sctx)
                 sctx->ps_shader.cso->info.uses_primid);
 }
 
+static bool si_update_ngg(struct si_context *sctx)
+{
+       if (sctx->chip_class <= GFX9 ||
+           sctx->screen->options.disable_ngg)
+               return false;
+
+       bool new_ngg = true;
+
+       /* EN_MAX_VERT_OUT_PER_GS_INSTANCE does not work with tesselation. */
+       if (sctx->gs_shader.cso && sctx->tes_shader.cso &&
+           sctx->gs_shader.cso->gs_num_invocations * sctx->gs_shader.cso->gs_max_out_vertices > 256)
+               new_ngg = false;
+
+       if (new_ngg != sctx->ngg) {
+               sctx->ngg = new_ngg;
+               sctx->last_rast_prim = -1; /* reset this so that it gets updated */
+               return true;
+       }
+       return false;
+}
+
 static void si_bind_gs_shader(struct pipe_context *ctx, void *state)
 {
        struct si_context *sctx = (struct si_context *)ctx;
@@ -2595,6 +2616,7 @@ static void si_bind_gs_shader(struct pipe_context *ctx, void *state)
        struct si_shader *old_hw_vs_variant = si_get_vs_state(sctx);
        struct si_shader_selector *sel = state;
        bool enable_changed = !!sctx->gs_shader.cso != !!sel;
+       bool ngg_changed;
 
        if (sctx->gs_shader.cso == sel)
                return;
@@ -2606,8 +2628,10 @@ static void si_bind_gs_shader(struct pipe_context *ctx, void *state)
        si_update_common_shader_state(sctx);
        sctx->last_rast_prim = -1; /* reset this so that it gets updated */
 
-       if (enable_changed) {
+       ngg_changed = si_update_ngg(sctx);
+       if (ngg_changed || enable_changed)
                si_shader_change_notify(sctx);
+       if (enable_changed) {
                if (sctx->ia_multi_vgt_param_key.u.uses_tess)
                        si_update_tess_uses_prim_id(sctx);
        }
@@ -2659,6 +2683,7 @@ static void si_bind_tes_shader(struct pipe_context *ctx, void *state)
        sctx->last_rast_prim = -1; /* reset this so that it gets updated */
 
        if (enable_changed) {
+               si_update_ngg(sctx);
                si_shader_change_notify(sctx);
                sctx->last_tes_sh_base = -1; /* invalidate derived tess state */
        }