Fifo: Make g_use_deterministic_gpu_thread a TU-local variable
This commit is contained in:
parent
5ebd1e215b
commit
32ce2be2bf
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue