New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Investigate feasibility of iOS support (prototype attached) #4198
Comments
Thanks for all your work on this, I've been eagerly following your work on Twitter the last couple of days. I think until we see an iPhone with 8GB of RAM released, that the market for this is going to be pretty slim. Skyline works (and can potentially be an actually useable emulator) because Android devices exist with 8GB and 12GB of memory. With that said, there is a lot of potential for optimising memory usage on UMA architectures, and with the better memory API's available on macOS/iOS a lot of the VA used for address space mirrors (etc) could be optimised. The 64GB of VA is always going to be a killer though. If anything, Ryujinx is likely moving in the direction of requiring more VA rather than less, with things like multi-process (and applet support) something that will likely come on the radar in 2023. Both of those things require maintaining a separate 36+ bit VA for each process/applet. You might be able to cobble together a build for iOS that didn't support those features, but the question is then about how many compromises you'd need to make before it's not worth it anymore, rather than is it possible at all. I know there is an entitlement for a larger address space on iPad Pro's, is that the same thing as the paid expanded 64GB VA on iPhone, or is that expanded address space even larger on iPad? Perhaps a more realistic target is Ryujinx on iPad... All in all, thanks massively for your work. Especially the launcher code, and the detailed documentation you've made, this will make it much easier for anyone to dabble with Ryujinx on iOS in the future. |
Decompressing and recompressing textures should not be required on the iPhone as AFAIK it supports the same compressed formats that the Switch does (BC formats, ETC2 and ASTC). At least that is the case on Apple Silicon. As a result GPU memory usage is also lower compared to desktop on games using those formats.
We can work around this using a multi-level page table, but it would make memory access even slower than what already is.
This should be easy to fix, we can allocate the memory for the JIT cache dynamically in chunks, instead of reserving a large region up-front.
There is another way to run the code directly which is simply loading it on memory and patching syscalls on the code to instead call the emulator implementation directly. But making this work also requires "Host memory" as the game should be able to access memory directly. Even ignoring the virtual memory issue, there's also the fact that those devices have 16 KB pages, and the fact that shared memory can't be mapped as executable. There are ways to work around all those issues, we already have one for 16 KB pages on macOS, for direct code execution we would need to make sure we can properly reprotect code memory as RX (for the code text section) and RW (for the data section) by carefully aligning the code in memory such as that the text section ends in a 16 KB page boundary. For the virtual memory issue, we would need to restrict the address space, I already experimented with this since Arm Linux usually only have 39 bits of virtual memory. In this case we would need to limit it to around 34 bits given we only get 36 bits at most on iOS. That is a lot lower but I think most games would still work. Of course that's assuming we have access to the 64 GB virtual memory extension, the default of 8 GB is way too low to make this work.
Not much we can do about that other than hoping Apple will loosen those restrictions in the future. I guess iOS users that are emulating newer systems are already used to that procedure.
As jD mentions above, most of those limitations does not apply to Android devices, this make it much more feasible.
It can still use "software" memory manager mode that does not require 36+ bit of VA for each guest process. We can also use reduced host mapped mode for the game and software mode for applets (since performance is not as important on those as it is for games). I think the main question is whenever or not it's worth it. There's several obstacles and working around them will sometimes have a compatibility and/or performance cost. |
I don't think iPhone supports BCn textures, at least right now. There appear to be a few GPU features of their hardware that are only accessible on MacOS, even on the M1 ipads... or at least that's what MoltenVK believes. Storage buffer writes from vertex/fragment are also not available, though many games avoid doing this entirely. The least impacted games as far as virtual memory goes are 32-bit games such as Mario Kart 8 Deluxe and Captain Toad: Treasure Tracker, though there are very few. I think you should be able to run those games host mapped with the same 16k page table workaround as macos, though you will need extended addressing to map both the 4GB physical memory and 4GB virtual memory regions. Decompressed BCn textures will definitely be an issue as they are much larger. Using CoreCLR is probably a much better choice than Mono. We rely a lot on assumptions about our operating environment, specifically around signal handlers, and all performance choices so far have been made to suit dotnet. I guess the only issue there is that running with a JIT will likely never be officially supported by dotnet. |
BC1-BC5 can be recompressed as ETC2/EAC and use the same amount of memory. ETC2 also has slightly higher quality than BCn so maybe it's possible to recompress without quality loss. BC7 can be recompressed as ASTC (I'm not sure if it can be recompressed as ETC2 without quality loss). The lack of storage buffer write from vertex and fragment seems more concerning. If it's from vertex, we can rewruite it as a compute shader. If it's from fragment, well I guess there's nothing we can do (unless it supports image store to a buffer texture? But if it doesn't support storage buffer it probably won't support that either). Alternatively one could use image store to a regular texture and then do a copy later... So yea, the issue is all those limitations. Working around all that would be a lot of work, and we still have many issues to solve even on M1 mac that doesn't have those limitations. |
Well I am no dev by any means, nor I can contribute by any means other than may be patreon support.
In the end all I wanna request with lots of gratitude is that, please don’t close this request, even if its low priority, keep it open, who knows within few months ios becomes more emulation friendly with upcoming os update. |
I doubt this will be a major issue. We will likely switch to Ava 11 soon after it comes out which is meant to be Q1 of this year, and will probably be finished before the PRs for macOS (and by extension many of the things needed for iOS) are upstreamed. |
Now, SideStore makes it so JIT can be done with only a Wi-Fi connection, so it wouldn’t be as much of an obstacle as it would be if you only used SideStore. |
Provenance took the code that dilphiios uses recently. It tries both altstore/sidestore method and if you've setup jit streamer, it tries that connection without using the jit streamer shortcut. You do need to pair it once with the instructions on jitstreamer.com but it's super simple. This will be added to sidestore as a developer framework but that feature isn't done yet. |
could possibly side-step the ordinary restrictions of JIT by compiling a bunch of gadgets at compile time and jumping between them, the output of the JIT would be a list of addresses to jump to in sequence. This paper explores the performance of such a scheme (using synthetic benchmarks) this doesn't help with any of the other issues though, and normal workarounds to use actual JIT have already been mentioned, so shrug |
The JIT mentioned in the first post is not the .NET Core JIT, I'd assume that we'd AOT targeting iOS. The JIT mentioned is the guest JIT we use to translate game code to host code. Obviously we can't do any sort of code generation for that at compile time, and this is where 99.99% of all of the JIT issues lie. |
I would be more worried about the virtual memory limitation. The JIT limitation is annoying but at least there's a way around it. I don't think there is a way around the memory limitation that doesn't require paying $100 per year. |
https://stackoverflow.com/questions/32664679/what-is-the-limit-on-virtual-memory-for-ios This post claims there’s no actual limit on virtual memory. For 64bit provessor limit is 18 exabytes according to post. People with better trained brain may understand what the post is saying. May come in helpful. |
You misunderstand, but I don't want to clog up the thread with my poor explanation when it's the least blocking issue. Read the paper if you're interested, it's the same concept as ROP (return oriented programming), but using jumps instead gives better performance if you're designing an application around this. |
@kitlith I do know about the threaded-interpreter approach:
However, since all sideloaded apps can get real JIT by attaching an Xcode debugger (or some VPN service emulating an Xcode), I'm not planning to look into it. @ansinerd As far as I can tell, that Stack Overflow answer is inaccurate: the 18 exabyte limit seems to be the theoretical maximum that a 64-bit CPU can support, not what's currently implemented in Apple's M1 CPUs (48 bits) or what iOS allows you to use (36 bits (64GB) with entitlement, 34 bits (16GB) without an entitlement on most devices). The other blog post that I found checked the iOS kernel source code to get the limits of ~16GB unentitled/64GB entitled, and so far my experience confirms it (I can only mmap a single 4GB region and a few 512MB regions before I run out of space.) |
Looks like NativeAOT will support iOS on .NET 8: dotnet/runtime#80905 |
OK, I was wrong about sideloading and memory limit: Apple does grant the extended memory entitlement even on my free provisioning, without paying $100. So we do get (64 - 8=)~56GB of address space and (on iPhone 14 Pro) ~4GB of RAM (can go slightly higher with debugger attached, ~5GB) even for sideloading. It still doesn't start up due to iOS's Metal limitations; for example, Pokémon Brilliant Diamond crashes the emulator after the language selection screen with
While Pokémon Scarlet got to the language selection screen once, froze, and on the next launch gave me
but at least it doesn't immediately go out-of-memory. |
The top error is pretty weird, I guess this is some MoltenVK quirk but it will probably break all games with multisampled textures. You can avoid seeing a multisample texture in this game by loading an existing save file, though it will crash in some of the cutscenes which trigger multisampling to be enabled. I don't understand the error for the bottom issue, though it's probably worth noting that I think something simpler like Super Mario Odyssey or Mario Kart 8 Deluxe are more likely to work, though they both use BCn textures which will inflate in size dramatically (4-8x) as they aren't available on iOS. I'm not really sure what doesn't use BCn. |
Also, what entitlements are you adding to the plist? I was testing with
...which seemed like it was pay-gating me. |
@riperiperi I have two hacky patches for MoltenVK that forces MoltenVK to report extra features (zhuowei/MoltenVK@64c648f, zhuowei/MoltenVK@215b4f9) to get Ryujinx to start up at all; I guess this means some of those features really aren't available on iOS after all. For what it's worth, for the top issue, if I disable Metal Validation, Metal still crashes with a similar multisample error:
|
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
does anyone know what commit to use to get a working build? and also how to embed a game? i do not know very much about emulation but i would like to try to build the ios launcher anyway. it would be great if i could contribute to this effort and help you all |
I took another look at this:
|
Did u get any answers? |
I have not looked further into this. If I have time this weekend, I'll try running the Vulkan test suite against MoltenVK on macOS vs macOS Catalyst to see if I can isolate why Brilliant Diamond renders a blank screen except in menus. |
@zhuowei I suggest running the test suite against your fork on Catalyst since this is what ryujinx-ios uses, and upstream MoltenVK on macOS since that is what upstream Ryujinx uses
@ansinerd Is Metal 4.0 is coming to iOS 17? Also, remember that, over time, there will probably be changes on upstream MVK if so. |
@duckfromdiscord Thanks for letting me know about the upstreamed macOS version. |
Glad to know that u dint give up and still looking forward to explore more |
I read it somewhere on discord |
thats nice to know bro |
Brother official arm port of Yuzu is released for android an hour ago. Their minimum requirement is 6gb of RAM and recommended is 8gb, i wish 8/16 gb RAM ipad pro m1/m2 should run it. Would u look into it as well? |
I don't think those requirements are accurate. Adreno GPUs also support BCn compression natively, iPhone doesn't have that. iPad might, MVK added support but IDK if the iPads advertise the capability. |
This comment was marked as spam.
This comment was marked as spam.
I think it would already be a big success if we can get it working on M1/M2 iPads first, because it's a much smaller step from macOS M1 to iPad M1 than to one of the tiny iPhone processors. Personally, I wouldn't want to play on a tiny iPhone screen anyway. But I am sure many people would go absolutely crazy over being able to play TOTK on an iPad. I just cloned myself the project although I probably can't be much help as I'm more of a backend developer and have never worked on emulators before. However, I would be happy to test if this helps |
Maybe one could port https://github.com/IsaacMarovitz/Ryujinx/tree/metal to iOS the same way as the MVK one? This is what I was hoping for |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment has been minimized.
This comment has been minimized.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
And I really hope people stop suggesting and asking silly things that have already been addressed by numerous knowledgeable developers of the emulator itself. Nothing has changed since all of the initial conversation about this. If it does, I'm sure you'll know about it. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Yes, the RAM requirement might be fulfilled and sideloading is now also possible. But as much as I’d love to play switch games on my iPad, until Apple provides its Hypervisor Framework to iPadOS, it won‘t be feasible to do a port. JIT emulation on mobile devices isn’t something you really want. |
The new JIT has almost the same performance that Hypervisor has on macOS now. |
Emulators are now officially allowed in App Stores worldwide. Emulators are also allowed in third-party stores for Europe. I suspect there's a good chance for hypervisor framework to debut in the iOS18 product cycle. Difference in screen size between Switch and iPhone Pro Max models is insignificant - Someone above said they didn't want to play on a "tiny iPhone screen" -hardly. They also called the processor on iPhone "tiny" - sure, in size, but it blows the doors off the Tegra in the Switch and a lot of low-end POS PCs in CPU/GPU performance. |
Yes, with iOS 18, and the Emulators being allowed in AppStore and even third-party stores in EU, we can finally hope to see some developement in iPhone emulation! The iphones processor are beasts in comparison to Switch (CPU/GPU) |
@ParanoidHitman Still impossible without JIT. There isn't a single CPU on earth that's fast enough to emulate the Switch CPU with an interpreter at playable frame rates. It's not even fast enough to run GameCube games on Dolphin without a JIT compiler. Besides, the App Store rules explicitly say that it's limited to retro games. |
Feature Request
What feature are you suggesting?
Overview:
Ryujinx recently added support for macOS Apple Silicon / Metal. This support can be used as the foundation for an iOS port.
I made a terrible prototype Ryujinx launcher that launches an unmodified Ryujinx 1.1.0-macos1 build on an iPhone 14 Pro on iOS 16.1. It barely runs a homebrew game, but it proves that iOS support may be possible.
I do not expect iOS devices to be able to run games at full speed and fidelity in the short term. However, they may be able to emulate small/simple games.
I'm not sure how feasible or worthwhile an iOS port would be, so I'm creating this feature request to list the limitations / challenges I encountered when building the prototype.
Please let me know whether this is worth pursuing, and what I should do to help.
Smaller Details:
For my prototype, I used:
OperatingSystem.IsMacOS
is true andIsIOS
is false), but using the iOS SDK, to minimize the changes requiredThis was enough to run Helltaker, a homebrew 2D Unity game by D3fau4 / vanripper - with occasional crashes from running out of memory or the GPU not responding (probably also out of memory?).
I did not try running any commercial games, because it barely ran a 2D homebrew as is - I doubt it'd would be able to handle anything more.
The main issues preventing Ryujinx from emulating a Switch on iPhone are:
lack of physical memory:
The Switch has 4GB of RAM, and Ryujinx itself requires at least an additional 1.5GB of RAM. The iPhone 14 Pro only has 6GB RAM total.
According to jduncanator, there is also significant extra RAM usage from Ryujinx emulating VRAM and decompressing/recompressing textures.
lack of virtual memory:
A desktop computer gives each application hundreds of terabytes of virtual memory.
iOS gives each app less than 8GB by default (!!)This is barely enough to fit Ryujinx's various reserved memory regions, such as the emulated 4GB Switch memory or the 512MB JIT cache.Even with a $100/year developer membership, you can only get 64GB of virtual memory.Update (2023-01-22): I was wrong: free apps can ask for 64GB of address space using the extended memory entitlement. This is still well below the amount you get on desktop platforms.
I had to patch Helltaker's .nca npdm flags to choose a 36-bit instead of a 39-bit address space, because there's not enough host virtual address space to allocate the 1GB JIT pagetable
Similarly, I intercept the mmap for 2GB of JIT cache and return only 512MB, since there's no space for 2GB.
JIT Host memory will probably never work, as discussed on Twitter: even with a paid account you get only 64GB of host address space, or 36 bits, so host emulation would leave no memory for Ryujinx itself.
lack of hypervisor support:
Ryujinx on macOS uses Hypervisor.framework to run Switch's CPU code directly
iOS does not offer this framework, so Ryujinx has to fall back on the slower JIT.
missing Metal features
Even in Helltaker, a simple Unity-based homebrew, Ryujinx on iOS fails to render the selected highlight around its menu options.
Ryujinx on macOS Apple Silicon does render it correctly, so it appears iOS Metal / MoltenVK is missing features.
Apple's stance on JIT and emulation
Emulators are not allowed on the App Store, so emulators must be sideloaded.
This is much more involved than downloading apps from the store: the user must set up some way to sideload the app, for example, using AltStore, and the app must be re-installed every 7 days.
While sideloaded apps can access JIT (unlike app store apps), the procedure is a hassle to set up.
Nature of Request:
Why would this feature be useful?
For users, it would offer an additional option to emulate games on the go.
The text was updated successfully, but these errors were encountered: