From 4d7fa271d43bca1172bb7c7df5a6b76f3ce57af7 Mon Sep 17 00:00:00 2001 From: Valiantsin Dzerakh Date: Fri, 30 Oct 2026 20:15:39 +0300 Subject: [PATCH] Make only cube textures cube compatible Every square 2D array of 6 or more layers was created cube compatible, though the replay makes cube views only of images whose own target is a cubemap or cubemap array (vk_exec_draw.c get_view). On AMD's Windows driver the flag changes the image layout, and Savage Wind Recomp traced rainbow blocks on terrain that moved with the mip level to it (their issue #59, BotW on an RX 580 and a 7800 XT); our AMD and Intel reports show the same symptom (#42, #67, #81). The flag now goes to cube targets only, on every driver. Co-Authored-By: Claude Opus 5.5 --- runtime/vk_texture.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/vk_texture.c b/runtime/vk_texture.c index 4920fa10..9631add8 100644 --- a/runtime/vk_texture.c +++ b/runtime/vk_texture.c @@ -313,7 +313,13 @@ static Tex *create_tex(const tex_t *t, const TexKey *k, int defer_init) { if ((d->flags & NVN_TEXTURE_FLAGS_IMAGE) && (ff & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) && samples == 1) usage |= VK_IMAGE_USAGE_STORAGE_BIT; VkImageCreateFlags flags = ds ? 0 : VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; // format-reinterpreting views - if (type == VK_IMAGE_TYPE_2D && layers >= 6 && w == h && samples == 1) flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + // Cube compatible only for cube targets: the replay makes cube views of nothing else (vk_exec_draw.c get_view checks + // the image's own view type). The flag on every square array of 6+ layers changed how AMD's Windows driver lays such + // an image out, and terrain material arrays sampled through it came out in rainbow blocks that moved with the mip + // level (Savage Wind Recomp issue #59, BotW on an RX 580 and a 7800 XT). + if (type == VK_IMAGE_TYPE_2D && layers >= 6 && w == h && samples == 1 && + (d->target == NVN_TEXTURE_TARGET_CUBEMAP || d->target == NVN_TEXTURE_TARGET_CUBEMAP_ARRAY)) + flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; // NVN renders into a 3D texture slice by slice (a view's min layer is the depth plane, nvn_mtl.m), e.g. the // grading LUT of the menu background blur. Vulkan needs a 2D view of the slice for that. if (type == VK_IMAGE_TYPE_3D && (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;