[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