For the series: Reviewed-by: Nicolai Hähnle <nicolai.haeh...@amd.com>
On 06.09.2016 00:46, Marek Olšák wrote:
From: Marek Olšák <marek.ol...@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;
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev