Dolphin Progress Report: February, March, and April 2022

After a long wait, the Progress Report is back! This time it wasn't so much from a lack of content, but from a lack of content creators. The past three months had illnesses hit one of our writers and the other had a very challenging move. Even with these major hurdles jumped, we're not even close to 100% yet. It's been a battle to get caught up with all of the big changes to Dolphin the past couple of months and because of that this report is a tad late.

Needless to say, there's only one way to start catching up, and that's to get to digging through the past three months of Notable Changes. Enjoy!

Notable Changes

5.0-16380 - Change default NUS Shop URL to Dolphin's fake NUS by OatmealDome

On the 16th of March the Wii Nintendo Update Servers (NUS) abruptly went offline. Without them, Wiis can no longer download previously purchased titles, or download critical files needed for setting up your Wii system. Nintendo refuses to say this is anything more than a temporary maintenance blip, but after two months we're starting to believe that this is a permanent change. To our knowledge, the life-support from the Wii Shop has been pulled and the Nintendo Wii is now an offline console.

While it may not seem like much, NUS was an important tool to casual users, the modding scene, and even Dolphin users. Easy access to official System Files (IOSes) and default channels allowed users to easily setup a clean Wii System that is fully up-to-date without needing a game with a late release date. If you made a mistake on a modded Wii, you could easily access NUS to get clean copies of IOS files to unbrick your system. On Dolphin, it made it so users could get a fully up-to-date Wii System Menu setup, complete with channels, with just a few clicks. For preservation of the Wii experience, NUS made things simple.

More importantly, Wii games require various IOS files in order to run. We've had our run-ins with differences between older IOS behaviors and newer IOS behaviors while wrangling with USB Microphone support. There are lots of games that either won't run, or won't run correctly if they're missing IOSes. The good news is that almost every Wii disc title comes with the necessary IOS files to run that game along with a full Wii System Menu and all the default channels. Whenever you insert a disc into a real Wii, it'll prompt you to update if there is a missing System File. Most Dolphin users won't notice much of a change, as Dolphin has a hack for when a game is launched from the gamelist to ignore missing IOS files. For anything more complicated, IOS files are also required in Dolphin.

This may seem like a minor issue, but since the servers have gone down, there's been a huge uptick in issue reports from Dolphin users, along with an increase in bugs relating to incorrectly configured Wii Systems. A lot of users would simply pull something like that the Mii Channel and the Wii System Menu off of a Wii or a Disc, and think that installing that was enough. But, without the IOSes required to run the Mii Channel, you'll either be greeted with a blackscreen, the system menu rebooting, or a notice that the title could not be launched. Issues like these have been running rampant, and we no longer had an immediate solution that would clean up their issues.

Here's the kicker; Nintendo is still hosting all of these core system files for the Wii, they're still available to download... from the Wii U Content Delivery Network (CDN)! It still has all of the Wii's System Files for some reason. As far as we know, the Wii U's Virtual Wii used the Wii NUS. This isn't exactly unusual for Nintendo, as the 3DS CDN also has the Wii System Files!

Because of this duplication, this gives us an option to extend the life of the "Perform Online System Update" functionality in Dolphin. We now have a Dolphin Update Server. OatmealDome created a static page and delroth configured the server to act as an intermediary Update Server so that Dolphin can use the Wii U CDN for System Updates. Because the same files are on the Wii U CDN, all of this shuffling should amount to no noticeable change from the previous behavior for our users. Perform Online System Update works just how it did before.

Inevitably, the Wii U and 3DS CDNs will eventually go down, but this should buy us time to develop a more permanent solution for when that happens.

5.0-16005 - Remove MMU Default in Disney Trio of Destruction™ by JMC47

During the previous Progress Report the blog writers, JMC47 and MayImilae, were discussing MMU (Memory Management Unit) titles. And this exchange took place.

MayImilae: do any wii games use mmu?
JMC47: yes
MayImilae: which ones?
JMC47: Disney Infinity, Cars 2, Toy Story 3
MayImilae: oh right, the anti emulation nonsense
JMC47: no!
JMC47: actually one of the devs reached out to us
JMC47: and explained that the MMU stuff was not anti-emulation
JMC47: the dcache stuff was
JMC47: but not the MMU usage

Sonicadvance1, MayImilae's partner, happened to see this conversation by peeking at her laptop. He simply pointed at the screen and said, "That's not MMU." and walked away. These three Disney titles we lovingly call the Disney Trio of Destruction™ had MMU enabled on by default, as without full MMU emulation they emitted a backpatch error then crashed. However, Sonicadvance1 is a former Dolphin developer who made Dolphin's ARM JIT - he knows what he is talking about. It was worth checking. So May immediately passed this on this comment, and JMC gave the three titles a quick test. They ran perfectly fine without full MMU emulation. Huh. Well there's only one thing to do when games are mysteriously fixed like this - bisect!

Through bisecting, we learned that 5.0-15699 is what now allows the Disney Trio of Destruction™ to work without full MMU emulation. This change was briefly mentioned in the previous Progress Report but was not explained, so we'll go over it now.

One of the biggest speedups in Dolphin is "fastmem". Emulating memory mapping is a very involved task, as the GameCube and Wii have very different memory mapping than the the hardware Dolphin runs on, and checking the mapping of every memory access beforehand is quite expensive. So Dolphin handles this by... just mapping the memory on the host system directly, differences be damned. Whenever the mappings are shared, as it can be for simple mappings, the host CPU will handle it and we get a massive speedup (fastmem). However, whenever it doesn't match, the host CPU faults. Then Dolphin's fastmem exception handler will backpatch that access to use "slowmem" where Dolphin will manually translate the memory address. Due to the brute force nature of fastmem, it fails a lot, a lot lot, but it's always worth it to try for fastmem on pretty much any memory access - a fastmem loadstore takes as little as 2 instructions, where as the same access in slowmem can take up to 1000 instructions! However, fastmem can only work because we catch exceptions and backpatch them through slowmem.

We just had to use this image again.

Even with exceptions, there is an exception. Quantized Paired Single Loadstore instructions, due to various quirks involving said quantization, cannot be backpatched. If one of these were to trigger an exception through fastmem, everything would explode. When fastmem was implemented in our x86-64 JIT long ago, the Dolphin's developers of the time were aware of this. They provided a solution, a "safe" path which uses a "test and branch" approach. Any instruction set to use this safe path will be tested before reaching fastmem, and if the test determines that it would fail in fastmem, it will be routed directly to slowmem without triggering an exception.

However, our predecessors only added test and branch to Quantized Paired Single Stores. For some reason, they left Quantized Paired Single Loads out of the safe route. We honestly don't know why. It is our assumption that they never encountered Quantized Paired Loads triggering exceptions after testing hundreds of games, so even though it was dangerous, they decided that the very minor performance hit of the test and branch method was not necessary.

Unfortunately, it appears that they never considered that Dolphin could force Quantized Paired Loads down the path of destruction.

While fixing the graphical issue in Rygar, we noticed that it now required full MMU emulation when it didn't need it before. Josjuice looked into it, and traced this regression to 5.0-14829. That change made Dolphin able to emulate the GameCube and Wii's broken masking for uncached unaligned writes, which was required for a powerful Majora's Mask speedrunning trick. But to accomplish that, we had to make uncached memory accesses always trigger a fastmem exception and go through slowmem.

Rygar just so happens to do a Quantized Paired Load from an uncached memory region. This forced a fastmem exception on a Quantized Paired Load and...

Full MMU emulation happened to work around this. Under full MMU emulation, all quantized memory access instructions use test and branch. Thanks to that, the test caught the Quantized Paired Load and routed it directly to slowmem, bypassing the exception and crash.

Fortunately the solution was very simple. In 5.0-15699, Josjuice made Quantized Paired Singles Loads safe with test and branch. Now, even without full MMU emulation, we always test Quantized Paired Loads and prevent them from triggering the exception that leads to catastrophy.

And now we return to the Disney Trio of Destruction™. In their case, well we don't know exactly, but we believe they are using a Quantized Paired Single Load to load from MMIO (Memory-Mapped Input and Output). MMIO cannot go through fastmem, so that case will always trigger a fastmem exception. And since it was a Quantized Paired Single Load... boom. But thanks to 5.0-15699, this no longer occurred, and we no longer needed to use full MMU emulation to work around it. Once we discovered this, we were able to safely remove the MMU default from the Disney Trio of Destruction™.

Now that Toy Story 3, Cars 2, and Disney Infinity can run without the extremely performance-intensive full MMU option, what kind of performance improvement will this give us?

Absolutely none - these games are bottlenecked by something else. Oh well!

5.0-16009 - MemArena: Use memory placeholders for fastmem on Windows to ensure nothing allocates within the fastmem space by AdmiralCurtiss

This change added a placeholder for our fastmem address region on Windows, making sure that nothing else can allocate memory within our fastmem address region once we've claimed it. This resolves an issue where very large texture packs could crash Dolphin.

It also broke our Windows 7 support.

5.0-16035 - MemArena: Restore Windows 7 support by AdmiralCurtiss

The above change works by using the Windows function UnmapViewOfFileEx. In the words of Microsoft, this function "Unmaps a mapped view of a file from the calling process's address space." This allows Dolphin to preserve fastmem against very large texture packs in a fairly elegant way. However, UnmapViewOfFileEx has a minimum supported version of Windows 8. On Windows 7, Dolphin calls for the nonexisting function and Windows, recognizing that it isn't there, panics and crashes Dolphin.

AdmiralCurtiss fixed this with 5.0-16035. With this, Dolphin itself now checks whether UnmapViewOfFileEx is present on the Windows system, and will not use it if it fails to detect it. Of course this means that Windows 7 users may still encounter crashes when using very large texture packs, but that's better than Dolphin not working at all.

5.0-16214 - InputCommon: Add Windows.Gaming.Input to ControllerInterface by Billiard

Long ago, there was DirectInput (DInput). This was Microsoft's original input API for game controllers on Windows, going all the way back to Windows 95. It was/is fairly messy by today's standards, requiring manual mapping of each button individually, but it was/is extremely flexible, able to handle any and all types of game control devices. However, once Microsoft created the Xbox 360, they wanted a way to easily connect a 360 controller to a PC without mapping or other hassle. So Microsoft created a new input API, XInput. While it is much less configurable than DInput, its simplicity allowed game developers to ship mappings for it within the game itself, so user mapping was no longer required.

Microsoft knew that they would want to add features to their controllers with new consoles, so they added a way to expand Xinput’s functionality with XInputGetCapabilities (link). This Windows function allowed a controller to report if it had differing functionality than a 360 controller, potentially allowing for future expandability or even “weird” functionality like touchpads or gyros featured on other controllers. However, it turned out that the majority of programs took a bit of a shortcut and ignored non-essential parts of the XInput spec. If a controller used XInputGetCapabilities, it was very unlikely to encounter software that even noticed. This laziness dripped down toward manufacturers, and many controllers began to improperly implement the XInput API because the games they used to test weren’t enforcing it correctly. If one of these flawed controllers was used in a software that actually supported the full, proper XInput spec, the software could crash. Ask us how we know.

When Microsoft created new Xbox controllers, they wanted to support the controller’s new functionality on Windows. Now with a reason to resolve the XInputGetCapabilities nightmare, Microsoft’s devised a solution - make a new input API. Naturally.

The creatively named “Windows.Gaming.Input” (WGI) is the newest input API for Windows. This ambitious new API seeks to combine the best of both DInput and XInput into a single API, with a new input-centric approach that theoretically will give it the flexibility for many different types of input devices while maintaining easy setup and use. However, those new features haven't been implemented yet, and as it stands today it is basically just XInput plus One/Series controller features. And it's still missing esssential features that aren't on their Xbox controllers, like accelerometers and gyros, so currently WGI is just yet another Microsoft input API for Microsoft input devices.

Regardless, Dolphin's need to emulate Wii Remotes and several odd controllers for the GameCube and Wii makes having robust input API support a higher priority for us than most other programs, so supporting Windows.Gaming.Input was a natural choice. Many benefits are immediate, as it supports up to eight simultaneous controllers (up from four with XInput), support for the Xbox One/Series rumble triggers, and has better battery reporting. Basically everything we were hoping XInputGetCapabilities would be. However, if the input-centric WGI future comes to pass, users may be able to use it for all kinds of different input devices. We shall see.

It also broke our Windows 7 support.

5.0-16236 - Core/WGInput: Dynamically load winrt function addresses by AdmiralCurtiss

AdmiralCurtiss came to rescue Windows 7 once again. Much like the previous Windows 7 fix, this change made Dolphin use IsApiSetImplemented (link) to check for Windows.Gaming.Input support before trying to use it. With that, Dolphin's Windows 7 support was saved.

...briefly. But that's a story for the next Dolphin Progress Report.

5.0-16174 - Fix OpenGL Label Identifiers for ANGLE by iwubcode

This may not sound very interesting, but this was a quick fix necessary to fix Dolphin running under an OpenGLES wrapper called ANGLE. Why exactly?

The story actually started a few months ago, when it was announced that the Exynos 2200 chipset to be used in some models of the Samsung Galaxy S22 would contain AMD's RDNA2 graphics hardware and drivers. This left us very interested. RDNA2 is great hardware, and while AMD's drivers may not be best in class, they are leagues above the horrors we've seen on Android. We were very hopeful!

Now the hardware is out and users have been able to test it. Vulkan performance on the Exynos 2200 is a step above what we've seen on any other phone. It's able to reach full speed in demanding games like Super Mario Galaxy at up to 2x Internal Resolution without having to disable critical features like EFB Access to CPU. This is notable because GPU readbacks have long been a major bottleneck on mobile devices.

But when we saw OpenGLES on the device, we were taken aback. It's disappointing to say the least. More disappointing than normal AMD OpenGL drivers on Windows. Even more disappointing than Mali drivers. That's because there are no OpenGLES drivers provided for this device. Instead, it uses a wrapper called ANGLE to translate OpenGLES to Vulkan.

This is how graphics software engineers responded to this news.

ANGLE was designed to translate WebGL to other graphics APIs. It was not designed for games, and it is not battle-hardened the way a graphics driver would be. Naturally, there were some growing pains.

For us, when the phones first launched Dolphin's OpenGLES backend wasn't even able to run on them due to a minor mistake in Dolphin's OpenGL Label Identifiers. This was a known whoops that iwubcode found during work on another feature a while ago, but it was so inconsequential that it wasn't a priority to split-off and upstream right away. When given an incorrect Label Identifier, the driver should just return an error saying it is incorrect then continue on. It's harmless. But ANGLE has no validation for this function, so rather than say that the Label is wrong and continue, it hits an unreachable and explodes. While it may have been a Dolphin mistake that caused this, crashing for such a minor mistake in a harmless debugging feature is absolutely an ANGLE issue.

Once we identified that this was the source of the problem, iwubcode picked out the Label Identifier fix and we merged it. We never should have needed to fix it, but here we are. With that, the OpenGLES backend now works on the Exynos 2200.

However, because OpenGLES is being translated to Vulkan by ANGLE for this device, performance seems significantly worse than native Vulkan in every recorded instance. If you have an Exynos 2200 device, please do not use the OpenGLES backend on it.

5.0-16301 - VideoCommon: Handle emboss texgen with only a single normal by Pokechu22

The Rogue Squadron series is a marvel of game engine programming. There seems to be no end to Factor 5's tricks, as we've talked about over and over and over again. But surely, after all these fixes over the years, we should have everything pretty down pat by now. There's no way there would be a major effect that has never worked in Dolphin before, right? RIIIIGHT?

These sand and snow effects looked alright in Dolphin.

Until you launched the games on console again and saw what they are supposed to look like.

This is an emboss effect Rogue Squadron 2 and 3 are applying to the sand and snow to give them more dimensionality and texture. Specifically, this is a GameCube implementation of DirectX6-era bump mapping. It's an impressive effect for the time, as the lighting on the ridges will shift and match the sun's angle even as the suns dynamically move through the sky. Bump mapping like this wouldn't become common until the next console generation, and here it is in a GameCube launch title from 2001!

However, there was a reason this effect didn't take off until years later. The DirectX9 and newer forms of bump mapping are painless - developers can use them with very little setup and they are very, very cheap to run. Devs don't even need to think about it. But with this older type of bump mapping, developers had to build the effect themselves. And it was not cheap. For something that just adds a bit of visual flare, most GameCube and Wii developers decided it was not worth it and passed it by.

But not Factor 5. This is Factor 5 we're talking about, of course they used it.

To explain how this all works, here is a bump mapping effect that already worked in Dolphin before this change. This X-Wing will be our example.

First Image Active Image

Click/Tap and hold to disable the X-Wing's bump mapping.

To build the effect, Factor 5 first needs to have a color map which contains the color of the object itself, then a height map, aka "bump map", which represents the height of the surface as a greyscale image. Cleverly, Factor 5 wasn't going to need the Alpha channel of the X-wing texture, so they used the Alpha as the height map.

This is the color map for an X-Wing in Rogue Squadron II.
And here's the height map, converted to traditional greyscale. Factor 5 is using bump mapping to add depth to the panels on the X-Wing.
But this is the actual texture. The "cut out" areas are the Alpha channel which the game is using as its height map.

The process begins with the game writing the light direction into the Tangent and Bi-normal vectors (registers) with each vertex. As opposed to the Normal vector which tracks movement out from a surface, the Tangent and Bi-normal vectors track movement parallel to the surface. If Normal is Z, Tangent and Bi-normal are X and Y, effectively.

From there, the game reads the texture twice, the first time with the base texture coordinates then again with an offset using the light direction values written into the Tangent and Bi-normal vectors earlier. Then it combines this with the height map to apply the bump mapping to the texture, brightening or darkening the texture based on the height differences. This process burns two TEV stages (out of sixteen), so this is not a cheap effect, but that is how you do bump mapping on the GameCube!

Due to how the effect is built we were not able to dump the final embossed texture. This is a photoshop creation that shows more or less how it would look when applied to the color map.

While this effect is fairly primitive by modern standards, literally just painting the texture, the magic of this effect is that it is tied to the light direction. Thanks to this, the effect does a fantastic job of giving convincing depth to the surface, even in motion!

Here is the bump mapping in motion, with most other effects and textures removed for clarity. Pay attention to the lines here. After the light moves over it, it flips! It uses the light direction!
Click the video for the high resolution version.

When added to all of the rest of the ahead-of-their-time effects like self-shadowing and reflections, these games look like nothing else.

This thumbnail does not do this video justice. Please click it for full res.

Now, all that we've covered so far already worked in Dolphin. So why didn't the sand and snow effect appear correctly? Well, the sand and snow are using effectively the same effect, but on these two surfaces the game doesn't supply the Tangent and Bi-normal vectors for the effect. Without them, Dolphin can't know what the offset is, and the effect cannot be rendered. Yet we know this works on console. It was as though Factor 5 used literal magic!

This has annoyed Dolphin developers for years. Factor 5 was clearly getting the offset from something, but try as we might, we couldn't find it. Sonicadvance1 years ago made a guess that it was using default values, and it even passed a hardware test, but further analysis proved this to be incorrect. Pokechu22 more recently tried to hardcode some values that looked correct for RS2, but they ended up being very wrong for RS3. No matter what we threw at it, we just couldn't figure it out.

In the end, we didn't - we were told how it was done by Factor 5 themselves when we discovered a 2002 article written by a Factor 5 employee.

A trick that is worth mentioning is how to avoid sending the same bi-normals and tangents for emboss mapping repeatedly to the transform unit (XF) of the graphics processor. It turns out that if these vectors are not present in the vertex format, XF will provide the previously transformed bi-normal and tangent, which reside in internal registers. Thus, if a dummy triangle is drawn with the bi-normal and tangent immediately before the landscape is drawn, then there is no need to send the same vectors over again for the rest of the height-map triangles. This means that only one vertex format is needed for the entire landscape, and it saves memory, transfer bandwidth and most importantly transform performance.

Basically, the sand and snow are the exact same effect as the bump mapping effects that were already working elsewhere in the Rogue Squadron games. However, the sand and snow have a performance optimization where the Tangent/Bi-normal vectors are written at the start of the terrain's construction, and all the subsequent steps (including the bump mapping) reuse the stale data in the vectors.

After discovering this, we weren't really all that surprised. We had considered this as one of the many possibilities. However, it was very difficult for us to test due to how Dolphin JITs the vertex loader - it was not designed to preserve the vectors and it would not be easy to make it do so. Due to the difficulty, we never tried it. But once we knew for sure that this is what they did, Pokechu22 did some hardware testing and confirmed it, then stepped in to make the vertex loader able to preserve stale data in the vectors.

And with that, the sand and snow bump mapping effect works in Dolphin!

At long last, Dolphin now properly supports this effect!

Now before we move on, we wanted to share one final thing. While working on this, Pokechu22 wanted to confirm that the bump mapping on the sand and snow reacted to the light direction, so they set up a time lapse on console by spinning around in circles and taking captures at regular intervals while the suns set. It ended up not being very useful as the stage runs out of time before the light moves enough to confirm it for sure, but it looked awesome. So Pokechu22 rerecorded a nicer version in Dolphin for us to share in this Report.

There will be no hyper compressed thumbnail video for this one. Click the image above to see the timelapse! Humming a certain Star Wars theme is optional.

5.0-16337 - macOS: Work Around EarlyZ Bug on Apple Silicon by OatmealDome

Apple silicon has proven to have an impressive capability at running Dolphin and has charmed the Dolphin developers. But there have been a few bumps here and there. One problem was that a lot of games were having a lot of darkness and strange flickering during some special effects. This ranges from platformers like Super Mario Sunshine to top-down shooters like Ikaruga.

Ikaruga was barely recognizable on Apple silicon.

The issue was tracked down by OatmealDome and they found that there was a nasty bug in the Apple driver when using discard while Early Z testing was enabled. Their solution was to simply emulate discard using a framebuffer fetch. This let Dolphin do things correctly while avoiding the broken codepath on the driver. This could result in a slight performance decrease on Apple Silicon, but so far we haven't recorded any noticeable differences.

Now that's more like it.

5.0-16348 - Rework scissor handling by Pokechu22

This is the second scissor change made to Dolphin in recent years, after the Mario Galaxy roar was discovered to use a negative scissor offset. Dolphin developers assumed that meant that the scissor offset could be negative and that was the end of the story. After all, if something else was wrong, wouldn't there be more examples of games having issues?

Well, there was one, we just didn't know it yet. This is the curious case of Major Minor's Majestic March, a game that barely rendered anything in Dolphin and for the past half decade, no one had much of an idea of why.

What's all this? It's just white.
Wait this is gameplay.

As we've already spoiled thanks to Pokechu22 being the change author, we now know way too much about how Major Minor's Majestic March works and the behaviors it relies on. Let's get technical. And please take notes, as there will be a test at the end.

The viewport, the scissor, and the scissor offset are all used to change where things end up on screen. Modern graphics APIs have both a viewport and a scissor, but don't have a direct equivalent to the scissor offset. Let's break down how each of these things work together.

The Viewport is used to scale vertices into screen coordinates. It uses floating-point numbers, so it doesn't necessarily need to be aligned to a pixel grid, though in practice it is most of the time. This is mostly used to set the size of the rendering canvas.

The Scissor is used to indicate which pixels get rasterized - pixels that are within the scissor region are drawn to and pixels that are not in that region are ignored. It usually is set to cover the whole screen with values that match the viewport, but can be set to a smaller value to create picture-in-picture style effects. There are 12 bits of space per coordinate, capable of representing a value from 0 to 4095, but testing found that the 12th bit is ignored, allowing only values from 0 to 2047. In Dolphin, it remains aligned to 1x IR pixel boundaries at higher internal resolutions in order to prevent issues.

Scissor Offset is used to shift pixels after they've been rasterized but before they're written into the Embedded Frame Buffer (EFB). It operates on Pixel Quads, much like our good friend bounding box, and it has 10 bits of space each for the x and y offsets, which could hypothetically represent a value from 0 to 1023 pixels directly, but instead is multiplied by 2 (to operate on pixel quads). Only 9 bits would be needed to represent a value from 0 to 1022, so the previous change assumed the 10th bit indicated negative numbers. This value is multiplied by 2, so to represent a value from 0-1022 only 9 bits are used, leaving the 10th bit unused. The EFB is 640 by 528 at most, and the largest size a texture can be is 1024 by 1024, so wrapping at 1024 isn't that strange.

All of this so far makes sense, but what follows doesn't. It turns out that much more space is provided than that, which can result in a triangle drawing over itself in a large enough viewport. We don't know of any games that do this, but it's apparently possible with fringe configurations. If you care about all of the hardware testing and strange behaviors, Pokechu22 documented the details of their hardware tests in copious detail.

In the case of Major Minor's Majestic March they add a 1024 scissor offset to most of their graphics, which resulted in it rendering off screen in Dolphin. If you were paying attention in the lecture above, you'd already know that an offset of 1024 doesn't actually do anything in practice because it wraps! By reworking Scissor Handling to be more correct, Pokechu22 fixed this issue to make the game finally playable in Dolphin.

Marching is a lot easier when you can see.

The fix for Dolphin's Hardware Backends is a bit simplified and doesn't handle certain cases, like a game using an offset to have the same thing render multiple times. This does mean there are some minor cases of graphics disappearing early during certain transitions in Major Minor's Majestic March and can be observed on the left side of the screen in the demonstration above. Note that this is seen because Major Minor's Majestic March, on top of the aforementioned initial offset, also uses scissor offset to scroll the screen for transitions! If you want to see these scrolls and the duplicated graphics shown correctly, you'll need to use Dolphin's software renderer.

As an added bonus, these changes also fix a minor issue in Mario Golf: Toadstool Tour in which a picture-in-picture effect used for the Hazard placard would render slightly bigger than it should. This was rarely noticed because the issue was seemingly random, and the viewport itself wasn't affected.

Sometimes the hazard screen would show up with a bit of garbage on the the right side.
This is how it would normally display

With some hackery, here's what Dolphin thought the game was trying to do.

Now that's widescreen.

5.0-16260 - Round Viewport Coordinates when using Vertex Rounding by Pokechu22

This is tangentially related to all of the viewport and scissor shenanigans we detailed above, but instead this is a hack to help games render correctly at higher resolutions. In this case, we're targeting Wii Sports Resort. At higher resolutions, an annoying blue line would appear in the Archery Minigame.

The cyan line here gets increasingly worse at high resolutions.

The issue is that the game is trying to reset depth on part of the screen by drawing a rectangle over it, and then clearing the color of the region using an EFB copy. Unfortunately, the coordinates stop matching up at higher resolutions because the game has the x coordinate of the viewport centered at 478.266. These decimals don't result in any problems with the low resolution of the console, but at higher resolutions this strange inaccuracy becomes increasingly noticeable.

Pokechu22 stumbled upon this and decided that it should be possible to fix similar to other high IR bugs by rounding viewport coordinates at higher resolutions. They tried it out and...

No more line!

It turns out that rounding the coordinates off so that they match up again does work, and the solution was presented. Because this is such an edge-case of an edge-case, it was decided not to make Viewport Rounding a new option, but instead it was rolled into the already existing Vertex Rounding which is used for similar looking issues.

If there are any games that need Vertex Rounding that break because of this change, the two options will be split apart, but from our testing this appears to be fairly unlikely.

Porpoise on Deck

Between Progress Reports we saw the arrival of the long awaited Steam Deck, a portable x86-based gaming PC/console hybrid from Valve. And you know we have one! So how does the Steam Deck handle some very challenging Dolphin workloads?

These are absolutely torturous scenes that we are putting the Steam Deck through, and it's handling them very well. These results easily beat high end Coffee Lake ultrabooks from just a few years ago! We are confident that the majority of titles can run at fullspeed on the Steam Deck.

However, we have noticed that there is a lot of confusion about optimizing Dolphin on the Steam Deck. Here are a few things to keep in mind.

Building Dolphin with our Building Dolphin for Linux guide does not work on the Deck due to its immutable root directory. Fortunately, in desktop mode the deck has an app store called "Discover" which distributes flatpaks from flathub, and it has Dolphin's latest "Beta" build ready for installation. This is our recommended way to install Dolphin onto the Steam Deck. We're working on a better solution, but for now this is the best method available. If you need any help with this process feel free to ask on our forums.

To preserve its battery as much as possible, the Steam Deck lowers the clockspeed of the CPU or GPU any chance it can. However, we're a bit unusual, and the Deck may guess incorrectly and take megahertz away from the CPU that we so desperately need. This is particularly present in readback heavy titles that use EFB Access or Store EFB to Texture and Ram. So when optimizing Dolphin on the Deck, be sure to use MangoHud to keep an eye on the CPU clockspeed. If you are below fullspeed and see MangoHud showing a CPU clock in the 2000-2500mhz range, you should make some adjustments - in our testing adjusting Dolphin's Internal Resolution and the Steam Deck's GPU Clocks help most. What you want to see is CPU clocks in the 3000-3400mhz range; then you know all of the Deck's CPU power is available to you.

The Steam Deck doesn't just support Vulkan, it supports OpenGL too. And sometimes, OpenGL can actually be faster than Vulkan! In the Skyward Sword test above, Vulkan tried desperately but couldn't quite reach fullspeed, while OpenGL ran right past it to around 38fps. So when running games on the Deck, be sure to give OpenGL a try.

And that's all for now. We have a lot more tips on the Steam Deck. In fact we even had a setup guide partially completed! However SteamOS is changing so fast that half of it was invalid within a month, so we decided to just cover the important tips. If you need help configuring Dolphin on your Steam Deck, please ask us on our forums.

Last Month's Contributors...

Special thanks to all of the contributors that incremented Dolphin from 5.0-15995 through to 5.0-16380!

You can continue the discussion in the forum thread of this article.

Next entry

Previous entry

Similar entries