GS/HW: Break channel shuffle on CBP change

Needed for Tomb Raider: Underworld
This commit is contained in:
Stenzek 2023-05-03 23:41:03 +10:00 committed by refractionpcsx2
parent ea30c90a6c
commit 61740fc9ed
4 changed files with 11 additions and 1 deletions

View File

@ -827,7 +827,15 @@ void GSState::ApplyTEX0(GIFRegTEX0& TEX0)
m_mem.m_clut.ClearDrawInvalidity();
CLUTAutoFlush(PRIM->PRIM);
}
Flush(GSFlushReason::CLUTCHANGE);
// Abort any channel shuffle skipping, since this is likely part of a new shuffle.
// Test case: Tomb Raider series. This is gated by the CBP actually changing, because
// Urban Chaos writes to the memory backing the CLUT in the middle of a shuffle, and
// it's unclear whether the CLUT would actually get reloaded in that case.
if (TEX0.CBP != m_mem.m_clut.GetCLUTCBP())
m_channel_shuffle = false;
}
TEX0.CPSM &= 0xa; // 1010b

View File

@ -227,6 +227,7 @@ public:
bool m_mipmap = false;
bool m_texflush_flag = false;
bool m_isPackedUV_HackFlag = false;
bool m_channel_shuffle = false;
u8 m_scanmask_used = 0;
u8 m_force_preload = 0;
u32 m_dirty_gs_regs = 0;

View File

@ -1415,6 +1415,8 @@ void GSRendererHW::Draw()
{
// NFSU2 does consecutive channel shuffles with blending, reducing the alpha channel over time.
// Fortunately, it seems to change the FBMSK along the way, so this check alone is sufficient.
// Tomb Raider: Underworld does similar, except with R, G, B in separate palettes, therefore
// we need to split on those too.
m_channel_shuffle = IsPossibleChannelShuffle() && m_last_channel_shuffle_fbmsk == m_context->FRAME.FBMSK;
#ifdef ENABLE_OGL_DEBUG

View File

@ -135,7 +135,6 @@ private:
u32 m_split_texture_shuffle_start_TBP = 0;
u32 m_last_channel_shuffle_fbmsk = 0;
bool m_channel_shuffle = false;
bool m_userhacks_tcoffset = false;
float m_userhacks_tcoffset_x = 0.0f;