From b2430b4d90016eb6a221224687459c1876bc5552 Mon Sep 17 00:00:00 2001 From: snowstormxd <214507868+snowstormxd@users.noreply.github.com> Date: Sun, 1 Nov 2026 21:32:04 +0000 Subject: shader_cache: batch memory-write invalidations without skipping ranges Adapt the batching from ymatrix1/Eglantine PR #237, retaining all CPU invalidations. Acquire the lock once and remove pending shaders once per write batch. Compare real cache contents with sequential invalidation across randomized overlapping writes and pending removals. Assisted-by: Codex (implementation, review, commit text and automated validation) (cherry picked from commit b65f818d7789ffadfb58fe4543b18060fd88ce53) --- src/video_core/shader_cache.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/video_core/shader_cache.cpp') diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp index 5faed0dba9..cafebaa56f 100644 --- a/src/video_core/shader_cache.cpp +++ b/src/video_core/shader_cache.cpp @@ -36,6 +36,17 @@ void ShaderCache::InvalidateRegion(VAddr addr, size_t size) { RemovePendingShaders(); } +void ShaderCache::InvalidateRegions(std::span> sequences) { + if (sequences.empty()) { + return; + } + std::scoped_lock lock{invalidation_mutex}; + for (const auto& [addr, size] : sequences) { + InvalidatePagesInRegion(addr, size); + } + RemovePendingShaders(); +} + void ShaderCache::OnCacheInvalidation(VAddr addr, size_t size) { std::scoped_lock lock{invalidation_mutex}; InvalidatePagesInRegion(addr, size); -- cgit v1.2.3 From ddbd076cfe952170b5ad331fcdbff3afdb38453f Mon Sep 17 00:00:00 2001 From: snowstormxd <214507868+snowstormxd@users.noreply.github.com> Date: Sun, 1 Nov 2026 22:04:02 +0000 Subject: shader_cache: use sorted membership for large removal batches Keep the linear path for sixteen or fewer removals. For larger batches, sort the auxiliary pointer list and binary-search it while preserving storage order and the same invalidation decisions. Existing real-cache differential tests cover both paths. Assisted-by: Codex (implementation, review, commit text and automated validation) (cherry picked from commit 7e2c8a535230d9810db07706d79130ce0f1b88f1) --- src/video_core/shader_cache.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/video_core/shader_cache.cpp') diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp index cafebaa56f..5d41dc9697 100644 --- a/src/video_core/shader_cache.cpp +++ b/src/video_core/shader_cache.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -315,10 +316,17 @@ void ShaderCache::RemovePendingShaders() { marked_for_removal.clear(); if (!removed_shaders.empty()) { - // Remove the given shaders from the cache - std::erase_if(storage, [&removed_shaders](const std::unique_ptr& shader) { - return std::ranges::find(removed_shaders, shader.get()) != removed_shaders.end(); - }); + if (removed_shaders.size() > 16) { + std::ranges::sort(removed_shaders, std::less{}); + std::erase_if(storage, [&removed_shaders](const std::unique_ptr& shader) { + return std::binary_search(removed_shaders.begin(), removed_shaders.end(), + shader.get(), std::less{}); + }); + } else { + std::erase_if(storage, [&removed_shaders](const std::unique_ptr& shader) { + return std::ranges::find(removed_shaders, shader.get()) != removed_shaders.end(); + }); + } } } -- cgit v1.2.3