GS-HW: Invalidate local mem for whole texture on local->local copy

This commit is contained in:
refractionpcsx2 2023-05-14 02:02:10 +01:00
parent 5eacfe1afb
commit b0c744bd29
3 changed files with 11 additions and 7 deletions

View File

@ -979,8 +979,11 @@ void GSRendererHW::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
break; break;
} }
if(!skip) if (!skip)
g_texture_cache->InvalidateLocalMem(m_mem.GetOffset(BITBLTBUF.SBP, BITBLTBUF.SBW, BITBLTBUF.SPSM), r); {
const bool recursive_copy = (BITBLTBUF.SBP == BITBLTBUF.DBP) && (m_env.TRXDIR.XDIR == 2);
g_texture_cache->InvalidateLocalMem(m_mem.GetOffset(BITBLTBUF.SBP, BITBLTBUF.SBW, BITBLTBUF.SPSM), r, recursive_copy);
}
} }
void GSRendererHW::Move() void GSRendererHW::Move()

View File

@ -2252,8 +2252,9 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
} }
// Goal: retrive the data from the GPU to the GS memory. // Goal: retrive the data from the GPU to the GS memory.
// Called each time you want to read from the GS memory // Called each time you want to read from the GS memory.
void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r) // full_flush is set when it's a Local->Local stransfer and both src and destination are the same.
void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r, bool full_flush)
{ {
const u32 bp = off.bp(); const u32 bp = off.bp();
const u32 psm = off.psm(); const u32 psm = off.psm();
@ -2306,7 +2307,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
const bool swizzle_match = GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth; const bool swizzle_match = GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth;
// Calculate the rect offset if the BP doesn't match. // Calculate the rect offset if the BP doesn't match.
GSVector4i targetr = {}; GSVector4i targetr = {};
if (t->readbacks_since_draw > 1) if (full_flush || t->readbacks_since_draw > 1)
{ {
targetr = t->m_drawn_since_read; targetr = t->m_drawn_since_read;
} }
@ -2440,7 +2441,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
const bool swizzle_match = GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth; const bool swizzle_match = GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth;
// Calculate the rect offset if the BP doesn't match. // Calculate the rect offset if the BP doesn't match.
GSVector4i targetr = {}; GSVector4i targetr = {};
if (t->readbacks_since_draw > 1) if (full_flush || t->readbacks_since_draw > 1)
{ {
targetr = t->m_drawn_since_read; targetr = t->m_drawn_since_read;
} }

View File

@ -464,7 +464,7 @@ public:
void InvalidateVideoMemType(int type, u32 bp); void InvalidateVideoMemType(int type, u32 bp);
void InvalidateVideoMemSubTarget(GSTextureCache::Target* rt); void InvalidateVideoMemSubTarget(GSTextureCache::Target* rt);
void InvalidateVideoMem(const GSOffset& off, const GSVector4i& r, bool eewrite = false, bool target = true); void InvalidateVideoMem(const GSOffset& off, const GSVector4i& r, bool eewrite = false, bool target = true);
void InvalidateLocalMem(const GSOffset& off, const GSVector4i& r); void InvalidateLocalMem(const GSOffset& off, const GSVector4i& r, bool full_flush = false);
/// Removes any targets overlapping the specified BP and rectangle. /// Removes any targets overlapping the specified BP and rectangle.
void InvalidateVideoMemTargets(int type, u32 bp, u32 bw, u32 psm, const GSVector4i& r); void InvalidateVideoMemTargets(int type, u32 bp, u32 bw, u32 psm, const GSVector4i& r);