Module: Mesa
Branch: main
Commit: ca25d5f846217d389eec5f73ede779123f9b87b1
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=ca25d5f846217d389eec5f73ede779123f9b87b1

Author: Pierre-Eric Pelloux-Prayer <[email protected]>
Date:   Fri Aug 18 11:53:34 2023 +0200

radeonsi/sdma: use multiple commands if required

Instead of failing the copy we can use multiple chunks.

This codepath shouldn't really be used since the source
image should usually be tiled but it still better to not
fail when possible.

Reviewed-by: Marek Olšák <[email protected]>
Reviewed-by: Samuel Pitoiset <[email protected]>
Reviewed-by: Daniel Stone <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24771>

---

 src/gallium/drivers/radeonsi/si_sdma_copy_image.c | 30 ++++++++++++++---------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_sdma_copy_image.c 
b/src/gallium/drivers/radeonsi/si_sdma_copy_image.c
index e5d4506c9f0..b42d1e40afb 100644
--- a/src/gallium/drivers/radeonsi/si_sdma_copy_image.c
+++ b/src/gallium/drivers/radeonsi/si_sdma_copy_image.c
@@ -73,23 +73,29 @@ static bool si_sdma_v4_v5_copy_texture(struct si_context 
*sctx, struct si_textur
       struct radeon_cmdbuf *cs = sctx->sdma_cs;
 
       uint64_t bytes = (uint64_t)src_pitch * copy_height * bpp;
-
-      if (!(bytes <= (1u << (is_v5_2 ? 30 : 22))))
-         return false;
+      uint32_t chunk_size = 1u << (is_v5_2 ? 30 : 22);
+      uint32_t chunk_count = DIV_ROUND_UP(bytes, chunk_size);
 
       src_address += ssrc->surface.u.gfx9.offset[0];
       dst_address += sdst->surface.u.gfx9.offset[0];
 
       radeon_begin(cs);
-      radeon_emit(CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY,
-                                  CIK_SDMA_COPY_SUB_OPCODE_LINEAR,
-                                  (tmz ? 4 : 0)));
-      radeon_emit(bytes - 1);
-      radeon_emit(0);
-      radeon_emit(src_address);
-      radeon_emit(src_address >> 32);
-      radeon_emit(dst_address);
-      radeon_emit(dst_address >> 32);
+      for (int i = 0; i < chunk_count; i++) {
+         uint32_t size = MIN2(chunk_size, bytes);
+         radeon_emit(CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY,
+                                     CIK_SDMA_COPY_SUB_OPCODE_LINEAR,
+                                     (tmz ? 4 : 0)));
+         radeon_emit(size - 1);
+         radeon_emit(0);
+         radeon_emit(src_address);
+         radeon_emit(src_address >> 32);
+         radeon_emit(dst_address);
+         radeon_emit(dst_address >> 32);
+
+         src_address += size;
+         dst_address += size;
+         bytes -= size;
+      }
       radeon_end();
       return true;
    }

Reply via email to