From e6ad87072df25f97c7d8ea761d8e40c113da88ca Mon Sep 17 00:00:00 2001 From: nmzik Date: Mon, 24 Aug 2026 01:12:41 +0200 Subject: [PATCH] renderer: avoid speculative buffer LRU touches --- .../host_gpu/renderer/cache/bufferCache.cpp | 1 - tests/ShaderRecompilerComputeTests.cpp | 37 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/graphics/host_gpu/renderer/cache/bufferCache.cpp b/src/graphics/host_gpu/renderer/cache/bufferCache.cpp index f98c45a7c..889af21f2 100644 --- a/src/graphics/host_gpu/renderer/cache/bufferCache.cpp +++ b/src/graphics/host_gpu/renderer/cache/bufferCache.cpp @@ -307,7 +307,6 @@ BufferId BufferCache::FindBuffer(uint64_t vaddr, uint64_t size) { if (owner != nullptr && *owner) { auto& buffer = m_slot_buffers[*owner]; if (buffer.IsInBounds(vaddr, size)) { - TouchBuffer(buffer); return *owner; } } diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 43b637313..2a439042b 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -3296,6 +3296,43 @@ public: cache, starvation_retired), "critical GC did not immediately free the skipped dirty owners"); + constexpr uint64_t lookup_only_offset = 0x218000; + constexpr uint64_t obtained_offset = 0x220000; + constexpr uint64_t residency_size = + 2 * BufferCache::CACHING_PAGE_SIZE; + BufferCacheTestAccess::SetGarbageCollectionThresholds( + cache, std::numeric_limits::max(), + std::numeric_limits::max()); + const auto lookup_only = cache.FindBuffer( + base + lookup_only_offset, residency_size); + const auto obtained = + cache.FindBuffer(base + obtained_offset, residency_size); + for (uint32_t tick = 0; tick <= 160; tick++) { + cache.RunGarbageCollector(); + } + Require(name, "lookup-only owner identity", + cache.FindBuffer(base + lookup_only_offset, residency_size) == + lookup_only, + "lookup-only discovery replaced its valid Buffer owner"); + const auto [obtained_buffer, obtained_buffer_offset] = cache.ObtainBuffer( + base + obtained_offset, residency_size, false, false, obtained); + BufferCacheTestAccess::SetGarbageCollectionThresholds( + cache, 0, std::numeric_limits::max()); + cache.RunGarbageCollector(); + Require(name, "lookup versus acquisition residency", + !cache.IsRegionRegistered(base + lookup_only_offset, + residency_size) && + !BufferCacheTestAccess::PageOwner( + cache, base + lookup_only_offset) && + obtained_buffer == &cache.GetBuffer(obtained) && + obtained_buffer_offset == 0 && + cache.IsRegionRegistered(base + obtained_offset, + residency_size) && + BufferCacheTestAccess::PageOwner( + cache, base + obtained_offset) == obtained, + "lookup refreshed residency or actual acquisition did not"); + BufferCacheTestAccess::SetGarbageCollectionThresholds(cache, 0, 0); + auto unmap_allocation = cache.ObtainBuffer( base + unmap_offset, sizeof(unmap_value), true, false); Require(name, "direct-invalidation allocation",