From e93b3052b4c272cd994897e6f54dd0640546690e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Sat, 9 Aug 2025 06:44:09 +0200 Subject: [PATCH] radv: Flush L2 before CP DMA copy/fill when CP DMA doesn't use L2 In case the source or destination were previously written through L2, we need to writeback L2 to avoid the CP DMA accessing stale data. However, as the CP DMA doesn't write L2 either, an invalidation is also needed to make sure other clients don't access stale data when they read it through L2 after the CP DMA is complete. Doing an invalidation before the CP DMA operation should take care of both. Additionally, radv_src_access_flush also invalidates L2 before the copied data can be read. Cc: mesa-stable Part-of: (cherry picked from commit c183eb5bc8747e401a38df427429570c4ef074ca) --- .pick_status.json | 2 +- src/amd/vulkan/radv_cp_dma.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 6748a520c12..93213c5b8a1 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -5084,7 +5084,7 @@ "description": "radv: Flush L2 before CP DMA copy/fill when CP DMA doesn't use L2", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/amd/vulkan/radv_cp_dma.c b/src/amd/vulkan/radv_cp_dma.c index 68dafdacf59..7792f904390 100644 --- a/src/amd/vulkan/radv_cp_dma.c +++ b/src/amd/vulkan/radv_cp_dma.c @@ -232,6 +232,11 @@ radv_cp_dma_copy_memory(struct radv_cmd_buffer *cmd_buffer, uint64_t src_va, uin uint64_t main_src_va, main_dest_va; uint64_t skipped_size = 0, realign_size = 0; + if (!(pdev->info.cp_dma_use_L2 && pdev->info.gfx_level >= GFX9)) { + /* Invalidate L2 in case "src_va" or "dest_va" were previously written through L2. */ + cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2; + } + /* Assume that we are not going to sync after the last DMA operation. */ cmd_buffer->state.dma_is_busy = true; @@ -296,9 +301,6 @@ radv_cp_dma_copy_memory(struct radv_cmd_buffer *cmd_buffer, uint64_t src_va, uin } if (realign_size) radv_cp_dma_realign_engine(cmd_buffer, realign_size); - - if (pdev->info.cp_sdma_ge_use_system_memory_scope) - cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2; } void @@ -310,6 +312,11 @@ radv_cp_dma_fill_memory(struct radv_cmd_buffer *cmd_buffer, uint64_t va, uint64_ if (!size) return; + if (!(pdev->info.cp_dma_use_L2 && pdev->info.gfx_level >= GFX9)) { + /* Invalidate L2 in case "va" was previously written through L2. */ + cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2; + } + assert(va % 4 == 0 && size % 4 == 0); enum amd_gfx_level gfx_level = pdev->info.gfx_level; @@ -339,9 +346,6 @@ radv_cp_dma_fill_memory(struct radv_cmd_buffer *cmd_buffer, uint64_t va, uint64_ size -= byte_count; va += byte_count; } - - if (pdev->info.cp_sdma_ge_use_system_memory_scope) - cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2; } void