Skip to content

Commit

Permalink
VideoCommon: rewrite sync on idle skipping hack
Browse files Browse the repository at this point in the history
Now it's done without a busy loop
  • Loading branch information
degasus committed Mar 7, 2015
1 parent ec767fa commit e8ba439
Show file tree
Hide file tree
Showing 10 changed files with 30 additions and 29 deletions.
6 changes: 1 addition & 5 deletions Source/Core/Core/CoreTiming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,11 +480,7 @@ void Idle()
//When the FIFO is processing data we must not advance because in this way
//the VI will be desynchronized. So, We are waiting until the FIFO finish and
//while we process only the events required by the FIFO.
while (g_video_backend->Video_IsPossibleWaitingSetDrawDone())
{
ProcessFifoWaitEvents();
Common::YieldCPU();
}
g_video_backend->Video_Sync();
}

idledCycles += DowncountToCycles(PowerPC::ppcState.downcount);
Expand Down
5 changes: 0 additions & 5 deletions Source/Core/VideoBackends/Software/SWmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,6 @@ void VideoSoftware::Video_GatherPipeBursted()
SWCommandProcessor::GatherPipeBursted();
}

bool VideoSoftware::Video_IsPossibleWaitingSetDrawDone()
{
return false;
}

void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
{
SWCommandProcessor::RegisterMMIO(mmio, base);
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/Software/VideoBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class VideoSoftware : public VideoBackend
void Video_SetRendering(bool bEnabled) override;

void Video_GatherPipeBursted() override;
bool Video_IsPossibleWaitingSetDrawDone() override;
void Video_Sync() override {}

void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override;

Expand Down
6 changes: 1 addition & 5 deletions Source/Core/VideoCommon/CommandProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ static u16 m_bboxright;
static u16 m_bboxbottom;
static u16 m_tokenReg;

volatile bool isPossibleWaitingSetDrawDone = false;
volatile bool interruptSet= false;
volatile bool interruptWaiting= false;
volatile bool interruptTokenWaiting = false;
Expand Down Expand Up @@ -70,7 +69,6 @@ void DoState(PointerWrap &p)
p.Do(m_tokenReg);
p.Do(fifo);

p.Do(isPossibleWaitingSetDrawDone);
p.Do(interruptSet);
p.Do(interruptWaiting);
p.Do(interruptTokenWaiting);
Expand Down Expand Up @@ -123,8 +121,6 @@ void Init()
interruptFinishWaiting = false;
interruptTokenWaiting = false;

isPossibleWaitingSetDrawDone = false;

et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
}

Expand Down Expand Up @@ -518,7 +514,7 @@ void SetCpControlRegister()
if (fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable)
{
fifo.bFF_GPReadEnable = m_CPCtrlReg.GPReadEnable;
while (fifo.isGpuReadingData) Common::YieldCPU();
FlushGpu();
}
else
{
Expand Down
1 change: 0 additions & 1 deletion Source/Core/VideoCommon/CommandProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ namespace CommandProcessor

extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator thread.

extern volatile bool isPossibleWaitingSetDrawDone; //This one is used for sync gfx thread and emulator thread.
extern volatile bool interruptSet;
extern volatile bool interruptWaiting;
extern volatile bool interruptTokenWaiting;
Expand Down
29 changes: 22 additions & 7 deletions Source/Core/VideoCommon/Fifo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ static std::atomic<bool> s_gpu_is_running;
static std::mutex s_fifo_mutex;
static std::condition_variable s_fifo_cond_var;

// events for flush gpu
static std::mutex s_gpu_flush_mutex;
static std::condition_variable s_gpu_flush_cond_var;

void Fifo_DoState(PointerWrap &p)
{
p.DoArray(s_video_buffer, FIFO_SIZE);
Expand Down Expand Up @@ -134,9 +138,8 @@ void ExitGpuLoop()
{
// This should break the wait loop in CPU thread
CommandProcessor::fifo.bFF_GPReadEnable = false;
SCPFifoStruct &fifo = CommandProcessor::fifo;
while (fifo.isGpuReadingData)
Common::YieldCPU();
FlushGpu();

// Terminate GPU thread loop
GpuRunningState = false;
EmuRunningState = true;
Expand Down Expand Up @@ -315,7 +318,6 @@ void RunGpuLoop()
while (GpuRunningState && EmuRunningState && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
{
fifo.isGpuReadingData = true;
CommandProcessor::isPossibleWaitingSetDrawDone = fifo.bFF_GPLinkEnable ? true : false;

if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU || Common::AtomicLoad(CommandProcessor::VITicks) > CommandProcessor::m_cpClockOrigin)
{
Expand Down Expand Up @@ -350,10 +352,12 @@ void RunGpuLoop()
// If we don't, s_swapRequested or s_efbAccessRequested won't be set to false
// leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down.
AsyncRequests::GetInstance()->PullEvents();
CommandProcessor::isPossibleWaitingSetDrawDone = false;
}

fifo.isGpuReadingData = false;
{
std::unique_lock<std::mutex> lock(s_gpu_flush_mutex);
fifo.isGpuReadingData = false;
s_gpu_flush_cond_var.notify_all();
}
}

if (EmuRunningState)
Expand Down Expand Up @@ -390,6 +394,17 @@ void RunGpuLoop()
AsyncRequests::GetInstance()->SetPassthrough(true);
}

void FlushGpu()
{
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread || g_use_deterministic_gpu_thread || !CommandProcessor::fifo.isGpuReadingData)
return;

std::unique_lock<std::mutex> lock(s_gpu_flush_mutex);
while (CommandProcessor::fifo.isGpuReadingData)
{
s_gpu_flush_cond_var.wait(lock);
}
}

bool AtBreakpoint()
{
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/Fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void SyncGPU(SyncGPUReason reason, bool may_move_read_ptr = true);
void PushFifoAuxBuffer(void* ptr, size_t size);
void* PopFifoAuxBuffer(size_t size);

void FlushGpu();
void RunGpu();
void RunGpuLoop();
void ExitGpuLoop();
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/VideoCommon/MainBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ void VideoBackendHardware::Video_GatherPipeBursted()
CommandProcessor::GatherPipeBursted();
}

bool VideoBackendHardware::Video_IsPossibleWaitingSetDrawDone()
void VideoBackendHardware::Video_Sync()
{
return CommandProcessor::isPossibleWaitingSetDrawDone;
FlushGpu();
}

void VideoBackendHardware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
Expand Down
1 change: 0 additions & 1 deletion Source/Core/VideoCommon/PixelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ void SetFinish_OnMainThread(u64 userdata, int cyclesLate)
Common::AtomicStore(*(volatile u32*)&g_bSignalFinishInterrupt, 1);
UpdateInterrupts();
CommandProcessor::interruptFinishWaiting = false;
CommandProcessor::isPossibleWaitingSetDrawDone = false;
}

// SetToken
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/VideoCommon/VideoBackendBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class VideoBackend

virtual void Video_GatherPipeBursted() = 0;

virtual bool Video_IsPossibleWaitingSetDrawDone() = 0;
virtual void Video_Sync() = 0;

// Registers MMIO handlers for the CommandProcessor registers.
virtual void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) = 0;
Expand Down Expand Up @@ -148,7 +148,7 @@ class VideoBackendHardware : public VideoBackend

void Video_GatherPipeBursted() override;

bool Video_IsPossibleWaitingSetDrawDone() override;
void Video_Sync() override;

void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override;

Expand Down

0 comments on commit e8ba439

Please sign in to comment.