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

2017-02-20 Thread Edward O'Callaghan
v2 is,
Acked-by: Edward O'Callaghan 

On 02/21/2017 09:05 AM, Nicolai Hähnle wrote:
> From: Nicolai Hähnle 
> 
> 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  (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(>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(>b.b,
> + info->indirect_params,
> + info->indirect_params_offset,
> + sizeof(unsigned),
> + PIPE_TRANSFER_READ, );
> +
> + indirect_count = *data;
> +
> + pipe_buffer_unmap(>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(>b.b, info->indirect,
> +  info->indirect_offset, map_size,
> +  PIPE_TRANSFER_READ, );
> +
> + 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(>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));
> 



signature.asc
Description: OpenPGP digital signature
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2017-02-20 Thread Nicolai Hähnle
From: Nicolai Hähnle 

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  (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(>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(>b.b,
+   info->indirect_params,
+   info->indirect_params_offset,
+   sizeof(unsigned),
+   PIPE_TRANSFER_READ, );
+
+   indirect_count = *data;
+
+   pipe_buffer_unmap(>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(>b.b, info->indirect,
+info->indirect_offset, map_size,
+PIPE_TRANSFER_READ, );
+
+   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(>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));
-- 
2.9.3

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