mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Optimize linked shader lookup in ApplyShader().
We already iterate all (skipping that with an if helps, though), and the list of shaders in most games is pretty small. Using a map is not gaining much, and actually makes the whole thing slower. Cuts from 9.84% time in Tales of Phantasia X (lots of flushes) to 1.85%.
This commit is contained in:
parent
6ce949a743
commit
386d51081c
2 changed files with 28 additions and 18 deletions
|
@ -433,13 +433,13 @@ void ShaderManager::DirtyUniform(u32 what) {
|
|||
}
|
||||
|
||||
void ShaderManager::Clear() {
|
||||
for (LinkedShaderCache::iterator iter = linkedShaderCache.begin(); iter != linkedShaderCache.end(); ++iter) {
|
||||
for (auto iter = linkedShaderCache.begin(); iter != linkedShaderCache.end(); ++iter) {
|
||||
delete iter->ls;
|
||||
}
|
||||
for (auto iter = fsCache.begin(); iter != fsCache.end(); ++iter) {
|
||||
delete iter->second;
|
||||
}
|
||||
for (FSCache::iterator iter = fsCache.begin(); iter != fsCache.end(); ++iter) {
|
||||
delete iter->second;
|
||||
}
|
||||
for (VSCache::iterator iter = vsCache.begin(); iter != vsCache.end(); ++iter) {
|
||||
for (auto iter = vsCache.begin(); iter != vsCache.end(); ++iter) {
|
||||
delete iter->second;
|
||||
}
|
||||
linkedShaderCache.clear();
|
||||
|
@ -494,12 +494,6 @@ LinkedShader *ShaderManager::ApplyShader(int prim) {
|
|||
lastShader->stop();
|
||||
}
|
||||
|
||||
// Deferred dirtying! Let's see if we can make this even more clever later.
|
||||
for (LinkedShaderCache::iterator iter = linkedShaderCache.begin(); iter != linkedShaderCache.end(); ++iter) {
|
||||
iter->second->dirtyUniforms |= shaderSwitchDirty;
|
||||
}
|
||||
shaderSwitchDirty = 0;
|
||||
|
||||
lastVSID = VSID;
|
||||
lastFSID = FSID;
|
||||
|
||||
|
@ -541,15 +535,23 @@ LinkedShader *ShaderManager::ApplyShader(int prim) {
|
|||
}
|
||||
|
||||
// Okay, we have both shaders. Let's see if there's a linked one.
|
||||
std::pair<Shader*, Shader*> linkedID(vs, fs);
|
||||
LinkedShader *ls = NULL;
|
||||
|
||||
LinkedShaderCache::iterator iter = linkedShaderCache.find(linkedID);
|
||||
LinkedShader *ls;
|
||||
if (iter == linkedShaderCache.end()) {
|
||||
for (auto iter = linkedShaderCache.begin(); iter != linkedShaderCache.end(); ++iter) {
|
||||
// Deferred dirtying! Let's see if we can make this even more clever later.
|
||||
iter->ls->dirtyUniforms |= shaderSwitchDirty;
|
||||
|
||||
if (iter->vs == vs && iter->fs == fs) {
|
||||
ls = iter->ls;
|
||||
}
|
||||
}
|
||||
shaderSwitchDirty = 0;
|
||||
|
||||
if (ls == NULL) {
|
||||
ls = new LinkedShader(vs, fs, vs->UseHWTransform()); // This does "use" automatically
|
||||
linkedShaderCache[linkedID] = ls;
|
||||
const LinkedShaderCacheEntry entry(vs, fs, ls);
|
||||
linkedShaderCache.push_back(entry);
|
||||
} else {
|
||||
ls = iter->second;
|
||||
ls->use();
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,15 @@ public:
|
|||
private:
|
||||
void Clear();
|
||||
|
||||
typedef std::map<std::pair<Shader *, Shader *>, LinkedShader *> LinkedShaderCache;
|
||||
struct LinkedShaderCacheEntry {
|
||||
LinkedShaderCacheEntry(Shader *vs_, Shader *fs_, LinkedShader *ls_)
|
||||
: vs(vs_), fs(fs_), ls(ls_) { }
|
||||
|
||||
Shader *vs;
|
||||
Shader *fs;
|
||||
LinkedShader *ls;
|
||||
};
|
||||
typedef std::vector<LinkedShaderCacheEntry> LinkedShaderCache;
|
||||
|
||||
LinkedShaderCache linkedShaderCache;
|
||||
FragmentShaderID lastFSID;
|
||||
|
|
Loading…
Add table
Reference in a new issue