mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-23 21:55:47 +00:00
Compare commits
3 Commits
Canary-1.3
...
Canary-1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d53b02fa8 | ||
|
|
4631e0a9e1 | ||
|
|
e477ec7149 |
@@ -28,7 +28,7 @@ jobs:
|
||||
configuration: [Release]
|
||||
platform:
|
||||
- { name: win-x64, zip_os_name: win_x64 }
|
||||
#- { name: win-arm64, zip_os_name: win_arm64 }
|
||||
- { name: win-arm64, zip_os_name: win_arm64 }
|
||||
- { name: linux-x64, zip_os_name: linux_x64 }
|
||||
- { name: linux-arm64, zip_os_name: linux_arm64 }
|
||||
#- { name: osx-x64, zip_os_name: osx_x64 }
|
||||
|
||||
@@ -32,9 +32,9 @@ jobs:
|
||||
matrix:
|
||||
platform:
|
||||
- { name: win-x64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: win_x64 }
|
||||
#- { name: win-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: win_arm64 }
|
||||
- { name: linux-x64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_x64 }
|
||||
- { name: linux-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_arm64 }
|
||||
- { name: win-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: win_arm64 }
|
||||
- { name: linux-x64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_x64 }
|
||||
- { name: linux-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_arm64 }
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ jobs:
|
||||
matrix:
|
||||
platform:
|
||||
- { name: win-x64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: win_x64 }
|
||||
#- { name: win-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: win_arm64 }
|
||||
- { name: linux-x64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_x64 }
|
||||
- { name: linux-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_arm64 }
|
||||
- { name: win-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: win_arm64 }
|
||||
- { name: linux-x64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_x64 }
|
||||
- { name: linux-arm64, os: ghcr.io/catthehacker/ubuntu:act-latest, zip_os_name: linux_arm64 }
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
|
||||
@@ -200,6 +200,31 @@
|
||||
"zh_TW": "使用 Hypervisor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabSystemGCLowLatency",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Use Low-latency Garbage Collector",
|
||||
"es_ES": "Usa recolección de basura de baja latencia",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "MenuBarFile",
|
||||
"Translations": {
|
||||
@@ -16550,6 +16575,31 @@
|
||||
"zh_TW": "變更客體記憶體的映射和存取方式。這會極大地影響模擬 CPU 效能。\n\n如果不確定,請設定為主體略過檢查模式。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GCLowLatencyTooltip",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Sets the garbage collector for the CLR to low-latency mode.\n\nThis may decrease stuttering at the cost of performance.\n\nLeave OFF if unsure.",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "MemoryManagerSoftwareTooltip",
|
||||
"Translations": {
|
||||
|
||||
@@ -49,12 +49,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
private const int MinCountForDeletion = 32;
|
||||
private const int MaxCapacity = 2048;
|
||||
private const ulong GiB = 1024 * 1024 * 1024;
|
||||
private ulong MaxTextureSizeCapacity = 4UL * GiB;
|
||||
private ulong MaxTextureSizeCapacity = 2 * GiB;
|
||||
private const ulong MinTextureSizeCapacity = 512 * 1024 * 1024;
|
||||
private const ulong DefaultTextureSizeCapacity = 1 * GiB;
|
||||
private const ulong TextureSizeCapacity6GiB = 4 * GiB;
|
||||
private const ulong TextureSizeCapacity8GiB = 6 * GiB;
|
||||
private const ulong TextureSizeCapacity12GiB = 12 * GiB;
|
||||
|
||||
private const float MemoryScaleFactor = 0.50f;
|
||||
private ulong _maxCacheMemoryUsage = DefaultTextureSizeCapacity;
|
||||
@@ -73,31 +70,22 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <remarks>
|
||||
/// If the backend GPU has 0 memory capacity, the cache size defaults to `DefaultTextureSizeCapacity`.
|
||||
///
|
||||
/// Reads the current Device total CPU Memory, to determine the maximum amount of Vram available. Capped to 50% of Current GPU Memory.
|
||||
/// Reads the current Device total CPU Memory, to determine the maximum amount of VRAM available. Capped to 50% of Current GPU Memory.
|
||||
/// </remarks>
|
||||
/// <param name="context">The GPU context that the cache belongs to</param>
|
||||
/// <param name="cpuMemorySize">The amount of physical CPU Memory Avaiable on the device.</param>
|
||||
/// <param name="cpuMemorySize">The amount of physical CPU Memory available on the device.</param>
|
||||
public void Initialize(GpuContext context, ulong cpuMemorySize)
|
||||
{
|
||||
ulong cpuMemorySizeGiB = cpuMemorySize / GiB;
|
||||
ulong MaximumGpuMemoryGiB = context.Capabilities.MaximumGpuMemory / GiB;
|
||||
ulong TextureSizeCapacity = cpuMemorySize - (2 * GiB);
|
||||
|
||||
if (cpuMemorySizeGiB < 6 || context.Capabilities.MaximumGpuMemory == 0)
|
||||
{
|
||||
_maxCacheMemoryUsage = DefaultTextureSizeCapacity;
|
||||
return;
|
||||
}
|
||||
else if (cpuMemorySizeGiB == 6)
|
||||
{
|
||||
MaxTextureSizeCapacity = TextureSizeCapacity6GiB;
|
||||
}
|
||||
else if (cpuMemorySizeGiB == 8)
|
||||
{
|
||||
MaxTextureSizeCapacity = TextureSizeCapacity8GiB;
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxTextureSizeCapacity = TextureSizeCapacity12GiB;
|
||||
}
|
||||
MaxTextureSizeCapacity =
|
||||
context.Capabilities.MaximumGpuMemory == 0 || cpuMemorySizeGiB < 6 && MaximumGpuMemoryGiB < 6
|
||||
? DefaultTextureSizeCapacity
|
||||
: cpuMemorySizeGiB < 12
|
||||
? TextureSizeCapacity
|
||||
: cpuMemorySize;
|
||||
|
||||
ulong cacheMemory = (ulong)(context.Capabilities.MaximumGpuMemory * MemoryScaleFactor);
|
||||
|
||||
|
||||
@@ -133,9 +133,9 @@ namespace Ryujinx.HLE.HOS.Services.Caps
|
||||
|
||||
using SKBitmap bitmap = new(new SKImageInfo(ScreenshotWidth, ScreenshotHeight, SKColorType.Rgba8888));
|
||||
|
||||
IntPtr pixels = bitmap.GetPixels();
|
||||
nint pixels = bitmap.GetPixels();
|
||||
|
||||
if (pixels == IntPtr.Zero)
|
||||
if (pixels == 0)
|
||||
{
|
||||
return ResultCode.InvalidArgument;
|
||||
}
|
||||
|
||||
@@ -198,6 +198,12 @@ namespace Ryujinx.Ava
|
||||
public static AppBuilder BuildAvaloniaApp() =>
|
||||
AppBuilder.Configure<RyujinxApp>()
|
||||
.UsePlatformDetect()
|
||||
|
||||
// Vulkan UI rendering performs better, but its unpolished, and as such it lacks effective transparency.
|
||||
// https://github.com/AvaloniaUI/Avalonia/issues/19378
|
||||
// https://github.com/AvaloniaUI/Avalonia/issues/9610
|
||||
// X11RenderingMode.Glx && X11RenderingMode.Egl, Win32RenderingMode.Vulkan have these issues.
|
||||
|
||||
.With(new X11PlatformOptions
|
||||
{
|
||||
EnableMultiTouch = true,
|
||||
|
||||
@@ -46,6 +46,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -579,6 +580,12 @@ namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
_isActive = false;
|
||||
_playTimer.Stop();
|
||||
|
||||
GCSettings.LatencyMode = GCLatencyMode.Interactive;
|
||||
if (ConfigurationState.Instance.System.GCLowLatency)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application, "Garbage collector set to interactive mode.");
|
||||
}
|
||||
}
|
||||
|
||||
private void Exit()
|
||||
@@ -662,6 +669,12 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
_chrono.Stop();
|
||||
_playTimer.Stop();
|
||||
|
||||
GCSettings.LatencyMode = GCLatencyMode.Interactive;
|
||||
if (ConfigurationState.Instance.System.GCLowLatency)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application, "Garbage collector set to interactive mode.");
|
||||
}
|
||||
}
|
||||
|
||||
public void DisposeGpu()
|
||||
@@ -915,7 +928,14 @@ namespace Ryujinx.Ava.Systems
|
||||
ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText,
|
||||
appMetadata => appMetadata.UpdatePreGame()
|
||||
);
|
||||
|
||||
_playTimer.Start();
|
||||
|
||||
if (ConfigurationState.Instance.System.GCLowLatency)
|
||||
{
|
||||
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
|
||||
Logger.Info?.Print(LogClass.Application, "Garbage collector set to low latency mode.");
|
||||
}
|
||||
}
|
||||
|
||||
internal void Resume()
|
||||
@@ -926,6 +946,12 @@ namespace Ryujinx.Ava.Systems
|
||||
_playTimer.Start();
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI);
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed.");
|
||||
|
||||
if (ConfigurationState.Instance.System.GCLowLatency)
|
||||
{
|
||||
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
|
||||
Logger.Info?.Print(LogClass.Application, "Garbage collector set to low latency mode.");
|
||||
}
|
||||
}
|
||||
|
||||
internal void Pause()
|
||||
@@ -936,6 +962,12 @@ namespace Ryujinx.Ava.Systems
|
||||
_playTimer.Stop();
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI, LocaleManager.Instance[LocaleKeys.Paused]);
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused.");
|
||||
|
||||
GCSettings.LatencyMode = GCLatencyMode.Interactive;
|
||||
if (ConfigurationState.Instance.System.GCLowLatency)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application, "Garbage collector set to interactive mode.");
|
||||
}
|
||||
}
|
||||
|
||||
private void InitEmulatedSwitch()
|
||||
|
||||
@@ -470,6 +470,11 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
/// Uses Hypervisor over JIT if available
|
||||
/// </summary>
|
||||
public bool UseHypervisor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable low-latency mode for garbage collection
|
||||
/// </summary>
|
||||
public bool GCLowLatency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the GDB stub
|
||||
|
||||
@@ -112,6 +112,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
System.IgnoreControllerApplet.Value = cff.IgnoreApplet;
|
||||
System.SkipUserProfilesManager.Value = cff.SkipUserProfiles;
|
||||
System.UseHypervisor.Value = cff.UseHypervisor;
|
||||
System.GCLowLatency.Value = cff.GCLowLatency;
|
||||
|
||||
UI.GuiColumns.FavColumn.Value = shouldLoadFromFile ? cff.GuiColumns.FavColumn : UI.GuiColumns.FavColumn.Value;
|
||||
UI.GuiColumns.IconColumn.Value = shouldLoadFromFile ? cff.GuiColumns.IconColumn : UI.GuiColumns.IconColumn.Value;
|
||||
@@ -535,7 +536,8 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
{
|
||||
if (cff.AudioBackend is AudioBackend.SDL2)
|
||||
cff.AudioBackend = AudioBackend.SDL3;
|
||||
})
|
||||
}),
|
||||
(72, static cff => cff.GCLowLatency = false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,6 +417,11 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
/// Uses Hypervisor over JIT if available
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> UseHypervisor { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable low-latency garbage collection
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> GCLowLatency { get; private set; }
|
||||
|
||||
public SystemSection()
|
||||
{
|
||||
@@ -471,6 +476,8 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
AudioVolume.LogChangesToValue(nameof(AudioVolume));
|
||||
UseHypervisor = new ReactiveObject<bool>();
|
||||
UseHypervisor.LogChangesToValue(nameof(UseHypervisor));
|
||||
GCLowLatency = new ReactiveObject<bool>();
|
||||
GCLowLatency.LogChangesToValue(nameof(GCLowLatency));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
IgnoreApplet = System.IgnoreControllerApplet,
|
||||
SkipUserProfiles = System.SkipUserProfilesManager,
|
||||
UseHypervisor = System.UseHypervisor,
|
||||
GCLowLatency = System.GCLowLatency,
|
||||
GuiColumns = new GuiColumns
|
||||
{
|
||||
FavColumn = UI.GuiColumns.FavColumn,
|
||||
|
||||
@@ -2066,7 +2066,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
// Remove window chrome: WS_OVERLAPPEDWINDOW -> WS_POPUP | WS_VISIBLE
|
||||
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE,
|
||||
unchecked((nint)(Win32NativeInterop.WS_POPUP | Win32NativeInterop.WS_VISIBLE)));
|
||||
|
||||
|
||||
// TODO: why is this nullable
|
||||
Avalonia.Platform.Screen? screen = Window.Screens.ScreenFromVisual(Window);
|
||||
int w = screen?.Bounds.Width ?? 0;
|
||||
int h = screen?.Bounds.Height ?? 0;
|
||||
|
||||
@@ -286,6 +286,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
public bool IsVulkanSelected =>
|
||||
GraphicsBackendIndex == 1 || (GraphicsBackendIndex == 0 && !OperatingSystem.IsMacOS());
|
||||
public bool UseHypervisor { get; set; }
|
||||
public bool GCLowLatency { get; set; }
|
||||
public bool DisableP2P { get; set; }
|
||||
|
||||
public bool ShowDirtyHacks => ConfigurationState.Instance.Hacks.ShowDirtyHacks;
|
||||
@@ -689,6 +690,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
EnableLowPowerPptc = config.System.EnableLowPowerPtc;
|
||||
MemoryMode = (int)config.System.MemoryManagerMode.Value;
|
||||
UseHypervisor = config.System.UseHypervisor;
|
||||
GCLowLatency = config.System.GCLowLatency;
|
||||
TurboMultiplier = config.System.TickScalar;
|
||||
|
||||
// Graphics
|
||||
@@ -800,6 +802,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
config.System.EnableLowPowerPtc.Value = EnableLowPowerPptc;
|
||||
config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;
|
||||
config.System.UseHypervisor.Value = UseHypervisor;
|
||||
config.System.GCLowLatency.Value = GCLowLatency;
|
||||
config.System.TickScalar.Value = TurboMultiplier;
|
||||
|
||||
// Graphics
|
||||
|
||||
@@ -71,6 +71,11 @@
|
||||
<TextBlock Text="{ext:Locale SettingsTabSystemUseHypervisor}"
|
||||
ToolTip.Tip="{ext:Locale UseHypervisorTooltip}" />
|
||||
</CheckBox>
|
||||
<CheckBox
|
||||
IsChecked="{Binding GCLowLatency}"
|
||||
ToolTip.Tip="{ext:Locale GCLowLatencyTooltip}">
|
||||
<TextBlock Text="{ext:Locale SettingsTabSystemGCLowLatency}" />
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
<Separator Height="1" />
|
||||
<StackPanel
|
||||
|
||||
11
src/Ryujinx/runtimeconfig.template.json
Normal file
11
src/Ryujinx/runtimeconfig.template.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"configProperties": {
|
||||
"System.GC.Concurrent": true,
|
||||
"System.GC.Server": false,
|
||||
"System.GC.RetainVM": true,
|
||||
"System.Runtime.TieredCompilation.QuickJit": false,
|
||||
"System.Runtime.TieredCompilation.QuickJitForLoops": false,
|
||||
"DOTNET_ReadyToRun": false,
|
||||
"DOTNET_TieredPGO": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user