[Tracking] Flicker and flashing: brightness pulses, one-frame flashes, doubled image with frame pacing #1005
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
2 participants
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot#1005
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
This issue collects every open report of flicker and flashing, so there is one place to follow it. The individual reports were closed pointing here; their logs, screenshots and discussion stay in each linked issue.
Summary
Problems reported:
Several causes were fixed in v2.0.0 and v2.0.2, and many reports below are from before that, so please retest on v2.0.6 and post here if it still flickers. HUD flicker on AMD handhelds is in the handheld tracker.
Affected GPUs and versions
Evidence from the logs
RX_VK_WAIT_GPU=0removes it.RX_VK_PER_QUEUE_FENCES=0fixed it for the reporters.Workarounds
RX_VK_WAIT_GPU=0,RX_VK_PER_QUEUE_FENCES=0.Reports merged here (11 issues, about 51 people)
170ce53Adding a report
Please update to v2.0.6 first (https://github.com/NotRexed/Hookshot/releases/tag/v2.0.6; Update next to Play in the launcher). Please add: GPU, version, Frame pacing / frame generation settings, a short video if possible, and
hookshot_log.txt.All tracking issues
Two flickers here have open fixes:
Steam Deck OLED (RADV VANGOGH, SteamOS 3.9.5), v2.0.14: one-frame white flashes, gone with the two workarounds above
Setup:
RX_VK_MESH_OPT=1andHOS_HANDHELD=1. The same flashes also showed on v2.0.11 withRX_VK_NO_MESH=1and no frame generation, so frame generation isn't the cause.RX_VK_PER_QUEUE_FENCES=0andRX_VK_WAIT_GPU=0tohookshot_env.txt: no flashes. I haven't yet checked which of the two does it. I can if that's useful.Where would I add those settings ? Where is the env file ?
From #2066 (RTX 4070, driver 616.56, Windows 11, v2.0.14, default settings): flickering lighting in Hyrule Field that gets worse toward the horizon and looks fog related, regardless of settings. Video and log are in #2066.
Black rectangles flickering during movies / title screen — RTX 2060 SUPER, Linux, v2.0.14 (not frame generation)
Same symptom as #1901 (also an RTX 2060 SUPER on v2.0.14), but here it persists with frame generation off, so I'm adding the data here as asked.
What happens
How often (measured)
I took screenshot bursts of the title screen and counted solid-black blocks automatically (8 px grid, ≥32×32 px, >80% black):
So it doesn't depend on frame generation, frame pacing, FSR 3.1 or the handheld profile.
Settings that stayed the same in every test
Quality preset Custom, Fullscreen On, GPU device 0 (RTX 2060 SUPER), HDR Off, Frame rate cap 60, NVIDIA Reflex On, Output resolution 1920x1080, Window scaling filter Lanczos, Sharpness 30%, Ultrawide 16:9, Robust buffers Auto, Descriptor reuse Off, Sampler cache Off. Render resolution was 50% (768x432) in the first two rows of the table.
I haven't tried Reflex Off or the other Robust buffers values yet. Happy to test anything you suggest.
System
hookshotin the game folder). No overlay or wrapper is hooked in: no MangoHud, no gamemoderun, no Steam. Only Hookshot's own FPS counter shows.Screenshots
Frame generation Auto + FSR 3.1 (blocks at the top):
Frame generation Off, Frame pacing Off, Upscaler Game's own (the menu is open so the settings show; blocks are still there):
Log
hookshot_log.txt (home path replaced with
~). All files are in this gist.Same two one-frame artefacts on an RTX 4090 (v2.1.0, source 0ef688a6, Windows 11, 4K).
Frame generation (3, also retested at 0) and the upscaler (DLSS, also retested native) make no difference.
What the log of one full session shows (37440 presents, 60.3 fps, GPU-bound wait 0.0 ms, so this is not a performance matter):
mirror syncs (600 submits): 15952 dirty pages from their submits' captures, 135636 from earlier ones'write-back diff (600 submits): 2465 runs, 1378.4 MB compared; 2203 pages read into the shadowstexture slot 0x3126f (handle 0x3a83126f) is not registered: sampled as the dummy— 0x3a83126f is 1e-3f as a float, so that field looks uninitialised rather than a real handlere-uploaded (its memory was written)), several of them 1920x1080 and 3840x2160That reads to me like a capture/upload timing window rather than a shading problem: the replay samples storage the capture has not caught up with. Is this the same thing as the "single white frames" listed above, or does it deserve its own entry?
Settings: 4K 3840x2160,
dlss=2,dlss_model=2,upscaling=2,frame_generation=3,frame_pacing=1, plusRX_VK_TAAU_KEYS=-andRX_VK_MMA_SOFTWARE=1(the #36 workaround, kept for the overexposure).Unrelated but noticed:
10 programs (10 failed)in the periodic stats.Would
RX_VK_WAIT_GPU=0orRX_VK_PER_QUEUE_FENCES=0be worth trying against this one-frame window specifically?A measured instance of the brightness pulse, in Kokiri Forest on v2.1.0, with
the renderer's own flash detector rather than an impression of what the screen
did.
Setup: ROG Ally X — Ryzen Z1 Extreme, Radeon 780M (RDNA3), 24 GB shared with
8 GB carved out for the GPU; Linux (Bazzite, kernel 7.2.15, RADV, Mesa 26.2.6),
Vulkan 1.4. 1280x720, quality preset Minimum, FSR, no frame generation. One
minute of walking and panning the camera in the village,
RX_VK_FLASH=1withRX_VK_SHOT_EVERY=1, thresholds left at their defaults (RX_VK_FLASH_DIFF48,RX_VK_FLASH_CELLS40).What it found
6 one-frame flashes in 60 s, in two bursts of three consecutive presents,
alternating bright and dark:
(and the same shape again at presents 1763-1765, 66 of 2304 cells, peak 105)
Taking each flagged frame against the mean of its two neighbours, the pulse is
and it covers rows 268 to 720 across the full width, on the lit grass and the
bushes — the sky and the trees above the horizon barely move. The two
neighbours differ from each other by 1.8, so this is not camera motion: a and c
agree, b does not agree with either.
That is the shape #570 describes — a view-dependent volume read a frame early —
and it is why the walk pans the camera on purpose: a volume that depends on the
view has no reason to pulse while the view holds still. I have not yet run the
same minute with the camera fixed to check that, so take the camera part as the
reason for the script, not as a result.
How it was driven, in case it is useful to you
The game ran headless in a nested Wayland compositor with a virtual Xbox pad,
driven by a scenario file rather than by hand, so the same minute can be played
again on another version and the two compared:
vk: replay readyandoe: startup logo finishedin the log;the shield so the movie behind it does not count;
pad_a=1puts the Switch's A onan Xbox pad's B);
cheats: inventory probefromHOS_OOT_CHEATS=1— the debug toolsprint the inventory once Link exists, which is how the scenario knows the
save is in rather than guessing from a picture;
Each run leaves a folder with the game log,
RX_VK_FRAME_LOG's per-frame times,the captures, the detector's frames, and a manifest holding the Hookshot
version, the kernel, the driver and a digest of the scenario and config — which
is what caught that my distro had changed Mesa under me between two
measurements.
The box is wbox-mcp and the scenarios
are in hookshot-wbox
(
scenarios/village-flash.yamlis this one). Neither repository holds any gamefile, dump, key or build output, and reference images and captures stay on the
PC that made them.
If it would help, I can run the same minute with
RX_VK_WAIT_GPU=0and withRX_VK_PER_QUEUE_FENCES=0and post whether the count goes to zero — that is acheap answer to have on this hardware, and I will do it next unless you would
rather have something else measured.
Follow-up to my measurement above, with repeats this time: three settings, three
runs each, interleaved (one run of each in turn, three times) so that anything
drifting with time hits all three equally. Same machine as before (Z1 Extreme /
Radeon 780M, Linux, Mesa 26.2.6), v2.1.0, same scripted minute in Kokiri Forest,
detector thresholds left at their defaults.
RX_VK_WAIT_GPU=2RX_VK_PER_QUEUE_FENCES=0The two bursts are at the same two moments of the walk every time: one within
about a second of the first step after the arrival, and one at t+36 to +38 s,
a few seconds into the forward walk that follows a camera pan. With per-queue
fences off, the first burst is still there and the second one is gone, in all
three runs.
That is worth a look, because per-queue fences were introduced for what looks
like this exact symptom — the comment at
gpu/vk/vk_replay.cpp:65-71describes"OoT's presentation work run ahead of the scene work it waits for: a frame of
the fog, haze and sun shafts of the frame before". On this machine they do
remove one of the two bursts' worth of that, but the one at the start of the
walk survives them, so either there is a second path to it or the fences do not
cover that case.
It is not free, either: with them off the scene runs slower here — median of the
last ten five-second windows of the walk, 39.5 fps against 46.4 with them on
(48.8 with
RX_VK_WAIT_GPU=2). So this is a finding about where the pulse comesfrom, not a workaround to recommend.
One correction to the issue body, if you want it
The tracking list says, twice:
In v2.1.0
RX_VK_WAIT_GPUis a number of frames of lead, and it is 0 whenthe variable is not set —
gpu/vk/vk_replay.cpp:3082-3090:So
RX_VK_WAIT_GPU=0is today's default and cannot remove anything: anyonefollowing that line is setting what is already set. My runs agree — 0 and unset
give byte-identical results, and the nine runs above show 2 is no better than
unset. If a lead limit still helps anywhere, the value to suggest is greater
than 0; otherwise the line is worth dropping from the workarounds so it stops
sending people down a dead end.
Correction to the performance figure in my comment above, and a methodological
note that may matter to anyone else measuring with the flash detector.
What I withdraw. I wrote that with
RX_VK_PER_QUEUE_FENCES=0the scene runsat "39.5 fps against 46.4 with them on (48.8 with
RX_VK_WAIT_GPU=2)". Thosenumbers came from a rolling-rate line in runs that had the detector on, and they
are not defensible: with
RX_VK_SHOT_EVERY=1the per-frame log ofRX_VK_FRAME_LOGcovers anywhere from 74% to 99% of the run, and its figuresdisagree with the cumulative present counts of the same runs. Three runs of the
same setting gave 55, 910 and 1587 logged frames for the same final minute.
What the clean measurement says. Same scenario, same machine, three runs per
setting, with the detector off so nothing is reading frames back — the
frame log then covers 98-99% of every run:
RX_VK_PER_QUEUE_FENCES=0So the direction of my original sentence was right and its size was wrong:
turning per-queue fences off costs about 36% of the frame rate in Kokiri
Forest on this machine, not the ~15% those bad numbers implied. It remains a
finding about where the second flash burst comes from, and not a setting to
recommend to anyone.
The methodological note. The detector is not free either. Same scenario,
same length, cumulative presents:
RX_VK_FLASH=1+RX_VK_SHOT_EVERY=1It roughly halves the frame rate, because every present is read back from the
GPU. So a frame rate quoted from a flash run is not the game's, and the two
cannot be mixed in one table — which is exactly the mistake I made. The flash
counts themselves are unaffected: they come from counting log lines, and they
reproduced 6/6/6, 3/3/3 and 6/6/7 as posted.
One more check on the "the second burst is gone" claim, because every burst I
had measured sat barely above the detector's default threshold
(
RX_VK_FLASH_CELLS=40, and the bursts scored 40 to 71 cells). A burst thatmerely weakened would therefore look identical to one that disappeared.
So I ran both settings again with the threshold lowered to 16, two runs each:
RX_VK_PER_QUEUE_FENCES=0RX_VK_PER_QUEUE_FENCES=0With per-queue fences off there is no second burst at a threshold of 16 either,
and those runs carry on for another 400 presents after the first burst, so it is
not a run that ended early. The claim holds: the second burst is absent, not
weakened under the threshold.
But the default threshold is marginal for this. In the second run at
defaults the second burst scored 21-23 cells — at
RX_VK_FLASH_CELLS=40that run would have reported 3 flashes, not 6, and I would have read it as the
burst disappearing. My earlier 6/6/6 at the default was partly luck. Anyone
measuring this pulse with the detector should lower the threshold rather than
trust the default, and a count taken at the default is a lower bound.
(For reference, the readback size does not change what is detected: at
RX_VK_SHOT_W=640 RX_VK_SHOT_H=360the bursts score 40-71 cells with peaks of87-106, against 42-67 cells and peaks of 86-108 at 1280x720. It does recover
some of the detector's cost, though less than the four-fold cut in bytes would
suggest: 59% of the uninstrumented frame rate against 48%.)
Correction to the setup line in my comments above, which says "Mesa 26.2.6"
twice. That is the Mesa of the host system, and it is not the one the game
loads.
The game here runs inside a Fedora 41 container (distrobox), and it loads that
container's RADV:
The game's own log had it right all along and I misread it:
vk: device 0: AMD Radeon Graphics (RADV PHOENIX), Vulkan 1.4, driver 0x6400007decodes as 25.0.7, not 26.2.6.
So everywhere I wrote "Mesa 26.2.6", read Mesa 25.0.7 (RADV, Fedora 41). The
measurements are unaffected — every run quoted was made on that driver — but if
anyone tries to reproduce them, the version to match is 25.0.7.
More reports of this, collected here:
Tracker upkeep note (merged pull requests and code checked against main
51da0464; no new test run was made for it).Main contains #1639's parallel colour/depth-clear marking, #1943's FSR low-resolution motion-vector fix, and the separate readback/fence/uniform repairs in #1133/#2125/#2419/#2464 and #2602. There is still a disclosed gap: parallel dry replay does not mark buffer-to-texture, texture-to-texture or texture-clear destinations before worker recording. That is a source-level candidate, not an established cause of the remaining screenshots. Also, #1581's tree-shadow stabilization is not an active default fix: #2374 disabled it after GPU hangs. Please keep this tracker open and preserve the reporters' corrections about actual container driver, capture thresholds and withdrawn timings; no new flash or performance result is claimed here.