GSdx: GSOffset::GetPages was caching a ridiculous amount of data, it isn't that much slower without it.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5028 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2011-12-28 20:21:32 +00:00
parent 03bca19d99
commit 6f97ca35e2
7 changed files with 63 additions and 71 deletions

View File

@ -1994,13 +1994,9 @@ GSOffset::GSOffset(uint32 _bp, uint32 _bw, uint32 _psm)
GSOffset::~GSOffset()
{
for(hash_map<uint64, list<uint32>*>::iterator i = m_cache.begin(); i != m_cache.end(); i++)
{
delete i->second;
}
}
list<uint32>* GSOffset::GetPages(const GSVector4i& rect, GSVector4i* bbox)
vector<uint32>* GSOffset::GetPages(const GSVector4i& rect, GSVector4i* bbox)
{
GSVector2i bs = (bp & 31) == 0 ? GSLocalMemory::m_psm[psm].pgs : GSLocalMemory::m_psm[psm].bs;
@ -2008,16 +2004,11 @@ list<uint32>* GSOffset::GetPages(const GSVector4i& rect, GSVector4i* bbox)
if(bbox != NULL) *bbox = r;
uint64 r_hash;
vector<uint32>* pages = new vector<uint32>();
GSVector4i::storel(&r_hash, r.sra32(3).ps32()); // max 19-bit coordinates, should not be a problem (can shift right by 3 because it is mod8, smallest block size)
// 32-bpp worst case: (w * h) / (64 * 32), it can be a bit more if we are only block-aligned (bp & 31) != 0
hash_map<uint64, list<uint32>*>::iterator i = m_cache.find(r_hash);
if(i != m_cache.end())
{
return i->second;
}
pages->reserve(((r.width() * r.height()) >> 11) + 2);
uint32 tmp[16];
@ -2033,30 +2024,18 @@ list<uint32>* GSOffset::GetPages(const GSVector4i& rect, GSVector4i* bbox)
if(n < MAX_PAGES)
{
tmp[n >> 5] |= 1 << (n & 31);
}
}
}
uint32& row = tmp[n >> 5];
uint32 col = 1 << (n & 31);
list<uint32>* l = new list<uint32>();
for(int i = 0; i < countof(tmp); i++)
if((row & col) == 0)
{
uint32 p = tmp[i];
row |= col;
if(p == 0) continue;
unsigned long j;
while(_BitScanForward(&j, p))
{
p ^= 1 << j;
l->push_back((i << 5) + j);
pages->push_back(n);
}
}
}
}
m_cache[r_hash] = l;
return l;
return pages;
}

View File

@ -30,8 +30,6 @@
class GSOffset : public GSAlignedClass<32>
{
hash_map<uint64, list<uint32>*> m_cache;
public:
__aligned(struct, 32) Block
{
@ -53,7 +51,7 @@ public:
GSOffset(uint32 bp, uint32 bw, uint32 psm);
virtual ~GSOffset();
list<uint32>* GetPages(const GSVector4i& rect, GSVector4i* bbox = NULL);
vector<uint32>* GetPages(const GSVector4i& rect, GSVector4i* bbox = NULL);
};
struct GSPixelOffset4

View File

@ -159,9 +159,6 @@ void GSRendererSW::Draw()
GSVector4i r = bbox.rintersect(scissor);
list<uint32>* fb_pages = m_context->offset.fb->GetPages(r);
list<uint32>* zb_pages = m_context->offset.zb->GetPages(r);
shared_ptr<GSRasterizerData> data(new GSRasterizerData2(this));
GSRasterizerData2* data2 = (GSRasterizerData2*)data.get();
@ -184,13 +181,20 @@ void GSRendererSW::Draw()
//
vector<uint32>* fb_pages = NULL;
vector<uint32>* zb_pages = NULL;
if(gd->sel.fwrite)
{
fb_pages = m_context->offset.fb->GetPages(r);
m_tc->InvalidatePages(fb_pages, m_context->offset.fb->psm);
}
if(gd->sel.zwrite)
{
zb_pages = m_context->offset.zb->GetPages(r);
m_tc->InvalidatePages(zb_pages, m_context->offset.zb->psm);
}
@ -210,7 +214,7 @@ void GSRendererSW::Draw()
{
if(gd->sel.fwrite)
{
for(list<uint32>::iterator i = fb_pages->begin(); i != fb_pages->end(); i++)
for(vector<uint32>::iterator i = fb_pages->begin(); i != fb_pages->end(); i++)
{
if(m_fzb_pages[*i] & 0xffff0000) // already used as a z-buffer
{
@ -226,7 +230,7 @@ void GSRendererSW::Draw()
{
if(gd->sel.zwrite)
{
for(list<uint32>::iterator i = zb_pages->begin(); i != zb_pages->end(); i++)
for(vector<uint32>::iterator i = zb_pages->begin(); i != zb_pages->end(); i++)
{
if(m_fzb_pages[*i] & 0x0000ffff) // already used as a frame buffer
{
@ -339,13 +343,13 @@ void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
{
GSOffset* o = m_mem.GetOffset(BITBLTBUF.DBP, BITBLTBUF.DBW, BITBLTBUF.DPSM);
list<uint32>* pages = o->GetPages(r);
vector<uint32>* pages = o->GetPages(r);
m_tc->InvalidatePages(pages, o->psm);
// check if the changing pages either used as a texture or a target
for(list<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
for(vector<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
{
uint32 page = *i;
@ -358,15 +362,17 @@ void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
break;
}
}
delete pages;
}
void GSRendererSW::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut)
{
GSOffset* o = m_mem.GetOffset(BITBLTBUF.SBP, BITBLTBUF.SBW, BITBLTBUF.SPSM);
list<uint32>* pages = o->GetPages(r);
vector<uint32>* pages = o->GetPages(r);
for(list<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
for(vector<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
{
//while(m_fzb_pages[*i]) _mm_pause();
@ -377,13 +383,15 @@ void GSRendererSW::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
break;
}
}
delete pages;
}
void GSRendererSW::UsePages(const list<uint32>* pages, int type)
void GSRendererSW::UsePages(const vector<uint32>* pages, int type)
{
if(type < 2)
{
for(list<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
for(vector<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
{
ASSERT(((short*)&m_fzb_pages[*i])[type] < SHRT_MAX);
@ -392,7 +400,7 @@ void GSRendererSW::UsePages(const list<uint32>* pages, int type)
}
else
{
for(list<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
for(vector<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
{
//while(m_fzb_pages[*i]) _mm_pause();
@ -404,7 +412,7 @@ void GSRendererSW::UsePages(const list<uint32>* pages, int type)
}
}
for(list<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
for(vector<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
{
ASSERT(m_tex_pages[*i] < SHRT_MAX);
@ -413,11 +421,11 @@ void GSRendererSW::UsePages(const list<uint32>* pages, int type)
}
}
void GSRendererSW::ReleasePages(const list<uint32>* pages, int type)
void GSRendererSW::ReleasePages(const vector<uint32>* pages, int type)
{
if(type < 2)
{
for(list<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
for(vector<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
{
ASSERT(((short*)&m_fzb_pages[*i])[type] > 0);
@ -426,7 +434,7 @@ void GSRendererSW::ReleasePages(const list<uint32>* pages, int type)
}
else
{
for(list<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
for(vector<uint32>::const_iterator i = pages->begin(); i != pages->end(); i++)
{
ASSERT(m_tex_pages[*i] > 0);
@ -1139,6 +1147,9 @@ GSRendererSW::GSRasterizerData2::~GSRasterizerData2()
}
}
delete m_fb_pages;
delete m_zb_pages;
for(size_t i = 0; i < countof(m_tex_pages) && m_tex_pages[i] != NULL; i++)
{
m_parent->ReleasePages(m_tex_pages[i], 2);
@ -1154,7 +1165,7 @@ GSRendererSW::GSRasterizerData2::~GSRasterizerData2()
m_parent->m_perfmon.Put(GSPerfMon::Fillrate, pixels);
}
void GSRendererSW::GSRasterizerData2::UseTargetPages(const list<uint32>* fb_pages, const list<uint32>* zb_pages)
void GSRendererSW::GSRasterizerData2::UseTargetPages(const vector<uint32>* fb_pages, const vector<uint32>* zb_pages)
{
if(m_using_pages) return;
@ -1180,7 +1191,7 @@ void GSRendererSW::GSRasterizerData2::UseSourcePages(GSTextureCacheSW::Texture*
{
ASSERT(m_tex_pages[level] == NULL);
const list<uint32>* pages = t->m_pages.n;
const vector<uint32>* pages = t->m_pages.n;
m_tex_pages[level] = pages;

View File

@ -30,16 +30,16 @@ class GSRendererSW : public GSRendererT<GSVertexSW>
class GSRasterizerData2 : public GSRasterizerData
{
GSRendererSW* m_parent;
const list<uint32>* m_fb_pages;
const list<uint32>* m_zb_pages;
const list<uint32>* m_tex_pages[7];
const vector<uint32>* m_fb_pages;
const vector<uint32>* m_zb_pages;
const vector<uint32>* m_tex_pages[7];
bool m_using_pages;
public:
GSRasterizerData2(GSRendererSW* parent);
virtual ~GSRasterizerData2();
void UseTargetPages(const list<uint32>* fb_pages, const list<uint32>* zb_pages);
void UseTargetPages(const vector<uint32>* fb_pages, const vector<uint32>* zb_pages);
void UseSourcePages(GSTextureCacheSW::Texture* t, int level);
};
@ -63,8 +63,8 @@ protected:
void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r);
void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false);
void UsePages(const list<uint32>* pages, int type);
void ReleasePages(const list<uint32>* pages, int type);
void UsePages(const vector<uint32>* pages, int type);
void ReleasePages(const vector<uint32>* pages, int type);
bool GetScanlineGlobalData(GSRasterizerData2* data2);

View File

@ -319,11 +319,11 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* o, const GSVector4i& rect, boo
GSVector4i r;
list<uint32>* pages = o->GetPages(rect, &r);
vector<uint32>* pages = o->GetPages(rect, &r);
bool found = false;
for(list<uint32>::iterator p = pages->begin(); p != pages->end(); p++)
for(vector<uint32>::iterator p = pages->begin(); p != pages->end(); p++)
{
uint32 page = *p;
@ -372,6 +372,8 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* o, const GSVector4i& rect, boo
}
}
delete pages;
if(!target) return;
for(int type = 0; type < 2; type++)

View File

@ -74,7 +74,7 @@ GSTextureCacheSW::Texture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, cons
m_textures.insert(t);
for(list<uint32>::const_iterator i = t->m_pages.n->begin(); i != t->m_pages.n->end(); i++)
for(vector<uint32>::const_iterator i = t->m_pages.n->begin(); i != t->m_pages.n->end(); i++)
{
m_map[*i].push_front(t);
}
@ -83,9 +83,9 @@ GSTextureCacheSW::Texture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, cons
return t;
}
void GSTextureCacheSW::InvalidatePages(const list<uint32>* pages, uint32 psm)
void GSTextureCacheSW::InvalidatePages(const vector<uint32>* pages, uint32 psm)
{
for(list<uint32>::const_iterator p = pages->begin(); p != pages->end(); p++)
for(vector<uint32>::const_iterator p = pages->begin(); p != pages->end(); p++)
{
uint32 page = *p;
@ -183,7 +183,7 @@ GSTextureCacheSW::Texture::Texture(GSState* state, uint32 tw0, const GIFRegTEX0&
m_pages.n = m_offset->GetPages(GSVector4i(0, 0, 1 << TEX0.TW, 1 << TEX0.TH));
for(list<uint32>::const_iterator i = m_pages.n->begin(); i != m_pages.n->end(); i++)
for(vector<uint32>::const_iterator i = m_pages.n->begin(); i != m_pages.n->end(); i++)
{
uint32 page = *i;
@ -200,6 +200,8 @@ GSTextureCacheSW::Texture::Texture(GSState* state, uint32 tw0, const GIFRegTEX0&
GSTextureCacheSW::Texture::~Texture()
{
delete m_pages.n;
if(m_buff)
{
_aligned_free(m_buff);

View File

@ -40,7 +40,7 @@ public:
bool m_repeating;
list<GSVector2i>* m_p2t;
uint32 m_valid[MAX_PAGES];
struct {uint32 bm[16]; const list<uint32>* n;} m_pages;
struct {uint32 bm[16]; const vector<uint32>* n;} m_pages;
// m_valid
// fast mode: each uint32 bits map to the 32 blocks of that page
@ -64,7 +64,7 @@ public:
Texture* Lookup(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, uint32 tw0 = 0);
void InvalidatePages(const list<uint32>* pages, uint32 psm);
void InvalidatePages(const vector<uint32>* pages, uint32 psm);
void RemoveAll();
void RemoveAt(Texture* t);