diff options
| author | CamilleLaVey <camillelavey99@gmail.com> | 2026-08-05 09:24:35 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-08-05 09:24:35 +0200 |
| commit | 5e1d5e82dcc98627c769b7ca32384ded16bc5e1d (patch) | |
| tree | 33870dec16238459232e492552989d438c02b2f3 /src/video_core/renderer_vulkan | |
| parent | ba9130fbf974e7a529f5507e4cb530986c5d0859 (diff) | |
[vulkan] Re-adjusting ASTC resolve (#4250)
This is an adjustment made due to problems caused by my ASTC changes some pr's earlier; added sanity to decoded blocks, removes the inconditional storage view for ASTC formats (verified against MaxwellToVk logic), added support to VK_EXT_astc_decode_mode which will ensure a better way to resolve RGFA16/RGFA32 on tilers, simplified ASTC HDR decoding into LDR valid formats.
This fixes some issues with SteamDeck, Fire Emblem: Engage washed colors and other problems related to ASTC.
_Special Thanks_
1.- Meowly The Smol (@Gidoly)
2.- @simply0001 for the actual idea on the redundant storage views on the transcoded ASTC path.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4250
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 46 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 1 |
2 files changed, 18 insertions, 29 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 44a4227a19..bd3117037f 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -144,11 +144,6 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { info.size.depth == 1; } -[[nodiscard]] bool WillUseWidenedAstcFormat(const Device& device, const ImageInfo& info) { - return WillUseAcceleratedAstcDecode(device, info) && - !VideoCore::Surface::IsPixelFormatSRGB(info.format); -} - [[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info, std::optional<VkFormat> format_override = {}) { auto format_info = @@ -269,6 +264,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { } } +[[nodiscard]] bool IsLdrAstcFormat(VkFormat format) { + return format >= VK_FORMAT_ASTC_4x4_UNORM_BLOCK && format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; +} + [[nodiscard]] VkImageAspectFlags ImageViewAspectMask(const VideoCommon::ImageViewInfo& info) { if (info.IsRenderTarget()) { return ImageAspectMask(info.format); @@ -1780,12 +1779,7 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), scheduler{&runtime_.scheduler}, runtime{&runtime_}, original_image(MakeImage(runtime_.device, runtime_.memory_allocator, info, - WillUseWidenedAstcFormat(runtime_.device, info) - ? std::span<const VkFormat>{} - : runtime->ViewFormats(info.format), - WillUseWidenedAstcFormat(runtime_.device, info) - ? std::make_optional(VK_FORMAT_R32G32B32A32_SFLOAT) - : std::nullopt)), + runtime->ViewFormats(info.format))), aspect_mask(ImageAspectMask(info.format)) { if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) { switch (Settings::values.accelerate_astc.GetValue()) { @@ -1812,13 +1806,9 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu } current_image = &Image::original_image; storage_image_views.resize(info.resources.levels); - if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported() && - Settings::values.astc_recompression.GetValue() == - Settings::AstcRecompression::Uncompressed) { + if (WillUseAcceleratedAstcDecode(runtime->device, info)) { const auto& device = runtime->device.GetLogical(); - const VkFormat storage_format = WillUseWidenedAstcFormat(runtime->device, info) - ? VK_FORMAT_R32G32B32A32_SFLOAT - : VK_FORMAT_A8B8G8R8_UNORM_PACK32; + const VkFormat storage_format = VK_FORMAT_A8B8G8R8_UNORM_PACK32; for (s32 level = 0; level < info.resources.levels; ++level) { storage_image_views[level] = MakeStorageView(device, level, *original_image, storage_format); @@ -2204,9 +2194,7 @@ VkImageView Image::StorageImageView(s32 level) noexcept { auto format_info = MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, true, info.format); if (WillUseAcceleratedAstcDecode(runtime->device, info)) { - format_info.format = WillUseWidenedAstcFormat(runtime->device, info) - ? VK_FORMAT_R32G32B32A32_SFLOAT - : VK_FORMAT_A8B8G8R8_UNORM_PACK32; + format_info.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32; } view = MakeStorageView(runtime->device.GetLogical(), level, *(this->*current_image), format_info.format); @@ -2382,11 +2370,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI SanitizeDepthStencilSwizzle(swizzle, device->SupportsDepthStencilSwizzleOne()); } } - uses_widened_astc_format = WillUseWidenedAstcFormat(*device, image.info); auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format); - if (uses_widened_astc_format) { - format_info.format = VK_FORMAT_R32G32B32A32_SFLOAT; - } if (device->ApiVersion() >= VK_API_VERSION_1_3) { const VkFormatProperties3 properties3 = device->GetPhysical().GetFormatProperties3(format_info.format); @@ -2404,9 +2388,18 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI .pNext = nullptr, .usage = clamped_view_usage, }; + const VkImageViewASTCDecodeModeEXT astc_decode_mode{ + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT, + .pNext = &image_view_usage, + .decodeMode = VK_FORMAT_R8G8B8A8_UNORM, + }; + const void* view_next = &image_view_usage; + if (device->IsExtAstcDecodeModeSupported() && IsLdrAstcFormat(format_info.format)) { + view_next = &astc_decode_mode; + } const VkImageViewCreateInfo create_info{ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = &image_view_usage, + .pNext = view_next, .flags = 0, .image = image.Handle(), .viewType = VkImageViewType{}, @@ -2531,9 +2524,6 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type, if (image_format == Shader::ImageFormat::Typeless) { if (!typeless_storage_view) { auto info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format); - if (uses_widened_astc_format) { - info.format = VK_FORMAT_R32G32B32A32_SFLOAT; - } typeless_storage_view = MakeView(info.format, VK_IMAGE_ASPECT_COLOR_BIT, texture_type); } return *typeless_storage_view; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 99f2978cca..4b4900e5d6 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -436,7 +436,6 @@ private: VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; u32 buffer_size = 0; - bool uses_widened_astc_format = false; bool supports_depth_comparison = false; }; |
