Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fe29a2ff6e | ||
|
e9a173e00c | ||
|
a11784fcbf | ||
|
fd36c8deca | ||
|
70638340b3 |
185
ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs
Normal file
185
ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Intrinsics.Arm;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
{
|
||||||
|
static partial class HardwareCapabilities
|
||||||
|
{
|
||||||
|
static HardwareCapabilities()
|
||||||
|
{
|
||||||
|
if (!ArmBase.Arm64.IsSupported)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsLinux())
|
||||||
|
{
|
||||||
|
LinuxFeatureInfoHwCap = (LinuxFeatureFlagsHwCap)getauxval(AT_HWCAP);
|
||||||
|
LinuxFeatureInfoHwCap2 = (LinuxFeatureFlagsHwCap2)getauxval(AT_HWCAP2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _sysctlNames.Length; i++)
|
||||||
|
{
|
||||||
|
if (CheckSysctlName(_sysctlNames[i]))
|
||||||
|
{
|
||||||
|
MacOsFeatureInfo |= (MacOsFeatureFlags)(1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Linux
|
||||||
|
|
||||||
|
private const ulong AT_HWCAP = 16;
|
||||||
|
private const ulong AT_HWCAP2 = 26;
|
||||||
|
|
||||||
|
[LibraryImport("libc", SetLastError = true)]
|
||||||
|
private static partial ulong getauxval(ulong type);
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum LinuxFeatureFlagsHwCap : ulong
|
||||||
|
{
|
||||||
|
Fp = 1 << 0,
|
||||||
|
Asimd = 1 << 1,
|
||||||
|
Evtstrm = 1 << 2,
|
||||||
|
Aes = 1 << 3,
|
||||||
|
Pmull = 1 << 4,
|
||||||
|
Sha1 = 1 << 5,
|
||||||
|
Sha2 = 1 << 6,
|
||||||
|
Crc32 = 1 << 7,
|
||||||
|
Atomics = 1 << 8,
|
||||||
|
FpHp = 1 << 9,
|
||||||
|
AsimdHp = 1 << 10,
|
||||||
|
CpuId = 1 << 11,
|
||||||
|
AsimdRdm = 1 << 12,
|
||||||
|
Jscvt = 1 << 13,
|
||||||
|
Fcma = 1 << 14,
|
||||||
|
Lrcpc = 1 << 15,
|
||||||
|
DcpOp = 1 << 16,
|
||||||
|
Sha3 = 1 << 17,
|
||||||
|
Sm3 = 1 << 18,
|
||||||
|
Sm4 = 1 << 19,
|
||||||
|
AsimdDp = 1 << 20,
|
||||||
|
Sha512 = 1 << 21,
|
||||||
|
Sve = 1 << 22,
|
||||||
|
AsimdFhm = 1 << 23,
|
||||||
|
Dit = 1 << 24,
|
||||||
|
Uscat = 1 << 25,
|
||||||
|
Ilrcpc = 1 << 26,
|
||||||
|
FlagM = 1 << 27,
|
||||||
|
Ssbs = 1 << 28,
|
||||||
|
Sb = 1 << 29,
|
||||||
|
Paca = 1 << 30,
|
||||||
|
Pacg = 1UL << 31
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum LinuxFeatureFlagsHwCap2 : ulong
|
||||||
|
{
|
||||||
|
Dcpodp = 1 << 0,
|
||||||
|
Sve2 = 1 << 1,
|
||||||
|
SveAes = 1 << 2,
|
||||||
|
SvePmull = 1 << 3,
|
||||||
|
SveBitperm = 1 << 4,
|
||||||
|
SveSha3 = 1 << 5,
|
||||||
|
SveSm4 = 1 << 6,
|
||||||
|
FlagM2 = 1 << 7,
|
||||||
|
Frint = 1 << 8,
|
||||||
|
SveI8mm = 1 << 9,
|
||||||
|
SveF32mm = 1 << 10,
|
||||||
|
SveF64mm = 1 << 11,
|
||||||
|
SveBf16 = 1 << 12,
|
||||||
|
I8mm = 1 << 13,
|
||||||
|
Bf16 = 1 << 14,
|
||||||
|
Dgh = 1 << 15,
|
||||||
|
Rng = 1 << 16,
|
||||||
|
Bti = 1 << 17,
|
||||||
|
Mte = 1 << 18,
|
||||||
|
Ecv = 1 << 19,
|
||||||
|
Afp = 1 << 20,
|
||||||
|
Rpres = 1 << 21,
|
||||||
|
Mte3 = 1 << 22,
|
||||||
|
Sme = 1 << 23,
|
||||||
|
Sme_i16i64 = 1 << 24,
|
||||||
|
Sme_f64f64 = 1 << 25,
|
||||||
|
Sme_i8i32 = 1 << 26,
|
||||||
|
Sme_f16f32 = 1 << 27,
|
||||||
|
Sme_b16f32 = 1 << 28,
|
||||||
|
Sme_f32f32 = 1 << 29,
|
||||||
|
Sme_fa64 = 1 << 30,
|
||||||
|
Wfxt = 1UL << 31,
|
||||||
|
Ebf16 = 1UL << 32,
|
||||||
|
Sve_Ebf16 = 1UL << 33,
|
||||||
|
Cssc = 1UL << 34,
|
||||||
|
Rprfm = 1UL << 35,
|
||||||
|
Sve2p1 = 1UL << 36
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LinuxFeatureFlagsHwCap LinuxFeatureInfoHwCap { get; } = 0;
|
||||||
|
public static LinuxFeatureFlagsHwCap2 LinuxFeatureInfoHwCap2 { get; } = 0;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region macOS
|
||||||
|
|
||||||
|
[LibraryImport("libSystem.dylib", SetLastError = true)]
|
||||||
|
private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
|
||||||
|
|
||||||
|
[SupportedOSPlatform("macos")]
|
||||||
|
private static bool CheckSysctlName(string name)
|
||||||
|
{
|
||||||
|
ulong size = sizeof(int);
|
||||||
|
if (sysctlbyname(name, out int val, ref size, IntPtr.Zero, 0) == 0 && size == sizeof(int))
|
||||||
|
{
|
||||||
|
return val != 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] _sysctlNames = new string[]
|
||||||
|
{
|
||||||
|
"hw.optional.floatingpoint",
|
||||||
|
"hw.optional.AdvSIMD",
|
||||||
|
"hw.optional.arm.FEAT_FP16",
|
||||||
|
"hw.optional.arm.FEAT_AES",
|
||||||
|
"hw.optional.arm.FEAT_PMULL",
|
||||||
|
"hw.optional.arm.FEAT_LSE",
|
||||||
|
"hw.optional.armv8_crc32",
|
||||||
|
"hw.optional.arm.FEAT_SHA1",
|
||||||
|
"hw.optional.arm.FEAT_SHA256"
|
||||||
|
};
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum MacOsFeatureFlags
|
||||||
|
{
|
||||||
|
Fp = 1 << 0,
|
||||||
|
AdvSimd = 1 << 1,
|
||||||
|
Fp16 = 1 << 2,
|
||||||
|
Aes = 1 << 3,
|
||||||
|
Pmull = 1 << 4,
|
||||||
|
Lse = 1 << 5,
|
||||||
|
Crc32 = 1 << 6,
|
||||||
|
Sha1 = 1 << 7,
|
||||||
|
Sha256 = 1 << 8
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public static bool SupportsAdvSimd => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Asimd) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.AdvSimd);
|
||||||
|
public static bool SupportsAes => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Aes) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Aes);
|
||||||
|
public static bool SupportsPmull => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Pmull) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Pmull);
|
||||||
|
public static bool SupportsLse => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Atomics) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Lse);
|
||||||
|
public static bool SupportsCrc32 => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Crc32) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Crc32);
|
||||||
|
public static bool SupportsSha1 => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Sha1) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Sha1);
|
||||||
|
public static bool SupportsSha256 => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Sha2) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Sha256);
|
||||||
|
}
|
||||||
|
}
|
@@ -2556,7 +2556,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||||
|
|
||||||
if (Optimizations.UseAdvSimd && false) // Not supported by all Arm CPUs.
|
if (Optimizations.UseArm64Pmull)
|
||||||
{
|
{
|
||||||
InstEmitSimdHelperArm64.EmitVectorBinaryOp(context, Intrinsic.Arm64PmullV);
|
InstEmitSimdHelperArm64.EmitVectorBinaryOp(context, Intrinsic.Arm64PmullV);
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
using ARMeilleure.CodeGen.X86;
|
|
||||||
using System.Runtime.Intrinsics.Arm;
|
using System.Runtime.Intrinsics.Arm;
|
||||||
|
|
||||||
namespace ARMeilleure
|
namespace ARMeilleure
|
||||||
{
|
{
|
||||||
|
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||||
|
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||||
|
|
||||||
public static class Optimizations
|
public static class Optimizations
|
||||||
{
|
{
|
||||||
public static bool FastFP { get; set; } = true;
|
public static bool FastFP { get; set; } = true;
|
||||||
@@ -11,6 +13,7 @@ namespace ARMeilleure
|
|||||||
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
||||||
|
|
||||||
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
||||||
|
public static bool UseArm64PmullIfAvailable { get; set; } = true;
|
||||||
|
|
||||||
public static bool UseSseIfAvailable { get; set; } = true;
|
public static bool UseSseIfAvailable { get; set; } = true;
|
||||||
public static bool UseSse2IfAvailable { get; set; } = true;
|
public static bool UseSse2IfAvailable { get; set; } = true;
|
||||||
@@ -29,25 +32,26 @@ namespace ARMeilleure
|
|||||||
|
|
||||||
public static bool ForceLegacySse
|
public static bool ForceLegacySse
|
||||||
{
|
{
|
||||||
get => HardwareCapabilities.ForceLegacySse;
|
get => X86HardwareCapabilities.ForceLegacySse;
|
||||||
set => HardwareCapabilities.ForceLegacySse = value;
|
set => X86HardwareCapabilities.ForceLegacySse = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool UseAdvSimd => UseAdvSimdIfAvailable && AdvSimd.IsSupported;
|
internal static bool UseAdvSimd => UseAdvSimdIfAvailable && Arm64HardwareCapabilities.SupportsAdvSimd;
|
||||||
|
internal static bool UseArm64Pmull => UseArm64PmullIfAvailable && Arm64HardwareCapabilities.SupportsPmull;
|
||||||
|
|
||||||
internal static bool UseSse => UseSseIfAvailable && HardwareCapabilities.SupportsSse;
|
internal static bool UseSse => UseSseIfAvailable && X86HardwareCapabilities.SupportsSse;
|
||||||
internal static bool UseSse2 => UseSse2IfAvailable && HardwareCapabilities.SupportsSse2;
|
internal static bool UseSse2 => UseSse2IfAvailable && X86HardwareCapabilities.SupportsSse2;
|
||||||
internal static bool UseSse3 => UseSse3IfAvailable && HardwareCapabilities.SupportsSse3;
|
internal static bool UseSse3 => UseSse3IfAvailable && X86HardwareCapabilities.SupportsSse3;
|
||||||
internal static bool UseSsse3 => UseSsse3IfAvailable && HardwareCapabilities.SupportsSsse3;
|
internal static bool UseSsse3 => UseSsse3IfAvailable && X86HardwareCapabilities.SupportsSsse3;
|
||||||
internal static bool UseSse41 => UseSse41IfAvailable && HardwareCapabilities.SupportsSse41;
|
internal static bool UseSse41 => UseSse41IfAvailable && X86HardwareCapabilities.SupportsSse41;
|
||||||
internal static bool UseSse42 => UseSse42IfAvailable && HardwareCapabilities.SupportsSse42;
|
internal static bool UseSse42 => UseSse42IfAvailable && X86HardwareCapabilities.SupportsSse42;
|
||||||
internal static bool UsePopCnt => UsePopCntIfAvailable && HardwareCapabilities.SupportsPopcnt;
|
internal static bool UsePopCnt => UsePopCntIfAvailable && X86HardwareCapabilities.SupportsPopcnt;
|
||||||
internal static bool UseAvx => UseAvxIfAvailable && HardwareCapabilities.SupportsAvx && !ForceLegacySse;
|
internal static bool UseAvx => UseAvxIfAvailable && X86HardwareCapabilities.SupportsAvx && !ForceLegacySse;
|
||||||
internal static bool UseF16c => UseF16cIfAvailable && HardwareCapabilities.SupportsF16c;
|
internal static bool UseF16c => UseF16cIfAvailable && X86HardwareCapabilities.SupportsF16c;
|
||||||
internal static bool UseFma => UseFmaIfAvailable && HardwareCapabilities.SupportsFma;
|
internal static bool UseFma => UseFmaIfAvailable && X86HardwareCapabilities.SupportsFma;
|
||||||
internal static bool UseAesni => UseAesniIfAvailable && HardwareCapabilities.SupportsAesni;
|
internal static bool UseAesni => UseAesniIfAvailable && X86HardwareCapabilities.SupportsAesni;
|
||||||
internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && HardwareCapabilities.SupportsPclmulqdq;
|
internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && X86HardwareCapabilities.SupportsPclmulqdq;
|
||||||
internal static bool UseSha => UseShaIfAvailable && HardwareCapabilities.SupportsSha;
|
internal static bool UseSha => UseShaIfAvailable && X86HardwareCapabilities.SupportsSha;
|
||||||
internal static bool UseGfni => UseGfniIfAvailable && HardwareCapabilities.SupportsGfni;
|
internal static bool UseGfni => UseGfniIfAvailable && X86HardwareCapabilities.SupportsGfni;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,7 +1,6 @@
|
|||||||
using ARMeilleure.CodeGen;
|
using ARMeilleure.CodeGen;
|
||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
using ARMeilleure.CodeGen.Unwinding;
|
using ARMeilleure.CodeGen.Unwinding;
|
||||||
using ARMeilleure.CodeGen.X86;
|
|
||||||
using ARMeilleure.Common;
|
using ARMeilleure.Common;
|
||||||
using ARMeilleure.Memory;
|
using ARMeilleure.Memory;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
@@ -22,12 +21,15 @@ using static ARMeilleure.Translation.PTC.PtcFormatter;
|
|||||||
|
|
||||||
namespace ARMeilleure.Translation.PTC
|
namespace ARMeilleure.Translation.PTC
|
||||||
{
|
{
|
||||||
|
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||||
|
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||||
|
|
||||||
class Ptc : IPtcLoadState
|
class Ptc : IPtcLoadState
|
||||||
{
|
{
|
||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 4114; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 4272; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
@@ -259,6 +261,13 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (outerHeader.Architecture != (uint)RuntimeInformation.ProcessArchitecture)
|
||||||
|
{
|
||||||
|
InvalidateCompressedStream(compressedStream);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
IntPtr intPtr = IntPtr.Zero;
|
IntPtr intPtr = IntPtr.Zero;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -435,6 +444,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
outerHeader.FeatureInfo = GetFeatureInfo();
|
outerHeader.FeatureInfo = GetFeatureInfo();
|
||||||
outerHeader.MemoryManagerMode = GetMemoryManagerMode();
|
outerHeader.MemoryManagerMode = GetMemoryManagerMode();
|
||||||
outerHeader.OSPlatform = GetOSPlatform();
|
outerHeader.OSPlatform = GetOSPlatform();
|
||||||
|
outerHeader.Architecture = (uint)RuntimeInformation.ProcessArchitecture;
|
||||||
|
|
||||||
outerHeader.UncompressedStreamSize =
|
outerHeader.UncompressedStreamSize =
|
||||||
(long)Unsafe.SizeOf<InnerHeader>() +
|
(long)Unsafe.SizeOf<InnerHeader>() +
|
||||||
@@ -951,12 +961,27 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static FeatureInfo GetFeatureInfo()
|
private static FeatureInfo GetFeatureInfo()
|
||||||
|
{
|
||||||
|
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
{
|
{
|
||||||
return new FeatureInfo(
|
return new FeatureInfo(
|
||||||
(uint)HardwareCapabilities.FeatureInfo1Ecx,
|
(ulong)Arm64HardwareCapabilities.LinuxFeatureInfoHwCap,
|
||||||
(uint)HardwareCapabilities.FeatureInfo1Edx,
|
(ulong)Arm64HardwareCapabilities.LinuxFeatureInfoHwCap2,
|
||||||
(uint)HardwareCapabilities.FeatureInfo7Ebx,
|
(ulong)Arm64HardwareCapabilities.MacOsFeatureInfo,
|
||||||
(uint)HardwareCapabilities.FeatureInfo7Ecx);
|
0);
|
||||||
|
}
|
||||||
|
else if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
|
||||||
|
{
|
||||||
|
return new FeatureInfo(
|
||||||
|
(ulong)X86HardwareCapabilities.FeatureInfo1Ecx,
|
||||||
|
(ulong)X86HardwareCapabilities.FeatureInfo1Edx,
|
||||||
|
(ulong)X86HardwareCapabilities.FeatureInfo7Ebx,
|
||||||
|
(ulong)X86HardwareCapabilities.FeatureInfo7Ecx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new FeatureInfo(0, 0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte GetMemoryManagerMode()
|
private byte GetMemoryManagerMode()
|
||||||
@@ -976,7 +1001,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return osPlatform;
|
return osPlatform;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 58*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 78*/)]
|
||||||
private struct OuterHeader
|
private struct OuterHeader
|
||||||
{
|
{
|
||||||
public ulong Magic;
|
public ulong Magic;
|
||||||
@@ -987,6 +1012,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
public FeatureInfo FeatureInfo;
|
public FeatureInfo FeatureInfo;
|
||||||
public byte MemoryManagerMode;
|
public byte MemoryManagerMode;
|
||||||
public uint OSPlatform;
|
public uint OSPlatform;
|
||||||
|
public uint Architecture;
|
||||||
|
|
||||||
public long UncompressedStreamSize;
|
public long UncompressedStreamSize;
|
||||||
|
|
||||||
@@ -1007,8 +1033,8 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 16*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 32*/)]
|
||||||
private record struct FeatureInfo(uint FeatureInfo0, uint FeatureInfo1, uint FeatureInfo2, uint FeatureInfo3);
|
private record struct FeatureInfo(ulong FeatureInfo0, ulong FeatureInfo1, ulong FeatureInfo2, ulong FeatureInfo3);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 128*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 128*/)]
|
||||||
private struct InnerHeader
|
private struct InnerHeader
|
||||||
|
@@ -119,7 +119,7 @@
|
|||||||
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
||||||
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
||||||
"SettingsTabSystemHacks": "Hacks",
|
"SettingsTabSystemHacks": "Hacks",
|
||||||
"SettingsTabSystemHacksNote": " (may cause instability)",
|
"SettingsTabSystemHacksNote": "May cause instability",
|
||||||
"SettingsTabSystemExpandDramSize": "Use alternative memory layout (Developers)",
|
"SettingsTabSystemExpandDramSize": "Use alternative memory layout (Developers)",
|
||||||
"SettingsTabSystemIgnoreMissingServices": "Ignore Missing Services",
|
"SettingsTabSystemIgnoreMissingServices": "Ignore Missing Services",
|
||||||
"SettingsTabGraphics": "Graphics",
|
"SettingsTabGraphics": "Graphics",
|
||||||
@@ -157,7 +157,8 @@
|
|||||||
"SettingsTabLoggingEnableGuestLogs": "Enable Guest Logs",
|
"SettingsTabLoggingEnableGuestLogs": "Enable Guest Logs",
|
||||||
"SettingsTabLoggingEnableFsAccessLogs": "Enable Fs Access Logs",
|
"SettingsTabLoggingEnableFsAccessLogs": "Enable Fs Access Logs",
|
||||||
"SettingsTabLoggingFsGlobalAccessLogMode": "Fs Global Access Log Mode:",
|
"SettingsTabLoggingFsGlobalAccessLogMode": "Fs Global Access Log Mode:",
|
||||||
"SettingsTabLoggingDeveloperOptions": "Developer Options (WARNING: Will reduce performance)",
|
"SettingsTabLoggingDeveloperOptions": "Developer Options",
|
||||||
|
"SettingsTabLoggingDeveloperOptionsNote": "WARNING: Will reduce performance",
|
||||||
"SettingsTabLoggingGraphicsBackendLogLevel": "Graphics Backend Log Level:",
|
"SettingsTabLoggingGraphicsBackendLogLevel": "Graphics Backend Log Level:",
|
||||||
"SettingsTabLoggingGraphicsBackendLogLevelNone": "None",
|
"SettingsTabLoggingGraphicsBackendLogLevelNone": "None",
|
||||||
"SettingsTabLoggingGraphicsBackendLogLevelError": "Error",
|
"SettingsTabLoggingGraphicsBackendLogLevelError": "Error",
|
||||||
|
@@ -60,5 +60,6 @@
|
|||||||
<Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
|
<Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
|
||||||
<Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
|
<Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
|
||||||
<Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
|
<Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
|
||||||
|
<Color x:Key="SecondaryTextColor">#A0FFFFFF</Color>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
</Styles>
|
</Styles>
|
@@ -52,5 +52,6 @@
|
|||||||
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
|
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
|
||||||
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
||||||
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
||||||
|
<Color x:Key="SecondaryTextColor">#A0000000</Color>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
</Styles>
|
</Styles>
|
@@ -56,8 +56,8 @@
|
|||||||
<Style Selector="Border.settings">
|
<Style Selector="Border.settings">
|
||||||
<Setter Property="Background" Value="{DynamicResource ThemeDarkColor}" />
|
<Setter Property="Background" Value="{DynamicResource ThemeDarkColor}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderColor}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderColor}" />
|
||||||
<Setter Property="BorderThickness" Value="2" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="3" />
|
<Setter Property="CornerRadius" Value="5" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="Image.small">
|
<Style Selector="Image.small">
|
||||||
<Setter Property="Width" Value="50" />
|
<Setter Property="Width" Value="50" />
|
||||||
@@ -303,6 +303,9 @@
|
|||||||
<Color x:Key="ThemeControlBorderColor">#FF505050</Color>
|
<Color x:Key="ThemeControlBorderColor">#FF505050</Color>
|
||||||
<Color x:Key="VsyncEnabled">#FF2EEAC9</Color>
|
<Color x:Key="VsyncEnabled">#FF2EEAC9</Color>
|
||||||
<Color x:Key="VsyncDisabled">#FFFF4554</Color>
|
<Color x:Key="VsyncDisabled">#FFFF4554</Color>
|
||||||
|
<Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
|
||||||
|
<Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
|
||||||
|
<Color x:Key="SecondaryTextColor">#A0FFFFFF</Color>
|
||||||
<x:Double x:Key="ScrollBarThickness">15</x:Double>
|
<x:Double x:Key="ScrollBarThickness">15</x:Double>
|
||||||
<x:Double x:Key="FontSizeSmall">8</x:Double>
|
<x:Double x:Key="FontSizeSmall">8</x:Double>
|
||||||
<x:Double x:Key="FontSizeNormal">10</x:Double>
|
<x:Double x:Key="FontSizeNormal">10</x:Double>
|
||||||
|
@@ -20,12 +20,12 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
{
|
{
|
||||||
return level switch
|
return level switch
|
||||||
{
|
{
|
||||||
AvaLogLevel.Verbose => RyuLogger.Trace,
|
AvaLogLevel.Verbose => RyuLogger.Debug,
|
||||||
AvaLogLevel.Debug => RyuLogger.Debug,
|
AvaLogLevel.Debug => RyuLogger.Debug,
|
||||||
AvaLogLevel.Information => RyuLogger.Info,
|
AvaLogLevel.Information => RyuLogger.Debug,
|
||||||
AvaLogLevel.Warning => RyuLogger.Warning,
|
AvaLogLevel.Warning => RyuLogger.Debug,
|
||||||
AvaLogLevel.Error => RyuLogger.Error,
|
AvaLogLevel.Error => RyuLogger.Error,
|
||||||
AvaLogLevel.Fatal => RyuLogger.Notice,
|
AvaLogLevel.Fatal => RyuLogger.Error,
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
|
_ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -37,34 +37,38 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
|
|
||||||
public void Log(AvaLogLevel level, string area, object source, string messageTemplate)
|
public void Log(AvaLogLevel level, string area, object source, string messageTemplate)
|
||||||
{
|
{
|
||||||
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(area, messageTemplate, source, null));
|
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log<T0>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0)
|
public void Log<T0>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0)
|
||||||
{
|
{
|
||||||
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(area, messageTemplate, source, new object[] { propertyValue0 }));
|
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, new object[] { propertyValue0 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log<T0, T1>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
|
public void Log<T0, T1>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
|
||||||
{
|
{
|
||||||
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(area, messageTemplate, source, new object[] { propertyValue0, propertyValue1 }));
|
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, new object[] { propertyValue0, propertyValue1 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log<T0, T1, T2>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
|
public void Log<T0, T1, T2>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
|
||||||
{
|
{
|
||||||
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(area, messageTemplate, source, new object[] { propertyValue0, propertyValue1, propertyValue2 }));
|
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, new object[] { propertyValue0, propertyValue1, propertyValue2 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log(AvaLogLevel level, string area, object source, string messageTemplate, params object[] propertyValues)
|
public void Log(AvaLogLevel level, string area, object source, string messageTemplate, params object[] propertyValues)
|
||||||
{
|
{
|
||||||
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(area, messageTemplate, source, propertyValues));
|
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, propertyValues));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string Format(string area, string template, object source, object[] v)
|
private static string Format(AvaLogLevel level, string area, string template, object source, object[] v)
|
||||||
{
|
{
|
||||||
var result = new StringBuilder();
|
var result = new StringBuilder();
|
||||||
var r = new CharacterReader(template.AsSpan());
|
var r = new CharacterReader(template.AsSpan());
|
||||||
var i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
result.Append('[');
|
||||||
|
result.Append(level);
|
||||||
|
result.Append("] ");
|
||||||
|
|
||||||
result.Append('[');
|
result.Append('[');
|
||||||
result.Append(area);
|
result.Append(area);
|
||||||
|
@@ -47,31 +47,34 @@
|
|||||||
ToolTip.Tip="{locale:Locale ErrorLogTooltip}">
|
ToolTip.Tip="{locale:Locale ErrorLogTooltip}">
|
||||||
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableErrorLogs}" />
|
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableErrorLogs}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<CheckBox IsChecked="{Binding EnableTrace}"
|
|
||||||
ToolTip.Tip="{locale:Locale TraceLogTooltip}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableTraceLogs}" />
|
|
||||||
</CheckBox>
|
|
||||||
<CheckBox IsChecked="{Binding EnableGuest}"
|
<CheckBox IsChecked="{Binding EnableGuest}"
|
||||||
ToolTip.Tip="{locale:Locale GuestLogTooltip}">
|
ToolTip.Tip="{locale:Locale GuestLogTooltip}">
|
||||||
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableGuestLogs}" />
|
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableGuestLogs}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Separator Height="1" />
|
<Separator Height="1" />
|
||||||
|
<StackPanel Orientation="Vertical" Spacing="2">
|
||||||
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabLoggingDeveloperOptions}" />
|
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabLoggingDeveloperOptions}" />
|
||||||
|
<TextBlock Foreground="{DynamicResource SecondaryTextColor}" Text="{locale:Locale SettingsTabLoggingDeveloperOptionsNote}" />
|
||||||
|
</StackPanel>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Orientation="Vertical"
|
Orientation="Vertical"
|
||||||
Spacing="10">
|
Spacing="10">
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<CheckBox IsChecked="{Binding EnableDebug}"
|
<CheckBox IsChecked="{Binding EnableTrace}"
|
||||||
ToolTip.Tip="{locale:Locale DebugLogTooltip}">
|
ToolTip.Tip="{locale:Locale TraceLogTooltip}">
|
||||||
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableDebugLogs}" />
|
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableTraceLogs}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<CheckBox IsChecked="{Binding EnableFsAccessLog}"
|
<CheckBox IsChecked="{Binding EnableFsAccessLog}"
|
||||||
ToolTip.Tip="{locale:Locale FileAccessLogTooltip}">
|
ToolTip.Tip="{locale:Locale FileAccessLogTooltip}">
|
||||||
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableFsAccessLogs}" />
|
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableFsAccessLogs}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
|
<CheckBox IsChecked="{Binding EnableDebug}"
|
||||||
|
ToolTip.Tip="{locale:Locale DebugLogTooltip}">
|
||||||
|
<TextBlock Text="{locale:Locale SettingsTabLoggingEnableDebugLogs}" />
|
||||||
|
</CheckBox>
|
||||||
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" VerticalAlignment="Stretch">
|
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" VerticalAlignment="Stretch">
|
||||||
<TextBlock VerticalAlignment="Center"
|
<TextBlock VerticalAlignment="Center"
|
||||||
ToolTip.Tip="{locale:Locale FSAccessLogModeTooltip}"
|
ToolTip.Tip="{locale:Locale FSAccessLogModeTooltip}"
|
||||||
|
@@ -172,9 +172,9 @@
|
|||||||
</CheckBox>
|
</CheckBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Separator Height="1" />
|
<Separator Height="1" />
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Vertical" Spacing="2">
|
||||||
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabSystemHacks}" />
|
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabSystemHacks}" />
|
||||||
<TextBlock Text="{locale:Locale SettingsTabSystemHacksNote}" />
|
<TextBlock Foreground="{DynamicResource SecondaryTextColor}" Text="{locale:Locale SettingsTabSystemHacksNote}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
|
@@ -44,7 +44,8 @@
|
|||||||
<settings:SettingsNetworkView Name="NetworkPage" />
|
<settings:SettingsNetworkView Name="NetworkPage" />
|
||||||
<settings:SettingsLoggingView Name="LoggingPage" />
|
<settings:SettingsLoggingView Name="LoggingPage" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ui:NavigationView Grid.Row="1"
|
<ui:NavigationView
|
||||||
|
Grid.Row="1"
|
||||||
IsSettingsVisible="False"
|
IsSettingsVisible="False"
|
||||||
Name="NavPanel"
|
Name="NavPanel"
|
||||||
IsBackEnabled="False"
|
IsBackEnabled="False"
|
||||||
@@ -54,7 +55,8 @@
|
|||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
OpenPaneLength="200">
|
OpenPaneLength="200">
|
||||||
<ui:NavigationView.MenuItems>
|
<ui:NavigationView.MenuItems>
|
||||||
<ui:NavigationViewItem IsSelected="True"
|
<ui:NavigationViewItem
|
||||||
|
IsSelected="True"
|
||||||
Content="{locale:Locale SettingsTabGeneral}"
|
Content="{locale:Locale SettingsTabGeneral}"
|
||||||
Tag="UiPage"
|
Tag="UiPage"
|
||||||
Icon="New" />
|
Icon="New" />
|
||||||
@@ -74,7 +76,8 @@
|
|||||||
Content="{locale:Locale SettingsTabCpu}"
|
Content="{locale:Locale SettingsTabCpu}"
|
||||||
Tag="CpuPage">
|
Tag="CpuPage">
|
||||||
<ui:NavigationViewItem.Icon>
|
<ui:NavigationViewItem.Icon>
|
||||||
<ui:FontIcon FontFamily="avares://Ryujinx.Ava/Assets/Fonts#Segoe Fluent Icons"
|
<ui:FontIcon
|
||||||
|
FontFamily="avares://Ryujinx.Ava/Assets/Fonts#Segoe Fluent Icons"
|
||||||
Glyph="{helpers:GlyphValueConverter Chip}" />
|
Glyph="{helpers:GlyphValueConverter Chip}" />
|
||||||
</ui:NavigationViewItem.Icon>
|
</ui:NavigationViewItem.Icon>
|
||||||
</ui:NavigationViewItem>
|
</ui:NavigationViewItem>
|
||||||
@@ -95,6 +98,11 @@
|
|||||||
Tag="LoggingPage"
|
Tag="LoggingPage"
|
||||||
Icon="Document" />
|
Icon="Document" />
|
||||||
</ui:NavigationView.MenuItems>
|
</ui:NavigationView.MenuItems>
|
||||||
|
<ui:NavigationView.Styles>
|
||||||
|
<Style Selector="Grid#PlaceholderGrid">
|
||||||
|
<Setter Property="Height" Value="40" />
|
||||||
|
</Style>
|
||||||
|
</ui:NavigationView.Styles>
|
||||||
</ui:NavigationView>
|
</ui:NavigationView>
|
||||||
<ReversibleStackPanel
|
<ReversibleStackPanel
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
|
using Ryujinx.Horizon.LogManager.Types;
|
||||||
using Ryujinx.Horizon.Sdk.Lm;
|
using Ryujinx.Horizon.Sdk.Lm;
|
||||||
using Ryujinx.Horizon.Sdk.Sf;
|
using Ryujinx.Horizon.Sdk.Sf;
|
||||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||||
@@ -13,13 +14,19 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
{
|
{
|
||||||
partial class LmLogger : ILmLogger
|
partial class LmLogger : ILmLogger
|
||||||
{
|
{
|
||||||
|
private const int MessageLengthLimit = 5000;
|
||||||
|
|
||||||
private readonly LogService _log;
|
private readonly LogService _log;
|
||||||
private readonly ulong _pid;
|
private readonly ulong _pid;
|
||||||
|
|
||||||
|
private LogPacket _logPacket;
|
||||||
|
|
||||||
public LmLogger(LogService log, ulong pid)
|
public LmLogger(LogService log, ulong pid)
|
||||||
{
|
{
|
||||||
_log = log;
|
_log = log;
|
||||||
_pid = pid;
|
_pid = pid;
|
||||||
|
|
||||||
|
_logPacket = new LogPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(0)]
|
[CmifCommand(0)]
|
||||||
@@ -30,7 +37,12 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Guest?.Print(LogClass.ServiceLm, LogImpl(message));
|
if (LogImpl(message))
|
||||||
|
{
|
||||||
|
Logger.Guest?.Print(LogClass.ServiceLm, _logPacket.ToString());
|
||||||
|
|
||||||
|
_logPacket = new LogPacket();
|
||||||
|
}
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
@@ -60,58 +72,86 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string LogImpl(ReadOnlySpan<byte> message)
|
private bool LogImpl(ReadOnlySpan<byte> message)
|
||||||
{
|
{
|
||||||
SpanReader reader = new(message);
|
SpanReader reader = new(message);
|
||||||
LogPacketHeader header = reader.Read<LogPacketHeader>();
|
LogPacketHeader header = reader.Read<LogPacketHeader>();
|
||||||
StringBuilder builder = new();
|
|
||||||
|
|
||||||
builder.AppendLine($"Guest Log:\n Log level: {header.Severity}");
|
bool isHeadPacket = (header.Flags & LogPacketFlags.IsHead) != 0;
|
||||||
|
bool isTailPacket = (header.Flags & LogPacketFlags.IsTail) != 0;
|
||||||
|
|
||||||
|
_logPacket.Severity = header.Severity;
|
||||||
|
|
||||||
while (reader.Length > 0)
|
while (reader.Length > 0)
|
||||||
{
|
{
|
||||||
int type = ReadUleb128(ref reader);
|
int type = ReadUleb128(ref reader);
|
||||||
int size = ReadUleb128(ref reader);
|
int size = ReadUleb128(ref reader);
|
||||||
|
|
||||||
LogDataChunkKey field = (LogDataChunkKey)type;
|
LogDataChunkKey key = (LogDataChunkKey)type;
|
||||||
|
|
||||||
string fieldStr;
|
if (key == LogDataChunkKey.Start)
|
||||||
|
|
||||||
if (field == LogDataChunkKey.Start)
|
|
||||||
{
|
{
|
||||||
reader.Skip(size);
|
reader.Skip(size);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (field == LogDataChunkKey.Stop)
|
else if (key == LogDataChunkKey.Stop)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (field == LogDataChunkKey.Line)
|
else if (key == LogDataChunkKey.Line)
|
||||||
{
|
{
|
||||||
fieldStr = $"{field}: {reader.Read<int>()}";
|
_logPacket.Line = reader.Read<int>();
|
||||||
}
|
}
|
||||||
else if (field == LogDataChunkKey.DropCount)
|
else if (key == LogDataChunkKey.DropCount)
|
||||||
{
|
{
|
||||||
fieldStr = $"{field}: {reader.Read<long>()}";
|
_logPacket.DropCount = reader.Read<long>();
|
||||||
}
|
}
|
||||||
else if (field == LogDataChunkKey.Time)
|
else if (key == LogDataChunkKey.Time)
|
||||||
{
|
{
|
||||||
fieldStr = $"{field}: {reader.Read<long>()}s";
|
_logPacket.Time = reader.Read<long>();
|
||||||
}
|
}
|
||||||
else if (field < LogDataChunkKey.Count)
|
else if (key == LogDataChunkKey.Message)
|
||||||
{
|
{
|
||||||
fieldStr = $"{field}: '{Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd()}'";
|
string text = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
||||||
|
|
||||||
|
if (isHeadPacket && isTailPacket)
|
||||||
|
{
|
||||||
|
_logPacket.Message = text;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fieldStr = $"Field{field}: '{Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd()}'";
|
_logPacket.Message += text;
|
||||||
|
|
||||||
|
if (_logPacket.Message.Length >= MessageLengthLimit)
|
||||||
|
{
|
||||||
|
isTailPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key == LogDataChunkKey.Filename)
|
||||||
|
{
|
||||||
|
_logPacket.Filename = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
||||||
|
}
|
||||||
|
else if (key == LogDataChunkKey.Function)
|
||||||
|
{
|
||||||
|
_logPacket.Function = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
||||||
|
}
|
||||||
|
else if (key == LogDataChunkKey.Module)
|
||||||
|
{
|
||||||
|
_logPacket.Module = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
||||||
|
}
|
||||||
|
else if (key == LogDataChunkKey.Thread)
|
||||||
|
{
|
||||||
|
_logPacket.Thread = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
||||||
|
}
|
||||||
|
else if (key == LogDataChunkKey.ProgramName)
|
||||||
|
{
|
||||||
|
_logPacket.ProgramName = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.AppendLine($" {fieldStr}");
|
return isTailPacket;
|
||||||
}
|
|
||||||
|
|
||||||
return builder.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ReadUleb128(ref SpanReader reader)
|
private static int ReadUleb128(ref SpanReader reader)
|
||||||
|
72
Ryujinx.Horizon/LogManager/Types/LogPacket.cs
Normal file
72
Ryujinx.Horizon/LogManager/Types/LogPacket.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using Ryujinx.Horizon.Sdk.Diag;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.LogManager.Types
|
||||||
|
{
|
||||||
|
struct LogPacket
|
||||||
|
{
|
||||||
|
public string Message;
|
||||||
|
public int Line;
|
||||||
|
public string Filename;
|
||||||
|
public string Function;
|
||||||
|
public string Module;
|
||||||
|
public string Thread;
|
||||||
|
public long DropCount;
|
||||||
|
public long Time;
|
||||||
|
public string ProgramName;
|
||||||
|
public LogSeverity Severity;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new();
|
||||||
|
builder.AppendLine($"Guest Log:\n Log level: {Severity}");
|
||||||
|
|
||||||
|
if (Time > 0)
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Time: {Time}s");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DropCount > 0)
|
||||||
|
{
|
||||||
|
builder.AppendLine($" DropCount: {DropCount}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(ProgramName))
|
||||||
|
{
|
||||||
|
builder.AppendLine($" ProgramName: {ProgramName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Module))
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Module: {Module}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Thread))
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Thread: {Thread}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Filename))
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Filename: {Filename}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Line > 0)
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Line: {Line}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Function))
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Function: {Function}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Message))
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Message: {Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user