Dolphin Progress Report: May 2015


After a slow April month, a chaotic May more than makes up for it. On top of working on an emulator, developers had their hands full with relicensing. It's always a good month when you can look back at the issues that were fixed and go "phew," hoping to never, ever encounter anything like that ever again.

A wide variety of issues, features and enhancements saw important updates this month that increase playability and make the emulator more robust. Please enjoy this month's progress report!


Notable Changes

4.0-6138 - Detect Native GC Adapter During Gameplay by mathieui

Wouldn't it be nice if, much like the GameCube, controllers could be plugged in while the game is already running? Currently in Dolphin, if a controller isn't connected before the emulator is started, it cannot detect it. As of this change, there is one exception to the rule: the Official GameCube Controller Adapter for Wii U and its clones!

That's right, if the game gets started up with the user forgetting to plug in the peripheral, they can just plug it in while the game is running and play without issues. Just follow the guide and have all the necessary drivers installed. Also, if the adapter for some reason gets unplugged, it can be plugged back in without needing to restart Dolphin in order to regain control. Nifty and useful for anyone who uses the adapter on PC and Wii U.


4.0-6178 - Flush Save Data to GCI Folder After Saving by LPFaint99

The GCI Folder feature remains one of Dolphin's most unique and useful enhancements. It's a great, quick way to store an infinite amount of save files on one "memory card" and break the 127 file limit present on hardware and raw files. Unfortunately, despite their usefulness GCI Folders are still considered an experimental feature due to a few minor problems. One of them is that a GCI folder saved the game data to the user's hard-disk when the game was closed rather than when the game actually saved. This means that if for some reason Dolphin crashes (hard to believe, right?) then all that save data from that play session would be lost.

This commit rectifies that by flushing saves to the GCI Folder one second after saving is completed. No more lost save files, and GCI Folders have moved one step closer to parity with Memory Cards.


4.0-6204 - Use Proper Floating Point Depth Precision by Armada, phire, and Fiora

In the world of Dolphin Development, every day is a new challenge for our heroes. In this episode, they face off with a notorious problem that has claimed many a developer before them. It's the story of: The Depth Divisor and its Farfetch'd Solution.

In all seriousness, this is a big change that fixes a ton of games that had no workarounds. There are a half a dozen games that could be featured and show off the bug all the same, but there was one game that brought everyone together - Pokémon Snap. It's not that there aren't more important problems to fix in the emulator, it's just that Pokémon Snap happens to always break in interesting ways. Plus, with the CPU Clock Override feature, Dolphin could run the game more smoothly than the Wii's Virtual Console ever could, increasing interest in making it work.

Sure, those who own the original Nintendo 64 version could play it on console or an N64 Emulator, but where's the challenge in that? The developers here wanted to get Pokémon Snap working because it is something that runs on the Wii.

Prior to this change, Pokémon Snap ran almost perfectly in Dolphin. When playing through the opening stage, Pokémon are detected by the camera, pictures are taken, and the stage progresses normally until the very end. But a problem shows up when our hero goes to show Professor Oak the amazing pictures taken throughout the journey.


Doduo is pretty forgettable, but not recognizing Pikachu?! Shame on you, Professor!


Professor Oak can't see the Pokémon in any of the pictures! Despite the game running mostly perfect, it was left unplayable by this fatal bug. How does one even tackle a problem like this? That's where it gets interesting.

Armada had two pretty big clues before even diving into the code.

  1. Galop1n had a modified build of Dolphin that inverted depth for the D3D Backend (in a supposedly accurate way.) This build successfully worked for Pokémon Snap.
  2. The Software Renderer works. It should, it's a software renderer. But, developers can compare its inputs and outputs to the hardware renderers for important information.

The first step was to determine if the inverted depth in Galop1n's build was what was fixing the problem. So Armada crafted several hardware tests to be run on Dolphin and the Wii in order to see how depth emulation behaved.


Flat Triangle Depth Test

Console:    13884592
Software:   13884592
OGL:        13884593
D3D:        13884593
Galop1n:    13884591

While Dolphin's hardware backends were off by one in the Flat Triangle Test, the results were so close that Armada moved onto more complicated tests. Further testing continued this trend: Dolphin's depth was pretty accurate regardless of the range, but was always off by minun-al amounts.

phire's research and the Software backend implementation showed that it was unlikely that inverted depth fixed Pokémon Snap since there is no evidence that the depth buffer should be inverted. In order to fully prove that inverted depth was not the solution, Armada fed Pokémon Snap inverted depth copies (one of the quirks of Galop1n's build) and the game still did not work properly. Despite it not fixing this specific issue, Armada had not heard the last of inverted depth; more on that later.

Without any idea why the game functioned correctly in Galop1n's branch and no leads, phire continued to study how the game internally worked, and determined what EFB Copies were being used for and why depth was important to the game.


  1. Pictures are not actually rendered until the course is exited.
  2. The photo has separate depth copies for the Pokemon and terrain and assembles them later for the final picture.
  3. Using these depth copies, the game can tell various statistics about the picture.
  4. When a picture is chosen for evaluation, the game calculates the scores based on the statistics.


Dolphin's finalized depth copies matched console very well and made sense when compared against the input.


Pokémon Snap

This is the assembled depth copy. Who's that Pokémon?

Pokémon Snap

It's Pidgey!



At that point, no one really had any idea what was wrong. All that could be done was to keep splashing around hoping for a breakthrough. Since the software renderer worked and the devs had a general idea of what Pokémon Snap was doing, Armada began to search for why Dolphin's hardware backends were always a tiny bit off in the hardware tests.

It turns out Dolphin was doing everything correctly until it wrote to the depth buffer and read it back. During a discussion in the channel, Fiora heard that the depth values were off by one and glanced at the issue. She suggested that dividing and multiplying by 0xFFFFFF was introducing a gastly round-trip error, since it was not a power of 2. A quick test concluded that this was exactly what was happening!

Once they were able to contain their laughter, Armada changed 0xFFFFFF to 2^24 in all necessary situations to quell the round-trip errors and allow Dolphin to correctly write and readback the value.


Pokémon Snap (VC N64): Working as of 4.0-6204


The entire issue was a rounding error. In addition to closing the shutter on Pokémon Snap, testing discovered that this simple fix also quelled lighting issues in Resident Evil Zero, missing UI elements in Mario Super Sluggers, and other minor problems in other titles.

As with any accuracy improvement, this broke assumptions elsewhere in Dolphin. There are a few minor regressions that will be fixed over time, but this change has improved the accuracy of depth throughout the emulator.

Our heroes rose victoriously over the sinister depth divisor. Yet, unbeknown to them, a more sinister problem just beyond the draw distance. And whatever happened to galop1n and his inverted depth? Catch that and more in 4.0-6422: What lurks within the fast depths.


4.0-6349 - Relicense Dolphin to GPLv2+ by Tilka

In case you missed it, Dolphin has relicensed to GPLv2+. The article goes in depth on how and why the relicensing happened. The important takeaway is that Dolphin developers will be free to continue improving the emulator without the potential for legal problems hanging over them. While it doesn't mean much for users today, many improvements will be coming in the future that are directly related to this change. Stay tuned!


4.0-6356 - Add Option to Disable Bounding Box by degasus

Enhanced Software and Hardware Bounding Box emulation were two of the biggest accuracy enhancements to Dolphin in quite some time. Unfortunately, software bounding box doesn't work with the new Vertex Loader JIT, and Hardware Bounding Box has significant requirements. Namely, a lot of video card drivers don't support it, or have issues that make it extremely slow.


Video Card Breakdown

NVIDIA

  • GT/GTS/GTX 300 series or older: Unsupported
  • GT/GTS/GTX 400 series or newer: Supported

AMD

  • Radeon 4000 series and older: Unsupported
  • Radeon 5000, 6000 and Terascale (lower 7000, lower 8000, lower 2xx): Extremely Slow
  • Graphics Core Next (few 7000, higher 8000, higher 2xx, all 3xx and 4xx) and newer: Supported

Windows Intel Integrated Solutions

  • Unsupported in OpenGL. D3D may work.

Linux Intel Mesa

  • Unsupported; but currently being worked on!

Mac OS X Support

  • Unsupported; no OGL 4.3 support in any drivers.

Android Support

  • NVIDIA Tegra K1 and X1


As evidence in the collected information, there is quite a wide variety of graphics cards that still can't handle Hardware Bounding Box. Any graphics card or driver without OpenGL 4.3 support is automatically out, and even then some older hardware and drivers will still have issues with performance beyond what could be considered reasonable.

During the previous bounding box work, it was determined that any game that doesn't use bounding box has no performance impact if bounding box is left on, so, in an attempt to mimic console behavior, it was decided that bounding box would be always on and available for any game to use if they needed it. It was still demanding on systems without ideal specifications, but with only five games known to actually use bounding box, it wasn't considered to be a big issue. Unfortunately, it was discovered that a lot of games use bounding box erroneously, multiples more than the ones that use it correctly! The Resident Evil series, Muramasa: The Demon Blade, Baten Kaitos and many more would enable and use bounding box for absolutely nothing. Disabling bounding box for them does not harm them in any way, but because there was no performance impact on console, the developers of those games either didn't notice or didn't care that bounding box was being called. Unfortunately for Dolphin, it absolutely has a performance impact, and what could be considered a minor mistake on console had dire consequences for users on Dolphin.

As of this change, by default bounding box is disabled for most games and only enabled for games that actually need it via pre-configured gameini settings. This will finally provide relief from game breaking slowdown and crashes on unsupported cards. Unfortunately, any computer that is using a graphics card that doesn't support hardware bounding box will have problems on any games that uses bounding box. Thankfully, the list is very small.


4.0-6385 - OpenGL: Merge EFB Pokes to speedup operation by degasus

Embedded Framebuffer pokes are extremely difficult to emulate quickly. The Wii/GameCube have almost no overhead using these compared to emulating them in modern PCs, making it an extremely difficult task to optimize.

For instance, a loading screen in 007: Agent Under Fire would drop to 2 FPS on every single loading screen except for the first one (which, doesn't use EFB pokes for some reason.) This would lead to a very, very lengthy wait for people who were looking forward to playing the second stage of the game.

Thankfully, degasus came up with a nifty way to speedup some of the games suffering from EFB poke bottlenecks in OpenGL. Before this, each EFB poke was converted into one GPU operation, creating a bottleneck between CPU and GPU communication. Now EFB pokes can be combined into one more expensive GPU operation, but because of the decrease in overhead it is much, much faster. In the same scene in 007: Agent Under Fire is around 20 FPS, a 1000% increase in performance.

This isn't a magic bullet though; the ever stubborn Monster Hunter Tri still requires EFB pokes to be disabled in order to reach playable speeds. You can do this in Dolphin within the "GPU Settings" by checking "Skip EFB Access to CPU" in the hacks tab.



Unfortunately this has only been implemented for the OpenGL graphics backend for now. D3D users will need to wait until it can be ported, but it should be relatively easy. New contributors looking for an opportunity to make a difference should look here.


4.0-6341 - Use OpenGL Clip Control Within Fast Depth and 4.0-6422 - Use Inverted Depth Calculations in D3D Fast Depth by Armada and galop1n

Use Proper Floating Point Depth Precision brought slow depth to near hardware accuracy, but the increased accuracy actually caused more problems in fast depth. After dealing with a few minor regressions in slow depth, Armada turned his gaze toward making fast depth more accurate than it has ever been.

Slow depth, commonly known as "fast depth disabled" to most Dolphin users, uses pixel shaders to perform depth calculations which then override the depth values of the hardware graphics backends. It allows Dolphin to ignore hardware differences and use the original depth calculations natively while still doing depth calculations on the GPU, albeit it prevents a number of GPU optimizations by doing it with this method. Thanks to the original depth formulas, slow depth has generally been the most accurate depth calculation method.


GameCube Depth Formula

$$ (far - near) * \frac{z}{w} + far $$

Fast depth uses standard OpenGL and Direct3D depth formulas, allowing the backends to be optimized as much as possible for maximum performance. Unfortunately, in exchange it must deal with how differently the GameCube/Wii, Direct3D, and OpenGL handle depth. On a GameCube depth goes from -1 to 0, while D3D uses 0 to 1 and OpenGL uses -1 to 1. D3D uses the correct range, but operates in positives and does not allow for inversion. On the other hand OGL allows inversion, but its depth range is twice as large and has to be offset. While Dolphin's graphical wizards were well aware of these differences and compensated for them as best as they could, these additional complications resulted in rounding errors that kept fast depth from being as accurate as slow depth.


OpenGL Fast Depth Formula

$$ \frac{(far - near)}{2} * \frac{z}{w} + \frac{near + far}{2} $$

Direct3D Fast Depth Formula

$$ (far - near) * \frac{z}{w} + near $$

The previous depth accuracy upgrade from 4.0-6204 broke many of the games that worked better on fast-depth. This is because both OpenGL and D3D's old ways of converting to GameCube depth caused rounding errors. In OpenGL, multiplying by a factor of two introduced precision problems, and D3D adding various values together throughout conversion led to small inaccuracies. These rounding errors can add up fast!


Metroid Prime

This is the visor working properly with fast depth before 4.0-6204.

Metroid Prime

Added accuracy put the lines outside of the scanner box, an obvious regression.



How do you fix an issue brought about by higher accuracy? Well, MORE ACCURACY, of course!


OpenGL Clip Control

GL_ARB_clip_control is an awesome OpenGL 4.5 extension that gives applications more exact control over depth ranges. By using this, Armada was able to constrain OpenGL's -1 to 1 range to operating in 0 to 1, then invert it to the GameCube's behavior. This removed a lot of rounding errors and fixed some weird bugs that cropped up from more accurate depth emulation. It is an elegant solution, but it requires that the computer's graphics card must support OpenGL 4.5 or newer, otherwise it won't have access to the clip control and will have to fall back to the older fast depth calculation techniques.


D3D Inverted Depth

A solution so clever that it was disregarded as incorrect and lucky several times. D3D mastermind galop1n came up with a way to invert D3D's depth (0 to 1) to match the GameCube's depth values through a complex formula.

That trick, with the proper floating point depth precision improvements from 4.0-6204 added to it, started passing the depth tests that normally fast depth would fail. This proved that Galop1n wasn't trying to invert the depth values to emulate the console, he was trying to work around the limitations of D3D and avoid rounding errors!

It's a messy solution that is nowhere near as elegant as the OpenGL Clip Control, but it's just as robust and powerful. And unlike OpenGL Clip Control, it will work on any graphics card that supports the D3D backend.


Despite all this work, fast depth and slow depth still have differences in Dolphin. Def Jam: Fight for New York only works on fast depth while Star Wars Rogue Squadron II only works on slow depth. Even the Metroid Prime lines bug shown above which is fixed in fast depth still occurs in slow depth. Though both options have significantly improved, neither option is 100% accurate yet. The ongoing effort toward perfect depth emulation should fix these inconsistencies, and eventually lead to a day where there will not need to be an option for fast depth at all!

In most titles though, it is now safe to use fast depth. Infamous bugs like Wind Waker's flickering waves will no longer happen under fast depth.


4.0-6415 - Preload Custom Textures by degasus

Custom textures have been in the progress report quite a bit as degasus has been trying to make them a more enjoyable experience. From decreasing the difficulty of making new packs, to making them compatible with multiple regions, and even writing a converter that takes old style packs and converts them into new style texture packs.

All of this effort comes down to the fact that projects like the Xenoblade Chronicles HD Texture Pack are not only beneficial to the emulator, but can breathe new life into the games themselves and give players another reason to play through them.

While the last time custom textures were mentioned things were made easier for the creators, this time degasus has a new type of enhancement in store for the users. One of the most prevalent problems with using a Custom Texture pack is that every time a texture is loaded onto the screen, Dolphin will stutter and chug as it decodes the texture.

Given enough RAM on a computer, Dolphin will now preload and decode all custom textures, making it so that users choosing to use texture packs won't have to deal with added stuttering and slowdown! Players no longer need to choose between having an HD Texture Pack and having a smooth experience. To enable this option, go to the graphics settings page and click the advanced tab. In the utility section, alongside 'Load Custom Textures' will be 'Prefetch Custom Textures.' When both are enabled, Dolphin will attempt to prefetch custom textures. The results can be stark.


Without prefetched textures, the emulator stutters as textures are loaded
With prefetched textures, users do not have to worry about HD textures hampering performance


4.0-6477 - Fix Invalid Pointers by phire

Featured in this episode of "Why on earth is this game doing that?!" is arcade racer Burnout 2: Point of Impact. As of magumagu's memory management unit cleanups, Burnout 2 has been throwing some odd invalid pointer errors at users when they pass a certain point in certain tracks. This was consistent and easy to reproduce. Weirdly enough, this bug isn't fatal; simply disable the popup and the game runs completely fine with no ill effects.

When debugged, it is indeed true that the game is feeding registers invalid data. The issue is that as far as anyone can tell, it'd do the exact same thing on console as well. What phire did was make it so we delayed the processing of the data until the game actually reads back from the registers. This entirely fixes the issue.

The question becomes, why is Burnout 2 feeding the registers with bad information that it has no intention of reading back? Well, in any case, Burnout 2 is working again. Just keep an eye out for other games doing strange things; perhaps the issue is Dolphin reacting to something that really isn't going to hurt the game at all.


Last Month's Contributors...

Special thanks to all of the contributors that incremented Dolphin from 4.0-6140 through to 4.0-6484!


Die Diskussion kann im Forenthread des Artikels fortgeführt werden.

Nächster Beitrag

Vorheriger Beitrag

Ähnliche Beiträge