1
0
forked from MeloNX/MeloNX

Hypervisor

This commit is contained in:
Stossy11 2025-01-20 23:22:42 +11:00
parent 5ee90c81e9
commit 9ce29d6ad1
27 changed files with 248 additions and 27 deletions

46
MeloNX-hv.entitlements Normal file
View File

@ -0,0 +1,46 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>get-task-allow</key>
<true/>
<key>com.apple.developer.kernel.increased-memory-limit</key>
<true/>
<key>com.apple.developer.kernel.extended-virtual-addressing</key>
<true/>
<key>com.apple.private.iokit.IOServiceSetAuthorizationID</key>
<true/>
<key>com.apple.security.exception.iokit-user-client-class</key>
<array>
<string>AGXCommandQueue</string>
<string>AGXDevice</string>
<string>AGXDeviceUserClient</string>
<string>AGXSharedUserClient</string>
<string>AppleUSBHostDeviceUserClient</string>
<string>AppleUSBHostInterfaceUserClient</string>
<string>IOSurfaceRootUserClient</string>
<string>IOAccelContext</string>
<string>IOAccelContext2</string>
<string>IOAccelDevice</string>
<string>IOAccelDevice2</string>
<string>IOAccelSharedUserClient</string>
<string>IOAccelSharedUserClient2</string>
<string>IOAccelSubmitter2</string>
</array>
<key>com.apple.system.diagnostics.iokit-properties</key>
<true/>
<key>com.apple.vm.device-access</key>
<true/>
<key>com.apple.private.hypervisor</key>
<true/>
<key>com.apple.private.memorystatus</key>
<true/>
<key>com.apple.private.security.no-sandbox</key>
<true/>
<key>com.apple.private.security.storage.AppDataContainers</key>
<true/>
<key>com.apple.private.security.storage.MobileDocuments</key>
<true/>
<key>platform-application</key>
<true/>
</dict>
</plist>

View File

@ -18,7 +18,7 @@ namespace ARMeilleure.Translation.Cache
private static readonly int _pageMask = _pageSize - 8;
private const int CodeAlignment = 4; // Bytes.
private const int CacheSize = 2047 * 1024 * 1024;
private const int CacheSize = 128 * 1024 * 1024;
private const int CacheSizeIOS = 64 * 1024 * 1024;
private static ReservedRegion _jitRegion;

View File

@ -627,6 +627,7 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
);
GCC_OPTIMIZATION_LEVEL = fast;
GENERATE_INFOPLIST_FILE = YES;
@ -863,6 +864,7 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
);
GCC_OPTIMIZATION_LEVEL = fast;
GENERATE_INFOPLIST_FILE = YES;

View File

@ -52,6 +52,7 @@ class Ryujinx {
var fullscreen: Bool
var memoryManagerMode: String
var disableShaderCache: Bool
var hypervisor: Bool
var disableDockedMode: Bool
var enableTextureRecompression: Bool
var additionalArgs: [String]
@ -63,14 +64,15 @@ class Ryujinx {
tracelogs: Bool = false,
listinputids: Bool = false,
fullscreen: Bool = false,
memoryManagerMode: String = "HostMapped",
memoryManagerMode: String = "HostMappedUnsafe",
disableShaderCache: Bool = false,
disableDockedMode: Bool = false,
nintendoinput: Bool = true,
enableInternet: Bool = false,
enableTextureRecompression: Bool = true,
additionalArgs: [String] = [],
resscale: Float = 1.00
resscale: Float = 1.00,
hypervisor: Bool = false
) {
self.gamepath = gamepath
self.inputids = inputids
@ -86,6 +88,7 @@ class Ryujinx {
self.resscale = resscale
self.nintendoinput = nintendoinput
self.enableInternet = enableInternet
self.hypervisor = hypervisor
}
}
@ -170,6 +173,10 @@ class Ryujinx {
// args.append("--disable-vsync")
if config.hypervisor {
args.append("--use-hypervisor")
}
if config.resscale != 1.0 {
args.append(contentsOf: ["--resolution-scale", String(config.resscale)])

View File

@ -39,36 +39,36 @@ struct SettingsView: View {
return memoryManagerModes.filter { $0.1.localizedCaseInsensitiveContains(searchText) }
}
var body: some View {
iOSNav {
List {
// Graphics & Performance
Section {
Toggle(isOn: $config.fullscreen) {
labelWithIcon("Fullscreen", iconName: "rectangle.expand.vertical")
}
.tint(.blue)
Toggle(isOn: $config.disableShaderCache) {
labelWithIcon("Shader Cache", iconName: "memorychip")
}
.tint(.blue)
Toggle(isOn: $config.enableTextureRecompression) {
labelWithIcon("Texture Recompression", iconName: "rectangle.compress.vertical")
}
.tint(.blue)
Toggle(isOn: $config.disableDockedMode) {
labelWithIcon("Docked Mode", iconName: "dock.rectangle")
}
.tint(.blue)
VStack(alignment: .leading, spacing: 10) {
HStack {
labelWithIcon("Resolution Scale", iconName: "magnifyingglass")
@ -91,7 +91,7 @@ struct SettingsView: View {
)
}
}
Slider(value: $config.resscale, in: 0.1...3.0, step: 0.1) {
Text("Resolution Scale")
} minimumValueLabel: {
@ -108,7 +108,7 @@ struct SettingsView: View {
.foregroundColor(.secondary)
}
.padding(.vertical, 8)
Toggle(isOn: $performacehud) {
labelWithIcon("Performance Overlay", iconName: "speedometer")
}
@ -192,7 +192,7 @@ struct SettingsView: View {
} footer: {
Text("Select input devices and on-screen controls to play with. ")
}
// Input Settings
Section {
@ -200,7 +200,7 @@ struct SettingsView: View {
labelWithIcon("List Input IDs", iconName: "list.bullet")
}
.tint(.blue)
Toggle(isOn: $ryuDemo) {
labelWithIcon("On-Screen Controller (Demo)", iconName: "hand.draw")
}
@ -229,6 +229,28 @@ struct SettingsView: View {
labelWithIcon("Memory Manager Mode", iconName: "gearshape")
}
}
if let cpuInfo = getCPUInfo(), cpuInfo.hasPrefix("Apple M") {
if #available (iOS 16.4, *), (false) {
Toggle(isOn: .constant(false)) {
labelWithIcon("Hypervisor", iconName: "bolt.fill")
}
.tint(.blue)
.disabled(true)
.onAppear() {
print("CPU Info: \(cpuInfo)")
}
} else {
Toggle(isOn: $config.hypervisor) {
labelWithIcon("Hypervisor", iconName: "bolt.fill")
}
.tint(.blue)
.onAppear() {
print("CPU Info: \(cpuInfo)")
}
}
}
} header: {
Text("CPU Mode")
.font(.title3.weight(.semibold))
@ -237,8 +259,8 @@ struct SettingsView: View {
} footer: {
Text("Select how memory is managed. 'Host (fast)' is best for most users.")
}
// Other Settings
Section {
@ -251,7 +273,7 @@ struct SettingsView: View {
labelWithIcon("Debug Logs", iconName: "exclamationmark.bubble")
}
.tint(.blue)
Toggle(isOn: $config.tracelogs) {
labelWithIcon("Trace Logs", iconName: "waveform.path")
}
@ -264,11 +286,11 @@ struct SettingsView: View {
} footer: {
Text("Enable logs for troubleshooting and Enable automatic TrollStore JIT.")
}
// Advanced
Section {
DisclosureGroup {
HStack {
labelWithIcon("Page Size", iconName: "textformat.size")
Spacer()
@ -276,7 +298,7 @@ struct SettingsView: View {
.foregroundColor(.secondary)
}
TextField("Additional Arguments", text: Binding(
get: {
config.additionalArgs.joined(separator: " ")
@ -352,6 +374,15 @@ struct SettingsView: View {
#endif
}
func getCPUInfo() -> String? {
let device = MTLCreateSystemDefaultDevice()
let gpu = device?.name
print("GPU: " + (gpu ?? ""))
return gpu
}
// Original loadSettings function assumed to exist
func loadSettings() -> Ryujinx.Configuration? {

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Info.plist</key>
<data>
kW04s165Fr3AhY1rHcISuPzpuPA=
</data>
</dict>
<key>files2</key>
<dict/>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View File

@ -6,6 +6,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
class HvAddressSpace : IDisposable
{
private const ulong KernelRegionBase = unchecked((ulong)-(1L << 39));

View File

@ -8,6 +8,7 @@ using System.Threading;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
class HvAddressSpaceRange : IDisposable
{
private const ulong AllocationGranule = 1UL << 14;

View File

@ -265,9 +265,10 @@ namespace Ryujinx.Cpu.AppleHv
}
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
static partial class HvApi
{
public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
public const string LibraryName = "Hypervisor.framework/Hypervisor";
[LibraryImport(LibraryName, SetLastError = true)]
public static partial HvResult hv_vm_get_max_vcpu_count(out uint max_vcpu_count);

View File

@ -4,6 +4,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
class HvCpuContext : ICpuContext
{
private readonly ITickSource _tickSource;

View File

@ -3,6 +3,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("ios")]
[SupportedOSPlatform("macos")]
public class HvEngine : ICpuEngine
{

View File

@ -8,6 +8,7 @@ using System.Threading;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
class HvExecutionContext : IExecutionContext
{
/// <inheritdoc/>

View File

@ -7,6 +7,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
class HvExecutionContextVcpu : IHvExecutionContext
{
private static readonly MemoryBlock _setSimdFpRegFuncMem;

View File

@ -5,6 +5,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
readonly struct HvMemoryBlockAllocation : IDisposable
{
private readonly HvMemoryBlockAllocator _owner;

View File

@ -4,6 +4,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
class HvMemoryBlockAllocator : PrivateMemoryAllocatorImpl<HvMemoryBlockAllocator.Block>
{
public class Block : PrivateMemoryAllocator.Block

View File

@ -16,6 +16,7 @@ namespace Ryujinx.Cpu.AppleHv
/// Represents a CPU memory manager which maps guest virtual memory directly onto the Hypervisor page table.
/// </summary>
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
public class HvMemoryManager : MemoryManagerBase, IMemoryManager, IVirtualMemoryManagerTracked, IWritableBlock
{
public const int PageBits = 12;

View File

@ -4,6 +4,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
unsafe class HvVcpu
{
private const ulong InterruptIntervalNs = 16 * 1000000; // 16 ms

View File

@ -5,6 +5,7 @@ using System.Threading;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
class HvVcpuPool
{
// Since there's a limit on the number of VCPUs we can create,

View File

@ -5,6 +5,7 @@ using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
static class HvVm
{
// This alignment allows us to use larger blocks on the page table.

View File

@ -10,6 +10,7 @@ namespace Ryujinx.Cpu.AppleHv
}
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
static partial class TimeApi
{
[LibraryImport("libc", SetLastError = true)]

View File

@ -313,7 +313,14 @@ namespace Ryujinx.Graphics.Vulkan
lock (_queueLock)
{
_api.QueueSubmit(_queue, 1, sInfo, entry.Fence.GetUnsafe()).ThrowOnError();
Result result = _api.QueueSubmit(_queue, 1, sInfo, entry.Fence.GetUnsafe());
if (result != Result.Success)
{
Console.WriteLine($"QueueSubmit failed with error: {result}");
}
}
}
}

View File

@ -1,4 +1,4 @@
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.Cpu.AppleHv;
@ -49,7 +49,7 @@ namespace Ryujinx.HLE.HOS
bool isArm64Host = RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
if (OperatingSystem.IsMacOS() && isArm64Host && for64Bit && context.Device.Configuration.UseHypervisor)
if ((OperatingSystem.IsMacOS() || (!OperatingSystem.IsIOSVersionAtLeast(16, 4))) && isArm64Host && for64Bit && context.Device.Configuration.UseHypervisor)
{
var cpuEngine = new HvEngine(_tickSource);
var memoryManager = new HvMemoryManager(context.Memory, addressSpaceSize, invalidAccessHandler);

View File

@ -147,8 +147,8 @@ namespace Ryujinx.Headless.SDL2
[Option("audio-volume", Required = false, Default = 1.0f, HelpText = "The audio level (0 to 1).")]
public float AudioVolume { get; set; }
[Option("use-hypervisor", Required = false, Default = true, HelpText = "Uses Hypervisor over JIT if available.")]
public bool? UseHypervisor { get; set; }
[Option("use-hypervisor", Required = false, Default = false, HelpText = "Uses Hypervisor over JIT if available.")]
public bool UseHypervisor { get; set; }
[Option("lan-interface-id", Required = false, Default = "0", HelpText = "GUID for the network interface used by LAN.")]
public string MultiplayerLanInterfaceId { get; set; }

View File

@ -1283,6 +1283,19 @@ namespace Ryujinx.Headless.SDL2
renderer = new ThreadedRenderer(renderer);
}
bool AppleHV = false;
if ((!OperatingSystem.IsIOSVersionAtLeast(16, 4)) && options.UseHypervisor)
{
AppleHV = true;
}
else if (OperatingSystem.IsIOS())
{
AppleHV = false;
} else {
AppleHV = options.UseHypervisor;
}
HLEConfiguration configuration = new(_virtualFileSystem,
_libHacHorizonManager,
_contentManager,
@ -1306,7 +1319,7 @@ namespace Ryujinx.Headless.SDL2
options.IgnoreMissingServices,
options.AspectRatio,
options.AudioVolume,
options.UseHypervisor ?? false,
AppleHV,
options.MultiplayerLanInterfaceId,
Common.Configuration.Multiplayer.MultiplayerMode.LdnMitm);