Paired MAC+ILU and duplicate output instructions can write to oPos while reading
from R12. This leads to a case where xemu's serialized emulation erroneously
uses the output of a previous instruction when calculating the value of a later
one.
E.g., in
```
/* 0x00000000 0x0080201A 0xC4002868 0x7CB0E800 */
MAD oPos.xyz, R12.xyz, R1.x, C[1].xyz
+ MAD R11.xy, R12.xyz, R1.x, C[1].xyz
```
the value of oPos prior to the first instruction should be used for both MAD
calculations.
This could alternatively be fixed by writing oPos to a temp vector and deferring
the output vector update until after the token is fully processed.
Note that we always process output registers writes before temp register writes
so the only interesting case should be the oPos/R12 alias. An op that writes to
one of its temp inputs will always execute the non-modifying output register
write before updating the temp register.
[Tests](https://github.com/abaire/nxdk_pgraph_tests/blob/1745a45290a5d607f9582303d6882cbf62f003de/src/tests/vertex_shader_independence_tests.cpp#L125)
[HW results](https://abaire.github.io/nxdk_pgraph_tests_golden_results/results/Vertex_shader_independence_tests/index.html)
json.wrap tracked WrapDB's legacy json package, which has been frozen at
3.2.0-1 since upstream renamed it. It also carried no wrapdb_version field, so
`meson wrap update` could not tell what it was upgrading from and the bump
script skipped it silently, leaving us stuck on a 2018 release.
Point the wrap at nlohmann/json directly rather than routing through WrapDB,
which is slow to adopt upstream releases. Upstream has shipped a root
meson.build declaring nlohmann_json_dep since 2017, so no packaging overlay is
needed and ui/thirdparty keeps asking for the same dependency name.
The revision stays on v3.2.0 so this is only a change of mechanism. The bump
script can now carry it forward to v3.12.0 on its own.
sdl3.wrap was a hand-written [wrap-file] pointing straight at upstream release
tarballs. The bump script hands every [wrap-file] to `meson wrap update`, which
needs a wrapdb_version field to work, so SDL3 was silently skipped on every run
and had to be bumped by hand. WrapDB's own sdl3 package trails upstream, so
pointing back at it is not the answer either.
A git wrap goes through the script's existing GitHub path, which already
resolves the newest matching tag and rewrites the revision. SDL tags releases
as release-X.Y.Z, which the default semver pattern does not match, so give the
wrap a tag_regex like glslang and SPIRV-Reflect have.
The release tarball is a git export plus REVISION.txt, so the only build
difference is that SDL's CMakeLists now takes its non-release path for the
revision string it reports.
In #2691, xemu was updated to decouple the guest vblank interrupt from the host
refresh. This allows the UI thread to run at host FPS while the guest runs at
60 fps, matching HW behavior.
On Window machines using AMD drivers, this led to a major decrease in guest
performance when vsync is enabled, apparently due to locking behavior in the
driver holding the guest pfifo thread while awaiting vblank. This manifests as
reduced perf that gets worse when running at a lower display refresh rate.
This PR bypasses the GL swap entirely, utilizing Windows DXGI to perform swaps
and allowing the pfifo operations to proceed without blocking.
https://github.com/abaire/xemu-perf-tests/blob/4115d262c5e80d6b71234f8df65fa78c8ef15e12/src/tests/surface_rendering_tests.cpp#L167
reproduces the issue seen with Conker L&R (slow glo_readpixels) but it is
somewhat subtle at the given tuning. Modifying this test to perform more draws
per frame will likely produce a more obvious result w/ the pre-PR builds as
there are more opportunities for glReadPixels to stall on main thread vblank waits.
* nv2a/vk: use NEAREST filter for CPU surface upscale blit
When the CPU uploads surface data at native resolution, the VK renderer
blits it up to the scaled resolution using VK_FILTER_LINEAR for color
surfaces (VK_FILTER_NEAREST for depth). This causes blurring of 2D/UI
content at scale factors > 1.
Switch to VK_FILTER_NEAREST unconditionally to match the GL renderer,
which uses nearest-neighbor pixel replication (surface_copy_expand()).
* nv2a/vk: use NEAREST filter for CPU surface downscale blit
In download_surface_to_buffer, when scaling the GPU surface back down to
guest resolution for CPU readback, use NEAREST rather than LINEAR.
The Xbox never rendered at any internal scale, so VRAM readbacks should
return pixel-exact values rather than host-fabricated averages. LINEAR
was producing blended colors the real hardware never wrote, which breaks
render-to-texture round-trips and any title that reads back VRAM content.
Consistent with the upload path fix which also uses NEAREST.