From 5a73fa2d2316faf15a5c53bd10c5fc6a50725a98 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Wed, 26 Apr 2023 20:17:23 +0100 Subject: [PATCH] GS-TC: Update dirty read overlap on local mem invalidate --- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 2875731c60..f26a0f2b8e 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -2219,9 +2219,9 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r } const GSVector4i draw_rect = (t->readbacks_since_draw > 1) ? t->m_drawn_since_read : targetr.rintersect(t->m_drawn_since_read); - + const GSVector4i dirty_rect = t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size); // Recently made this section dirty, no need to read it. - if (draw_rect.rintersect(t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size)).eq(draw_rect)) + if (draw_rect.rintersect(dirty_rect).eq(draw_rect)) return; if (t->m_drawn_since_read.eq(GSVector4i::zero())) @@ -2234,6 +2234,10 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r if (!draw_rect.rempty()) { + // The draw rect and read rect overlap somewhat, we should update the target before downloading it. + if (!dirty_rect.rintersect(targetr).rempty()) + t->Update(false); + Read(t, draw_rect); z_found = read_start >= t->m_TEX0.TBP0 && read_end <= t->m_end_block; @@ -2356,8 +2360,9 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r continue; } + const GSVector4i dirty_rect = t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size); // Recently made this section dirty, no need to read it. - if (targetr.rintersect(t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size)).eq(targetr)) + if (targetr.rintersect(dirty_rect).eq(targetr)) { if (exact_bp) return; @@ -2378,6 +2383,10 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r continue; } + // The draw rect and read rect overlap somewhat, we should update the target before downloading it. + if (!dirty_rect.rintersect(targetr).rempty()) + t->Update(false); + Read(t, targetr); // Try to cut down how much we read next, if we can. @@ -3855,7 +3864,8 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec void GSTextureCache::Read(Target* t, const GSVector4i& r) { - if (!t->m_dirty.empty() || r.width() == 0 || r.height() == 0) + if ((!t->m_dirty.empty() && !t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size).rintersect(r).rempty()) + || r.width() == 0 || r.height() == 0) return; const GIFRegTEX0& TEX0 = t->m_TEX0;