From 53b930b8a5fd7c0d8a16df459852e3f23acdfb70 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Mon, 25 Sep 2023 20:33:15 +0100 Subject: [PATCH] GS: Add optimisations for common GIF transfer sequences --- pcsx2/GS/GSRegs.h | 74 ++++++- pcsx2/GS/GSState.cpp | 449 ++++++++++++++++++++++++++++++++++++++++++- pcsx2/GS/GSState.h | 21 +- 3 files changed, 537 insertions(+), 7 deletions(-) diff --git a/pcsx2/GS/GSRegs.h b/pcsx2/GS/GSRegs.h index 352ed39ba008f0..cf09bdd4d65f9b 100644 --- a/pcsx2/GS/GSRegs.h +++ b/pcsx2/GS/GSRegs.h @@ -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 @@ -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) @@ -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; } @@ -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; diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index 8c4d9afac01c21..dde14aeffa0be6 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -210,7 +210,16 @@ void GSState::SetPrimHandlers() m_fpGIFRegHandlerXYZ[P][2] = &GSState::GIFRegHandlerXYZ2; \ m_fpGIFRegHandlerXYZ[P][3] = &GSState::GIFRegHandlerXYZ2; \ m_fpGIFPackedRegHandlerSTQRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZF2; \ - m_fpGIFPackedRegHandlerSTQRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZ2; + m_fpGIFPackedRegHandlerSTQRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZ2; \ + m_fpGIFPackedRegHandlerUVRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerUVRGBAXYZ2; \ + m_fpGIFPackedRegHandlerRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerRGBAXYZ2; \ + m_fpGIFPackedRegHandlerRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerRGBAXYZF2; \ + m_fpGIFPackedRegHandlerSTQXYZ2[P] = &GSState::GIFPackedRegHandlerSTQXYZ2; \ + m_fpGIFPackedRegHandlerSTQXYZF2[P] = &GSState::GIFPackedRegHandlerSTQXYZF2; \ + m_fpGIFPackedRegHandlerUVXYZ2[P] = &GSState::GIFPackedRegHandlerUVXYZ2; \ + m_fpGIFPackedRegHandlerUVXYZF2[P] = &GSState::GIFPackedRegHandlerUVXYZF2; \ + m_fpGIFPackedRegHandlerRGBAUVXYZF2[P] = &GSState::GIFPackedRegHandlerRGBAUVXYZF2; \ + m_fpGIFPackedRegHandlerUVRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerUVRGBAXYZF2; SetHandlerXYZ(GS_POINTLIST, true, false); SetHandlerXYZ(GS_LINELIST, auto_flush, index_swap); @@ -714,7 +723,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV)); // TODO: only store the last one - const bool skip = r[2].XYZF2.Skip(); + const bool skip = r[2].XYZ2.Skip(); if (!flushes_checked && !skip) { flushes_checked = true; @@ -728,6 +737,378 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 m_q = r[-3].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time } +template +void GSState::GIFPackedRegHandlerUVRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 3 == 0); + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + const GSVector4i st = GSVector4i::loadl(&m_v.ST); + const GSVector4i q = GSVector4i::loadl(&m_v.RGBAQ.U32[1]).blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero()); + + while (r < r_end) + { + const GSVector4i rgba = (GSVector4i::load(&r[1]) & GSVector4i::x000000ff()).ps32().pu16(); + + m_v.m[0] = st.upl64(rgba.upl32(q)); + + const GSVector4i xy = GSVector4i::loadl(&r[2].U64[0]); + const GSVector4i z = GSVector4i::loadl(&r[2].U64[1]); + const GSVector4i xyz = xy.upl16(xy.srl<4>()).upl32(z); + + const GSVector4i uv = GSVector4i::loadl(&r[0]) & GSVector4i::x00003fff(); + + m_v.m[1] = xyz.upl64(uv.ps32(uv)); + + const bool skip = r[2].XYZ2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 3; + } +} + +template +void GSState::GIFPackedRegHandlerRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 2 == 0); + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + const GSVector4i st = GSVector4i::loadl(&m_v.ST); + const GSVector4i q = GSVector4i(m_v.RGBAQ.U32[1]).blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ + + while (r < r_end) + { + const GSVector4i rgba = (GSVector4i::load(&r[0]) & GSVector4i::x000000ff()).ps32().pu16(); + + m_v.m[0] = st.upl64(rgba.upl32(q)); + + const GSVector4i xy = GSVector4i::loadl(&r[1].U64[0]); + const GSVector4i z = GSVector4i::loadl(&r[1].U64[1]); + const GSVector4i xyz = xy.upl16(xy.srl<4>()).upl32(z); + + m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV)); + + const bool skip = r[1].XYZ2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 2; + } +} + +template +void GSState::GIFPackedRegHandlerRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 2 == 0); + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + const GSVector4i st = GSVector4i::loadl(&m_v.ST); + const GSVector4i q = GSVector4i(m_v.RGBAQ.U32[1]).blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ + + while (r < r_end) + { + const GSVector4i rgba = (GSVector4i::load(&r[0]) & GSVector4i::x000000ff()).ps32().pu16(); + + m_v.m[0] = st.upl64(rgba.upl32(q)); + + GSVector4i xy = GSVector4i::loadl(&r[1].U64[0]); + GSVector4i zf = GSVector4i::loadl(&r[1].U64[1]); + xy = xy.upl16(xy.srl<4>()).upl32(GSVector4i::load((int)m_v.UV)); + zf = zf.srl32(4) & GSVector4i::x00ffffff().upl32(GSVector4i::x000000ff()); + + m_v.m[1] = xy.upl32(zf); + + const bool skip = r[1].XYZF2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 2; + } +} + +template +void GSState::GIFPackedRegHandlerUVRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 3 == 0); + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + const GSVector4i st = GSVector4i::loadl(&m_v.ST); + const GSVector4i q = GSVector4i(m_v.RGBAQ.U32[1]).blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ + + while (r < r_end) + { + const GSVector4i rgba = (GSVector4i::load(&r[1]) & GSVector4i::x000000ff()).ps32().pu16(); + + m_v.m[0] = st.upl64(rgba.upl32(q)); + + GSVector4i xy = GSVector4i::loadl(&r[2].U64[0]); + GSVector4i zf = GSVector4i::loadl(&r[2].U64[1]); + + const GSVector4i uv = GSVector4i::loadl(&r[0]) & GSVector4i::x00003fff(); + + xy = xy.upl16(xy.srl<4>()).upl32(uv.ps32(uv)); + zf = zf.srl32(4) & GSVector4i::x00ffffff().upl32(GSVector4i::x000000ff()); + + m_v.m[1] = xy.upl32(zf); + + const bool skip = r[2].XYZF2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 3; + } +} + +template +void GSState::GIFPackedRegHandlerRGBAUVXYZF2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 3 == 0); + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + const GSVector4i st = GSVector4i::loadl(&m_v.ST); + const GSVector4i q = GSVector4i(m_v.RGBAQ.U32[1]).blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ + + while (r < r_end) + { + const GSVector4i rgba = (GSVector4i::load(&r[0]) & GSVector4i::x000000ff()).ps32().pu16(); + + m_v.m[0] = st.upl64(rgba.upl32(q)); // TODO: only store the last one + + GSVector4i xy = GSVector4i::loadl(&r[2].U64[0]); + GSVector4i zf = GSVector4i::loadl(&r[2].U64[1]); + + const GSVector4i uv = GSVector4i::loadl(&r[1]) & GSVector4i::x00003fff(); + + xy = xy.upl16(xy.srl<4>()).upl32(uv.ps32(uv)); + zf = zf.srl32(4) & GSVector4i::x00ffffff().upl32(GSVector4i::x000000ff()); + + m_v.m[1] = xy.upl32(zf); + + const bool skip = r[2].XYZF2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 3; + } +} + +template +void GSState::GIFPackedRegHandlerSTQXYZ2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 2 == 0); + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + while (r < r_end) + { + const GSVector4i st = GSVector4i::loadl(&r[0].U64[0]); + m_v.ST.U64 = st.U64[0]; + + const GSVector4i xy = GSVector4i::loadl(&r[1].U64[0]); + const GSVector4i z = GSVector4i::loadl(&r[1].U64[1]); + const GSVector4i xyz = xy.upl16(xy.srl<4>()).upl32(z); + + m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV)); // TODO: only store the last one + + const bool skip = r[1].XYZ2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 2; + } + + m_q = r[-2].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time +} + +template +void GSState::GIFPackedRegHandlerSTQXYZF2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 2 == 0); + + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + while (r < r_end) + { + const GSVector4i st = GSVector4i::loadl(&r[0].U64[0]); + m_v.ST.U64 = st.U64[0]; + + GSVector4i xy = GSVector4i::loadl(&r[1].U64[0]); + GSVector4i zf = GSVector4i::loadl(&r[1].U64[1]); + xy = xy.upl16(xy.srl<4>()).upl32(GSVector4i::load((int)m_v.UV)); + zf = zf.srl32(4) & GSVector4i::x00ffffff().upl32(GSVector4i::x000000ff()); + + m_v.m[1] = xy.upl32(zf); // TODO: only store the last one + + const bool skip = r[1].XYZF2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 2; + } + + m_q = r[-2].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time +} + +template +void GSState::GIFPackedRegHandlerUVXYZ2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 2 == 0); + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + while (r < r_end) + { + const GSVector4i xy = GSVector4i::loadl(&r[1].U64[0]); + const GSVector4i z = GSVector4i::loadl(&r[1].U64[1]); + const GSVector4i xyz = xy.upl16(xy.srl<4>()).upl32(z); + const GSVector4i uv = GSVector4i::loadl(&r[0]) & GSVector4i::x00003fff(); + + m_v.m[1] = xyz.upl64(uv.ps32(uv)); // TODO: only store the last one + + const bool skip = r[1].XYZ2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 2; + } + + m_q = r[-2].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time +} + +template +void GSState::GIFPackedRegHandlerUVXYZF2(const GIFPackedReg* RESTRICT r, u32 size) +{ + ASSERT(size > 0 && size % 2 == 0); + + bool flushes_checked = false; + + if (GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET))) + { + flushes_checked = true; + CheckFlushes(); + } + + const GIFPackedReg* RESTRICT r_end = r + size; + + while (r < r_end) + { + GSVector4i xy = GSVector4i::loadl(&r[1].U64[0]); + GSVector4i zf = GSVector4i::loadl(&r[1].U64[1]); + const GSVector4i uv = GSVector4i::loadl(&r[0]) & GSVector4i::x00003fff(); + xy = xy.upl16(xy.srl<4>()).upl32(uv.ps32(uv)); + zf = zf.srl32(4) & GSVector4i::x00ffffff().upl32(GSVector4i::x000000ff()); + + m_v.m[1] = xy.upl32(zf); // TODO: only store the last one + + const bool skip = r[1].XYZF2.Skip(); + if (!flushes_checked && !skip) + { + flushes_checked = true; + CheckFlushes(); + } + VertexKick(skip); + + r += 2; + } + + m_q = r[-2].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time +} + void GSState::GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, u32 size) { } @@ -2393,6 +2774,61 @@ void GSState::Transfer(const u8* mem, u32 size) mem += total * sizeof(GIFPackedReg); break; + case GIFPath::TYPE_UVRGBAXYZ2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_UVRGBAXYZ2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_RGBAXYZF2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_RGBAXYZF2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_STQXYZF2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_STQXYZF2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_RGBAXYZ2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_RGBAXYZ2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_STQXYZ2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_STQXYZ2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_UVRGBAXYZF2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_UVRGBAXYZF2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_RGBAUVXYZF2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_RGBAUVXYZF2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_UVXYZ2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_UVXYZ2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + case GIFPath::TYPE_UVXYZF2: + (this->*m_fpGIFPackedRegHandlersC[GIF_REG_UVXYZF2])((GIFPackedReg*)mem, total); + + mem += total * sizeof(GIFPackedReg); + + break; + default: __assume(0); } @@ -2744,6 +3180,15 @@ void GSState::UpdateVertexKick() m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZF2] = m_fpGIFPackedRegHandlerSTQRGBAXYZF2[prim]; m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZ2] = m_fpGIFPackedRegHandlerSTQRGBAXYZ2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_UVRGBAXYZ2] = m_fpGIFPackedRegHandlerUVRGBAXYZ2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_RGBAXYZ2] = m_fpGIFPackedRegHandlerRGBAXYZ2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_RGBAXYZF2] = m_fpGIFPackedRegHandlerRGBAXYZF2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_STQXYZ2] = m_fpGIFPackedRegHandlerSTQXYZ2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_STQXYZF2] = m_fpGIFPackedRegHandlerSTQXYZF2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_RGBAUVXYZF2] = m_fpGIFPackedRegHandlerRGBAUVXYZF2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_UVRGBAXYZF2] = m_fpGIFPackedRegHandlerUVRGBAXYZF2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_UVXYZ2] = m_fpGIFPackedRegHandlerUVXYZ2[prim]; + m_fpGIFPackedRegHandlersC[GIF_REG_UVXYZF2] = m_fpGIFPackedRegHandlerUVXYZF2[prim]; } void GSState::GrowVertexBuffer() diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index 9e3fd1de299851..5766542e4c1353 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -63,12 +63,31 @@ class GSState : public GSAlignedClass<32> typedef void (GSState::*GIFPackedRegHandlerC)(const GIFPackedReg* RESTRICT r, u32 size); - GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[2] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[11] = {}; GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8] = {}; GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerUVRGBAXYZ2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerRGBAXYZ2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerRGBAXYZF2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQXYZ2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQXYZF2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerUVXYZ2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerUVXYZF2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerRGBAUVXYZF2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerUVRGBAXYZF2[8] = {}; template void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size); template void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerUVRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerSTQXYZ2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerSTQXYZF2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerUVXYZ2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerUVXYZF2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerRGBAUVXYZF2(const GIFPackedReg* RESTRICT r, u32 size); + template void GIFPackedRegHandlerUVRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size); + void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, u32 size); template void ApplyTEX0(GIFRegTEX0& TEX0);