From ca25d5f846217d389eec5f73ede779123f9b87b1 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 18 Aug 2023 11:53:34 +0200 Subject: [PATCH] radeonsi/sdma: use multiple commands if required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Samuel Pitoiset Reviewed-by: Daniel Stone Part-of: --- .../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; }