Compare commits

...

14 commits

Author SHA1 Message Date
MutantAura
c201ed6491
Merge 811c2651f2 into 6ce49a2dc7 2024-07-27 18:54:10 +09:00
Isaac Marovitz
6ce49a2dc7
Ava UI: Handle updates containing non numeric characters (#7043)
* Handle updates containing non numeric characters

Smh

Dont be stupid

* Use Berry’s method

* Thanks gdk

* Remove using
2024-07-25 16:44:33 -03:00
riperiperi
ccd330ba0f
Vulkan: Add missing barriers for texture to buffer copy (#7092)
This barrier has always been missing, but it only became apparent when #7012 merged.

I also added some barriers in case the target buffer used here is used by other commands, though right now it isn't.

Fixes a regression where water would turn white on AMD GPUs with the proprietary driver. May fix other issues on this driver.
2024-07-25 16:34:30 -03:00
MutantAura
811c2651f2 Keep OGL threading specific path and adjust warning to info log. 2024-04-25 18:00:49 +01:00
MutantAura
7e3f6af6c6 De-duplicate and simplify enum naming. 2024-04-21 16:55:01 +01:00
MutantAura
32628bb8a3 Add message to ArgumentException 2024-04-21 16:55:01 +01:00
MutantAura
190791a1c9 dotnet format fixes 2024-04-21 16:55:01 +01:00
MutantAura
965ee0d016 Further de-duplicate NVAPI interface code + GTK 2024-04-21 16:55:01 +01:00
MutantAura
1c4f8b8175 Add logging to the nvapi try-catch. 2024-04-21 16:55:00 +01:00
MutantAura
c1c8aaee0f Remove some line breaks and fix ID -> Id. 2024-04-21 16:55:00 +01:00
MutantAura
d1aa76d22d Remove whitespace via format. 2024-04-21 16:55:00 +01:00
MutantAura
9cf64e612f Add spacing back. 2024-04-21 16:55:00 +01:00
MutantAura
e2122a532d Remove unused usings... 2024-04-21 16:55:00 +01:00
MutantAura
2d14384a7d Adjust driver helper to more generic NVAPI interface and add DXGI present option. 2024-04-21 16:55:00 +01:00
11 changed files with 126 additions and 56 deletions

View file

@ -1,21 +1,28 @@
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging;
using System; using System;
namespace Ryujinx.Common.GraphicsDriver namespace Ryujinx.Common.GraphicsDriver
{ {
public static class DriverUtilities 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("mesa_glthread", enabled.ToString().ToLower());
Environment.SetEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0"); Environment.SetEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0");
ToggleNvDriverSetting(NvapiSettingId.OglThreadControlId, enabled);
}
public static void ToggleNvDriverSetting(NvapiSettingId id, bool enabled)
{
try try
{ {
NVThreadedOptimization.SetThreadedOptimization(enabled); NVDriverHelper.SetControlOption(id, enabled);
} }
catch 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 namespace Ryujinx.Common.GraphicsDriver.NVAPI
{ {
enum Nvapi : uint public enum NvapiSettingId : uint
{ {
OglThreadControlId = 0x20C1221E, OglThreadControlId = 0x20C1221E,
OglCplPreferDxPresentId = 0x20D690F8,
}
OglThreadControlDefault = 0, enum OglThreadControl : uint
OglThreadControlEnable = 1, {
OglThreadControlDisable = 2, 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)] [FieldOffset(0x4)]
public NvapiUnicodeString SettingName; public NvapiUnicodeString SettingName;
[FieldOffset(0x1004)] [FieldOffset(0x1004)]
public Nvapi SettingId; public NvapiSettingId SettingId;
[FieldOffset(0x1008)] [FieldOffset(0x1008)]
public NvdrsSettingType SettingType; public NvdrsSettingType SettingType;
[FieldOffset(0x100C)] [FieldOffset(0x100C)]

View file

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Common.GraphicsDriver namespace Ryujinx.Common.GraphicsDriver
{ {
static partial class NVThreadedOptimization static partial class NVDriverHelper
{ {
private const string ProfileName = "Ryujinx Nvidia Profile"; private const string ProfileName = "Ryujinx Nvidia Profile";
@ -49,6 +49,9 @@ namespace Ryujinx.Common.GraphicsDriver
private delegate int NvAPI_DRS_DestroySessionDelegate(IntPtr handle); private delegate int NvAPI_DRS_DestroySessionDelegate(IntPtr handle);
private static NvAPI_DRS_DestroySessionDelegate NvAPI_DRS_DestroySession; private static NvAPI_DRS_DestroySessionDelegate NvAPI_DRS_DestroySession;
private static IntPtr _handle;
private static nint _profileHandle;
private static bool _initialized; private static bool _initialized;
private static void Check(int status) 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_Initialize());
Check(NvAPI_DRS_CreateSession(out IntPtr handle)); Check(NvAPI_DRS_CreateSession(out IntPtr handle));
@ -98,7 +92,6 @@ namespace Ryujinx.Common.GraphicsDriver
Check(NvAPI_DRS_LoadSettings(handle)); Check(NvAPI_DRS_LoadSettings(handle));
// Check if the profile already exists. // Check if the profile already exists.
int status = NvAPI_DRS_FindProfileByName(handle, new NvapiUnicodeString(ProfileName), out nint profileHandle); int status = NvAPI_DRS_FindProfileByName(handle, new NvapiUnicodeString(ProfileName), out nint profileHandle);
if (status != 0) if (status != 0)
@ -126,10 +119,32 @@ namespace Ryujinx.Common.GraphicsDriver
Check(NvAPI_DRS_CreateApplication(handle, profileHandle, ref application)); 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() NvdrsSetting setting = new()
{ {
Version = MakeVersion<NvdrsSetting>(1), Version = MakeVersion<NvdrsSetting>(1),
SettingId = Nvapi.OglThreadControlId, SettingId = id,
SettingType = NvdrsSettingType.NvdrsDwordType, SettingType = NvdrsSettingType.NvdrsDwordType,
SettingLocation = NvdrsSettingLocation.NvdrsCurrentProfileLocation, SettingLocation = NvdrsSettingLocation.NvdrsCurrentProfileLocation,
IsCurrentPredefined = 0, IsCurrentPredefined = 0,
@ -138,11 +153,10 @@ namespace Ryujinx.Common.GraphicsDriver
PredefinedValue = targetValue, 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 private static T NvAPI_Delegate<T>(uint id) where T : class

View file

@ -667,8 +667,36 @@ namespace Ryujinx.Graphics.Vulkan
if (PrepareOutputBuffer(cbs, hostSize, buffer, out VkBuffer copyToBuffer, out BufferHolder tempCopyHolder)) if (PrepareOutputBuffer(cbs, hostSize, buffer, out VkBuffer copyToBuffer, out BufferHolder tempCopyHolder))
{ {
// No barrier necessary, as this is a temporary copy buffer.
offset = 0; offset = 0;
} }
else
{
BufferHolder.InsertBufferBarrier(
_gd,
cbs.CommandBuffer,
copyToBuffer,
BufferHolder.DefaultAccessFlags,
AccessFlags.TransferWriteBit,
PipelineStageFlags.AllCommandsBit,
PipelineStageFlags.TransferBit,
offset,
outSize);
}
InsertImageBarrier(
_gd.Api,
cbs.CommandBuffer,
image,
TextureStorage.DefaultAccessMask,
AccessFlags.TransferReadBit,
PipelineStageFlags.AllCommandsBit,
PipelineStageFlags.TransferBit,
Info.Format.ConvertAspectFlags(),
FirstLayer + layer,
FirstLevel + level,
1,
1);
CopyFromOrToBuffer(cbs.CommandBuffer, copyToBuffer, image, hostSize, true, layer, level, 1, 1, singleSlice: true, offset, stride); CopyFromOrToBuffer(cbs.CommandBuffer, copyToBuffer, image, hostSize, true, layer, level, 1, 1, singleSlice: true, offset, stride);
@ -677,6 +705,19 @@ namespace Ryujinx.Graphics.Vulkan
CopyDataToOutputBuffer(cbs, tempCopyHolder, autoBuffer, hostSize, range.Offset); CopyDataToOutputBuffer(cbs, tempCopyHolder, autoBuffer, hostSize, range.Offset);
tempCopyHolder.Dispose(); tempCopyHolder.Dispose();
} }
else
{
BufferHolder.InsertBufferBarrier(
_gd,
cbs.CommandBuffer,
copyToBuffer,
AccessFlags.TransferWriteBit,
BufferHolder.DefaultAccessFlags,
PipelineStageFlags.TransferBit,
PipelineStageFlags.AllCommandsBit,
offset,
outSize);
}
} }
private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer) private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer)

View file

@ -2,6 +2,7 @@ using Gtk;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.SystemInterop; using Ryujinx.Common.SystemInterop;
using Ryujinx.Modules; using Ryujinx.Modules;
@ -239,7 +240,10 @@ namespace Ryujinx
// Enable OGL multithreading on the driver, when available. // Enable OGL multithreading on the driver, when available.
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading; 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. // Initialize Gtk.
Application.Init(); Application.Init();

View file

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

View file

@ -5,6 +5,7 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.SystemInterop; using Ryujinx.Common.SystemInterop;
using Ryujinx.Modules; using Ryujinx.Modules;
@ -112,7 +113,10 @@ namespace Ryujinx.Ava
PrintSystemInfo(); PrintSystemInfo();
// Enable OGL multithreading on the driver, when available. // 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. // Check if keys exists.
if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys"))) if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys")))

View file

@ -1,21 +1,20 @@
using LibHac.Ns;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
namespace Ryujinx.Ava.UI.Models namespace Ryujinx.Ava.UI.Models
{ {
public class TitleUpdateModel public class TitleUpdateModel
{ {
public ApplicationControlProperty Control { get; } public uint Version { get; }
public string Path { get; } public string Path { get; }
public string Label { get; }
public string Label => LocaleManager.Instance.UpdateAndGetDynamicValue( public TitleUpdateModel(uint version, string displayVersion, string path)
System.IO.Path.GetExtension(Path)?.ToLower() == ".xci" ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel,
Control.DisplayVersionString.ToString()
);
public TitleUpdateModel(ApplicationControlProperty control, string path)
{ {
Control = control; Version = version;
Label = LocaleManager.Instance.UpdateAndGetDynamicValue(
System.IO.Path.GetExtension(path)?.ToLower() == ".xci" ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel,
displayVersion
);
Path = path; Path = path;
} }
} }

View file

@ -12,6 +12,7 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.GraphicsDriver.NVAPI;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
@ -545,7 +546,7 @@ namespace Ryujinx.Ava.UI.ViewModels
if (ConfigurationState.Instance.Graphics.BackendThreading != (BackendThreading)GraphicsBackendMultithreadingIndex) 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; config.Graphics.BackendThreading.Value = (BackendThreading)GraphicsBackendMultithreadingIndex;

View file

@ -131,26 +131,11 @@ namespace Ryujinx.Ava.UI.ViewModels
public void SortUpdates() public void SortUpdates()
{ {
var list = TitleUpdates.ToList(); var sortedUpdates = TitleUpdates.OrderByDescending(update => update.Version);
list.Sort((first, second) =>
{
if (string.IsNullOrEmpty(first.Control.DisplayVersionString.ToString()))
{
return -1;
}
if (string.IsNullOrEmpty(second.Control.DisplayVersionString.ToString()))
{
return 1;
}
return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
});
Views.Clear(); Views.Clear();
Views.Add(new BaseModel()); Views.Add(new BaseModel());
Views.AddRange(list); Views.AddRange(sortedUpdates);
if (SelectedUpdate == null) if (SelectedUpdate == null)
{ {
@ -204,7 +189,9 @@ namespace Ryujinx.Ava.UI.ViewModels
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure(); controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure(); nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
var update = new TitleUpdateModel(controlData, path); var displayVersion = controlData.DisplayVersionString.ToString();
var update = new TitleUpdateModel(content.Version.Version, displayVersion, path);
TitleUpdates.Add(update); TitleUpdates.Add(update);
if (selected) if (selected)