softgpu: Optimize lookup of last jit func.

This is common (for example, maybe a pixel state is updated but sampler is
not), and reduces time spent in ComputeRasterizerState() quite a bit in
Darkstalkers, where jits are available (i.e. Intel currently.)
This commit is contained in:
Unknown W. Brackets 2022-12-06 19:16:19 -08:00
parent 87fb9eef37
commit 400f6abf9a
4 changed files with 59 additions and 12 deletions

View File

@ -791,11 +791,15 @@ SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id, BinManager *binner) {
if (!g_Config.bSoftwareRenderingJit)
return nullptr;
std::unique_lock<std::mutex> guard(jitCacheLock);
const size_t key = std::hash<PixelFuncID>()(id);
auto last = lastSingle_.load();
if (last.key == key)
return last.func;
std::unique_lock<std::mutex> guard(jitCacheLock);
auto it = cache_.Get(key);
if (it != nullptr) {
lastSingle_ = { key, it };
return it;
}
@ -821,7 +825,9 @@ SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id, BinManager *binner) {
if (!cache_.Get(key))
Compile(id);
return cache_.Get(key);
it = cache_.Get(key);
lastSingle_ = { key, it };
return it;
}
void PixelJitCache::Compile(const PixelFuncID &id) {

View File

@ -19,6 +19,7 @@
#include "ppsspp_config.h"
#include <atomic>
#include <string>
#include <vector>
#include <unordered_map>
@ -109,9 +110,15 @@ private:
bool Jit_ConvertFrom5551(const PixelFuncID &id, RegCache::Reg colorReg, RegCache::Reg temp1Reg, RegCache::Reg temp2Reg, bool keepAlpha);
bool Jit_ConvertFrom4444(const PixelFuncID &id, RegCache::Reg colorReg, RegCache::Reg temp1Reg, RegCache::Reg temp2Reg, bool keepAlpha);
struct LastEntry {
size_t key;
SingleFunc func;
};
DenseHashMap<size_t, SingleFunc, nullptr> cache_;
std::unordered_map<PixelFuncID, const u8 *> addresses_;
std::unordered_set<PixelFuncID> compileQueue_;
std::atomic<LastEntry> lastSingle_;
const u8 *constBlendHalf_11_4s_ = nullptr;
const u8 *constBlendInvert_11_4s_ = nullptr;

View File

@ -154,13 +154,8 @@ void SamplerJitCache::Flush() {
compileQueue_.clear();
}
NearestFunc SamplerJitCache::GetByID(const SamplerID &id, BinManager *binner) {
if (!g_Config.bSoftwareRenderingJit)
return nullptr;
NearestFunc SamplerJitCache::GetByID(const SamplerID &id, size_t key, BinManager *binner) {
std::unique_lock<std::mutex> guard(jitCacheLock);
const size_t key = std::hash<SamplerID>()(id);
auto it = cache_.Get(key);
if (it != nullptr)
return it;
@ -191,15 +186,45 @@ NearestFunc SamplerJitCache::GetByID(const SamplerID &id, BinManager *binner) {
}
NearestFunc SamplerJitCache::GetNearest(const SamplerID &id, BinManager *binner) {
return (NearestFunc)GetByID(id, binner);
if (!g_Config.bSoftwareRenderingJit)
return nullptr;
const size_t key = std::hash<SamplerID>()(id);
auto last = lastNearest_.load();
if (last.key == key)
return (NearestFunc)last.func;
auto func = GetByID(id, key, binner);
lastNearest_ = { key, func };
return (NearestFunc)func;
}
LinearFunc SamplerJitCache::GetLinear(const SamplerID &id, BinManager *binner) {
return (LinearFunc)GetByID(id, binner);
if (!g_Config.bSoftwareRenderingJit)
return nullptr;
const size_t key = std::hash<SamplerID>()(id);
auto last = lastLinear_.load();
if (last.key == key)
return (LinearFunc)last.func;
auto func = GetByID(id, key, binner);
lastLinear_ = { key, func };
return (LinearFunc)func;
}
FetchFunc SamplerJitCache::GetFetch(const SamplerID &id, BinManager *binner) {
return (FetchFunc)GetByID(id, binner);
if (!g_Config.bSoftwareRenderingJit)
return nullptr;
const size_t key = std::hash<SamplerID>()(id);
auto last = lastFetch_.load();
if (last.key == key)
return (FetchFunc)last.func;
auto func = GetByID(id, key, binner);
lastFetch_ = { key, func };
return (FetchFunc)func;
}
void SamplerJitCache::Compile(const SamplerID &id) {

View File

@ -19,6 +19,7 @@
#include "ppsspp_config.h"
#include <atomic>
#include <unordered_map>
#include <unordered_set>
#include "Common/Data/Collections/Hashmaps.h"
@ -67,7 +68,7 @@ public:
private:
void Compile(const SamplerID &id);
NearestFunc GetByID(const SamplerID &id, BinManager *binner);
NearestFunc GetByID(const SamplerID &id, size_t key, BinManager *binner);
FetchFunc CompileFetch(const SamplerID &id);
NearestFunc CompileNearest(const SamplerID &id);
LinearFunc CompileLinear(const SamplerID &id);
@ -128,9 +129,17 @@ private:
const u8 *const5551Swizzle_ = nullptr;
const u8 *const5650Swizzle_ = nullptr;
struct LastEntry {
size_t key;
NearestFunc func;
};
DenseHashMap<size_t, NearestFunc, nullptr> cache_;
std::unordered_map<SamplerID, const u8 *> addresses_;
std::unordered_set<SamplerID> compileQueue_;
std::atomic<LastEntry> lastFetch_;
std::atomic<LastEntry> lastNearest_;
std::atomic<LastEntry> lastLinear_;
};
#if defined(__clang__) || defined(__GNUC__)