mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-19 21:52:45 +00:00
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:
parent
87fb9eef37
commit
400f6abf9a
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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__)
|
||||
|
Loading…
x
Reference in New Issue
Block a user