mirror of https://github.com/PCSX2/pcsx2.git
EE/DMA: Try to avoid very small DMA loops
This commit is contained in:
parent
c1c6bde429
commit
7d8d16091e
|
@ -54,6 +54,7 @@ R5900cpu *Cpu = NULL;
|
||||||
static const uint eeWaitCycles = 3072;
|
static const uint eeWaitCycles = 3072;
|
||||||
|
|
||||||
bool eeEventTestIsActive = false;
|
bool eeEventTestIsActive = false;
|
||||||
|
EE_intProcessStatus eeRunInterruptScan = INT_NOT_RUNNING;
|
||||||
|
|
||||||
u32 g_eeloadMain = 0, g_eeloadExec = 0, g_osdsys_str = 0;
|
u32 g_eeloadMain = 0, g_eeloadExec = 0, g_osdsys_str = 0;
|
||||||
|
|
||||||
|
@ -277,37 +278,50 @@ static __fi bool _cpuTestInterrupts()
|
||||||
//Console.Write("DMAC Disabled or suspended");
|
//Console.Write("DMAC Disabled or suspended");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* These are 'pcsx2 interrupts', they handle asynchronous stuff
|
|
||||||
that depends on the cycle timings */
|
|
||||||
TESTINT(VU_MTVU_BUSY, MTVUInterrupt);
|
|
||||||
TESTINT(DMAC_VIF1, vif1Interrupt);
|
|
||||||
TESTINT(DMAC_GIF, gifInterrupt);
|
|
||||||
TESTINT(DMAC_SIF0, EEsif0Interrupt);
|
|
||||||
TESTINT(DMAC_SIF1, EEsif1Interrupt);
|
|
||||||
// Profile-guided Optimization (sorta)
|
|
||||||
// The following ints are rarely called. Encasing them in a conditional
|
|
||||||
// as follows helps speed up most games.
|
|
||||||
|
|
||||||
if (cpuRegs.interrupt & ((1 << DMAC_VIF0) | (1 << DMAC_FROM_IPU) | (1 << DMAC_TO_IPU)
|
eeRunInterruptScan = INT_RUNNING;
|
||||||
| (1 << DMAC_FROM_SPR) | (1 << DMAC_TO_SPR) | (1 << DMAC_MFIFO_VIF) | (1 << DMAC_MFIFO_GIF)
|
|
||||||
| (1 << VIF_VU0_FINISH) | (1 << VIF_VU1_FINISH) | (1 << IPU_PROCESS)))
|
while (eeRunInterruptScan == INT_RUNNING)
|
||||||
{
|
{
|
||||||
TESTINT(DMAC_VIF0, vif0Interrupt);
|
/* These are 'pcsx2 interrupts', they handle asynchronous stuff
|
||||||
|
that depends on the cycle timings */
|
||||||
|
TESTINT(VU_MTVU_BUSY, MTVUInterrupt);
|
||||||
|
TESTINT(DMAC_VIF1, vif1Interrupt);
|
||||||
|
TESTINT(DMAC_GIF, gifInterrupt);
|
||||||
|
TESTINT(DMAC_SIF0, EEsif0Interrupt);
|
||||||
|
TESTINT(DMAC_SIF1, EEsif1Interrupt);
|
||||||
|
// Profile-guided Optimization (sorta)
|
||||||
|
// The following ints are rarely called. Encasing them in a conditional
|
||||||
|
// as follows helps speed up most games.
|
||||||
|
|
||||||
TESTINT(DMAC_FROM_IPU, ipu0Interrupt);
|
if (cpuRegs.interrupt & ((1 << DMAC_VIF0) | (1 << DMAC_FROM_IPU) | (1 << DMAC_TO_IPU)
|
||||||
TESTINT(DMAC_TO_IPU, ipu1Interrupt);
|
| (1 << DMAC_FROM_SPR) | (1 << DMAC_TO_SPR) | (1 << DMAC_MFIFO_VIF) | (1 << DMAC_MFIFO_GIF)
|
||||||
TESTINT(IPU_PROCESS, ipuCMDProcess);
|
| (1 << VIF_VU0_FINISH) | (1 << VIF_VU1_FINISH) | (1 << IPU_PROCESS)))
|
||||||
|
{
|
||||||
|
TESTINT(DMAC_VIF0, vif0Interrupt);
|
||||||
|
|
||||||
TESTINT(DMAC_FROM_SPR, SPRFROMinterrupt);
|
TESTINT(DMAC_FROM_IPU, ipu0Interrupt);
|
||||||
TESTINT(DMAC_TO_SPR, SPRTOinterrupt);
|
TESTINT(DMAC_TO_IPU, ipu1Interrupt);
|
||||||
|
TESTINT(IPU_PROCESS, ipuCMDProcess);
|
||||||
|
|
||||||
TESTINT(DMAC_MFIFO_VIF, vifMFIFOInterrupt);
|
TESTINT(DMAC_FROM_SPR, SPRFROMinterrupt);
|
||||||
TESTINT(DMAC_MFIFO_GIF, gifMFIFOInterrupt);
|
TESTINT(DMAC_TO_SPR, SPRTOinterrupt);
|
||||||
|
|
||||||
TESTINT(VIF_VU0_FINISH, vif0VUFinish);
|
TESTINT(DMAC_MFIFO_VIF, vifMFIFOInterrupt);
|
||||||
TESTINT(VIF_VU1_FINISH, vif1VUFinish);
|
TESTINT(DMAC_MFIFO_GIF, gifMFIFOInterrupt);
|
||||||
|
|
||||||
|
TESTINT(VIF_VU0_FINISH, vif0VUFinish);
|
||||||
|
TESTINT(VIF_VU1_FINISH, vif1VUFinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eeRunInterruptScan == INT_REQ_LOOP)
|
||||||
|
eeRunInterruptScan = INT_RUNNING;
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eeRunInterruptScan = INT_NOT_RUNNING;
|
||||||
|
|
||||||
if ((cpuRegs.interrupt & 0x1FFFF) & ~cpuRegs.dmastall)
|
if ((cpuRegs.interrupt & 0x1FFFF) & ~cpuRegs.dmastall)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -391,17 +405,20 @@ __fi void _cpuEventTest_Shared()
|
||||||
// These are basically just DMAC-related events, which also piggy-back the same bits as
|
// These are basically just DMAC-related events, which also piggy-back the same bits as
|
||||||
// the PS2's own DMA channel IRQs and IRQ Masks.
|
// the PS2's own DMA channel IRQs and IRQ Masks.
|
||||||
|
|
||||||
// This is a BIOS hack because the coding in the BIOS is terrible but the bug is masked by Data Cache
|
if (cpuRegs.interrupt)
|
||||||
// where a DMA buffer is overwritten without waiting for the transfer to end, which causes the fonts to get all messed up
|
|
||||||
// so to fix it, we run all the DMA's instantly when in the BIOS.
|
|
||||||
// Only use the lower 17 bits of the cpuRegs.interrupt as the upper bits are for VU0/1 sync which can't be done in a tight loop
|
|
||||||
if (CHECK_INSTANTDMAHACK && dmacRegs.ctrl.DMAE && !(psHu8(DMAC_ENABLER + 2) & 1) && (cpuRegs.interrupt & 0x1FFFF))
|
|
||||||
{
|
{
|
||||||
while ((cpuRegs.interrupt & 0x1FFFF) && _cpuTestInterrupts())
|
// This is a BIOS hack because the coding in the BIOS is terrible but the bug is masked by Data Cache
|
||||||
;
|
// where a DMA buffer is overwritten without waiting for the transfer to end, which causes the fonts to get all messed up
|
||||||
|
// so to fix it, we run all the DMA's instantly when in the BIOS.
|
||||||
|
// Only use the lower 17 bits of the cpuRegs.interrupt as the upper bits are for VU0/1 sync which can't be done in a tight loop
|
||||||
|
if (CHECK_INSTANTDMAHACK && dmacRegs.ctrl.DMAE && !(psHu8(DMAC_ENABLER + 2) & 1) && (cpuRegs.interrupt & 0x1FFFF))
|
||||||
|
{
|
||||||
|
while ((cpuRegs.interrupt & 0x1FFFF) && _cpuTestInterrupts())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_cpuTestInterrupts();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_cpuTestInterrupts();
|
|
||||||
|
|
||||||
// ---- IOP -------------
|
// ---- IOP -------------
|
||||||
// * It's important to run a iopEventTest before calling ExecuteBlock. This
|
// * It's important to run a iopEventTest before calling ExecuteBlock. This
|
||||||
|
@ -523,6 +540,17 @@ __fi void CPU_SET_DMASTALL(EE_EventType n, bool set)
|
||||||
|
|
||||||
__fi void CPU_INT( EE_EventType n, s32 ecycle)
|
__fi void CPU_INT( EE_EventType n, s32 ecycle)
|
||||||
{
|
{
|
||||||
|
// If it's retunning too quick, just rerun the DMA, there's no point in running the EE for < 4 cycles.
|
||||||
|
// This causes a huge uplift in performance for ONI FMV's.
|
||||||
|
if (ecycle < 4 && !(cpuRegs.dmastall & (1 << n)) && eeRunInterruptScan != INT_NOT_RUNNING)
|
||||||
|
{
|
||||||
|
eeRunInterruptScan = INT_REQ_LOOP;
|
||||||
|
cpuRegs.interrupt |= 1 << n;
|
||||||
|
cpuRegs.sCycle[n] = cpuRegs.cycle;
|
||||||
|
cpuRegs.eCycle[n] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// EE events happen 8 cycles in the future instead of whatever was requested.
|
// EE events happen 8 cycles in the future instead of whatever was requested.
|
||||||
// This can be used on games with PATH3 masking issues for example, or when
|
// This can be used on games with PATH3 masking issues for example, or when
|
||||||
// some FMV look bad.
|
// some FMV look bad.
|
||||||
|
|
|
@ -333,6 +333,13 @@ extern R5900cpu *Cpu;
|
||||||
extern R5900cpu intCpu;
|
extern R5900cpu intCpu;
|
||||||
extern R5900cpu recCpu;
|
extern R5900cpu recCpu;
|
||||||
|
|
||||||
|
enum EE_intProcessStatus
|
||||||
|
{
|
||||||
|
INT_NOT_RUNNING = 0,
|
||||||
|
INT_RUNNING,
|
||||||
|
INT_REQ_LOOP
|
||||||
|
};
|
||||||
|
|
||||||
enum EE_EventType
|
enum EE_EventType
|
||||||
{
|
{
|
||||||
DMAC_VIF0 = 0,
|
DMAC_VIF0 = 0,
|
||||||
|
|
|
@ -341,7 +341,10 @@ __fi void vif1Interrupt()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vif1ch.chcr.STR)
|
if (!vif1ch.chcr.STR)
|
||||||
|
{
|
||||||
Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32);
|
Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (vif1.irq && vif1.vifstalled.enabled && vif1.vifstalled.value == VIF_IRQ_STALL)
|
if (vif1.irq && vif1.vifstalled.enabled && vif1.vifstalled.value == VIF_IRQ_STALL)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue