Skip to content

Commit

Permalink
GS: Add optimisations for common GIF transfer sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
refractionpcsx2 committed Sep 26, 2023
1 parent fef282f commit 53b930b
Show file tree
Hide file tree
Showing 3 changed files with 537 additions and 7 deletions.
74 changes: 70 additions & 4 deletions pcsx2/GS/GSRegs.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ enum GIF_REG_COMPLEX
{
GIF_REG_STQRGBAXYZF2 = 0x00,
GIF_REG_STQRGBAXYZ2 = 0x01,
GIF_REG_UVRGBAXYZ2 = 0x02,
GIF_REG_RGBAXYZ2 = 0x03,
GIF_REG_RGBAXYZF2 = 0x04,
GIF_REG_STQXYZ2 = 0x05,
GIF_REG_STQXYZF2 = 0x06,
GIF_REG_UVXYZ2 = 0x07,
GIF_REG_UVXYZF2 = 0x08,
GIF_REG_RGBAUVXYZF2 = 0x09,
GIF_REG_UVRGBAXYZF2 = 0x0A
};

enum GIF_A_D_REG
Expand Down Expand Up @@ -1126,7 +1135,16 @@ struct alignas(32) GIFPath
TYPE_UNKNOWN,
TYPE_ADONLY,
TYPE_STQRGBAXYZF2,
TYPE_STQRGBAXYZ2
TYPE_STQRGBAXYZ2,
TYPE_UVRGBAXYZ2,
TYPE_RGBAXYZF2,
TYPE_UVXYZF2,
TYPE_STQXYZF2,
TYPE_RGBAXYZ2,
TYPE_UVXYZ2,
TYPE_STQXYZ2,
TYPE_RGBAUVXYZF2,
TYPE_UVRGBAXYZF2,
};

__forceinline void SetTag(const void* mem)
Expand Down Expand Up @@ -1156,7 +1174,7 @@ struct alignas(32) GIFPath

if (tag.FLG == GIF_FLG_PACKED)
{
if (regs.eq8(GSVector4i(0x0e0e0e0e)).mask() == (1 << nreg) - 1)
if (regs.eq8(GSVector4i::cxpr(0x0e0e0e0e)).mask() == (1 << nreg) - 1)
{
type = TYPE_ADONLY;
}
Expand All @@ -1167,21 +1185,69 @@ struct alignas(32) GIFPath
case 1:
break;
case 2:
if (regs.eq8(GSVector4i::cxpr(0x00000401)).mask() == (1 << 2) - 1)
type = TYPE_RGBAXYZF2;
else if (regs.eq8(GSVector4i::cxpr(0x0000040)).mask() == (1 << 2) - 1)
type = TYPE_STQXYZF2;
else if (regs.eq8(GSVector4i::cxpr(0x00000402)).mask() == (1 << 2) - 13)
type = TYPE_UVXYZF2;
else if (regs.eq8(GSVector4i::cxpr(0x00000501)).mask() == (1 << 2) - 1)
type = TYPE_RGBAXYZ2;
else if (regs.eq8(GSVector4i::cxpr(0x00000502)).mask() == (1 << 2) - 1)
type = TYPE_STQXYZ2;
else if (regs.eq8(GSVector4i::cxpr(0x00000503)).mask() == (1 << 2) - 1)
type = TYPE_UVXYZ2;
break;
case 3:
// many games, TODO: formats mixed with NOPs (xeno2: 040f010f02, 04010f020f, mgs3: 04010f0f02, 0401020f0f, 04010f020f)
if (regs.U32[0] == 0x00040102)
if (regs.eq8(GSVector4i::cxpr(0x00040102)).mask() == (1 << 3) - 1)
type = TYPE_STQRGBAXYZF2;
// GoW (has other crazy formats, like ...030503050103)
if (regs.U32[0] == 0x00050102)
else if (regs.eq8(GSVector4i::cxpr(0x00050102)).mask() == (1 << 3) - 1)
type = TYPE_STQRGBAXYZ2;
// TODO: common types with UV instead
else if (regs.eq8(GSVector4i::cxpr(0x00050103)).mask() == (1 << 3) - 1)
type = TYPE_UVRGBAXYZ2;
else if (regs.eq8(GSVector4i::cxpr(0x00040103)).mask() == (1 << 3) - 1)
type = TYPE_UVRGBAXYZF2;
else if (regs.eq8(GSVector4i::cxpr(0x00040301)).mask() == (1 << 3) - 1)
type = TYPE_RGBAUVXYZF2;
break;
case 4:
if (regs.eq8(GSVector4i(0x04030403)).mask() == (1 << 4) - 1)
{
type = TYPE_UVXYZF2;
nreg = 2;
nloop *= 2;
}
else if (regs.eq8(GSVector4i::cxpr(0x05030503)).mask() == (1 << 4) - 1)
{
type = TYPE_UVXYZ2;
nreg = 2;
nloop *= 2;
}
break;
case 5:
break;
case 6:
if (regs.U32[0] == 0x03040103 && regs.U32[1] == 0x00000401)
{
type = TYPE_UVRGBAXYZF2;
nreg = 3;
nloop *= 2;
}
else if (regs.U32[0] == 0x01040301 && regs.U32[1] == 0x00000403)
{
type = TYPE_RGBAUVXYZF2;
nreg = 3;
nloop *= 2;
}
else if (regs.U32[0] == 0x03050103 && regs.U32[1] == 0x00000501)
{
type = TYPE_UVRGBAXYZ2;
nreg = 3;
nloop *= 2;
}
break;
case 7:
break;
Expand Down
Loading

0 comments on commit 53b930b

Please sign in to comment.