mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-01-11 20:10:30 +00:00
Log start/stop capture, give captures a title
and make the RenderDoc API more resistant to being called without an underlying Api struct
This commit is contained in:
parent
7a1c7b714e
commit
801dcd5237
4 changed files with 65 additions and 13 deletions
|
|
@ -92,13 +92,13 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
/// Checks if the RenderDoc UI is currently connected to this process.
|
||||
/// </summary>
|
||||
[RenderDocApiVersion(1, 0)]
|
||||
public static bool IsTargetControlConnected => Api->IsTargetControlConnected() != 0;
|
||||
public static bool IsTargetControlConnected => Api is not null && Api->IsTargetControlConnected() != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current frame is capturing.
|
||||
/// </summary>
|
||||
[RenderDocApiVersion(1, 0)]
|
||||
public static bool IsFrameCapturing => Api->IsFrameCapturing() != 0;
|
||||
public static bool IsFrameCapturing => Api is not null && Api->IsFrameCapturing() != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Set one of the options for tweaking some behaviors of capturing.
|
||||
|
|
@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static bool SetCaptureOption(CaptureOption option, int integer)
|
||||
{
|
||||
return Api->SetCaptureOptionU32(option, integer) != 0;
|
||||
return Api is not null && Api->SetCaptureOptionU32(option, integer) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -129,7 +129,7 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static bool SetCaptureOption(CaptureOption option, float single)
|
||||
{
|
||||
return Api->SetCaptureOptionF32(option, single) != 0;
|
||||
return Api is not null && Api->SetCaptureOptionF32(option, single) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -183,6 +183,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static void SetFocusToggleKeys(ReadOnlySpan<InputButton> buttons)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
fixed (InputButton* ptr = buttons)
|
||||
{
|
||||
Api->SetFocusToggleKeys(ptr, buttons.Length);
|
||||
|
|
@ -196,6 +198,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static void SetCaptureKeys(ReadOnlySpan<InputButton> buttons)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
fixed (InputButton* ptr = buttons)
|
||||
{
|
||||
Api->SetCaptureKeys(ptr, buttons.Length);
|
||||
|
|
@ -210,6 +214,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static void RemoveHooks()
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
Api->RemoveHooks();
|
||||
}
|
||||
|
||||
|
|
@ -221,6 +227,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static void UnloadCrashHandler()
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
Api->UnloadCrashHandler();
|
||||
}
|
||||
|
||||
|
|
@ -231,6 +239,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static void TriggerCapture()
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
Api->TriggerCapture();
|
||||
}
|
||||
|
||||
|
|
@ -242,6 +252,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static Capture? GetCapture(int index)
|
||||
{
|
||||
if (Api is null) return null;
|
||||
|
||||
int length = 0;
|
||||
if (Api->GetCapture(index, null, &length, null) == 0)
|
||||
{
|
||||
|
|
@ -267,6 +279,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static bool LaunchReplayUI(bool connectTargetControl, string? commandLine = null)
|
||||
{
|
||||
if (Api is null) return false;
|
||||
|
||||
if (commandLine == null)
|
||||
{
|
||||
return Api->LaunchReplayUI(connectTargetControl ? 1 : 0, null) != 0;
|
||||
|
|
@ -287,6 +301,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static void SetActiveWindow(nint hDevice, nint hWindow)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
Api->SetActiveWindow((void*)hDevice, (void*)hWindow);
|
||||
}
|
||||
|
||||
|
|
@ -298,6 +314,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static void StartFrameCapture(nint hDevice, nint hWindow)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
Api->StartFrameCapture((void*)hDevice, (void*)hWindow);
|
||||
}
|
||||
|
||||
|
|
@ -310,6 +328,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 0)]
|
||||
public static bool EndFrameCapture(nint hDevice, nint hWindow)
|
||||
{
|
||||
if (Api is null) return false;
|
||||
|
||||
return Api->EndFrameCapture((void*)hDevice, (void*)hWindow) != 0;
|
||||
}
|
||||
|
||||
|
|
@ -323,6 +343,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 1)]
|
||||
public static void TriggerMultiFrameCapture(int numFrames)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
AssertAtLeast(1, 1);
|
||||
Api->TriggerMultiFrameCapture(numFrames);
|
||||
}
|
||||
|
|
@ -337,6 +359,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 2)]
|
||||
public static void SetCaptureFileComments(string? fileName, string comments)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
AssertAtLeast(1, 2);
|
||||
|
||||
byte[] commentBytes = comments.ToNullTerminatedByteArray();
|
||||
|
|
@ -369,6 +393,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 4)]
|
||||
public static void DiscardFrameCapture(nint hDevice, nint hWindow)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
AssertAtLeast(1, 4);
|
||||
Api->DiscardFrameCapture((void*)hDevice, (void*)hWindow);
|
||||
}
|
||||
|
|
@ -386,6 +412,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 5)]
|
||||
public static bool ShowReplayUI()
|
||||
{
|
||||
if (Api is null) return false;
|
||||
|
||||
AssertAtLeast(1, 5);
|
||||
return Api->ShowReplayUI() != 0;
|
||||
}
|
||||
|
|
@ -406,6 +434,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
[RenderDocApiVersion(1, 6)]
|
||||
public static void SetCaptureTitle(string title)
|
||||
{
|
||||
if (Api is null) return;
|
||||
|
||||
AssertAtLeast(1, 6);
|
||||
fixed (byte* ptr = title.ToNullTerminatedByteArray())
|
||||
Api->SetCaptureTitle(ptr);
|
||||
|
|
@ -518,7 +548,8 @@ namespace Ryujinx.Graphics.RenderDocApi
|
|||
return encoding.GetBytes(str + '\0');
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"(lib)?renderdoc(\.dll|\.so|\.dylib)(\.\d+)?", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
|
||||
[GeneratedRegex(@"(lib)?renderdoc(\.dll|\.so|\.dylib)(\.\d+)?",
|
||||
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
|
||||
private static partial Regex RenderDocApiDynamicLibraryRegex();
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@ using Avalonia;
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Platform;
|
||||
using Ryujinx.Ava.Systems.Configuration;
|
||||
using Ryujinx.Ava.Utilities;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Helper;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.RenderDocApi;
|
||||
using Ryujinx.HLE;
|
||||
using SPB.Graphics;
|
||||
using SPB.Platform;
|
||||
using SPB.Platform.GLX;
|
||||
|
|
@ -48,21 +51,21 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
|
||||
protected virtual void OnWindowDestroyed() { }
|
||||
|
||||
public void StartRenderDocCapture()
|
||||
public void StartRenderDocCapture(Switch device)
|
||||
{
|
||||
if (!RenderDoc.IsAvailable) return;
|
||||
|
||||
if (RenderDoc.IsFrameCapturing) return;
|
||||
|
||||
try
|
||||
{
|
||||
RenderDoc.StartFrameCapture(nint.Zero, WindowHandle);
|
||||
} catch {}
|
||||
RenderDoc.StartFrameCapture(nint.Zero, WindowHandle);
|
||||
RenderDoc.SetCaptureTitle(TitleHelper.TruncatedApplicationTitle(device.Processes.ActiveApplication, Program.Version));
|
||||
|
||||
Logger.Info?.Print(LogClass.Application, "Starting RenderDoc capture.");
|
||||
}
|
||||
|
||||
public bool EndRenderDocCapture()
|
||||
{
|
||||
return RenderDoc.IsAvailable && RenderDoc.EndFrameCapture(nint.Zero, WindowHandle);
|
||||
return RenderDoc.IsAvailable && RenderDoc.IsFrameCapturing && RenderDoc.EndFrameCapture(nint.Zero, WindowHandle);
|
||||
}
|
||||
|
||||
protected virtual void OnWindowDestroying()
|
||||
|
|
|
|||
|
|
@ -2500,7 +2500,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
viewModel =>
|
||||
{
|
||||
if (!RenderDoc.IsFrameCapturing)
|
||||
viewModel.AppHost.RendererHost.EmbeddedWindow.StartRenderDocCapture();
|
||||
viewModel.AppHost.RendererHost.EmbeddedWindow.StartRenderDocCapture(viewModel.AppHost.Device);
|
||||
|
||||
viewModel.RenderDocIsCapturing = true;
|
||||
});
|
||||
|
|
@ -2510,7 +2510,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
viewModel =>
|
||||
{
|
||||
if (RenderDoc.IsFrameCapturing)
|
||||
viewModel.AppHost.RendererHost.EmbeddedWindow.EndRenderDocCapture();
|
||||
{
|
||||
if (viewModel.AppHost.RendererHost.EmbeddedWindow.EndRenderDocCapture())
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application, "Ended RenderDoc capture.");
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.RenderDocIsCapturing = false;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,5 +22,18 @@ namespace Ryujinx.Ava.Utilities
|
|||
? appTitle + $" ({pauseString})"
|
||||
: appTitle;
|
||||
}
|
||||
|
||||
public static string TruncatedApplicationTitle(ProcessResult activeProcess, string applicationVersion)
|
||||
{
|
||||
if (activeProcess == null)
|
||||
return string.Empty;
|
||||
|
||||
string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}";
|
||||
string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}";
|
||||
string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})";
|
||||
string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)";
|
||||
|
||||
return $"{applicationVersion}\n{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue