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
This commit is contained in:
junminlee2004 authored and GitHub committed 2026-09-23 22:10:48 +03:00
1 parent bc028b7ca6
commit f22bce85ed
7 files changed
+19 -9

No files matched your search

@@ -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 {
+1
View File
@@ -170,6 +170,7 @@ struct SamplerResource {
SharpFetch<AmdGpu::Sampler> 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{};
@@ -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;
+3 -2
View File
@@ -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(),
+1 -1
View File
@@ -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;
@@ -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 {
+2 -1
View File
@@ -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) {