diff --git a/pcsx2/x86/newVif.h b/pcsx2/x86/newVif.h index 1cbd8a5278..fc7939ed1c 100644 --- a/pcsx2/x86/newVif.h +++ b/pcsx2/x86/newVif.h @@ -25,16 +25,17 @@ typedef void (__fastcall *nVifrecCall)(uptr dest, uptr src); #include "newVif_HashBucket.h" #include "x86emitter/x86emitter.h" using namespace x86Emitter; -extern void mVUmergeRegs(int dest, int src, int xyzw, bool modXYZW = 0); -extern void nVifGen(int usn, int mask, int curCycle); -extern void _nVifUnpack (int idx, u8 *data, u32 size); -extern void dVifUnpack (int idx, u8 *data, u32 size); -extern void dVifInit (int idx); +extern void mVUmergeRegs(int dest, int src, int xyzw, bool modXYZW = 0); +extern void nVifGen (int usn, int mask, int curCycle); +extern void _nVifUnpack (int idx, u8 *data, u32 size); +extern void dVifUnpack (int idx, u8 *data, u32 size); +extern void dVifInit (int idx); static __pagealigned u8 nVifUpkExec[__pagesize*4]; static __aligned16 nVifCall nVifUpk[(2*2*16) *4]; // ([USN][Masking][Unpack Type]) [curCycle] static __aligned16 u32 nVifMask[3][4][4] = {0}; // [MaskNumber][CycleNumber][Vector] +#define VUFT VIFUnpackFuncTable #define _1mb (0x100000) #define _v0 0 #define _v1 0x55 @@ -113,23 +114,28 @@ static const u32 nVifT[32] = { 2, // V4-5 // Second verse, same as the first! + 4,2,1,0,8,4,2,0,12,6,3,0,16,8,4,2 +}; - 4, // S-32 - 2, // S-16 - 1, // S-8 - 0, // ---- - 8, // V2-32 - 4, // V2-16 - 2, // V2-8 - 0, // ---- - 12,// V3-32 - 6, // V3-16 - 3, // V3-8 - 0, // ---- - 16,// V4-32 - 8, // V4-16 - 4, // V4-8 - 2, // V4-5 +template< int idx, bool doMode, bool isFill, bool singleUnpack > +__releaseinline void __fastcall _nVifUnpackLoop(u8 *data, u32 size); + +typedef void (__fastcall* Fnptr_VifUnpackLoop)(u8 *data, u32 size); + +// Unpacks Until 'Num' is 0 +static const __aligned16 Fnptr_VifUnpackLoop UnpackLoopTable[2][2][2] = { + {{ _nVifUnpackLoop<0,0,0,0>, _nVifUnpackLoop<0,0,1,0> }, + { _nVifUnpackLoop<0,1,0,0>, _nVifUnpackLoop<0,1,1,0> },}, + {{ _nVifUnpackLoop<1,0,0,0>, _nVifUnpackLoop<1,0,1,0> }, + { _nVifUnpackLoop<1,1,0,0>, _nVifUnpackLoop<1,1,1,0> },}, +}; + +// Unpacks until 1 normal write cycle unpack has been written to VU mem +static const __aligned16 Fnptr_VifUnpackLoop UnpackSingleTable[2][2][2] = { + {{ _nVifUnpackLoop<0,0,0,1>, _nVifUnpackLoop<0,0,1,1> }, + { _nVifUnpackLoop<0,1,0,1>, _nVifUnpackLoop<0,1,1,1> },}, + {{ _nVifUnpackLoop<1,0,0,1>, _nVifUnpackLoop<1,0,1,1> }, + { _nVifUnpackLoop<1,1,0,1>, _nVifUnpackLoop<1,1,1,1> },}, }; #define useOldUnpack 0 // Use code in newVif_OldUnpack.inl diff --git a/pcsx2/x86/newVif_Dynarec.inl b/pcsx2/x86/newVif_Dynarec.inl index f2424da124..7a88e30268 100644 --- a/pcsx2/x86/newVif_Dynarec.inl +++ b/pcsx2/x86/newVif_Dynarec.inl @@ -35,8 +35,9 @@ void dVifInit(int idx) { _f void dVifRecLimit(int idx) { if (nVif[idx].recPtr > nVif[idx].recEnd) { - nVif[idx].vifBlocks->clear(); DevCon.WriteLn("nVif Rec - Out of Rec Cache! [%x > %x]", nVif[idx].recPtr, nVif[idx].recEnd); + nVif[idx].vifBlocks->clear(); + nVif[idx].recPtr = nVif[idx].vifCache->getBlock(); } } diff --git a/pcsx2/x86/newVif_Unpack.inl b/pcsx2/x86/newVif_Unpack.inl index 7505586d2c..d3616a1385 100644 --- a/pcsx2/x86/newVif_Unpack.inl +++ b/pcsx2/x86/newVif_Unpack.inl @@ -78,18 +78,15 @@ int nVifUnpack(int idx, u8* data) { vif->tag.size -= ret; if (v.partTransfer) { // Last transfer was a partial vector transfer... - const u8* vuMemBase = (idx ? VU1 : VU0).Mem; - const u8* dest = setVUptr(idx, vuMemBase, vif->tag.addr); - const u8 upkNum = vif->cmd & 0x1f; - const int usn = !!(vif->usn); - const VIFUnpackFuncTable& ft = VIFfuncTable[upkNum]; - UNPACKFUNCTYPE func = usn ? ft.funcU : ft.funcS; - const int diff = ft.gsize - v.partTransfer; + const bool doMode = vifRegs->mode && !(vif->tag.cmd & 0x10); + const bool isFill = (vifRegs->cycle.cl < vifRegs->cycle.wl); + const u8 upkNum = vif->cmd & 0x1f; + const VUFT& ft = VIFfuncTable[upkNum]; + const int diff = ft.gsize - v.partTransfer; memcpy(&v.partBuffer[v.partTransfer], data, diff); - func((u32*)dest, (u32*)v.partBuffer); + UnpackSingleTable[idx][doMode][isFill]( v.partBuffer, size ); data += diff; size -= diff; - vifRegs->num--; vif->tag.addr += 16; v.partTransfer = 0; //DevCon.WriteLn("Diff = %d", diff); @@ -171,7 +168,7 @@ static void setMasks(int idx, const VIFregisters& v) { // elimination that it would probably be a win in most cases (and for sure in many // "slow" games that need it most). --air -template< int idx, bool doMode, bool isFill > +template< int idx, bool doMode, bool isFill, bool singleUnpack > __releaseinline void __fastcall _nVifUnpackLoop(u8 *data, u32 size) { const int cycleSize = isFill ? vifRegs->cycle.cl : vifRegs->cycle.wl; @@ -217,8 +214,10 @@ __releaseinline void __fastcall _nVifUnpackLoop(u8 *data, u32 size) { vifRegs->num--; incVUptrBy16(idx, dest, vuMemBase); if (++vif->cl == blockSize) vif->cl = 0; + if (singleUnpack) break; } else if (isFill) { + //DevCon.WriteLn("isFill!"); func((u32*)dest, (u32*)data); vifRegs->num--; incVUptrBy16(idx, dest, vuMemBase); @@ -231,21 +230,6 @@ __releaseinline void __fastcall _nVifUnpackLoop(u8 *data, u32 size) { } } -typedef void (__fastcall* Fnptr_VifUnpackLoop)(u8 *data, u32 size); - -static const __aligned16 Fnptr_VifUnpackLoop UnpackLoopTable[2][2][2] = -{ - { - { _nVifUnpackLoop<0,false,false>, _nVifUnpackLoop<0,false,true> }, - { _nVifUnpackLoop<0,true, false>, _nVifUnpackLoop<0,true, true> }, - }, - { - { _nVifUnpackLoop<1,false,false>, _nVifUnpackLoop<1,false,true> }, - { _nVifUnpackLoop<1,true, false>, _nVifUnpackLoop<1,true, true> }, - }, - -}; - _f void _nVifUnpack(int idx, u8 *data, u32 size) { if (useOldUnpack) { @@ -254,12 +238,8 @@ _f void _nVifUnpack(int idx, u8 *data, u32 size) { return; } - const bool doMode = vifRegs->mode && !(vif->tag.cmd & 0x10); - const bool isFill = (vifRegs->cycle.cl < vifRegs->cycle.wl); + const bool doMode = vifRegs->mode && !(vif->tag.cmd & 0x10); + const bool isFill = (vifRegs->cycle.cl < vifRegs->cycle.wl); UnpackLoopTable[idx][doMode][isFill]( data, size ); - - //if (isFill) - //DevCon.WriteLn("%s Write! [num = %d][%s]", (isFill?"Filling":"Skipping"), vifRegs->num, (vifRegs->num%3 ? "bad!" : "ok")); - //DevCon.WriteLn("%s Write! [mask = %08x][type = %02d][num = %d]", (isFill?"Filling":"Skipping"), vifRegs->mask, upkNum, vifRegs->num); }