mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
Add -renderdoc <path> and -renderdoc-frame N[,C], writing one .rdc per selected dump frame. RenderDoc's own triggers cannot reach gsrunner on a Wayland session. It polls only X11/xcb for the capture key, so PlatformHasKeyInput() is false and F12 is never seen. Target control cannot drive it either: RenderDoc hooks only the core EGL entry points, while GLContextEGL prefers eglGetPlatformDisplayEXT and eglCreatePlatformWindowSurfaceEXT, so no native window is ever registered for the surface and there is nothing to attach a capture to. The in-application API sidesteps both -- StartFrameCapture(nullptr, nullptr) captures the active device whatever the windowing system, and needs no keypress, so a headless dump replay can capture unattended. Captures open and close at present boundaries in Host::BeginPresentFrame(), which runs on the GS thread with the frame's work submitted but not yet presented. RenderDoc must already be in the process, since it installs its hooks from its library constructor. A late dlopen hands back a working API whose hooks were never installed and then captures nothing, so that case is refused with the LD_PRELOAD command to use instead. Verified on aarch64/Asahi against a God of War II dump. Vulkan surfaceless produces a valid capture: 351 actions, 218 draws, 99 textures, render target carrying real image data. Windowed Vulkan cannot work under RenderDoc's layer at all, which does not advertise VK_KHR_wayland_surface. GL captures record correct events and texture contents but replay with black render targets on Honeykrisp. 3rdparty/include/renderdoc_app.h is RenderDoc's MIT-licensed in-application API header, vendored verbatim.
41 lines
1.9 KiB
C++
41 lines
1.9 KiB
C++
// SPDX-FileCopyrightText: 2026 ARMSX2 Contributors
|
|
// SPDX-License-Identifier: GPL-3.0+
|
|
|
|
#pragma once
|
|
|
|
#include "common/Pcsx2Defs.h"
|
|
|
|
#include <string>
|
|
|
|
// RenderDoc capture driven from inside gsrunner, rather than by RenderDoc itself.
|
|
//
|
|
// The usual F12 trigger cannot work here. RenderDoc only polls X11/xcb for the
|
|
// capture key (its Wayland input backend sits behind an off-by-default build
|
|
// option), so on a Wayland surface PlatformHasKeyInput() is false and the key is
|
|
// never seen. Triggering over target control does not help either: gsrunner opens
|
|
// EGL through eglGetPlatformDisplayEXT / eglCreatePlatformWindowSurfaceEXT, and
|
|
// RenderDoc hooks only the core entry points, so it never records a native window
|
|
// for the surface and has nothing to attach a capture to.
|
|
//
|
|
// The in-application API sidesteps both. StartFrameCapture(nullptr, nullptr)
|
|
// captures the active device whatever windowing system the swapchain came from,
|
|
// and needs no keypress, so a headless dump replay can capture unattended.
|
|
namespace RenderDocCapture
|
|
{
|
|
/// Binds the RenderDoc API and arms a capture of dump frames
|
|
/// [start_frame, start_frame + num_frames). Must be called before the GS device
|
|
/// exists, since RenderDoc installs its hooks when its library loads. Returns
|
|
/// false (and disables capture) if RenderDoc is unavailable.
|
|
bool Initialize(const std::string& path_template, u32 start_frame, u32 num_frames);
|
|
|
|
/// Runs on the GS thread at each present boundary, where `frame_number` is the
|
|
/// dump frame whose GS work has just been submitted. Opens and closes captures
|
|
/// so that each armed frame lands in its own .rdc.
|
|
void OnPresentFrame(u32 frame_number);
|
|
|
|
/// Reports whether the armed range completed. Does not close an in-flight
|
|
/// capture: EndFrameCapture must run on the GS thread, and this is called from
|
|
/// the CPU thread after the GS thread is gone.
|
|
void Shutdown();
|
|
} // namespace RenderDocCapture
|