summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2015-01-31 12:01:01 +0100
committerdegasus <wickmarkus@web.de>2015-02-22 08:41:15 +0100
commitad7264da7de4ca20472dfc2ef911314ff0e78de7 (patch)
treecdf4c362d4b3eaa271c590ccc69074b29187fe74 /Source/Core
parentbc248f8941ae5f24e651d5bf029740bc96c3df89 (diff)
VideoCommon: implement swap requests in the full async way
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoCommon/AsyncRequests.cpp20
-rw-r--r--Source/Core/VideoCommon/AsyncRequests.h11
-rw-r--r--Source/Core/VideoCommon/Fifo.cpp2
-rw-r--r--Source/Core/VideoCommon/MainBase.cpp55
-rw-r--r--Source/Core/VideoCommon/MainBase.h3
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp2
6 files changed, 42 insertions, 51 deletions
diff --git a/Source/Core/VideoCommon/AsyncRequests.cpp b/Source/Core/VideoCommon/AsyncRequests.cpp
index dce56c0d7b..9430d390fa 100644
--- a/Source/Core/VideoCommon/AsyncRequests.cpp
+++ b/Source/Core/VideoCommon/AsyncRequests.cpp
@@ -4,7 +4,7 @@
AsyncRequests AsyncRequests::s_singleton;
AsyncRequests::AsyncRequests()
-: m_enable(false)
+: m_enable(false), m_passthrough(true)
{
}
@@ -34,6 +34,13 @@ void AsyncRequests::PullEventsInternal()
void AsyncRequests::PushEvent(const AsyncRequests::Event& event, bool blocking)
{
std::unique_lock<std::mutex> lock(m_mutex);
+
+ if (m_passthrough)
+ {
+ HandleEvent(event);
+ return;
+ }
+
m_empty.store(false);
m_wake_me_up_again |= blocking;
@@ -65,6 +72,7 @@ void AsyncRequests::SetEnable(bool enable)
void AsyncRequests::HandleEvent(const AsyncRequests::Event& e)
{
+ EFBRectangle rc;
switch (e.type)
{
case Event::EFB_POKE_COLOR:
@@ -83,6 +91,16 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e)
*e.efb_peek.data = g_renderer->AccessEFB(PEEK_Z, e.efb_peek.x, e.efb_peek.y, 0);
break;
+ case Event::SWAP_EVENT:
+ Renderer::Swap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride, e.swap_event.fbHeight, rc);
+ break;
+
}
}
+void AsyncRequests::SetPassthrough(bool enable)
+{
+ std::unique_lock<std::mutex> lock(m_mutex);
+ m_passthrough = enable;
+}
+
diff --git a/Source/Core/VideoCommon/AsyncRequests.h b/Source/Core/VideoCommon/AsyncRequests.h
index d3cfece7eb..fe3d5c3234 100644
--- a/Source/Core/VideoCommon/AsyncRequests.h
+++ b/Source/Core/VideoCommon/AsyncRequests.h
@@ -22,6 +22,7 @@ public:
EFB_POKE_Z,
EFB_PEEK_COLOR,
EFB_PEEK_Z,
+ SWAP_EVENT,
} type;
u64 time;
@@ -40,6 +41,14 @@ public:
u16 y;
u32* data;
} efb_peek;
+
+ struct
+ {
+ u32 xfbAddr;
+ u32 fbWidth;
+ u32 fbStride;
+ u32 fbHeight;
+ } swap_event;
};
};
@@ -52,6 +61,7 @@ public:
}
void PushEvent(const Event& event, bool blocking = false);
void SetEnable(bool enable);
+ void SetPassthrough(bool enable);
static AsyncRequests* GetInstance() { return &s_singleton; }
@@ -68,4 +78,5 @@ private:
bool m_wake_me_up_again;
bool m_enable;
+ bool m_passthrough;
};
diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp
index b8f4002d4d..74470a9fcd 100644
--- a/Source/Core/VideoCommon/Fifo.cpp
+++ b/Source/Core/VideoCommon/Fifo.cpp
@@ -284,6 +284,7 @@ void RunGpuLoop()
bool yield_cpu = cpu_info.num_cores <= 2;
AsyncRequests::GetInstance()->SetEnable(true);
+ AsyncRequests::GetInstance()->SetPassthrough(false);
while (GpuRunningState)
{
@@ -383,6 +384,7 @@ void RunGpuLoop()
// wake up SyncGPU if we were interrupted
s_video_buffer_cond.notify_all();
AsyncRequests::GetInstance()->SetEnable(false);
+ AsyncRequests::GetInstance()->SetPassthrough(true);
}
diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp
index 47eab7d941..25741ea7d8 100644
--- a/Source/Core/VideoCommon/MainBase.cpp
+++ b/Source/Core/VideoCommon/MainBase.cpp
@@ -19,7 +19,6 @@
bool s_BackendInitialized = false;
-Common::Flag s_swapRequested;
static Common::Flag s_FifoShuttingDown;
static Common::Flag s_perfQueryRequested;
@@ -61,45 +60,11 @@ void VideoBackendHardware::Video_SetRendering(bool bEnabled)
Fifo_SetRendering(bEnabled);
}
-// Run from the graphics thread (from Fifo.cpp)
-static void VideoFifo_CheckSwapRequest()
-{
- if (g_ActiveConfig.bUseXFB)
- {
- if (s_swapRequested.IsSet())
- {
- EFBRectangle rc;
- Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbStride, s_beginFieldArgs.fbHeight, rc);
- s_swapRequested.Clear();
- }
- }
-}
-
-// Run from the graphics thread (from Fifo.cpp)
-void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
-{
- if (g_ActiveConfig.bUseXFB)
- {
- if (s_swapRequested.IsSet())
- {
- u32 aLower = xfbAddr;
- u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
- u32 bLower = s_beginFieldArgs.xfbAddr;
- u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbStride * s_beginFieldArgs.fbHeight;
-
- if (AddressRangesOverlap(aLower, aUpper, bLower, bUpper))
- VideoFifo_CheckSwapRequest();
- }
- }
-}
-
// Run from the CPU thread (from VideoInterface.cpp)
void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight)
{
if (s_BackendInitialized && g_ActiveConfig.bUseXFB)
{
- if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
- VideoFifo_CheckSwapRequest();
s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbStride = fbStride;
@@ -110,16 +75,19 @@ void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStri
// Run from the CPU thread (from VideoInterface.cpp)
void VideoBackendHardware::Video_EndField()
{
- if (s_BackendInitialized)
+ if (s_BackendInitialized && g_ActiveConfig.bUseXFB && g_renderer)
{
SyncGPU(SYNC_GPU_SWAP);
- // Wait until the GPU thread has swapped. Prevents FIFO overflows.
- while (g_ActiveConfig.bUseXFB && SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread && s_swapRequested.IsSet())
- {
- Common::YieldCPU();
- }
- s_swapRequested.Set();
+ AsyncRequests::Event e;
+ e.time = 0;
+ e.type = AsyncRequests::Event::SWAP_EVENT;
+
+ e.swap_event.xfbAddr = s_beginFieldArgs.xfbAddr;
+ e.swap_event.fbWidth = s_beginFieldArgs.fbWidth;
+ e.swap_event.fbStride = s_beginFieldArgs.fbStride;
+ e.swap_event.fbHeight = s_beginFieldArgs.fbHeight;
+ AsyncRequests::GetInstance()->PushEvent(e, false);
}
}
@@ -246,7 +214,6 @@ void VideoBackendHardware::InitializeShared()
{
VideoCommon_Init();
- s_swapRequested.Clear();
s_perfQueryRequested.Clear();
s_FifoShuttingDown.Clear();
memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs));
@@ -268,7 +235,6 @@ void VideoBackendHardware::DoState(PointerWrap& p)
VideoCommon_DoState(p);
p.DoMarker("VideoCommon");
- p.Do(s_swapRequested);
p.Do(s_beginFieldArgs);
p.DoMarker("VideoBackendHardware");
@@ -308,7 +274,6 @@ void VideoBackendHardware::RunLoop(bool enable)
void VideoFifo_CheckAsyncRequest()
{
- VideoFifo_CheckSwapRequest();
VideoFifo_CheckPerfQueryRequest();
VideoFifo_CheckBBoxRequest();
}
diff --git a/Source/Core/VideoCommon/MainBase.h b/Source/Core/VideoCommon/MainBase.h
index b8eebf37a0..c9d059cf7a 100644
--- a/Source/Core/VideoCommon/MainBase.h
+++ b/Source/Core/VideoCommon/MainBase.h
@@ -4,6 +4,3 @@
#include "Common/Flag.h"
extern bool s_BackendInitialized;
-extern Common::Flag s_swapRequested;
-
-void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index cb9be880e0..ccceb954dd 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -116,7 +116,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidt
if (!fbWidth || !fbHeight)
return;
- VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
XFBWrited = true;
if (g_ActiveConfig.bUseXFB)
@@ -126,7 +125,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidt
else
{
Swap(xfbAddr, fbWidth, fbWidth, fbHeight, sourceRc, Gamma);
- s_swapRequested.Clear();
}
}