The Impossible Port: MacOS

The Impossible Port: MacOS
"We're really, really excited about games, and again our goal, is to have the best gaming machine in the world."

Let's cut to the chase: macOS and Apple Silicon support (including older Intel Macs, although your mileage may vary)!  Even with all the hurdles, roadblocks and brick walls put in our way, we're finally back on Mac! And back in style!

With the launch of a new entry in the vast Pokémon library and an already brimming catalog of nearly 4000 incredible Switch titles, we hope you're as excited for this release as we are. Today, Ryujinx claims ANOTHER groundbreaking advancement to Switch emulation, tapping the unique potential of Apple Silicon to deliver the first & only macOS-compatible Switch emulator. The potential for Apple Silicon Macs is unparalleled in the current market. These devices could enable emulation that is closer to a native port than most gaming PCs, thanks to the powerful ARM synergy they share with the Switch.

We're committed to writing an accurate, stable and performant Nintendo Switch emulator with no hacks or shortcuts. If you wish to support us in delivering our goals across Windows, Linux and now macOS too, then consider backing us on Patreon and letting us know how everything is going over on Discord.

This release also includes LDN functionality - the ability to play with other Ryujinx, and CFW Switch users, via our hosted servers, LAN or ldn_mitm. You can read more about the features of LDN3 in this separate post!

Just want the download? Head over to our website.
Give the install guide below a read first though!

Install Guide

This will be split into two sections: macOS 12 'Monterey', macOS 13 ' Ventura' and above (if you're reading this in the future).

macOS 13 'Ventura'

  • Extract the downloaded zip package from the download page somewhere safe. We recommend against any folders that may be protected or otherwise cause permission issues, such as directly on the desktop or at the root of any drive.
  • When you try to run the 'Ryujinx' executable you will be met with this pop-up, as the build is not officially signed.
We promise we aren't malicious software.
  • At this point you'll need to go to Settings and then navigate to Privacy & Security.
  • Scroll down to the Allow applications downloaded from options and you will find a box informing you that Ryujinx was blocked; select Open Anyway. A pop-up will ask you to confirm this choice.

This is a one-time process. Subsequent boots will not need to authorise Ryujinx. We are looking into official signing of macOS releases in the future!

macOS 12 'Monterey'

  • Exactly the same process as above but your settings window will look a bit different!
  • Attempt to boot Ryujinx, then navigate to Security & Privacy.
  • Select the Open Anyway option near the bottom of the page, a pop-up will ask you to confirm this choice.

Alright, if any of you are interested in the nerd stuff, how we got it to work and what challenges still remain then the bulk of this post remains. Even if you're the kind of person to never read the manual, we'd suggest reading this anyway. Having a base understanding of what's happening, the current strengths and limitations, and future work will help enormously if and when you have questions.

New SoC, who dis?

Credit: TechRadar

When we last supported macOS, Apple was booorriinnggg. They used the same architectures and hardware as regular desktops and laptops, but with worse software support. However, since the shift to their own 'Apple Silicon' SoCs (System on a Chip), many consumers, and more importantly, developers have been foaming at the mouth to see what they're capable of. For Switch Emulation it's a bit of a double kill with the increased performance of Apple Silicon combined with the 1:1 ARMv8 CPU architecture of the Switch's Tegra X1.

Implementing ARM compatibility is a big-deal for normal software, and emulators are far from normal. But, as we alluded to earlier, one of the niceties for Switch Emulation in particular is that the host and guest system both execute the same code. Dedicated optimizations for Apple Silicon have thus been made:

  • ARM Hypervisor - Allows native ARMv8 code execution with no translation. The overhead cost of emulating the game code is almost entirely removed, accessing the full potential of the chip.
  • ARM64 JIT - ARM support has been added to our CPU JIT recompiler 'ARMeilleure' for cases where the above hypervisor won't work, such as 32-bit titles like Mario Kart 8 Deluxe. This has been optimised to allow a much more direct mapping for floating point instructions and behaviours compared to x86. Because of this, there is a lot more potential for JIT performance than regular x86 CPUs.
  • For the rare titles that don't work using the Hypervisor, a manual option to use the JIT has been made available. Beware, while this may increase compatibility, performance and stability will be severely impacted.

While the ARM CPU cores on Apple Silicon are mighty impressive, not everything is as rosy on the GPU side...

A trip down memory lane...

For those unaware, Ryujinx did initially support macOS all those years ago, before our OpenGL version-needs exceeded what Apple was prepared to provide. Apple have since fully deprecated OpenGL on macOS and support only very old versions for legacy purposes, thus forcing our exodus. While Apple do develop and maintain their own proprietary graphics API 'Metal', many had hoped that the new kid on the block, Vulkan, would eventually be on the agenda for Apple going forward. Unfortunately, here we are in 2022 with no sign that anything other than Metal is a priority or even a goal on Apple's roadmap.

Many other emulators such as RPCS3, PCSX2, and most notably Dolphin have all, over time, been able to implement graphical support for macOS via one of two routes: a Metal backend or MoltenVK. Some used both at one point or another.

Vulkan... Volcano... Molten. I see what you did there!

MoltenVK is a library that translates between Vulkan and Metal, effectively meaning if you have a Vulkan backend you can make use of MoltenVK to translate those calls to Metal; thus acting as a pseudo-Metal backend. The issue is that those aforementioned emulators all mimic consoles with relatively old GPU architectures which, while complex in their own ways, do not particularly stress the limits of Metal, Vulkan, and by extension MoltenVK. By contrast, the Switch uses a relatively modern (architecturally-speaking) Nvidia GPU, with all the bells and whistles that follow along. To say that this stretches Metal would be an understatement. Fundamentally it's a brick wall.

Or at least that's what we thought...

Fetching our Sledgehammers

This was not easy. Metal being feature-barren, and the new Mac GPUs being closer to mobile hardware than desktop has caused a whole world of hurt. Core extensions and features simply don't exist and paths that a desktop GPU would consider "free" are suddenly huge rendering costs, if they even have the ability to render at all. It's hard enough to make a Mac port of a video game that you yourself develop; it's even harder when you have no power over what the emulated game requests from your system.

Luckily our GPU developers are experienced in the dark arts of getting stuff working on APIs and hardware which hate cooperating. Let's run through some of the core issues faced and how they're being overcome. This may be for the tech-wizards; but we'll try to make it digestible!

  • 4-byte Vertex Buffer Alignment Requirement: A very large number of games bind vertex buffers that just contain one attribute. When they do this, they tend to pack them tightly, which is allowed on normal graphics APIs. However, Metal demands that the stride aligns to 4 bytes, no matter what the size of the attribute is. To do this, we have a compute shader converting incompatible vertex buffers functioning alongside a cache, so the cost is only paid once. Most games would not work without this.
  • Transform Feedback: Transform Feedback is another feature that doesn't exist on Mac, but is used by a few choice games like Xenoblade and Legends Arceus. We have a rather ingenious (but complicated) solution to this - just write the transform feedback outputs to storage buffers at the end of the vertex stage. The result is just as fast and works properly across affected titles.
Transform Feedback: Pokémon Legends Arceus
  • 16 Samplers: This issue is a bit of a killer, since more complicated Switch games bind a lot more textures and samplers than this. Thankfully, this limitation can be avoided through Metal Argument Buffers, which MoltenVK has an option to use. This has proven to be a bit buggy and slower in general, but significantly more games work thanks to it.
  • Triangle Fan: A rather niche topology that draws triangles around a starting point, occasionally used to draw quads and circles in user interfaces. We support this by using the same compute shader conversion path as we do with vertex buffers, but converting an index buffer to the target topology instead. This has actually already been added to mainline, in the form of quads to tris conversion, which ended up faster there too.
  • No Sampler Bias: We just pretend this doesn't exist for now. A rather ingenious solution, if you ask us.
  • Geometry Shaders: Geometry shaders do not exist in Metal or MoltenVK. Used for writing 3D textures in UE4 games, and a number of complex graphical effects in others, missing this would definitely hurt compatibility. However, gdkchan has come up with a clever method to emulate these stages using additional draws to vertex shader only. The result is incredibly impressive - hardware-accelerated geometry shaders on a GPU that doesn't support them. Coup de grâce!
Geometry Shaders: Yoshis Crafted World

Alas, we're not all-powerful deities nor wizards with magic wands. There are some things that we simply can't work around, most of them being architectural. As we mentioned before, the GPUs in Apple Silicon Macs are fundamentally different to typical desktop/laptop GPUs. These GPUs are more similar to mobile hardware where rendering is done in tile memory, which is copied to/from the unified memory when a render pass happens. This means that updates to buffers in the middle of a render pass are more costly than usual, as it can result in render targets being copied in and out of memory all the time. However, the macOS build includes many strategies that attempt to mitigate this almost entirely, and some of these changes have already started being upstreamed (with positive performance impacts on Windows/Linux!).

And now, after we've spoken so much about the GPU, let's see it all come together and render something!

Media Gallery

Animal Crossing: New Horizons
Mario Kart 8 Deluxe
Super Mario Odyssey
Finally... a Nintendo 64 emulator on MacOS :D

Known issues

Ryujinx is an experimental emulator, and this is our first release on a completely different platform and architecture. Experimental-squared! As such, there will be issues.

  • ARM64 Hypervisor does not function in all titles, most notably The Legend of Zelda: Breath of the Wild. Manually forcing the ARM64 JIT may allow these games to boot. Forcing Ryujinx to run via Rosetta could also be a potential option, although this is relatively uncharted territory as far as stability goes.
  • Shader stutter is amplified due to the translation required between Vulkan's SPIR-V and Metal's MSL shaders. While not as significant as OpenGL, it is noticeable.
  • General performance, stability and graphical issues will occur. We haven't tested every game under the sun but we're sure you guys will!

Closing words

All in all, we're pleased with what we've managed to accomplish. A barrier that many, including ourselves, originally thought unbreakable has been cracked wide open, and the best part is: this is just the beginning. With not only our own efforts to improve the core emulation, but upcoming updates to Metal 3 and the constantly improving MoltenVK, the experience is only going to get better.

To wrap up, the download is here, our Discord is here, and if you wish to support us on Patreon you can find us here.