mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
03bca19d99
commit
6f97ca35e2
|
@ -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)
|
||||
|
||||
hash_map<uint64, list<uint32>*>::iterator i = m_cache.find(r_hash);
|
||||
|
||||
if(i != m_cache.end())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
// 32-bpp worst case: (w * h) / (64 * 32), it can be a bit more if we are only block-aligned (bp & 31) != 0
|
||||
|
||||
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);
|
||||
|
||||
if((row & col) == 0)
|
||||
{
|
||||
row |= col;
|
||||
|
||||
pages->push_back(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list<uint32>* l = new list<uint32>();
|
||||
|
||||
for(int i = 0; i < countof(tmp); i++)
|
||||
{
|
||||
uint32 p = tmp[i];
|
||||
|
||||
if(p == 0) continue;
|
||||
|
||||
unsigned long j;
|
||||
|
||||
while(_BitScanForward(&j, p))
|
||||
{
|
||||
p ^= 1 << j;
|
||||
|
||||
l->push_back((i << 5) + j);
|
||||
}
|
||||
}
|
||||
|
||||
m_cache[r_hash] = l;
|
||||
|
||||
return l;
|
||||
return pages;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue