diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index b884574eeb..5b05226e1b 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -20,6 +20,7 @@ #include "Gif.h" #include "GS.h" #include "Vif.h" +#include "Vif_Dma.h" #include "IPU/IPU.h" #include "IPU/IPU_Fifo.h" @@ -64,12 +65,20 @@ void __fastcall ReadFIFO_page_5(u32 mem, u64 *out) if(vif1Regs->stat.FQC == 0) Console.Warning("FQC = 0 on VIF FIFO READ!"); if (vif1Regs->stat.FDR) { + if(vif1Regs->stat.FQC > vif1.GSLastDownloadSize) + { + DevCon.Warning("Warning! GS Download size < FIFO count!"); + } if (vif1Regs->stat.FQC > 0) { GetMTGS().WaitGS(); GSreadFIFO(&psHu64(VIF1_FIFO)); } - if(vif1Regs->stat.FQC > 0)--vif1Regs->stat.FQC; + if(vif1Regs->stat.FQC > 0) + { + --vif1.GSLastDownloadSize; + vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize); + } if(vif1Regs->stat.FQC == 0) //We're out of data now so clear this.. gifRegs->stat.OPH = false; diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index ad0a8fd53f..f3d83a91c4 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -31,7 +31,7 @@ __forceinline void vif1FLUSH() void vif1TransferToMemory() { - int size; + u32 size; u64* pMem = (u64*)dmaGetAddr(vif1ch->madr, false); // VIF from gsMemory @@ -53,38 +53,69 @@ void vif1TransferToMemory() //Console.Warning("Real QWC %x", vif1ch->qwc); XMMRegisters::Freeze(); + size = min((u32)vif1ch->qwc, vif1.GSLastDownloadSize); + if (GSreadFIFO2 == NULL) { - for (size = vif1ch->qwc; size > 0; --size) + for (;size > 0; --size) { - if (size > 1) - { - GetMTGS().WaitGS(); - GSreadFIFO(&psHu64(VIF1_FIFO)); - } + GetMTGS().WaitGS(); + GSreadFIFO(&psHu64(VIF1_FIFO)); + pMem[0] = psHu64(VIF1_FIFO); pMem[1] = psHu64(VIF1_FIFO + 8); pMem += 2; } + if(vif1ch->qwc > vif1.GSLastDownloadSize) + { + DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space"); + for (size = vif1ch->qwc - vif1.GSLastDownloadSize; size > 0; --size) + { + psHu64(VIF1_FIFO) = 0; + psHu64(VIF1_FIFO + 8) = 0; + pMem[0] = psHu64(VIF1_FIFO); + pMem[1] = psHu64(VIF1_FIFO + 8); + pMem += 2; + } + } } else { GetMTGS().WaitGS(); - GSreadFIFO2(pMem, vif1ch->qwc); + GSreadFIFO2(pMem, size); // set incase read - psHu64(VIF1_FIFO) = pMem[2*vif1ch->qwc-2]; - psHu64(VIF1_FIFO + 8) = pMem[2*vif1ch->qwc-1]; + psHu64(VIF1_FIFO) = pMem[2*size-2]; + psHu64(VIF1_FIFO + 8) = pMem[2*size-1]; + pMem += size * 2; + if(vif1ch->qwc > vif1.GSLastDownloadSize) + { + DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space"); + for (size = vif1ch->qwc - vif1.GSLastDownloadSize; size > 0; --size) + { + psHu64(VIF1_FIFO) = 0; + psHu64(VIF1_FIFO + 8) = 0; + pMem[0] = psHu64(VIF1_FIFO); + pMem[1] = psHu64(VIF1_FIFO + 8); + pMem += 2; + } + } } + XMMRegisters::Thaw(); g_vifCycles += vif1ch->qwc * 2; vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes if(vif1.GSLastDownloadSize > vif1ch->qwc) - vif1Regs->stat.FQC = vif1.GSLastDownloadSize - vif1ch->qwc; + { + vif1.GSLastDownloadSize -= vif1ch->qwc; + vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize); + } else + { vif1Regs->stat.FQC = 0; + } vif1ch->qwc = 0; } @@ -213,7 +244,8 @@ __forceinline void vif1Interrupt() return; } - vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16); + //We need to check the direction, if it is downloading from the GS, we handle that seperately (KH2 for testing) + if (vif1ch->chcr.DIR)vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16); //Simulated GS transfer time done, clear the flags if(gifRegs->stat.APATH == GIF_APATH2 && (vif1.cmd & 0x70) != 0x50) { diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index 2d01c8f4de..b2c37e34e7 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -311,12 +311,12 @@ static __forceinline void gsHandler(const u8* pMem) Console.Error("Illegal format for GS upload: SPSM=0%02o", vif1.BITBLTBUF.SPSM); } - VIF_LOG("GS Download %dx%d SPSM= bpp=%d", vif1.TRXREG.RRW, vif1.TRXREG.RRH, vif1.BITBLTBUF.SPSM, bpp); + VIF_LOG("GS Download %dx%d SPSM=%x bpp=%d", vif1.BITBLTBUF.DBP, vif1.TRXREG.RRH, vif1.BITBLTBUF.SPSM, bpp); // qwords, rounded down; any extra bits are lost // games must take care to ensure transfer rectangles are exact multiples of a qword vif1.GSLastDownloadSize = vif1.TRXREG.RRW * vif1.TRXREG.RRH * bpp >> 7; - + VIF_LOG("GS Download size %x", vif1.GSLastDownloadSize); gifRegs->stat.OPH = true; } }