From: Marek Olšák <marek.ol...@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. */
+
+       /* 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to