This commit is contained in:
MutantAura 2024-05-19 15:12:22 -05:00 committed by GitHub
commit 408f264cfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 72 additions and 29 deletions

View File

@ -1,21 +1,28 @@
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging;
using System;
namespace Ryujinx.Common.GraphicsDriver
{
public static class DriverUtilities
{
public static void ToggleOGLThreading(bool enabled)
public static void ToggleOglThreading(bool enabled)
{
Environment.SetEnvironmentVariable("mesa_glthread", enabled.ToString().ToLower());
Environment.SetEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0");
ToggleNvDriverSetting(NvapiSettingId.OglThreadControlId, enabled);
}
public static void ToggleNvDriverSetting(NvapiSettingId id, bool enabled)
{
try
{
NVThreadedOptimization.SetThreadedOptimization(enabled);
NVDriverHelper.SetControlOption(id, enabled);
}
catch
{
// NVAPI is not available, or couldn't change the application profile.
Logger.Info?.Print(LogClass.Application, "NVAPI was unreachable, no changes were made.");
}
}
}

View File

@ -1,11 +1,23 @@
namespace Ryujinx.Common.GraphicsDriver.NVAPI
{
enum Nvapi : uint
public enum NvapiSettingId : uint
{
OglThreadControlId = 0x20C1221E,
OglCplPreferDxPresentId = 0x20D690F8,
}
OglThreadControlDefault = 0,
OglThreadControlEnable = 1,
OglThreadControlDisable = 2,
enum OglThreadControl : uint
{
Default = 0,
Enabled = 1,
Disabled = 2,
}
// Only present in driver versions >= 526.47
enum OglCplDxPresent : uint
{
Disabled = 0,
Enabled = 1,
Default = 2,
}
}

View File

@ -26,7 +26,7 @@ namespace Ryujinx.Common.GraphicsDriver.NVAPI
[FieldOffset(0x4)]
public NvapiUnicodeString SettingName;
[FieldOffset(0x1004)]
public Nvapi SettingId;
public NvapiSettingId SettingId;
[FieldOffset(0x1008)]
public NvdrsSettingType SettingType;
[FieldOffset(0x100C)]

View File

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Common.GraphicsDriver
{
static partial class NVThreadedOptimization
static partial class NVDriverHelper
{
private const string ProfileName = "Ryujinx Nvidia Profile";
@ -49,6 +49,9 @@ namespace Ryujinx.Common.GraphicsDriver
private delegate int NvAPI_DRS_DestroySessionDelegate(IntPtr handle);
private static NvAPI_DRS_DestroySessionDelegate NvAPI_DRS_DestroySession;
private static IntPtr _handle;
private static nint _profileHandle;
private static bool _initialized;
private static void Check(int status)
@ -80,17 +83,8 @@ namespace Ryujinx.Common.GraphicsDriver
}
}
private static uint MakeVersion<T>(uint version) where T : unmanaged
private static void SetupNvProfile()
{
return (uint)Unsafe.SizeOf<T>() | version << 16;
}
public static void SetThreadedOptimization(bool enabled)
{
Initialize();
uint targetValue = (uint)(enabled ? Nvapi.OglThreadControlEnable : Nvapi.OglThreadControlDisable);
Check(NvAPI_Initialize());
Check(NvAPI_DRS_CreateSession(out IntPtr handle));
@ -98,7 +92,6 @@ namespace Ryujinx.Common.GraphicsDriver
Check(NvAPI_DRS_LoadSettings(handle));
// Check if the profile already exists.
int status = NvAPI_DRS_FindProfileByName(handle, new NvapiUnicodeString(ProfileName), out nint profileHandle);
if (status != 0)
@ -126,10 +119,32 @@ namespace Ryujinx.Common.GraphicsDriver
Check(NvAPI_DRS_CreateApplication(handle, profileHandle, ref application));
}
_handle = handle;
_profileHandle = profileHandle;
}
private static uint MakeVersion<T>(uint version) where T : unmanaged
{
return (uint)Unsafe.SizeOf<T>() | version << 16;
}
public static void SetControlOption(NvapiSettingId id, bool enabled)
{
Initialize();
SetupNvProfile();
uint targetValue = id switch
{
NvapiSettingId.OglThreadControlId => (uint)(enabled ? OglThreadControl.Enabled : OglThreadControl.Disabled),
NvapiSettingId.OglCplPreferDxPresentId => (uint)(enabled ? OglCplDxPresent.Enabled : OglCplDxPresent.Disabled),
_ => throw new ArgumentException($"Invalid NVAPI setting id: 0x{id:X}"),
};
NvdrsSetting setting = new()
{
Version = MakeVersion<NvdrsSetting>(1),
SettingId = Nvapi.OglThreadControlId,
SettingId = id,
SettingType = NvdrsSettingType.NvdrsDwordType,
SettingLocation = NvdrsSettingLocation.NvdrsCurrentProfileLocation,
IsCurrentPredefined = 0,
@ -138,11 +153,10 @@ namespace Ryujinx.Common.GraphicsDriver
PredefinedValue = targetValue,
};
Check(NvAPI_DRS_SetSetting(handle, profileHandle, ref setting));
Check(NvAPI_DRS_SetSetting(_handle, _profileHandle, ref setting));
Check(NvAPI_DRS_SaveSettings(_handle));
Check(NvAPI_DRS_SaveSettings(handle));
NvAPI_DRS_DestroySession(handle);
NvAPI_DRS_DestroySession(_handle);
}
private static T NvAPI_Delegate<T>(uint id) where T : class

View File

@ -2,6 +2,7 @@ using Gtk;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging;
using Ryujinx.Common.SystemInterop;
using Ryujinx.Modules;
@ -238,7 +239,10 @@ namespace Ryujinx
// Enable OGL multithreading on the driver, when available.
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
DriverUtilities.ToggleOGLThreading(threadingMode == BackendThreading.Off);
DriverUtilities.ToggleOglThreading(threadingMode == BackendThreading.Off);
// Enable DXGI present mode on the driver, when available.
DriverUtilities.ToggleNvDriverSetting(NvapiSettingId.OglCplPreferDxPresentId, true);
// Initialize Gtk.
Application.Init();

View File

@ -7,6 +7,7 @@ using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
using Ryujinx.UI.Common.Configuration;
@ -610,7 +611,7 @@ namespace Ryujinx.UI.Windows
BackendThreading backendThreading = Enum.Parse<BackendThreading>(_galThreading.ActiveId);
if (ConfigurationState.Instance.Graphics.BackendThreading != backendThreading)
{
DriverUtilities.ToggleOGLThreading(backendThreading == BackendThreading.Off);
DriverUtilities.ToggleOglThreading(backendThreading == BackendThreading.Off);
}
ConfigurationState.Instance.Logger.EnableError.Value = _errorLogToggle.Active;

View File

@ -5,6 +5,7 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging;
using Ryujinx.Common.SystemInterop;
using Ryujinx.Modules;
@ -112,7 +113,10 @@ namespace Ryujinx.Ava
PrintSystemInfo();
// Enable OGL multithreading on the driver, when available.
DriverUtilities.ToggleOGLThreading(ConfigurationState.Instance.Graphics.BackendThreading == BackendThreading.Off);
DriverUtilities.ToggleOglThreading(ConfigurationState.Instance.Graphics.BackendThreading == BackendThreading.Off);
// Enable Dxgi present on the driver, when available.
DriverUtilities.ToggleNvDriverSetting(NvapiSettingId.OglCplPreferDxPresentId, true);
// Check if keys exists.
if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys")))

View File

@ -12,6 +12,7 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE.FileSystem;
@ -545,7 +546,7 @@ namespace Ryujinx.Ava.UI.ViewModels
if (ConfigurationState.Instance.Graphics.BackendThreading != (BackendThreading)GraphicsBackendMultithreadingIndex)
{
DriverUtilities.ToggleOGLThreading(GraphicsBackendMultithreadingIndex == (int)BackendThreading.Off);
DriverUtilities.ToggleOglThreading(GraphicsBackendMultithreadingIndex == (int)BackendThreading.Off);
}
config.Graphics.BackendThreading.Value = (BackendThreading)GraphicsBackendMultithreadingIndex;