[Mesa-dev] [PATCH 4/4] radeonsi: skip redundant INDEX_TYPE writes
Marek Olšák
maraeo at gmail.com
Mon Sep 5 22:46:34 UTC 2016
From: Marek Olšák <marek.olsak at amd.com>
Ported from Vulkan.
---
src/gallium/drivers/radeonsi/si_hw_context.c | 1 +
src/gallium/drivers/radeonsi/si_pipe.h | 1 +
src/gallium/drivers/radeonsi/si_state_draw.c | 50 +++++++++++++++++-----------
3 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c
index a03b327..24b0360 100644
--- a/src/gallium/drivers/radeonsi/si_hw_context.c
+++ b/src/gallium/drivers/radeonsi/si_hw_context.c
@@ -218,20 +218,21 @@ void si_begin_new_cs(struct si_context *ctx)
si_mark_atom_dirty(ctx, &ctx->b.viewports.atom);
r600_postflush_resume_features(&ctx->b);
assert(!ctx->b.gfx.cs->prev_dw);
ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->current.cdw;
/* Invalidate various draw states so that they are emitted before
* the first draw call. */
si_invalidate_draw_sh_constants(ctx);
+ ctx->last_index_size = -1;
ctx->last_primitive_restart_en = -1;
ctx->last_restart_index = SI_RESTART_INDEX_UNKNOWN;
ctx->last_gs_out_prim = -1;
ctx->last_prim = -1;
ctx->last_multi_vgt_param = -1;
ctx->last_ls_hs_config = -1;
ctx->last_rast_prim = -1;
ctx->last_sc_line_stipple = ~0;
ctx->last_vtx_reuse_depth = -1;
ctx->emit_scratch_reloc = true;
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 5c041ce..a648d86 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -300,20 +300,21 @@ struct si_context {
bool db_flush_depth_inplace;
bool db_flush_stencil_inplace;
bool db_depth_clear;
bool db_depth_disable_expclear;
bool db_stencil_clear;
bool db_stencil_disable_expclear;
unsigned ps_db_shader_control;
bool occlusion_queries_disabled;
/* Emitted draw state. */
+ int last_index_size;
int last_base_vertex;
int last_start_instance;
int last_drawid;
int last_sh_base_reg;
int last_primitive_restart_en;
int last_restart_index;
int last_gs_out_prim;
int last_prim;
int last_multi_vgt_param;
int last_ls_hs_config;
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index d4447a9..d7325ff 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -546,49 +546,59 @@ static void si_emit_draw_packets(struct si_context *sctx,
radeon_emit(cs, R_028B2C_VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE >> 2);
radeon_emit(cs, 0); /* unused */
radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
t->buf_filled_size, RADEON_USAGE_READ,
RADEON_PRIO_SO_FILLED_SIZE);
}
/* draw packet */
if (info->indexed) {
- radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0));
-
- /* index type */
- switch (ib->index_size) {
- case 1:
- radeon_emit(cs, V_028A7C_VGT_INDEX_8);
- break;
- case 2:
- radeon_emit(cs, V_028A7C_VGT_INDEX_16 |
- (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
- V_028A7C_VGT_DMA_SWAP_16_BIT : 0));
- break;
- case 4:
- radeon_emit(cs, V_028A7C_VGT_INDEX_32 |
- (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
- V_028A7C_VGT_DMA_SWAP_32_BIT : 0));
- break;
- default:
- assert(!"unreachable");
- return;
+ if (ib->index_size != sctx->last_index_size) {
+ radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0));
+
+ /* index type */
+ switch (ib->index_size) {
+ case 1:
+ radeon_emit(cs, V_028A7C_VGT_INDEX_8);
+ break;
+ case 2:
+ radeon_emit(cs, V_028A7C_VGT_INDEX_16 |
+ (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
+ V_028A7C_VGT_DMA_SWAP_16_BIT : 0));
+ break;
+ case 4:
+ radeon_emit(cs, V_028A7C_VGT_INDEX_32 |
+ (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
+ V_028A7C_VGT_DMA_SWAP_32_BIT : 0));
+ break;
+ default:
+ assert(!"unreachable");
+ return;
+ }
+
+ sctx->last_index_size = ib->index_size;
}
index_max_size = (ib->buffer->width0 - ib->offset) /
ib->index_size;
index_va = r600_resource(ib->buffer)->gpu_address + ib->offset;
radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
(struct r600_resource *)ib->buffer,
RADEON_USAGE_READ, RADEON_PRIO_INDEX_BUFFER);
+ } else {
+ /* On CI and later, non-indexed draws overwrite VGT_INDEX_TYPE,
+ * so the state must be re-emitted before the next indexed draw.
+ */
+ if (sctx->b.chip_class >= CIK)
+ sctx->last_index_size = -1;
}
if (!info->indirect) {
int base_vertex;
radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
radeon_emit(cs, info->instance_count);
/* Base vertex and start instance. */
base_vertex = info->indexed ? info->index_bias : info->start;
--
2.7.4
More information about the mesa-dev
mailing list