mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #1317 from PCSX2/gsdx-array-coverage
Gsdx array coverage
This commit is contained in:
commit
96b5170d8c
|
@ -2016,10 +2016,20 @@ GSOffset::GSOffset(uint32 _bp, uint32 _bw, uint32 _psm)
|
||||||
{
|
{
|
||||||
pixel.col[i] = GSLocalMemory::m_psm[_psm].rowOffset[i];
|
pixel.col[i] = GSLocalMemory::m_psm[_psm].rowOffset[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
coverages[i] = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSOffset::~GSOffset()
|
GSOffset::~GSOffset()
|
||||||
{
|
{
|
||||||
|
for(int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
_aligned_free(coverages[i]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32* GSOffset::GetPages(const GSVector4i& rect, uint32* pages, GSVector4i* bbox)
|
uint32* GSOffset::GetPages(const GSVector4i& rect, uint32* pages, GSVector4i* bbox)
|
||||||
|
@ -2030,12 +2040,12 @@ uint32* GSOffset::GetPages(const GSVector4i& rect, uint32* pages, GSVector4i* bb
|
||||||
|
|
||||||
if(bbox != NULL) *bbox = r;
|
if(bbox != NULL) *bbox = r;
|
||||||
|
|
||||||
// worst case:
|
// worst case:
|
||||||
// bp page-aligned: (w * h) / (64 * 32)
|
// bp page-aligned: (w * h) / (64 * 32)
|
||||||
// bp block-aligned: (w * h) / (8 * 8)
|
// bp block-aligned: (w * h) / (8 * 8)
|
||||||
|
|
||||||
int size = r.width() * r.height();
|
int size = r.width() * r.height();
|
||||||
|
|
||||||
int limit = MAX_PAGES + 1;
|
int limit = MAX_PAGES + 1;
|
||||||
|
|
||||||
if(pages == NULL)
|
if(pages == NULL)
|
||||||
|
@ -2058,7 +2068,7 @@ uint32* GSOffset::GetPages(const GSVector4i& rect, uint32* pages, GSVector4i* bb
|
||||||
bs.y >>= 3;
|
bs.y >>= 3;
|
||||||
|
|
||||||
uint32* RESTRICT p = pages;
|
uint32* RESTRICT p = pages;
|
||||||
|
|
||||||
for(int y = r.top; y < r.bottom; y += bs.y)
|
for(int y = r.top; y < r.bottom; y += bs.y)
|
||||||
{
|
{
|
||||||
uint32 base = block.row[y];
|
uint32 base = block.row[y];
|
||||||
|
@ -2129,4 +2139,4 @@ GSVector4i* GSOffset::GetPagesAsBits(const GSVector4i& rect, GSVector4i* pages,
|
||||||
|
|
||||||
return pages;
|
return pages;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ public:
|
||||||
Block block;
|
Block block;
|
||||||
Pixel pixel;
|
Pixel pixel;
|
||||||
|
|
||||||
|
uint32* coverages[256]; // texture page coverage based on the texture size. Lazy allocated
|
||||||
|
|
||||||
GSOffset(uint32 bp, uint32 bw, uint32 psm);
|
GSOffset(uint32 bp, uint32 bw, uint32 psm);
|
||||||
virtual ~GSOffset();
|
virtual ~GSOffset();
|
||||||
|
|
||||||
|
|
|
@ -1839,7 +1839,7 @@ bool GSTextureCache::Target::Inside(uint32 bp, uint32 bw, uint32 psm, const GSVe
|
||||||
|
|
||||||
// GSTextureCache::SourceMap
|
// GSTextureCache::SourceMap
|
||||||
|
|
||||||
void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, const GSOffset* off)
|
void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSOffset* off)
|
||||||
{
|
{
|
||||||
m_surfaces.insert(s);
|
m_surfaces.insert(s);
|
||||||
|
|
||||||
|
@ -1857,48 +1857,6 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, const GSO
|
||||||
// Remaining code will compute a list of pages that are dirty (in a similar fashion as GSOffset::GetPages)
|
// Remaining code will compute a list of pages that are dirty (in a similar fashion as GSOffset::GetPages)
|
||||||
// (Maybe GetPages could be used instead, perf opt?)
|
// (Maybe GetPages could be used instead, perf opt?)
|
||||||
// The source pointer will be stored/duplicated in all m_map[array of pages]
|
// The source pointer will be stored/duplicated in all m_map[array of pages]
|
||||||
#if 0
|
|
||||||
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
|
||||||
|
|
||||||
GSVector2i bs = (TEX0.TBP0 & 31) == 0 ? psm.pgs : psm.bs;
|
|
||||||
|
|
||||||
int tw = 1 << TEX0.TW;
|
|
||||||
int th = 1 << TEX0.TH;
|
|
||||||
|
|
||||||
for(int y = 0; y < th; y += bs.y)
|
|
||||||
{
|
|
||||||
uint32 base = off->block.row[y >> 3];
|
|
||||||
|
|
||||||
for(int x = 0; x < tw; x += bs.x)
|
|
||||||
{
|
|
||||||
uint32 page = (base + off->block.col[x >> 3]) >> 5;
|
|
||||||
|
|
||||||
if(page < MAX_PAGES)
|
|
||||||
{
|
|
||||||
m_pages[page >> 5] |= 1 << (page & 31);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(size_t i = 0; i < countof(m_pages); i++)
|
|
||||||
{
|
|
||||||
if(uint32 p = m_pages[i])
|
|
||||||
{
|
|
||||||
m_pages[i] = 0;
|
|
||||||
|
|
||||||
list<Source*>* m = &m_map[i << 5];
|
|
||||||
|
|
||||||
unsigned long j;
|
|
||||||
|
|
||||||
while(_BitScanForward(&j, p))
|
|
||||||
{
|
|
||||||
p ^= 1 << j;
|
|
||||||
|
|
||||||
m[j].push_front(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
uint32* pages = GetPagesCoverage(TEX0, off);
|
uint32* pages = GetPagesCoverage(TEX0, off);
|
||||||
for(size_t i = 0; i < countof(m_pages); i++)
|
for(size_t i = 0; i < countof(m_pages); i++)
|
||||||
{
|
{
|
||||||
|
@ -1916,21 +1874,24 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, const GSO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32* GSTextureCache::SourceMap::GetPagesCoverage(const GIFRegTEX0& TEX0, const GSOffset* off)
|
uint32* GSTextureCache::SourceMap::GetPagesCoverage(const GIFRegTEX0& TEX0, GSOffset* off)
|
||||||
{
|
{
|
||||||
uint64 hash = TEX0.u64 & 0x3ffffffffull; // TBP0 TBW PSM TW TH
|
// Performance note:
|
||||||
|
// GSOffset is a hash lookup of the following parameter TB0, TBW, PSM
|
||||||
|
// Coverage adds TW and Th (8bits). Therefore GSOffset was extended with a small array.
|
||||||
|
// Avoid the hash map overhead (memory and lookup)
|
||||||
|
|
||||||
auto it_pages = m_pages_coverage.find(hash);
|
int index = (TEX0.u64 >> 26) & 0xFF;
|
||||||
|
|
||||||
if (it_pages != m_pages_coverage.end()) return it_pages->second;
|
if (off->coverages[index])
|
||||||
|
return off->coverages[index];
|
||||||
|
|
||||||
// Aligned on 64 bytes to store the full bitmap in a single cache line
|
// Aligned on 64 bytes to store the full bitmap in a single cache line
|
||||||
uint32* pages = (uint32*)_aligned_malloc(MAX_PAGES/8, 64);
|
uint32* pages = (uint32*)_aligned_malloc(MAX_PAGES/8, 64);
|
||||||
|
|
||||||
m_pages_coverage.emplace(hash, pages);
|
off->coverages[index] = pages;
|
||||||
|
|
||||||
((GSVector4i*)pages)[0] = GSVector4i::zero();
|
((GSVector4i*)pages)[0] = GSVector4i::zero();
|
||||||
((GSVector4i*)pages)[1] = GSVector4i::zero();
|
((GSVector4i*)pages)[1] = GSVector4i::zero();
|
||||||
|
@ -1975,9 +1936,6 @@ void GSTextureCache::SourceMap::RemoveAll()
|
||||||
{
|
{
|
||||||
m_map[i].clear();
|
m_map[i].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each(m_pages_coverage.begin(), m_pages_coverage.end(), aligned_free_second());
|
|
||||||
m_pages_coverage.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSTextureCache::SourceMap::RemoveAt(Source* s)
|
void GSTextureCache::SourceMap::RemoveAt(Source* s)
|
||||||
|
|
|
@ -110,12 +110,12 @@ public:
|
||||||
|
|
||||||
SourceMap() : m_used(false) {memset(m_pages, 0, sizeof(m_pages));}
|
SourceMap() : m_used(false) {memset(m_pages, 0, sizeof(m_pages));}
|
||||||
|
|
||||||
void Add(Source* s, const GIFRegTEX0& TEX0, const GSOffset* off);
|
void Add(Source* s, const GIFRegTEX0& TEX0, GSOffset* off);
|
||||||
void RemoveAll();
|
void RemoveAll();
|
||||||
void RemovePartial();
|
void RemovePartial();
|
||||||
void RemoveAt(Source* s);
|
void RemoveAt(Source* s);
|
||||||
|
|
||||||
uint32* GetPagesCoverage(const GIFRegTEX0& TEX0, const GSOffset* off);
|
uint32* GetPagesCoverage(const GIFRegTEX0& TEX0, GSOffset* off);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in New Issue