GS: Improve Autoflush detection with channel masks

This commit is contained in:
refractionpcsx2 2024-04-23 11:14:32 +01:00
parent 25737a1a46
commit a0e323dae5
2 changed files with 10 additions and 5 deletions

View File

@ -3090,6 +3090,10 @@ __forceinline bool GSState::IsAutoFlushDraw(u32 prim)
if (!PRIM->TME || (GSConfig.UserHacks_AutoFlush == GSHWAutoFlushLevel::SpritesOnly && prim != GS_SPRITE))
return false;
// Not using the same channels.
if (!(GSUtil::GetChannelMask(m_context->TEX0.PSM) & GSUtil::GetChannelMask(m_context->FRAME.PSM, m_context->FRAME.FBMSK | ~(GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk))))
return false;
const u32 frame_mask = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk;
const bool frame_hit = m_context->FRAME.Block() == m_context->TEX0.TBP0 && !(m_context->TEST.ATE && m_context->TEST.ATST == 0 && m_context->TEST.AFAIL == 2) && ((m_context->FRAME.FBMSK & frame_mask) != frame_mask);
// There's a strange behaviour we need to test on a PS2 here, if the FRAME is a Z format, like Powerdrome something swaps over, and it seems Alpha Fail of "FB Only" writes to the Z.. it's odd.
@ -3272,8 +3276,9 @@ __forceinline void GSState::HandleAutoFlush()
if (tex_rect.y == tex_rect.w)
tex_rect += GSVector4i::cxpr(0, 0, 0, 1);
const bool swap_index = index_swap && GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GS_SPRITE_CLASS;
// Get the last texture position from the last draw.
const GSVertex* v = &m_vertex.buff[m_index.buff[m_index.tail - (index_swap ? n : 1)]];
const GSVertex* v = &m_vertex.buff[m_index.buff[m_index.tail - (swap_index ? n : 1)]];
if (PRIM->FST)
{

View File

@ -191,10 +191,10 @@ u32 GSUtil::GetChannelMask(u32 spsm)
u32 GSUtil::GetChannelMask(u32 spsm, u32 fbmsk)
{
u32 mask = GetChannelMask(spsm);
mask &= (fbmsk & 0xFF) ? (~0x1 & 0xf) : 0xf;
mask &= (fbmsk & 0xFF00) ? (~0x2 & 0xf) : 0xf;
mask &= (fbmsk & 0xFF0000) ? (~0x4 & 0xf) : 0xf;
mask &= (fbmsk & 0xFF000000) ? (~0x8 & 0xf) : 0xf;
mask &= ((fbmsk & 0xFF) == 0xFF) ? (~0x1 & 0xf) : 0xf;
mask &= ((fbmsk & 0xFF00) == 0xFF00) ? (~0x2 & 0xf) : 0xf;
mask &= ((fbmsk & 0xFF0000) == 0xFF0000) ? (~0x4 & 0xf) : 0xf;
mask &= ((fbmsk & 0xFF000000) == 0xFF000000) ? (~0x8 & 0xf) : 0xf;
return mask;
}