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 <samuel.pitoiset@gmail.com>
(cherry picked from commit 837078b8d5)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40092>
This commit is contained in:
Samuel Pitoiset 2026-02-18 13:20:05 +01:00 committed by Eric Engestrom
parent 6f75431e98
commit 54293d4fdd
2 changed files with 18 additions and 2 deletions

View file

@ -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

View file

@ -8,6 +8,7 @@
#include <stdbool.h>
#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,