summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Rodrigo Locatti2020-03-15 19:28:43 -0300
committerGravatar GitHub2020-03-15 19:28:43 -0300
commit86b1f15d9ae90ec6161accc665a7b4be2de9cb6b (patch)
tree56531badf430f61332e5af74c544b382f9734d25 /src
parentMerge pull request #3516 from makigumo/patch-3 (diff)
parentrenderer_opengl: Keep presentation frames in lock-step when GPU debugging. (diff)
downloadyuzu-86b1f15d9ae90ec6161accc665a7b4be2de9cb6b.tar.gz
yuzu-86b1f15d9ae90ec6161accc665a7b4be2de9cb6b.tar.xz
yuzu-86b1f15d9ae90ec6161accc665a7b4be2de9cb6b.zip
Merge pull request #3512 from bunnei/fix-renderdoc
renderer_opengl: Keep frames synchronized when using a GPU debugger.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp33
3 files changed, 38 insertions, 1 deletions
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 1a2e2a9f7..e824e216d 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -157,6 +157,7 @@ Device::Device() : base_bindings{BuildBaseBindings()} {
157 has_precise_bug = TestPreciseBug(); 157 has_precise_bug = TestPreciseBug();
158 has_broken_compute = is_intel_proprietary; 158 has_broken_compute = is_intel_proprietary;
159 has_fast_buffer_sub_data = is_nvidia; 159 has_fast_buffer_sub_data = is_nvidia;
160 has_debug_tool = HasExtension(extensions, "GL_EXT_debug_tool");
160 161
161 LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); 162 LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi);
162 LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); 163 LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug);
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index d73b099d0..7aaa3a077 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -84,6 +84,10 @@ public:
84 return has_fast_buffer_sub_data; 84 return has_fast_buffer_sub_data;
85 } 85 }
86 86
87 bool HasDebugTool() const {
88 return has_debug_tool;
89 }
90
87private: 91private:
88 static bool TestVariableAoffi(); 92 static bool TestVariableAoffi();
89 static bool TestPreciseBug(); 93 static bool TestPreciseBug();
@@ -102,6 +106,7 @@ private:
102 bool has_precise_bug{}; 106 bool has_precise_bug{};
103 bool has_broken_compute{}; 107 bool has_broken_compute{};
104 bool has_fast_buffer_sub_data{}; 108 bool has_fast_buffer_sub_data{};
109 bool has_debug_tool{};
105}; 110};
106 111
107} // namespace OpenGL 112} // namespace OpenGL
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:
56 std::deque<Frame*> present_queue; 56 std::deque<Frame*> present_queue;
57 Frame* previous_frame{}; 57 Frame* previous_frame{};
58 58
59 FrameMailbox() { 59 FrameMailbox() : has_debug_tool{Device().HasDebugTool()} {
60 for (auto& frame : swap_chain) { 60 for (auto& frame : swap_chain) {
61 free_queue.push(&frame); 61 free_queue.push(&frame);
62 } 62 }
@@ -127,9 +127,13 @@ public:
127 std::unique_lock lock{swap_chain_lock}; 127 std::unique_lock lock{swap_chain_lock};
128 present_queue.push_front(frame); 128 present_queue.push_front(frame);
129 present_cv.notify_one(); 129 present_cv.notify_one();
130
131 DebugNotifyNextFrame();
130 } 132 }
131 133
132 Frame* TryGetPresentFrame(int timeout_ms) { 134 Frame* TryGetPresentFrame(int timeout_ms) {
135 DebugWaitForNextFrame();
136
133 std::unique_lock lock{swap_chain_lock}; 137 std::unique_lock lock{swap_chain_lock};
134 // wait for new entries in the present_queue 138 // wait for new entries in the present_queue
135 present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms), 139 present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms),
@@ -155,6 +159,33 @@ public:
155 previous_frame = frame; 159 previous_frame = frame;
156 return frame; 160 return frame;
157 } 161 }
162
163private:
164 std::mutex debug_synch_mutex;
165 std::condition_variable debug_synch_condition;
166 std::atomic_int frame_for_debug{};
167 const bool has_debug_tool; // When true, using a GPU debugger, so keep frames in lock-step
168
169 /// Signal that a new frame is available (called from GPU thread)
170 void DebugNotifyNextFrame() {
171 if (!has_debug_tool) {
172 return;
173 }
174 frame_for_debug++;
175 std::lock_guard lock{debug_synch_mutex};
176 debug_synch_condition.notify_one();
177 }
178
179 /// Wait for a new frame to be available (called from presentation thread)
180 void DebugWaitForNextFrame() {
181 if (!has_debug_tool) {
182 return;
183 }
184 const int last_frame = frame_for_debug;
185 std::unique_lock lock{debug_synch_mutex};
186 debug_synch_condition.wait(lock,
187 [this, last_frame] { return frame_for_debug > last_frame; });
188 }
158}; 189};
159 190
160namespace { 191namespace {