From e959ec8a6219d55c3753e2ad5f3e4ff4b2fb128b Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Sat, 17 Oct 2026 07:31:15 +0100 Subject: [PATCH] GS/TC: Fix some issues with page widths --- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 26 ++++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 566f5d2b60..327a833cb3 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -1891,11 +1891,6 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const GSVector4i new_rect = (GSLocalMemory::m_psm[color_psm].bpp != GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp && (psm & 0x7) != PSMCT16) ? block_boundary_rect : rect; - // If the sizing is completely wrong on the frame vs the source when reading from alpha then it's likely the target has 2 different sizes for rgb and alpha. - // This is just changing the target width for the rect translation, it has no bearing on the actual source read or the target itself. - // Hitman Blood Money is an example of this in the theatre. - rt_tbw = (possible_shuffle || bw == 1 || GSUtil::GetChannelMask(psm) != 0x8 || frame.FBW <= bw || frame.FBW == t->m_TEX0.TBW || bw == t->m_TEX0.TBW) ? t->m_TEX0.TBW : frame.FBW; - const bool can_translate = CanTranslate(adj_bp, bw, src_psm, new_rect, t->m_TEX0.TBP0, t->m_TEX0.PSM, rt_tbw); if (can_translate) { @@ -7983,6 +7978,7 @@ void GSTextureCache::Target::RearrangeTarget(u32 new_bw, bool recycle) alloca(sizeof(GSDevice::MultiStretchRect) * static_cast(page_count))); u32 ndrects = 0; GSVector4i new_valid = GSVector4i::zero(); + GSVector4i new_drawn = GSVector4i::zero(); Update(false); @@ -8002,10 +7998,20 @@ void GSTextureCache::Target::RearrangeTarget(u32 new_bw, bool recycle) drect.filter = Nearest; drect.wmask = 0xF; - if (page == 0) - new_valid = write_page; - else - new_valid = new_valid.runion(write_page); + if (!m_valid.rintersect(read_page).rempty()) + { + if (page == 0) + new_valid = write_page; + else + new_valid = new_valid.runion(write_page); + } + if (!m_drawn_since_read.rintersect(read_page).rempty()) + { + if (page == 0) + new_drawn = write_page; + else + new_drawn = new_drawn.runion(write_page); + } } if (ndrects > 0) @@ -8032,7 +8038,9 @@ void GSTextureCache::Target::RearrangeTarget(u32 new_bw, bool recycle) m_texture = tex; m_unscaled_size = GSVector2i(new_x_size, new_y_size); m_valid = new_valid; + m_drawn_since_read = new_drawn; tex = nullptr; + m_TEX0.TBW = new_bw; } }