radeonsi: disable primitive restart for triangles for DiRT Rally
authorMarek Olšák <marek.olsak@amd.com>
Wed, 20 Feb 2019 16:42:05 +0000 (11:42 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 16 May 2019 17:13:36 +0000 (13:13 -0400)
It may decrease performance and it prevents compute-based primitive culling.

Acked-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_compute_prim_discard.c
src/gallium/drivers/radeonsi/si_debug_options.h
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state_draw.c
src/util/00-mesa-defaults.conf

index 71253c50092380ece1e30ecf8641bb3126bcb343..8261311f74a26724eb11b3b7593f1bc8086ff91d 100644 (file)
@@ -876,14 +876,15 @@ void si_build_prim_discard_compute_shader(struct si_shader_context *ctx)
 
 /* Return false if the shader isn't ready. */
 static bool si_shader_select_prim_discard_cs(struct si_context *sctx,
-                                            const struct pipe_draw_info *info)
+                                            const struct pipe_draw_info *info,
+                                            bool primitive_restart)
 {
        struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
        struct si_shader_key key;
 
        /* Primitive restart needs ordered counters. */
-       assert(!info->primitive_restart || VERTEX_COUNTER_GDS_MODE == 2);
-       assert(!info->primitive_restart || info->instance_count == 1);
+       assert(!primitive_restart || VERTEX_COUNTER_GDS_MODE == 2);
+       assert(!primitive_restart || info->instance_count == 1);
 
        memset(&key, 0, sizeof(key));
        si_shader_selector_key_vs(sctx, sctx->vs_shader.cso, &key, &key.part.vs.prolog);
@@ -894,13 +895,13 @@ static bool si_shader_select_prim_discard_cs(struct si_context *sctx,
        key.opt.cs_prim_type = info->mode;
        key.opt.cs_indexed = info->index_size != 0;
        key.opt.cs_instancing = info->instance_count > 1;
-       key.opt.cs_primitive_restart = info->primitive_restart;
+       key.opt.cs_primitive_restart = primitive_restart;
        key.opt.cs_provoking_vertex_first = rs->provoking_vertex_first;
 
        /* Primitive restart with triangle strips needs to preserve primitive
         * orientation for cases where front and back primitive orientation matters.
         */
-       if (info->primitive_restart) {
+       if (primitive_restart) {
                struct si_shader_selector *ps = sctx->ps_shader.cso;
 
                key.opt.cs_need_correct_orientation =
@@ -1000,10 +1001,11 @@ static bool si_check_ring_space(struct si_context *sctx, unsigned out_indexbuf_s
 
 enum si_prim_discard_outcome
 si_prepare_prim_discard_or_split_draw(struct si_context *sctx,
-                                     const struct pipe_draw_info *info)
+                                     const struct pipe_draw_info *info,
+                                     bool primitive_restart)
 {
        /* If the compute shader compilation isn't finished, this returns false. */
-       if (!si_shader_select_prim_discard_cs(sctx, info))
+       if (!si_shader_select_prim_discard_cs(sctx, info, primitive_restart))
                return SI_PRIM_DISCARD_DISABLED;
 
        if (!si_initialize_prim_discard_cmdbuf(sctx))
@@ -1029,6 +1031,8 @@ si_prepare_prim_discard_or_split_draw(struct si_context *sctx,
                           (1 << PIPE_PRIM_TRIANGLE_STRIP))) {
                /* Split draws. */
                struct pipe_draw_info split_draw = *info;
+               split_draw.primitive_restart = primitive_restart;
+
                unsigned base_start = split_draw.start;
 
                if (prim == PIPE_PRIM_TRIANGLES) {
@@ -1055,7 +1059,7 @@ si_prepare_prim_discard_or_split_draw(struct si_context *sctx,
                                sctx->b.draw_vbo(&sctx->b, &split_draw);
 
                                if (start == 0 &&
-                                   split_draw.primitive_restart &&
+                                   primitive_restart &&
                                    sctx->cs_prim_discard_state.current->key.opt.cs_need_correct_orientation)
                                        sctx->preserve_prim_restart_gds_at_flush = true;
                        }
@@ -1362,9 +1366,11 @@ void si_dispatch_prim_discard_cs_and_draw(struct si_context *sctx,
 
        si_resource_reference(&indexbuf_desc, NULL);
 
+       bool primitive_restart = sctx->cs_prim_discard_state.current->key.opt.cs_primitive_restart;
+
        if (VERTEX_COUNTER_GDS_MODE == 1) {
                gds_offset = sctx->compute_gds_offset;
-               gds_size = info->primitive_restart ? 8 : 4;
+               gds_size = primitive_restart ? 8 : 4;
                sctx->compute_gds_offset += gds_size;
 
                /* Reset the counters in GDS for the first dispatch using WRITE_DATA.
@@ -1476,7 +1482,7 @@ void si_dispatch_prim_discard_cs_and_draw(struct si_context *sctx,
                        uint32_t gds_prim_restart_continue_bit = 0;
 
                        if (sctx->preserve_prim_restart_gds_at_flush) {
-                               assert(info->primitive_restart &&
+                               assert(primitive_restart &&
                                       info->mode == PIPE_PRIM_TRIANGLE_STRIP);
                                assert(start_prim < 1 << 31);
                                gds_prim_restart_continue_bit = 1 << 31;
index 0bde7910fc6f3d3573683ae3973a848703eca646..d5fe8499bb9b9233cf8200ce6bfcc26a43b11a93 100644 (file)
@@ -3,5 +3,6 @@ OPT_BOOL(enable_nir, false, "Enable NIR")
 OPT_BOOL(aux_debug, false, "Generate ddebug_dumps for the auxiliary context")
 OPT_BOOL(sync_compile, false, "Always compile synchronously (will cause stalls)")
 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")
 
 #undef OPT_BOOL
index 0fd3ec4675591a061d7660ea64be9352167c90c4..c3a62e8f355c2edd79bc61f8c5f4b895564b415f 100644 (file)
@@ -1360,7 +1360,8 @@ enum si_prim_discard_outcome {
 void si_build_prim_discard_compute_shader(struct si_shader_context *ctx);
 enum si_prim_discard_outcome
 si_prepare_prim_discard_or_split_draw(struct si_context *sctx,
-                                     const struct pipe_draw_info *info);
+                                     const struct pipe_draw_info *info,
+                                     bool primitive_restart);
 void si_compute_signal_gfx(struct si_context *sctx);
 void si_dispatch_prim_discard_cs_and_draw(struct si_context *sctx,
                                          const struct pipe_draw_info *info,
index 485efcb0dffee0f055d26a50187eb58416e490e1..2c571016ada54e11f35286fbf5d88311b58ca0b8 100644 (file)
@@ -1414,7 +1414,10 @@ static void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *i
        unsigned index_size = info->index_size;
        unsigned index_offset = info->indirect ? info->start * index_size : 0;
        unsigned instance_count = info->instance_count;
-       bool primitive_restart = info->primitive_restart;
+       bool primitive_restart = info->primitive_restart &&
+                                (!sctx->screen->options.prim_restart_tri_strips_only ||
+                                 (prim != PIPE_PRIM_TRIANGLE_STRIP &&
+                                  prim != PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY));
 
        if (likely(!info->indirect)) {
                /* GFX6-GFX7 treat instance_count==0 as instance_count==1. There is
@@ -1506,7 +1509,7 @@ static void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *i
                bool gs_tri_strip_adj_fix =
                        !sctx->tes_shader.cso &&
                        prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY &&
-                       !info->primitive_restart;
+                       !primitive_restart;
 
                if (gs_tri_strip_adj_fix != sctx->gs_tri_strip_adj_fix) {
                        sctx->gs_tri_strip_adj_fix = gs_tri_strip_adj_fix;
@@ -1640,7 +1643,7 @@ static void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *i
            /* Check that all buffers are used for read only, because compute
             * dispatches can run ahead. */
            (si_all_vs_resources_read_only(sctx, index_size ? indexbuf : NULL) || pd_msg("write reference"))) {
-               switch (si_prepare_prim_discard_or_split_draw(sctx, info)) {
+               switch (si_prepare_prim_discard_or_split_draw(sctx, info, primitive_restart)) {
                case SI_PRIM_DISCARD_ENABLED:
                        original_index_size = index_size;
                        prim_discard_cs_instancing = instance_count > 1;
index d27e8541951ae6f56d4c10015068a95f0aaee137..3c459f3dec4c22b37576dda07c616f6fa78aac14 100644 (file)
@@ -483,5 +483,8 @@ TODO: document the other workarounds.
         <application name="Civilization 6" executable="Civ6Sub">
             <option name="radeonsi_enable_nir" value="true"/>
         </application>
+        <application name="DiRT Rally" executable="DirtRally">
+            <option name="radeonsi_prim_restart_tri_strips_only" value="true"/>
+        </application>
     </device>
   </driconf>