VU-MTVU: Simulate VU times when in MTVU w/o Instant VU.

This commit is contained in:
refractionpcsx2 2022-07-25 20:54:23 +01:00
parent 742a929966
commit 53161f76a6
8 changed files with 38 additions and 13 deletions

View File

@ -89,7 +89,7 @@ SystemSettingsWidget::SystemSettingsWidget(SettingsDialog* dialog, QWidget* pare
"Safe for most games, but a few are incompatible and may hang.")); "Safe for most games, but a few are incompatible and may hang."));
dialog->registerWidgetHelp(m_ui.instantVU1, tr("Instant VU1"), tr("Checked"), dialog->registerWidgetHelp(m_ui.instantVU1, tr("Instant VU1"), tr("Checked"),
tr("Runs VU1 instantly (when MTVU is disabled). Provides a modest speed improvement. " tr("Runs VU1 instantly. Provides a modest speed improvement in most games. "
"Safe for most games, but a few games may exhibit graphical errors.")); "Safe for most games, but a few games may exhibit graphical errors."));
dialog->registerWidgetHelp(m_ui.fastCDVD, tr("Enable Fast CDVD"), tr("Unchecked"), dialog->registerWidgetHelp(m_ui.fastCDVD, tr("Enable Fast CDVD"), tr("Unchecked"),
@ -103,7 +103,7 @@ SystemSettingsWidget::~SystemSettingsWidget() = default;
void SystemSettingsWidget::updateVU1InstantState() void SystemSettingsWidget::updateVU1InstantState()
{ {
m_ui.instantVU1->setEnabled(!m_dialog->getEffectiveBoolValue("EmuCore/Speedhacks", "vuThread", false)); //m_ui.instantVU1->setEnabled(!m_dialog->getEffectiveBoolValue("EmuCore/Speedhacks", "vuThread", false));
} }
int SystemSettingsWidget::getGlobalClampingModeIndex(bool vu) const int SystemSettingsWidget::getGlobalClampingModeIndex(bool vu) const

View File

@ -416,7 +416,8 @@ void VU_Thread::Get_MTVUChanges()
{ {
mtvuInterrupts.fetch_and(~InterruptFlagVUEBit, std::memory_order_relaxed); mtvuInterrupts.fetch_and(~InterruptFlagVUEBit, std::memory_order_relaxed);
VU0.VI[REG_VPU_STAT].UL &= ~0xFF00; if(!INSTANT_VU1)
VU0.VI[REG_VPU_STAT].UL &= ~0xFF00;
//DevCon.Warning("E-Bit registered %x", VU0.VI[REG_VPU_STAT].UL); //DevCon.Warning("E-Bit registered %x", VU0.VI[REG_VPU_STAT].UL);
} }
if (interrupts & InterruptFlagVUTBit) if (interrupts & InterruptFlagVUTBit)
@ -458,10 +459,17 @@ void VU_Thread::ExecuteVU(u32 vu_addr, u32 vif_top, u32 vif_itop, u32 fbrst)
CommitWritePos(); CommitWritePos();
gifUnit.TransferGSPacketData(GIF_TRANS_MTVU, NULL, 0); gifUnit.TransferGSPacketData(GIF_TRANS_MTVU, NULL, 0);
KickStart(); KickStart();
u32 cycles = std::min(Get_vuCycles(), 3000u); u32 cycles = std::max(Get_vuCycles(), 4u);
cpuRegs.cycle += cycles * EmuConfig.Speedhacks.EECycleSkip; u32 skip_cycles = std::min(cycles, 3000u);
VU0.cycle += cycles * EmuConfig.Speedhacks.EECycleSkip; cpuRegs.cycle += skip_cycles * EmuConfig.Speedhacks.EECycleSkip;
VU0.cycle += skip_cycles * EmuConfig.Speedhacks.EECycleSkip;
Get_MTVUChanges(); Get_MTVUChanges();
if (!INSTANT_VU1)
{
VU0.VI[REG_VPU_STAT].UL |= 0x100;
CPU_INT(VU_MTVU_BUSY, cycles);
}
} }
void VU_Thread::VifUnpack(vifStruct& _vif, VIFregisters& _vifRegs, u8* data, u32 size) void VU_Thread::VifUnpack(vifStruct& _vif, VIFregisters& _vifRegs, u8* data, u32 size)

View File

@ -246,6 +246,13 @@ __fi void cpuSetNextEventDelta( s32 delta )
cpuSetNextEvent( cpuRegs.cycle, delta ); cpuSetNextEvent( cpuRegs.cycle, delta );
} }
__fi int cpuGetCycles(int interrupt)
{
int cycles = (cpuRegs.sCycle[interrupt] + cpuRegs.eCycle[interrupt]) - cpuRegs.cycle;
return std::max(1, cycles);
}
// tests the cpu cycle against the given start and delta values. // tests the cpu cycle against the given start and delta values.
// Returns true if the delta time has passed. // Returns true if the delta time has passed.
__fi int cpuTestCycle( u32 startCycle, s32 delta ) __fi int cpuTestCycle( u32 startCycle, s32 delta )
@ -292,7 +299,7 @@ static __fi void _cpuTestInterrupts()
} }
/* These are 'pcsx2 interrupts', they handle asynchronous stuff /* These are 'pcsx2 interrupts', they handle asynchronous stuff
that depends on the cycle timings */ that depends on the cycle timings */
TESTINT(VU_MTVU_BUSY, MTVUInterrupt);
TESTINT(DMAC_VIF1, vif1Interrupt); TESTINT(DMAC_VIF1, vif1Interrupt);
TESTINT(DMAC_GIF, gifInterrupt); TESTINT(DMAC_GIF, gifInterrupt);
TESTINT(DMAC_SIF0, EEsif0Interrupt); TESTINT(DMAC_SIF0, EEsif0Interrupt);

View File

@ -415,7 +415,8 @@ enum EE_EventType
DMAC_GIF_UNIT, DMAC_GIF_UNIT,
VIF_VU0_FINISH, VIF_VU0_FINISH,
VIF_VU1_FINISH, VIF_VU1_FINISH,
IPU_PROCESS IPU_PROCESS,
VU_MTVU_BUSY
}; };
extern void CPU_INT( EE_EventType n, s32 ecycle ); extern void CPU_INT( EE_EventType n, s32 ecycle );
@ -435,6 +436,7 @@ extern void cpuSetNextEvent( u32 startCycle, s32 delta );
extern void cpuSetNextEventDelta( s32 delta ); extern void cpuSetNextEventDelta( s32 delta );
extern int cpuTestCycle( u32 startCycle, s32 delta ); extern int cpuTestCycle( u32 startCycle, s32 delta );
extern void cpuSetEvent(); extern void cpuSetEvent();
extern int cpuGetCycles(int interrupt);
extern void _cpuEventTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900: extern void _cpuEventTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:

View File

@ -70,7 +70,6 @@ void vu1ExecMicro(u32 addr)
// VU0.VI[REG_VPU_STAT].UL |= 0x0100; // VU0.VI[REG_VPU_STAT].UL |= 0x0100;
// } // }
// Update 25/06/2022: Disabled this for now, let games YOLO it, if it breaks MTVU, disable MTVU (it doesn't work properly anyway) - Refraction // Update 25/06/2022: Disabled this for now, let games YOLO it, if it breaks MTVU, disable MTVU (it doesn't work properly anyway) - Refraction
vu1Thread.ExecuteVU(addr, vif1Regs.top, vif1Regs.itop, VU0.VI[REG_FBRST].UL); vu1Thread.ExecuteVU(addr, vif1Regs.top, vif1Regs.itop, VU0.VI[REG_FBRST].UL);
return; return;
} }
@ -90,3 +89,8 @@ void vu1ExecMicro(u32 addr)
else else
CpuVU1->Execute(vu1RunCycles); CpuVU1->Execute(vu1RunCycles);
} }
void MTVUInterrupt()
{
VU0.VI[REG_VPU_STAT].UL &= ~0xFF00;
}

View File

@ -256,6 +256,7 @@ extern void vu1ResetRegs();
extern void vu1ExecMicro(u32 addr); extern void vu1ExecMicro(u32 addr);
extern void vu1Exec(VURegs* VU); extern void vu1Exec(VURegs* VU);
extern void iDumpVU1Registers(); extern void iDumpVU1Registers();
extern void MTVUInterrupt();
#ifdef VUM_LOG #ifdef VUM_LOG

View File

@ -238,7 +238,10 @@ __fi void vif1VUFinish()
u32 _cycles = VU1.cycle; u32 _cycles = VU1.cycle;
//DevCon.Warning("Finishing VU1"); //DevCon.Warning("Finishing VU1");
vu1Finish(false); vu1Finish(false);
CPU_INT(VIF_VU1_FINISH, VU1.cycle - _cycles); if (THREAD_VU1 && !INSTANT_VU1 && (VU0.VI[REG_VPU_STAT].UL & 0x100))
CPU_INT(VIF_VU1_FINISH, cpuGetCycles(VU_MTVU_BUSY));
else
CPU_INT(VIF_VU1_FINISH, VU1.cycle - _cycles);
return; return;
} }

View File

@ -167,7 +167,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
m_check_vuThread = new pxCheckBox( vuHacksPanel, _("MTVU (Multi-Threaded microVU1)"), m_check_vuThread = new pxCheckBox( vuHacksPanel, _("MTVU (Multi-Threaded microVU1)"),
_("Good Speedup and High Compatibility; may cause hanging... [Recommended on 3+ cores]") ); _("Good Speedup and High Compatibility; may cause hanging... [Recommended on 3+ cores]") );
m_check_vu1Instant = new pxCheckBox(vuHacksPanel, _("Instant VU1 (without MTVU only)"), m_check_vu1Instant = new pxCheckBox(vuHacksPanel, _("Instant VU1"),
_("Good Speedup and High Compatibility; may cause some graphical errors")); _("Good Speedup and High Compatibility; may cause some graphical errors"));
m_check_vuFlagHack->SetToolTip( pxEt( L"Updates Status Flags only on blocks which will read them, instead of all the time. This is safe most of the time." m_check_vuFlagHack->SetToolTip( pxEt( L"Updates Status Flags only on blocks which will read them, instead of all the time. This is safe most of the time."
@ -176,7 +176,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
m_check_vuThread->SetToolTip( pxEt( L"Runs VU1 on its own thread (microVU1-only). Generally a speedup on CPUs with 3 or more cores. This is safe for most games, but a few games are incompatible and may hang. In the case of GS limited games, it may be a slowdown (especially on dual core CPUs)." m_check_vuThread->SetToolTip( pxEt( L"Runs VU1 on its own thread (microVU1-only). Generally a speedup on CPUs with 3 or more cores. This is safe for most games, but a few games are incompatible and may hang. In the case of GS limited games, it may be a slowdown (especially on dual core CPUs)."
) ); ) );
m_check_vu1Instant->SetToolTip(pxEt(L"Runs VU1 instantly (when MTVU is disabled). Provides a modest speed improvement. This is safe for most games, but a few games may exhibit graphical errors." m_check_vu1Instant->SetToolTip(pxEt(L"Runs VU1 instantly. Provides a modest speed improvement in most games. This is safe for most games, but a few games may exhibit graphical errors."
)); ));
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -270,7 +270,7 @@ void Panels::SpeedHacksPanel::EnableStuff( AppConfig* configToUse )
// Disables the Instant VU1 checkbox when MTVU is checked in the GUI as reflected in the code. // Disables the Instant VU1 checkbox when MTVU is checked in the GUI as reflected in the code.
// Makes Instant VU1 toggleable when MTVU is unchecked in the GUI. // Makes Instant VU1 toggleable when MTVU is unchecked in the GUI.
// Some may think that having MTVU + Instant VU1 checked, can have bad side-effects when it doesn't. // Some may think that having MTVU + Instant VU1 checked, can have bad side-effects when it doesn't.
m_check_vu1Instant->Enable(hacksEnabled && !m_check_vuThread->GetValue()); //m_check_vu1Instant->Enable(hacksEnabled && !m_check_vuThread->GetValue());
// Layout necessary to ensure changed slider text gets re-aligned properly // Layout necessary to ensure changed slider text gets re-aligned properly
// and to properly gray/ungray pxStaticText stuff (I suspect it causes a // and to properly gray/ungray pxStaticText stuff (I suspect it causes a