From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/drivers/radeonsi/si_hw_context.c | 3 +++ src/gallium/drivers/radeonsi/si_pipe.h | 10 ++++++++++ src/gallium/drivers/radeonsi/si_state_draw.c | 24 +++++++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index f597218..5d46365 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -155,4 +155,7 @@ void si_begin_new_cs(struct si_context *ctx) r600_postflush_resume_features(&ctx->b); ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw; + ctx->last_base_vertex = SI_BASE_VERTEX_UNKNOWN; + ctx->last_start_instance = -1; /* reset to an unknown value */ + ctx->last_sh_base_reg = -1; /* reset to an unknown value */ } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 15ca9a5..cc497af 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -34,6 +34,11 @@ #define SI_BIG_ENDIAN 0 #endif +/* The base vertex can be any number, but we must pick one which + * will mean "unknown" for the purpose of state tracking and the number + * shouldn't be a commonly-used one. */ +#define SI_BASE_VERTEX_UNKNOWN INT_MIN + #define SI_TRACE_CS 0 #define SI_TRACE_CS_DWORDS 6 @@ -169,6 +174,11 @@ struct si_context { bool db_depth_clear; bool db_depth_disable_expclear; unsigned ps_db_shader_control; + + /* Draw state. */ + int last_base_vertex; + int last_start_instance; + int last_sh_base_reg; }; /* si_blit.c */ diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index a69d596..3e581ab 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -242,13 +242,31 @@ static void si_emit_draw_packets(struct si_context *sctx, } if (!info->indirect) { + int base_vertex; + radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, 0)); radeon_emit(cs, info->instance_count); - si_write_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2); - radeon_emit(cs, info->indexed ? info->index_bias : info->start); - radeon_emit(cs, info->start_instance); + /* Base vertex and start instance. */ + base_vertex = info->indexed ? info->index_bias : info->start; + + if (base_vertex != sctx->last_base_vertex || + sctx->last_base_vertex == SI_BASE_VERTEX_UNKNOWN || + info->start_instance != sctx->last_start_instance || + sh_base_reg != sctx->last_sh_base_reg) { + si_write_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2); + radeon_emit(cs, base_vertex); + radeon_emit(cs, info->start_instance); + + sctx->last_base_vertex = base_vertex; + sctx->last_start_instance = info->start_instance; + sctx->last_sh_base_reg = sh_base_reg; + } } else { + sctx->last_base_vertex = SI_BASE_VERTEX_UNKNOWN; + sctx->last_start_instance = -1; /* reset to an unknown value */ + sctx->last_sh_base_reg = -1; /* reset to an unknown value */ + r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, (struct r600_resource *)info->indirect, RADEON_USAGE_READ, RADEON_PRIO_MIN); -- 2.1.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev