Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 20bae91376 | |||
| fafb99c702 | |||
| df9e6e4812 | |||
| c279c7d5de | |||
| 566f3d079a | |||
| d7707d4176 | |||
| 753ca01c0d | |||
| 7a9b62884a | |||
| de9faf183a | |||
| 5aedeebfe9 | |||
| 0bf7c5dfa2 | |||
| 11bc32d98e | |||
| 063430ea16 | |||
| 65f08caaa3 | |||
| f225b18c05 | |||
| d8549f687b | |||
| 5ab50680b4 | |||
| a0edc5c2b0 | |||
| 158ea7b4d6 | |||
| 8bc3de8303 | |||
| c812106611 | |||
| 5c67efd291 | |||
| b2354768c4 | |||
| 745bd91250 | |||
| 11e4d8f970 | |||
| 07ab817557 | |||
| 0e8a41b198 | |||
| 969e94f913 | |||
| 2e2d26d49d | |||
| 774edb7b29 | |||
| 55536f5d78 | |||
| b2eecd28ce | |||
| fe43c32e60 | |||
| 8117e160c2 | |||
| bf713a80d6 | |||
| b38b5a1e70 | |||
| 2d7700949c | |||
| ea2287af03 | |||
| 37af8c70aa | |||
| 50cee3fd19 | |||
| a46aacf2e2 | |||
| ad9d6588e8 | |||
| 38ef65aae0 | |||
| 9f94aa1c79 | |||
| 2c9a26c11c | |||
| a4a15a4c80 | |||
| cc3b95eee1 | |||
| 2ab806f759 | |||
| 6d75410bd2 | |||
| 196b2eaf66 | |||
| 82fe519766 | |||
| ff05e03cc8 | |||
| e18c6d90c4 | |||
| 9075a3960b | |||
| 3cf54987d2 | |||
| 9c12f52805 | |||
| 059fc83d4d | |||
| 04ce7fb764 | |||
| 359852b5c0 | |||
| 796674d9cf | |||
| 4efe24a3bc |
@@ -2483,7 +2483,7 @@
|
|||||||
0100A5200C2E0000,"Safety First!",,playable,2021-01-06 09:05:23
|
0100A5200C2E0000,"Safety First!",,playable,2021-01-06 09:05:23
|
||||||
0100A51013530000,"SaGa Frontier Remastered",nvdec,playable,2022-11-03 13:54:56
|
0100A51013530000,"SaGa Frontier Remastered",nvdec,playable,2022-11-03 13:54:56
|
||||||
010003A00D0B4000,"SaGa SCARLET GRACE: AMBITIONS™",,playable,2022-10-06 13:20:31
|
010003A00D0B4000,"SaGa SCARLET GRACE: AMBITIONS™",,playable,2022-10-06 13:20:31
|
||||||
01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN,playable,2023-12-04 18:33:37
|
01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN;deadlock,ingame,2025-02-02 16:57:53
|
||||||
0100DE600BEEE000,"SAINTS ROW®: THE THIRD™ - THE FULL PACKAGE",slow;LAN,playable,2023-08-24 02:40:58
|
0100DE600BEEE000,"SAINTS ROW®: THE THIRD™ - THE FULL PACKAGE",slow;LAN,playable,2023-08-24 02:40:58
|
||||||
01007F000EB36000,"Sakai and...",nvdec,playable,2022-12-15 13:53:19
|
01007F000EB36000,"Sakai and...",nvdec,playable,2022-12-15 13:53:19
|
||||||
0100B1400E8FE000,"Sakuna: Of Rice and Ruin",,playable,2023-07-24 13:47:13
|
0100B1400E8FE000,"Sakuna: Of Rice and Ruin",,playable,2023-07-24 13:47:13
|
||||||
|
|||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
using ARMeilleure.CodeGen.Unwinding;
|
using ARMeilleure.CodeGen.Unwinding;
|
||||||
using ARMeilleure.Translation.Cache;
|
using ARMeilleure.Translation.Cache;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen
|
namespace ARMeilleure.CodeGen
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace ARMeilleure.Memory
|
|||||||
public const int DefaultGranularity = 65536; // Mapping granularity in Windows.
|
public const int DefaultGranularity = 65536; // Mapping granularity in Windows.
|
||||||
|
|
||||||
public IJitMemoryBlock Block { get; }
|
public IJitMemoryBlock Block { get; }
|
||||||
|
public IJitMemoryAllocator Allocator { get; }
|
||||||
|
|
||||||
public nint Pointer => Block.Pointer;
|
public nint Pointer => Block.Pointer;
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ namespace ARMeilleure.Memory
|
|||||||
granularity = DefaultGranularity;
|
granularity = DefaultGranularity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Allocator = allocator;
|
||||||
Block = allocator.Reserve(maxSize);
|
Block = allocator.Reserve(maxSize);
|
||||||
_maxSize = maxSize;
|
_maxSize = maxSize;
|
||||||
_sizeGranularity = granularity;
|
_sizeGranularity = granularity;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using Ryujinx.Common.Memory.PartialUnmaps;
|
using Ryujinx.Common.Memory.PartialUnmaps;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace ARMeilleure.State
|
namespace ARMeilleure.State
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using ARMeilleure.Instructions;
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ using ARMeilleure.CodeGen;
|
|||||||
using ARMeilleure.CodeGen.Unwinding;
|
using ARMeilleure.CodeGen.Unwinding;
|
||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using ARMeilleure.Native;
|
using ARMeilleure.Native;
|
||||||
|
using Humanizer;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -18,9 +20,8 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
private static readonly int _pageMask = _pageSize - 1;
|
private static readonly int _pageMask = _pageSize - 1;
|
||||||
|
|
||||||
private const int CodeAlignment = 4; // Bytes.
|
private const int CodeAlignment = 4; // Bytes.
|
||||||
private const int CacheSize = 2047 * 1024 * 1024;
|
private const int CacheSize = 128 * 1024 * 1024;
|
||||||
|
|
||||||
private static ReservedRegion _jitRegion;
|
|
||||||
private static JitCacheInvalidation _jitCacheInvalidator;
|
private static JitCacheInvalidation _jitCacheInvalidator;
|
||||||
|
|
||||||
private static CacheMemoryAllocator _cacheAllocator;
|
private static CacheMemoryAllocator _cacheAllocator;
|
||||||
@@ -30,6 +31,9 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
private static readonly Lock _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
|
||||||
|
private static readonly List<ReservedRegion> _jitRegions = new();
|
||||||
|
private static int _activeRegionIndex = 0;
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
[LibraryImport("kernel32.dll", SetLastError = true)]
|
[LibraryImport("kernel32.dll", SetLastError = true)]
|
||||||
public static partial nint FlushInstructionCache(nint hProcess, nint lpAddress, nuint dwSize);
|
public static partial nint FlushInstructionCache(nint hProcess, nint lpAddress, nuint dwSize);
|
||||||
@@ -48,7 +52,9 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_jitRegion = new ReservedRegion(allocator, CacheSize);
|
var firstRegion = new ReservedRegion(allocator, CacheSize);
|
||||||
|
_jitRegions.Add(firstRegion);
|
||||||
|
_activeRegionIndex = 0;
|
||||||
|
|
||||||
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
@@ -59,7 +65,9 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
{
|
{
|
||||||
JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, CacheSize, _jitRegion.Pointer + Allocate(_pageSize));
|
JitUnwindWindows.InstallFunctionTableHandler(
|
||||||
|
firstRegion.Pointer, CacheSize, firstRegion.Pointer + Allocate(_pageSize)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
@@ -75,8 +83,8 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
Debug.Assert(_initialized);
|
Debug.Assert(_initialized);
|
||||||
|
|
||||||
int funcOffset = Allocate(code.Length);
|
int funcOffset = Allocate(code.Length);
|
||||||
|
ReservedRegion targetRegion = _jitRegions[_activeRegionIndex];
|
||||||
nint funcPtr = _jitRegion.Pointer + funcOffset;
|
nint funcPtr = targetRegion.Pointer + funcOffset;
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
{
|
{
|
||||||
@@ -90,9 +98,9 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReprotectAsWritable(funcOffset, code.Length);
|
ReprotectAsWritable(targetRegion, funcOffset, code.Length);
|
||||||
Marshal.Copy(code, 0, funcPtr, code.Length);
|
Marshal.Copy(code, 0, funcPtr, code.Length);
|
||||||
ReprotectAsExecutable(funcOffset, code.Length);
|
ReprotectAsExecutable(targetRegion, funcOffset, code.Length);
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
{
|
{
|
||||||
@@ -116,52 +124,83 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
{
|
{
|
||||||
Debug.Assert(_initialized);
|
Debug.Assert(_initialized);
|
||||||
|
|
||||||
int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64());
|
foreach (var region in _jitRegions)
|
||||||
|
|
||||||
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
|
||||||
{
|
{
|
||||||
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
if (pointer.ToInt64() < region.Pointer.ToInt64() ||
|
||||||
_cacheEntries.RemoveAt(entryIndex);
|
pointer.ToInt64() >= (region.Pointer + CacheSize).ToInt64())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int funcOffset = (int)(pointer.ToInt64() - region.Pointer.ToInt64());
|
||||||
|
|
||||||
|
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
||||||
|
{
|
||||||
|
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
||||||
|
_cacheEntries.RemoveAt(entryIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReprotectAsWritable(int offset, int size)
|
private static void ReprotectAsWritable(ReservedRegion region, int offset, int size)
|
||||||
{
|
{
|
||||||
int endOffs = offset + size;
|
int endOffs = offset + size;
|
||||||
|
|
||||||
int regionStart = offset & ~_pageMask;
|
int regionStart = offset & ~_pageMask;
|
||||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||||
|
|
||||||
_jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
region.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReprotectAsExecutable(int offset, int size)
|
private static void ReprotectAsExecutable(ReservedRegion region, int offset, int size)
|
||||||
{
|
{
|
||||||
int endOffs = offset + size;
|
int endOffs = offset + size;
|
||||||
|
|
||||||
int regionStart = offset & ~_pageMask;
|
int regionStart = offset & ~_pageMask;
|
||||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||||
|
|
||||||
_jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
region.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Allocate(int codeSize)
|
private static int Allocate(int codeSize)
|
||||||
{
|
{
|
||||||
codeSize = AlignCodeSize(codeSize);
|
codeSize = AlignCodeSize(codeSize);
|
||||||
|
|
||||||
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
|
||||||
|
|
||||||
if (allocOffset < 0)
|
|
||||||
{
|
{
|
||||||
throw new OutOfMemoryException("JIT Cache exhausted.");
|
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
||||||
|
|
||||||
|
if (allocOffset >= 0)
|
||||||
|
{
|
||||||
|
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||||
|
_activeRegionIndex = i;
|
||||||
|
return allocOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
int exhaustedRegion = _activeRegionIndex;
|
||||||
|
var newRegion = new ReservedRegion(_jitRegions[0].Allocator, CacheSize);
|
||||||
|
_jitRegions.Add(newRegion);
|
||||||
|
_activeRegionIndex = _jitRegions.Count - 1;
|
||||||
|
|
||||||
|
int newRegionNumber = _activeRegionIndex;
|
||||||
|
|
||||||
return allocOffset;
|
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||||
|
|
||||||
|
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||||
|
|
||||||
|
int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
|
||||||
|
if (allocOffsetNew < 0)
|
||||||
|
{
|
||||||
|
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
|
||||||
|
}
|
||||||
|
|
||||||
|
newRegion.ExpandIfNeeded((ulong)allocOffsetNew + (ulong)codeSize);
|
||||||
|
return allocOffsetNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static int AlignCodeSize(int codeSize)
|
private static int AlignCodeSize(int codeSize)
|
||||||
{
|
{
|
||||||
return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
|
return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
|
||||||
@@ -185,18 +224,21 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0, default));
|
foreach (var region in _jitRegions)
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
{
|
{
|
||||||
index = ~index - 1;
|
int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0, default));
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
entry = _cacheEntries[index];
|
index = ~index - 1;
|
||||||
entryIndex = index;
|
}
|
||||||
return true;
|
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
entry = _cacheEntries[index];
|
||||||
|
entryIndex = index;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ARMeilleure.Translation.Cache
|
namespace ARMeilleure.Translation.Cache
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
namespace ARMeilleure.Translation
|
||||||
{
|
{
|
||||||
class DelegateInfo
|
class DelegateInfo
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
namespace ARMeilleure.Translation
|
||||||
{
|
{
|
||||||
delegate void DispatcherFunction(nint nativeContext, ulong startAddress);
|
delegate void DispatcherFunction(nint nativeContext, ulong startAddress);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
namespace ARMeilleure.Translation
|
||||||
{
|
{
|
||||||
delegate ulong GuestFunction(nint nativeContextPtr);
|
delegate ulong GuestFunction(nint nativeContextPtr);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.Common;
|
using ARMeilleure.Common;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
namespace ARMeilleure.Translation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using ARMeilleure.Diagnostics;
|
|||||||
using ARMeilleure.Instructions;
|
using ARMeilleure.Instructions;
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using ARMeilleure.Signal;
|
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using ARMeilleure.Translation.Cache;
|
using ARMeilleure.Translation.Cache;
|
||||||
using ARMeilleure.Translation.PTC;
|
using ARMeilleure.Translation.PTC;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using ARMeilleure.IntermediateRepresentation;
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using ARMeilleure.Translation.Cache;
|
using ARMeilleure.Translation.Cache;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
|
using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Ryujinx.Audio.Common;
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Backends.Common
|
namespace Ryujinx.Audio.Backends.Common
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using CpuAddress = System.UInt64;
|
using CpuAddress = System.UInt64;
|
||||||
using DspAddress = System.UInt64;
|
using DspAddress = System.UInt64;
|
||||||
|
|||||||
@@ -6,4 +6,16 @@ namespace Ryujinx.Common.Configuration
|
|||||||
Unbounded,
|
Unbounded,
|
||||||
Custom
|
Custom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class VSyncModeExtensions
|
||||||
|
{
|
||||||
|
public static VSyncMode Next(this VSyncMode vsync, bool customEnabled = false) =>
|
||||||
|
vsync switch
|
||||||
|
{
|
||||||
|
VSyncMode.Switch => customEnabled ? VSyncMode.Custom : VSyncMode.Unbounded,
|
||||||
|
VSyncMode.Unbounded => VSyncMode.Switch,
|
||||||
|
VSyncMode.Custom => VSyncMode.Unbounded,
|
||||||
|
_ => VSyncMode.Switch
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Helper
|
||||||
|
{
|
||||||
|
public static partial class Patterns
|
||||||
|
{
|
||||||
|
#region Accessors
|
||||||
|
|
||||||
|
public static readonly Regex Numeric = NumericRegex();
|
||||||
|
|
||||||
|
public static readonly Regex AmdGcn = AmdGcnRegex();
|
||||||
|
public static readonly Regex NvidiaConsumerClass = NvidiaConsumerClassRegex();
|
||||||
|
|
||||||
|
public static readonly Regex DomainLp1Ns = DomainLp1NsRegex();
|
||||||
|
public static readonly Regex DomainLp1Lp1Npln = DomainLp1Lp1NplnRegex();
|
||||||
|
public static readonly Regex DomainLp1Znc = DomainLp1ZncRegex();
|
||||||
|
public static readonly Regex DomainSbApi = DomainSbApiRegex();
|
||||||
|
public static readonly Regex DomainSbAccounts = DomainSbAccountsRegex();
|
||||||
|
public static readonly Regex DomainAccounts = DomainAccountsRegex();
|
||||||
|
|
||||||
|
public static readonly Regex Module = ModuleRegex();
|
||||||
|
public static readonly Regex FsSdk = FsSdkRegex();
|
||||||
|
public static readonly Regex SdkMw = SdkMwRegex();
|
||||||
|
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
|
public static readonly Regex CJK = CJKRegex();
|
||||||
|
|
||||||
|
public static readonly Regex LdnPassphrase = LdnPassphraseRegex();
|
||||||
|
|
||||||
|
public static readonly Regex CleanText = CleanTextRegex();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Generated pattern stubs
|
||||||
|
|
||||||
|
#region Numeric validation
|
||||||
|
|
||||||
|
[GeneratedRegex("[0-9]|.")]
|
||||||
|
internal static partial Regex NumericRegex();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GPU names
|
||||||
|
|
||||||
|
[GeneratedRegex(
|
||||||
|
"Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")]
|
||||||
|
internal static partial Regex AmdGcnRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")]
|
||||||
|
internal static partial Regex NvidiaConsumerClassRegex();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DNS blocking
|
||||||
|
|
||||||
|
public static readonly Regex[] BlockedHosts =
|
||||||
|
[
|
||||||
|
DomainLp1Ns,
|
||||||
|
DomainLp1Lp1Npln,
|
||||||
|
DomainLp1Znc,
|
||||||
|
DomainSbApi,
|
||||||
|
DomainSbAccounts,
|
||||||
|
DomainAccounts
|
||||||
|
];
|
||||||
|
|
||||||
|
const RegexOptions DnsRegexOpts =
|
||||||
|
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", DnsRegexOpts)]
|
||||||
|
internal static partial Regex DomainLp1NsRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", DnsRegexOpts)]
|
||||||
|
internal static partial Regex DomainLp1Lp1NplnRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", DnsRegexOpts)]
|
||||||
|
internal static partial Regex DomainLp1ZncRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", DnsRegexOpts)]
|
||||||
|
internal static partial Regex DomainSbApiRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", DnsRegexOpts)]
|
||||||
|
internal static partial Regex DomainSbAccountsRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^accounts\.nintendo\.com$", DnsRegexOpts)]
|
||||||
|
internal static partial Regex DomainAccountsRegex();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Executable information
|
||||||
|
|
||||||
|
[GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
|
||||||
|
internal static partial Regex ModuleRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"sdk_version: ([0-9.]*)")]
|
||||||
|
internal static partial Regex FsSdkRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"SDK MW[ -~]*")]
|
||||||
|
internal static partial Regex SdkMwRegex();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region CJK
|
||||||
|
|
||||||
|
[GeneratedRegex(
|
||||||
|
"\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")]
|
||||||
|
private static partial Regex CJKRegex();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[GeneratedRegex("Ryujinx-[0-9a-f]{8}")]
|
||||||
|
private static partial Regex LdnPassphraseRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")]
|
||||||
|
private static partial Regex CleanTextRegex();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,14 +10,18 @@ namespace Ryujinx.Common.Helper
|
|||||||
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
||||||
public static bool IsWindows => OperatingSystem.IsWindows();
|
public static bool IsWindows => OperatingSystem.IsWindows();
|
||||||
public static bool IsLinux => OperatingSystem.IsLinux();
|
public static bool IsLinux => OperatingSystem.IsLinux();
|
||||||
|
|
||||||
|
public static bool IsArm => RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
||||||
|
|
||||||
|
public static bool IsX64 => RuntimeInformation.OSArchitecture is Architecture.X64;
|
||||||
|
|
||||||
public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64;
|
public static bool IsIntelMac => IsMacOS && IsX64;
|
||||||
public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
public static bool IsArmMac => IsMacOS && IsArm;
|
||||||
|
|
||||||
public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
public static bool IsX64Windows => IsWindows && IsX64;
|
||||||
public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
public static bool IsArmWindows => IsWindows && IsArm;
|
||||||
|
|
||||||
public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
public static bool IsX64Linux => IsLinux && IsX64;
|
||||||
public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
public static bool IsArmLinux => IsLinux && IsArmMac;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Ryujinx.Common.Configuration;
|
|||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common
|
namespace Ryujinx.Common
|
||||||
{
|
{
|
||||||
@@ -30,10 +29,11 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public static readonly string[] GreatMetalTitles =
|
public static readonly string[] GreatMetalTitles =
|
||||||
[
|
[
|
||||||
"010076f0049a2000", // Bayonetta
|
"01009b500007c000", // ARMS
|
||||||
"0100a5c00d162000", // Cuphead
|
"0100a5c00d162000", // Cuphead
|
||||||
"010023800d64a000", // Deltarune
|
"010023800d64a000", // Deltarune
|
||||||
"01003a30012c0000", // LEGO City Undercover
|
"01003a30012c0000", // LEGO City Undercover
|
||||||
|
"010048701995e000", // Luigi's Manion 2 HD
|
||||||
"010028600EBDA000", // Mario 3D World
|
"010028600EBDA000", // Mario 3D World
|
||||||
"0100152000022000", // Mario Kart 8 Deluxe
|
"0100152000022000", // Mario Kart 8 Deluxe
|
||||||
"010075a016a3a000", // Persona 4 Arena Ultimax
|
"010075a016a3a000", // Persona 4 Arena Ultimax
|
||||||
@@ -47,11 +47,16 @@ namespace Ryujinx.Common
|
|||||||
"01006f8002326000", // Animal Crossings: New Horizons
|
"01006f8002326000", // Animal Crossings: New Horizons
|
||||||
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
||||||
"01009510001ca000", // Fast RMX
|
"01009510001ca000", // Fast RMX
|
||||||
"01005CA01580E000", // Persona 5 Royale
|
"01005CA01580E000", // Persona 5 Royal
|
||||||
|
"0100b880154fc000", // Persona 5 The Royal (Japan)
|
||||||
|
"010015100b514000", // Super Mario Bros. Wonder
|
||||||
"0100000000010000", // Super Mario Odyssey
|
"0100000000010000", // Super Mario Odyssey
|
||||||
|
|
||||||
//Isaac claims it has a issue in level 2, but I am not able to replicate it on my M3. More testing would be appreciated:
|
// Further testing is appreciated, I did not test the entire game:
|
||||||
"010015100b514000", // Super Mario Bros. Wonder
|
"01007300020fa000", // Astral Chain
|
||||||
|
"010076f0049a2000", // Bayonetta
|
||||||
|
"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
|
||||||
|
"0100f4300bf2c000", // New Pokemon Snap
|
||||||
];
|
];
|
||||||
|
|
||||||
public static string GetDiscordGameAsset(string titleId)
|
public static string GetDiscordGameAsset(string titleId)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Ryujinx.Memory.Tracking;
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using ARMeilleure.Common;
|
|||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using Ryujinx.Cpu.Signal;
|
using Ryujinx.Cpu.Signal;
|
||||||
using Ryujinx.Memory;
|
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.Jit
|
namespace Ryujinx.Cpu.Jit
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Ryujinx.Memory.Tracking;
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using Ryujinx.Memory.Tracking;
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.Jit
|
namespace Ryujinx.Cpu.Jit
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using ARMeilleure.Memory;
|
|||||||
using Ryujinx.Cpu.LightningJit.Arm32;
|
using Ryujinx.Cpu.LightningJit.Arm32;
|
||||||
using Ryujinx.Cpu.LightningJit.Arm64;
|
using Ryujinx.Cpu.LightningJit.Arm64;
|
||||||
using Ryujinx.Cpu.LightningJit.State;
|
using Ryujinx.Cpu.LightningJit.State;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit
|
namespace Ryujinx.Cpu.LightningJit
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using ARMeilleure.Common;
|
|||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
using Ryujinx.Cpu.LightningJit.CodeGen;
|
||||||
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
using Ryujinx.Cpu.LightningJit.CodeGen;
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||||
{
|
{
|
||||||
static class InstEmitVfpMove
|
static class InstEmitVfpMove
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit.Arm64
|
namespace Ryujinx.Cpu.LightningJit.Arm64
|
||||||
{
|
{
|
||||||
static class SysUtils
|
static class SysUtils
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using ARMeilleure.Memory;
|
|||||||
using Ryujinx.Cpu.LightningJit.CodeGen;
|
using Ryujinx.Cpu.LightningJit.CodeGen;
|
||||||
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
||||||
using Ryujinx.Cpu.LightningJit.Graph;
|
using Ryujinx.Cpu.LightningJit.Graph;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
|
using Humanizer;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -15,9 +17,8 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
private static readonly int _pageMask = _pageSize - 1;
|
private static readonly int _pageMask = _pageSize - 1;
|
||||||
|
|
||||||
private const int CodeAlignment = 4; // Bytes.
|
private const int CodeAlignment = 4; // Bytes.
|
||||||
private const int CacheSize = 2047 * 1024 * 1024;
|
private const int CacheSize = 128 * 1024 * 1024;
|
||||||
|
|
||||||
private static ReservedRegion _jitRegion;
|
|
||||||
private static JitCacheInvalidation _jitCacheInvalidator;
|
private static JitCacheInvalidation _jitCacheInvalidator;
|
||||||
|
|
||||||
private static CacheMemoryAllocator _cacheAllocator;
|
private static CacheMemoryAllocator _cacheAllocator;
|
||||||
@@ -26,6 +27,8 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
|
|
||||||
private static readonly Lock _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
private static readonly List<ReservedRegion> _jitRegions = new();
|
||||||
|
private static int _activeRegionIndex = 0;
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
[LibraryImport("kernel32.dll", SetLastError = true)]
|
[LibraryImport("kernel32.dll", SetLastError = true)]
|
||||||
@@ -45,7 +48,9 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_jitRegion = new ReservedRegion(allocator, CacheSize);
|
var firstRegion = new ReservedRegion(allocator, CacheSize);
|
||||||
|
_jitRegions.Add(firstRegion);
|
||||||
|
_activeRegionIndex = 0;
|
||||||
|
|
||||||
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
@@ -65,8 +70,8 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
Debug.Assert(_initialized);
|
Debug.Assert(_initialized);
|
||||||
|
|
||||||
int funcOffset = Allocate(code.Length);
|
int funcOffset = Allocate(code.Length);
|
||||||
|
ReservedRegion targetRegion = _jitRegions[_activeRegionIndex];
|
||||||
nint funcPtr = _jitRegion.Pointer + funcOffset;
|
nint funcPtr = targetRegion.Pointer + funcOffset;
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
{
|
{
|
||||||
@@ -80,18 +85,11 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReprotectAsWritable(funcOffset, code.Length);
|
ReprotectAsWritable(targetRegion, funcOffset, code.Length);
|
||||||
code.CopyTo(new Span<byte>((void*)funcPtr, code.Length));
|
Marshal.Copy(code.ToArray(), 0, funcPtr, code.Length);
|
||||||
ReprotectAsExecutable(funcOffset, code.Length);
|
ReprotectAsExecutable(targetRegion, funcOffset, code.Length);
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
_jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length);
|
||||||
{
|
|
||||||
FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (nuint)code.Length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Add(funcOffset, code.Length);
|
Add(funcOffset, code.Length);
|
||||||
@@ -106,50 +104,80 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
{
|
{
|
||||||
Debug.Assert(_initialized);
|
Debug.Assert(_initialized);
|
||||||
|
|
||||||
int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64());
|
foreach (var region in _jitRegions)
|
||||||
|
|
||||||
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
|
||||||
{
|
{
|
||||||
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
if (pointer.ToInt64() < region.Pointer.ToInt64() ||
|
||||||
_cacheEntries.RemoveAt(entryIndex);
|
pointer.ToInt64() >= (region.Pointer + CacheSize).ToInt64())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int funcOffset = (int)(pointer.ToInt64() - region.Pointer.ToInt64());
|
||||||
|
|
||||||
|
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
|
||||||
|
{
|
||||||
|
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
|
||||||
|
_cacheEntries.RemoveAt(entryIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReprotectAsWritable(int offset, int size)
|
private static void ReprotectAsWritable(ReservedRegion region, int offset, int size)
|
||||||
{
|
{
|
||||||
int endOffs = offset + size;
|
int endOffs = offset + size;
|
||||||
|
|
||||||
int regionStart = offset & ~_pageMask;
|
int regionStart = offset & ~_pageMask;
|
||||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||||
|
|
||||||
_jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
region.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReprotectAsExecutable(int offset, int size)
|
private static void ReprotectAsExecutable(ReservedRegion region, int offset, int size)
|
||||||
{
|
{
|
||||||
int endOffs = offset + size;
|
int endOffs = offset + size;
|
||||||
|
|
||||||
int regionStart = offset & ~_pageMask;
|
int regionStart = offset & ~_pageMask;
|
||||||
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
|
||||||
|
|
||||||
_jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
region.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Allocate(int codeSize)
|
private static int Allocate(int codeSize)
|
||||||
{
|
{
|
||||||
codeSize = AlignCodeSize(codeSize);
|
codeSize = AlignCodeSize(codeSize);
|
||||||
|
|
||||||
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
|
||||||
|
|
||||||
if (allocOffset < 0)
|
|
||||||
{
|
{
|
||||||
throw new OutOfMemoryException("JIT Cache exhausted.");
|
int allocOffset = _cacheAllocator.Allocate(codeSize);
|
||||||
|
|
||||||
|
if (allocOffset >= 0)
|
||||||
|
{
|
||||||
|
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
||||||
|
_activeRegionIndex = i;
|
||||||
|
return allocOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
|
int exhaustedRegion = _activeRegionIndex;
|
||||||
|
var newRegion = new ReservedRegion(_jitRegions[0].Allocator, CacheSize);
|
||||||
|
_jitRegions.Add(newRegion);
|
||||||
|
_activeRegionIndex = _jitRegions.Count - 1;
|
||||||
|
|
||||||
|
int newRegionNumber = _activeRegionIndex;
|
||||||
|
|
||||||
return allocOffset;
|
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
|
||||||
|
|
||||||
|
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
|
||||||
|
|
||||||
|
int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
|
||||||
|
if (allocOffsetNew < 0)
|
||||||
|
{
|
||||||
|
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
|
||||||
|
}
|
||||||
|
|
||||||
|
newRegion.ExpandIfNeeded((ulong)allocOffsetNew + (ulong)codeSize);
|
||||||
|
return allocOffsetNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int AlignCodeSize(int codeSize)
|
private static int AlignCodeSize(int codeSize)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit.Cache
|
namespace Ryujinx.Cpu.LightningJit.Cache
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit
|
namespace Ryujinx.Cpu.LightningJit
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit
|
namespace Ryujinx.Cpu.LightningJit
|
||||||
{
|
{
|
||||||
class TranslatedFunction
|
class TranslatedFunction
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Ryujinx.Cpu.LightningJit.Cache;
|
|||||||
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
|
||||||
using Ryujinx.Cpu.LightningJit.State;
|
using Ryujinx.Cpu.LightningJit.State;
|
||||||
using Ryujinx.Cpu.Signal;
|
using Ryujinx.Cpu.Signal;
|
||||||
using Ryujinx.Memory;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.Signal
|
namespace Ryujinx.Cpu.Signal
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Ryujinx.Common.Logging;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Device
|
namespace Ryujinx.Graphics.Device
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
|
namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Graphics.Device;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Ryujinx.Graphics.Gpu.Memory;
|
|||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.Gpu.Image;
|
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using Ryujinx.Memory.Range;
|
using Ryujinx.Memory.Range;
|
||||||
using System;
|
using System;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Ryujinx.Memory;
|
|||||||
using Ryujinx.Memory.Range;
|
using Ryujinx.Memory.Range;
|
||||||
using Ryujinx.Memory.Tracking;
|
using Ryujinx.Memory.Tracking;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.GAL;
|
|||||||
using Ryujinx.Graphics.Gpu.Engine;
|
using Ryujinx.Graphics.Gpu.Engine;
|
||||||
using Ryujinx.Graphics.Gpu.Image;
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Shader
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization
|
|||||||
}
|
}
|
||||||
|
|
||||||
using ManualResetEvent waitEvent = new(false);
|
using ManualResetEvent waitEvent = new(false);
|
||||||
SyncpointWaiterHandle info = _syncpoints[id].RegisterCallback(threshold, (x) => waitEvent.Set());
|
SyncpointWaiterHandle info = _syncpoints[id].RegisterCallback(threshold, _ => waitEvent.Set());
|
||||||
|
|
||||||
if (info == null)
|
if (info == null)
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization
|
|||||||
|
|
||||||
bool signaled = waitEvent.WaitOne(timeout);
|
bool signaled = waitEvent.WaitOne(timeout);
|
||||||
|
|
||||||
if (!signaled && info != null)
|
if (!signaled)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Gpu, $"Wait on syncpoint {id} for threshold {threshold} took more than {timeout.TotalMilliseconds}ms, resuming execution...");
|
Logger.Error?.Print(LogClass.Gpu, $"Wait on syncpoint {id} for threshold {threshold} took more than {timeout.TotalMilliseconds}ms, resuming execution...");
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using SharpMetal.Metal;
|
using SharpMetal.Metal;
|
||||||
using System;
|
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Metal
|
namespace Ryujinx.Graphics.Metal
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
struct AVCodec
|
struct AVCodec
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
struct AVCodec501
|
struct AVCodec501
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
struct FFCodec<T> where T : struct
|
struct FFCodec<T> where T : struct
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
{
|
{
|
||||||
struct FFCodecLegacy<T> where T : struct
|
struct FFCodecLegacy<T> where T : struct
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Ryujinx.Graphics.Nvdec.FFmpeg.Native;
|
using Ryujinx.Graphics.Nvdec.FFmpeg.Native;
|
||||||
using Ryujinx.Graphics.Video;
|
using Ryujinx.Graphics.Video;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.Video;
|
using Ryujinx.Graphics.Video;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using OpenTK.Graphics.OpenGL;
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL.Image;
|
using Ryujinx.Graphics.OpenGL.Image;
|
||||||
using System;
|
|
||||||
using static Ryujinx.Graphics.OpenGL.Effects.ShaderHelper;
|
using static Ryujinx.Graphics.OpenGL.Effects.ShaderHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.OpenGL.Effects
|
namespace Ryujinx.Graphics.OpenGL.Effects
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Graphics.OpenGL.Helper;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.OpenGL
|
namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
using Spv.Generator;
|
using Spv.Generator;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using static Spv.Specification;
|
|
||||||
using Instruction = Spv.Generator.Instruction;
|
using Instruction = Spv.Generator.Instruction;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Video
|
namespace Ryujinx.Graphics.Video
|
||||||
{
|
{
|
||||||
public readonly record struct Plane(nint Pointer, int Length);
|
public readonly record struct Plane(nint Pointer, int Length);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Ryujinx.Graphics.GAL;
|
|||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ using System.Runtime.InteropServices;
|
|||||||
using BlendOp = Silk.NET.Vulkan.BlendOp;
|
using BlendOp = Silk.NET.Vulkan.BlendOp;
|
||||||
using Buffer = Silk.NET.Vulkan.Buffer;
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
using Format = Ryujinx.Graphics.GAL.Format;
|
|
||||||
using FrontFace = Ryujinx.Graphics.GAL.FrontFace;
|
using FrontFace = Ryujinx.Graphics.GAL.FrontFace;
|
||||||
using IndexType = Ryujinx.Graphics.GAL.IndexType;
|
using IndexType = Ryujinx.Graphics.GAL.IndexType;
|
||||||
using PolygonMode = Ryujinx.Graphics.GAL.PolygonMode;
|
using PolygonMode = Ryujinx.Graphics.GAL.PolygonMode;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using VkFormat = Silk.NET.Vulkan.Format;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Ryujinx.Common.Memory;
|
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.GAL;
|
|||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan.Queries
|
namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ using Ryujinx.Common.Memory;
|
|||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Format = Ryujinx.Graphics.GAL.Format;
|
|
||||||
using VkFormat = Silk.NET.Vulkan.Format;
|
using VkFormat = Silk.NET.Vulkan.Format;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|||||||
@@ -16,14 +16,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
static partial class VendorUtils
|
static class VendorUtils
|
||||||
{
|
{
|
||||||
[GeneratedRegex("Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")]
|
|
||||||
public static partial Regex AmdGcnRegex();
|
|
||||||
|
|
||||||
[GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")]
|
|
||||||
public static partial Regex NvidiaConsumerClassRegex();
|
|
||||||
|
|
||||||
public static Vendor FromId(uint id)
|
public static Vendor FromId(uint id)
|
||||||
{
|
{
|
||||||
return id switch
|
return id switch
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
@@ -375,11 +376,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}";
|
GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}";
|
||||||
|
|
||||||
IsAmdGcn = !IsMoltenVk && Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex().IsMatch(GpuRenderer);
|
IsAmdGcn = !IsMoltenVk && Vendor == Vendor.Amd && Patterns.AmdGcn.IsMatch(GpuRenderer);
|
||||||
|
|
||||||
if (Vendor == Vendor.Nvidia)
|
if (Vendor == Vendor.Nvidia)
|
||||||
{
|
{
|
||||||
Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer);
|
Match match = Patterns.NvidiaConsumerClass.Match(GpuRenderer);
|
||||||
|
|
||||||
if (match != null && int.TryParse(match.Groups[2].Value, out int gpuNumber))
|
if (match != null && int.TryParse(match.Groups[2].Value, out int gpuNumber))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Exceptions
|
namespace Ryujinx.HLE.Exceptions
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ using Ryujinx.HLE.HOS.Applets.Cabinet;
|
|||||||
using Ryujinx.HLE.HOS.Applets.Dummy;
|
using Ryujinx.HLE.HOS.Applets.Dummy;
|
||||||
using Ryujinx.HLE.HOS.Applets.Error;
|
using Ryujinx.HLE.HOS.Applets.Error;
|
||||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets
|
namespace Ryujinx.HLE.HOS.Applets
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using Ryujinx.Common.Logging;
|
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.HLE.HOS.Applets;
|
|
||||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets.Dummy
|
namespace Ryujinx.HLE.HOS.Applets.Dummy
|
||||||
{
|
{
|
||||||
internal class DummyApplet : IApplet
|
internal class DummyApplet : IApplet
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using LibHac.FsSystem;
|
|||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
@@ -30,9 +31,6 @@ namespace Ryujinx.HLE.HOS.Applets.Error
|
|||||||
|
|
||||||
public event EventHandler AppletStateChanged;
|
public event EventHandler AppletStateChanged;
|
||||||
|
|
||||||
[GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")]
|
|
||||||
private static partial Regex CleanTextRegex();
|
|
||||||
|
|
||||||
public ErrorApplet(Horizon horizon)
|
public ErrorApplet(Horizon horizon)
|
||||||
{
|
{
|
||||||
_horizon = horizon;
|
_horizon = horizon;
|
||||||
@@ -107,7 +105,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
|
|||||||
|
|
||||||
private static string CleanText(string value)
|
private static string CleanText(string value)
|
||||||
{
|
{
|
||||||
return CleanTextRegex().Replace(value, string.Empty).Replace("\0", string.Empty);
|
return Patterns.CleanText.Replace(value, string.Empty).Replace("\0", string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetMessageText(uint module, uint description, string key)
|
private string GetMessageText(uint module, uint description, string key)
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|
||||||
{
|
|
||||||
public static partial class CJKCharacterValidation
|
|
||||||
{
|
|
||||||
public static bool IsCJK(char value)
|
|
||||||
{
|
|
||||||
Regex regex = CJKRegex();
|
|
||||||
|
|
||||||
return regex.IsMatch(value.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
[GeneratedRegex("\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")]
|
|
||||||
private static partial Regex CJKRegex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using Ryujinx.Common.Helper;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
|
{
|
||||||
|
public static class CharacterValidation
|
||||||
|
{
|
||||||
|
public static bool IsNumeric(char value) => Patterns.Numeric.IsMatch(value.ToString());
|
||||||
|
public static bool IsCJK(char value) => Patterns.CJK.IsMatch(value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|
||||||
{
|
|
||||||
public static partial class NumericCharacterValidation
|
|
||||||
{
|
|
||||||
public static bool IsNumeric(char value)
|
|
||||||
{
|
|
||||||
Regex regex = NumericRegex();
|
|
||||||
|
|
||||||
return regex.IsMatch(value.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
[GeneratedRegex("[0-9]|.")]
|
|
||||||
private static partial Regex NumericRegex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Ryujinx.Common;
|
|||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Kernel.Common
|
namespace Ryujinx.HLE.HOS.Kernel.Common
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Common.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Ryujinx.HLE.HOS.Services.Mii.Types;
|
|||||||
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
||||||
using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
|
using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.HLE.HOS.Ipc;
|
using Ryujinx.HLE.HOS.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Kernel;
|
using Ryujinx.HLE.HOS.Kernel;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Ipc;
|
using Ryujinx.HLE.HOS.Kernel.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Services.Apm;
|
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl
|
|||||||
{ BsdSocketOption.SoLinger, SocketOptionName.Linger },
|
{ BsdSocketOption.SoLinger, SocketOptionName.Linger },
|
||||||
{ BsdSocketOption.SoOobInline, SocketOptionName.OutOfBandInline },
|
{ BsdSocketOption.SoOobInline, SocketOptionName.OutOfBandInline },
|
||||||
{ BsdSocketOption.SoReusePort, SocketOptionName.ReuseAddress },
|
{ BsdSocketOption.SoReusePort, SocketOptionName.ReuseAddress },
|
||||||
|
{ BsdSocketOption.SoNoSigpipe, SocketOptionName.DontLinger },
|
||||||
{ BsdSocketOption.SoSndBuf, SocketOptionName.SendBuffer },
|
{ BsdSocketOption.SoSndBuf, SocketOptionName.SendBuffer },
|
||||||
{ BsdSocketOption.SoRcvBuf, SocketOptionName.ReceiveBuffer },
|
{ BsdSocketOption.SoRcvBuf, SocketOptionName.ReceiveBuffer },
|
||||||
{ BsdSocketOption.SoSndLoWat, SocketOptionName.SendLowWater },
|
{ BsdSocketOption.SoSndLoWat, SocketOptionName.SendLowWater },
|
||||||
|
|||||||
@@ -1,37 +1,13 @@
|
|||||||
|
using Ryujinx.Common.Helper;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy
|
namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy
|
||||||
{
|
{
|
||||||
static partial class DnsBlacklist
|
static class DnsBlacklist
|
||||||
{
|
{
|
||||||
const RegexOptions RegexOpts = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
|
|
||||||
|
|
||||||
[GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", RegexOpts)]
|
|
||||||
private static partial Regex BlockedHost1();
|
|
||||||
[GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", RegexOpts)]
|
|
||||||
private static partial Regex BlockedHost2();
|
|
||||||
[GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", RegexOpts)]
|
|
||||||
private static partial Regex BlockedHost3();
|
|
||||||
[GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", RegexOpts)]
|
|
||||||
private static partial Regex BlockedHost4();
|
|
||||||
[GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", RegexOpts)]
|
|
||||||
private static partial Regex BlockedHost5();
|
|
||||||
[GeneratedRegex(@"^accounts\.nintendo\.com$", RegexOpts)]
|
|
||||||
private static partial Regex BlockedHost6();
|
|
||||||
|
|
||||||
private static readonly Regex[] _blockedHosts =
|
|
||||||
[
|
|
||||||
BlockedHost1(),
|
|
||||||
BlockedHost2(),
|
|
||||||
BlockedHost3(),
|
|
||||||
BlockedHost4(),
|
|
||||||
BlockedHost5(),
|
|
||||||
BlockedHost6()
|
|
||||||
];
|
|
||||||
|
|
||||||
public static bool IsHostBlocked(string host)
|
public static bool IsHostBlocked(string host)
|
||||||
{
|
{
|
||||||
foreach (Regex regex in _blockedHosts)
|
foreach (Regex regex in Patterns.BlockedHosts)
|
||||||
{
|
{
|
||||||
if (regex.IsMatch(host))
|
if (regex.IsMatch(host))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Ryujinx.HLE.HOS.Ipc;
|
|||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user