[Mesa-dev] [PATCH 4/4] radeonsi: skip redundant INDEX_TYPE writes

Nicolai Hähnle nhaehnle at gmail.com
Tue Sep 6 07:36:06 UTC 2016


For the series:

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

On 06.09.2016 00:46, Marek Olšák wrote:
> 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;
>


More information about the mesa-dev mailing list