From bc248f8941ae5f24e651d5bf029740bc96c3df89 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 31 Jan 2015 11:38:23 +0100 Subject: [PATCH 1/4] VideoCommon: use a new async event system for efb access --- Source/Core/VideoCommon/AsyncRequests.cpp | 88 +++++++++++++++++++ Source/Core/VideoCommon/AsyncRequests.h | 71 +++++++++++++++ Source/Core/VideoCommon/CMakeLists.txt | 3 +- Source/Core/VideoCommon/Fifo.cpp | 6 ++ Source/Core/VideoCommon/MainBase.cpp | 79 ++++++----------- Source/Core/VideoCommon/MainBase.h | 1 - Source/Core/VideoCommon/RenderBase.cpp | 1 - Source/Core/VideoCommon/VertexManagerBase.cpp | 2 - Source/Core/VideoCommon/VideoCommon.vcxproj | 2 + .../VideoCommon/VideoCommon.vcxproj.filters | 6 ++ 10 files changed, 201 insertions(+), 58 deletions(-) create mode 100644 Source/Core/VideoCommon/AsyncRequests.cpp create mode 100644 Source/Core/VideoCommon/AsyncRequests.h diff --git a/Source/Core/VideoCommon/AsyncRequests.cpp b/Source/Core/VideoCommon/AsyncRequests.cpp new file mode 100644 index 0000000000..dce56c0d7b --- /dev/null +++ b/Source/Core/VideoCommon/AsyncRequests.cpp @@ -0,0 +1,88 @@ +#include "VideoCommon/AsyncRequests.h" +#include "VideoCommon/RenderBase.h" + +AsyncRequests AsyncRequests::s_singleton; + +AsyncRequests::AsyncRequests() +: m_enable(false) +{ +} + +void AsyncRequests::PullEventsInternal() +{ + std::unique_lock lock(m_mutex); + m_empty.store(true); + + while (!m_queue.empty()) + { + const Event& e = m_queue.front(); + + lock.unlock(); + HandleEvent(e); + lock.lock(); + + m_queue.pop(); + } + + if (m_wake_me_up_again) + { + m_wake_me_up_again = false; + m_cond.notify_all(); + } +} + +void AsyncRequests::PushEvent(const AsyncRequests::Event& event, bool blocking) +{ + std::unique_lock lock(m_mutex); + m_empty.store(false); + m_wake_me_up_again |= blocking; + + if (!m_enable) + return; + + m_queue.push(event); + + if (blocking) + { + m_cond.wait(lock, [this]{return m_queue.empty();}); + } +} + +void AsyncRequests::SetEnable(bool enable) +{ + std::unique_lock lock(m_mutex); + m_enable = enable; + + if (!enable) + { + // flush the queue on disabling + while (!m_queue.empty()) + m_queue.pop(); + if (m_wake_me_up_again) + m_cond.notify_all(); + } +} + +void AsyncRequests::HandleEvent(const AsyncRequests::Event& e) +{ + switch (e.type) + { + case Event::EFB_POKE_COLOR: + g_renderer->AccessEFB(POKE_COLOR, e.efb_poke.x, e.efb_poke.y, e.efb_poke.data); + break; + + case Event::EFB_POKE_Z: + g_renderer->AccessEFB(POKE_Z, e.efb_poke.x, e.efb_poke.y, e.efb_poke.data); + break; + + case Event::EFB_PEEK_COLOR: + *e.efb_peek.data = g_renderer->AccessEFB(PEEK_COLOR, e.efb_peek.x, e.efb_peek.y, 0); + break; + + case Event::EFB_PEEK_Z: + *e.efb_peek.data = g_renderer->AccessEFB(PEEK_Z, e.efb_peek.x, e.efb_peek.y, 0); + break; + + } +} + diff --git a/Source/Core/VideoCommon/AsyncRequests.h b/Source/Core/VideoCommon/AsyncRequests.h new file mode 100644 index 0000000000..d3cfece7eb --- /dev/null +++ b/Source/Core/VideoCommon/AsyncRequests.h @@ -0,0 +1,71 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include + +#include "Common/CommonTypes.h" + +class AsyncRequests +{ +public: + struct Event + { + enum Type + { + EFB_POKE_COLOR, + EFB_POKE_Z, + EFB_PEEK_COLOR, + EFB_PEEK_Z, + } type; + u64 time; + + union + { + struct + { + u16 x; + u16 y; + u32 data; + } efb_poke; + + struct + { + u16 x; + u16 y; + u32* data; + } efb_peek; + }; + }; + + AsyncRequests(); + + void PullEvents() + { + if (!m_empty.load()) + PullEventsInternal(); + } + void PushEvent(const Event& event, bool blocking = false); + void SetEnable(bool enable); + + static AsyncRequests* GetInstance() { return &s_singleton; } + +private: + void PullEventsInternal(); + void HandleEvent(const Event& e); + + static AsyncRequests s_singleton; + + std::atomic m_empty; + std::queue m_queue; + std::mutex m_mutex; + std::condition_variable m_cond; + + bool m_wake_me_up_again; + bool m_enable; +}; diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 4e6dd8a6b6..f3ef98a741 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -1,4 +1,5 @@ -set(SRCS BoundingBox.cpp +set(SRCS AsyncRequests.cpp + BoundingBox.cpp BPFunctions.cpp BPMemory.cpp BPStructs.cpp diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp index 9da3583a9d..b8f4002d4d 100644 --- a/Source/Core/VideoCommon/Fifo.cpp +++ b/Source/Core/VideoCommon/Fifo.cpp @@ -15,6 +15,7 @@ #include "Core/NetPlayProto.h" #include "Core/HW/Memmap.h" +#include "VideoCommon/AsyncRequests.h" #include "VideoCommon/CommandProcessor.h" #include "VideoCommon/CPMemory.h" #include "VideoCommon/DataReader.h" @@ -282,11 +283,14 @@ void RunGpuLoop() // This allows a system that we are maxing out in dual core mode to do other things bool yield_cpu = cpu_info.num_cores <= 2; + AsyncRequests::GetInstance()->SetEnable(true); + while (GpuRunningState) { g_video_backend->PeekMessages(); VideoFifo_CheckAsyncRequest(); + AsyncRequests::GetInstance()->PullEvents(); if (g_use_deterministic_gpu_thread) { // All the fifo/CP stuff is on the CPU. We just need to run the opcode decoder. @@ -349,6 +353,7 @@ void RunGpuLoop() // If we don't, s_swapRequested or s_efbAccessRequested won't be set to false // leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down. VideoFifo_CheckAsyncRequest(); + AsyncRequests::GetInstance()->PullEvents(); CommandProcessor::isPossibleWaitingSetDrawDone = false; } @@ -377,6 +382,7 @@ void RunGpuLoop() } // wake up SyncGPU if we were interrupted s_video_buffer_cond.notify_all(); + AsyncRequests::GetInstance()->SetEnable(false); } diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp index b5c6cdebf9..47eab7d941 100644 --- a/Source/Core/VideoCommon/MainBase.cpp +++ b/Source/Core/VideoCommon/MainBase.cpp @@ -1,6 +1,7 @@ #include "Common/Event.h" #include "Core/ConfigManager.h" +#include "VideoCommon/AsyncRequests.h" #include "VideoCommon/BoundingBox.h" #include "VideoCommon/BPStructs.h" #include "VideoCommon/CommandProcessor.h" @@ -20,8 +21,6 @@ bool s_BackendInitialized = false; Common::Flag s_swapRequested; static Common::Flag s_FifoShuttingDown; -static Common::Flag s_efbAccessRequested; -static Common::Event s_efbAccessReadyEvent; static Common::Flag s_perfQueryRequested; static Common::Event s_perfQueryReadyEvent; @@ -39,16 +38,6 @@ static volatile struct u32 fbHeight; } s_beginFieldArgs; -static struct -{ - EFBAccessType type; - u32 x; - u32 y; - u32 Data; -} s_accessEFBArgs; - -static u32 s_AccessEFBResult = 0; - void VideoBackendHardware::EmuStateChange(EMUSTATE_CHANGE newState) { EmulatorState((newState == EMUSTATE_CHANGE_PLAY) ? true : false); @@ -64,7 +53,6 @@ void VideoBackendHardware::Video_ExitLoop() { ExitGpuLoop(); s_FifoShuttingDown.Set(); - s_efbAccessReadyEvent.Set(); s_perfQueryReadyEvent.Set(); } @@ -152,44 +140,36 @@ bool VideoBackendHardware::Video_Screenshot(const std::string& filename) return true; } -void VideoFifo_CheckEFBAccess() -{ - if (s_efbAccessRequested.IsSet()) - { - s_AccessEFBResult = g_renderer->AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data); - s_efbAccessRequested.Clear(); - s_efbAccessReadyEvent.Set(); - } -} - u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) { - if (s_BackendInitialized && g_ActiveConfig.bEFBAccessEnable) + if (!g_ActiveConfig.bEFBAccessEnable) { - SyncGPU(SYNC_GPU_EFB_POKE); - - s_accessEFBArgs.type = type; - s_accessEFBArgs.x = x; - s_accessEFBArgs.y = y; - s_accessEFBArgs.Data = InputData; - - s_efbAccessRequested.Set(); - - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) - { - s_efbAccessReadyEvent.Reset(); - if (s_FifoShuttingDown.IsSet()) - return 0; - s_efbAccessRequested.Set(); - s_efbAccessReadyEvent.Wait(); - } - else - VideoFifo_CheckEFBAccess(); - - return s_AccessEFBResult; + return 0; } - return 0; + if (type == POKE_COLOR || type == POKE_Z) + { + AsyncRequests::Event e; + e.type = type == POKE_COLOR ? AsyncRequests::Event::EFB_POKE_COLOR : AsyncRequests::Event::EFB_POKE_Z; + e.time = 0; + e.efb_poke.data = InputData; + e.efb_poke.x = x; + e.efb_poke.y = y; + AsyncRequests::GetInstance()->PushEvent(e, 0); + return 0; + } + else + { + AsyncRequests::Event e; + u32 result; + e.type = type == PEEK_COLOR ? AsyncRequests::Event::EFB_PEEK_COLOR : AsyncRequests::Event::EFB_PEEK_Z; + e.time = 0; + e.efb_peek.x = x; + e.efb_peek.y = y; + e.efb_peek.data = &result; + AsyncRequests::GetInstance()->PushEvent(e, 1); + return result; + } } static void VideoFifo_CheckPerfQueryRequest() @@ -267,12 +247,9 @@ void VideoBackendHardware::InitializeShared() VideoCommon_Init(); 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; m_invalid = false; } @@ -292,10 +269,7 @@ void VideoBackendHardware::DoState(PointerWrap& p) p.DoMarker("VideoCommon"); p.Do(s_swapRequested); - p.Do(s_efbAccessRequested); p.Do(s_beginFieldArgs); - p.Do(s_accessEFBArgs); - p.Do(s_AccessEFBResult); p.DoMarker("VideoBackendHardware"); // Refresh state. @@ -335,7 +309,6 @@ void VideoBackendHardware::RunLoop(bool enable) void VideoFifo_CheckAsyncRequest() { VideoFifo_CheckSwapRequest(); - VideoFifo_CheckEFBAccess(); VideoFifo_CheckPerfQueryRequest(); VideoFifo_CheckBBoxRequest(); } diff --git a/Source/Core/VideoCommon/MainBase.h b/Source/Core/VideoCommon/MainBase.h index bcef8024ec..b8eebf37a0 100644 --- a/Source/Core/VideoCommon/MainBase.h +++ b/Source/Core/VideoCommon/MainBase.h @@ -6,5 +6,4 @@ extern bool s_BackendInitialized; extern Common::Flag s_swapRequested; -void VideoFifo_CheckEFBAccess(); void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 3e95eca5cc..cb9be880e0 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_CheckEFBAccess(); VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight); XFBWrited = true; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index bf7800cc9a..520654448f 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -166,8 +166,6 @@ void VertexManager::Flush() // loading a state will invalidate BP, so check for it g_video_backend->CheckInvalidState(); - VideoFifo_CheckEFBAccess(); - #if defined(_DEBUG) || defined(DEBUGFAST) PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfmem.numTexGen.numTexGens, xfmem.numChan.numColorChans, xfmem.dualTexTrans.enabled, bpmem.ztex2.op, diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj b/Source/Core/VideoCommon/VideoCommon.vcxproj index 649cd5095e..ff56a97703 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj @@ -35,6 +35,7 @@ + @@ -84,6 +85,7 @@ + diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index eca9287439..1998fce1cc 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -146,6 +146,9 @@ Decoding + + Util + Util @@ -290,6 +293,9 @@ Vertex Loading + + Util + Util From ad7264da7de4ca20472dfc2ef911314ff0e78de7 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 31 Jan 2015 12:01:01 +0100 Subject: [PATCH 2/4] 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(); } } From edbd4021014cd24a7aa98396160df12b590529f7 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 31 Jan 2015 12:43:58 +0100 Subject: [PATCH 3/4] VideoCommon: bbox by async events --- Source/Core/VideoCommon/AsyncRequests.cpp | 3 ++ Source/Core/VideoCommon/AsyncRequests.h | 7 +++++ Source/Core/VideoCommon/MainBase.cpp | 37 +++++------------------ 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/Source/Core/VideoCommon/AsyncRequests.cpp b/Source/Core/VideoCommon/AsyncRequests.cpp index 9430d390fa..e99b1ab255 100644 --- a/Source/Core/VideoCommon/AsyncRequests.cpp +++ b/Source/Core/VideoCommon/AsyncRequests.cpp @@ -95,6 +95,9 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e) Renderer::Swap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride, e.swap_event.fbHeight, rc); break; + case Event::BBOX_READ: + *e.bbox.data = g_renderer->BBoxRead(e.bbox.index); + } } diff --git a/Source/Core/VideoCommon/AsyncRequests.h b/Source/Core/VideoCommon/AsyncRequests.h index fe3d5c3234..15cc5c72e8 100644 --- a/Source/Core/VideoCommon/AsyncRequests.h +++ b/Source/Core/VideoCommon/AsyncRequests.h @@ -23,6 +23,7 @@ public: EFB_PEEK_COLOR, EFB_PEEK_Z, SWAP_EVENT, + BBOX_READ, } type; u64 time; @@ -49,6 +50,12 @@ public: u32 fbStride; u32 fbHeight; } swap_event; + + struct + { + int index; + u16* data; + } bbox; }; }; diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp index 25741ea7d8..74a2cc5fcf 100644 --- a/Source/Core/VideoCommon/MainBase.cpp +++ b/Source/Core/VideoCommon/MainBase.cpp @@ -24,11 +24,6 @@ static Common::Flag s_FifoShuttingDown; static Common::Flag s_perfQueryRequested; static Common::Event s_perfQueryReadyEvent; -static Common::Flag s_BBoxRequested; -static Common::Event s_BBoxReadyEvent; -static int s_BBoxIndex; -static u16 s_BBoxResult; - static volatile struct { u32 xfbAddr; @@ -184,30 +179,15 @@ u16 VideoBackendHardware::Video_GetBoundingBox(int index) SyncGPU(SYNC_GPU_BBOX); - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) - { - s_BBoxReadyEvent.Reset(); - if (s_FifoShuttingDown.IsSet()) - return 0; - s_BBoxIndex = index; - s_BBoxRequested.Set(); - s_BBoxReadyEvent.Wait(); - return s_BBoxResult; - } - else - { - return g_renderer->BBoxRead(index); - } -} + AsyncRequests::Event e; + u16 result; + e.time = 0; + e.type = AsyncRequests::Event::BBOX_READ; + e.bbox.index = index; + e.bbox.data = &result; + AsyncRequests::GetInstance()->PushEvent(e, true); -static void VideoFifo_CheckBBoxRequest() -{ - if (s_BBoxRequested.IsSet()) - { - s_BBoxResult = g_renderer->BBoxRead(s_BBoxIndex); - s_BBoxRequested.Clear(); - s_BBoxReadyEvent.Set(); - } + return result; } void VideoBackendHardware::InitializeShared() @@ -275,7 +255,6 @@ void VideoBackendHardware::RunLoop(bool enable) void VideoFifo_CheckAsyncRequest() { VideoFifo_CheckPerfQueryRequest(); - VideoFifo_CheckBBoxRequest(); } void VideoBackendHardware::Video_GatherPipeBursted() From b35fa222f5db3d7862a8526735d195284b4a1f34 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 31 Jan 2015 13:09:25 +0100 Subject: [PATCH 4/4] VideoCommon: perf querys by async events --- Source/Core/VideoCommon/AsyncRequests.cpp | 5 +++ Source/Core/VideoCommon/AsyncRequests.h | 5 +++ Source/Core/VideoCommon/Fifo.cpp | 2 -- Source/Core/VideoCommon/Fifo.h | 4 --- Source/Core/VideoCommon/MainBase.cpp | 43 ++++------------------- 5 files changed, 17 insertions(+), 42 deletions(-) diff --git a/Source/Core/VideoCommon/AsyncRequests.cpp b/Source/Core/VideoCommon/AsyncRequests.cpp index e99b1ab255..a6cc5a4b9c 100644 --- a/Source/Core/VideoCommon/AsyncRequests.cpp +++ b/Source/Core/VideoCommon/AsyncRequests.cpp @@ -97,6 +97,11 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e) case Event::BBOX_READ: *e.bbox.data = g_renderer->BBoxRead(e.bbox.index); + break; + + case Event::PERF_QUERY: + g_perf_query->FlushResults(); + break; } } diff --git a/Source/Core/VideoCommon/AsyncRequests.h b/Source/Core/VideoCommon/AsyncRequests.h index 15cc5c72e8..68ef08cf67 100644 --- a/Source/Core/VideoCommon/AsyncRequests.h +++ b/Source/Core/VideoCommon/AsyncRequests.h @@ -24,6 +24,7 @@ public: EFB_PEEK_Z, SWAP_EVENT, BBOX_READ, + PERF_QUERY, } type; u64 time; @@ -56,6 +57,10 @@ public: int index; u16* data; } bbox; + + struct + { + } perf_query; }; }; diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp index 74470a9fcd..4a85679210 100644 --- a/Source/Core/VideoCommon/Fifo.cpp +++ b/Source/Core/VideoCommon/Fifo.cpp @@ -290,7 +290,6 @@ void RunGpuLoop() { g_video_backend->PeekMessages(); - VideoFifo_CheckAsyncRequest(); AsyncRequests::GetInstance()->PullEvents(); if (g_use_deterministic_gpu_thread) { @@ -353,7 +352,6 @@ void RunGpuLoop() // 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 // leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down. - VideoFifo_CheckAsyncRequest(); AsyncRequests::GetInstance()->PullEvents(); CommandProcessor::isPossibleWaitingSetDrawDone = false; } diff --git a/Source/Core/VideoCommon/Fifo.h b/Source/Core/VideoCommon/Fifo.h index d0b3c07015..56212e7d17 100644 --- a/Source/Core/VideoCommon/Fifo.h +++ b/Source/Core/VideoCommon/Fifo.h @@ -53,7 +53,3 @@ void EmulatorState(bool running); bool AtBreakpoint(); void ResetVideoBuffer(); void Fifo_SetRendering(bool bEnabled); - - -// Implemented by the Video Backend -void VideoFifo_CheckAsyncRequest(); diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp index 74a2cc5fcf..a8af71b31e 100644 --- a/Source/Core/VideoCommon/MainBase.cpp +++ b/Source/Core/VideoCommon/MainBase.cpp @@ -21,9 +21,6 @@ bool s_BackendInitialized = false; static Common::Flag s_FifoShuttingDown; -static Common::Flag s_perfQueryRequested; -static Common::Event s_perfQueryReadyEvent; - static volatile struct { u32 xfbAddr; @@ -47,7 +44,6 @@ void VideoBackendHardware::Video_ExitLoop() { ExitGpuLoop(); s_FifoShuttingDown.Set(); - s_perfQueryReadyEvent.Set(); } void VideoBackendHardware::Video_SetRendering(bool bEnabled) @@ -118,7 +114,7 @@ u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 e.efb_poke.data = InputData; e.efb_poke.x = x; e.efb_poke.y = y; - AsyncRequests::GetInstance()->PushEvent(e, 0); + AsyncRequests::GetInstance()->PushEvent(e, false); return 0; } else @@ -130,21 +126,11 @@ u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 e.efb_peek.x = x; e.efb_peek.y = y; e.efb_peek.data = &result; - AsyncRequests::GetInstance()->PushEvent(e, 1); + AsyncRequests::GetInstance()->PushEvent(e, true); return result; } } -static void VideoFifo_CheckPerfQueryRequest() -{ - if (s_perfQueryRequested.IsSet()) - { - g_perf_query->FlushResults(); - s_perfQueryRequested.Clear(); - s_perfQueryReadyEvent.Set(); - } -} - u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type) { if (!g_perf_query->ShouldEmulate()) @@ -154,20 +140,12 @@ u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type) SyncGPU(SYNC_GPU_PERFQUERY); - // TODO: Is this check sane? + AsyncRequests::Event e; + e.time = 0; + e.type = AsyncRequests::Event::PERF_QUERY; + if (!g_perf_query->IsFlushed()) - { - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) - { - s_perfQueryReadyEvent.Reset(); - if (s_FifoShuttingDown.IsSet()) - return 0; - s_perfQueryRequested.Set(); - s_perfQueryReadyEvent.Wait(); - } - else - g_perf_query->FlushResults(); - } + AsyncRequests::GetInstance()->PushEvent(e, true); return g_perf_query->GetQueryResult(type); } @@ -194,7 +172,6 @@ void VideoBackendHardware::InitializeShared() { VideoCommon_Init(); - s_perfQueryRequested.Clear(); s_FifoShuttingDown.Clear(); memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs)); m_invalid = false; @@ -246,17 +223,11 @@ void VideoBackendHardware::PauseAndLock(bool doLock, bool unpauseOnUnlock) Fifo_PauseAndLock(doLock, unpauseOnUnlock); } - void VideoBackendHardware::RunLoop(bool enable) { VideoCommon_RunLoop(enable); } -void VideoFifo_CheckAsyncRequest() -{ - VideoFifo_CheckPerfQueryRequest(); -} - void VideoBackendHardware::Video_GatherPipeBursted() { CommandProcessor::GatherPipeBursted();