fix(vk): a timeline wait that comes back device-lost is said as a lost device, not as a timeout #670
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
beanstalk: approved @ 1697603
beanstalk: approved @ 2c5a62e
beanstalk: approved @ 4fd82b7
beanstalk: approved @ 64d6d09
beanstalk: approved @ 6f91fae
beanstalk: approved @ 70a78f9
beanstalk: approved @ 8d361dc
beanstalk: approved @ 9d8356e
beanstalk: approved @ abf2227
beanstalk: approved @ d82f202
beanstalk: approved @ e5f1e40
beanstalk: approved @ ee8ab5f
ci: approved
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!670
Loading…
Reference in a new issue
No description provided.
Delete branch "mooki/Longshot:fix/lost-wait-said"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type: fix · Risk: low · Tested on: macOS 26.7.1, Apple M4 Max (MoltenVK 1.4.2), arm64 and x86_64 under Rosetta · Needs: Windows and Linux, any GPU (build and start)
Why
When the GPU device is lost while the game waits on one of its timelines, the log says the wait timed out, which points at the
wrong thing. In the macOS port's start 21 the device was lost during a scene load, and the last line before the end was
vk: a capture's wait for write-back 9646 timed out (done 0): the wait had come back at once withVK_ERROR_DEVICE_LOST, anddone 0was a counter the driver never wrote once the device was lost. Whoever reads such a log looks for a slow GPU or adeadlock instead of a lost device. This PR says a lost wait as a lost device. Nothing else changes. It came out of the macOS port
(See #420), but every platform runs this code.
How to reproduce
Seen on: macOS 26.7.1, Apple M4 Max, MoltenVK 1.4.2 (the macOS port's integration build 09f9a171; main does not run on
macOS yet); the same code path runs on every driver
Settings and switches: defaults
Steps: play until the GPU device is lost while a capture waits for its write-back (start 21: the field-dawn save's load
under memory pressure).
Expected: a line that says the device is lost.
Actual:
vk: a capture's wait for write-back 9646 timed out (done 0)(about 17 ms after the wait began), then the game endson the next submit (
reports/2026-11-14-mac-startup-21.md; analysis inreports/2026-11-14-device-lost-21.md§1: MoltenVKreturns
VK_ERROR_DEVICE_LOSTfrom the wait at once and leaves the semaphore's counter unwritten once the device is marked lost,so
completed()read 0).What changed
A timeline wait that comes back
VK_ERROR_DEVICE_LOSTis said asvk: a wait for recording N came back VK_ERROR_DEVICE_LOST: the GPU device is lost(ora capture's wait for write-back N …; 8 lines at most), and no longer as a wait that timed out. The game still ends where it did: at the nextsubmit or by the GPU hang watch (
device_lost, issue 1275); a wait that times out is said as before.gpu/vk/vk_replay.cppwait_rec_seq: keeps its wait's result (wait_rec_result, thread-local) and says a lost one throughwait_lost("a wait for recording N").vk_timeline_wait: after a recordings' wait, a lost one is not said again as a capture's wait that timed out; its owntimeline wait says a lost one through
wait_lost("a capture's wait for write-back N").tests/test_lost_wait_said.py(new): both waits cut fromvk_replay.cppand run against a made-up driver: a lostrecordings' wait and a lost capture wait each said as a lost device and not as a timeout, a timeout said as before, a finished
wait silent, the line capped, no wait ending the process; and every
VK_ERROR_DEVICE_LOSTcheck kept intest_device_lost_exit's form.Measurements
Nothing to measure: the change is one log line where a wait comes back device-lost; the game-free test shows the lines.
Flags and settings
None.
Testing
Tested: on macOS 26.7.1, Apple M4 Max, at
3a4dfd5a, this PR's head before the rebases ontoe090cc48andaa95d35f(main
6c9edffeplus this PR):tests/test_lost_wait_said.py --arch arm64and--arch x86_64(the fixture runs under Rosetta): pass on both. On main6c9edffewith the test file copied in (sha256 inlw-test-files.sha256): fails on both: the recordings' lost wait said asa capture's wait for write-back 9646 timed out (done 0), the capture's lost wait said not at all(
reports/PubWave-files/PubLate1/lw-proof-01/).tests/test_device_lost_exit.py(with/usr/bin/clang++, and throughclang++ -arch x86_64under Rosetta): passes.vk_replay.cpp, and the new one, throughtools/ls-suite.py: 84 pass, 5 fail; 4 fail on main6c9edffeon macOS too (
reports/Baseline-files/main-6c9edffe/), andtest_present_aspect_vulkanis skipped on macOS in a full run andfails only because it was named (no Vulkan library to link on this Mac) (
lost-wait-said-related-01/,-compare.txt).gpu/vk/vk_replay.cppcompiled whole for arm64 and x86_64 with main's renderer flags (with #476's, #490's and #492's macOScompile pieces merged in a scratch tree only): both objects made, exit 0 (
reports/PubWave-files/PubLate1/compile/lost-wait-said/).unifdef -U__APPLE__):vk_replay.cppdiffers, as intended: this is every platform's change(
reports/PubWave-files/PubLate1/offapple-lost-wait-said.txt).aa95d35f, at0c916d9f(3a4dfd5abefore the rebases ontoe090cc48andaa95d35f):Sweep3's checks of this head (the C/C++ it changes compiled, and its own tests run, on arm64 and x86_64 where they
apply) gave the same results as before;
python -I -B tests/run_all.pyon wave S1's merge11a5b4e7, which carriesthis head: 568/22/17 (passed/failed/skipped) against main aa95d35f's 543/33/17 on this Mac, no new failure
(
reports/2026-11-15-rebase-sweep-3.md).Not tested: a real lost device on any platform with this head (the line is shown by the test's made-up driver); Windows and
Linux: not built on Windows or Linux; its test request covers it.
Must be tested:
0c916d9f, on main alone) and mainaa95d35fthe same way and starteach to the title, expecting no
came back VK_ERROR_DEVICE_LOSTline in a run that keeps its device andtests/test_lost_wait_said.pypassing, and every other line to match main's (by hand: test request T-5A9G).Risks
What could break: only log text where a timeline wait comes back
VK_ERROR_DEVICE_LOST: one line (at most 8 in a run) in placeof the "timed out" line, or where none was said. The early return after a lost recordings' wait skips only that "timed out" line;
the function returned there anyway. Every
VK_ERROR_DEVICE_LOSTcheck still goes todevice_lostas before.Turning it off: revert the PR.
Compatibility: Nothing changes for players: no switch, shader stamp, cache format or
MKWVK_API_VERSIONchange.Reviewer notes
3a4dfd5a(one commit on main6c9edffe).their own PRs: there the Mac also ends the game at such a wait (
device_lost), Apple-gated, and its other platforms keep main'stext.
git merge-treewith that branch's head conflicts ingpu/vk/vk_replay.cpp(both change the two waits): whichever landssecond keeps this PR's
wait_rec_resultand line on every platform and adds the Mac'sdevice_lost()after the line, as thetopic first had it (
macos/giant-mem-gate230dde4c).git merge-tree) with the other open macOS PRs (#423, #427, #428, #431, #438, #476, #479, #480, #490, #491, #492,#498), #642, #650, #651, #652, #653 or #666 (
reports/PubWave-files/PubLate1/merge-check-lost-wait-said.txt).Issues
See #420
Checklist
Everyone
type(scope): description) of the status line's type.main: onaa95d35f(#761, 2026-11-15), head0c916d9f, without a conflict; this PR's owncommits, old → new:
3a4dfd5a→0c916d9f; the commit names elsewhere in this description are from before therebase.
python -I -B tests/run_all.pypasses (any failure that also fails onmainis named). (At3a4dfd5a: 532 passed, 32 failed, 17 skipped against main 6c9edffe's 531/32/17 on this Mac; the 32 failures are main's own, nothing that passes on main fails, andtest_lost_wait_saidis new and passes;reports/PubWave-files/lost-wait-full-3a4dfd5a/. After the rebase onto mainaa95d35f(head0c916d9f): wave S1's merge11a5b4e7, 568/22/17 against main aa95d35f's 543/33/17, no new failure.)third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
Assisted-by:/Co-Authored-By:trailers.mainand passing here.3a4dfd5aaf8dfd549b55WIP: fix(vk): a timeline wait that comes back device-lost is said as a lost device, not as a timeoutto fix(vk): a timeline wait that comes back device-lost is said as a lost device, not as a timeout8dfd549b550c916d9f86View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.