GS/HW: Improve depth updating on source target match

This commit is contained in:
refractionpcsx2 2024-04-16 11:06:58 +01:00
parent 2a2dad9280
commit a38dd74d0e
1 changed files with 39 additions and 24 deletions

View File

@ -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))
{