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

@ -1947,6 +1947,25 @@ 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))
{
// 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: Preserving alpha on 24-bit/masked %s[%x] because it was previously valid.", to_string(type), dst->m_TEX0.TBP0);
// 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())
{
@ -1959,6 +1978,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
g_gs_device->InvalidateRenderTarget(dst->m_texture);
}
}
}
else if (!is_frame && !GSConfig.UserHacks_DisableDepthSupport)
{
const int rev_type = (type == DepthStencil) ? RenderTarget : DepthStencil;
@ -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);