From f22bce85ed877499cddde5ce36d637d77ec6d398 Mon Sep 17 00:00:00 2001 From: junminlee2004 <62260557+junminlee2004@users.noreply.github.com> Date: Wed, 23 Sep 2026 15:10:48 -0400 Subject: [PATCH] video_core: Only enable sampler comparison for comparison fetches (#5020) * video_core: Only enable sampler comparison for comparison fetches * Use HashCombine for the sampler hash --- .../ir/passes/resource_patching_pass.cpp | 4 +++- src/shader_recompiler/resource.h | 1 + src/video_core/renderer_vulkan/vk_rasterizer.cpp | 3 ++- src/video_core/texture_cache/sampler.cpp | 5 +++-- src/video_core/texture_cache/sampler.h | 2 +- src/video_core/texture_cache/texture_cache.cpp | 10 +++++++--- src/video_core/texture_cache/texture_cache.h | 3 ++- 7 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/shader_recompiler/ir/passes/resource_patching_pass.cpp b/src/shader_recompiler/ir/passes/resource_patching_pass.cpp index 853c29f61..0c285cdac 100644 --- a/src/shader_recompiler/ir/passes/resource_patching_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_patching_pass.cpp @@ -126,7 +126,8 @@ public: u32 Add(const SamplerResource& desc) { const u32 index{Add(sampler_resources, desc, [this, &desc](const auto& existing) { return desc.sharp_fetch == existing.sharp_fetch && desc.post_op == existing.post_op && - desc.post_op_tsharp_dw3_off == existing.post_op_tsharp_dw3_off; + desc.post_op_tsharp_dw3_off == existing.post_op_tsharp_dw3_off && + desc.is_depth == existing.is_depth; })}; return index; } @@ -312,6 +313,7 @@ void PatchImageSharp(const ResourceDiscovery& resource, Info& info, Descriptors& .post_op = resource.sharps[1].post_op, .post_op_tsharp_dw3_off = lod_prod.IsEmpty() ? UNKNOWN_LOCATION : SharpLocationFromSource(lod_prod.Inst()), + .is_depth = bool(inst_info.is_depth), // true for the _C (compare) opcodes }); inst.SetArg(0, ir.Imm32(image_binding | sampler_binding << 16)); } else { diff --git a/src/shader_recompiler/resource.h b/src/shader_recompiler/resource.h index d6e676a74..ff5bff8a9 100644 --- a/src/shader_recompiler/resource.h +++ b/src/shader_recompiler/resource.h @@ -170,6 +170,7 @@ struct SamplerResource { SharpFetch sharp_fetch{}; SharpFetchPostOp post_op{}; SharpLocation post_op_tsharp_dw3_off{}; + bool is_depth{}; constexpr AmdGpu::Sampler GetSharp(const auto& info) const noexcept { AmdGpu::Sampler sampler{}; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 92947c1e5..ef9d32159 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -950,7 +950,8 @@ void Rasterizer::BindTextures(const Shader::Info& stage, Shader::Backend::Bindin for (const auto& sampler : stage.samplers) { auto ssharp = sampler.GetSharp(stage); - const auto vk_sampler = texture_cache.GetSampler(ssharp, liverpool->regs.ta_bc_base); + const auto vk_sampler = + texture_cache.GetSampler(ssharp, liverpool->regs.ta_bc_base, sampler.is_depth); image_infos.emplace_back(vk_sampler, VK_NULL_HANDLE, vk::ImageLayout::eGeneral); auto& set_write = set_writes[set_write_index++]; set_write.dstSet = VK_NULL_HANDLE; diff --git a/src/video_core/texture_cache/sampler.cpp b/src/video_core/texture_cache/sampler.cpp index 3d74793f8..192ad33d3 100644 --- a/src/video_core/texture_cache/sampler.cpp +++ b/src/video_core/texture_cache/sampler.cpp @@ -9,7 +9,7 @@ namespace VideoCore { Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler, - const AmdGpu::BorderColorBuffer border_color_base) { + const AmdGpu::BorderColorBuffer border_color_base, const bool is_depth) { using namespace Vulkan; const bool anisotropy_enable = instance.IsAnisotropicFilteringSupported() && (AmdGpu::IsAnisoFilter(sampler.xy_mag_filter) || @@ -54,7 +54,8 @@ Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sample .mipLodBias = std::min(sampler.LodBias(), instance.MaxSamplerLodBias()), .anisotropyEnable = anisotropy_enable, .maxAnisotropy = max_anisotropy, - .compareEnable = sampler.depth_compare_func != AmdGpu::DepthCompare::Never, + // GCN compares per instruction; a plain read of a compare sampler is undefined in Vulkan. + .compareEnable = is_depth, .compareOp = LiverpoolToVK::DepthCompare(sampler.depth_compare_func), .minLod = sampler.MinLod(), .maxLod = sampler.MaxLod(), diff --git a/src/video_core/texture_cache/sampler.h b/src/video_core/texture_cache/sampler.h index e60c0f379..b68f4e80c 100644 --- a/src/video_core/texture_cache/sampler.h +++ b/src/video_core/texture_cache/sampler.h @@ -16,7 +16,7 @@ namespace VideoCore { class Sampler { public: explicit Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler, - const AmdGpu::BorderColorBuffer border_color_base); + const AmdGpu::BorderColorBuffer border_color_base, bool is_depth); ~Sampler(); Sampler(const Sampler&) = delete; diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index 746b3ca00..be3529889 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -6,6 +6,7 @@ #include "common/assert.h" #include "common/debug.h" #include "common/div_ceil.h" +#include "common/hash.h" #include "common/scope_exit.h" #include "core/emulator_settings.h" #include "core/memory.h" @@ -766,11 +767,14 @@ void TextureCache::RefreshImage(Image& image) { } vk::Sampler TextureCache::GetSampler(const AmdGpu::Sampler& sampler, - AmdGpu::BorderColorBuffer border_color_base) { - const u64 hash = XXH3_64bits(&sampler, sizeof(sampler)); + AmdGpu::BorderColorBuffer border_color_base, + const bool is_depth) { + // Compare and plain uses of one S# need separate samplers. + const u64 hash = HashCombine(XXH3_64bits(&sampler, sizeof(sampler)), is_depth); std::scoped_lock lock{samplers_mutex}; - const auto [it, new_sampler] = samplers.try_emplace(hash, instance, sampler, border_color_base); + const auto [it, new_sampler] = + samplers.try_emplace(hash, instance, sampler, border_color_base, is_depth); if (new_sampler) { samplers.at(hash).lru_id = sampler_lru_cache.Insert(hash, gc_tick); } else { diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 53d0350c4..69309d337 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -143,7 +143,8 @@ public: /// Retrieves the sampler that matches the provided S# descriptor. [[nodiscard]] vk::Sampler GetSampler(const AmdGpu::Sampler& sampler, - AmdGpu::BorderColorBuffer border_color_base); + AmdGpu::BorderColorBuffer border_color_base, + bool is_depth); /// Retrieves the image with the specified id. [[nodiscard]] Image& GetImage(ImageId id) {