Skip to content

Commit

Permalink
Merge pull request #867 from comex/gpu-determinism-pr1
Browse files Browse the repository at this point in the history
Some small preparatory changes to VideoCommon for GPU thread determinism mode.
  • Loading branch information
comex committed Aug 27, 2014
2 parents f52888d + e31d6fe commit 75b9d6d
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 90 deletions.
9 changes: 9 additions & 0 deletions Source/Core/Common/ChunkFile.h
Expand Up @@ -25,6 +25,7 @@

#include "Common/Common.h"
#include "Common/FileUtil.h"
#include "Common/Flag.h"

// ewww
#if _LIBCPP_VERSION
Expand Down Expand Up @@ -165,6 +166,14 @@ class PointerWrap
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)
{
Expand Down
9 changes: 0 additions & 9 deletions Source/Core/VideoBackends/D3D/main.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
7 changes: 0 additions & 7 deletions Source/Core/VideoBackends/OGL/main.cpp
Expand Up @@ -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();

Expand Down Expand Up @@ -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
Expand Down
46 changes: 23 additions & 23 deletions Source/Core/VideoCommon/CommandProcessor.cpp
Expand Up @@ -317,7 +317,7 @@ void STACKALIGN GatherPipeBursted()
}

if (IsOnThread())
SetCpStatus(true);
SetCPStatusFromCPU();

// update the fifo pointer
if (fifo.CPWritePointer >= fifo.CPEnd)
Expand Down Expand Up @@ -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)
{
INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer);
fifo.bFF_Breakpoint = true;
}
}
else
if (!fifo.bFF_Breakpoint)
{
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
Expand All @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/CommandProcessor.h
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions Source/Core/VideoCommon/Fifo.cpp
Expand Up @@ -148,7 +148,7 @@ void RunGpuLoop()

VideoFifo_CheckAsyncRequest();

CommandProcessor::SetCpStatus();
CommandProcessor::SetCPStatusFromGPU();

Common::AtomicStore(CommandProcessor::VITicks, CommandProcessor::m_cpClockOrigin);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -247,5 +247,5 @@ void RunGpu()

fifo.CPReadWriteDistance -= 32;
}
CommandProcessor::SetCpStatus();
CommandProcessor::SetCPStatusFromGPU();
}
75 changes: 35 additions & 40 deletions Source/Core/VideoCommon/MainBase.cpp
@@ -1,5 +1,4 @@

#include "Common/Atomic.h"
#include "Common/Event.h"
#include "Core/ConfigManager.h"

#include "VideoCommon/BPStructs.h"
Expand All @@ -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
{
Expand Down Expand Up @@ -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)
Expand All @@ -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();
}
}
}
Expand All @@ -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;
Expand Down Expand Up @@ -115,7 +116,7 @@ void VideoBackendHardware::Video_EndField()
{
if (s_BackendInitialized)
{
Common::AtomicStoreRelease(s_swapRequested, true);
s_swapRequested.Set();
}
}

Expand All @@ -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();
}
}

Expand All @@ -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();
Expand All @@ -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();
}
}

Expand All @@ -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();
Expand All @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions Source/Core/VideoCommon/MainBase.h
@@ -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);
7 changes: 4 additions & 3 deletions Source/Core/VideoCommon/OpcodeDecoding.cpp
Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/RenderBase.cpp
Expand Up @@ -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();
}
}

Expand Down

0 comments on commit 75b9d6d

Please sign in to comment.