diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 8d085f4541..f5c6ca78b5 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -15,6 +15,7 @@ #include "shader_recompiler/shader_info.h" #include "video_core/renderer_vulkan/vk_texture_cache.h" #include "video_core/renderer_vulkan/vk_update_descriptor.h" +#include "video_core/surface.h" #include "video_core/texture_cache/types.h" #include "video_core/vulkan_common/vulkan_device.h" @@ -232,10 +233,16 @@ inline void PushImageDescriptors(TextureCache& texture_cache, ImageView& image_view{texture_cache.GetImageView(image_view_id)}; const VkImageView vk_image_view{image_view.Handle(desc.type)}; const Sampler& sampler{texture_cache.GetSampler(sampler_id)}; + const auto surface_type{VideoCore::Surface::GetFormatType(image_view.format)}; + const bool allow_depth_compare = + desc.is_depth && (surface_type == VideoCore::Surface::SurfaceType::Depth || + surface_type == VideoCore::Surface::SurfaceType::DepthStencil); const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && !image_view.SupportsAnisotropy()}; - const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() - : sampler.Handle()}; + const VkSampler vk_sampler{use_fallback_sampler + ? sampler.HandleWithDefaultAnisotropy( + allow_depth_compare) + : sampler.Handle(allow_depth_compare)}; guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); rescaling.PushTexture(texture_cache.IsRescaling(image_view)); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 5cd4273c2d..a289865102 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2314,6 +2314,7 @@ vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& tsc) { const auto& device = runtime.device; + has_depth_compare = tsc.depth_compare_enabled != 0; // Check if custom border colors are supported const bool has_custom_border_colors = runtime.device.IsCustomBorderColorsSupported(); const bool has_format_undefined = runtime.device.IsCustomBorderColorWithoutFormatSupported(); @@ -2354,7 +2355,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t // Some games have samplers with garbage. Sanitize them here. const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f); - const auto create_sampler = [&](const f32 anisotropy) { + const auto create_sampler = [&](const f32 anisotropy, bool enable_depth_compare) { return device.GetLogical().CreateSampler(VkSamplerCreateInfo{ .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, .pNext = pnext, @@ -2368,7 +2369,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t .mipLodBias = tsc.LodBias(), .anisotropyEnable = static_cast(anisotropy > 1.0f ? VK_TRUE : VK_FALSE), .maxAnisotropy = anisotropy, - .compareEnable = tsc.depth_compare_enabled, + .compareEnable = enable_depth_compare, .compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), @@ -2378,11 +2379,18 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t }); }; - sampler = create_sampler(max_anisotropy); + sampler = create_sampler(max_anisotropy, has_depth_compare); + if (has_depth_compare) { + sampler_no_compare = create_sampler(max_anisotropy, false); + } const f32 max_anisotropy_default = static_cast(1U << tsc.max_anisotropy); if (max_anisotropy > max_anisotropy_default) { - sampler_default_anisotropy = create_sampler(max_anisotropy_default); + sampler_default_anisotropy = create_sampler(max_anisotropy_default, has_depth_compare); + if (has_depth_compare) { + sampler_default_anisotropy_no_compare = + create_sampler(max_anisotropy_default, false); + } } } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 4bb9687ab0..ee1c842852 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project @@ -396,11 +396,18 @@ class Sampler { public: explicit Sampler(TextureCacheRuntime&, const Tegra::Texture::TSCEntry&); - [[nodiscard]] VkSampler Handle() const noexcept { + [[nodiscard]] VkSampler Handle(bool enable_depth_compare = true) const noexcept { + if (!enable_depth_compare && sampler_no_compare) { + return *sampler_no_compare; + } return *sampler; } - [[nodiscard]] VkSampler HandleWithDefaultAnisotropy() const noexcept { + [[nodiscard]] VkSampler HandleWithDefaultAnisotropy( + bool enable_depth_compare = true) const noexcept { + if (!enable_depth_compare && sampler_default_anisotropy_no_compare) { + return *sampler_default_anisotropy_no_compare; + } return *sampler_default_anisotropy; } @@ -408,9 +415,16 @@ public: return static_cast(sampler_default_anisotropy); } + [[nodiscard]] bool HasDepthCompareEnabled() const noexcept { + return has_depth_compare; + } + private: vk::Sampler sampler; + vk::Sampler sampler_no_compare; vk::Sampler sampler_default_anisotropy; + vk::Sampler sampler_default_anisotropy_no_compare; + bool has_depth_compare = false; }; struct TextureCacheParams {