GS: Adjust CLUT dirty checks to reduce false positives

This commit is contained in:
refractionpcsx2 2022-06-30 13:27:16 +01:00
parent cb0e79972d
commit f191915b53
1 changed files with 54 additions and 5 deletions

View File

@ -752,19 +752,68 @@ void GSClut::Expand16(const u16* RESTRICT src, u32* RESTRICT dst, int w, const G
}
}
//
bool GSClut::WriteState::IsDirty(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
return dirty || !GSVector4i::load<true>(this).eq(GSVector4i::load(&TEX0, &TEXCLUT));
constexpr u64 mask = 0x1FFFFFE000000000ull; // CSA CSM CPSM CBP
bool is_dirty = dirty;
if ((this->TEX0.U64 ^ TEX0.U64) & mask)
is_dirty |= true;
else if (TEX0.CSM == 1 && (TEXCLUT.U32[0] ^ this->TEXCLUT.U32[0]))
is_dirty |= true;
if (!is_dirty)
{
this->TEX0.U64 = TEX0.U64;
this->TEXCLUT.U64 = TEXCLUT.U64;
}
return is_dirty;
}
bool GSClut::ReadState::IsDirty(const GIFRegTEX0& TEX0)
{
return dirty || !GSVector4i::load<true>(this).eq(GSVector4i::load(&TEX0, &this->TEXA));
constexpr u64 mask = 0x1FFFFFE000000000ull; // CSA CSM CPSM CBP
bool is_dirty = dirty;
if ((this->TEX0.U64 ^ TEX0.U64) & mask)
is_dirty |= true;
if (!is_dirty)
{
this->TEX0.U64 = TEX0.U64;
}
return is_dirty;
}
bool GSClut::ReadState::IsDirty(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
{
return dirty || !GSVector4i::load<true>(this).eq(GSVector4i::load(&TEX0, &TEXA));
constexpr u64 tex0_mask = 0x1FFFFFE000000000ull; // CSA CSM CPSM CBP
constexpr u64 texa24_mask = 0x80FFull; // AEM TA0
constexpr u64 texa16_mask = 0xFF000080FFull; // TA1 AEM TA0
bool is_dirty = dirty;
if ((this->TEX0.U64 ^ TEX0.U64) & tex0_mask)
is_dirty |= true;
else // Just to optimise the checks.
{
// Check TA0 and AEM in 24bit mode.
if (TEX0.CPSM == PSM_PSMCT24 && ((this->TEXA.U64 ^ TEXA.U64) & texa24_mask))
is_dirty |= true;
// Check all fields in 16bit mode.
else if (TEX0.CPSM >= PSM_PSMCT16 && ((this->TEXA.U64 ^ TEXA.U64) & texa16_mask))
is_dirty |= true;
}
if (!is_dirty)
{
this->TEX0.U64 = TEX0.U64;
this->TEXA.U64 = TEXA.U64;
}
return is_dirty;
}