From 428c975f098cf3c8914e07219be02bed56a0b8d1 Mon Sep 17 00:00:00 2001 From: Erik Abair Date: Fri, 4 Apr 2025 10:32:49 -0700 Subject: [PATCH] nv2a: Allow multiframe RenderDoc captures with nv2a traces Allows multiple frames to be captured at once by holding shift while pressing F10. Temporarily toggles nv2a trace messages if control is held while pressing F10. --- hw/xbox/nv2a/debug.h | 3 ++- hw/xbox/nv2a/pgraph/debug_renderdoc.c | 4 +++- hw/xbox/nv2a/pgraph/gl/debug.c | 26 +++++++++++++++++++------- hw/xbox/nv2a/pgraph/vk/debug.c | 16 ++++++++++++++-- ui/xui/main.cc | 4 ++-- ui/xui/menubar.cc | 4 +++- 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/hw/xbox/nv2a/debug.h b/hw/xbox/nv2a/debug.h index 3873f94239..2dc4bece96 100644 --- a/hw/xbox/nv2a/debug.h +++ b/hw/xbox/nv2a/debug.h @@ -155,8 +155,9 @@ static inline void nv2a_profile_inc_counter(enum NV2A_PROF_COUNTERS_ENUM cnt) void nv2a_dbg_renderdoc_init(void); void *nv2a_dbg_renderdoc_get_api(void); bool nv2a_dbg_renderdoc_available(void); -void nv2a_dbg_renderdoc_capture_frames(int num_frames); +void nv2a_dbg_renderdoc_capture_frames(int num_frames, bool trace); extern int renderdoc_capture_frames; +extern bool renderdoc_trace_frames; #endif #ifdef __cplusplus diff --git a/hw/xbox/nv2a/pgraph/debug_renderdoc.c b/hw/xbox/nv2a/pgraph/debug_renderdoc.c index 273e307973..667f01a0c9 100644 --- a/hw/xbox/nv2a/pgraph/debug_renderdoc.c +++ b/hw/xbox/nv2a/pgraph/debug_renderdoc.c @@ -36,6 +36,7 @@ static RENDERDOC_API_1_6_0 *rdoc_api = NULL; int renderdoc_capture_frames = 0; +bool renderdoc_trace_frames = false; void nv2a_dbg_renderdoc_init(void) { @@ -89,7 +90,8 @@ bool nv2a_dbg_renderdoc_available(void) return rdoc_api != NULL; } -void nv2a_dbg_renderdoc_capture_frames(int num_frames) +void nv2a_dbg_renderdoc_capture_frames(int num_frames, bool trace) { renderdoc_capture_frames += num_frames; + renderdoc_trace_frames = trace; } diff --git a/hw/xbox/nv2a/pgraph/gl/debug.c b/hw/xbox/nv2a/pgraph/gl/debug.c index 968941dc7e..97803bc301 100644 --- a/hw/xbox/nv2a/pgraph/gl/debug.c +++ b/hw/xbox/nv2a/pgraph/gl/debug.c @@ -29,6 +29,8 @@ #include #ifdef CONFIG_RENDERDOC +#include "trace/control.h" + #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include "thirdparty/renderdoc_app.h" #endif @@ -154,7 +156,8 @@ void gl_debug_frame_terminator(void) RENDERDOC_API_1_6_0 *rdoc_api = nv2a_dbg_renderdoc_get_api(); if (rdoc_api->IsTargetControlConnected()) { - if (rdoc_api->IsFrameCapturing()) { + bool capturing = rdoc_api->IsFrameCapturing(); + if (capturing && renderdoc_capture_frames == 0) { rdoc_api->EndFrameCapture(NULL, NULL); GLenum error = glGetError(); if (error != GL_NO_ERROR) { @@ -162,14 +165,23 @@ void gl_debug_frame_terminator(void) "Renderdoc EndFrameCapture triggered GL error 0x%X - ignoring\n", error); } + if (renderdoc_trace_frames) { + trace_enable_events("-nv2a_pgraph_*"); + renderdoc_trace_frames = false; + } } if (renderdoc_capture_frames > 0) { - rdoc_api->StartFrameCapture(NULL, NULL); - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - fprintf(stderr, - "Renderdoc StartFrameCapture triggered GL error 0x%X - ignoring\n", - error); + if (!capturing) { + if (renderdoc_trace_frames) { + trace_enable_events("nv2a_pgraph_*"); + } + rdoc_api->StartFrameCapture(NULL, NULL); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + fprintf(stderr, + "Renderdoc StartFrameCapture triggered GL error 0x%X - ignoring\n", + error); + } } --renderdoc_capture_frames; } diff --git a/hw/xbox/nv2a/pgraph/vk/debug.c b/hw/xbox/nv2a/pgraph/vk/debug.c index 5c31c9f119..88327b0cca 100644 --- a/hw/xbox/nv2a/pgraph/vk/debug.c +++ b/hw/xbox/nv2a/pgraph/vk/debug.c @@ -25,6 +25,8 @@ #endif #ifdef CONFIG_RENDERDOC +#include "trace/control.h" + #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include "thirdparty/renderdoc_app.h" #endif @@ -46,11 +48,21 @@ void pgraph_vk_debug_frame_terminator(void) PGRAPHVkState *r = g_nv2a->pgraph.vk_renderer_state; if (rdoc_api->IsTargetControlConnected()) { - if (rdoc_api->IsFrameCapturing()) { + bool capturing = rdoc_api->IsFrameCapturing(); + if (capturing && renderdoc_capture_frames == 0) { rdoc_api->EndFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(r->instance), 0); + if (renderdoc_trace_frames) { + trace_enable_events("-nv2a_pgraph_*"); + renderdoc_trace_frames = false; + } } if (renderdoc_capture_frames > 0) { - rdoc_api->StartFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(r->instance), 0); + if (!capturing) { + if (renderdoc_trace_frames) { + trace_enable_events("nv2a_pgraph_*"); + } + rdoc_api->StartFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(r->instance), 0); + } --renderdoc_capture_frames; } } diff --git a/ui/xui/main.cc b/ui/xui/main.cc index 699805f113..a0e57820e1 100644 --- a/ui/xui/main.cc +++ b/ui/xui/main.cc @@ -218,7 +218,7 @@ void xemu_hud_render(void) #if defined(CONFIG_RENDERDOC) if (g_capture_renderdoc_frame) { - nv2a_dbg_renderdoc_capture_frames(1); + nv2a_dbg_renderdoc_capture_frames(1, false); g_capture_renderdoc_frame = false; } #endif @@ -291,7 +291,7 @@ void xemu_hud_render(void) !ImGui::IsAnyItemFocused() && !ImGui::IsAnyItemHovered())) { g_scene_mgr.PushScene(g_popup_menu); } - + bool mod_key_down = ImGui::IsKeyDown(ImGuiKey_ModShift); for (int f_key = 0; f_key < 4; ++f_key) { if (ImGui::IsKeyPressed((enum ImGuiKey)(ImGuiKey_F5 + f_key))) { diff --git a/ui/xui/menubar.cc b/ui/xui/menubar.cc index f0b6c1d5c2..83a0b08ae2 100644 --- a/ui/xui/menubar.cc +++ b/ui/xui/menubar.cc @@ -73,7 +73,9 @@ void ProcessKeyboardShortcuts(void) #ifdef CONFIG_RENDERDOC if (ImGui::IsKeyPressed(ImGuiKey_F10) && nv2a_dbg_renderdoc_available()) { - nv2a_dbg_renderdoc_capture_frames(1); + ImGuiIO& io = ImGui::GetIO(); + int num_frames = io.KeyShift ? 5 : 1; + nv2a_dbg_renderdoc_capture_frames(num_frames, io.KeyCtrl); } #endif }