From 6f97ca35e23edacecb3353c40b5fa8f451787ef4 Mon Sep 17 00:00:00 2001 From: gabest11 Date: Wed, 28 Dec 2011 20:21:32 +0000 Subject: [PATCH] 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 --- plugins/GSdx/GSLocalMemory.cpp | 51 +++++++++---------------------- plugins/GSdx/GSLocalMemory.h | 4 +-- plugins/GSdx/GSRendererSW.cpp | 47 +++++++++++++++++----------- plugins/GSdx/GSRendererSW.h | 12 ++++---- plugins/GSdx/GSTextureCache.cpp | 6 ++-- plugins/GSdx/GSTextureCacheSW.cpp | 10 +++--- plugins/GSdx/GSTextureCacheSW.h | 4 +-- 7 files changed, 63 insertions(+), 71 deletions(-) diff --git a/plugins/GSdx/GSLocalMemory.cpp b/plugins/GSdx/GSLocalMemory.cpp index 51140a3315..4d8a62c1d7 100644 --- a/plugins/GSdx/GSLocalMemory.cpp +++ b/plugins/GSdx/GSLocalMemory.cpp @@ -1994,13 +1994,9 @@ GSOffset::GSOffset(uint32 _bp, uint32 _bw, uint32 _psm) GSOffset::~GSOffset() { - for(hash_map*>::iterator i = m_cache.begin(); i != m_cache.end(); i++) - { - delete i->second; - } } -list* GSOffset::GetPages(const GSVector4i& rect, GSVector4i* bbox) +vector* 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* GSOffset::GetPages(const GSVector4i& rect, GSVector4i* bbox) if(bbox != NULL) *bbox = r; - uint64 r_hash; + vector* pages = new vector(); - 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*>::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* 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* l = new list(); - - 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; } diff --git a/plugins/GSdx/GSLocalMemory.h b/plugins/GSdx/GSLocalMemory.h index d8fa7e7dc1..798d5da4a7 100644 --- a/plugins/GSdx/GSLocalMemory.h +++ b/plugins/GSdx/GSLocalMemory.h @@ -30,8 +30,6 @@ class GSOffset : public GSAlignedClass<32> { - hash_map*> m_cache; - public: __aligned(struct, 32) Block { @@ -53,7 +51,7 @@ public: GSOffset(uint32 bp, uint32 bw, uint32 psm); virtual ~GSOffset(); - list* GetPages(const GSVector4i& rect, GSVector4i* bbox = NULL); + vector* GetPages(const GSVector4i& rect, GSVector4i* bbox = NULL); }; struct GSPixelOffset4 diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 1a50ae0c90..dc97a7ae20 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -159,9 +159,6 @@ void GSRendererSW::Draw() GSVector4i r = bbox.rintersect(scissor); - list* fb_pages = m_context->offset.fb->GetPages(r); - list* zb_pages = m_context->offset.zb->GetPages(r); - shared_ptr data(new GSRasterizerData2(this)); GSRasterizerData2* data2 = (GSRasterizerData2*)data.get(); @@ -184,13 +181,20 @@ void GSRendererSW::Draw() // + vector* fb_pages = NULL; + vector* 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::iterator i = fb_pages->begin(); i != fb_pages->end(); i++) + for(vector::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::iterator i = zb_pages->begin(); i != zb_pages->end(); i++) + for(vector::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* pages = o->GetPages(r); + vector* 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::const_iterator i = pages->begin(); i != pages->end(); i++) + for(vector::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* pages = o->GetPages(r); + vector* pages = o->GetPages(r); - for(list::const_iterator i = pages->begin(); i != pages->end(); i++) + for(vector::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* pages, int type) +void GSRendererSW::UsePages(const vector* pages, int type) { if(type < 2) { - for(list::const_iterator i = pages->begin(); i != pages->end(); i++) + for(vector::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* pages, int type) } else { - for(list::const_iterator i = pages->begin(); i != pages->end(); i++) + for(vector::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* pages, int type) } } - for(list::const_iterator i = pages->begin(); i != pages->end(); i++) + for(vector::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* pages, int type) } } -void GSRendererSW::ReleasePages(const list* pages, int type) +void GSRendererSW::ReleasePages(const vector* pages, int type) { if(type < 2) { - for(list::const_iterator i = pages->begin(); i != pages->end(); i++) + for(vector::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* pages, int type) } else { - for(list::const_iterator i = pages->begin(); i != pages->end(); i++) + for(vector::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* fb_pages, const list* zb_pages) +void GSRendererSW::GSRasterizerData2::UseTargetPages(const vector* fb_pages, const vector* 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* pages = t->m_pages.n; + const vector* pages = t->m_pages.n; m_tex_pages[level] = pages; diff --git a/plugins/GSdx/GSRendererSW.h b/plugins/GSdx/GSRendererSW.h index 54d1236941..21e3274b8d 100644 --- a/plugins/GSdx/GSRendererSW.h +++ b/plugins/GSdx/GSRendererSW.h @@ -30,16 +30,16 @@ class GSRendererSW : public GSRendererT class GSRasterizerData2 : public GSRasterizerData { GSRendererSW* m_parent; - const list* m_fb_pages; - const list* m_zb_pages; - const list* m_tex_pages[7]; + const vector* m_fb_pages; + const vector* m_zb_pages; + const vector* m_tex_pages[7]; bool m_using_pages; public: GSRasterizerData2(GSRendererSW* parent); virtual ~GSRasterizerData2(); - void UseTargetPages(const list* fb_pages, const list* zb_pages); + void UseTargetPages(const vector* fb_pages, const vector* 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* pages, int type); - void ReleasePages(const list* pages, int type); + void UsePages(const vector* pages, int type); + void ReleasePages(const vector* pages, int type); bool GetScanlineGlobalData(GSRasterizerData2* data2); diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index d5574b9231..01a2e6b21f 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -319,11 +319,11 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* o, const GSVector4i& rect, boo GSVector4i r; - list* pages = o->GetPages(rect, &r); + vector* pages = o->GetPages(rect, &r); bool found = false; - for(list::iterator p = pages->begin(); p != pages->end(); p++) + for(vector::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++) diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index 93d026fadf..1f0a8fb707 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -74,7 +74,7 @@ GSTextureCacheSW::Texture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, cons m_textures.insert(t); - for(list::const_iterator i = t->m_pages.n->begin(); i != t->m_pages.n->end(); i++) + for(vector::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* pages, uint32 psm) +void GSTextureCacheSW::InvalidatePages(const vector* pages, uint32 psm) { - for(list::const_iterator p = pages->begin(); p != pages->end(); p++) + for(vector::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::const_iterator i = m_pages.n->begin(); i != m_pages.n->end(); i++) + for(vector::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); diff --git a/plugins/GSdx/GSTextureCacheSW.h b/plugins/GSdx/GSTextureCacheSW.h index 0ac12dcbec..7142d53f42 100644 --- a/plugins/GSdx/GSTextureCacheSW.h +++ b/plugins/GSdx/GSTextureCacheSW.h @@ -40,7 +40,7 @@ public: bool m_repeating; list* m_p2t; uint32 m_valid[MAX_PAGES]; - struct {uint32 bm[16]; const list* n;} m_pages; + struct {uint32 bm[16]; const vector* 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* pages, uint32 psm); + void InvalidatePages(const vector* pages, uint32 psm); void RemoveAll(); void RemoveAt(Texture* t);