radeonsi: emit base vertex and start instance only if they change

v2: added a helper function for invalidation of the sh constants

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
Marek Olšák 2014-12-07 20:04:40 +01:00
parent b472709090
commit 3382036946
3 changed files with 38 additions and 3 deletions

View File

@ -155,4 +155,5 @@ void si_begin_new_cs(struct si_context *ctx)
r600_postflush_resume_features(&ctx->b); r600_postflush_resume_features(&ctx->b);
ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw; ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw;
si_invalidate_draw_sh_constants(ctx);
} }

View File

@ -34,6 +34,11 @@
#define SI_BIG_ENDIAN 0 #define SI_BIG_ENDIAN 0
#endif #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 0
#define SI_TRACE_CS_DWORDS 6 #define SI_TRACE_CS_DWORDS 6
@ -169,6 +174,11 @@ struct si_context {
bool db_depth_clear; bool db_depth_clear;
bool db_depth_disable_expclear; bool db_depth_disable_expclear;
unsigned ps_db_shader_control; unsigned ps_db_shader_control;
/* Draw state. */
int last_base_vertex;
int last_start_instance;
int last_sh_base_reg;
}; };
/* si_blit.c */ /* si_blit.c */
@ -227,4 +237,12 @@ si_resource_create_custom(struct pipe_screen *screen,
PIPE_BIND_CUSTOM, usage, size)); PIPE_BIND_CUSTOM, usage, size));
} }
static INLINE void
si_invalidate_draw_sh_constants(struct si_context *sctx)
{
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 */
}
#endif #endif

View File

@ -242,13 +242,29 @@ static void si_emit_draw_packets(struct si_context *sctx,
} }
if (!info->indirect) { if (!info->indirect) {
int base_vertex;
radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, 0)); radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
radeon_emit(cs, info->instance_count); radeon_emit(cs, info->instance_count);
si_write_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2); /* Base vertex and start instance. */
radeon_emit(cs, info->indexed ? info->index_bias : info->start); base_vertex = info->indexed ? info->index_bias : info->start;
radeon_emit(cs, info->start_instance);
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 { } else {
si_invalidate_draw_sh_constants(sctx);
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
(struct r600_resource *)info->indirect, (struct r600_resource *)info->indirect,
RADEON_USAGE_READ, RADEON_PRIO_MIN); RADEON_USAGE_READ, RADEON_PRIO_MIN);