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;