From 965334350f3c4b2e4ebe0b82245e718ed24fa3c0 Mon Sep 17 00:00:00 2001 From: Alessandro Vetere Date: Fri, 4 Aug 2017 19:52:18 +0200 Subject: [PATCH] GSdx GSTextureCacheSW: Ported erase iterator trick. Using FastList instead of std::list. Using range loops. Using more efficient erase pattern. --- plugins/GSdx/GSTextureCacheSW.cpp | 80 +++++++++++++------------------ plugins/GSdx/GSTextureCacheSW.h | 6 ++- 2 files changed, 36 insertions(+), 50 deletions(-) diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index 59118fa4d3..22a19e969f 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -36,48 +36,42 @@ GSTextureCacheSW::Texture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, cons { const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; - Texture* t = NULL; + auto& m = m_map[TEX0.TBP0 >> 5]; - list& m = m_map[TEX0.TBP0 >> 5]; - - for(list::iterator i = m.begin(); i != m.end(); ++i) + for(auto 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; } - 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; } - if(tw0 != 0 && t2->m_tw != tw0) + if(tw0 != 0 && t->m_tw != tw0) { continue; } - m.splice(m.begin(), m, i); - - t = t2; - + // Lookup hit + m.MoveFront(i.Index()); t->m_age = 0; - - break; + return t; } - if(t == NULL) + // Lookup miss + Texture* t = new Texture(m_state, tw0, TEX0, TEXA); + + m_textures.insert(t); + + for(const uint32* p = t->m_pages.n; *p != GSOffset::EOP; p++) { - t = new Texture(m_state, tw0, TEX0, TEXA); - - m_textures.insert(t); - - 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; @@ -87,25 +81,19 @@ void GSTextureCacheSW::InvalidatePages(const uint32* pages, uint32 psm) { for(const uint32* p = pages; *p != GSOffset::EOP; p++) { - uint32 page = *p; - - const list& map = m_map[page]; - - for(list::const_iterator i = map.begin(); i != map.end(); ++i) + const uint32 page = *p; + + for(Texture* t : m_map[page]) { - Texture* t = *i; - if(GSUtil::HasSharedBits(psm, t->m_sharedbits)) { uint32* RESTRICT valid = t->m_valid; if(t->m_repeating) { - vector& l = t->m_p2t[page]; - - for(vector::iterator j = l.begin(); j != l.end(); ++j) + for(const GSVector2i& j : t->m_p2t[page]) { - valid[j->x] &= j->y; + valid[j.x] &= j.y; } } else @@ -121,7 +109,7 @@ void GSTextureCacheSW::InvalidatePages(const uint32* pages, uint32 psm) void GSTextureCacheSW::RemoveAll() { - for(auto &i : m_textures) delete i; + for(auto i : m_textures) delete i; m_textures.clear(); @@ -133,30 +121,26 @@ void GSTextureCacheSW::RemoveAll() void GSTextureCacheSW::IncAge() { - for(hash_set::iterator i = m_textures.begin(); i != m_textures.end(); ) + for(auto i = m_textures.begin(); i != m_textures.end(); ) { - hash_set::iterator j = i++; - - Texture* t = *j; + Texture* t = *i; 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++) { - list& m = m_map[*p]; - - for(list::iterator i = m.begin(); i != m.end(); ) - { - list::iterator j = i++; - - if(*j == t) {m.erase(j); break;} - } + const uint32 page = *p; + m_map[page].EraseIndex(t->m_erase_it[page]); } delete t; } + else + { + ++i; + } } } diff --git a/plugins/GSdx/GSTextureCacheSW.h b/plugins/GSdx/GSTextureCacheSW.h index b090d2e8ae..d6454bb59e 100644 --- a/plugins/GSdx/GSTextureCacheSW.h +++ b/plugins/GSdx/GSTextureCacheSW.h @@ -22,6 +22,7 @@ #pragma once #include "GSRenderer.h" +#include "GSFastList.h" class GSTextureCacheSW { @@ -38,8 +39,9 @@ public: uint32 m_age; bool m_complete; bool m_repeating; - vector* m_p2t; + std::vector* m_p2t; uint32 m_valid[MAX_PAGES]; + std::array m_erase_it; struct {uint32 bm[16]; const uint32* n;} m_pages; const uint32* RESTRICT m_sharedbits; @@ -57,7 +59,7 @@ public: protected: GSState* m_state; hash_set m_textures; - std::array, MAX_PAGES> m_map; + std::array, MAX_PAGES> m_map; public: GSTextureCacheSW(GSState* state);