Ryujinx wrapped up Q1 and put a snazzy bowtie on it with an absolute avalanche of graphical bug fixes for some of your favorite games, and a significant increase in compatibility & stability in games utilizing Unreal Engine 4, thanks to the introduction of Texture Groups/Texture Dependencies and a handful of other related improvements.
The new Switch-exclusive game Bravely Default II was released at the end of February, and its status in Ryujinx progressed from “almost completely broken” to “almost perfect” in just a few weeks’ time.
Amiibo emulation (our first Patreon goal) was also merged into the main build this month! Thank you to all who helped during the Amiibo feature’s public testing phase; many bugs were identified & fixed, and game compatibility with the feature improved greatly as a result.
Before diving in to all of the March 2021 updates, let’s take a look at the current state of Ryujinx’s Patreon goals and deliverables:
Amiibo Emulation - merged into the main build on 3/18/21.
While compatibility is now almost perfect, there are still some improvements to come for Amiibo which can be tracked on the associated Github issue here: https://github.com/Ryujinx/Ryujinx/issues/2122
Custom User Profiles - still in progress. This was delayed several weeks but is back on the docket!
Vulkan GPU Backend - in progress, ETA April 2021 for public testing. See below for a more in-depth report on the progress of this feature.
$1500/month - ARB Shaders - Almost there!
ARB shaders will further reduce stuttering on first-run by improving the shader compilation speed on NVIDIA GPUs using the OpenGL API.
$2500/month - One full-time developer - Not yet met
This amount of monthly donations will allow the project's founder, gdkchan, to work full-time on developing Ryujinx.
$5000/month - Additional full-time developer - Not yet met
This amount of monthly donations will allow an additional Ryujinx team developer to work full-time on the project.
We realize there is a large gap between the ARB Shaders goal and the first full-time developer goal, so we will be looking to add at least one more goal soon to bridge the gap.
Vulkan Progress
The Vulkan implementation is progressing steadily; most of the features are already implemented. Since last month’s progress report, transform feedback, conditional rendering and buffer textures were implemented. Some time was also invested in improving performance; Super Mario Odyssey is now more than twice as fast on Vulkan than OpenGL on Intel iGPUs. On NVIDIA, performance is currently slightly slower than OpenGL, but can be potentially a bit faster after the remaining optimizations are implemented.
Tests on Intel GPUs just began, and we will commence testing on AMD GPUs shortly. We plan to deliver the first Vulkan preview in the middle of April as promised!
Below we can see how Super Mario Odyssey currently renders in OpenGL on an Intel iGPU:

And here's Vulkan on that same Intel iGPU for comparison:

And here we can see transform feedback working on Xenoblade Chronicles Definitive Edition (required in order to render the grass).

Will Vulkan include a shader cache?
The main goal right now is getting Vulkan working before the estimated release date. If this is done before the estimated date, and there's still enough time left for a shader cache implementation, then shader cache could be added. Otherwise, it will be left as a follow-up task and will be implemented after the Vulkan implementation is merged into the master branch of the emulator. To clarify, our ETAs of these Patreon goal features is the estimated time to develop the feature and submit the PR (pull request) for public testing & review. Actual merge dates into the main build may vary and do not have ETAs.
Will Vulkan include async shader compilation?
No, for the same reason it is not implemented in OpenGL. The async shader compilation feature implemented on other emulators come with compromises like visual glitches while shaders compile, some of them being persistent until emulation is stopped. It also does not fully eliminate stutter as some shaders cannot be compiled asynchronously. For those reasons, the current Ryujinx GPU emulation developers are not interested in implementing it. We are not opposed to an external contributor implementing this feature, however.
Will Vulkan support resolution scaling?
Yes. The goal is having feature parity with OpenGL upon release.
What kind of improvement can I expect?
AMD and Intel GPU users should expect a significant improvement in compatibility, performance and, especially for Intel GPU users, a drastic reduction in graphical glitches. NVIDIA users can expect a small performance improvement in a few titles (we will defer saying which ones until after the Vulkan implementation is properly optimized and tested). All GPU vendors should benefit from faster shader compilation and less stuttering on Vulkan.
What's currently missing?
Vulkan still needs the following: alpha test, multisampling, resolution scaling, shader cache, complete SPIR-V support, and of course thorough testing on AMD and Intel GPUs.
Textures are actually a collection of multiple images: mip levels, 3d texture slices or 2d textures in an array. Texture Groups greatly improve both the memory management when handling individual images and when sharing images between overlapping textures, reducing the time these textures contain old (usually "swapped") or garbage data. Texture Dependencies allow for images in the same location in memory to copy to each other when we can't create a "view" with OpenGL. This fixes a ton of issues with wonky texture use, such as when drawing to overlapping texture arrays and compressed textures. The net effect is improved graphical accuracy for a more faithful reproduction of what is seen on original hardware.
For a more in-depth explanation of this new functionality, please see the original pull request here:
https://github.com/Ryujinx/Ryujinx/pull/2001
Character select screen:
Before:

After:

Electrodome:
Before:

After:

Royal Raceway:
Before:

After:

A Hat in Time:
Title screen
Before:

After:

Mafia Town
Before:

After:

Super Mario Odyssey
Fog (Metro)
Before:

After:

Fog (wooded)
Before:
https://user-images.githubusercontent.com/1518948/108624037-60a0cf00-7496-11eb-9e2e-436faca3c6f3.mp4
After:
https://user-images.githubusercontent.com/1518948/108624003-2cc5a980-7496-11eb-8260-384f5bf18d9e.mp4
Seaside Waves
Before:
https://user-images.githubusercontent.com/1518948/108624028-554da380-7496-11eb-9425-846458e63fb7.mp4
After:
https://user-images.githubusercontent.com/1518948/108624010-3818d500-7496-11eb-852d-5a647c6f74ab.mp4
Plaza (1st load)
Before:

After:

Menu buttons
Before:

After:

Yoshi’s Crafted World
Before:
https://user-images.githubusercontent.com/6294155/108612697-fd099980-73e2-11eb-97f4-66d2e3a935cd.mp4
After:
https://user-images.githubusercontent.com/6294155/108612715-0c88e280-73e3-11eb-8853-1d6384527bb3.mp4
Other improvements that we’d love to include comparisons on, but really need to keep the progress report under 50 pages...
Implemented on (#2001) by riperiperi
Following the Texture Groups/Texture Dependencies update there still remained a large problem with instability in games utilizing Unreal Engine 4, especially the newer varieties of the engine such as the one used by Bravely Default II. The improper handling of unmapped GPU resources can lead to frequent crashes and in many cases the inability of the emulator to even go in-game on an affected title.
This update took care of several issues at once:
Buffers can try to sync memory that's unmapped if the size is too large, which it usually is for UE4 games, as it seems to pass in a large uniform buffer size no matter what is actually in the slot. These fixes prevent that from happening.
Textures can try to sync memory that's unmapped if a smaller view is created within a larger texture, but part of that larger texture has been unmapped. This can also happen due to GPU virtual addresses for a texture being mapped to something else, but its pool entry remaining unchanged. It's important that we do partial sync only with the data that we know is available to avoid an invalid memory access.
This greatly improves the emulator's stability for newer UE4 games, such as Bravely Default II. Does not fix all crashes, though.
Quick fix list:
Implemented on (#2083) by riperiperi
Memory tracking initially supported tracking physical regions of memory, as a potential goal was to replace the memory tracking part of software address translation, and rely on host memory protection of the switch "physical memory" to signal tracking when needed. This would have simplified memory instructions in the JIT, but it turned out that OS memory protection and signals cost a lot more than just doing the protection in software.
Virtual Regions created within the tracking structure would also maintain a collection of Physical Regions that make it up. These are calculated at creation, and recalculated any time the virtual region is mapped or unmapped. This physical region recalculation is quite expensive, and becomes a large problem when the guest (the game that is running) decides to map/unmap cpu va at a very granular level.
With this update, physical region tracking is removed entirely, as it is not used and can cause a lot of unnecessary work to be done by the emulator.
The net effect is a reduction in boot time in some Unreal Engine 4 games; in Bravely Default II the improvement was a nearly 50% reduction in boot time! Another benefit is the mitigation of a type of in-game stutter that is not related to shader compile.
Below is an example of a pain point in Bravely Default II where going in or out of a building caused a noticeable stutter.
https://i.imgur.com/pfiO1HH.mp4
After the update, there’s no more stutter!
https://i.imgur.com/Gvv6tax.mp4
Implemented on (#2085) by riperiperi
Buffer textures are one-dimensional textures whose storage comes from a buffer object. These buffer textures are used to allow a shader to access a large table of memory that is managed by a buffer object. This update reworks buffer textures to create their buffers in the TextureManager, then bind them with the BufferManager later. Additionally, an issue was fixed regarding width unpacking for large buffer textures; the width is now 32-bit rather than 16-bit. Finally, buffer textures are now forced to be re-bound whenever any buffer is created.
The sum of these changes fixes all vertex explosions and flickering animations in Unreal Engine 4 games, and is particularly impactful in Bravely Default II.
Before:

After:

Before:

After:

These changes also fixed broken lighting in Fire Emblem: Three Houses that had been plaguing the emulator for quite a long time!
Before:

After:

Implemented on (#2088) by riperiperi
The first update in this paired group—Flip component mask if target is BGRA— fixes an issue in which we simply forgot to swap the component mask when using RGBA textures as BGRA (since OpenGL does not support BGRA textures). This led to situations where textures that were meant to be drawing only blue were actually drawing only red and vice versa.
On its own, this fix didn’t affect anything that we know of.
However, together with another update—Traverse PhiNodes for Bindless elimination— to allow bindless handles to be found for image/texture instructions with predicates when the assignment of the texture handle is within the same predicate, the missing graphics in Billiards and Shooting Gallery in Clubhouse Games: 51 Worldwide Classics were restored, and the black eyes & missing shadows were fixed in Bravely Default II.
Bravely Default II comparison (check the eyes and the lack of shadows. Ignore the difference in daylight as the screenshots were taken at different times of day in-game).
Before:

After:

Implemented on (#2087, #2089) by riperiperi
Even after all the updates mentioned above, Bravely Default II was still randomly crashing frequently. The issue was tracked down to a scenario where width could be greater than stride due to alignment when copying textures with the copy buffer method. After this update, the game is much more stable (but still retains the right to crash on rare occasions).
Implemented on (#2091) by riperiperi
Since the introduction of Ryujinx’s resilient disk shader cache feature, code name Salieri, many have enjoyed the stutter-free enjoyment of playing a game with cached shaders. However, in certain games having shader cache enabled was causing crashes on the 2nd boot of a game. This was due to an issue with the emulator’s handling of bindless textures and associated shaders. Many games utilizing Unreal Engine 4 use bindless textures so with all of these improvements to UE4, the shader cache issue stuck out like a sore thumb.
To alleviate these issues and make it so that the shader cache can stay enabled, Thog’s change essentially blacklists shaders that are using bindless textures from being cached. No more crashes on boot in hundreds of UE4 games.
mageven further optimized the implementation to catch bindless textures even earlier in the process (in the decode phase instead of the later translation phase) to prevent any cache-related processing. This optimization fixes a crash on boot in the Monster Hunter Rise version 1.1.1 game update if shader cache was enabled.
This is a temporary workaround that will be replaced with full bindless texture support so that all shaders may be cached safely. Look for more on that soon!
Implemented on (#2097, #2145) by Thog & mageven
In the wee hours of March 26th, a user somewhere in East Asia reported the results of testing Monster Hunter Rise on our Discord server, uploading a log that referenced a crash occurring due to a missing ARM instruction. This instruction was being called by the in-game camera function. This camera functionality was in turn part of the Monster Hunter Rise built-in tutorial, so any users who were following the tutorial would end up crashing if they tried to take a picture.
This update provides the necessary ARM instructions to be able to take the picture without causing a crash. Note that attempting to view the picture album in-game crashes the emulator for other reasons, so don’t open the album until we’ve had a chance to fix it!
Instead, thanks to the “Implement SaveScreenShot calls and cleanup” update mentioned in the HLE Improvements section below, you can retrieve your in-game screenshots as JPG files in %appdata%\ryujinx\sdcard\nintendo\album\.
Implemented on (#2139) by LDj3SNuD
After establishing Patreon goals early this year in the hopes of ultimately enabling the project’s founder, gdkchan, (and hopefully another developer one day) to work on the project full-time, the first goal—Amiibo scanning emulation—was reached almost immediately. The feature was released for public testing in early February and, thanks to many end user reports, a handful of bugs were identified and fixed before Amiibo scanning support was merged into the main build a couple of weeks ago.
What are Amiibo good for?
Amiibo are essentially physical cheat codes for many popular games, unlocking exclusive content in some games and providing on the spot bonus items in others. In Ryujinx’s case, they are 100% virtual and can all be used so long as you are actively connected to the internet.
How does Ryujinx’s Amiibo emulation work?
We currently use a self-hosted fork of a time-tested API (https://github.com/N3evin/AmiiboAPI - big thanks to N3evin!) so end users don't have to provide any Amiibo dumps. The benefit of using this API is being able to use all Amiibo and associated information & images with just a couple of clicks through the Ryujinx user interface.
To scan an Amiibo:
1. Go to the Amiibo-specific scanning location or in-game menu option in a supported game.
2. Click on the Ryujinx Actions menu header > Scan an Amiibo which will bring up the Amiibo UI, seen in the screenshots below


And yes, these Amiibo are indeed writable, which means you can train them up in Super Smash Bros. Ultimate!

Implemented on (#2006) by AcK77
After the IPC refactor part 2 was merged in December, a rare but frustrating bug could occur in certain situations. Most commonly, the issue manifested in scenarios where more than one controller was enabled/configured but not in use; some games could end up crashing with an “out of handles” error if they tried to create an applet multiple times (seen in Splatoon 2).
This update fixes the issue by ensuring that the associated handles are properly closed on disposal, and these crashes no longer occur.
Fixed on (#2094) by gdkchan
Ryujinx has been bundled with the OpenAL library developed by openal-soft since late December, and since then some strange audio quality issues began to be noticed by some users: in certain situations, the game audio was noticeably degraded while using the OpenAL backend. This was caused by Windows believing the attached audio device was a pair of headphones, and then the openal-soft configuration applying associated audio filtering.
This update enforces the audio output recognized by OpenAL to be stereo speakers, preventing headphone filtering from occurring.
Implemented on (#2101) by Thog
After the audio change above, there still remained some very noticeable issues in audio quality with Pokemon Sword/Shield in some edge cases. It turns out that some games read the active audio device name, and if they detect it as the Switch’s internal speakers, the audio output is essentially butchered so that the internal speakers are not overloaded.
This update hardcoded the active audio device to be identified as a TV, preserving the original audio feed and fixing audio in Pokemon Sword/Shield (and other games that may have had the same issue) for good.
Implemented on (#2103) by riperiperi
Many Switch titles use networking in some form or another, with some requiring a service call to perform internet connection checks in order for the boot process to continue, or to go in-game. As a result, over a hundred tested games in the compatibility list were crashing as a result of a few of these being services that were yet to be implemented in the Ryujinx main build.
With these services already being part of the Ryujinx (internet multiplayer enabled) LDN build, this update brought the code over to the main build, resolving the missing service crashes and enabling many of these titles to become playable. A pleasant side effect of this update is that there are fewer differences between the main build and the LDN build, meaning fewer items to maintain separately and an easier eventual integration of the LDN functionality into the main build.
Implemented on (#2130) by Thog, riperiperi, AcK77
A few newer Switch games failed to boot in Ryujinx for a particular reason: these games were built with version 11.x of the Nintendo SDK, which adds some newer services. Without these services implemented in the emulator, these games could crash on boot. These games included WereWolf Princess Kaguya, The Witch and The 66 Mushrooms, and CARRION, which now boot properly.
In one of the emulator’s more lucky moments, this implementation was merged just one day before Monster Hunter Rise’s release-day 1.1.1 game update which happens to require these services; the original version 1.0.0 does not use these newer services. In tandem with the bindless texture/shader cache handling updates this month, Monster Hunter Rise fans can now enjoy the 1.1.1 update.
Implemented on (#2136) by AcK77
Some Switch games have an in-game camera/screenshot functionality that has never worked in the emulator. The most well-known example is Animal Crossing: New Horizons, but the recently released Monster Hunter Rise also contains this feature. Until now, attempting to take a picture would simply crash the emulator.
This update implements all necessary service calls to facilitate this functionality, with a twist (since the underlying Switch operating system is not present to show the screenshots): ImageSharp is used to generate JPG files from the raw screenshot data, so you can retrieve your Animal Crossing or Monster Hunter Rise screenshots from %appdata%\ryujinx\sdcard\nintendo\album\.
In conjunction with the missing ARM instructions added (as mentioned in the Kernel & CPU Improvements section), the in-game camera is now working in Monster Hunter Rise as well. Note: trying to use Monster Hunter Rise’s album viewer results in a crash, so don’t use it! Stick to retrieving your pictures manually from the path mentioned above.
See below for a couple of in-game pictures generated with this new functionality.


Implemented on (#2140) by AcK77
One of the more fun things an emulator can be used for is modifying memory addresses in real-time. This can be leveraged in a variety of ways but is most often used to cheat: infinite lives, invincibility, starting the game with a rare item, or any number of other less-game breaking advantages can be granted just by placing a file in the right place for the cheat functionality to kick in. Another use for real-time memory modification is uncapping the frame rate, or disabling the anti-aliasing filters that can make games look blurry.
Note that romfs/exefs mods that modify game code prior to startup (and support framerate uncapping/AA disabling, etc.), have been working in the emulator since the middle of 2020.
With this new implementation, coined TamperMachine, runtime mods & cheats work natively in the emulator. This includes all Atmosphere-style cheats, with the exception of pause/resume.
Below is an example of a cheat in Mario Kart 8 Deluxe now natively working to allow the player to start the race with 10 coins:

And another “cheat” used to change the intended framerate of Monster Hunter Generations Ultimate from 30fps to 60fps.

Implemented on (#1928) by caian
After all of the other improvements and bugfixes for Monster Hunter Rise this month, there was still a pain point for some users who were using version 1.1.1 of the game: on first launch, the Privacy Policy/”Play Data Collection/Analysis” screen would pop up and softlock the emulator, leaving the user unable to proceed. This was due to a missing service related to the web applet that handles the exit operations.

With this update, the softlock is resolved and the 1.1.1 update version game is able to be progressed through without any privacy policy softlock issues.
This update also fixes a softlock that could occur in Monster Hunter Generations Ultimate
Implemented on (#2142) by AcK77
Up until now, when waiting for a game to boot, an end user would need to watch the somewhat cryptic console window to see if PPTC/PTC or Shader Cache were loading, and even then the indicators were not very clear unless one knew specifically what they were looking for.
Thanks to the joint efforts of Joshi234 and mageven, there is now a loading bar at the bottom of the main window showing each the progress of PTC and Shader Cache pre-boot operations, respectively.

Implemented on (#2057, #2129) by Joshi234, mageven
Since optional custom data directories were implemented last August, many have enjoyed using the feature as a sort of “portable mode” option. Unfortunately, these custom data directories had to be called via command line parameters or a batch script on every launch.
With this update, simply placing a subfolder named “portable” under the Ryujinx program base directory automatically activates portable mode on launch of the executable; this subfolder will then be used for all Ryujinx system data (shader cache, game saves, PPTC, etc.). This also means that the main Ryujinx folder is now fully portable and can be moved at will. Custom parameters and batch scripts are no longer necessary!
Implemented on (#1885) by mageven
3031 titles tested
44% playable - no visible bugs; no crashes or deadlocks; fast enough to enjoy on an average PC
33% in-game - goes past menus but suffers from visible bugs, crashes, deadlocks, or is too slow
10% menus - boots and goes past the title screen but does not reach main gameplay
8% boots - boots but does not advance past the title screen
5% nothing - does not boot/shows no signs of life
3242 titles tested - (211 new additions)
58% playable - no visible bugs; no crashes or deadlocks; fast enough to enjoy on an average PC
26% in-game - goes past menus but suffers from visible bugs, crashes, deadlocks, or is too slow
6% menus - boots and goes past the title screen but does not reach main gameplay
5% boots - boots but does not advance past the title screen
5% nothing - does not boot/shows no signs of life

Apart from the huge increase in compatibility overall this quarter, games utilizing Unreal Engine 4 in particular realized significant benefits in March. Out of the roughly 230 UE4 tested titles, after the major improvements PRs #2001, #2083, and #2085 delivered: 80% now go in-game (with many now graphically perfect), compared to roughly 30% going in-game previously. Of those UE4 titles that were already going in-game, graphics are now perfect in dozens of them.
Below are just a few examples of the many UE4 games that improved in March:
February 2021:

The title screen was missing all of the background graphics and the game rendered mostly black from here on out, making gameplay impossible.
March 2021:

The title screen is now rendered properly.

And the game is playable!
February 2021:

(game crashed shortly after this broken main menu screen)
March 2021:

The main menu screen now renders correctly.

And the game is playable!
February 2021:
(not pictured because the game did not boot)
March 2021:

Torchlight III is now playable!
February 2021:

While stable, the game was missing lighting & textures making gameplay difficult if not impossible.
March 2021:

Lighting & textures now look the way they’re supposed to, and the game is playable!
Spongebob SquarePants: Battle for Bikini Bottom - Rehydrated
Xenon Racer
Subdivision Infinity DX
Bee Simulator
Welcome to Hanwell
Samurai Shodown
ELEA: Paradigm Shift
The Otterman Empire
Call of Cthulhu
Koral
EVERSPACE
Trover Saves the Universe
Hyper Jam
Alluris
Wartile Complete Edition
Georifters
EQQO
The Park
Meow Motors
Asemblance
PLANET ALPHA
Little Nightmares II
Tracks - Toybox Edition
Gigantosaurus The Game
Hollow
Hello Neighbor
Creature in the Well
Dragon Quest XI S: Echoes of an Elusive Age
The Caligula Effect: Overdose
Observer
TINY METAL
Headsnatchers
Redeemer: Enhanced Edition
As always, you can see the compatibility of a particular game by navigating to our game compatibility list. We do our best to keep these up to date, and are constantly adding missing titles. All the same, please alert us if you know the status of a game has changed, either by replying to the Github issue or by sending us a message on Discord.
Look for the next game compatibility update at the end of Q2!
Congratulations, you made it through the whole thing. As a reward, here’s a sneak peek at something we’re working on (note: this is not a UI re-creation or mock-up)…

Thanks to everyone that has supported us so far, be it via Patreon donations, code contributions, testing games in the emulator, or simply being an active member of our community. You’ve helped make this emulator what it is today!
We now have an active Patreon campaign with specific goals and restructured subscriber benefits/tiers, so please consider becoming a patron to help push Ryujinx forward!