From c5afe93dccef4aacb194cd87cbbf3bca875f203b Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 14 Mar 2020 17:45:01 -0400 Subject: [PATCH] renderer_opengl: Keep presentation frames in lock-step when GPU debugging. - Fixes renderdoc with OpenGL renderer. --- .../renderer_opengl/renderer_opengl.cpp | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 12333e8c9..c91658cd1 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -56,7 +56,7 @@ public: std::deque present_queue; Frame* previous_frame{}; - FrameMailbox() { + FrameMailbox() : has_debug_tool{Device().HasDebugTool()} { for (auto& frame : swap_chain) { free_queue.push(&frame); } @@ -127,9 +127,13 @@ public: std::unique_lock lock{swap_chain_lock}; present_queue.push_front(frame); present_cv.notify_one(); + + DebugNotifyNextFrame(); } Frame* TryGetPresentFrame(int timeout_ms) { + DebugWaitForNextFrame(); + std::unique_lock lock{swap_chain_lock}; // wait for new entries in the present_queue present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms), @@ -155,6 +159,33 @@ public: previous_frame = frame; return frame; } + +private: + std::mutex debug_synch_mutex; + std::condition_variable debug_synch_condition; + std::atomic_int frame_for_debug{}; + const bool has_debug_tool; // When true, using a GPU debugger, so keep frames in lock-step + + /// Signal that a new frame is available (called from GPU thread) + void DebugNotifyNextFrame() { + if (!has_debug_tool) { + return; + } + frame_for_debug++; + std::lock_guard lock{debug_synch_mutex}; + debug_synch_condition.notify_one(); + } + + /// Wait for a new frame to be available (called from presentation thread) + void DebugWaitForNextFrame() { + if (!has_debug_tool) { + return; + } + const int last_frame = frame_for_debug; + std::unique_lock lock{debug_synch_mutex}; + debug_synch_condition.wait(lock, + [this, last_frame] { return frame_for_debug > last_frame; }); + } }; namespace {