From a38dd74d0eb206b90a54b5a9e18ce65226f62205 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Tue, 16 Apr 2024 11:06:58 +0100 Subject: [PATCH] GS/HW: Improve depth updating on source target match --- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 63 +++++++++++++++--------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index dc3d717576..8a879975fd 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -926,8 +926,16 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c // Have to update here, because this is a source, it won't Update(). if (FullRectDirty(t, 0x7)) t->Update(); - else if (!t->m_valid_rgb) + else if (!t->m_valid_rgb || dst->m_unscaled_size != t->m_unscaled_size) + { + if (dst->m_unscaled_size != t->m_unscaled_size) + { + t->ResizeTexture(t->m_unscaled_size.x, t->m_unscaled_size.y); + t->m_valid = dst->m_valid; + } + CopyRGBFromDepthToColor(t, dst); + } dst = t; @@ -1103,7 +1111,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const const bool width_match = (std::max(64U, bw * 64U) >> GSLocalMemory::m_psm[psm].info.pageShiftX()) == (std::max(64U, t->m_TEX0.TBW * 64U) >> GSLocalMemory::m_psm[t->m_TEX0.PSM].info.pageShiftX()); - if (bp == t->m_TEX0.TBP0 && !t->m_dirty.empty() && overlaps && GSUtil::GetChannelMask(psm) == GSUtil::GetChannelMask(t->m_TEX0.PSM) && GSRendererHW::GetInstance()->m_draw_transfers.size() > 0) + if (bp == t->m_TEX0.TBP0 && !t->m_dirty.empty() && GSUtil::GetChannelMask(psm) == GSUtil::GetChannelMask(t->m_TEX0.PSM) && GSRendererHW::GetInstance()->m_draw_transfers.size() > 0) { bool can_use = true; @@ -1318,6 +1326,30 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const const bool can_convert = (GSUtil::HasCompatibleBits(psm, t_psm) && ((bw == t->m_TEX0.TBW) || (bw <= 1 && req_rect.w < GSLocalMemory::m_psm[psm].pgs.y))) || (possible_shuffle && ((bw == t->m_TEX0.TBW) || (bw == (t->m_TEX0.TBW * 2) || bw <= 2)) && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32); + if (t->m_was_dst_matched) + { + // If we don't need alpha, or the alpha is valid + const bool indexed_format = psm_s.trbpp < 16; + const bool alpha_ok = (!indexed_format && (!req_alpha || req_alpha == (t->m_valid_alpha_low || t->m_valid_alpha_high))) || (indexed_format && (t->m_valid_alpha_low || t->m_valid_alpha_high)); + if (((!indexed_format && req_color) || (psm == PSMT8 || psm == PSMT4)) && alpha_ok && !t->m_valid_rgb) + { + GL_CACHE("TC: Attempt to repopulate RGB for target [%x] on source lookup", t->m_TEX0.TBP0); + for (Target* dst_match : m_dst[DepthStencil]) + { + if (dst_match->m_TEX0.TBP0 != t->m_TEX0.TBP0 || !dst_match->m_valid_rgb) + continue; + + if (!CopyRGBFromDepthToColor(t, dst_match)) + { + // If we can't update it, then just read back the valid data. + DevCon.Warning("Failed to update dst matched texture"); + } + t->m_valid_rgb = true; + break; + } + } + } + // Match if we haven't already got a tex in rt if (((!t_clean && can_convert) || t_clean || !overlapping_dirty) && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t_psm)) { @@ -1359,26 +1391,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const } else { - if (req_color && t->m_was_dst_matched && !t->m_valid_rgb) - { - - GL_CACHE("TC: Attempt to repopulate RGB for target [%x] on source lookup", t->m_TEX0.TBP0); - for (Target* dst_match : m_dst[DepthStencil]) - { - if (dst_match->m_TEX0.TBP0 != t->m_TEX0.TBP0 || !dst_match->m_valid_rgb) - continue; - - if (!CopyRGBFromDepthToColor(t, dst_match)) - { - // If we can't update it, then just read back the valid data. - DevCon.Warning("Failed to update dst matched texture"); - } - t->m_valid_rgb = true; - break; - } - } - - if (overlaps && !t->HasValidBitsForFormat(psm, req_color, req_alpha) && !(possible_shuffle && GSLocalMemory::m_psm[psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32)) + if (!t->HasValidBitsForFormat(psm, req_color, req_alpha) && !(possible_shuffle && GSLocalMemory::m_psm[psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32)) continue; dst = t; @@ -1403,7 +1416,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const // Detect half of the render target (fix snow engine game) // Target Page (8KB) have always a width of 64 pixels // Half of the Target is TBW/2 pages * 8KB / (1 block * 256B) = 0x10 - if (overlaps && !t->HasValidBitsForFormat(psm, req_color, req_alpha) && !(possible_shuffle && GSLocalMemory::m_psm[psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32)) + if (!t->HasValidBitsForFormat(psm, req_color, req_alpha) && !(possible_shuffle && GSLocalMemory::m_psm[psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32)) continue; half_right = true; @@ -2007,7 +2020,9 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe dst->m_was_dst_matched = true; dst->m_TEX0.TBW = dst_match->m_TEX0.TBW; - dst->UpdateValidity(dst->m_valid); + // Force the valid rect to the new size in case of shrinkage. + dst->m_valid = dst_match->m_valid; + dst->UpdateValidity(dst_match->m_valid); if (!CopyRGBFromDepthToColor(dst, dst_match)) {