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."));
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."));
dialog->registerWidgetHelp(m_ui.fastCDVD, tr("Enable Fast CDVD"), tr("Unchecked"),
@ -103,7 +103,7 @@ SystemSettingsWidget::~SystemSettingsWidget() = default;
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

View File

@ -416,6 +416,7 @@ void VU_Thread::Get_MTVUChanges()
{
mtvuInterrupts.fetch_and(~InterruptFlagVUEBit, std::memory_order_relaxed);
if(!INSTANT_VU1)
VU0.VI[REG_VPU_STAT].UL &= ~0xFF00;
//DevCon.Warning("E-Bit registered %x", VU0.VI[REG_VPU_STAT].UL);
}
@ -458,10 +459,17 @@ void VU_Thread::ExecuteVU(u32 vu_addr, u32 vif_top, u32 vif_itop, u32 fbrst)
CommitWritePos();
gifUnit.TransferGSPacketData(GIF_TRANS_MTVU, NULL, 0);
KickStart();
u32 cycles = std::min(Get_vuCycles(), 3000u);
cpuRegs.cycle += cycles * EmuConfig.Speedhacks.EECycleSkip;
VU0.cycle += cycles * EmuConfig.Speedhacks.EECycleSkip;
u32 cycles = std::max(Get_vuCycles(), 4u);
u32 skip_cycles = std::min(cycles, 3000u);
cpuRegs.cycle += skip_cycles * EmuConfig.Speedhacks.EECycleSkip;
VU0.cycle += skip_cycles * EmuConfig.Speedhacks.EECycleSkip;
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)

View File

@ -246,6 +246,13 @@ __fi void cpuSetNextEventDelta( s32 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.
// Returns true if the delta time has passed.
__fi int cpuTestCycle( u32 startCycle, s32 delta )
@ -292,7 +299,7 @@ static __fi void _cpuTestInterrupts()
}
/* 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);

View File

@ -415,7 +415,8 @@ enum EE_EventType
DMAC_GIF_UNIT,
VIF_VU0_FINISH,
VIF_VU1_FINISH,
IPU_PROCESS
IPU_PROCESS,
VU_MTVU_BUSY
};
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 int cpuTestCycle( u32 startCycle, s32 delta );
extern void cpuSetEvent();
extern int cpuGetCycles(int interrupt);
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;
// }
// 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);
return;
}
@ -90,3 +89,8 @@ void vu1ExecMicro(u32 addr)
else
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 vu1Exec(VURegs* VU);
extern void iDumpVU1Registers();
extern void MTVUInterrupt();
#ifdef VUM_LOG

View File

@ -238,6 +238,9 @@ __fi void vif1VUFinish()
u32 _cycles = VU1.cycle;
//DevCon.Warning("Finishing VU1");
vu1Finish(false);
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;
}

View File

@ -167,7 +167,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
m_check_vuThread = new pxCheckBox( vuHacksPanel, _("MTVU (Multi-Threaded microVU1)"),
_("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"));
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_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.
// 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.
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
// and to properly gray/ungray pxStaticText stuff (I suspect it causes a