DC fix: Since game's frame-finish-watchdog have nothing to do with RTC, the faked GP watchdog moved in scheduler. DC should work for everyone now, we just may need to adjust FAKE_GP_WATCHDOG_PERIOD. TODO if it worth it: the actual re-scheduling of the new callback is stupid, so... + Some clean up. + Remove the unused GPUCallBack.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1210 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
memberTwo.mb2 committed 2008-11-18 13:08:46 +00:00
1 parent 9e31e3796a
commit e069e5997a
6 files changed
+43 -107

No files matched your search

-6
View File
@@ -22,8 +22,6 @@
#include "CoreTiming.h"
#include "StringUtil.h"
#include "HW/CommandProcessor.h" // <- for DC watchdog hack
// TODO(ector): Replace new/delete in this file with a simple memory pool
// Don't expect a massive speedup though.
@@ -305,10 +303,6 @@ void Advance()
globalTimer += cyclesExecuted;
// for DC watchdog hack
// TODO (mb2): add DC mode check
CommandProcessor::CheckGPWDInterruptForSpinlock();
while (first)
{
if (first->time <= globalTimer)
+14 -22
View File
@@ -48,11 +48,10 @@
// TODO (mb2):
// * raise watermark Ov/Un irq: POINTLESS since emulated GP timings can't be accuratly set.
// Only 3 choices IMHO for a correct emulated load balancing in DC mode:
// - make our own GP watchdog hack that can lock CPU if GP too slow.
// - make our own GP watchdog hack that can lock CPU if GP too slow. STARTED
// - hack directly something in PPC timings (dunno how)
// - boost GP so we can consider it as infinitely fast compared to CPU.
// * raise ReadIdle/CmdIdle flags and observe behaviour of MP1 & ZTP (at least)
// * investigate VI and PI for fixing the DC ZTP bug.
// * Clean useless comments and debug stuff in Read16, Write16, GatherPipeBursted when sync will be fixed for DC
// * (reminder) do the same in:
// PeripheralInterface.cpp, PixelEngine.cpp, OGL->BPStructs.cpp, fifo.cpp... ok just check change log >>
@@ -173,31 +172,28 @@ int et_UpdateInterrupts;
// for GP watchdog hack
void IncrementGPWDToken()
{
#ifdef WIN32
#ifdef _WIN32
InterlockedIncrement((LONG*)&fifo.Fake_GPWDToken);
#else
Common::InterlockedIncrement((int*)&fifo.Fake_GPWDToken);
#endif
}
void CheckGPWDInterruptForSpinlock()
// Check every FAKE_GP_WATCHDOG_PERIOD if a PE-frame-finish occured
// if not then lock CPUThread until GP finish a frame.
u32 fake_GPWatchdogLastToken = 0;
void WaitForFrameFinish()
{
if (fifo.Fake_GPWDInterrupt)
{
// Wait for GPU to catch up
while (fifo.bFF_GPReadEnable && (fifo.CPReadWriteDistance > 0) && !(fifo.bFF_BPEnable && fifo.bFF_Breakpoint))
//while (fifo.bFF_GPReadEnable && (fifo.CPReadWriteDistance > 0))
;
//if (!fifo.bFF_GPReadEnable) PanicAlert("WARNING: Fake_GPWDInterrupt raised but can't flush fifo. Fake_GPWDToken %i",fifo.Fake_GPWDToken);
#ifdef _WIN32
InterlockedExchange((LONG*)&fifo.Fake_GPWDInterrupt, 0);
#else
Common::InterlockedExchange((int*)&fifo.Fake_GPWDInterrupt, 0);
#endif
LOGV(COMMANDPROCESSOR, 2, "!!! Fake_GPWDInterrupt raised. Fake_GPWDToken %i",fifo.Fake_GPWDToken);
}
while (fake_GPWatchdogLastToken == fifo.Fake_GPWDToken && fifo.bFF_GPReadEnable && (fifo.CPReadWriteDistance > 0) && !(fifo.bFF_BPEnable && fifo.bFF_Breakpoint))
;
// oh well, should be safe.
// Assuming: time between 2 GP-frame-finish (ie. increment of fifo.Fake_GPWDToken)
// will be EVER way superior to time between
// "while (g_FAKE_GPWatchdogToken == fifo.Fake_GPWDToken..." and this line. :p
fake_GPWatchdogLastToken = fifo.Fake_GPWDToken;
}
void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate)
{
UpdateInterrupts();
@@ -517,10 +513,6 @@ void GatherPipeBursted()
if (Core::g_CoreStartupParameter.bUseDualCore)
{
// for GP watchdog hack
// not very safe to do that here
CheckGPWDInterruptForSpinlock();
// update the fifo-pointer
fifo.CPWritePointer += GPFifo::GATHER_PIPE_SIZE;
if (fifo.CPWritePointer >= fifo.CPEnd)
+2 -2
View File
@@ -79,9 +79,9 @@ void UpdateInterruptsFromVideoPlugin();
bool AllowIdleSkipping();
// for GP watchdog hack
// for DC GP watchdog hack
void IncrementGPWDToken();
void CheckGPWDInterruptForSpinlock();
void WaitForFrameFinish();
} // end of namespace CommandProcessor
+1 -1
View File
@@ -177,7 +177,6 @@ void SetFinish_OnMainThread(u64 userdata, int cyclesLate)
{
g_bSignalFinishInterrupt = 1;
UpdateInterrupts();
CommandProcessor::IncrementGPWDToken();
}
// SetToken
@@ -192,6 +191,7 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge)
// THIS IS EXECUTED FROM VIDEO THREAD
void SetFinish()
{
CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack
CoreTiming::ScheduleEvent_Threadsafe(
0, et_SetFinishOnMainThread);
LOGV(PIXELENGINE, 2, "VIDEO Set Finish");
+18 -8
View File
@@ -24,6 +24,7 @@
#include "../HW/AudioInterface.h"
#include "../HW/VideoInterface.h"
#include "../HW/SerialInterface.h"
#include "../HW/CommandProcessor.h" // for DC watchdog hack
#include "../PowerPC/PowerPC.h"
#include "../CoreTiming.h"
#include "../Core.h"
@@ -42,6 +43,7 @@ s64 fakeDec;
// With TB clk at 1/4 of BUS clk
// and it seems BUS clk is really 1/3 of CPU clk
// note: ZWW is ok and faster with TIMER_RATIO=8 though.
// !!! POSSIBLE STABLE PERF BOOST HACK THERE !!!
enum {
TIMER_RATIO = 12
};
@@ -53,7 +55,7 @@ int et_AI;
int et_AudioFifo;
int et_DSP;
int et_IPC_HLE;
int et_GPU;
int et_FakeGPWD; // for DC watchdog hack
// These are badly educated guesses
// Feel free to experiment
@@ -77,8 +79,10 @@ int
// increase this number.
IPC_HLE_PERIOD = GetTicksPerSecond() / 250,
// This one is also fairly arbitrary. Every N cycles, run the GPU until it starves (in single core mode only).
GPU_PERIOD = 10000;
// For DC watchdog hack
// Once every 2 frame-period should be enough.
// Assuming game's frame-finish-watchdog wait more than 2 emulated frame-period before starting its mess.
FAKE_GP_WATCHDOG_PERIOD = GetTicksPerSecond() / 30;
u32 GetTicksPerSecond()
{
@@ -161,9 +165,12 @@ void AdvanceCallback(int cyclesExecuted)
PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO;
}
void GPUCallback(u64 userdata, int cyclesLate)
// For DC watchdog hack
void FakeGPWatchdogCallback(u64 userdata, int cyclesLate)
{
CoreTiming::ScheduleEvent(GPU_PERIOD-cyclesLate, et_GPU);
CommandProcessor::WaitForFrameFinish(); // lock CPUThread until frame finish
CoreTiming::ScheduleEvent(FAKE_GP_WATCHDOG_PERIOD-cyclesLate, et_FakeGPWD);
}
void Init()
@@ -197,7 +204,6 @@ void Init()
et_VI = CoreTiming::RegisterEvent("VICallback", VICallback);
et_SI = CoreTiming::RegisterEvent("SICallback", SICallback);
et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback);
et_GPU = CoreTiming::RegisterEvent("GPUCallback", GPUCallback);
et_AudioFifo = CoreTiming::RegisterEvent("AudioFifoCallback", AudioFifoCallback);
et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
@@ -207,8 +213,12 @@ void Init()
CoreTiming::ScheduleEvent(SI_PERIOD, et_SI);
CoreTiming::ScheduleEvent(CPU_CORE_CLOCK / (32000 * 4 / 32), et_AudioFifo);
if (!Core::GetStartupParameter().bUseDualCore)
CoreTiming::ScheduleEvent(GPU_PERIOD, et_GPU);
// For DC watchdog hack
if (Core::GetStartupParameter().bUseDualCore)
{
et_FakeGPWD = CoreTiming::RegisterEvent("FakeGPWatchdogCallback", FakeGPWatchdogCallback);
CoreTiming::ScheduleEvent(FAKE_GP_WATCHDOG_PERIOD, et_FakeGPWD);
}
if (Core::GetStartupParameter().bWii)
CoreTiming::ScheduleEvent(IPC_HLE_PERIOD, et_IPC_HLE);