mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-11 00:29:11 +01:00
Merge pull request #867 from comex/gpu-determinism-pr1
Some small preparatory changes to VideoCommon for GPU thread determinism mode.
This commit is contained in:
commit
75b9d6da48
@ -25,6 +25,7 @@
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Flag.h"
|
||||
|
||||
// ewww
|
||||
#if _LIBCPP_VERSION
|
||||
@ -165,6 +166,14 @@ public:
|
||||
Do(x[i]);
|
||||
}
|
||||
|
||||
void Do(Common::Flag& flag)
|
||||
{
|
||||
bool s = flag.IsSet();
|
||||
Do(s);
|
||||
if (mode == MODE_READ)
|
||||
flag.Set(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Do(T& x)
|
||||
{
|
||||
|
@ -160,11 +160,6 @@ bool VideoBackend::Initialize(void *window_handle)
|
||||
|
||||
void VideoBackend::Video_Prepare()
|
||||
{
|
||||
// Better be safe...
|
||||
s_efbAccessRequested = FALSE;
|
||||
s_FifoShuttingDown = FALSE;
|
||||
s_swapRequested = FALSE;
|
||||
|
||||
// internal interfaces
|
||||
g_renderer = new Renderer(m_window_handle);
|
||||
g_texture_cache = new TextureCache;
|
||||
@ -196,10 +191,6 @@ void VideoBackend::Shutdown()
|
||||
// TODO: should be in Video_Cleanup
|
||||
if (g_renderer)
|
||||
{
|
||||
s_efbAccessRequested = FALSE;
|
||||
s_FifoShuttingDown = FALSE;
|
||||
s_swapRequested = FALSE;
|
||||
|
||||
// VideoCommon
|
||||
Fifo_Shutdown();
|
||||
CommandProcessor::Shutdown();
|
||||
|
@ -189,10 +189,6 @@ void VideoBackend::Video_Prepare()
|
||||
|
||||
g_renderer = new Renderer;
|
||||
|
||||
s_efbAccessRequested = false;
|
||||
s_FifoShuttingDown = false;
|
||||
s_swapRequested = false;
|
||||
|
||||
CommandProcessor::Init();
|
||||
PixelEngine::Init();
|
||||
|
||||
@ -230,9 +226,6 @@ void VideoBackend::Video_Cleanup()
|
||||
{
|
||||
if (g_renderer)
|
||||
{
|
||||
s_efbAccessRequested = false;
|
||||
s_FifoShuttingDown = false;
|
||||
s_swapRequested = false;
|
||||
Fifo_Shutdown();
|
||||
|
||||
// The following calls are NOT Thread Safe
|
||||
|
@ -317,7 +317,7 @@ void STACKALIGN GatherPipeBursted()
|
||||
}
|
||||
|
||||
if (IsOnThread())
|
||||
SetCpStatus(true);
|
||||
SetCPStatusFromCPU();
|
||||
|
||||
// update the fifo pointer
|
||||
if (fifo.CPWritePointer >= fifo.CPEnd)
|
||||
@ -361,30 +361,17 @@ void UpdateInterruptsFromVideoBackend(u64 userdata)
|
||||
CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata);
|
||||
}
|
||||
|
||||
void SetCpStatus(bool isCPUThread)
|
||||
void SetCPStatusFromGPU()
|
||||
{
|
||||
// overflow & underflow check
|
||||
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
|
||||
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
|
||||
|
||||
// breakpoint
|
||||
if (!isCPUThread)
|
||||
if (fifo.bFF_BPEnable)
|
||||
{
|
||||
if (fifo.bFF_BPEnable)
|
||||
if (fifo.CPBreakpoint == fifo.CPReadPointer)
|
||||
{
|
||||
if (fifo.CPBreakpoint == fifo.CPReadPointer)
|
||||
if (!fifo.bFF_Breakpoint)
|
||||
{
|
||||
if (!fifo.bFF_Breakpoint)
|
||||
{
|
||||
INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer);
|
||||
fifo.bFF_Breakpoint = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fifo.bFF_Breakpoint)
|
||||
INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer);
|
||||
fifo.bFF_Breakpoint = false;
|
||||
INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer);
|
||||
fifo.bFF_Breakpoint = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -394,6 +381,20 @@ void SetCpStatus(bool isCPUThread)
|
||||
fifo.bFF_Breakpoint = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fifo.bFF_Breakpoint)
|
||||
INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer);
|
||||
fifo.bFF_Breakpoint = false;
|
||||
}
|
||||
SetCPStatusFromCPU();
|
||||
}
|
||||
|
||||
void SetCPStatusFromCPU()
|
||||
{
|
||||
// overflow & underflow check
|
||||
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
|
||||
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
|
||||
|
||||
bool bpInt = fifo.bFF_Breakpoint && fifo.bFF_BPInt;
|
||||
bool ovfInt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt;
|
||||
@ -408,15 +409,14 @@ void SetCpStatus(bool isCPUThread)
|
||||
{
|
||||
if (!interrupt || bpInt || undfInt || ovfInt)
|
||||
{
|
||||
if (!isCPUThread)
|
||||
if (Core::IsGPUThread())
|
||||
{
|
||||
// GPU thread:
|
||||
// Schedule the interrupt asynchronously
|
||||
interruptWaiting = true;
|
||||
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
// CPU thread:
|
||||
interruptSet = interrupt;
|
||||
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
|
||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt);
|
||||
|
@ -135,7 +135,8 @@ void DoState(PointerWrap &p);
|
||||
|
||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||
|
||||
void SetCpStatus(bool isCPUThread = false);
|
||||
void SetCPStatusFromGPU();
|
||||
void SetCPStatusFromCPU();
|
||||
void GatherPipeBursted();
|
||||
void UpdateInterrupts(u64 userdata);
|
||||
void UpdateInterruptsFromVideoBackend(u64 userdata);
|
||||
|
@ -148,7 +148,7 @@ void RunGpuLoop()
|
||||
|
||||
VideoFifo_CheckAsyncRequest();
|
||||
|
||||
CommandProcessor::SetCpStatus();
|
||||
CommandProcessor::SetCPStatusFromGPU();
|
||||
|
||||
Common::AtomicStore(CommandProcessor::VITicks, CommandProcessor::m_cpClockOrigin);
|
||||
|
||||
@ -184,7 +184,7 @@ void RunGpuLoop()
|
||||
Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer);
|
||||
}
|
||||
|
||||
CommandProcessor::SetCpStatus();
|
||||
CommandProcessor::SetCPStatusFromGPU();
|
||||
|
||||
// This call is pretty important in DualCore mode and must be called in the FIFO Loop.
|
||||
// If we don't, s_swapRequested or s_efbAccessRequested won't be set to false
|
||||
@ -247,5 +247,5 @@ void RunGpu()
|
||||
|
||||
fifo.CPReadWriteDistance -= 32;
|
||||
}
|
||||
CommandProcessor::SetCpStatus();
|
||||
CommandProcessor::SetCPStatusFromGPU();
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
#include "Common/Atomic.h"
|
||||
#include "Common/Event.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include "VideoCommon/BPStructs.h"
|
||||
@ -18,13 +17,13 @@
|
||||
|
||||
bool s_BackendInitialized = false;
|
||||
|
||||
volatile u32 s_swapRequested = false;
|
||||
u32 s_efbAccessRequested = false;
|
||||
volatile u32 s_FifoShuttingDown = false;
|
||||
Common::Flag s_swapRequested;
|
||||
static Common::Flag s_FifoShuttingDown;
|
||||
static Common::Flag s_efbAccessRequested;
|
||||
static Common::Event s_efbAccessReadyEvent;
|
||||
|
||||
static std::condition_variable s_perf_query_cond;
|
||||
static std::mutex s_perf_query_lock;
|
||||
static volatile bool s_perf_query_requested;
|
||||
static Common::Flag s_perfQueryRequested;
|
||||
static Common::Event s_perfQueryReadyEvent;
|
||||
|
||||
static volatile struct
|
||||
{
|
||||
@ -57,7 +56,9 @@ void VideoBackendHardware::Video_EnterLoop()
|
||||
void VideoBackendHardware::Video_ExitLoop()
|
||||
{
|
||||
ExitGpuLoop();
|
||||
s_FifoShuttingDown = true;
|
||||
s_FifoShuttingDown.Set();
|
||||
s_efbAccessReadyEvent.Set();
|
||||
s_perfQueryReadyEvent.Set();
|
||||
}
|
||||
|
||||
void VideoBackendHardware::Video_SetRendering(bool bEnabled)
|
||||
@ -70,11 +71,11 @@ static void VideoFifo_CheckSwapRequest()
|
||||
{
|
||||
if (g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
if (Common::AtomicLoadAcquire(s_swapRequested))
|
||||
if (s_swapRequested.IsSet())
|
||||
{
|
||||
EFBRectangle rc;
|
||||
Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc);
|
||||
Common::AtomicStoreRelease(s_swapRequested, false);
|
||||
s_swapRequested.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,7 +85,7 @@ void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
|
||||
{
|
||||
if (g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
if (Common::AtomicLoadAcquire(s_swapRequested))
|
||||
if (s_swapRequested.IsSet())
|
||||
{
|
||||
u32 aLower = xfbAddr;
|
||||
u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
||||
@ -115,7 +116,7 @@ void VideoBackendHardware::Video_EndField()
|
||||
{
|
||||
if (s_BackendInitialized)
|
||||
{
|
||||
Common::AtomicStoreRelease(s_swapRequested, true);
|
||||
s_swapRequested.Set();
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,11 +139,11 @@ bool VideoBackendHardware::Video_Screenshot(const std::string& filename)
|
||||
|
||||
void VideoFifo_CheckEFBAccess()
|
||||
{
|
||||
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
||||
if (s_efbAccessRequested.IsSet())
|
||||
{
|
||||
s_AccessEFBResult = g_renderer->AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
|
||||
|
||||
Common::AtomicStoreRelease(s_efbAccessRequested, false);
|
||||
s_efbAccessRequested.Clear();
|
||||
s_efbAccessReadyEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,13 +156,15 @@ u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32
|
||||
s_accessEFBArgs.y = y;
|
||||
s_accessEFBArgs.Data = InputData;
|
||||
|
||||
Common::AtomicStoreRelease(s_efbAccessRequested, true);
|
||||
s_efbAccessRequested.Set();
|
||||
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
||||
{
|
||||
while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown)
|
||||
//Common::SleepCurrentThread(1);
|
||||
Common::YieldCPU();
|
||||
s_efbAccessReadyEvent.Reset();
|
||||
if (s_FifoShuttingDown.IsSet())
|
||||
return 0;
|
||||
s_efbAccessRequested.Set();
|
||||
s_efbAccessReadyEvent.Wait();
|
||||
}
|
||||
else
|
||||
VideoFifo_CheckEFBAccess();
|
||||
@ -172,23 +175,13 @@ u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool QueryResultIsReady()
|
||||
{
|
||||
return !s_perf_query_requested || s_FifoShuttingDown;
|
||||
}
|
||||
|
||||
static void VideoFifo_CheckPerfQueryRequest()
|
||||
{
|
||||
if (s_perf_query_requested)
|
||||
if (s_perfQueryRequested.IsSet())
|
||||
{
|
||||
g_perf_query->FlushResults();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(s_perf_query_lock);
|
||||
s_perf_query_requested = false;
|
||||
}
|
||||
|
||||
s_perf_query_cond.notify_one();
|
||||
s_perfQueryRequested.Clear();
|
||||
s_perfQueryReadyEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,9 +197,11 @@ u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type)
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
||||
{
|
||||
s_perf_query_requested = true;
|
||||
std::unique_lock<std::mutex> lk(s_perf_query_lock);
|
||||
s_perf_query_cond.wait(lk, QueryResultIsReady);
|
||||
s_perfQueryReadyEvent.Reset();
|
||||
if (s_FifoShuttingDown.IsSet())
|
||||
return 0;
|
||||
s_perfQueryRequested.Set();
|
||||
s_perfQueryReadyEvent.Wait();
|
||||
}
|
||||
else
|
||||
g_perf_query->FlushResults();
|
||||
@ -219,10 +214,10 @@ void VideoBackendHardware::InitializeShared()
|
||||
{
|
||||
VideoCommon_Init();
|
||||
|
||||
s_swapRequested = 0;
|
||||
s_efbAccessRequested = 0;
|
||||
s_perf_query_requested = false;
|
||||
s_FifoShuttingDown = 0;
|
||||
s_swapRequested.Clear();
|
||||
s_efbAccessRequested.Clear();
|
||||
s_perfQueryRequested.Clear();
|
||||
s_FifoShuttingDown.Clear();
|
||||
memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs));
|
||||
memset(&s_accessEFBArgs, 0, sizeof(s_accessEFBArgs));
|
||||
s_AccessEFBResult = 0;
|
||||
|
@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Flag.h"
|
||||
|
||||
extern bool s_BackendInitialized;
|
||||
extern u32 s_efbAccessRequested;
|
||||
extern volatile u32 s_FifoShuttingDown;
|
||||
extern volatile u32 s_swapRequested;
|
||||
extern Common::Flag s_swapRequested;
|
||||
|
||||
void VideoFifo_CheckEFBAccess();
|
||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
||||
|
@ -469,12 +469,13 @@ void OpcodeDecoder_Shutdown()
|
||||
u32 OpcodeDecoder_Run(bool skipped_frame)
|
||||
{
|
||||
u32 totalCycles = 0;
|
||||
u32 cycles = FifoCommandRunnable();
|
||||
while (cycles > 0)
|
||||
while (true)
|
||||
{
|
||||
u32 cycles = FifoCommandRunnable();
|
||||
if (cycles == 0)
|
||||
break;
|
||||
skipped_frame ? DecodeSemiNop() : Decode();
|
||||
totalCycles += cycles;
|
||||
cycles = FifoCommandRunnable();
|
||||
}
|
||||
return totalCycles;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidt
|
||||
else
|
||||
{
|
||||
Swap(xfbAddr, fbWidth, fbHeight,sourceRc,Gamma);
|
||||
Common::AtomicStoreRelease(s_swapRequested, false);
|
||||
s_swapRequested.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user