mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-03 11:32:43 +01:00
This could alleviate the suffering of dual core synchronization a bit.
But I doubt you would notice it in most cases. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4830 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
b186f0821e
commit
571a47ef9a
@ -106,7 +106,6 @@ void DSound::SoundLoop()
|
|||||||
while (!threadData)
|
while (!threadData)
|
||||||
{
|
{
|
||||||
// No blocking inside the csection
|
// No blocking inside the csection
|
||||||
soundCriticalSection.Enter();
|
|
||||||
dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0);
|
dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0);
|
||||||
int numBytesToRender = FIX128(ModBufferSize(currentPos - lastPos));
|
int numBytesToRender = FIX128(ModBufferSize(currentPos - lastPos));
|
||||||
if (numBytesToRender >= 256)
|
if (numBytesToRender >= 256)
|
||||||
@ -117,7 +116,6 @@ void DSound::SoundLoop()
|
|||||||
WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
|
WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
|
||||||
lastPos = ModBufferSize(lastPos + numBytesToRender);
|
lastPos = ModBufferSize(lastPos + numBytesToRender);
|
||||||
}
|
}
|
||||||
soundCriticalSection.Leave();
|
|
||||||
soundSyncEvent.Wait();
|
soundSyncEvent.Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,10 +147,8 @@ void DSound::SetVolume(int volume)
|
|||||||
// This is in "dBA attenuation" from 0 to -10000, logarithmic
|
// This is in "dBA attenuation" from 0 to -10000, logarithmic
|
||||||
m_volume = (int)floor(log10((float)volume) * 5000.0f) - 10000;
|
m_volume = (int)floor(log10((float)volume) * 5000.0f) - 10000;
|
||||||
|
|
||||||
soundCriticalSection.Enter();
|
|
||||||
if (dsBuffer != NULL)
|
if (dsBuffer != NULL)
|
||||||
dsBuffer->SetVolume(m_volume);
|
dsBuffer->SetVolume(m_volume);
|
||||||
soundCriticalSection.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSound::Update()
|
void DSound::Update()
|
||||||
@ -164,7 +160,6 @@ void DSound::Clear(bool mute)
|
|||||||
{
|
{
|
||||||
m_muted = mute;
|
m_muted = mute;
|
||||||
|
|
||||||
soundCriticalSection.Enter();
|
|
||||||
if (m_muted)
|
if (m_muted)
|
||||||
{
|
{
|
||||||
dsBuffer->Stop();
|
dsBuffer->Stop();
|
||||||
@ -173,7 +168,6 @@ void DSound::Clear(bool mute)
|
|||||||
{
|
{
|
||||||
dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
|
dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
|
||||||
}
|
}
|
||||||
soundCriticalSection.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSound::Stop()
|
void DSound::Stop()
|
||||||
@ -182,13 +176,11 @@ void DSound::Stop()
|
|||||||
// kick the thread if it's waiting
|
// kick the thread if it's waiting
|
||||||
soundSyncEvent.Set();
|
soundSyncEvent.Set();
|
||||||
|
|
||||||
soundCriticalSection.Enter();
|
|
||||||
delete thread;
|
delete thread;
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
dsBuffer->Stop();
|
dsBuffer->Stop();
|
||||||
dsBuffer->Release();
|
dsBuffer->Release();
|
||||||
ds->Release();
|
ds->Release();
|
||||||
soundCriticalSection.Leave();
|
|
||||||
|
|
||||||
soundSyncEvent.Shutdown();
|
soundSyncEvent.Shutdown();
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,7 @@ class DSound : public SoundStream
|
|||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Common::Thread *thread;
|
Common::Thread *thread;
|
||||||
Common::CriticalSection soundCriticalSection;
|
Common::EventEx soundSyncEvent;
|
||||||
Common::Event soundSyncEvent;
|
|
||||||
void *hWnd;
|
void *hWnd;
|
||||||
|
|
||||||
IDirectSound8* ds;
|
IDirectSound8* ds;
|
||||||
|
@ -64,8 +64,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Common::Thread *thread;
|
Common::Thread *thread;
|
||||||
Common::CriticalSection soundCriticalSection;
|
Common::EventEx soundSyncEvent;
|
||||||
Common::Event soundSyncEvent;
|
|
||||||
|
|
||||||
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
|
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
|
||||||
ALuint uiBuffers[OAL_NUM_BUFFERS];
|
ALuint uiBuffers[OAL_NUM_BUFFERS];
|
||||||
|
@ -117,6 +117,60 @@ void Thread::SetCurrentThreadAffinity(int mask)
|
|||||||
SetThreadAffinityMask(GetCurrentThread(), mask);
|
SetThreadAffinityMask(GetCurrentThread(), mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
EventEx::EventEx()
|
||||||
|
{
|
||||||
|
InterlockedExchange(&m_Lock, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventEx::Init()
|
||||||
|
{
|
||||||
|
InterlockedExchange(&m_Lock, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventEx::Shutdown()
|
||||||
|
{
|
||||||
|
InterlockedExchange(&m_Lock, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventEx::Set()
|
||||||
|
{
|
||||||
|
InterlockedExchange(&m_Lock, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventEx::Spin()
|
||||||
|
{
|
||||||
|
while (InterlockedCompareExchange(&m_Lock, 1, 0))
|
||||||
|
// This only yields when there is a runnable thread on this core
|
||||||
|
// If not, spin
|
||||||
|
SwitchToThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventEx::Wait()
|
||||||
|
{
|
||||||
|
while (InterlockedCompareExchange(&m_Lock, 1, 0))
|
||||||
|
// This directly enters Ring0 and enforces a sleep about 15ms
|
||||||
|
SleepCurrentThread(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventEx::MsgWait()
|
||||||
|
{
|
||||||
|
while (InterlockedCompareExchange(&m_Lock, 1, 0))
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
if (msg.message == WM_QUIT) return false;
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
// This directly enters Ring0 and enforces a sleep about 15ms
|
||||||
|
SleepCurrentThread(1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Regular same thread loop based waiting
|
// Regular same thread loop based waiting
|
||||||
Event::Event()
|
Event::Event()
|
||||||
{
|
{
|
||||||
@ -164,6 +218,7 @@ void Event::MsgWait()
|
|||||||
if (msg.message == WM_QUIT)
|
if (msg.message == WM_QUIT)
|
||||||
return;
|
return;
|
||||||
// Otherwise, dispatch the message.
|
// Otherwise, dispatch the message.
|
||||||
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,31 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Event(WaitForSingleObject) is too expensive
|
||||||
|
// as it always enters Ring0 regardless of the state of lock
|
||||||
|
// This EventEx will try to stay in Ring3 as much as possible
|
||||||
|
// If the lock can be obtained in the first time, Ring0 won't be entered at all
|
||||||
|
class EventEx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EventEx();
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
void Set();
|
||||||
|
// Infinite wait
|
||||||
|
void Spin();
|
||||||
|
// Infinite wait with sleep
|
||||||
|
void Wait();
|
||||||
|
// Wait with message processing and sleep
|
||||||
|
bool MsgWait();
|
||||||
|
private:
|
||||||
|
volatile long m_Lock;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
// TODO: implement for Linux
|
||||||
|
#define EventEx Event
|
||||||
|
#endif
|
||||||
|
|
||||||
class Event
|
class Event
|
||||||
{
|
{
|
||||||
@ -182,9 +206,10 @@ private:
|
|||||||
void InitThreading();
|
void InitThreading();
|
||||||
void SleepCurrentThread(int ms);
|
void SleepCurrentThread(int ms);
|
||||||
|
|
||||||
// YieldCPU: Use this function during a spin-wait to make the current thread
|
// YieldCPU: This function is only effective on HyperThreading CPU
|
||||||
// relax while another thread is working. This may be more efficient than using
|
// Use this function during a spin-wait to make the current thread
|
||||||
// events because event functions use kernel calls.
|
// relax while another thread is working. This may be more efficient
|
||||||
|
// than using events because event functions use kernel calls.
|
||||||
inline void YieldCPU()
|
inline void YieldCPU()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -548,13 +548,14 @@ void ScreenShot()
|
|||||||
// This should only be called from VI
|
// This should only be called from VI
|
||||||
void VideoThrottle()
|
void VideoThrottle()
|
||||||
{
|
{
|
||||||
u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 1) ? SConfig::GetInstance().m_Framelimit * 10
|
u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 1) ?
|
||||||
: VideoInterface::TargetRefreshRate;
|
SConfig::GetInstance().m_Framelimit * 10 : VideoInterface::TargetRefreshRate;
|
||||||
|
|
||||||
// When frame limit is NOT off
|
// When frame limit is NOT off
|
||||||
if (SConfig::GetInstance().m_Framelimit)
|
if (SConfig::GetInstance().m_Framelimit)
|
||||||
{
|
{
|
||||||
u32 frametime = DrawnVideo * 1000 / TargetVPS;
|
// Make the limiter a bit loose
|
||||||
|
u32 frametime = DrawnVideo * 1000 / ++TargetVPS;
|
||||||
while ((u32)Timer.GetTimeDifference() < frametime)
|
while ((u32)Timer.GetTimeDifference() < frametime)
|
||||||
Common::YieldCPU();
|
Common::YieldCPU();
|
||||||
//Common::SleepCurrentThread(1);
|
//Common::SleepCurrentThread(1);
|
||||||
@ -567,7 +568,7 @@ void VideoThrottle()
|
|||||||
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
||||||
|
|
||||||
u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime;
|
u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime;
|
||||||
u32 VPS = DrawnVideo * 1000 / ElapseTime;
|
u32 VPS = --DrawnVideo * 1000 / ElapseTime;
|
||||||
u32 Speed = VPS * 100 / VideoInterface::TargetRefreshRate;
|
u32 Speed = VPS * 100 / VideoInterface::TargetRefreshRate;
|
||||||
|
|
||||||
// Settings are shown the same for both extended and summary info
|
// Settings are shown the same for both extended and summary info
|
||||||
@ -611,7 +612,7 @@ void VideoThrottle()
|
|||||||
SystemTimers::GetTicksPerSecond() / 1000000,
|
SystemTimers::GetTicksPerSecond() / 1000000,
|
||||||
_CoreParameter.bSkipIdle ? "~" : "",
|
_CoreParameter.bSkipIdle ? "~" : "",
|
||||||
TicksPercentage);
|
TicksPercentage);
|
||||||
|
|
||||||
#else // Summary information
|
#else // Summary information
|
||||||
std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed);
|
std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed);
|
||||||
#endif
|
#endif
|
||||||
@ -630,7 +631,7 @@ void VideoThrottle()
|
|||||||
Common::AtomicStore(DrawnFrame, 0);
|
Common::AtomicStore(DrawnFrame, 0);
|
||||||
DrawnVideo = 0;
|
DrawnVideo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawnVideo++;
|
DrawnVideo++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,13 +132,7 @@ int
|
|||||||
|
|
||||||
// This is completely arbitrary. If we find that we need lower latency, we can just
|
// This is completely arbitrary. If we find that we need lower latency, we can just
|
||||||
// increase this number.
|
// increase this number.
|
||||||
IPC_HLE_PERIOD,
|
IPC_HLE_PERIOD;
|
||||||
|
|
||||||
// For DC watchdog hack
|
|
||||||
// Once every 4 frame-period seems to be enough (arbitrary taking 60fps as the ref).
|
|
||||||
// TODO: make it VI output frame rate compliant (30/60 and 25/50)
|
|
||||||
// Assuming game's frame-finish-watchdog wait more than 4 emulated frame-period before starting its mess.
|
|
||||||
FAKE_GP_WATCHDOG_PERIOD;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -227,7 +221,7 @@ void AdvanceCallback(int cyclesExecuted)
|
|||||||
void FakeGPWatchdogCallback(u64 userdata, int cyclesLate)
|
void FakeGPWatchdogCallback(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
CPluginManager::GetInstance().GetVideo()->Video_WaitForFrameFinish(); // lock CPUThread until frame finish
|
CPluginManager::GetInstance().GetVideo()->Video_WaitForFrameFinish(); // lock CPUThread until frame finish
|
||||||
CoreTiming::ScheduleEvent(FAKE_GP_WATCHDOG_PERIOD-cyclesLate, et_FakeGPWD);
|
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_FakeGPWD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatchEngineCallback(u64 userdata, int cyclesLate)
|
void PatchEngineCallback(u64 userdata, int cyclesLate)
|
||||||
@ -235,7 +229,7 @@ void PatchEngineCallback(u64 userdata, int cyclesLate)
|
|||||||
// Patch mem and run the Action Replay
|
// Patch mem and run the Action Replay
|
||||||
PatchEngine::ApplyFramePatches();
|
PatchEngine::ApplyFramePatches();
|
||||||
PatchEngine::ApplyARPatches();
|
PatchEngine::ApplyARPatches();
|
||||||
CoreTiming::ScheduleEvent((GetTicksPerSecond() / 5000) - cyclesLate, et_PatchEngine);
|
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_PatchEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
@ -271,8 +265,6 @@ void Init()
|
|||||||
if (UsingDSPLLE)
|
if (UsingDSPLLE)
|
||||||
DSP_PERIOD = 12000; // TO BE TWEAKED
|
DSP_PERIOD = 12000; // TO BE TWEAKED
|
||||||
|
|
||||||
FAKE_GP_WATCHDOG_PERIOD = GetTicksPerSecond() / 60;
|
|
||||||
|
|
||||||
// This is the biggest question mark.
|
// This is the biggest question mark.
|
||||||
AI_PERIOD = GetTicksPerSecond() / 80;
|
AI_PERIOD = GetTicksPerSecond() / 80;
|
||||||
|
|
||||||
@ -297,16 +289,14 @@ void Init()
|
|||||||
CoreTiming::ScheduleEvent(AI_PERIOD, et_AI);
|
CoreTiming::ScheduleEvent(AI_PERIOD, et_AI);
|
||||||
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_VI);
|
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_VI);
|
||||||
CoreTiming::ScheduleEvent(DSP_PERIOD, et_DSP);
|
CoreTiming::ScheduleEvent(DSP_PERIOD, et_DSP);
|
||||||
CoreTiming::ScheduleEvent(GetTicksPerSecond() / 60, et_SI);
|
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_SI);
|
||||||
CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA);
|
CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA);
|
||||||
|
|
||||||
// For DC watchdog hack
|
// For DC watchdog hack
|
||||||
if (Core::GetStartupParameter().bCPUThread)
|
if (Core::GetStartupParameter().bCPUThread)
|
||||||
{
|
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_FakeGPWD);
|
||||||
CoreTiming::ScheduleEvent(FAKE_GP_WATCHDOG_PERIOD, et_FakeGPWD);
|
|
||||||
}
|
|
||||||
|
|
||||||
CoreTiming::ScheduleEvent(GetTicksPerSecond() / 60, et_PatchEngine);
|
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_PatchEngine);
|
||||||
|
|
||||||
if (Core::GetStartupParameter().bWii)
|
if (Core::GetStartupParameter().bWii)
|
||||||
CoreTiming::ScheduleEvent(IPC_HLE_PERIOD, et_IPC_HLE);
|
CoreTiming::ScheduleEvent(IPC_HLE_PERIOD, et_IPC_HLE);
|
||||||
|
@ -391,7 +391,7 @@ void CMemoryWindow::onSearch(wxCommandEvent& event){
|
|||||||
}
|
}
|
||||||
if(size){
|
if(size){
|
||||||
unsigned char* pnt=&Dest.front();
|
unsigned char* pnt=&Dest.front();
|
||||||
int k=0;
|
unsigned int k=0;
|
||||||
//grab
|
//grab
|
||||||
|
|
||||||
wxString txt = addrbox->GetValue();
|
wxString txt = addrbox->GetValue();
|
||||||
|
@ -187,7 +187,7 @@ void CLogWindow::LoadSettings()
|
|||||||
m_verbosity->SetSelection(verbosity - 1);
|
m_verbosity->SetSelection(verbosity - 1);
|
||||||
ini.Get("Options", "Font", &font, 0);
|
ini.Get("Options", "Font", &font, 0);
|
||||||
m_FontChoice->SetSelection(font);
|
m_FontChoice->SetSelection(font);
|
||||||
if (m_FontChoice->GetSelection() < Font.size())
|
if (m_FontChoice->GetSelection() < (int)Font.size())
|
||||||
m_Log->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, Font.at(m_FontChoice->GetSelection())));
|
m_Log->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, Font.at(m_FontChoice->GetSelection())));
|
||||||
ini.Get("Options", "WriteToFile", &m_writeFile, true);
|
ini.Get("Options", "WriteToFile", &m_writeFile, true);
|
||||||
m_writeFileCB->SetValue(m_writeFile);
|
m_writeFileCB->SetValue(m_writeFile);
|
||||||
@ -303,7 +303,7 @@ wxTextCtrl* CLogWindow::CreateTextCtrl(wxPanel* parent, wxWindowID id, long Styl
|
|||||||
TC->SetBackgroundColour(*wxBLACK);
|
TC->SetBackgroundColour(*wxBLACK);
|
||||||
if (m_FontChoice)
|
if (m_FontChoice)
|
||||||
{
|
{
|
||||||
if (m_FontChoice->GetSelection() < Font.size())
|
if (m_FontChoice->GetSelection() < (int)Font.size())
|
||||||
TC->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, Font.at(m_FontChoice->GetSelection())));
|
TC->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, Font.at(m_FontChoice->GetSelection())));
|
||||||
}
|
}
|
||||||
return TC;
|
return TC;
|
||||||
|
@ -105,7 +105,7 @@ int m_bboxbottom;
|
|||||||
u16 m_tokenReg;
|
u16 m_tokenReg;
|
||||||
|
|
||||||
static u32 fake_GPWatchdogLastToken = 0;
|
static u32 fake_GPWatchdogLastToken = 0;
|
||||||
static Common::Event s_fifoIdleEvent;
|
static Common::EventEx s_fifoIdleEvent;
|
||||||
static Common::CriticalSection sFifoCritical;
|
static Common::CriticalSection sFifoCritical;
|
||||||
|
|
||||||
void FifoCriticalEnter()
|
void FifoCriticalEnter()
|
||||||
@ -381,7 +381,7 @@ void Write16(const u16 _Value, const u32 _Address)
|
|||||||
// Touching that game is a no-go so I don't want to take the risk :p
|
// Touching that game is a no-go so I don't want to take the risk :p
|
||||||
while (fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
while (fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
||||||
{
|
{
|
||||||
s_fifoIdleEvent.MsgWait();
|
s_fifoIdleEvent.Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,7 +573,7 @@ void WaitForFrameFinish()
|
|||||||
{
|
{
|
||||||
while ((fake_GPWatchdogLastToken == fifo.Fake_GPWDToken) && fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)));
|
while ((fake_GPWatchdogLastToken == fifo.Fake_GPWDToken) && fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)));
|
||||||
{
|
{
|
||||||
s_fifoIdleEvent.MsgWait();
|
s_fifoIdleEvent.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_GPWatchdogLastToken = fifo.Fake_GPWDToken;
|
fake_GPWatchdogLastToken = fifo.Fake_GPWDToken;
|
||||||
@ -618,7 +618,7 @@ void STACKALIGN GatherPipeBursted()
|
|||||||
// Wait for GPU to catch up
|
// Wait for GPU to catch up
|
||||||
while (fifo.CPReadWriteDistance > fifo.CPLoWatermark && fifo.bFF_GPReadEnable && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
while (fifo.CPReadWriteDistance > fifo.CPLoWatermark && fifo.bFF_GPReadEnable && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
||||||
{
|
{
|
||||||
s_fifoIdleEvent.MsgWait();
|
s_fifoIdleEvent.Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if we are in sync
|
// check if we are in sync
|
||||||
|
@ -36,7 +36,7 @@ namespace
|
|||||||
static volatile bool fifoStateRun = false;
|
static volatile bool fifoStateRun = false;
|
||||||
static volatile bool EmuRunning = false;
|
static volatile bool EmuRunning = false;
|
||||||
static u8 *videoBuffer;
|
static u8 *videoBuffer;
|
||||||
static Common::Event fifo_run_event;
|
static Common::EventEx fifo_run_event;
|
||||||
// STATE_TO_SAVE
|
// STATE_TO_SAVE
|
||||||
static int size = 0;
|
static int size = 0;
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -170,6 +170,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
|||||||
{
|
{
|
||||||
Common::AtomicStore(_fifo.bFF_Breakpoint, 1);
|
Common::AtomicStore(_fifo.bFF_Breakpoint, 1);
|
||||||
CommandProcessor::UpdateInterruptsFromVideoPlugin(true);
|
CommandProcessor::UpdateInterruptsFromVideoPlugin(true);
|
||||||
|
CommandProcessor::FifoCriticalLeave();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
distToSend = 32;
|
distToSend = 32;
|
||||||
@ -208,10 +209,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
|||||||
// leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down.
|
// leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down.
|
||||||
VideoFifo_CheckEFBAccess();
|
VideoFifo_CheckEFBAccess();
|
||||||
VideoFifo_CheckSwapRequest();
|
VideoFifo_CheckSwapRequest();
|
||||||
|
|
||||||
CommandProcessor::SetFifoIdleFromVideoPlugin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandProcessor::SetFifoIdleFromVideoPlugin();
|
CommandProcessor::SetFifoIdleFromVideoPlugin();
|
||||||
if (EmuRunning)
|
if (EmuRunning)
|
||||||
Common::YieldCPU();
|
Common::YieldCPU();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user