From 54293d4fdd3cc5afdcf0735b21bec67b74ea37c9 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 18 Feb 2026 13:20:05 +0100 Subject: [PATCH] radv: fix potential corruption after FMASK decompression on GFX6-8 While reworking image resolves completely in RADV, I found a very weird bug where the only fix was to emit caches immediately after decompressing the source resolve image (after FMASK_DECOMPRESS). I have been struggling this for few hours and figured that it was something related to context rolls (ie. as long the context was rolled out, emitting the flushes immediately was required). It turns out this was a known hardware bug on GFX6 that was implemented in PAL. Though PAL only applies on GFX6 but GFX7-8 are also affected based on my testing. Note that RadeonSI flushes CB_META too. Cc: mesa-stable Signed-off-by: Samuel Pitoiset (cherry picked from commit 837078b8d55651a6fa3031d91de88b9c77862ea0) Part-of: --- .pick_status.json | 2 +- src/amd/vulkan/meta/radv_meta_fast_clear.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index a1ea137deec..a526126cd76 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1864,7 +1864,7 @@ "description": "radv: fix potential corruption after FMASK decompression on GFX6-8", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/amd/vulkan/meta/radv_meta_fast_clear.c b/src/amd/vulkan/meta/radv_meta_fast_clear.c index b5fadeb5dc3..f5b0837735d 100644 --- a/src/amd/vulkan/meta/radv_meta_fast_clear.c +++ b/src/amd/vulkan/meta/radv_meta_fast_clear.c @@ -8,6 +8,7 @@ #include #include "nir/radv_meta_nir.h" +#include "radv_cs.h" #include "radv_meta.h" enum radv_color_op { @@ -241,6 +242,7 @@ radv_process_color_image_layer(struct radv_cmd_buffer *cmd_buffer, struct radv_i const VkImageSubresourceRange *range, int level, int layer, enum radv_color_op op) { struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); + const struct radv_physical_device *pdev = radv_device_physical(device); struct radv_image_view iview; uint32_t width, height; @@ -303,9 +305,23 @@ radv_process_color_image_layer(struct radv_cmd_buffer *cmd_buffer, struct radv_i radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0); - if (op == FMASK_DECOMPRESS || op == DCC_DECOMPRESS) + if (op == FMASK_DECOMPRESS || op == DCC_DECOMPRESS) { + /* On GFX6-8, the CB FMASK cache writes corrupted data if cache lines are flushed after their + * context has been retired. To avoid this, we must flush the CB metadata caches immediately + * after every FMASK decompress. + * + * PAL only applies this workaround on GFX6 but GFX7-8 are also affected and that matches + * RadeonSI. + */ + if (pdev->info.gfx_level <= GFX8 && op == FMASK_DECOMPRESS) { + radeon_begin(cmd_buffer->cs); + radeon_event_write(V_028A90_FLUSH_AND_INV_CB_META); + radeon_end(); + } + cmd_buffer->state.flush_bits |= radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, 0, image, range); + } const VkRenderingEndInfoKHR end_info = { .sType = VK_STRUCTURE_TYPE_RENDERING_END_INFO_KHR,