GS/HW: Don't discard alpha in C32 targets being used as C24

This commit is contained in:
Stenzek 2023-12-31 00:04:01 +10:00 committed by Connor McLaughlin
parent 714e355c87
commit bcbf390334
1 changed files with 28 additions and 8 deletions

View File

@ -1948,15 +1948,35 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
// Drop dirty rect if we're overwriting the whole target.
if (!preserve_target && draw_rect.rintersect(dst->m_valid).eq(dst->m_valid))
{
if (!dst->m_dirty.empty())
// Preserve alpha if this is a 32-bit target being used as 24-bit.
const bool dont_invalidate_alpha = (dst->HasValidAlpha() && (psm_s.fmt == GSLocalMemory::PSM_FMT_24 || (fbmask & 0xFF000000u) != 0));
if (dont_invalidate_alpha)
{
GL_INS("TC: Clearing dirty list for %s[%x] because we're overwriting the whole target.", to_string(type), dst->m_TEX0.TBP0);
dst->m_dirty.clear();
}
GL_INS("TC: Preserving alpha on 24-bit/masked %s[%x] because it was previously valid.", to_string(type), dst->m_TEX0.TBP0);
// And invalidate the target, we're drawing over it so we don't care what's there.
GL_INS("TC: Invalidating target %s[%x] because it's completely overwritten.", to_string(type), dst->m_TEX0.TBP0);
g_gs_device->InvalidateRenderTarget(dst->m_texture);
// We can still toss all dirty RGB writes though. Gotta save those uploads.
if (!dst->m_dirty.empty())
{
GL_INS("TC: Clearing RGB dirty list for %s[%x] because we're overwriting the whole target.", to_string(type), dst->m_TEX0.TBP0);
for (s32 i = static_cast<s32>(dst->m_dirty.size()) - 1; i >= 0; i--)
{
if (!dst->m_dirty[i].rgba.c.a)
dst->m_dirty.erase(dst->m_dirty.begin() + static_cast<size_t>(i));
}
}
}
else
{
if (!dst->m_dirty.empty())
{
GL_INS("TC: Clearing dirty list for %s[%x] because we're overwriting the whole target.", to_string(type), dst->m_TEX0.TBP0);
dst->m_dirty.clear();
}
// And invalidate the target, we're drawing over it so we don't care what's there.
GL_INS("TC: Invalidating target %s[%x] because it's completely overwritten.", to_string(type), dst->m_TEX0.TBP0);
g_gs_device->InvalidateRenderTarget(dst->m_texture);
}
}
}
else if (!is_frame && !GSConfig.UserHacks_DisableDepthSupport)
@ -2025,7 +2045,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
calcRescale(dst_match);
// If we don't need A, and the existing target doesn't have valid alpha, don't bother converting it.
const bool has_alpha = dst_match->m_valid_alpha_low || dst_match->m_valid_alpha_high;
const bool has_alpha = dst_match->HasValidAlpha();
const bool preserve_target = (preserve_rgb || (preserve_alpha && has_alpha)) ||
!draw_rect.rintersect(dst_match->m_valid).eq(dst_match->m_valid);