[Mesa-dev] [PATCH v2] radeonsi: handle MultiDrawIndirect in si_get_draw_start_count

Edward O'Callaghan funfunctor at folklore1984.net
Mon Feb 20 23:23:15 UTC 2017


v2 is,
Acked-by: Edward O'Callaghan <funfunctor at folklore1984.net>

On 02/21/2017 09:05 AM, Nicolai Hähnle wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
> 
> Also handle the GL_ARB_indirect_parameters case where the count itself
> is in a buffer.
> 
> Use transfers rather than mapping the buffers directly. This anticipates
> the possibility that the buffers are sparse (once ARB_sparse_buffer is
> implemented), in which case they cannot be mapped directly.
> 
> Fixes GL45-CTS.gtf43.GL3Tests.multi_draw_indirect.multi_draw_indirect_type
> on <= CIK.
> 
> v2:
> - unmap the indirect buffer correctly
> - handle the corner case where we have indirect draws, but all of them
>   have count 0.
> 
> Cc: mesa-stable at lists.freedesktop.org
> Reviewed-by: Marek Olšák <marek.olsak at amd.com> (v1)
> ---
>  src/gallium/drivers/radeonsi/si_state_draw.c | 60 ++++++++++++++++++++++++----
>  1 file changed, 53 insertions(+), 7 deletions(-)
> 
> diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
> index 141dd8f..1ff1547 100644
> --- a/src/gallium/drivers/radeonsi/si_state_draw.c
> +++ b/src/gallium/drivers/radeonsi/si_state_draw.c
> @@ -907,27 +907,73 @@ void si_emit_cache_flush(struct si_context *sctx)
>  	}
>  
>  	rctx->flags = 0;
>  }
>  
>  static void si_get_draw_start_count(struct si_context *sctx,
>  				    const struct pipe_draw_info *info,
>  				    unsigned *start, unsigned *count)
>  {
>  	if (info->indirect) {
> -		struct r600_resource *indirect =
> -			(struct r600_resource*)info->indirect;
> -		int *data = r600_buffer_map_sync_with_rings(&sctx->b,
> -					indirect, PIPE_TRANSFER_READ);
> -                data += info->indirect_offset/sizeof(int);
> -		*start = data[2];
> -		*count = data[0];
> +		unsigned indirect_count;
> +		struct pipe_transfer *transfer;
> +		unsigned begin, end;
> +		unsigned map_size;
> +		unsigned *data;
> +
> +		if (info->indirect_params) {
> +			data = pipe_buffer_map_range(&sctx->b.b,
> +					info->indirect_params,
> +					info->indirect_params_offset,
> +					sizeof(unsigned),
> +					PIPE_TRANSFER_READ, &transfer);
> +
> +			indirect_count = *data;
> +
> +			pipe_buffer_unmap(&sctx->b.b, transfer);
> +		} else {
> +			indirect_count = info->indirect_count;
> +		}
> +
> +		if (!indirect_count) {
> +			*start = *count = 0;
> +			return;
> +		}
> +
> +		map_size = (indirect_count - 1) * info->indirect_stride + 3 * sizeof(unsigned);
> +		data = pipe_buffer_map_range(&sctx->b.b, info->indirect,
> +					     info->indirect_offset, map_size,
> +					     PIPE_TRANSFER_READ, &transfer);
> +
> +		begin = UINT_MAX;
> +		end = 0;
> +
> +		for (unsigned i = 0; i < indirect_count; ++i) {
> +			unsigned count = data[0];
> +			unsigned start = data[2];
> +
> +			if (count > 0) {
> +				begin = MIN2(begin, start);
> +				end = MAX2(end, start + count);
> +			}
> +
> +			data += info->indirect_stride / sizeof(unsigned);
> +		}
> +
> +		pipe_buffer_unmap(&sctx->b.b, transfer);
> +
> +		if (begin < end) {
> +			*start = begin;
> +			*count = end - begin;
> +		} else {
> +			*start = *count = 0;
> +		}
>  	} else {
>  		*start = info->start;
>  		*count = info->count;
>  	}
>  }
>  
>  void si_ce_pre_draw_synchronization(struct si_context *sctx)
>  {
>  	if (sctx->ce_need_synchronization) {
>  		radeon_emit(sctx->ce_ib, PKT3(PKT3_INCREMENT_CE_COUNTER, 0, 0));
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170221/48c8ff54/attachment.sig>


More information about the mesa-dev mailing list