Re: [Mesa-dev] [PATCH 5/5] radeonsi: calculate optimal GS ring sizes to fix GS hangs on Tonga
On 09.11.2015 07:00, Marek Olšák wrote: > From: Marek Olšák> > I discovered that increasing the ESGS ring size fixes GS hangs on Tonga, > so let's do it properly. > > There is now a separate init_config_gs_rings state that is not immutable, > because GS rings are resized when needed. > > This also saves some memory. Most apps won't need more than 1MB > per ring per shader engine. [...] > - /* Flush the context to re-emit the init_config state. > - * This is done only once in a lifetime of a context. > - */ > - si_pm4_upload_indirect_buffer(sctx, sctx->init_config); > + /* Set the state. */ > + if (sctx->init_config_gs_rings) > + si_pm4_free_state(sctx, sctx->init_config_gs_rings, ~0); > + sctx->init_config_gs_rings = pm4; > + > + if (!sctx->init_config_has_vgt_flush) { > + si_init_config_add_vgt_flush(sctx); > + si_pm4_upload_indirect_buffer(sctx, sctx->init_config); > + } > + > + /* Flush the context to re-emit the state. */ > sctx->b.initial_gfx_cs_size = 0; /* force flush */ > si_context_gfx_flush(sctx, RADEON_FLUSH_ASYNC, NULL); Maybe the comment should still say "re-emit the init_config state". Either way, Reviewed-by: Michel Dänzer -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Mesa and X developer ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 5/5] radeonsi: calculate optimal GS ring sizes to fix GS hangs on Tonga
On 08.11.2015 23:00, Marek Olšák wrote: From: Marek OlšákI discovered that increasing the ESGS ring size fixes GS hangs on Tonga, so let's do it properly. There is now a separate init_config_gs_rings state that is not immutable, because GS rings are resized when needed. This also saves some memory. Most apps won't need more than 1MB per ring per shader engine. --- src/gallium/drivers/radeonsi/si_hw_context.c| 2 + src/gallium/drivers/radeonsi/si_pipe.c | 2 + src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_shader.h| 1 + src/gallium/drivers/radeonsi/si_state_shaders.c | 153 5 files changed, 112 insertions(+), 47 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index f28c11c..baa0229 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -165,6 +165,8 @@ void si_begin_new_cs(struct si_context *ctx) /* The CS initialization should be emitted before everything else. */ si_pm4_emit(ctx, ctx->init_config); + if (ctx->init_config_gs_rings) + si_pm4_emit(ctx, ctx->init_config_gs_rings); ctx->framebuffer.dirty_cbufs = (1 << 8) - 1; ctx->framebuffer.dirty_zsbuf = true; diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 2b9784f..1cbee8d 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -50,6 +50,8 @@ static void si_destroy_context(struct pipe_context *context) sctx->b.ws->fence_reference(>last_gfx_fence, NULL); si_pm4_free_state(sctx, sctx->init_config, ~0); + if (sctx->init_config_gs_rings) + si_pm4_free_state(sctx, sctx->init_config_gs_rings, ~0); for (i = 0; i < Elements(sctx->vgt_shader_config); i++) si_pm4_delete_state(sctx, vgt_shader_config, sctx->vgt_shader_config[i]); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 6e742fc..05d52fe 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -202,6 +202,7 @@ struct si_context { /* Precomputed states. */ struct si_pm4_state *init_config; + struct si_pm4_state *init_config_gs_rings; boolinit_config_has_vgt_flush; struct si_pm4_state *vgt_shader_config[4]; diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 1f4f0de..3400a03 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -202,6 +202,7 @@ struct si_shader_selector { boolforces_persample_interp_for_linear; unsignedesgs_itemsize; + unsignedgs_input_verts_per_prim; unsignedgs_output_prim; unsignedgs_max_out_vertices; unsignedgs_num_invocations; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index c402ce2..b543971 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -33,6 +33,7 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_ureg.h" #include "util/u_memory.h" +#include "util/u_prim.h" #include "util/u_simple_shaders.h" static void si_set_tesseval_regs(struct si_shader *shader, @@ -703,6 +704,9 @@ static void *si_create_shader_selector(struct pipe_context *ctx, for (i = 0; i < sel->so.num_outputs; i++) sel->max_gs_stream = MAX2(sel->max_gs_stream, sel->so.output[i].stream); + + sel->gs_input_verts_per_prim = + u_vertices_per_prim(sel->info.properties[TGSI_PROPERTY_GS_INPUT_PRIM]); break; case PIPE_SHADER_VERTEX: @@ -1054,6 +1058,7 @@ static void si_init_config_add_vgt_flush(struct si_context *sctx) if (sctx->init_config_has_vgt_flush) return; + /* VGT_FLUSH is required even if VGT is idle. It resets VGT pointers. */ si_pm4_cmd_begin(sctx->init_config, PKT3_EVENT_WRITE); si_pm4_cmd_add(sctx->init_config, EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0)); si_pm4_cmd_end(sctx->init_config, false); @@ -1061,62 +1066,119 @@ static void si_init_config_add_vgt_flush(struct si_context *sctx) } /* Initialize state related to ESGS / GSVS ring buffers */ -static void si_init_gs_rings(struct si_context *sctx) +static bool si_update_gs_ring_buffers(struct si_context *sctx) { - unsigned esgs_ring_size = 128 * 1024; - unsigned gsvs_ring_size = 60 * 1024 * 1024; + struct si_shader_selector *es = +
[Mesa-dev] [PATCH 5/5] radeonsi: calculate optimal GS ring sizes to fix GS hangs on Tonga
From: Marek OlšákI discovered that increasing the ESGS ring size fixes GS hangs on Tonga, so let's do it properly. There is now a separate init_config_gs_rings state that is not immutable, because GS rings are resized when needed. This also saves some memory. Most apps won't need more than 1MB per ring per shader engine. --- src/gallium/drivers/radeonsi/si_hw_context.c| 2 + src/gallium/drivers/radeonsi/si_pipe.c | 2 + src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_shader.h| 1 + src/gallium/drivers/radeonsi/si_state_shaders.c | 153 5 files changed, 112 insertions(+), 47 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index f28c11c..baa0229 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -165,6 +165,8 @@ void si_begin_new_cs(struct si_context *ctx) /* The CS initialization should be emitted before everything else. */ si_pm4_emit(ctx, ctx->init_config); + if (ctx->init_config_gs_rings) + si_pm4_emit(ctx, ctx->init_config_gs_rings); ctx->framebuffer.dirty_cbufs = (1 << 8) - 1; ctx->framebuffer.dirty_zsbuf = true; diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 2b9784f..1cbee8d 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -50,6 +50,8 @@ static void si_destroy_context(struct pipe_context *context) sctx->b.ws->fence_reference(>last_gfx_fence, NULL); si_pm4_free_state(sctx, sctx->init_config, ~0); + if (sctx->init_config_gs_rings) + si_pm4_free_state(sctx, sctx->init_config_gs_rings, ~0); for (i = 0; i < Elements(sctx->vgt_shader_config); i++) si_pm4_delete_state(sctx, vgt_shader_config, sctx->vgt_shader_config[i]); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 6e742fc..05d52fe 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -202,6 +202,7 @@ struct si_context { /* Precomputed states. */ struct si_pm4_state *init_config; + struct si_pm4_state *init_config_gs_rings; boolinit_config_has_vgt_flush; struct si_pm4_state *vgt_shader_config[4]; diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 1f4f0de..3400a03 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -202,6 +202,7 @@ struct si_shader_selector { boolforces_persample_interp_for_linear; unsignedesgs_itemsize; + unsignedgs_input_verts_per_prim; unsignedgs_output_prim; unsignedgs_max_out_vertices; unsignedgs_num_invocations; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index c402ce2..b543971 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -33,6 +33,7 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_ureg.h" #include "util/u_memory.h" +#include "util/u_prim.h" #include "util/u_simple_shaders.h" static void si_set_tesseval_regs(struct si_shader *shader, @@ -703,6 +704,9 @@ static void *si_create_shader_selector(struct pipe_context *ctx, for (i = 0; i < sel->so.num_outputs; i++) sel->max_gs_stream = MAX2(sel->max_gs_stream, sel->so.output[i].stream); + + sel->gs_input_verts_per_prim = + u_vertices_per_prim(sel->info.properties[TGSI_PROPERTY_GS_INPUT_PRIM]); break; case PIPE_SHADER_VERTEX: @@ -1054,6 +1058,7 @@ static void si_init_config_add_vgt_flush(struct si_context *sctx) if (sctx->init_config_has_vgt_flush) return; + /* VGT_FLUSH is required even if VGT is idle. It resets VGT pointers. */ si_pm4_cmd_begin(sctx->init_config, PKT3_EVENT_WRITE); si_pm4_cmd_add(sctx->init_config, EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0)); si_pm4_cmd_end(sctx->init_config, false); @@ -1061,62 +1066,119 @@ static void si_init_config_add_vgt_flush(struct si_context *sctx) } /* Initialize state related to ESGS / GSVS ring buffers */ -static void si_init_gs_rings(struct si_context *sctx) +static bool si_update_gs_ring_buffers(struct si_context *sctx) { - unsigned esgs_ring_size = 128 * 1024; - unsigned gsvs_ring_size = 60 * 1024 * 1024; + struct si_shader_selector *es = + sctx->tes_shader.cso ?