GS-HW: On overwrite of large incompatible format texture, erase old.

This commit is contained in:
refractionpcsx2 2023-02-09 03:58:46 +00:00
parent 892d3a370d
commit 16989f2122
1 changed files with 38 additions and 28 deletions

View File

@ -1134,9 +1134,10 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
// Possibly because the block layout is opposite for the 32bit colour and depth, it never actually overwrites the depth, so this is kind of a miss detection. // Possibly because the block layout is opposite for the 32bit colour and depth, it never actually overwrites the depth, so this is kind of a miss detection.
// The new code rightfully calculates that the depth does not become dirty, but in other cases, like bigger draws of the same format // The new code rightfully calculates that the depth does not become dirty, but in other cases, like bigger draws of the same format
// it might become invalid, so we check below and erase as before if so. // it might become invalid, so we check below and erase as before if so.
bool can_erase = found; bool can_erase = true;
if (!found && t->m_age <= 1) if (!found && t->m_age <= 1)
{ {
// Compatible formats and same width, probably updating the same texture, so just mark it as dirty.
if (bw == t->m_TEX0.TBW && GSLocalMemory::m_psm[psm].bpp == GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp) if (bw == t->m_TEX0.TBW && GSLocalMemory::m_psm[psm].bpp == GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp)
{ {
AddDirtyRectTarget(t, rect, psm, bw); AddDirtyRectTarget(t, rect, psm, bw);
@ -1158,8 +1159,17 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
r.y, r.y,
r.z, r.z,
r.w); r.w);
can_erase = false;
} }
else else
{
// Incompatible format write, small writes *should* be okay (Destruction Derby Arenas) and matching bpp should be fine.
// If it's overwriting a good chunk of the texture, it's more than likely a different texture, so kill it (Dragon Quest 8).
const GSLocalMemory::psm_t& t_psm_s = GSLocalMemory::m_psm[psm];
const u32 bp_end = t_psm_s.info.bn(r.z - 1, r.w - 1, bp, bw);
if (GSLocalMemory::m_psm[psm].bpp == GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp ||
((100.0f / static_cast<float>(t->m_end_block - t->m_TEX0.TBP0)) * static_cast<float>(bp_end - bp)) < 20.0f)
{ {
SurfaceOffset so = ComputeSurfaceOffset(off, r, t); SurfaceOffset so = ComputeSurfaceOffset(off, r, t);
if (so.is_valid) if (so.is_valid)
@ -1184,15 +1194,11 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
r.z, r.z,
r.w); r.w);
if (eewrite) can_erase = false;
t->m_age = 0; }
} }
else
can_erase = true;
} }
} }
else
can_erase = true;
if (can_erase) if (can_erase)
{ {
@ -1203,7 +1209,11 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
delete t; delete t;
} }
else else
{
if (eewrite)
t->m_age = 0;
++i; ++i;
}
continue; continue;
} }
} }