From 555c96a94141526669ba41a72eb5efb7819669eb Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Wed, 14 Dec 2016 19:12:31 +0100 Subject: [PATCH] vif: reorganize dVifUnpack Inline the execution part Add a num parameter to dVifsetVUptr Use a local variable for the nVifBlock instead of a global struct state The goal is to ease future update of the nVifBlock struct --- pcsx2/x86/newVif.h | 3 -- pcsx2/x86/newVif_Dynarec.cpp | 58 ++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/pcsx2/x86/newVif.h b/pcsx2/x86/newVif.h index 1a1b1760fb..83b6beeb2c 100644 --- a/pcsx2/x86/newVif.h +++ b/pcsx2/x86/newVif.h @@ -56,9 +56,6 @@ _vifT extern void dVifUnpack (const u8* data, bool isFill); #define xmmTemp xmm7 struct nVifStruct { - - __aligned16 nVifBlock block; - // Buffer for partial transfers (should always be first to ensure alignment) // Maximum buffer size is 256 (vifRegs.Num max range) * 16 (quadword) __aligned16 u8 buffer[256*16]; diff --git a/pcsx2/x86/newVif_Dynarec.cpp b/pcsx2/x86/newVif_Dynarec.cpp index 65084d355d..d4b9811c2c 100644 --- a/pcsx2/x86/newVif_Dynarec.cpp +++ b/pcsx2/x86/newVif_Dynarec.cpp @@ -258,21 +258,20 @@ void VifUnpackSSE_Dynarec::CompileRoutine() { xRET(); } -_vifT static __fi u8* dVifsetVUptr(uint cl, uint wl, bool isFill) { - nVifStruct& v = nVif[idx]; +_vifT static __fi u8* dVifsetVUptr(uint cl, uint wl, u8 num, bool isFill) { vifStruct& vif = MTVU_VifX; const VURegs& VU = vuRegs[idx]; const uint vuMemLimit = idx ? 0x4000 : 0x1000; u8* startmem = VU.Mem + (vif.tag.addr & (vuMemLimit-0x10)); u8* endmem = VU.Mem + vuMemLimit; - uint length = (v.block.num > 0) ? (v.block.num * 16) : 4096; // 0 = 256 + uint length = (num > 0) ? (num * 16) : 4096; // 0 = 256 //wl = wl ? wl : 256; //0 is taken as 256 (KH2) //if (wl == 256) isFill = true; if (!isFill) { uint skipSize = (cl - wl) * 16; - uint blocks = (v.block.num + (wl-1)) / wl; //Need to round up num's to calculate skip size correctly. + uint blocks = (num + (wl-1)) / wl; //Need to round up num's to calculate skip size correctly. length += (blocks-1) * skipSize; } @@ -283,19 +282,6 @@ _vifT static __fi u8* dVifsetVUptr(uint cl, uint wl, bool isFill) { return NULL; // Fall Back to Interpreters which have wrap-around logic } -_vifT static __ri void dVifExecuteUnpack(const u8* data, uptr x86, bool isFill) -{ - VIFregisters& vifRegs = MTVU_VifXRegs; - - if (u8* dest = dVifsetVUptr(vifRegs.cycle.cl, vifRegs.cycle.wl, isFill)) { - //DevCon.WriteLn("Running Recompiled Block!"); - ((nVifrecCall)x86)((uptr)dest, (uptr)data); - } else { - VIF_LOG("Running Interpreter Block"); - _nVifUnpack(idx, data, vifRegs.mode, isFill); - } -} - _vifT __fi uptr dVifCompile(nVifBlock& key) { nVifStruct& v = nVif[idx]; nVifBlock* block = v.vifBlocks.find(&key); @@ -320,7 +306,7 @@ _vifT __fi uptr dVifCompile(nVifBlock& key) { VifUnpackSSE_Dynarec(v, key).CompileRoutine(); - Perf::vif.map((uptr)v.recWritePtr, xGetPtr() - v.recWritePtr, v.block.upkType /* FIXME ideally a key*/); + Perf::vif.map((uptr)v.recWritePtr, xGetPtr() - v.recWritePtr, key.upkType /* FIXME ideally a key*/); v.recWritePtr = xGetPtr(); return key.startPtr; @@ -335,31 +321,39 @@ _vifT __fi void dVifUnpack(const u8* data, bool isFill) { const u8 upkType = (vif.cmd & 0x1f) | (vif.usn << 5); const int doMask = isFill? 1 : (vif.cmd & 0x10); - v.block.upkType = upkType; - v.block.num = (u8&)vifRegs.num; - v.block.mode = (u8&)vifRegs.mode; - v.block.cl = vifRegs.cycle.cl; - v.block.wl = vifRegs.cycle.wl ? vifRegs.cycle.wl : 256; - v.block.aligned = vif.start_aligned; //MTVU doesn't have a packet size! - v.block.startPtr = 0; // Ease the detection of the end of the hash bucket + __aligned16 nVifBlock block; + block.upkType = upkType; + block.num = (u8&)vifRegs.num; + block.mode = (u8&)vifRegs.mode; + block.cl = vifRegs.cycle.cl; + block.wl = vifRegs.cycle.wl ? vifRegs.cycle.wl : 256; + block.aligned = vif.start_aligned; //MTVU doesn't have a packet size! + block.startPtr = 0; // Ease the detection of the end of the hash bucket if ((upkType & 0xf) != 9) - v.block.aligned &= 0x1; + block.aligned &= 0x1; - //DevCon.Warning("Alignment %d", v.block.aligned); + //DevCon.Warning("Alignment %d", block.aligned); // Zero out the mask parameter if it's unused -- games leave random junk // values here which cause false recblock cache misses. - v.block.mask = doMask ? vifRegs.mask : 0; + block.mask = doMask ? vifRegs.mask : 0; //DevCon.WriteLn("nVif%d: Recompiled Block!", idx); //DevCon.WriteLn(L"[num=% 3d][upkType=0x%02x][scl=%d][cl=%d][wl=%d][mode=%d][m=%d][mask=%s]", - // v.Block.num, v.Block.upkType, v.Block.scl, v.Block.cl, v.Block.wl, v.Block.mode, - // doMask >> 4, doMask ? wxsFormat( L"0x%08x", v.Block.mask ).c_str() : L"ignored" + // block.num, block.upkType, block.scl, block.cl, block.wl, block.mode, + // doMask >> 4, doMask ? wxsFormat( L"0x%08x", block.mask ).c_str() : L"ignored" //); - uptr x86 = dVifCompile(v.block); + uptr x86 = dVifCompile(block); - dVifExecuteUnpack(data, x86, isFill); + // Run either the dynarec or the interpreter (if complex wrapping) + if (u8* dest = dVifsetVUptr(vifRegs.cycle.cl, vifRegs.cycle.wl, vifRegs.num, isFill)) { + //DevCon.WriteLn("Running Recompiled Block!"); + ((nVifrecCall)x86)((uptr)dest, (uptr)data); + } else { + VIF_LOG("Running Interpreter Block"); + _nVifUnpack(idx, data, vifRegs.mode, isFill); + } } template void dVifUnpack<0>(const u8* data, bool isFill);