Compare commits

..

3 Commits

4 changed files with 68 additions and 57 deletions
+39 -1
View File
@@ -20,4 +20,42 @@ if command -v gamemoderun > /dev/null 2>&1; then
COMMAND="$COMMAND gamemoderun" COMMAND="$COMMAND gamemoderun"
fi fi
exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@" # Check if user already has a manual Avalonia scaling override or session type is x11.
if [[ -n "${AVALONIA_GLOBAL_SCALE_FACTOR-}" || "$(echo "$XDG_SESSION_TYPE")" == "x11" ]]; then
echo "Scaling: Performed by environment, skipping." >&2
else
# Query monitor config directly (GNOME), default display only.
if [[ "$(echo "$XDG_CURRENT_DESKTOP")" == "GNOME" && -f ~/.config/monitors.xml ]] then
echo -n 'Scaling: Monitor config located, querying scale...' >&2
SCALING="$(grep '<scale' ~/.config/monitors.xml -m 1 | cut -f2 -d">"|cut -f1 -d"<")"
SCALING="${SCALING##* }"
echo "found! Factor: ${SCALING}" >&2
# Fallback to X DPI query for others.
# Plasma handles this fine, GNOME will always round up e.g. 1.25 -> 2.00.
elif command -v xrdb >/dev/null; then
echo -n 'Scaling: Attempting to get scaling from X DPI value...' >&2
dpi="$(xrdb -get Xft.dpi)"
if [[ -n "${dpi}" ]]; then
SCALING=$(echo "scale=2; ${dpi}/96" | bc)
fi
echo "found! Factor: ${SCALING}"
# Query kscreen-doctor for Plasma as a fallback.
elif [[ "$(echo "$XDG_CURRENT_DESKTOP")" == "KDE" ]] && command -v kscreen-doctor >/dev/null; then
echo -n 'Scaling: Attempting to get Plasma desktop scaling factor...' >&2
SCALING="$(kscreen-doctor --outputs | grep "Scale" -m 1)"
SCALING="${SCALING##* }"
SCALING=$(echo $SCALING | sed 's/\x1B\[[0-9;]*m//g') # Trim ANSI chars from ksd output.
echo "found! Factor: ${SCALING}"
fi
if [[ -z "${SCALING-}" || "${SCALING-}" == "0" ]]; then
echo 'Unset invalid scaling value' >&2
SCALING="1"
fi
COMMAND="$COMMAND AVALONIA_GLOBAL_SCALE_FACTOR=$SCALING"
fi
exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"
+28 -33
View File
@@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
private static JitCacheInvalidation _jitCacheInvalidator; private static JitCacheInvalidation _jitCacheInvalidator;
private static List<CacheMemoryAllocator> _cacheAllocators = []; private static CacheMemoryAllocator _cacheAllocator;
private static readonly List<CacheEntry> _cacheEntries = []; private static readonly List<CacheEntry> _cacheEntries = [];
@@ -40,48 +40,37 @@ namespace ARMeilleure.Translation.Cache
public static void Initialize(IJitMemoryAllocator allocator) public static void Initialize(IJitMemoryAllocator allocator)
{ {
if (_initialized)
{
return;
}
lock (_lock) lock (_lock)
{ {
if (_initialized) if (_initialized)
{ {
if (OperatingSystem.IsWindows()) return;
{
JitUnwindWindows.RemoveFunctionTableHandler(
_jitRegions[0].Pointer);
}
for (int i = 0; i < _jitRegions.Count; i++)
{
_jitRegions[i].Dispose();
}
_jitRegions.Clear();
_cacheAllocators.Clear();
} }
else
{
_initialized = true;
}
_activeRegionIndex = 0;
ReservedRegion firstRegion = new(allocator, CacheSize); ReservedRegion firstRegion = new(allocator, CacheSize);
_jitRegions.Add(firstRegion); _jitRegions.Add(firstRegion);
_activeRegionIndex = 0;
CacheMemoryAllocator firstCacheAllocator = new(CacheSize);
_cacheAllocators.Add(firstCacheAllocator);
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS()) if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
{ {
_jitCacheInvalidator = new JitCacheInvalidation(allocator); _jitCacheInvalidator = new JitCacheInvalidation(allocator);
} }
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
{ {
JitUnwindWindows.InstallFunctionTableHandler( JitUnwindWindows.InstallFunctionTableHandler(
firstRegion.Pointer, CacheSize, firstRegion.Pointer + Allocate(_pageSize) firstRegion.Pointer, CacheSize, firstRegion.Pointer + Allocate(_pageSize)
); );
} }
_initialized = true;
} }
} }
@@ -147,7 +136,7 @@ namespace ARMeilleure.Translation.Cache
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset) if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
{ {
_cacheAllocators[_activeRegionIndex].Free(funcOffset, AlignCodeSize(entry.Size)); _cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
_cacheEntries.RemoveAt(entryIndex); _cacheEntries.RemoveAt(entryIndex);
} }
@@ -178,24 +167,30 @@ namespace ARMeilleure.Translation.Cache
{ {
codeSize = AlignCodeSize(codeSize); codeSize = AlignCodeSize(codeSize);
int allocOffset = _cacheAllocators[_activeRegionIndex].Allocate(codeSize); for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
if (allocOffset >= 0)
{ {
_jitRegions[_activeRegionIndex].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize); int allocOffset = _cacheAllocator.Allocate(codeSize);
return allocOffset;
if (allocOffset >= 0)
{
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
_activeRegionIndex = i;
return allocOffset;
}
} }
int exhaustedRegion = _activeRegionIndex; int exhaustedRegion = _activeRegionIndex;
ReservedRegion newRegion = new(_jitRegions[0].Allocator, CacheSize); ReservedRegion newRegion = new(_jitRegions[0].Allocator, CacheSize);
_jitRegions.Add(newRegion); _jitRegions.Add(newRegion);
_activeRegionIndex = _jitRegions.Count - 1; _activeRegionIndex = _jitRegions.Count - 1;
int newRegionNumber = _activeRegionIndex;
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {_activeRegionIndex} ({((long)(_activeRegionIndex + 1) * CacheSize).Bytes()} Total Allocation)."); Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
_cacheAllocators.Add(new CacheMemoryAllocator(CacheSize)); int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
int allocOffsetNew = _cacheAllocators[_activeRegionIndex].Allocate(codeSize);
if (allocOffsetNew < 0) if (allocOffsetNew < 0)
{ {
throw new OutOfMemoryException("Failed to allocate in new Cache Region!"); throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
@@ -52,11 +52,6 @@ namespace ARMeilleure.Translation.Cache
nint context, nint context,
[MarshalAs(UnmanagedType.LPWStr)] string outOfProcessCallbackDll); [MarshalAs(UnmanagedType.LPWStr)] string outOfProcessCallbackDll);
[LibraryImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static unsafe partial bool RtlDeleteFunctionTable(
ulong tableIdentifier);
private static GetRuntimeFunctionCallback _getRuntimeFunctionCallback; private static GetRuntimeFunctionCallback _getRuntimeFunctionCallback;
private static int _sizeOfRuntimeFunction; private static int _sizeOfRuntimeFunction;
@@ -96,23 +91,6 @@ namespace ARMeilleure.Translation.Cache
} }
} }
public static void RemoveFunctionTableHandler(nint codeCachePointer)
{
ulong codeCachePtr = (ulong)codeCachePointer.ToInt64();
bool result;
unsafe
{
result = RtlDeleteFunctionTable(codeCachePtr | 3);
}
if (!result)
{
throw new InvalidOperationException("Failure removing function table callback.");
}
}
private static unsafe RuntimeFunction* FunctionTableHandler(ulong controlPc, nint context) private static unsafe RuntimeFunction* FunctionTableHandler(ulong controlPc, nint context)
{ {
int offset = (int)((long)controlPc - context.ToInt64()); int offset = (int)((long)controlPc - context.ToInt64());
@@ -200,7 +200,7 @@ namespace Ryujinx.Ava.UI.Controls
if (backupDir.Exists) if (backupDir.Exists)
{ {
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache")); cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
cacheFiles.AddRange(backupDir.EnumerateFiles("*.info")); cacheFiles.AddRange(mainDir.EnumerateFiles("*.info"));
} }
if (cacheFiles.Count > 0) if (cacheFiles.Count > 0)