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

Alex Deucher alexdeucher at gmail.com
Tue Nov 3 19:02:33 PST 2015


On Tue, Nov 3, 2015 at 6:47 PM, Marek Olšák <maraeo at gmail.com> 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;
> +               }
> +
> +               sctx->b.clear_buffer(ctx, dst, offset, size, value, false);
> +               return;
> +       }
> +
> +       /* TODO: use a compute shader for other cases. */

What about using SDMA?  It supports byte aligned constant fills at
least on CIK+.

Alex


> +
> +       /* 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;
> --
> 2.1.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list