From 32ce2be2bfc74f0b395800328c494b423480358d Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Sat, 23 Jan 2016 23:31:13 -0500
Subject: [PATCH] Fifo: Make g_use_deterministic_gpu_thread a TU-local variable

---
 Source/Core/VideoCommon/BPStructs.cpp        |  6 ++--
 Source/Core/VideoCommon/CommandProcessor.cpp |  4 +--
 Source/Core/VideoCommon/Fifo.cpp             | 29 ++++++++++++--------
 Source/Core/VideoCommon/Fifo.h               |  6 ++--
 Source/Core/VideoCommon/OpcodeDecoding.cpp   |  2 +-
 Source/Core/VideoCommon/PixelEngine.cpp      |  4 +--
 Source/Core/VideoCommon/XFStructs.cpp        |  2 +-
 7 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp
index ff125652a6..aaa73d991d 100644
--- a/Source/Core/VideoCommon/BPStructs.cpp
+++ b/Source/Core/VideoCommon/BPStructs.cpp
@@ -179,7 +179,7 @@ static void BPWritten(const BPCmd& bp)
 		switch (bp.newvalue & 0xFF)
 		{
 		case 0x02:
-			if (!Fifo::g_use_deterministic_gpu_thread)
+			if (!Fifo::UseDeterministicGPUThread())
 				PixelEngine::SetFinish(); // may generate interrupt
 			DEBUG_LOG(VIDEO, "GXSetDrawDone SetPEFinish (value: 0x%02X)", (bp.newvalue & 0xFFFF));
 			return;
@@ -190,12 +190,12 @@ static void BPWritten(const BPCmd& bp)
 		}
 		return;
 	case BPMEM_PE_TOKEN_ID: // Pixel Engine Token ID
-		if (!Fifo::g_use_deterministic_gpu_thread)
+		if (!Fifo::UseDeterministicGPUThread())
 			PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), false);
 		DEBUG_LOG(VIDEO, "SetPEToken 0x%04x", (bp.newvalue & 0xFFFF));
 		return;
 	case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
-		if (!Fifo::g_use_deterministic_gpu_thread)
+		if (!Fifo::UseDeterministicGPUThread())
 			PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), true);
 		DEBUG_LOG(VIDEO, "SetPEToken + INT 0x%04x", (bp.newvalue & 0xFFFF));
 		return;
diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp
index 747bec83fe..92bb3c715d 100644
--- a/Source/Core/VideoCommon/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/CommandProcessor.cpp
@@ -302,7 +302,7 @@ void GatherPipeBursted()
 	// if we aren't linked, we don't care about gather pipe data
 	if (!m_CPCtrlReg.GPLinkEnable)
 	{
-		if (IsOnThread() && !Fifo::g_use_deterministic_gpu_thread)
+		if (IsOnThread() && !Fifo::UseDeterministicGPUThread())
 		{
 			// In multibuffer mode is not allowed write in the same FIFO attached to the GPU.
 			// Fix Pokemon XD in DC mode.
@@ -368,7 +368,7 @@ void UpdateInterrupts(u64 userdata)
 
 void UpdateInterruptsFromVideoBackend(u64 userdata)
 {
-	if (!Fifo::g_use_deterministic_gpu_thread)
+	if (!Fifo::UseDeterministicGPUThread())
 		CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata);
 }
 
diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp
index 953484c114..9e383b84d4 100644
--- a/Source/Core/VideoCommon/Fifo.cpp
+++ b/Source/Core/VideoCommon/Fifo.cpp
@@ -44,7 +44,9 @@ static u8 s_fifo_aux_data[FIFO_SIZE];
 static u8* s_fifo_aux_write_ptr;
 static u8* s_fifo_aux_read_ptr;
 
-bool g_use_deterministic_gpu_thread;
+// This could be in SConfig, but it depends on multiple settings
+// and can change at runtime.
+static bool s_use_deterministic_gpu_thread;
 
 static u64 s_last_sync_gpu_tick;
 static int s_event_sync_gpu;
@@ -56,7 +58,7 @@ static std::atomic<u8*> s_video_buffer_write_ptr;
 static std::atomic<u8*> s_video_buffer_seen_ptr;
 static u8* s_video_buffer_pp_read_ptr;
 // The read_ptr is always owned by the GPU thread.  In normal mode, so is the
-// write_ptr, despite it being atomic.  In g_use_deterministic_gpu_thread mode,
+// write_ptr, despite it being atomic.  In deterministic GPU thread mode,
 // things get a bit more complicated:
 // - The seen_ptr is written by the GPU thread, and points to what it's already
 // processed as much of as possible - in the case of a partial command which
@@ -77,7 +79,7 @@ void DoState(PointerWrap &p)
 	p.DoPointer(write_ptr, s_video_buffer);
 	s_video_buffer_write_ptr = write_ptr;
 	p.DoPointer(s_video_buffer_read_ptr, s_video_buffer);
-	if (p.mode == PointerWrap::MODE_READ && g_use_deterministic_gpu_thread)
+	if (p.mode == PointerWrap::MODE_READ && s_use_deterministic_gpu_thread)
 	{
 		// We're good and paused, right?
 		s_video_buffer_seen_ptr = s_video_buffer_pp_read_ptr = s_video_buffer_read_ptr;
@@ -159,7 +161,7 @@ void EmulatorState(bool running)
 
 void SyncGPU(SyncGPUReason reason, bool may_move_read_ptr)
 {
-	if (g_use_deterministic_gpu_thread)
+	if (s_use_deterministic_gpu_thread)
 	{
 		s_gpu_mainloop.Wait();
 		if (!s_gpu_mainloop.IsRunning())
@@ -306,7 +308,7 @@ void RunGpuLoop()
 		if (!s_emu_running_state.load())
 			return;
 
-		if (g_use_deterministic_gpu_thread)
+		if (s_use_deterministic_gpu_thread)
 		{
 			AsyncRequests::GetInstance()->PullEvents();
 
@@ -392,7 +394,7 @@ void FlushGpu()
 {
 	const SConfig& param = SConfig::GetInstance();
 
-	if (!param.bCPUThread || g_use_deterministic_gpu_thread)
+	if (!param.bCPUThread || s_use_deterministic_gpu_thread)
 		return;
 
 	s_gpu_mainloop.Wait();
@@ -415,12 +417,12 @@ void RunGpu()
 	const SConfig& param = SConfig::GetInstance();
 
 	// execute GPU
-	if (!param.bCPUThread || g_use_deterministic_gpu_thread)
+	if (!param.bCPUThread || s_use_deterministic_gpu_thread)
 	{
 		bool reset_simd_state = false;
 		while (fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint() )
 		{
-			if (g_use_deterministic_gpu_thread)
+			if (s_use_deterministic_gpu_thread)
 			{
 				ReadDataFromFifoOnCPU(fifo.CPReadPointer);
 				s_gpu_mainloop.Wakeup();
@@ -490,9 +492,9 @@ void UpdateWantDeterminism(bool want)
 
 	gpu_thread = gpu_thread && param.bCPUThread;
 
-	if (g_use_deterministic_gpu_thread != gpu_thread)
+	if (s_use_deterministic_gpu_thread != gpu_thread)
 	{
-		g_use_deterministic_gpu_thread = gpu_thread;
+		s_use_deterministic_gpu_thread = gpu_thread;
 		if (gpu_thread)
 		{
 			// These haven't been updated in non-deterministic mode.
@@ -503,6 +505,11 @@ void UpdateWantDeterminism(bool want)
 	}
 }
 
+bool UseDeterministicGPUThread()
+{
+	return s_use_deterministic_gpu_thread;
+}
+
 /* This function checks the emulated CPU - GPU distance and may wake up the GPU,
  * or block the CPU if required. It should be called by the CPU thread regulary.
  * @ticks The gone emulated CPU time.
@@ -513,7 +520,7 @@ static int Update(int ticks)
 	const SConfig& param = SConfig::GetInstance();
 
 	// GPU is sleeping, so no need for synchronization
-	if (s_gpu_mainloop.IsDone() || g_use_deterministic_gpu_thread)
+	if (s_gpu_mainloop.IsDone() || s_use_deterministic_gpu_thread)
 	{
 		if (s_sync_ticks.load() < 0)
 		{
diff --git a/Source/Core/VideoCommon/Fifo.h b/Source/Core/VideoCommon/Fifo.h
index e5e5cd36ac..92cfc044af 100644
--- a/Source/Core/VideoCommon/Fifo.h
+++ b/Source/Core/VideoCommon/Fifo.h
@@ -13,9 +13,6 @@ class PointerWrap;
 namespace Fifo
 {
 
-// This could be in SConfig, but it depends on multiple settings
-// and can change at runtime.
-extern bool g_use_deterministic_gpu_thread;
 extern std::atomic<u8*> g_video_buffer_write_ptr_xthread;
 
 void Init();
@@ -24,6 +21,7 @@ void Prepare(); // Must be called from the CPU thread.
 void DoState(PointerWrap &f);
 void PauseAndLock(bool doLock, bool unpauseOnUnlock);
 void UpdateWantDeterminism(bool want);
+bool UseDeterministicGPUThread();
 
 // Used for diagnostics.
 enum SyncGPUReason
@@ -36,7 +34,7 @@ enum SyncGPUReason
 	SYNC_GPU_SWAP,
 	SYNC_GPU_AUX_SPACE,
 };
-// In g_use_deterministic_gpu_thread mode, waits for the GPU to be done with pending work.
+// In deterministic GPU thread mode this waits for the GPU to be done with pending work.
 void SyncGPU(SyncGPUReason reason, bool may_move_read_ptr = true);
 
 void PushFifoAuxBuffer(void* ptr, size_t size);
diff --git a/Source/Core/VideoCommon/OpcodeDecoding.cpp b/Source/Core/VideoCommon/OpcodeDecoding.cpp
index 1733a89ad9..32a3782aaf 100644
--- a/Source/Core/VideoCommon/OpcodeDecoding.cpp
+++ b/Source/Core/VideoCommon/OpcodeDecoding.cpp
@@ -39,7 +39,7 @@ static u32 InterpretDisplayList(u32 address, u32 size)
 {
 	u8* startAddress;
 
-	if (Fifo::g_use_deterministic_gpu_thread)
+	if (Fifo::UseDeterministicGPUThread())
 		startAddress = (u8*)Fifo::PopFifoAuxBuffer(size);
 	else
 		startAddress = Memory::GetPointer(address);
diff --git a/Source/Core/VideoCommon/PixelEngine.cpp b/Source/Core/VideoCommon/PixelEngine.cpp
index eec9a5730a..9b61ecee4c 100644
--- a/Source/Core/VideoCommon/PixelEngine.cpp
+++ b/Source/Core/VideoCommon/PixelEngine.cpp
@@ -296,7 +296,7 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge)
 
 	CommandProcessor::SetInterruptTokenWaiting(true);
 
-	if (!SConfig::GetInstance().bCPUThread || Fifo::g_use_deterministic_gpu_thread)
+	if (!SConfig::GetInstance().bCPUThread || Fifo::UseDeterministicGPUThread())
 		CoreTiming::ScheduleEvent(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16));
 	else
 		CoreTiming::ScheduleEvent_Threadsafe(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16));
@@ -308,7 +308,7 @@ void SetFinish()
 {
 	CommandProcessor::SetInterruptFinishWaiting(true);
 
-	if (!SConfig::GetInstance().bCPUThread || Fifo::g_use_deterministic_gpu_thread)
+	if (!SConfig::GetInstance().bCPUThread || Fifo::UseDeterministicGPUThread())
 		CoreTiming::ScheduleEvent(0, et_SetFinishOnMainThread, 0);
 	else
 		CoreTiming::ScheduleEvent_Threadsafe(0, et_SetFinishOnMainThread, 0);
diff --git a/Source/Core/VideoCommon/XFStructs.cpp b/Source/Core/VideoCommon/XFStructs.cpp
index 402f76c493..964dc15355 100644
--- a/Source/Core/VideoCommon/XFStructs.cpp
+++ b/Source/Core/VideoCommon/XFStructs.cpp
@@ -259,7 +259,7 @@ void LoadIndexedXF(u32 val, int refarray)
 
 	u32* currData = (u32*)(&xfmem) + address;
 	u32* newData;
-	if (Fifo::g_use_deterministic_gpu_thread)
+	if (Fifo::UseDeterministicGPUThread())
 	{
 		newData = (u32*)Fifo::PopFifoAuxBuffer(size * sizeof(u32));
 	}