From bd3601b2d66c337ed1c23e20b010f4c5d0b5ced0 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Tue, 15 Sep 2009 06:24:41 +0000 Subject: [PATCH] gifTransferDummy() now handles path2 and path3 transfers. Hopefully doesn't break anything :) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1827 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/FiFo.cpp | 6 +- pcsx2/GS.h | 29 ++---- pcsx2/Gif.cpp | 13 +-- pcsx2/MTGS.cpp | 264 ++++++----------------------------------------- pcsx2/VifDma.cpp | 6 +- 5 files changed, 50 insertions(+), 268 deletions(-) diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index 4a0b1baee5..e89c47525f 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -160,6 +160,9 @@ void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value) assert( ret == 0 ); // vif stall code not implemented } +// Dummy GIF-TAG Packet to Guarantee Count = 1 +PCSX2_ALIGNED16(u32 nloop0_packet[4]) = {0x8000, 0, 0, 0}; + void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value) { jASSUME( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) ); @@ -172,8 +175,7 @@ void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value) psHu64(0x6008) = value[1]; FreezeRegs(1); - const uint count = mtgsThread->PrepDataPacket( GIF_PATH_3, value, 1 ); - jASSUME( count == 1 ); + const uint count = mtgsThread->PrepDataPacket(GIF_PATH_3, nloop0_packet, 1); u64* data = (u64*)mtgsThread->GetDataPacketPtr(); data[0] = value[0]; data[1] = value[1]; diff --git a/pcsx2/GS.h b/pcsx2/GS.h index 62ab53047c..cf07c4feed 100644 --- a/pcsx2/GS.h +++ b/pcsx2/GS.h @@ -89,28 +89,12 @@ struct GIFTAG struct GIFPath { GIFTAG tag; - u32 curreg; + u32 curreg; // Not Used Anymore u32 _pad[3]; u8 regs[16]; - __forceinline void PrepRegs(); - void SetTag(const void* mem, bool doPrepRegs); - u32 GetReg(); - - __forceinline bool StepReg() - { - if((++curreg & 0xf) == tag.nreg) - { - curreg = 0; - - if(--tag.nloop == 0) - { - return false; - } - } - - return true; - } + __forceinline void PrepRegs(bool doPrep); + __forceinline void SetTag(const void* mem); }; @@ -230,9 +214,8 @@ public: // Used primarily for plugin startup/shutdown. void WaitGS(); - int PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size ); + int PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size ); int PrepDataPacket( GIF_PATH pathidx, const u32* srcdata, u32 size ); - int PrepDataPacket( GIF_PATH pathidx, const u64* srcdata, u32 size ); void SendDataPacket(); void SendSimplePacket( GS_RINGTYPE type, int data0, int data1, int data2 ); @@ -257,8 +240,8 @@ protected: // Processes a GIFtag & packet, and throws out some gsIRQs as needed. // Used to keep interrupts in sync with the EE, while the GS itself // runs potentially several frames behind. - int _gifTransferDummy ( GIF_PATH pathidx, const u8 *pMem, u32 size ); - int _gifTransferDummy2( GIF_PATH pathidx, const u8 *pMem, u32 size ); + int gifTransferDummy(GIF_PATH pathidx, const u8 *pMem, u32 size); + int _gifTransferDummy(GIF_PATH pathidx, const u8 *pMem, u32 size); // Used internally by SendSimplePacket type functions uint _PrepForSimplePacket(); diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index d6ef41dd0e..91711176ff 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -98,8 +98,7 @@ static u32 WRITERING_DMA(u32 *pMem, u32 qwc) { psHu32(GIF_STAT) |= GIF_STAT_APATH3 | GIF_STAT_OPH; - int sizetoread = qwc; - sizetoread = mtgsThread->PrepDataPacket( GIF_PATH_3, pMem, qwc ); + int size = mtgsThread->PrepDataPacket(GIF_PATH_3, pMem, qwc); u8* pgsmem = mtgsThread->GetDataPacketPtr(); /* check if page of endmem is valid (dark cloud2) */ @@ -111,10 +110,10 @@ static u32 WRITERING_DMA(u32 *pMem, u32 qwc) // fixed? PrepDataPacket now returns the actual size of the packet. // VIF handles scratchpad wrapping also, so this code shouldn't be needed anymore. - memcpy_aligned(pgsmem, pMem, sizetoread<<4); + memcpy_aligned(pgsmem, pMem, size<<4); mtgsThread->SendDataPacket(); - return sizetoread; + return size; } int _GIFchain() @@ -134,8 +133,8 @@ int _GIFchain() Console::Notice( "Hackfix - NULL GIFchain" ); return -1; } - - return (WRITERING_DMA(pMem, qwc)); + + return WRITERING_DMA(pMem, qwc); } static __forceinline void GIFchain() @@ -384,7 +383,6 @@ static __forceinline int mfifoGIFrbTransfer() /* it doesn't, so just transfer 'qwc*16' words from 'gif->madr' to GS */ src = (u32*)PSM(gif->madr); if (src == NULL) return -1; - mfifoqwc = WRITERING_DMA(src, mfifoqwc); gif->madr = psHu32(DMAC_RBOR) + (gif->madr & psHu32(DMAC_RBSR)); } @@ -410,7 +408,6 @@ static __forceinline int mfifoGIFchain() int mfifoqwc = gif->qwc; u32 *pMem = (u32*)dmaGetAddr(gif->madr); if (pMem == NULL) return -1; - mfifoqwc = WRITERING_DMA(pMem, mfifoqwc); mfifocycles += (mfifoqwc) * 2; /* guessing */ } diff --git a/pcsx2/MTGS.cpp b/pcsx2/MTGS.cpp index 00c8f50ff4..ae13b79094 100644 --- a/pcsx2/MTGS.cpp +++ b/pcsx2/MTGS.cpp @@ -59,8 +59,9 @@ using namespace std; // registers are stored as a sequence of 4 bit values in the // upper 64 bits of the GIFTAG. That sucks for us, so we unpack // them into an 8 bit array. -__forceinline void GIFPath::PrepRegs() +__forceinline void GIFPath::PrepRegs(bool doPrep = 1) { + if (!doPrep) return; int loopEnd = ((tag.nreg-1)&0xf) + 1; u32 tempreg = tag.regs[0]; @@ -71,17 +72,10 @@ __forceinline void GIFPath::PrepRegs() } } -void GIFPath::SetTag(const void* mem, bool doPrepRegs = 1) +__forceinline void GIFPath::SetTag(const void* mem) { tag = *((GIFTAG*)mem); curreg = 0; - - if (doPrepRegs) PrepRegs(); -} - -u32 GIFPath::GetReg() -{ - return regs[curreg]; } static void _mtgsFreezeGIF( SaveState& state, GIFPath (&paths)[3] ) @@ -235,26 +229,28 @@ void mtgsThreadObject::Reset() memzero_obj( m_path ); } -#define incPmem(x) { \ - if ((pMem + x) >= ptrEnd) pMem = (pMem + x) - 0x4000; \ - else pMem += x; \ - size += x; \ +#define incPmem(x) { \ + pMem += x; \ + size += x; \ + if ((pathidx==GIF_PATH_1)&&(pMem>=vuMemEnd)) pMem -= 0x4000; \ } -__forceinline int mtgsThreadObject::_gifTransferDummy2(GIF_PATH pathidx, const u8* pMem, u32 size) +__forceinline int mtgsThreadObject::_gifTransferDummy(GIF_PATH pathidx, const u8* pMem, u32 size) { GIFPath& path = m_path[pathidx]; - u8* ptrEnd = (u8*)pMem + (size<<4); // End of VU Mem + u8* vuMemEnd = (u8*)pMem + (size<<4); // End of VU Mem + u32 finish = (pathidx == GIF_PATH_1) ? 0x4000 : (size<<4); bool EOP = 0; bool hasRegAD = 0; size = 0; - while(!EOP && size < 0x4000) { - path.SetTag(pMem, !path.tag.flg); - EOP = path.tag.eop; - int numRegs = ((path.tag.nreg-1)&0xf)+1; + while(!EOP && size < finish) { + path.SetTag(pMem); + path.PrepRegs(!path.tag.flg); + EOP = (pathidx == GIF_PATH_2) ? 0 : path.tag.eop; incPmem(16); if (!path.tag.nloop) continue; + int numRegs = ((path.tag.nreg-1)&0xf)+1; switch(path.tag.flg) { case GIF_FLG_PACKED: for (u32 i = 0; i < path.tag.nloop; i++) { @@ -262,12 +258,13 @@ __forceinline int mtgsThreadObject::_gifTransferDummy2(GIF_PATH pathidx, const u if (path.regs[j] == 0x0e) { const int handler = pMem[8]; if (handler >= 0x60 && handler < 0x63) { - //DevCon::Status("GIF Tag Signal"); + //DevCon::Status("GIF Tag Interrupt"); s_GSHandlers[handler&0x3]((const u32*)pMem); } hasRegAD = 1; } incPmem(16); + if (size >= finish) goto endLoop; } if (!hasRegAD) { // Optimization: No Need to Loop incPmem((16 * numRegs * (path.tag.nloop-1))); @@ -285,23 +282,25 @@ __forceinline int mtgsThreadObject::_gifTransferDummy2(GIF_PATH pathidx, const u break; } } +endLoop: + if (size > finish) size = finish; + if (pathidx == GIF_PATH_3) { + gif->madr += size; + gif->qwc -= (size/16); + Path3progress = STOPPED_MODE; + } return (size / 16); } // Processes a GIFtag & packet, and throws out some gsIRQs as needed. // Used to keep interrupts in sync with the EE, while the GS itself // runs potentially several frames behind. -// size - size of the packet in simd128's -__forceinline int mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u8* pMem, u32 size ) +__forceinline int mtgsThreadObject::gifTransferDummy(GIF_PATH pathidx, const u8* pMem, u32 size) { - GIFPath& path = m_path[pathidx]; - /* bool path1loop = false; - int startval = size;*/ #ifdef PCSX2_GSRING_SAMPLING_STATS static uptr profStartPtr = 0; static uptr profEndPtr = 0; - if( profStartPtr == 0 ) - { + if (profStartPtr == 0) { __asm { __beginfunc: @@ -312,197 +311,16 @@ __forceinline int mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u } #endif - while(size > 0) - { - if (path.tag.nloop == 0) - { - path.SetTag( pMem ); + int retSize = _gifTransferDummy(pathidx, pMem, size); - pMem += sizeof(GIFTAG); - --size; - - if (pathidx == 2) - { - if (path.tag.flg != GIF_FLG_IMAGE) - Path3progress = TRANSFER_MODE; //Other mode (but not stopped, I guess?) - else - Path3progress = IMAGE_MODE; //IMAGE mode - //if(pathidx == 2) GIF_LOG("Set Giftag NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress); - } - - if (pathidx == 0) - { - // int transize = 0; - // hack: if too much data for VU1, just ignore. - - // The GIF is evil : if nreg is 0, it's really 16. Otherwise it's the value in nreg. - /*const int numregs = path.tag.nreg ? path.tag.nreg : 16; - if(path.tag.flg < 2) - { - transize = (path.tag.nloop * numregs); - } - else transize = path.tag.nloop; - - if(transize > (path.tag.flg == 1 ? 0x800 : 0x400)) - { - //DevCon::Notice("Too much data"); - path.tag.nloop = 0; - if(path1loop == true)return ++size - 0x400; - else return ++size; - }*/ - const int numregs = ((path.tag.nreg-1)&15)+1; - - if((path.tag.nloop * numregs) > (size * ((path.tag.flg == 1) ? 2 : 1))) - { - path.tag.nloop = 0; - return ++size; - } - } - } - else - { - // NOTE: size > 0 => do {} while(size > 0); should be faster than while(size > 0) {} - - //if(pathidx == 2) GIF_LOG("PATH3 NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress); - switch(path.tag.flg) - { - case GIF_FLG_PACKED: - - do - { - if( path.GetReg() == 0xe ) - { - const int handler = pMem[8]; - if(handler >= 0x60 && handler < 0x63) - s_GSHandlers[handler&0x3]((const u32*)pMem); - } - - size--; - pMem += 16; // 128 bits! //sizeof(GIFPackedReg); - } - while(path.StepReg() && size > 0); - - break; - - case GIF_FLG_REGLIST: - - size *= 2; - - do - { - const int handler = path.GetReg(); - if(handler >= 0x60 && handler < 0x63) - s_GSHandlers[handler&0x3]((const u32*)pMem); - - size--; - pMem += 8; //sizeof(GIFReg); -- 64 bits! - } - while(path.StepReg() && size > 0); - - if(size & 1) pMem += 8; //sizeof(GIFReg); - - size /= 2; - - break; - - case GIF_FLG_IMAGE2: // hmmm - assert(0); - path.tag.nloop = 0; - - break; - - case GIF_FLG_IMAGE: - { - int len = (int)min(size, path.tag.nloop); - - pMem += len * 16; - path.tag.nloop -= len; - size -= len; - } - break; - - jNO_DEFAULT; - - } - } - - if(path.tag.nloop == 0) - { - if(path.tag.eop) - { - if(pathidx != 1) - { - break; - } - /*if((path.tag.nloop > 0 || (!path.tag.eop && path.tag.nloop == 0)) && size == 0) - { - if(path1loop == true) return size - 0x400; - //DevCon::Notice("Looping Nloop %x, Eop %x, FLG %x", path.tag.nloop, path.tag.eop, path.tag.flg); - size = 0x400; - pMem -= 0x4000; - path1loop = true; - }*/ - } - /*else if(size == 0 && pathidx == 0) - { - if(path1loop == true) return size - 0x400; - //DevCon::Notice("Looping Nloop %x, Eop %x, FLG %x", path.tag.nloop, path.tag.eop, path.tag.flg); - size = 0x400; - pMem -= 0x4000; - path1loop = true; - }*/ - } - /*else if(size == 0 && pathidx == 0) - { - if(path1loop == true) return size - 0x400; - //DevCon::Notice("Looping Nloop %x, Eop %x, FLG %x", path.tag.nloop, path.tag.eop, path.tag.flg); - size = 0x400; - pMem -= 0x4000; - path1loop = true; - }*/ - } - - if(pathidx == 0) - { - //If the XGKick has spun around the VU memory end address, we need to INCREASE the size sent. - /*if(path1loop == true) - { - return (size - 0x400); //This will cause a negative making eg. size(20) - retval(-30) = 50; - }*/ - if(size == 0 && path.tag.nloop > 0) - { - path.tag.nloop = 0; - DevCon::Write( "path1 hack! " ); - - // This means that the giftag data got screwly somewhere - // along the way (often means curreg was in a bad state or something) - } - } - - - if(pathidx == 2) - { - if(path.tag.nloop == 0 ) - { - //DevCon::Notice("Finishing Giftag NLoop %d EOP %x Mode %d nregs %d Path3progress %d Vifstat VGW %x", - //params path.tag.nloop, path.tag.eop, path.tag.flg, path.tag.nreg, Path3progress, vif1Regs->stat & VIF1_STAT_VGW); - if(path.tag.eop) - { - Path3progress = STOPPED_MODE; - //GIF_LOG("Set progress NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress); - } - - } - - } #ifdef PCSX2_GSRING_SAMPLING_STATS - __asm + __asm { __endfunc: nop; } #endif - return size; + return retSize; } void mtgsThreadObject::PostVsyncEnd( bool updategs ) @@ -848,11 +666,6 @@ void mtgsThreadObject::SendDataPacket() //m_PacketLocker.Unlock(); } -int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u64* srcdata, u32 size ) -{ - return PrepDataPacket( pathidx, (u8*)srcdata, size ); -} - int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u32* srcdata, u32 size ) { return PrepDataPacket( pathidx, (u8*)srcdata, size ); @@ -947,23 +760,8 @@ int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 s size = (size+15)&(~15); }*/ - if (pathidx != GIF_PATH_1) { - // retval has the amount of data *not* processed, so we only need to reserve - // enough room for size - retval: - int retval = _gifTransferDummy( pathidx, srcdata, size ); - - if(pathidx == GIF_PATH_3) - { - gif->madr += (size - retval) * 16; - gif->qwc -= size - retval; - } - //if(retval < 0) DevCon::Notice("Increasing size from %x to %x path %x", size, size-retval, pathidx+1); - size = size - retval; - } - else size = _gifTransferDummy2(pathidx, srcdata, size); - - m_packet_size = size; - size++; // takes into account our command qword. + m_packet_size = gifTransferDummy(pathidx, srcdata, size); + size = m_packet_size + 1; // takes into account our command qword. if( writepos + size < m_RingBufferSize ) { diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index 1dbfb8c8c5..345b07b72b 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -1854,6 +1854,9 @@ static int __fastcall Vif1TransMPG(u32 *data) } } +// Dummy GIF-TAG Packet to Guarantee Count = 1 +PCSX2_ALIGNED16_EXTERN(u32 nloop0_packet[4]); + static int __fastcall Vif1TransDirectHL(u32 *data) { int ret = 0; @@ -1884,8 +1887,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data) FreezeRegs(1); // copy 16 bytes the fast way: const u64* src = (u64*)splittransfer[0]; - const uint count = mtgsThread->PrepDataPacket(GIF_PATH_2, src, 1); - jASSUME(count == 1); + const uint count = mtgsThread->PrepDataPacket(GIF_PATH_2, nloop0_packet, 1); u64* dst = (u64*)mtgsThread->GetDataPacketPtr(); dst[0] = src[0]; dst[1] = src[1];