softgpu: Avoid clear hazard for last cached funcs.

This commit is contained in:
Unknown W. Brackets 2022-12-06 20:55:52 -08:00
parent eda3ce556e
commit d9522a7ac5
4 changed files with 31 additions and 11 deletions

View File

@ -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<PixelFuncID>()(id);
if (lastSingle_.key == key)
if (lastSingle_.Match(key, clearGen_))
return lastSingle_.func;
std::unique_lock<std::mutex> 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;
}

View File

@ -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<size_t, SingleFunc, nullptr> cache_;
std::unordered_map<PixelFuncID, const u8 *> addresses_;
std::unordered_set<PixelFuncID> compileQueue_;
int clearGen_ = 0;
static thread_local LastCache lastSingle_;
const u8 *constBlendHalf_11_4s_ = nullptr;

View File

@ -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<SamplerID>()(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<SamplerID>()(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<SamplerID>()(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;
}

View File

@ -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<size_t, NearestFunc, nullptr> cache_;
std::unordered_map<SamplerID, const u8 *> addresses_;
std::unordered_set<SamplerID> compileQueue_;
int clearGen_ = 0;
static thread_local LastCache lastFetch_;
static thread_local LastCache lastNearest_;
static thread_local LastCache lastLinear_;