From 34380b1ee7446b7b270f240d59ddfd6614e3294d Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Feb 2026 22:01:31 +0300 Subject: [PATCH] vk: Make use of mutable formats for dynamic views --- rpcs3/Emu/RSX/VK/VKFormats.cpp | 33 ------------------------- rpcs3/Emu/RSX/VK/VKTextureCache.cpp | 37 ++++++++++++++++++++++++++++- rpcs3/Emu/RSX/VK/VKTextureCache.h | 3 ++- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index ed824de77d..0110460a51 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -253,15 +253,6 @@ namespace vk return VK_FORMAT_R8G8B8A8_SRGB; case VK_FORMAT_B8G8R8A8_UNORM: return VK_FORMAT_B8G8R8A8_SRGB; - // 16-bit - case VK_FORMAT_R16_UNORM: - case VK_FORMAT_R16G16_UNORM: - return VK_FORMAT_UNDEFINED; // No match - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - return VK_FORMAT_UNDEFINED; // No match // DXT case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return VK_FORMAT_BC1_RGBA_SRGB_BLOCK; @@ -269,14 +260,7 @@ namespace vk return VK_FORMAT_BC2_SRGB_BLOCK; case VK_FORMAT_BC3_UNORM_BLOCK: return VK_FORMAT_BC3_SRGB_BLOCK; - // Depth - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - return VK_FORMAT_UNDEFINED; // Unsupported default: - rsx_log.error("[SRGB_FMT] Unexpected VkFormat 0x%x", static_cast(rgb_format)); return VK_FORMAT_UNDEFINED; } } @@ -299,24 +283,7 @@ namespace vk return VK_FORMAT_R16_SNORM; case VK_FORMAT_R16G16_UNORM: return VK_FORMAT_R16G16_SNORM; - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - return VK_FORMAT_UNDEFINED; // No match - // DXT - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC3_UNORM_BLOCK: - return VK_FORMAT_UNDEFINED; // No match - // Depth - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - return VK_FORMAT_UNDEFINED; // Unsupported default: - rsx_log.error("[SEXT_FMT] Unexpected VkFormat 0x%x", static_cast(rgb_format)); return VK_FORMAT_UNDEFINED; } } diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp index d1b0e536ef..2427cd8da3 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp @@ -1025,6 +1025,29 @@ namespace vk const VkFormat vk_format = get_compatible_sampler_format(m_formats_support, gcm_format); VkImageCreateFlags create_flags = is_cubemap ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0; VkSharingMode sharing_mode = (flags & texture_create_flags::shareable) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE; + rsx::simple_array mutable_format_list; + + if (flags & texture_create_flags::mutable_format) + { + const VkFormat snorm_fmt = get_compatible_snorm_format(vk_format); + const VkFormat srgb_fmt = get_compatible_srgb_format(vk_format); + + if (snorm_fmt != VK_FORMAT_UNDEFINED) + { + mutable_format_list.push_back(snorm_fmt); + } + + if (srgb_fmt != VK_FORMAT_UNDEFINED) + { + mutable_format_list.push_back(srgb_fmt); + } + + if (!mutable_format_list.empty()) + { + create_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + mutable_format_list.push_back(vk_format); + } + } if (auto found = find_cached_image(vk_format, width, height, depth, mipmaps, image_type, create_flags, usage_flags, sharing_mode)) { @@ -1037,9 +1060,16 @@ namespace vk create_flags |= VK_IMAGE_CREATE_SHAREABLE_RPCS3; } + VkFormatEx create_format = vk_format; + if (!mutable_format_list.empty()) + { + create_format.pViewFormats = mutable_format_list.data(); + create_format.viewFormatCount = mutable_format_list.size(); + } + image = new vk::viewable_image(*m_device, m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - image_type, vk_format, + image_type, create_format, width, height, depth, mipmaps, layer, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, usage_flags, create_flags, VMM_ALLOCATION_POOL_TEXTURE_CACHE, rsx::classify_format(gcm_format)); @@ -1123,6 +1153,11 @@ namespace vk const bool upload_async = rsx::get_current_renderer()->get_backend_config().supports_asynchronous_compute; rsx::flags32_t create_flags = 0; + if (context == rsx::texture_upload_context::shader_read) + { + create_flags |= texture_create_flags::mutable_format; + } + if (upload_async && ensure(g_fxo->try_get())->is_host_mode()) { create_flags |= texture_create_flags::do_not_reuse; diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 786eb51270..85687c8c69 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -418,7 +418,8 @@ namespace vk { initialize_image_contents = 1, do_not_reuse = 2, - shareable = 4 + shareable = 4, + mutable_format = 8 }; void on_section_destroyed(cached_texture_section& tex) override;