At the end of July 2011, LM published a free DSP ROM that works with games
using the Zelda UCode. His ROM only has the code to handle UCode loading and a
few utility functions, the rest is missing. This includes the four large sound
mixing functions used by the AX UCode and the DROM containing coefficients used
for polyphase resampling in AX.
This is an improved, updated version of this ROM, which changes the following:
- We now have a free DROM that works for polyphase resampling by "emulating"
linear interpolation. The coefficients contained in the DROM are normally a
list of { c1, c2, c3, c4 } which are used to interpolate a sample value from
four previous samples:
out_sample = prev1 * c1 + prev2 * c2 + prev3 * c3 + prev4 * c4
The coefficients are chosen depending on the fractional part of the current
position (basically, our position between the previous and the next sample).
We can use this fact to generate (c1, c2, c3, c4) for each possible
fractional part so that:
out_sample = prev3 * curr_pos + prev4 * (1 - curr_pos)
Which is the formula for linear interpolation between prev3 and prev4. Linear
interpolation is not as good as polyphase resampling but it still works very
well and I couldn't really hear any difference between the two. If someone
wants to generate real polyphase filter coefficients, they are welcome to
submit a patch.
- The IROM now contains the 4 mixing functions used by the AX UCode: mix_add,
mix_add_two, mix_add_ramp, mix_add_ramp_two. They are large, inlined
functions (probably for performance reasons) in the official DSP IROM, our
version prefers to use a loop. This *should* be more performant with our DSP
JIT implementation, but I did not benchmark that.
Because the new DSP ROM is working just as well as the official ROM in 95% of
cases, it is now shipped by default with Dolphin and will be used with DSPLLE
if you don't have an official DSP ROM in User/GC. It will still display a panic
alert at every boot to notice you that you are using a non official DSP ROM
made by us, which is not perfect.
Games using the CARD, IPL or GBA UCodes are still broken. I don't know what
games this actually impacts, but this is a very small proportion compared to
what works.
They are currently broken and cause sound issues which are not present in other
backends:
* OpenAL plays music 2x too fast in Zelda UCode games with HLE
* Pulse backend uses a lot of CPU power and slows down emulation significantly
Both backends are currently being re-implemented in separate branches of
Dolphin, so this should be a temporary removal.
Workaround for issue 5864 disabling parts of an optimization in the JIT. This
is not the best solution to fix this issue, but at least it does not crash.
Only AX GC is merged so far, the new Wii AX development will be done in a
separate branch when I'll start working on it.
There are still a few AX GC bugs remaining, but overall a lot less games have
sound issues than before.
Thanks to everyone who helped test the development builds of this branch and
reported results on the forum thread.
Conflicts:
Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp
Tales of Symphonia and Skies of Arcadia Legends now have working musics with
DSPHLE. Some other games with the same symptoms (missing instruments) should
probably be fixed by that change too.
Most of the InvalidateICache calls are for a 32 bytes block: this is the
number of bytes invalidated by PowerPC dcb*/icb* instructions. Profiling
shows that a lot of CPU time is spent checking if there are any JIT blocks
covered by these 32 bytes (using std::map::lower_bound).
This patch adds a bitset containing the state of every 32 bytes block in
RAM (JIT cached/not JIT cached). Using that, a 32 bytes InvalidateICache
can check in the bitset if any JIT block might be invalidated. A bitset
check is a lot faster than an std::map::lower_bound operation, improving
performance of JitCache::InvalidateICache by more than 100%.
Some practical numbers:
* Xenoblade Chronicles (PAL)
56.04FPS -> 59.28FPS (+5.78%)
* The Last Story (PAL)
30.9FPS -> 32.83FPS (+6.25%)
* Super Mario Galaxy (PAL)
59.76FPS -> 62.46FPS (+4.52%)
This function still takes more time than it should - more optimization in
this area might be possible (specializing for 32 bytes blocks to avoid
useless memcpy, for example).
Very useful to compare performance between two builds, check the impact of
a configuration option, etc. FPS log is stored in User/Logs/fps.txt and is
reset each time you launch a game. Only enabled if you check the "Log FPS
to file" option in your graphics settings.
Could be improved a bit: currently logs only every 1s (so you can't really
see small variations), maybe output more infos to the fps.txt like
average/stddev (but Excel/Libreoffice/Google Docs can compute that easily
too).
This was not needed for most games before because the external exception was
itself delayed. aram-dma-fixes changed that and made the external exception
happen a lot quicker, breaking games that relied on the memcard operations
delay.
Fixes issue 5583.
These merges, while in theory improving emulation accuracy, cause issues
in other parts of the emulator based on invalid assumptions. memcard-delay
fixed some of these issues in the EXI memcard code, but several other
problems still exist and I don't have the time to debug that right now.
This was not needed for most games before because the external exception was
itself delayed. aram-dma-fixes changed that and made the external exception
happen a lot quicker, breaking games that relied on the memcard operations
delay.
Fixes issue 5583.
The GL EFB cache did not clamp correctly the coordinates when computing
the rectangle it needed to cache, leading to negative values being used
as indexes and often crashes.
Fixes issue 5510.
This branch fixes the ARAM DMA state tracking and makes external exceptions
timing more accurate.
Fixes WWE: Day of Reckoning 1 and 2 (issue 617)
Fixes Knockout Kings 2003 (issue 4904)
Fixes Spider-Man (GC)