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_precise_bug = TestPreciseBug(); | ||||||
|     has_broken_compute = is_intel_proprietary; |     has_broken_compute = is_intel_proprietary; | ||||||
|     has_fast_buffer_sub_data = is_nvidia; |     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_VariableAOFFI: {}", has_variable_aoffi); | ||||||
|     LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); |     LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); | ||||||
|  |  | ||||||
|  | @ -84,6 +84,10 @@ public: | ||||||
|         return has_fast_buffer_sub_data; |         return has_fast_buffer_sub_data; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     bool HasDebugTool() const { | ||||||
|  |         return has_debug_tool; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     static bool TestVariableAoffi(); |     static bool TestVariableAoffi(); | ||||||
|     static bool TestPreciseBug(); |     static bool TestPreciseBug(); | ||||||
|  | @ -102,6 +106,7 @@ private: | ||||||
|     bool has_precise_bug{}; |     bool has_precise_bug{}; | ||||||
|     bool has_broken_compute{}; |     bool has_broken_compute{}; | ||||||
|     bool has_fast_buffer_sub_data{}; |     bool has_fast_buffer_sub_data{}; | ||||||
|  |     bool has_debug_tool{}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace OpenGL
 | } // namespace OpenGL
 | ||||||
|  |  | ||||||
|  | @ -56,7 +56,7 @@ public: | ||||||
|     std::deque<Frame*> present_queue; |     std::deque<Frame*> present_queue; | ||||||
|     Frame* previous_frame{}; |     Frame* previous_frame{}; | ||||||
| 
 | 
 | ||||||
|     FrameMailbox() { |     FrameMailbox() : has_debug_tool{Device().HasDebugTool()} { | ||||||
|         for (auto& frame : swap_chain) { |         for (auto& frame : swap_chain) { | ||||||
|             free_queue.push(&frame); |             free_queue.push(&frame); | ||||||
|         } |         } | ||||||
|  | @ -127,9 +127,13 @@ public: | ||||||
|         std::unique_lock lock{swap_chain_lock}; |         std::unique_lock lock{swap_chain_lock}; | ||||||
|         present_queue.push_front(frame); |         present_queue.push_front(frame); | ||||||
|         present_cv.notify_one(); |         present_cv.notify_one(); | ||||||
|  | 
 | ||||||
|  |         DebugNotifyNextFrame(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Frame* TryGetPresentFrame(int timeout_ms) { |     Frame* TryGetPresentFrame(int timeout_ms) { | ||||||
|  |         DebugWaitForNextFrame(); | ||||||
|  | 
 | ||||||
|         std::unique_lock lock{swap_chain_lock}; |         std::unique_lock lock{swap_chain_lock}; | ||||||
|         // wait for new entries in the present_queue
 |         // wait for new entries in the present_queue
 | ||||||
|         present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms), |         present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms), | ||||||
|  | @ -155,6 +159,33 @@ public: | ||||||
|         previous_frame = frame; |         previous_frame = frame; | ||||||
|         return 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 { | namespace { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rodrigo Locatti
						Rodrigo Locatti