From d9522a7ac5cfdae225ccfbe0baf87e15272f3454 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 6 Dec 2022 20:55:52 -0800 Subject: [PATCH] softgpu: Avoid clear hazard for last cached funcs. --- GPU/Software/DrawPixel.cpp | 8 +++++--- GPU/Software/DrawPixel.h | 9 ++++++++- GPU/Software/Sampler.cpp | 16 ++++++++++------ GPU/Software/Sampler.h | 9 ++++++++- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/GPU/Software/DrawPixel.cpp b/GPU/Software/DrawPixel.cpp index 306522312d..97e84b6807 100644 --- a/GPU/Software/DrawPixel.cpp +++ b/GPU/Software/DrawPixel.cpp @@ -748,9 +748,11 @@ thread_local PixelJitCache::LastCache PixelJitCache::lastSingle_; // 256k should be plenty of space for plenty of variations. PixelJitCache::PixelJitCache() : CodeBlock(1024 * 64 * 4), cache_(64) { + lastSingle_.gen = -1; } void PixelJitCache::Clear() { + clearGen_++; CodeBlock::Clear(); cache_.Clear(); addresses_.clear(); @@ -794,13 +796,13 @@ SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id, BinManager *binner) { return nullptr; const size_t key = std::hash()(id); - if (lastSingle_.key == key) + if (lastSingle_.Match(key, clearGen_)) return lastSingle_.func; std::unique_lock guard(jitCacheLock); auto it = cache_.Get(key); if (it != nullptr) { - lastSingle_.Set(key, it); + lastSingle_.Set(key, it, clearGen_); return it; } @@ -827,7 +829,7 @@ SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id, BinManager *binner) { Compile(id); it = cache_.Get(key); - lastSingle_.Set(key, it); + lastSingle_.Set(key, it, clearGen_); return it; } diff --git a/GPU/Software/DrawPixel.h b/GPU/Software/DrawPixel.h index 4bcbf3e834..d72c04a744 100644 --- a/GPU/Software/DrawPixel.h +++ b/GPU/Software/DrawPixel.h @@ -112,16 +112,23 @@ private: struct LastCache { size_t key; SingleFunc func; + int gen = -1; - void Set(size_t k, SingleFunc f) { + bool Match(size_t k, int g) const { + return key == k && gen == g; + } + + void Set(size_t k, SingleFunc f, int g) { key = k; func = f; + gen = g; } }; DenseHashMap cache_; std::unordered_map addresses_; std::unordered_set compileQueue_; + int clearGen_ = 0; static thread_local LastCache lastSingle_; const u8 *constBlendHalf_11_4s_ = nullptr; diff --git a/GPU/Software/Sampler.cpp b/GPU/Software/Sampler.cpp index 9ad7e9a169..c748260dd4 100644 --- a/GPU/Software/Sampler.cpp +++ b/GPU/Software/Sampler.cpp @@ -104,9 +104,13 @@ thread_local SamplerJitCache::LastCache SamplerJitCache::lastLinear_; // 256k should be enough. SamplerJitCache::SamplerJitCache() : Rasterizer::CodeBlock(1024 * 64 * 4), cache_(64) { + lastFetch_.gen = -1; + lastNearest_.gen = -1; + lastLinear_.gen = -1; } void SamplerJitCache::Clear() { + clearGen_++; CodeBlock::Clear(); cache_.Clear(); addresses_.clear(); @@ -194,11 +198,11 @@ NearestFunc SamplerJitCache::GetNearest(const SamplerID &id, BinManager *binner) return nullptr; const size_t key = std::hash()(id); - if (lastNearest_.key == key) + if (lastNearest_.Match(key, clearGen_)) return (NearestFunc)lastNearest_.func; auto func = GetByID(id, key, binner); - lastNearest_.Set(key, func); + lastNearest_.Set(key, func, clearGen_); return (NearestFunc)func; } @@ -207,11 +211,11 @@ LinearFunc SamplerJitCache::GetLinear(const SamplerID &id, BinManager *binner) { return nullptr; const size_t key = std::hash()(id); - if (lastLinear_.key == key) + if (lastLinear_.Match(key, clearGen_)) return (LinearFunc)lastLinear_.func; auto func = GetByID(id, key, binner); - lastLinear_.Set(key, func); + lastLinear_.Set(key, func, clearGen_); return (LinearFunc)func; } @@ -220,11 +224,11 @@ FetchFunc SamplerJitCache::GetFetch(const SamplerID &id, BinManager *binner) { return nullptr; const size_t key = std::hash()(id); - if (lastFetch_.key == key) + if (lastFetch_.Match(key, clearGen_)) return (FetchFunc)lastFetch_.func; auto func = GetByID(id, key, binner); - lastFetch_.Set(key, func); + lastFetch_.Set(key, func, clearGen_); return (FetchFunc)func; } diff --git a/GPU/Software/Sampler.h b/GPU/Software/Sampler.h index cb989e6a32..fbe606b110 100644 --- a/GPU/Software/Sampler.h +++ b/GPU/Software/Sampler.h @@ -131,16 +131,23 @@ private: struct LastCache { size_t key; NearestFunc func; + int gen = -1; - void Set(size_t k, NearestFunc f) { + bool Match(size_t k, int g) const { + return key == k && gen == g; + } + + void Set(size_t k, NearestFunc f, int g) { key = k; func = f; + gen = g; } }; DenseHashMap cache_; std::unordered_map addresses_; std::unordered_set compileQueue_; + int clearGen_ = 0; static thread_local LastCache lastFetch_; static thread_local LastCache lastNearest_; static thread_local LastCache lastLinear_;