Repository navigation
Releases: MichaelJSr/xemu-macos
Release list
v0.16.1 — Two boot-hang fixes; automation, GPU counters and RAM above 128 MiB
macOS (Apple Silicon and Intel) release; ad-hoc-signed xemu.app for macOS 14+.
Fixes for two rare boot hangs, an upstream sync, opt-in automation and GPU-measurement features for harnesses, experimental guest RAM above 128 MiB, PAL 50 Hz, and faster translation.
Before upgrading
- Savestates saved by this release don't load in v0.16 or older (upstream's NV2A section moved to version 5 for vertex-shader fog). Older savestates load as before.
- The first launch recompiles each programmable vertex shader and its pipelines once.
Changes
- Fixed a rare boot hang (2-3% of real-time boots in soaks here) where a game's USB driver lost a completed transfer and crashed: the emulated USB controller now writes its done list before raising the interrupt, as the spec requires.
- Fixed a rare hang right after a reset (about 1 in 100 windowed boots after a disc swap): a reset now clears the GPU's interrupt state as power-on does.
- Upstream xemu v0.8.138-3: vertex-shader fog carryover (Blade 2 and others), Vulkan texture-format fixes, format checks in GPU selection.
- Settings > System offers experimental 256 and 512 MiB guest RAM (also
-m, up to 3840 MiB). Stock kernels still use 64 MiB and the GPU reaches 128 MiB, so this only helps kernels that manage more. - PAL 50 Hz: Settings > System > Guest Vblank (
[sys] vblank_rate), off by default; with 'eeprom' a PAL50 console runs PAL titles at PAL speed. - Windowed presentation can no longer hold up input or screenshots when macOS is slow to hand out a drawable (seen with 2x frame interpolation); such stalls are logged.
- Snapshots: when the tray holds another disc, the disc dialog offers "Load With Tray Disc", with a warning that RAM keeps the old disc's code until a reset.
- Faster translation and fewer render passes: against v0.16, deterministic stream-e2 and cold-boot runs take 2.6% and 2.5% fewer host cycles per frame (heavy-f1 unchanged); clears no longer split Vulkan render passes (heavy-f1 8 to 5 passes a flip, text-heavy homebrew about 1,700 to 2).
- For automation (all opt-in, documented in the README): NV2A workload counters over QMP, a read-only QMP watch monitor that answers during frame advances, a listen backlog above 1,
xemu-input-queue, rendering a requested frame with a null run's RAM, a picture-stale flag after restores, guest bugcheck reporting, a per-run console language, and loading a 128 MiB savestate into 64 MiB. - Removed four unused diagnostic and hatch switches (
XEMU_VTX_SPAN_FINISH,XEMU_DSP_JIT_DIFF_MAX,XEMU_UI_FRAME_CAP_NS,XEMU_UI_LOCK_STATS).
Validation: null-renderer goldens unchanged (heavy-f1, stream-e2, cold boot); all 32 Azurik D98 savestates replay to v0.16's RAM; boot-hang soaks 0 of 184 (USB) and 0 of 320 (reset) with the fixes; xbox test suite 11/11; CI green including the Roswell tests.
Full Changelog: v0.16...v0.16.1
v0.16 — KosmicKrisp as an opt-in Vulkan driver; lower CPU at the 60 fps cap
macOS (Apple Silicon and Intel) release; ad-hoc-signed xemu.app for macOS 14+.
Mesa's KosmicKrisp Vulkan driver ships as an opt-in beside MoltenVK, which stays the default. The release also has less CPU at the 60 fps cap, faster streaming in deterministic runs, renderer fixes and x86_64 TCG work for Windows.
Changes
- KosmicKrisp (Mesa 26.3.0-rc1) opt-in: Settings > Display > Vulkan driver > KosmicKrisp, then restart (or
[display.vulkan] driver = 'kosmickrisp'in xemu.toml). Needs macOS 26 on Apple Silicon; elsewhere Settings shows why MoltenVK runs. Against MoltenVK it peaks 0.4-0.6 GB lower and applies the NV2A texture LOD bias that MoltenVK drops. If it crashes while starting, the next launch falls back to MoltenVK with a notice until you pick it again. - KosmicKrisp known issues: more shader-compile hitches on first visits to an area (11 against MoltenVK's 6 on a cold streaming walk); under heavy host load an occasional occlusion test reads back as empty; wireframe draws filled; the first launch of a new build takes 1.6-2.2 s longer; tested on an M2 Ultra only. Auto moves to KosmicKrisp only once a later Mesa clears these.
- Lower CPU at the 60 fps cap on MoltenVK: guest triangle fans are built on the CPU instead of by a per-draw compute pass, so heavy-f1 uses 9.9 and W2 8.1 points of a core less than v0.15.3.
- Fewer pipeline compiles in streaming areas: a 40 s walk now creates about 104 pipelines instead of 404-485, and with a warm cache its slowest compile fell from 136 ms to 5 ms on MoltenVK (118 ms to 10 ms on KosmicKrisp).
- Renderer fixes: a draw after a clear could run on the clear pipeline; depth bias and blend constants could go stale on Mesa drivers.
- Streaming: when the guest reloads its page tables, unchanged TLB entries now survive (deterministic stream-e2 -6.6% host cycles per frame; normal-mode walk -2.2% CPU).
- Deterministic (headless) runs against v0.15.3: heavy-f1 -1.6% and stream-e2 -6.1% host cycles per frame. Offscreen Vulkan runs are 36-72% faster (the pusher runs on the vCPU).
- Windows and other x86_64 hosts: x87 stack bookkeeping deferred, x87 memory operands read straight from the guest page, and TLB walks shared within straight-line code: 18% fewer host instructions in a heavy-f1 frame's translated code (measured under Rosetta; Windows timings to come). The upstream DSP engine those hosts run copies DMA and mixbuffer data in bulk (about -3% host cycles per frame).
- Upstream xemu through v0.8.137-22: Vulkan 1.4, 2D blits and textures that share memory with rendered surfaces no longer show stale data (Tron 2.0), X1A7 surface clears, and Help > Report GitHub Title Issue, which opens a prefilled issue on this fork's tracker.
- CI: the Roswell tests run a hard-FPU Windows leg that now gates, and the Linux leg no longer fails when the ffmpeg download does.
Validation: null-renderer goldens unchanged on the CI-built app (heavy-f1, stream-e2, cold boot), and its KosmicKrisp offscreen digests match the gate's; MoltenVK offscreen digests and screendumps unchanged by the renderer changes; KosmicKrisp 30-minute soak with a flat footprint and no device loss; xbox test suite 9/9; CI green on all platforms including the Roswell tests.
Full Changelog: v0.15.3...v0.16
v0.15.3 — Frame interpolation in the macOS release
macOS (Apple Silicon and Intel) release; ad-hoc-signed xemu.app for macOS 14+.
Frame interpolation now works in the published app. Every earlier release bundle was built against the macOS 15.5 SDK, which compiles MetalFX frame interpolation out, so its 2x and 4x modes reported "unsupported" even on macOS 26. Nothing else changed.
Before upgrading
- Frame interpolation (Settings > Display) needs macOS 26 on Apple Silicon. On macOS 14 and 15 the option stays unavailable, as before.
Changes
- macOS release builds now use the macOS 26 SDK (Xcode 26) with the same macOS 14.0 floor. CI checks that every build links the frame interpolator, and launches the release bundle on macOS 14 (Apple Silicon) and macOS 15 (Intel) so a newer-than-14 dependency can't slip in.
build.shuses the active Xcode's SDK before the newest Command Line Tools SDK, so a beta SDK installed beside an older Xcode no longer breaks the build.
Validation: null-renderer goldens unchanged on the CI-built app (heavy-f1, stream-e2, cold boot); 2x interpolation runs on the CI-built app (heavy-f1 at the 60 fps cap); CI green on all platforms including the Roswell tests and the macOS 14 and Intel launch checks.
Full Changelog: v0.15.2...v0.15.3
v0.15.2 — Windows x86_64 3.5-4.8x faster; Windows startup crash fixed
Windows (x86_64) and macOS release. The macOS app is an ad-hoc-signed xemu.app for macOS 14+; this is the first release whose Windows build was tested on a real Windows PC.
x87 floating point now runs on the host's own x87 unit on x86_64, which makes Azurik's heavy scenes 3.5-4.8x faster on Windows, and two Windows crashes are fixed. macOS behaviour is unchanged.
Before upgrading
- Windows deterministic-mode RAM hashes differ from v0.15.1: x87 math now follows the guest's precision and rounding control. The macOS goldens are unchanged.
- The
XEMU_SPIRV_CACHEswitch is gone: Settings > Cache shaders to disk now controls the Vulkan SPIR-V cache as well. - On Windows the vCPU, GPU (PFIFO) and audio frame threads run above normal priority;
XEMU_VCPU_QOS=0leaves them at normal.
Performance on Windows x86_64
| v0.15.1 | v0.15.2 | Gain | |
|---|---|---|---|
| Heavy scene (heavy-f1), windowed fps | 11.1 | 38.7 | 3.5× |
| Second heavy scene (heavy-w2), windowed fps | 8.5 | 40.7 | 4.8× |
Changes
- x86_64 CPU (Windows, Linux, Intel Macs): x87 math runs under the guest's control word on the host x87 unit, the hot x87 instructions run inline in translated code instead of through helpers, translated blocks are keyed by the x87 stack top,
fcmovis a select, the SSE fast path is on by default with exact MXCSR flags, hot and cold code are laid out apart, and release builds use-O3. - Windows fixes: a crash 7-9 s after launch with either renderer (an SDL3 clipboard race); a crash at every headless null-mode quit;
frndint/fistignored the guest's rounding mode and extended-precision math ran at double precision; the main loop no longer busy-waits a CPU core (high-resolution waitable timer); a minimized window no longer spins;xemu.logkeeps its tail after a crash, and a stderr redirected to a file stays put; validation layers are no longer passed as device layers; the OS version in the log. - Windows deterministic mode runs block I/O inline, so cold boots replay faster.
- Found in review: on Windows and Intel Macs a guest fault could leave the host FPU on the previous rounding mode until the guest's next
fldcw. XEMU_MAX_QUERIES(a diagnostic) now shrinks only the occlusion query pool.- macOS: PGO profile retrained; no behaviour change.
Validation: macOS null-renderer goldens and the x87 refuter unchanged; xbox suite 9/9; the Windows test plan on real hardware (6 of 6 clean launches, a 30-cycle savestate soak, the refuters at 0 violations, deterministic replays repeatable); an x86_64 macOS build under Rosetta is deterministic with 0 x87 refuter violations; CI green on all platforms including the Roswell tests.
Full Changelog: v0.15.1...v0.15.2
KosmicKrisp 26.3.0-rc1 (arm64)
Mesa's KosmicKrisp Vulkan driver, built from mesa-26.3.0-rc1 (470651298910062f5ad5c4e7fb480c60c6943bc9) for xemu-macos on Apple Silicon with macOS 26. A build dependency, not an xemu release.
sha256 of kosmickrisp-mesa-26.3.0-rc1-arm64.tar.xz: 9f8a91d110e8bbef482238961ae7a70f636a1516293ce10a9f8c1c40dd5f75ce
Pin in build.sh: kk_mesa_tag=mesa-26.3.0-rc1, kk_mesa_sha=470651298910062f5ad5c4e7fb480c60c6943bc9, kk_asset_sha256=9f8a91d110e8bbef482238961ae7a70f636a1516293ce10a9f8c1c40dd5f75ce.
Built by https://github.com/MichaelJSr/xemu-macos/actions/runs/39207608786.
release=kosmickrisp-mesa-26.3.0-rc1
mesa_tag=mesa-26.3.0-rc1
mesa_commit=470651298910062f5ad5c4e7fb480c60c6943bc9
mesa_version=Mesa 26.3.0-rc1 (git-4706512989)
llvm=22.1.8 LLVM-22.1.8-macOS-ARM64.tar.xz sha256 f260f4f7c0d430828a81ae8a3826a1d63fc0963ec2459489308cc23b1f7eab4f
spirv_headers=vulkan-sdk-1.4.363.0 496543121ce6419f23d6fa5d7194ba66c36212d2
spirv_tools=vulkan-sdk-1.4.363.0 ef96ed763b43b59b33b31b362f09a02b729fa1c9
spirv_llvm_translator=v22.1.7 b4c9189bcba7ed9a1189d6a2c27edc3d9a3d5277
zstd=1.5.7 /opt/homebrew/Cellar/zstd/1.5.7_1/lib/libzstd.a sha256 55cc7856ad9f52bd8f97f052537400e5788eae22f2e92cbd4057528ebb7839e2
python=Python 3.15.0 meson==1.12.1 mako==1.4.3 markupsafe==3.0.4 pyyaml==6.0.3 packaging==26.3
xcode=26.6 (17F113)
sdk=macosx 26.5 (25F70)
clang=Apple clang version 21.0.0 (clang-2100.1.1.101)
host=macOS 26.6.2 (25G83)
runner_image=macos26 20261013.0424.1
run_url=https://github.com/MichaelJSr/xemu-macos/actions/runs/39207608786/attempts/1
script_sha256=e96dc125c89aedbb55694f514365ff4635d4c894c7b20b6d1aa23f4d63f8e468
dylib_sha256=e2786cefd1bde18c933a33190d38890d315a0cc95578183c1546b91f87b8e7cc
dylib_uuid=B732529F-B483-345D-9858-33BC4823B037
v0.15.1 — Read-span vertex finishes, faster headless runs, upstream nv2a fixes
Performance across releases
| v0.14 | v0.15 | v0.15.1 | Gain vs v0.14 | |
|---|---|---|---|---|
| Heavy scene (heavy-f1), windowed fps | 9.7 | 60.1 (cap) | 60.1 (cap) | 6.2× |
| Second heavy scene (heavy-w2), windowed fps | 7.0 | 60.1 (cap) | 60.1 (cap) | 8.6× |
| Heavy scene, process CPU at the cap | 203% | 107% | ≈107%‡ | −47% |
| Deterministic replay, heavy scene, host cycles per frame* | 44.8 M | 16.4 M | 12.7 M | 3.5× fewer |
| Deterministic replay, streaming walk, host cycles per frame* | 55.2 M | 19.1 M | 15.7 M | 3.5× fewer |
| Deterministic replay on a busy Mac, heavy scene, wall fps† | — | 73 | 250 | 3.4× vs v0.15 |
| Cold boot to gameplay, null renderer* | 16.5 s | 7.0 s | 3.8 s | 4.3× |
Measured on an M2 Ultra under background load. The v0.14 and v0.15 columns come from the v0.15 release measurements (1-minute load 30-40); v0.15.1 was measured against v0.15 in one session at load 51-65, where v0.15 came out at 17.3 M and 20.7 M cycles, 73 fps and 9.7 s, so the v0.15 → v0.15.1 step shown is conservative. *v0.14 here means v0.14-36, the first build with deterministic mode. †Null-renderer replays had been starved of CPU on a busy Mac (macOS ignored their thread priorities); v0.15.1 fixes that. ‡Same as v0.15 in a same-session windowed A/B (122% vs 121%). On an idle Mac v0.14 ran the heavy scene at about 31 fps, and both newer versions sit at the 60 fps cap with CPU to spare.
macOS (Apple Silicon) release; ad-hoc-signed xemu.app for macOS 14+.
A follow-up to v0.15: faster x87 and vertex handling, headless runs that get their fair share of the CPU, upstream's latest nv2a rendering fixes, and a fix for homebrew that hung or aborted on slow hosts.
Before upgrading
- Two new real-time switches, default on (
=0restores the old behaviour):XEMU_VTX_SPAN_FINISH(the GPU only waits for vertex data a draw actually reads) andXEMU_PFIFO_RING_FREEZE(keeps a restarted push buffer's unread commands for a lagging GPU thread).XEMU_VCPU_QOS=0now also covers the main loop. - Offscreen deterministic screenshots can differ from v0.15 by a handful of pixels (at most 2 colour levels), because fewer render-pass splits change rounding on Apple GPUs. Guest RAM and the null-renderer goldens are unchanged.
Changes
- CPU: 64-bit x87 float loads quiet NaNs on the FP side,
fpatanruns the same algorithm with cheaper steps (bit-identical), and x87 memory operands hold their own data pointer. About 1.7-1.9% fewer host instructions per frame. - GPU: the renderer finishes and waits for vertex uploads only when a recorded draw reads the changed bytes. In offscreen deterministic runs (GPU in the loop) that cuts heavy-scene host cycles per frame by 43% against the previous master, and Azurik's death level drops from 35 to under 1 vertex finish per flip; normal windowed play saves render-pass splits too.
XEMU_VTX_SPAN_REFUTE=1checks every skipped wait at run time. - Headless and automation: null-renderer runs now get the scheduling priority they ask for (macOS had been ignoring it), so harness runs on a busy Mac are 2.6-4.5x faster in wall time; deterministic offscreen runs are 36-49% faster; hooks that read memory no longer force slow GPU report handling.
- Fixes: pbkit/nxdk homebrew no longer hangs or aborts when the GPU thread falls behind a push-buffer restart (Direct3D games were never affected); a debug-build depth-buffer assert; a double free at quit when a QMP client was connected; honest DSP validator counts; clearer frame-interpolation labels; Vulkan validation errors from shader
discardare gone, and the log names the Vulkan driver. - MetalFX temporal upscaling no longer gets jitter offsets for frames that were never jittered, the VGA upload no longer trips Metal stride warnings at boot, and the screenshot hotkey and savestate thumbnails wait for the compositor like QMP screendump does.
- The pipeline cache saves off-thread whenever it grew, so a crash or kill no longer loses every shader compiled in the session.
- Upstream xemu merged to v0.8.137-13: spotlight falloff, texgen view model, Y16 textures, specular and material colour fixes, point sprites only for points, surface offsets, and R12 in paired vertex-program ops.
- CI now runs upstream's Roswell test suite on macOS, Linux and Windows. The fork's macOS filter expects TestFloat's 109 failures, which come from the hard-FPU design: x87 maths runs in double precision without x87 exception flags.
Validation: null-renderer goldens and the x87 refuter unchanged; guest RAM identical in offscreen deterministic runs with the new vertex finishes, whose refuter reported 0 violations; xbox suite 9/9; CI green on all platforms including Roswell.
Full Changelog: v0.15...v0.15.1
v0.15 — Heavy scenes hold 60 fps under load; headless automation
Performance vs v0.14
| v0.14 | v0.15 | Gain | |
|---|---|---|---|
| Heavy scene (heavy-f1), windowed fps | 9.7 | 60.1 (cap) | 6.2× |
| Heavy scene, process CPU | 203% | 107% | −47% |
| Heavy scene, draws per second | 6,361 | 34,587 | 5.4× |
| Second heavy scene (heavy-w2), windowed fps | 7.0 | 60.1 (cap) | 8.5× |
| Second heavy scene, process CPU | 177% | 96% | −46% |
| Headless deterministic replay, heavy scene* | 44 fps | 119 fps | 2.7× |
| Headless deterministic replay, streaming walk* | 37 fps | 110 fps | 3.0× |
| Cold boot to gameplay, null renderer* | 16.5 s | 7.0 s | 2.3× |
A large performance batch for the emulated CPU, audio and GPU paths, a headless, deterministic automation interface for test harnesses, the upstream v0.8.137 sync, and the profile-guided build retrained on this code.
Before upgrading
- The fork's ARM64 DSP JIT is now on by default (Settings > Audio). Turn it off only to work around an audio problem.
- Frame interpolation runs only while the display can show its steps: at 60 fps on a 60 Hz panel 2x stays off, and 4x falls back to 2x, then off.
XEMU_INTERP_GATE=0restores always-on. - Nearly every
XEMU_*escape hatch is gone (includingXEMU_WIN32_DXGIandXEMU_VK_VOLK_DEVICE), and so is the legacydisplay.metalfx_upscalekey. Real-time changes keep a switch (=0restores the old behaviour):XEMU_VCPU_QOS,XEMU_KI_IDLE_HALT,XEMU_PFIFO_STALL_DOORBELL,XEMU_BQL_SPIN,XEMU_INTERP_GATE. - A stuck GPU fence now ends the run after 60 s (warning at 5 s), not 5 s.
Changes
- CPU: guest registers live in host registers, TLB walks are shared, and x87 math runs inline.
- The emulated CPU thread runs at user-interactive priority and halts in the guest's idle loop instead of spinning.
- Audio: DSP JIT block chaining, the EP DSP on the JIT, vectorised HRTF and resampling.
- Cold boot: deterministic disk requests no longer wake the main loop.
- Automation: headless mode, deterministic replay (
-icountwith the null or offscreen renderer), QMP frame stepping, in-memory checkpoints, guest-PC hooks, gdbstub extensions and an[automation]table for tracker endpoints (README, "Headless mode (automation)"). - Fixes: gdb watchpoints, a crash after a code-cache flush, x87 values outside double's range, and the store prefilter, which let stores into translated code skip invalidation in real-time mode.
Deterministic replays: since v0.14-36 one bench golden moved, the stream-e2 walk (f8cf1cee14c86e53 → 1e98a85ee122f87c, x87 NaN payloads now survive inline code). On the Azurik harness's d01/d02 checks, the pipe, vanilla-exit, HDD-read and all 32 start hashes are unchanged; 3 of 32 end hashes moved, each by 8 bytes at 0x274db4: vanilla-rz-w1-dark 45b6a58101bc, vanilla-rz-e7-keylord 23ab6ea774c0, vanilla-rz-e7-dark a192738a65b1.
Validation: bench goldens and the x87 refuter unchanged through the batch; hooks, gdb-stub and DSP-validator suites pass; muted windowed walks render clean at 60 fps; CI green.
Full Changelog: v0.14...v0.15
v0.14 — Fix the post-loadvm crash; texture bounds checks; retrained PGO
macOS (Apple Silicon) release; ad-hoc-signed xemu.app for macOS 14+.
A stability release: a long-standing crash fixed, renderer and CPU
fixes from a code review, dead experiment knobs removed, and the
profile-guided build retrained on the current code. No performance
change.
Changes
- Fixed an occasional crash soon after loading a savestate, or during
play, in the USB controller path. The cause was a use-after-free in
the GPU surface-tracking list that USB transfers walk; upstream xemu
has the same bug. - A malformed guest texture now stops the emulator with an error
instead of reading past the end of video memory. - Surface uploads no longer reuse staging memory the GPU may still be
reading (possible garbled textures or a corrupted video overlay). - A full occlusion-query pool no longer corrupts the next draw's render
state; the capacity check now runs before per-draw setup. - After the guest remaps a code page, the CPU's return-address cache
drops entries for that page (stale code was possible, never seen). - Profile-guided optimization retrained on this release's code; the
previous profile dated from 2026-08-04. - Removed the off-by-default knobs
XEMU_TB_RANGE_INV,XEMU_RETC_BITS,
XEMU_X87_ELIDE_CLEAN,XEMU_PRESENT_DRAWABLE_FIRST,XEMU_HARDENING
andXEMU_PGRAPH_MMIO_STATS. - Debug builds now run the Vulkan renderer's internal assertions;
release builds are unchanged.
Validation: fps parity with v0.13.3 on the heavy savestate (31.05 vs 30.89 fps, 6 interleaved pairs, signs 3/3); 200-frame artifact soak through a Finder launch clean; the crash reproduced on demand before the fix (3/3) and not after it (120 savestate loads); CI green.
Full Changelog: v0.13.3...v0.14
v0.13.3 — Two upstream syncs, Windows hardening wave 1, SDL3 3.4.18
macOS (Apple Silicon) release. Attached build is an ad-hoc-signed xemu.app for macOS 14+ (macOS 26 Tahoe recommended for MetalFX + frame interpolation).
Highlights
Two upstream merges (xemu master through 478b4f4961), the first batch of
hardening from the native Windows port audit, and a refresh of every
vendored dependency. No performance claim in this release: the headline
change for a macOS user is that upstream's PTIMER alarm interrupts are now
emulated, which bumps the NV2A savestate format, and that the shader cache
re-keys on the new glslang.
Read before upgrading
- Savestates saved on this build do not load on v0.13.2 or older. The
NV2A vmstate moved to v4 for the PTIMER alarm state. Old savestates still
load here. - First launch is cold. The SPIR-V cache is keyed on the linked
glslang's runtime version (now 16.6.0), so every shader recompiles once;
expect stutter for the first minutes of each title until the cache
refills. - DSP engine default is the fork's again. Upstream flipped
audio.use_dsp_jitoff "for first release"; this fork keeps it on, so a
stock config runs upstream's dsp56300 JIT as before, and
[audio.dsp_jit] enabled = truestill selects the fork's inline ARM64
JIT.
NV2A
- PTIMER alarm interrupts, with correct rounding. Upstream's
NV_PTIMER_ALARM_0implementation (first merge) now fires guest alarm
IRQs; the second merge rounds the host-timer distance up to a whole
internal tick with a 1 ns floor (muldiv64_round_up,
get_next_alarm_time) so an alarm can no longer land one tick early and
re-fire. The fork adds a guard for the window before the guest programs
NUMERATOR/DENOMINATORand the PRAMDAC PLL, when every divisor is
zero: the clock reads as stopped and no alarm is armed instead of a
divide trap. Upstream's new on-target unit test (tests/xbox/ptimer, 20
cases) runs in thexboxsuite on every CI leg.
Vulkan renderer (pgraph/vk)
- SPIR-V disk cache hardened. Cache files open through
qemu_fopen
(UTF-16 paths on Windows), are written atomically (temp + rename), carry
a-dbgtag whendebug_shadersis on, and are validated before
SPIRV-Reflect sees them: the instruction stream is walked and the last
instruction must beOpFunctionEnd, because about a fifth of
word-aligned truncations land on an instruction boundary and the
parser's own bounds check is a liveassert. A bad blob is regenerated
instead of aborting every launch. Orphaned.tmpfiles are swept at
cache open.XEMU_SPIRV_CACHE=0bypasses the cache,
XEMU_SPIRV_CACHE_ATOMIC=0restores in-place writes. - Cache key follows the linked glslang. The directory name used to
come from whichever glslang header the compiler found first (on a dev
box, Homebrew's), so a wrap bump could serve stale SPIR-V; it now comes
fromglslang_get_version()at runtime. - Bounds checks are real in release builds.
nv2a_vk_bounds_checkwas
__builtin_unreachable()outside debug builds; it is now a check on
every platform (28 per-draw sites). Also from the audit:volkLoadDevice()
dispatch on non-Apple drivers,VK_KHR_external_semaphore_win32made
optional, and the LRU eviction in-use filter restored to upstream's
lru_try_evict_onesemantics.
APU
- Guest voice handles are bounds-checked. An out-of-range handle used
to index hostfilters[]/ HRTF / SSL tables (an out-of-bounds read,
then write). The voice-list walk now stops on a badNEXT_VOICE_HANDLE
and reports once per run; an out-of-range handle is dropped rather than
falling through to the guest-RAM path, whoseaddress_space_*fallback
could take the BQL from a voice-worker thread whiled->lockis held
(a lock-order inversion againstgp_write). The runtimeuse_dsp_jit
engine switch is serialised under the BQL and the APU frame thread
registers with RCU. APU direct RAM stores mark dirty behind
XEMU_APU_RAM_DIRTY(default off on Apple, on elsewhere).
Input
- Pad index bounded before
bound_controllers[]. A guest-visible XID
index outside 0..3 no longer reaches the host array
(hw/xbox/xid.c,hw/xbox/xid-gamepad.c).
Windows
- DXGI presenter activates on NVIDIA. The WGL_NV_DX_interop FBO was
completeness-checked before the interop object was locked, which
returnedGL_FRAMEBUFFER_UNSUPPORTEDand silently fell back to
SDL_GL_SwapWindow. The check now runs under the lock, one lock/unlock
per frame;XEMU_WIN32_DXGI=0restores the SDL swap path. - Native MSYS2 build on Python 3.13+.
build.shpasses acygpath -m
prefix (Python'sntpath.isabsrejects/qemu) and the dsp56300
prebuilt is extracted with--force-local. GCC profile-guided
optimisation is wired for MinGW (XEMU_PGO), and the-O3 / -Dstack_protector=disabledbuild is opt-in behindXEMU_WIN_O3=1
because the 2026-09-08 review named that flip as the leading suspect
for an intermittent crash seen with the wave-1 binary; the shipped
Windows legs stay at-O2. The wave-1 source changes have not yet been
exercised natively at the shipped flags. - Harness transport.
XEMU_INPUT_PIPErides a Win32 named pipe
(same line protocol as the POSIX FIFO), andnsprof/ heartbeat /
invalidation timing report under the OpenGL renderer and on x86
(rdtsc). The PVIDEO/display overlay fix from the audit remains on
branchwindows-wave1-wip, not in this release.
Build + packaging
- Shipped SDL3 moves from 3.4.8 to 3.4.18. The MacPorts vendoring
script picked the lexicographically last listing entry, so3.4.8beat
3.4.18on every clean build, CI included, for months. It now ranks by
numeric version and revision. The same change survives Python 3.14's
stricter default tar filter, which rejected an absolute symlink in the
dbusbottle that MacPorts' currentglib2pulls in (dbus is not
bundled; nothing links it). Other vendored bumps: glib2 2.88.3, libusb
1.0.30, pcre2 10.48. - glslang 16.6.0, nlohmann_json 3.12.0, SDL3 (non-macOS subproject)
3.4.16 via upstream's wrap bumps.build.shwarns before configure
when a subproject checkout no longer matches its wrap's pinned revision,
which previously left a local build silently on an older glslang than
CI. - MoltenVK. The macOS bundle still ships the official 1.4.2
release. The maintainer's local pipeline now tracks MoltenVK main past
that tag (self-reports 1.4.3); it is not what this zip contains.
Testing & tooling
scripts/boot-smoke-corpus.shboots a list of titles on an isolated
bundle clone, taps through menus, scores screenshots and reports
crashes/asserts per title — the soak gate for state-table and bounds
changes. The Windows benchmark harness (scripts/bench-savestate-ab-win.py,
scripts/win/) and upstream'smake check-unitCI job are in the tree;
neither has produced a result that gates this release yet.
Validation
- fps parity with v0.13.2. I ran an interleaved cross-binary savestate
A/B on the F8 heavy scene, 6 pairs × 60 s, fullscreen with macOS Game
Mode on. The base arm was v0.13.2 rebuilt locally with the same
toolchain and its original MoltenVK 1.4.2 and SDL3 3.4.8. In the four
pairs where Game Mode held for the whole run, v0.13.2 averaged 21.35 fps
and this tree 21.36 fps. Across all six pairs this tree was +0.18 fps
(+0.9%), with a 3/3 sign split and identical scene load (876.8
draws/flip in both arms). The machine was busy with unrelated batch
jobs (load 11–21), so absolute fps is below the quiet-machine anchors.
Only the interleaved difference is meaningful. - Artifact soak. I ran it on an isolated clone of a local build of
this tree (MoltenVK main67b26826), across F8 idle, a 40 s walk, and
F5 → F8 reloads. All 319 window captures were clean: no magenta, white
or uniform frames. There were no asserts, and the fork's DSP JIT was
active. - The attached macOS zip itself (stock MoltenVK 1.4.2, PGO). I
launched it through LaunchServices and ran F8 idle, a 30 s walk, and
F5 → F8 reloads. All 236 window captures were clean, with no asserts or
crash report, and the fork's DSP JIT was active. - Tests and CI.
meson test --suite xboxpasses 7/7 locally and on
every CI leg that runs it (DSP interpreter/JIT differential, swizzle,
and PTIMER's 20 cases). CI was green on every leg, including both
win64-cross jobs and upstream's new unit-test job.
Full Changelog: v0.13.2...v0.13.3
v0.13.2
Changes
- ea96337 docs: record the 2026-08-09 deep cross-platform audit fixes
- 0aeb199 tcg: gate sub-page dirty tracking default to Apple (match its contract)
- 3eb1b2d i386: fix inline x87 host-correctness on non-AArch64 / Windows-ARM64 hosts
- a824334 vk: gate GS gl_PointSize on device feature (complete the relaxation)
- 5917538 vk: align texture-upload staging bufferOffset to texel block size
- 5866112 vk: fix dynamic-state reuse across command buffers on native drivers
- f87315c docs: record Windows/native-Vulkan black-screen fix in the ledger + README
- db83513 docs: record Windows/native Vulkan black-screen root cause + fix (audit §K-Q)
- e2c2e9f vk: don't require shaderTessellationAndGeometryPointSize on non-Apple
- dbc6cfe vk: fix display descriptor use-after-free on native drivers (non-Apple)
- 0f914b8 vk: fix black screen on native Vulkan drivers — split cross-stage UBO descriptor write
Full Changelog: xemu-project/xemu@v0.13.1...v0.13.2