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 13, 2015
1 parent 026dfb3 commit a24761d
Show file tree
Hide file tree
Showing 10 changed files with 24 additions and 39 deletions.
6 changes: 1 addition & 5 deletions Source/Core/Core/CoreTiming.cpp
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
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
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
17 changes: 2 additions & 15 deletions Source/Core/VideoCommon/CommandProcessor.cpp
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 @@ -319,7 +315,7 @@ void GatherPipeBursted()
(ProcessorInterface::Fifo_CPUBase == fifo.CPBase) &&
fifo.CPReadWriteDistance > 0)
{
ProcessFifoAllDistance();
FlushGpu();
}
}
RunGpu();
Expand Down Expand Up @@ -468,15 +464,6 @@ void SetCPStatusFromCPU()
}
}

void ProcessFifoAllDistance()
{
if (IsOnThread())
{
while (!interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
Common::YieldCPU();
}
}

void ProcessFifoEvents()
{
if (IsOnThread() && (interruptWaiting || interruptFinishWaiting || interruptTokenWaiting))
Expand Down Expand Up @@ -518,7 +505,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
2 changes: 0 additions & 2 deletions Source/Core/VideoCommon/CommandProcessor.h
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 Expand Up @@ -145,7 +144,6 @@ void UpdateInterruptsFromVideoBackend(u64 userdata);
void SetCpClearRegister();
void SetCpControlRegister();
void SetCpStatusRegister();
void ProcessFifoAllDistance();
void ProcessFifoEvents();

void Update();
Expand Down
21 changes: 15 additions & 6 deletions Source/Core/VideoCommon/Fifo.cpp
Expand Up @@ -61,6 +61,7 @@ static u8* s_video_buffer_pp_read_ptr;

static std::atomic<bool> s_gpu_is_running;
static Common::Event s_gpu_event;
static Common::Event s_gpu_flush_event;

void Fifo_DoState(PointerWrap &p)
{
Expand Down Expand Up @@ -131,9 +132,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 @@ -312,7 +312,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 @@ -347,10 +346,9 @@ 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;
s_gpu_flush_event.Set();
}

if (EmuRunningState)
Expand Down Expand Up @@ -383,6 +381,13 @@ void RunGpuLoop()
AsyncRequests::GetInstance()->SetPassthrough(true);
}

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

s_gpu_flush_event.Wait();
}

bool AtBreakpoint()
{
Expand All @@ -398,6 +403,10 @@ void RunGpu()
{
if (!s_gpu_is_running.load())
{
// mark the GPU as running
CommandProcessor::fifo.isGpuReadingData = true;
s_gpu_flush_event.Reset();

s_gpu_event.Set();
}
return;
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/Fifo.h
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
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
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
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 a24761d

Please sign in to comment.