From 9f505ce21d675b102cb2c89ac1ab2f03d6680b22 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 20 Feb 2019 11:42:05 -0500 Subject: [PATCH] radeonsi: disable primitive restart for triangles for DiRT Rally MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit It may decrease performance and it prevents compute-based primitive culling. Acked-by: Nicolai Hähnle --- .../radeonsi/si_compute_prim_discard.c | 26 ++++++++++++------- .../drivers/radeonsi/si_debug_options.h | 1 + src/gallium/drivers/radeonsi/si_pipe.h | 3 ++- src/gallium/drivers/radeonsi/si_state_draw.c | 9 ++++--- src/util/00-mesa-defaults.conf | 3 +++ 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_compute_prim_discard.c b/src/gallium/drivers/radeonsi/si_compute_prim_discard.c index 71253c50092..8261311f74a 100644 --- a/src/gallium/drivers/radeonsi/si_compute_prim_discard.c +++ b/src/gallium/drivers/radeonsi/si_compute_prim_discard.c @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_debug_options.h b/src/gallium/drivers/radeonsi/si_debug_options.h index 0bde7910fc6..d5fe8499bb9 100644 --- a/src/gallium/drivers/radeonsi/si_debug_options.h +++ b/src/gallium/drivers/radeonsi/si_debug_options.h @@ -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 diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 0fd3ec46755..c3a62e8f355 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -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, diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 485efcb0dff..2c571016ada 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -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; diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf index d27e8541951..3c459f3dec4 100644 --- a/src/util/00-mesa-defaults.conf +++ b/src/util/00-mesa-defaults.conf @@ -483,5 +483,8 @@ TODO: document the other workarounds. + + -- 2.30.2