GSdx GSTextureCacheSW: Ported erase iterator trick. Using FastList instead of std::list. Using range loops. Using more efficient erase pattern.

This commit is contained in:
Alessandro Vetere 2017-08-04 19:52:18 +02:00 committed by Gregory Hainaut
parent 676c7b89c7
commit 965334350f
2 changed files with 36 additions and 50 deletions

View File

@ -36,48 +36,42 @@ GSTextureCacheSW::Texture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, cons
{ {
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
Texture* t = NULL; auto& m = m_map[TEX0.TBP0 >> 5];
list<Texture*>& m = m_map[TEX0.TBP0 >> 5]; for(auto i = m.begin(); i != m.end(); ++i)
for(list<Texture*>::iterator i = m.begin(); i != m.end(); ++i)
{ {
Texture* t2 = *i; Texture* t = *i;
if(((TEX0.u32[0] ^ t2->m_TEX0.u32[0]) | ((TEX0.u32[1] ^ t2->m_TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH if(((TEX0.u32[0] ^ t->m_TEX0.u32[0]) | ((TEX0.u32[1] ^ t->m_TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH
{ {
continue; continue;
} }
if((psm.trbpp == 16 || psm.trbpp == 24) && TEX0.TCC && TEXA != t2->m_TEXA) if((psm.trbpp == 16 || psm.trbpp == 24) && TEX0.TCC && TEXA != t->m_TEXA)
{ {
continue; continue;
} }
if(tw0 != 0 && t2->m_tw != tw0) if(tw0 != 0 && t->m_tw != tw0)
{ {
continue; continue;
} }
m.splice(m.begin(), m, i); // Lookup hit
m.MoveFront(i.Index());
t = t2;
t->m_age = 0; t->m_age = 0;
return t;
break;
} }
if(t == NULL) // Lookup miss
{ Texture* t = new Texture(m_state, tw0, TEX0, TEXA);
t = new Texture(m_state, tw0, TEX0, TEXA);
m_textures.insert(t); m_textures.insert(t);
for(const uint32* p = t->m_pages.n; *p != GSOffset::EOP; p++) for(const uint32* p = t->m_pages.n; *p != GSOffset::EOP; p++)
{ {
m_map[*p].push_front(t); const uint32 page = *p;
} t->m_erase_it[page] = m_map[page].InsertFront(t);
} }
return t; return t;
@ -87,25 +81,19 @@ void GSTextureCacheSW::InvalidatePages(const uint32* pages, uint32 psm)
{ {
for(const uint32* p = pages; *p != GSOffset::EOP; p++) for(const uint32* p = pages; *p != GSOffset::EOP; p++)
{ {
uint32 page = *p; const uint32 page = *p;
const list<Texture*>& map = m_map[page]; for(Texture* t : m_map[page])
for(list<Texture*>::const_iterator i = map.begin(); i != map.end(); ++i)
{ {
Texture* t = *i;
if(GSUtil::HasSharedBits(psm, t->m_sharedbits)) if(GSUtil::HasSharedBits(psm, t->m_sharedbits))
{ {
uint32* RESTRICT valid = t->m_valid; uint32* RESTRICT valid = t->m_valid;
if(t->m_repeating) if(t->m_repeating)
{ {
vector<GSVector2i>& l = t->m_p2t[page]; for(const GSVector2i& j : t->m_p2t[page])
for(vector<GSVector2i>::iterator j = l.begin(); j != l.end(); ++j)
{ {
valid[j->x] &= j->y; valid[j.x] &= j.y;
} }
} }
else else
@ -121,7 +109,7 @@ void GSTextureCacheSW::InvalidatePages(const uint32* pages, uint32 psm)
void GSTextureCacheSW::RemoveAll() void GSTextureCacheSW::RemoveAll()
{ {
for(auto &i : m_textures) delete i; for(auto i : m_textures) delete i;
m_textures.clear(); m_textures.clear();
@ -133,30 +121,26 @@ void GSTextureCacheSW::RemoveAll()
void GSTextureCacheSW::IncAge() void GSTextureCacheSW::IncAge()
{ {
for(hash_set<Texture*>::iterator i = m_textures.begin(); i != m_textures.end(); ) for(auto i = m_textures.begin(); i != m_textures.end(); )
{ {
hash_set<Texture*>::iterator j = i++; Texture* t = *i;
Texture* t = *j;
if(++t->m_age > 10) if(++t->m_age > 10)
{ {
m_textures.erase(j); i = m_textures.erase(i);
for(const uint32* p = t->m_pages.n; *p != GSOffset::EOP; p++) for(const uint32* p = t->m_pages.n; *p != GSOffset::EOP; p++)
{ {
list<Texture*>& m = m_map[*p]; const uint32 page = *p;
m_map[page].EraseIndex(t->m_erase_it[page]);
for(list<Texture*>::iterator i = m.begin(); i != m.end(); )
{
list<Texture*>::iterator j = i++;
if(*j == t) {m.erase(j); break;}
}
} }
delete t; delete t;
} }
else
{
++i;
}
} }
} }

View File

@ -22,6 +22,7 @@
#pragma once #pragma once
#include "GSRenderer.h" #include "GSRenderer.h"
#include "GSFastList.h"
class GSTextureCacheSW class GSTextureCacheSW
{ {
@ -38,8 +39,9 @@ public:
uint32 m_age; uint32 m_age;
bool m_complete; bool m_complete;
bool m_repeating; bool m_repeating;
vector<GSVector2i>* m_p2t; std::vector<GSVector2i>* m_p2t;
uint32 m_valid[MAX_PAGES]; uint32 m_valid[MAX_PAGES];
std::array<uint16, MAX_PAGES> m_erase_it;
struct {uint32 bm[16]; const uint32* n;} m_pages; struct {uint32 bm[16]; const uint32* n;} m_pages;
const uint32* RESTRICT m_sharedbits; const uint32* RESTRICT m_sharedbits;
@ -57,7 +59,7 @@ public:
protected: protected:
GSState* m_state; GSState* m_state;
hash_set<Texture*> m_textures; hash_set<Texture*> m_textures;
std::array<std::list<Texture*>, MAX_PAGES> m_map; std::array<FastList<Texture*>, MAX_PAGES> m_map;
public: public:
GSTextureCacheSW(GSState* state); GSTextureCacheSW(GSState* state);