Skip to content

Commit

Permalink
GS: Properly check load condition when reloading CLUT
Browse files Browse the repository at this point in the history
  • Loading branch information
refractionpcsx2 committed Oct 29, 2023
1 parent bb7e08c commit b8d224e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 26 deletions.
65 changes: 40 additions & 25 deletions pcsx2/GS/GSClut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,43 +168,58 @@ bool GSClut::InvalidateRange(u32 start_block, u32 end_block, bool is_draw)
return m_write.dirty;
}

bool GSClut::WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
bool GSClut::CanLoadCLUT(const GIFRegTEX0& TEX0, const bool update_CBP)
{
// Check if PSM is an indexed format BEFORE the load condition, updating CBP0/1 on an invalid format is not allowed
// and can break games. Corvette (NTSC) is a good example of this.
if ((TEX0.PSM & 0x7) < 3)
return false;

switch (TEX0.CLD)
{
case 0:
return false;
case 1:
break;
case 2:
case 0:
return false;
case 1:
break;
case 2:
if (update_CBP)
m_CBP[0] = TEX0.CBP;
break;
case 3:
break;
case 3:
if (update_CBP)
m_CBP[1] = TEX0.CBP;
break;
case 4:
if (m_CBP[0] == TEX0.CBP)
return false;
break;
case 4:
if (m_CBP[0] == TEX0.CBP)
return false;
if(update_CBP)
m_CBP[0] = TEX0.CBP;
break;
case 5:
if (m_CBP[1] == TEX0.CBP)
return false;
break;
case 5:
if (m_CBP[1] == TEX0.CBP)
return false;
if (update_CBP)
m_CBP[1] = TEX0.CBP;
break;
case 6:
return false; // ffx2 menu.
case 7:
return false; // ford mustang racing // Bouken Jidai Katsugeki Goemon.
default:
__assume(0);
break;
case 6:
return false; // ffx2 menu.
case 7:
return false; // ford mustang racing // Bouken Jidai Katsugeki Goemon.
default:
__assume(0);
}

return true;
}

bool GSClut::WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
// Check if PSM is an indexed format BEFORE the load condition, updating CBP0/1 on an invalid format is not allowed
// and can break games. Corvette (NTSC) is a good example of this.
if ((TEX0.PSM & 0x7) < 3)
return false;

if (!CanLoadCLUT(TEX0, true))
return false;

// CLUT only reloads if PSM is a valid index type, avoid unnecessary flushes.
return m_write.IsDirty(TEX0, TEXCLUT);
}
Expand Down
1 change: 1 addition & 0 deletions pcsx2/GS/GSClut.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class alignas(32) GSClut final : public GSAlignedClass<32>
u32 GetCLUTCBP();
u32 GetCLUTCPSM();
void SetNextCLUTTEX0(u64 CBP);
bool CanLoadCLUT(const GIFRegTEX0& TEX0, const bool update_CBP = false);
bool WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT);
void Write(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT);
//void Read(const GIFRegTEX0& TEX0);
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/GS/GSState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ void GSState::ApplyTEX0(GIFRegTEX0& TEX0)

GL_REG("Apply TEX0_%d = 0x%x_%x", i, TEX0.U32[1], TEX0.U32[0]);

if ((TEX0.PSM & 0x7) >= 3 && TEX0.CLD)
if ((TEX0.PSM & 0x7) >= 3 && m_mem.m_clut.CanLoadCLUT(TEX0))
{
m_mem.m_clut.ClearDrawInvalidity();
m_mem.m_clut.SetNextCLUTTEX0(TEX0.U64);
Expand Down

0 comments on commit b8d224e

Please sign in to comment.