Unify three types of non-FIFO requests to the GPU thread around Common::Event and Common::Flag.

The only possible functionality change is that s_efbAccessRequested and
s_swapRequested are no longer reset at init and shutdown of the OGL
backend (only; this is the only interaction any files other than
MainBase.cpp have with them).  I am fairly certain this was entirely
vestigial.

Possible performance implications: efbAccessReady now uses an Event
rather than spinning, which might be slightly slower, but considering
the slow loop the flags are being checked in from the GPU thread, I
doubt it's noticeable.

Also, this uses sequentially consistent rather than release/acquire
memory order, which might be slightly slower, especially on ARM...
something to improve in Event/Flag, really.
This commit is contained in:
comex 2014-08-24 19:13:46 -04:00
parent de7294ecc1
commit e31d6feaa2
5 changed files with 38 additions and 60 deletions

View File

@ -160,11 +160,6 @@ bool VideoBackend::Initialize(void *window_handle)
void VideoBackend::Video_Prepare() void VideoBackend::Video_Prepare()
{ {
// Better be safe...
s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
// internal interfaces // internal interfaces
g_renderer = new Renderer(m_window_handle); g_renderer = new Renderer(m_window_handle);
g_texture_cache = new TextureCache; g_texture_cache = new TextureCache;
@ -196,10 +191,6 @@ void VideoBackend::Shutdown()
// TODO: should be in Video_Cleanup // TODO: should be in Video_Cleanup
if (g_renderer) if (g_renderer)
{ {
s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
// VideoCommon // VideoCommon
Fifo_Shutdown(); Fifo_Shutdown();
CommandProcessor::Shutdown(); CommandProcessor::Shutdown();

View File

@ -189,10 +189,6 @@ void VideoBackend::Video_Prepare()
g_renderer = new Renderer; g_renderer = new Renderer;
s_efbAccessRequested = false;
s_FifoShuttingDown = false;
s_swapRequested = false;
CommandProcessor::Init(); CommandProcessor::Init();
PixelEngine::Init(); PixelEngine::Init();
@ -230,9 +226,6 @@ void VideoBackend::Video_Cleanup()
{ {
if (g_renderer) if (g_renderer)
{ {
s_efbAccessRequested = false;
s_FifoShuttingDown = false;
s_swapRequested = false;
Fifo_Shutdown(); Fifo_Shutdown();
// The following calls are NOT Thread Safe // The following calls are NOT Thread Safe

View File

@ -1,5 +1,4 @@
#include "Common/Event.h"
#include "Common/Atomic.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "VideoCommon/BPStructs.h" #include "VideoCommon/BPStructs.h"
@ -18,13 +17,13 @@
bool s_BackendInitialized = false; bool s_BackendInitialized = false;
volatile u32 s_swapRequested = false; Common::Flag s_swapRequested;
u32 s_efbAccessRequested = false; static Common::Flag s_FifoShuttingDown;
volatile u32 s_FifoShuttingDown = false; static Common::Flag s_efbAccessRequested;
static Common::Event s_efbAccessReadyEvent;
static std::condition_variable s_perf_query_cond; static Common::Flag s_perfQueryRequested;
static std::mutex s_perf_query_lock; static Common::Event s_perfQueryReadyEvent;
static volatile bool s_perf_query_requested;
static volatile struct static volatile struct
{ {
@ -57,7 +56,9 @@ void VideoBackendHardware::Video_EnterLoop()
void VideoBackendHardware::Video_ExitLoop() void VideoBackendHardware::Video_ExitLoop()
{ {
ExitGpuLoop(); ExitGpuLoop();
s_FifoShuttingDown = true; s_FifoShuttingDown.Set();
s_efbAccessReadyEvent.Set();
s_perfQueryReadyEvent.Set();
} }
void VideoBackendHardware::Video_SetRendering(bool bEnabled) void VideoBackendHardware::Video_SetRendering(bool bEnabled)
@ -70,11 +71,11 @@ static void VideoFifo_CheckSwapRequest()
{ {
if (g_ActiveConfig.bUseXFB) if (g_ActiveConfig.bUseXFB)
{ {
if (Common::AtomicLoadAcquire(s_swapRequested)) if (s_swapRequested.IsSet())
{ {
EFBRectangle rc; EFBRectangle rc;
Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,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 (g_ActiveConfig.bUseXFB)
{ {
if (Common::AtomicLoadAcquire(s_swapRequested)) if (s_swapRequested.IsSet())
{ {
u32 aLower = xfbAddr; u32 aLower = xfbAddr;
u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight; u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
@ -115,7 +116,7 @@ void VideoBackendHardware::Video_EndField()
{ {
if (s_BackendInitialized) 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() 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); s_AccessEFBResult = g_renderer->AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
s_efbAccessRequested.Clear();
Common::AtomicStoreRelease(s_efbAccessRequested, false); s_efbAccessReadyEvent.Set();
} }
} }
@ -155,13 +156,15 @@ u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32
s_accessEFBArgs.y = y; s_accessEFBArgs.y = y;
s_accessEFBArgs.Data = InputData; s_accessEFBArgs.Data = InputData;
Common::AtomicStoreRelease(s_efbAccessRequested, true); s_efbAccessRequested.Set();
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
{ {
while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown) s_efbAccessReadyEvent.Reset();
//Common::SleepCurrentThread(1); if (s_FifoShuttingDown.IsSet())
Common::YieldCPU(); return 0;
s_efbAccessRequested.Set();
s_efbAccessReadyEvent.Wait();
} }
else else
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
@ -172,23 +175,13 @@ u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32
return 0; return 0;
} }
static bool QueryResultIsReady()
{
return !s_perf_query_requested || s_FifoShuttingDown;
}
static void VideoFifo_CheckPerfQueryRequest() static void VideoFifo_CheckPerfQueryRequest()
{ {
if (s_perf_query_requested) if (s_perfQueryRequested.IsSet())
{ {
g_perf_query->FlushResults(); g_perf_query->FlushResults();
s_perfQueryRequested.Clear();
{ s_perfQueryReadyEvent.Set();
std::lock_guard<std::mutex> lk(s_perf_query_lock);
s_perf_query_requested = false;
}
s_perf_query_cond.notify_one();
} }
} }
@ -204,9 +197,11 @@ u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type)
{ {
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
{ {
s_perf_query_requested = true; s_perfQueryReadyEvent.Reset();
std::unique_lock<std::mutex> lk(s_perf_query_lock); if (s_FifoShuttingDown.IsSet())
s_perf_query_cond.wait(lk, QueryResultIsReady); return 0;
s_perfQueryRequested.Set();
s_perfQueryReadyEvent.Wait();
} }
else else
g_perf_query->FlushResults(); g_perf_query->FlushResults();
@ -219,10 +214,10 @@ void VideoBackendHardware::InitializeShared()
{ {
VideoCommon_Init(); VideoCommon_Init();
s_swapRequested = 0; s_swapRequested.Clear();
s_efbAccessRequested = 0; s_efbAccessRequested.Clear();
s_perf_query_requested = false; s_perfQueryRequested.Clear();
s_FifoShuttingDown = 0; s_FifoShuttingDown.Clear();
memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs)); memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs));
memset(&s_accessEFBArgs, 0, sizeof(s_accessEFBArgs)); memset(&s_accessEFBArgs, 0, sizeof(s_accessEFBArgs));
s_AccessEFBResult = 0; s_AccessEFBResult = 0;

View File

@ -1,11 +1,10 @@
#pragma once #pragma once
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Flag.h"
extern bool s_BackendInitialized; extern bool s_BackendInitialized;
extern u32 s_efbAccessRequested; extern Common::Flag s_swapRequested;
extern volatile u32 s_FifoShuttingDown;
extern volatile u32 s_swapRequested;
void VideoFifo_CheckEFBAccess(); void VideoFifo_CheckEFBAccess();
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);

View File

@ -126,7 +126,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidt
else else
{ {
Swap(xfbAddr, fbWidth, fbHeight,sourceRc,Gamma); Swap(xfbAddr, fbWidth, fbHeight,sourceRc,Gamma);
Common::AtomicStoreRelease(s_swapRequested, false); s_swapRequested.Clear();
} }
} }