Skip to content

Commit

Permalink
gsdx tc: save list iterator to allow fast removal
Browse files Browse the repository at this point in the history
ZoE2:
RemoveAt overhead plummet to 0.5%. It was 17% !

However insertion is a bit slower. Due to the begin() after the push_front

v2: use std:: for lists and arrays
  • Loading branch information
gregory38 committed Jan 15, 2017
1 parent 87fc4c1 commit d1315b6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
29 changes: 21 additions & 8 deletions plugins/GSdx/GSTextureCache.cpp
Expand Up @@ -1610,6 +1610,9 @@ GSTextureCache::Source::Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFR
{
m_p2t = r->m_mem.GetPage2TileMap(m_TEX0);
}

// will be useless with texture page coverage
m_erase_it.fill(list<Source*>::iterator(0));
}
}

Expand Down Expand Up @@ -1982,8 +1985,10 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSOffset*
// TODO

// GH: I don't know why but it seems we only consider the first page for a render target
size_t page = TEX0.TBP0 >> 5;

m_map[TEX0.TBP0 >> 5].push_front(s);
m_map[page].push_front(s);
s->m_erase_it[page] = m_map[page].begin();

return;
}
Expand All @@ -1997,6 +2002,7 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSOffset*
if(uint32 p = pages[i])
{
list<Source*>* m = &m_map[i << 5];
auto* e = &s->m_erase_it[i << 5];

unsigned long j;

Expand All @@ -2008,6 +2014,7 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSOffset*
p ^= 1 << j;

m[j].push_front(s);
e[j] = m[j].begin();
}
}
}
Expand Down Expand Up @@ -2083,16 +2090,22 @@ void GSTextureCache::SourceMap::RemoveAt(Source* s)
s->m_texture ? s->m_texture->GetID() : 0,
s->m_TEX0.TBP0);

// Source (except render target) is duplicated for each page they use.
for(size_t start = s->m_TEX0.TBP0 >> 5, end = s->m_target ? start : countof(m_map) - 1; start <= end; start++)
if (s->m_target)
{
list<Source*>& m = m_map[start];
size_t page = s->m_TEX0.TBP0 >> 5;
ASSERT(*s->m_erase_it[page] == s);
m_map[page].erase(s->m_erase_it[page]);

for(list<Source*>::iterator i = m.begin(); i != m.end(); )
}
else
{
// Source is duplicated for each page they use.
for(size_t page = s->m_TEX0.TBP0 >> 5, end = countof(m_map) - 1; page <= end; page++)
{
list<Source*>::iterator j = i++;

if(*j == s) {m.erase(j); break;}
if (s->m_erase_it[page] != list<Source*>::iterator(0)) {
ASSERT(*s->m_erase_it[page] == s);
m_map[page].erase(s->m_erase_it[page]);
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions plugins/GSdx/GSTextureCache.h
Expand Up @@ -72,6 +72,8 @@ class GSTextureCache
// so it can be used to access un-converted data for the current draw call.
GSTexture* m_from_target;
GIFRegTEX0 m_layer_TEX0[7]; // Detect already loaded value
// Keep an GSTextureCache::m_map iterator to allow fast erase
std::array<std::list<Source*>::iterator, MAX_PAGES> m_erase_it;

public:
Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, uint8* temp, bool dummy_container = false);
Expand Down Expand Up @@ -106,7 +108,7 @@ class GSTextureCache
public:
hash_set<Source*> m_surfaces;
hash_map<uint64, uint32*> m_pages_coverage;
list<Source*> m_map[MAX_PAGES];
std::list<Source*> m_map[MAX_PAGES];
uint32 m_pages[16]; // bitmap of all pages
bool m_used;

Expand All @@ -123,7 +125,7 @@ class GSTextureCache
protected:
GSRenderer* m_renderer;
SourceMap m_src;
list<Target*> m_dst[2];
std::list<Target*> m_dst[2];
bool m_paltex;
int m_spritehack;
bool m_preload_frame;
Expand Down
1 change: 1 addition & 0 deletions plugins/GSdx/stdafx.h
Expand Up @@ -102,6 +102,7 @@ typedef int64 sint64;

#include <complex>
#include <string>
#include <array>
#include <vector>
#include <list>
#include <map>
Expand Down

0 comments on commit d1315b6

Please sign in to comment.