GS-TC: Delete fully dirtied old targets

This commit is contained in:
refractionpcsx2 2023-05-13 07:00:10 +01:00
parent e61d8f2f8f
commit 2f985b479e
2 changed files with 100 additions and 12 deletions

View File

@ -94,6 +94,19 @@ void GSTextureCache::RemoveAll()
m_surface_offset_cache.clear();
}
bool GSTextureCache::FullRectDirty(Target* target)
{
RGBAMask rgba;
rgba._u32 = GSUtil::GetChannelMask(target->m_TEX0.PSM);
// One complete dirty rect, not pieces (Add dirty rect function should be able to join these all together).
if (target->m_age > 2 && target->m_dirty.size() == 1 && rgba._u32 == target->m_dirty[0].rgba._u32 && target->m_valid.rintersect(target->m_dirty[0].r).eq(target->m_valid))
{
return true;
}
return false;
}
void GSTextureCache::AddDirtyRectTarget(Target* target, GSVector4i rect, u32 psm, u32 bw, RGBAMask rgba, bool req_linear)
{
bool skipdirty = false;
@ -1827,12 +1840,22 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
GL_CACHE("TC: Dirty Target(%s) (0x%x) r(%d,%d,%d,%d)", to_string(type),
t->m_TEX0.TBP0, r.x, r.y, r.z, r.w);
if (eewrite)
t->m_age = 0;
AddDirtyRectTarget(t, r, psm, bw, rgba);
++i;
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
continue;
}
if (eewrite)
t->m_age = 0;
i++;
continue;
}
else
@ -1867,6 +1890,15 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
r.z,
r.w);
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
continue;
}
can_erase = false;
}
else
@ -1884,6 +1916,15 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
{
DirtyRectByPage(bp, psm, bw, t, r);
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
continue;
}
if (eewrite)
t->m_age = 0;
@ -1908,6 +1949,15 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
}
DirtyRectByPage(bp & ~((1 << 5) - 1), psm, bw, t, new_rect);
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
continue;
}
if (eewrite)
t->m_age = 0;
@ -1934,6 +1984,7 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
so.b2a_offset.w, psm_str(psm), bp, bw, r.x, r.y, r.z, r.w);
AddDirtyRectTarget(t, so.b2a_offset, psm, bw, rgba);
can_erase = false;
}
else
@ -2005,11 +2056,20 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
GL_CACHE("TC: Dirty After Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
if (eewrite)
t->m_age = 0;
const GSVector4i dirty_r = GSVector4i(r.left, r.top - y, r.right, r.bottom - y);
AddDirtyRectTarget(t, dirty_r, psm, bw, rgba);
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
}
if (t && eewrite)
t->m_age = 0;
continue;
}
}
@ -2035,11 +2095,20 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
t->m_TEX0.TBP0, t->m_end_block,
r.left, r.top + y, r.right, r.bottom + y, bw);
if (eewrite)
t->m_age = 0;
const GSVector4i dirty_r = GSVector4i(r.left, r.top + y, r.right, r.bottom + y);
AddDirtyRectTarget(t, dirty_r, psm, bw, rgba);
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
}
if (t && eewrite)
t->m_age = 0;
continue;
}
}
@ -2108,6 +2177,15 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
{
DirtyRectByPage(bp, psm, bw, t, r);
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
continue;
}
if (eewrite)
t->m_age = 0;
}
@ -2151,10 +2229,19 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
const SurfaceOffset so = ComputeSurfaceOffset(sok);
if (so.is_valid)
{
AddDirtyRectTarget(t, so.b2a_offset, t->m_TEX0.PSM, t->m_TEX0.TBW, rgba);
if (FullRectDirty(t))
{
i = list.erase(j);
GL_CACHE("TC: Remove Target(%s) (0x%x)", to_string(type),
t->m_TEX0.TBP0);
delete t;
continue;
}
if (eewrite)
t->m_age = 0;
AddDirtyRectTarget(t, so.b2a_offset, t->m_TEX0.PSM, t->m_TEX0.TBW, rgba);
}
}
}

View File

@ -438,6 +438,7 @@ public:
void RemoveAll();
void ReadbackAll();
void AddDirtyRectTarget(Target* target, GSVector4i rect, u32 psm, u32 bw, RGBAMask rgba, bool req_linear = false);
bool FullRectDirty(Target* target);
bool CanTranslate(u32 bp, u32 bw, u32 spsm, GSVector4i r, u32 dbp, u32 dpsm, u32 dbw);
GSVector4i TranslateAlignedRectByPage(Target* t, u32 sbp, u32 spsm, u32 sbw, GSVector4i src_r, bool is_invalidation = false);
void DirtyRectByPage(u32 sbp, u32 spsm, u32 sbw, Target* t, GSVector4i src_r);