diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 39a43d5950..07ad9007c2 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2115,6 +2115,26 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI "Image view format {} has different usage flags than image format {}", format, image.info.format); } + + VkImageViewASTCDecodeModeEXT astc_decode_mode{ + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT, + .pNext = nullptr, + .decodeMode = VK_FORMAT_UNDEFINED, + }; + + const void* view_pNext = &image_view_usage; + + if (device->IsExtASTCDecodeModeSupported() && + VideoCommon::Surface::IsPixelFormatASTC(image.info.format) && + VideoCommon::Surface::IsPixelFormatASTC(format)) { + + const bool view_is_srgb = VideoCommon::Surface::IsPixelFormatSRGB(format); + astc_decode_mode.decodeMode = view_is_srgb ? VK_FORMAT_R8G8B8A8_SRGB_PACK32 + : VK_FORMAT_R8G8B8A8_UNORM_PACK32; + astc_decode_mode.pNext = view_pNext; + view_pNext = &astc_decode_mode; + } + const VkImageViewUsageCreateInfo image_view_usage{ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, .pNext = nullptr, @@ -2122,7 +2142,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI }; const VkImageViewCreateInfo create_info{ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = &image_view_usage, + .pNext = view_pNext, .flags = 0, .image = image.Handle(), .viewType = VkImageViewType{}, diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index f52c28e7ef..ef1c9fdbfc 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1406,6 +1406,18 @@ void Device::RemoveUnsuitableExtensions() { VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME); } + // VK_EXT_astc_decode_mode + if (is_optimal_astc_supported && loaded_extensions.contains(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME)) { + extensions.astc_decode_mode = true; + LOG_INFO(Render_Vulkan, "VK_EXT_astc_decode_mode enabled"); + } else { + extensions.astc_decode_mode = false; + if (loaded_extensions.contains(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME) && !is_optimal_astc_supported) { + LOG_INFO(Render_Vulkan, "VK_EXT_astc_decode_mode disabled: Requires native ASTC support"); + loaded_extensions.erase(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME); + } + } + // VK_EXT_robustness2 extensions.robustness_2 = features.robustness2.robustBufferAccess2 || features.robustness2.robustImageAccess2 || diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 0fdbb7aadc..0f96eba040 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -75,6 +75,7 @@ VK_DEFINE_HANDLE(VmaAllocator) // Define miscellaneous extensions which may be used by the implementation here. #define FOR_EACH_VK_EXTENSION(EXTENSION) \ + EXTENSION(EXT, ASTC_DECODE_MODE, astc_decode_mode) \ EXTENSION(EXT, CONDITIONAL_RENDERING, conditional_rendering) \ EXTENSION(EXT, CONSERVATIVE_RASTERIZATION, conservative_rasterization) \ EXTENSION(EXT, DEPTH_RANGE_UNRESTRICTED, depth_range_unrestricted) \ @@ -577,6 +578,11 @@ public: return extensions.color_write_enable; } + /// Returns true if the device supports VK_EXT_astc_decode_mode. + bool IsExtASTCDecodeModeSupported() const { + return extensions.astc_decode_mode; + } + /// Returns true if the device supports VK_EXT_image_robustness. bool IsExtImageRobustnessSupported() const { return extensions.image_robustness;