Merge pull request #3512 from bunnei/fix-renderdoc

renderer_opengl: Keep frames synchronized when using a GPU debugger.
This commit is contained in:
Rodrigo Locatti 2020-03-15 19:28:43 -03:00 committed by GitHub
commit 86b1f15d9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 1 deletions

View File

@ -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);

View File

@ -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

View File

@ -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 {