[Mesa-dev] [PATCH] radeonsi: add basic glClearBufferSubData acceleration

Nicolai Hähnle nhaehnle at gmail.com
Thu Nov 5 10:58:20 PST 2015


On 04.11.2015 00:47, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> ---
>   src/gallium/drivers/radeonsi/si_blit.c | 55 ++++++++++++++++++++++++++++++++++
>   1 file changed, 55 insertions(+)
>
> diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
> index fce014a..e934146 100644
> --- a/src/gallium/drivers/radeonsi/si_blit.c
> +++ b/src/gallium/drivers/radeonsi/si_blit.c
> @@ -731,9 +731,64 @@ static void si_flush_resource(struct pipe_context *ctx,
>   	}
>   }
>
> +static void si_pipe_clear_buffer(struct pipe_context *ctx,
> +				 struct pipe_resource *dst,
> +				 unsigned offset, unsigned size,
> +				 const void *clear_value,
> +				 int clear_value_size)
> +{
> +	struct si_context *sctx = (struct si_context*)ctx;
> +	const uint32_t *u32 = clear_value;
> +	unsigned i;
> +	bool clear_value_fits_dword = true;
> +	uint8_t *map;
> +
> +	if (clear_value_size > 4)
> +		for (i = 1; i < clear_value_size / 4; i++)
> +			if (u32[0] != u32[i]) {
> +				clear_value_fits_dword = false;
> +				break;
> +			}
> +
> +	/* Use CP DMA for the simple case. */
> +	if (offset % 4 == 0 && size % 4 == 0 && clear_value_fits_dword) {
> +		uint32_t value = u32[0];
> +
> +		switch (clear_value_size) {
> +		case 1:
> +			value &= 0xff;
> +			value |= (value << 8) | (value << 16) | (value << 24);
> +			break;
> +		case 2:
> +			value &= 0xffff;
> +			value |= value << 16;
> +			break;
> +		}

To reduce the chance of complaints by valgrind et al:

switch (clear_value_size) {
case 1:
	value = *(uint8_t *)u32;
	value |= (value << 8) | (value << 16) | (value << 24);
	break;
case 2:
	value = *(uint16_t *)u32;
	value |= value << 16;
	break;
default:
	value = *u32;
	break;
}

Cheers,
Nicolai

> +
> +		sctx->b.clear_buffer(ctx, dst, offset, size, value, false);
> +		return;
> +	}
> +
> +	/* TODO: use a compute shader for other cases. */
> +
> +	/* Software fallback. */
> +	map = r600_buffer_map_sync_with_rings(&sctx->b, r600_resource(dst),
> +					      PIPE_TRANSFER_WRITE);
> +	if (!map)
> +		return;
> +
> +	map += offset;
> +	size /= clear_value_size;
> +	for (i = 0; i < size; i++) {
> +		memcpy(map, clear_value, clear_value_size);
> +		map += clear_value_size;
> +	}
> +}
> +
>   void si_init_blit_functions(struct si_context *sctx)
>   {
>   	sctx->b.b.clear = si_clear;
> +	sctx->b.b.clear_buffer = si_pipe_clear_buffer;
>   	sctx->b.b.clear_render_target = si_clear_render_target;
>   	sctx->b.b.clear_depth_stencil = si_clear_depth_stencil;
>   	sctx->b.b.resource_copy_region = si_resource_copy_region;
>



More information about the mesa-dev mailing list