forked from eden-emu/eden
		
	Merge pull request #3512 from bunnei/fix-renderdoc
renderer_opengl: Keep frames synchronized when using a GPU debugger.
This commit is contained in:
		
						commit
						86b1f15d9a
					
				
					 3 changed files with 38 additions and 1 deletions
				
			
		|  | @ -157,6 +157,7 @@ Device::Device() : base_bindings{BuildBaseBindings()} { | |||
|     has_precise_bug = TestPreciseBug(); | ||||
|     has_broken_compute = is_intel_proprietary; | ||||
|     has_fast_buffer_sub_data = is_nvidia; | ||||
|     has_debug_tool = HasExtension(extensions, "GL_EXT_debug_tool"); | ||||
| 
 | ||||
|     LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); | ||||
|     LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); | ||||
|  |  | |||
|  | @ -84,6 +84,10 @@ public: | |||
|         return has_fast_buffer_sub_data; | ||||
|     } | ||||
| 
 | ||||
|     bool HasDebugTool() const { | ||||
|         return has_debug_tool; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     static bool TestVariableAoffi(); | ||||
|     static bool TestPreciseBug(); | ||||
|  | @ -102,6 +106,7 @@ private: | |||
|     bool has_precise_bug{}; | ||||
|     bool has_broken_compute{}; | ||||
|     bool has_fast_buffer_sub_data{}; | ||||
|     bool has_debug_tool{}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace OpenGL
 | ||||
|  |  | |||
|  | @ -56,7 +56,7 @@ public: | |||
|     std::deque<Frame*> 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 { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rodrigo Locatti
						Rodrigo Locatti