GS/HW: Rename and improve dirty alpha to valid alpha

This commit is contained in:
Stenzek 2023-05-11 23:11:37 +10:00 committed by refractionpcsx2
parent 61f344dd66
commit 5bab8af38f
4 changed files with 36 additions and 13 deletions

View File

@ -2069,10 +2069,15 @@ void GSRendererHW::Draw()
rt->m_TEX0 = FRAME_TEX0;
rt->m_TEX0.TBW = std::max(width, FRAME_TEX0.TBW);
}
rt->UpdateValidAlpha(FRAME_TEX0.PSM, fm);
}
if (ds)
{
ds->m_TEX0 = ZBUF_TEX0;
ds->UpdateValidAlpha(ZBUF_TEX0.PSM, zm);
}
}
else if (!m_texture_shuffle)
{
@ -2082,11 +2087,14 @@ void GSRendererHW::Draw()
{
rt->m_TEX0.TBW = std::max(rt->m_TEX0.TBW, FRAME_TEX0.TBW);
rt->m_TEX0.PSM = FRAME_TEX0.PSM;
rt->UpdateValidAlpha(FRAME_TEX0.PSM, fm);
}
if (ds)
{
ds->m_TEX0.TBW = std::max(ds->m_TEX0.TBW, ZBUF_TEX0.TBW);
ds->m_TEX0.PSM = ZBUF_TEX0.PSM;
ds->UpdateValidAlpha(ZBUF_TEX0.PSM, zm);
}
}
if (rt)
@ -2581,7 +2589,7 @@ void GSRendererHW::EmulateZbuffer(const GSTextureCache::Target* ds)
}
}
void GSRendererHW::EmulateTextureShuffleAndFbmask()
void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt)
{
// Uncomment to disable texture shuffle emulation.
// m_texture_shuffle = false;
@ -2713,6 +2721,10 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask()
m_conf.ps.fbmask = 0;
}
// Set dirty alpha on target, but only if we're actually writing to it.
if (rt)
rt->m_valid_alpha |= m_conf.colormask.wa;
// Once we draw the shuffle, no more buffering.
m_split_texture_shuffle_pages = 0;
m_split_texture_shuffle_pages_high = 0;
@ -4230,7 +4242,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
else
m_prim_overlap = PRIM_OVERLAP_UNKNOW;
EmulateTextureShuffleAndFbmask();
EmulateTextureShuffleAndFbmask(rt);
// DATE: selection of the algorithm. Must be done before blending because GL42 is not compatible with blending
if (DATE)

View File

@ -76,7 +76,7 @@ private:
void ResetStates();
void SetupIA(float target_scale, float sx, float sy);
void EmulateTextureShuffleAndFbmask();
void EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt);
bool EmulateChannelShuffle(GSTextureCache::Target* src, bool test_only);
void EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool& blending_alpha_pass);

View File

@ -773,7 +773,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
// because of the previous draw call format
//
// Solution: consider the RT as 32 bits if the alpha was used in the past
const u32 t_psm = (t->m_dirty_alpha) ? t->m_TEX0.PSM & ~0x1 : t->m_TEX0.PSM;
// We can render to the target as C32, but mask alpha, in which case, pretend like it doesn't have any.
const u32 t_psm = t->m_valid_alpha ? t->m_TEX0.PSM & ~0x1 : ((t->m_TEX0.PSM == PSMCT32) ? PSMCT24 : t->m_TEX0.PSM);
bool rect_clean = GSUtil::HasSameSwizzleBits(psm, t_psm);
if (rect_clean && bp >= t->m_TEX0.TBP0 && bp < t->UnwrappedEndBlock() && !t->m_dirty.empty() &&
@ -1316,9 +1317,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
dst->m_scale = scale;
dst->m_unscaled_size = new_size;
}
if (!is_frame)
dst->m_dirty_alpha |= (psm_s.trbpp == 32 && (fbmask & 0xFF000000) != 0xFF000000) || (psm_s.trbpp == 16);
}
else if (!is_frame && !GSConfig.UserHacks_DisableDepthSupport)
{
@ -1509,7 +1507,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
dst->m_used |= used;
if (is_frame)
dst->m_dirty_alpha = false;
dst->m_valid_alpha = false;
dst->readbacks_since_draw = 0;
@ -1938,7 +1936,7 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
if (rgba._u32 == 0x8 && t->m_TEX0.PSM == PSMCT32)
{
t->m_TEX0.PSM = PSMCT24;
t->m_dirty_alpha = false;
t->m_valid_alpha = false;
++i;
}
else
@ -1964,7 +1962,7 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
// the texture cache. Otherwise it will generate a wrong
// hit on the texture cache.
// Game: Conflict - Desert Storm (flickering)
t->m_dirty_alpha = false;
t->m_valid_alpha = false;
}
++i;
@ -2645,7 +2643,7 @@ GSTextureCache::Target* GSTextureCache::GetTargetWithSharedBits(u32 BP, u32 PSM)
for (auto it = rts.begin(); it != rts.end(); ++it) // Iterate targets from MRU to LRU.
{
Target* t = *it;
const u32 t_psm = (t->m_dirty_alpha) ? t->m_TEX0.PSM & ~0x1 : t->m_TEX0.PSM;
const u32 t_psm = (t->m_valid_alpha) ? t->m_TEX0.PSM & ~0x1 : t->m_TEX0.PSM;
if (GSUtil::HasSharedBits(BP, PSM, t->m_TEX0.TBP0, t_psm))
return t;
}
@ -4348,7 +4346,6 @@ GSTextureCache::Target::Target(const GIFRegTEX0& TEX0, const int type)
{
m_TEX0 = TEX0;
m_32_bits_fmt |= (GSLocalMemory::m_psm[TEX0.PSM].trbpp != 16);
m_dirty_alpha = GSLocalMemory::m_psm[TEX0.PSM].trbpp != 24;
}
GSTextureCache::Target::~Target()
@ -4506,6 +4503,13 @@ void GSTextureCache::Target::UpdateIfDirtyIntersects(const GSVector4i& rc)
break;
}
}
void GSTextureCache::Target::UpdateValidAlpha(u32 psm, u32 fbmsk)
{
const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[psm];
m_valid_alpha |= (psm_s.trbpp == 32 && (fbmsk & 0xFF000000) != 0xFF000000) || (psm_s.trbpp == 16);
}
void GSTextureCache::Target::ResizeDrawn(const GSVector4i& rect)
{
m_drawn_since_read = m_drawn_since_read.rintersect(rect);

View File

@ -208,7 +208,11 @@ public:
{
public:
const int m_type = 0;
bool m_dirty_alpha = true;
// Valid alpha means "we have rendered to the alpha channel of this target".
// A false value means that the alpha in local memory is still valid/up-to-date.
bool m_valid_alpha = false;
bool m_is_frame = false;
bool m_used = false;
float OffsetHack_modxy = 0.0f;
@ -233,6 +237,9 @@ public:
/// Updates the target, if the dirty area intersects with the specified rectangle.
void UpdateIfDirtyIntersects(const GSVector4i& rc);
/// Updates the valid alpha flag, based on PSM and fbmsk.
void UpdateValidAlpha(u32 psm, u32 fbmsk);
/// Resizes target texture, DOES NOT RESCALE.
bool ResizeTexture(int new_unscaled_width, int new_unscaled_height, bool recycle_old = true);
};