From 24da16703dd2a9f883d80f3c5c0280d12767b5ea Mon Sep 17 00:00:00 2001 From: snowstormxd <214507868+snowstormxd@users.noreply.github.com> Date: Sun, 1 Nov 2026 22:04:01 +0000 Subject: texture_cache: clear only exposed descriptor bitmap words Avoid zeroing unused preallocation during invalidation and pool refresh. Clear newly exposed words whenever limits grow, bound clearing to allocated storage, and test word/allocation boundaries, shrink/regrowth and malformed large limits. Assisted-by: Codex (implementation, review, commit text and automated validation) (cherry picked from commit 4bc1ae01f79cef43be016504c850ca8a6998457a) --- src/video_core/texture_cache/descriptor_table.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/video_core/texture_cache') diff --git a/src/video_core/texture_cache/descriptor_table.h b/src/video_core/texture_cache/descriptor_table.h index 32ce01eeed..a441e572de 100644 --- a/src/video_core/texture_cache/descriptor_table.h +++ b/src/video_core/texture_cache/descriptor_table.h @@ -39,7 +39,7 @@ public: [[nodiscard]] std::pair Read(const MemoryManager& gpu_memory, u32 index) noexcept { DEBUG_ASSERT(index <= current_limit); if (invalidated) { - std::ranges::fill(read_descriptors, 0); + ClearReadDescriptors(); invalidated = false; } const GPUVAddr gpu_addr = current_gpu_addr + index * sizeof(T); @@ -63,10 +63,8 @@ public: // Mario Brothership reallocates a lot of times, so use aggressive pre-alloc sizes // std::vector by default uses quadratic growth, but that isn't even enough to satisfy brothership const size_t num_descriptors = ((limit + 0x80000) & (~0x7ffff)) + 1; - size_t old_size = read_descriptors.size(); read_descriptors.resize(Common::DivCeil(num_descriptors, 64U)); - old_size = (std::min)(old_size, read_descriptors.size()); - std::fill(read_descriptors.begin(), read_descriptors.begin() + old_size, 0); + ClearReadDescriptors(); invalidated = false; // descriptors.resize(num_descriptors); @@ -77,6 +75,13 @@ public: GPUVAddr current_gpu_addr{}; u32 current_limit{}; bool invalidated{}; ///< read_descriptors is to be cleared before the next read + +private: + void ClearReadDescriptors() noexcept { + // Reserved capacity is not addressable. A later limit increase clears its new range. + const size_t words = (std::min)(read_descriptors.size(), size_t{current_limit} / 64 + 1); + std::fill_n(read_descriptors.begin(), words, u64{0}); + } }; } // namespace VideoCommon -- cgit v1.2.3