forked from suyu/suyu
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…
Reference in a new issue