FSR 3.1 frame interpolation at 2x draws the HUD into generated frames: hearts, magic bar and button icons doubled (RX 7800 XT, release/v2.0.12) #1588

Closed
opened 2026-11-10 10:04:02 +00:00 by lucasmazzoni45-del · 3 comments
lucasmazzoni45-del commented 2026-11-10 10:04:02 +00:00 (Migrated from github.com)

Found while testing a build of release/v2.0.12 on an RX 7800 XT (Windows 11, Vulkan 1.4, driver 0x8001a0), frame generation 2x, output 2560x1440.

What I see (screenshot of normal play): the hearts, the magic bar and the button icons are doubled, with the second copy offset sideways; the bar's edge is stepped. The 3D scene next to them looks fine. It was not in a build of main before the FSR 3.1 backend (#1386), which uses the older interpolation at 2x.

What the code says (reading only): at 2x the Frame generation row now asks for the FSR 3.1 interpolation (vk_fsr3fi.cpp, asked(): opts.framegen == 2). The file says itself that it has no HUD-less input: the comments at the bindings 4-6 (~line 107), hudless_attached_factor = 0 (~857) and "the present backbuffer and the interpolation source are the same image here: this game has no separate HUD-less colour" (~1135). vk_framegen.cpp copies the present texture into the interpolation source (~657), so the HUD is in it, and FSR 3.1's interpolation can move or blend it.

Workaround: RX_VK_FSR_FG=0 (the older interpolation). I have set it but have not yet confirmed by eye that it removes the doubled HUD; I will say so here when I have.

Why a HUD-less copy is not trivial (from reading, not tested): the gameplay upscale writes a full-resolution "picture before the HUD" (vk_dlss.cpp, vk_fsr3.cpp), but it is linear HDR scene colour, a different image from the one presented, so it cannot be passed as the HUD-less input as it is (FSR needs the same colour space as the backbuffer). The other way is to copy the present-format RGBA8 target just before the first UI draw into it, which needs the draw-level boundary between the post-process pass and the HUD draws. I could not find it in the logs and did not guess it.

Question: does anyone know where in a frame the HUD draws begin (which pass writes the present image, and after how many draws)? A one-frame pass trace (target, format, size, draw count per pass) would show it, and I can produce one on this card if that helps.

Found while testing a build of `release/v2.0.12` on an RX 7800 XT (Windows 11, Vulkan 1.4, driver 0x8001a0), frame generation 2x, output 2560x1440. **What I see (screenshot of normal play):** the hearts, the magic bar and the button icons are doubled, with the second copy offset sideways; the bar's edge is stepped. The 3D scene next to them looks fine. It was not in a build of main before the FSR 3.1 backend (#1386), which uses the older interpolation at 2x. **What the code says (reading only):** at 2x the Frame generation row now asks for the FSR 3.1 interpolation (`vk_fsr3fi.cpp`, `asked()`: `opts.framegen == 2`). The file says itself that it has no HUD-less input: the comments at the bindings 4-6 (~line 107), `hudless_attached_factor = 0` (~857) and "the present backbuffer and the interpolation source are the same image here: this game has no separate HUD-less colour" (~1135). `vk_framegen.cpp` copies the present texture into the interpolation source (~657), so the HUD is in it, and FSR 3.1's interpolation can move or blend it. **Workaround:** `RX_VK_FSR_FG=0` (the older interpolation). I have set it but have **not yet confirmed by eye** that it removes the doubled HUD; I will say so here when I have. **Why a HUD-less copy is not trivial (from reading, not tested):** the gameplay upscale writes a full-resolution "picture before the HUD" (`vk_dlss.cpp`, `vk_fsr3.cpp`), but it is linear HDR scene colour, a different image from the one presented, so it cannot be passed as the HUD-less input as it is (FSR needs the same colour space as the backbuffer). The other way is to copy the present-format RGBA8 target just before the first UI draw into it, which needs the draw-level boundary between the post-process pass and the HUD draws. I could not find it in the logs and did not guess it. **Question:** does anyone know where in a frame the HUD draws begin (which pass writes the present image, and after how many draws)? A one-frame pass trace (target, format, size, draw count per pass) would show it, and I can produce one on this card if that helps.
lucasmazzoni45-del commented 2026-11-10 10:04:47 +00:00 (Migrated from github.com)

Retracting this report. New information from the same session: the doubled HUD went away by itself after changing area (it was in the Kakariko graveyard; after walking to the neighbouring village the HUD was normal), and the game had not been restarted, so the FSR 3.1 interpolation was still active both times. A cause that is always present (FSR's missing HUD-less input) would not come and go with the area, so my explanation in the first post is not supported. The code facts I quoted about the missing HUD-less input are still true, but I have no evidence that they caused what I saw.

It looks more like the other area-bound artifacts from that place (a bright light shaft over dark forest; see #1117 / #1004: blocky halos that clear when leaving and coming back), now also showing on the HUD that sits over it. I do not know yet. I will reopen or file a new report only with a capture where it happens with and without RX_VK_FSR_FG=0, in the same spot.

Closing as not planned. Sorry for the noise.

Retracting this report. New information from the same session: the doubled HUD **went away by itself after changing area** (it was in the Kakariko graveyard; after walking to the neighbouring village the HUD was normal), and the game had not been restarted, so the FSR 3.1 interpolation was still active both times. A cause that is always present (FSR's missing HUD-less input) would not come and go with the area, so my explanation in the first post is not supported. The code facts I quoted about the missing HUD-less input are still true, but I have no evidence that they caused what I saw. It looks more like the other area-bound artifacts from that place (a bright light shaft over dark forest; see #1117 / #1004: blocky halos that clear when leaving and coming back), now also showing on the HUD that sits over it. I do not know yet. I will reopen or file a new report only with a capture where it happens with and without `RX_VK_FSR_FG=0`, in the same spot. Closing as not planned. Sorry for the noise.
lucasmazzoni45-del commented 2026-11-10 12:51:08 +00:00 (Migrated from github.com)

Reopening, with a correction: my retraction above was wrong. It rested on a session in which the log said 0 of the last 600 made frames by FSR 3.1 (the renderer's own interpolation was making the frames), so that session neither showed nor ruled out the FSR 3.1 backend. In the later session where FSR 3.1 was really making the frames (RX 7800 XT, v2.0.12 + local patches, 2560x1440, render scale 100%, frame generation 2x, frame pacing on; the log says fsr3fi: 2560x1440 from 2560x1440 inputs ... and then 600 of the last 600 made frames by FSR 3.1), I saw the HUD tremble when moving the camera and a ghost-like effect on Link when he moves. With RX_VK_FSR_FG=0 in hookshot_env.txt, nothing else changed, the HUD no longer trembles (first session, only a few minutes, so a short sample; the log shows the renderer's interpolation again and the shown frames evenly spaced: 600 of 600 in 7-9 ms, against about 16% in 9-12 ms with FSR).

This is the same as @SaKenLpB's report in #995 (HUD hearts and top-left button flicker with FSR 3.1 interpolation on by default in v2.0.12, fixed by RX_VK_FSR_FG=0, about 1.3 ms a frame saved).

Why, from reading the code (not tested on screen): the FSR 3.1 interpolation gets the final colour with the HUD already on it and no HUD-less input (vk_fsr3fi.cpp ~107, ~857, ~1135); its depth and motion come from the scene (shaders/fsr3_prep.comp ~35-53), so a HUD pixel takes the motion of whatever is behind it and moves with the camera in made frames. And an actor like Link has no motion of its own in this path (fsr3_prep.comp ~15-16, vk_fsr3_inputs.cpp), unlike the DLSS path, which has the bone transforms.

Not confirmed yet: whether the ghost on Link also goes away with RX_VK_FSR_FG=0 in a longer session, and whether a fix exists that keeps FSR 3.1 (an HUD-less input needs the draw where the HUD starts; I could not find it in the logs). I will say here after a longer run.

The one-off doubled HUD with stepped edges at the Kakariko graveyard that I first reported happened in a session where the renderer, not FSR, made the frames, so that one is a different, transient thing.

Reopening, with a correction: **my retraction above was wrong.** It rested on a session in which the log said `0 of the last 600 made frames by FSR 3.1` (the renderer's own interpolation was making the frames), so that session neither showed nor ruled out the FSR 3.1 backend. In the later session where FSR 3.1 was really making the frames (RX 7800 XT, v2.0.12 + local patches, 2560x1440, render scale 100%, frame generation 2x, frame pacing on; the log says `fsr3fi: 2560x1440 from 2560x1440 inputs ...` and then `600 of the last 600 made frames by FSR 3.1`), I saw **the HUD tremble when moving the camera and a ghost-like effect on Link when he moves**. With `RX_VK_FSR_FG=0` in `hookshot_env.txt`, nothing else changed, **the HUD no longer trembles** (first session, only a few minutes, so a short sample; the log shows the renderer's interpolation again and the shown frames evenly spaced: 600 of 600 in 7-9 ms, against about 16% in 9-12 ms with FSR). This is the same as @SaKenLpB's report in #995 (HUD hearts and top-left button flicker with FSR 3.1 interpolation on by default in v2.0.12, fixed by `RX_VK_FSR_FG=0`, about 1.3 ms a frame saved). **Why, from reading the code (not tested on screen):** the FSR 3.1 interpolation gets the final colour with the HUD already on it and no HUD-less input (`vk_fsr3fi.cpp` ~107, ~857, ~1135); its depth and motion come from the scene (`shaders/fsr3_prep.comp` ~35-53), so a HUD pixel takes the motion of whatever is behind it and moves with the camera in made frames. And an actor like Link has no motion of its own in this path (`fsr3_prep.comp` ~15-16, `vk_fsr3_inputs.cpp`), unlike the DLSS path, which has the bone transforms. **Not confirmed yet:** whether the ghost on Link also goes away with `RX_VK_FSR_FG=0` in a longer session, and whether a fix exists that keeps FSR 3.1 (an HUD-less input needs the draw where the HUD starts; I could not find it in the logs). I will say here after a longer run. The one-off doubled HUD with stepped edges at the Kakariko graveyard that I first reported happened in a session where the renderer, not FSR, made the frames, so that one is a different, transient thing.
NotRexed commented 2026-11-11 21:22:59 +00:00 (Migrated from github.com)

Thanks for the report. Reports of the same problem are now collected in #2510, which lists this one with your details and links back here, so one fix closes them together and the open list stays readable. Follow #2510 for the fix, and add new details there (or here). If this turns out to be a separate problem it will be reopened.

Thanks for the report. Reports of the same problem are now collected in #2510, which lists this one with your details and links back here, so one fix closes them together and the open list stays readable. Follow #2510 for the fix, and add new details there (or here). If this turns out to be a separate problem it will be reopened.
Commenting is not possible because the repository is archived.
No milestone
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Hookshot#1588
No description provided.