From ad7264da7de4ca20472dfc2ef911314ff0e78de7 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 31 Jan 2015 12:01:01 +0100 Subject: [PATCH] VideoCommon: implement swap requests in the full async way --- Source/Core/VideoCommon/AsyncRequests.cpp | 20 ++++++++- Source/Core/VideoCommon/AsyncRequests.h | 11 +++++ Source/Core/VideoCommon/Fifo.cpp | 2 + Source/Core/VideoCommon/MainBase.cpp | 55 +++++------------------ Source/Core/VideoCommon/MainBase.h | 3 -- Source/Core/VideoCommon/RenderBase.cpp | 2 - 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 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 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(); } }