OoT exposure flashes: CPU reads of GPU results wait for the work that writes them #296
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!296
Loading…
Reference in a new issue
No description provided.
Delete branch "pr/exposure-flicker"
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?
Fixes the white flashes / fog pulsing at Kokiri Forest (several times a second, while standing still).
What it was. Not the fog: OoT's auto-exposure hunting in 0.2 EV steps (~15% brightness each). The game meters the
scene on the GPU: a pass adds the frame's brightness into a small buffer, and the CPU reads it after an invalidate and
stores 0 back (f_80357060). On the console that memory is coherent. Here the GPU's result reaches guest memory only with
the write-back at the end of its submission, and the game read it as soon as it had handed the work over: one frame it
read 0, then the old sum came back over the CPU's 0 (a whole-page sync of the captured page) and the next frame added to
it (2x). The exposure logic saw 0 / 1x / 2x and kept correcting.
The fix. The pages each submission writes into guest memory (write-backs from a mirror, small bindings written in
place) are noted with its timeline value;
invalidatewaits (replay caught up, then that value) before the CPU reads arange a GPU write ever reached.
RX_VK_NO_READBACK_WAIT=1restores the old behaviour.Measured at the Kokiri rock, 300 screen captures in ~4.5 s at normal speed (GDI, so the game isn't slowed): 17-84
brightness jumps before, 0-1 after; ~46 fps both ways (RTX 4060 Ti). Confirmed in play: the flashes are gone.
Diagnostics added:
RX_VK_LOG_READBACK=<present>(what the CPU is about to read at each invalidate),RX_VK_LOG_READBACK_WAITS=1,RX_VK_WATCH_CPU=<present>:<addr>[,...](CPU writes to those pages with the writer's stack;the host page watch now also logs the host pc, which hookshot.map turns into the guest function),
RX_VK_READBACK_NO_CATCHUP=1(A/B).Also adds EvilBoyce (Discord: evilmfkr) to the README credits.
🤖 Generated with Claude Code
Thanks