From 8df37083807a5d6d3cab5ed61eb6b53502e254a6 Mon Sep 17 00:00:00 2001 From: Ribbit Date: Thu, 16 Oct 2025 19:45:24 -0700 Subject: [PATCH] more fixes --- .../renderer_vulkan/pipeline_helper.h | 4 ++-- .../renderer_vulkan/vk_texture_cache.cpp | 22 +++++++++++++++++-- .../renderer_vulkan/vk_texture_cache.h | 3 +++ .../vulkan_common/vulkan_device.cpp | 10 +++++++++ src/video_core/vulkan_common/vulkan_device.h | 3 +++ 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index b105fcd1ab..f868e5dd9b 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -200,8 +200,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache, format_type == VideoCore::Surface::SurfaceType::DepthStencil; const bool force_disable_compare = sampler.DepthCompareEnabled() && !view_supports_depth_compare; - const bool is_integer_format = VideoCore::Surface::IsPixelFormatInteger(image_view.format); - const bool needs_nearest = is_integer_format && sampler.HasLinearFiltering(); + const bool needs_nearest = + sampler.HasLinearFiltering() && !image_view.SupportsLinearFiltering(); VkSampler vk_sampler{}; if (use_fallback_sampler) { if (needs_nearest) { diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index ab8d320990..cc3f0b8b27 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2025,6 +2025,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI } } const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format); + vk_format = format_info.format; if (ImageUsageFlags(format_info, format) != image.UsageFlags()) { LOG_WARNING(Render_Vulkan, "Image view format {} has different usage flags than image format {}", format, @@ -2099,8 +2100,11 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info, const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_) - : VideoCommon::ImageViewBase{info, view_info, gpu_addr_}, - buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {} + : VideoCommon::ImageViewBase{info, view_info, gpu_addr_}, device{&runtime.device}, + buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} { + const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format); + vk_format = format_info.format; +} ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params) : VideoCommon::ImageViewBase{params}, device{&runtime.device} { @@ -2117,6 +2121,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageV for (u32 i = 0; i < Shader::NUM_TEXTURE_TYPES; i++) { image_views[i] = MakeView(VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_ASPECT_COLOR_BIT); } + vk_format = VK_FORMAT_A8B8G8R8_UNORM_PACK32; } ImageView::~ImageView() = default; @@ -2187,6 +2192,19 @@ bool ImageView::IsRescaled() const noexcept { return src_image.IsRescaled(); } +bool ImageView::SupportsLinearFiltering() const noexcept { + if (!device) { + return false; + } + if (VideoCore::Surface::IsPixelFormatInteger(format)) { + return false; + } + if (vk_format == VK_FORMAT_UNDEFINED) { + return false; + } + return device->SupportsLinearFiltering(vk_format, FormatType::Optimal); +} + vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { return device->GetLogical().CreateImageView({ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index e495c741d3..9b81ff6f3d 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -238,6 +238,8 @@ public: [[nodiscard]] bool IsRescaled() const noexcept; + [[nodiscard]] bool SupportsLinearFiltering() const noexcept; + [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { return *image_views[static_cast(texture_type)]; } @@ -279,6 +281,7 @@ private: vk::ImageView stencil_view; vk::ImageView color_view; vk::Image null_image; + VkFormat vk_format{VK_FORMAT_UNDEFINED}; VkImage image_handle = VK_NULL_HANDLE; VkImageView render_target = VK_NULL_HANDLE; VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 230348f21a..5324aa5dd7 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -895,6 +895,16 @@ bool Device::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags want return (supported_usage & wanted_usage) == wanted_usage; } +bool Device::SupportsLinearFiltering(VkFormat format, FormatType format_type) const { + const auto it = format_properties.find(format); + if (it == format_properties.end()) { + UNIMPLEMENTED_MSG("Unimplemented format query={}", format); + return false; + } + const auto supported_usage = GetFormatFeatures(it->second, format_type); + return (supported_usage & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0; +} + std::string Device::GetDriverName() const { switch (properties.driver.driverID) { case VK_DRIVER_ID_AMD_PROPRIETARY: diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index cb13f28523..829b7840ce 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -214,6 +214,9 @@ public: bool IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage, FormatType format_type) const; + /// Returns true if the format supports linear filtering for sampled image usage. + bool SupportsLinearFiltering(VkFormat format, FormatType format_type) const; + /// Reports a device loss. void ReportLoss() const;