diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index a03b3275d04..24b03604890 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -225,6 +225,7 @@ void si_begin_new_cs(struct si_context *ctx) /* 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; diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 5c041ce88b6..a648d868225 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -307,6 +307,7 @@ struct si_context { bool occlusion_queries_disabled; /* Emitted draw state. */ + int last_index_size; int last_base_vertex; int last_start_instance; int last_drawid; diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index d4447a975fe..d7325ff37d2 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -553,26 +553,30 @@ static void si_emit_draw_packets(struct si_context *sctx, /* draw packet */ if (info->indexed) { - radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0)); + 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; + /* 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) / @@ -582,6 +586,12 @@ static void si_emit_draw_packets(struct si_context *sctx, 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) {