From 4f42d95d3c034ced526b49ee91a033ddf24a97e0 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Sun, 12 Jan 2025 08:17:17 +0000 Subject: [PATCH] GS/HW: If HW Move is outside of target, make a new target instead --- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index c63531d8c14e2..cd1b87024e181 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -3758,6 +3758,19 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u if (alpha_only && (!dst || GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp != 32)) return false; + // Beware of the case where a game might create a larger texture by moving a bunch of chunks around. + if (dst && DBP == SBP && dy > dst->m_unscaled_size.y) + { + const u32 new_DBP = DBP + (((dy / GSLocalMemory::m_psm[dst->m_TEX0.PSM].pgs.y) * DBW) << 5); + + dst = nullptr; + + DBP = new_DBP; + dy = 0; + + dst = GetExactTarget(DBP, DBW, dpsm_s.depth ? DepthStencil : RenderTarget, DBP); + } + // Beware of the case where a game might create a larger texture by moving a bunch of chunks around. // We use dx/dy == 0 and the TBW check as a safeguard to make sure these go through to local memory. // We can also recreate the target if it's previously been created in the height cache with a valid size.