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

On 02/21/2017 09:05 AM, Nicolai Hähnle wrote:
> From: Nicolai Hähnle <nicolai.haeh...@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-sta...@lists.freedesktop.org
> Reviewed-by: Marek Olšák <marek.ol...@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));
> 

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to