v2.1.0, RX 9070 XT, 4K HDR + frame generation: render targets remade ~3.6 times a frame, VRAM reaches the allowed limit, then the main and presentation threads stop (freeze on breaking a jar) #2180

Closed
opened 2026-11-11 06:18:25 +00:00 by bunbeans2-arch · 9 comments
bunbeans2-arch commented 2026-11-11 06:18:25 +00:00 (Migrated from github.com)

Hookshot version

v2.1.0 (source 10a10b90), built from source with make_game.py. Not a stock build: three local changes (the one-line RGB10A2 format-class workaround from #2038, a host-side sprint patch, and a hook that swaps one tone-map fragment stage for another SPIR-V module at load). I have not yet repeated this on the stock renderer, so please weigh it accordingly; I will post that result here.

What kind of problem

Freeze (picture stops, the process stays alive)

What happened

Two bad sessions out of two on v2.1.0, same PC that has run v2.0.9 and v2.0.13 for days:

  1. First session: the whole PC reset a few minutes into play (Windows Kernel-Power 41, bugcheck code 0, no minidump, no LiveKernelEvent 141). The log just ends, no error line.
  2. Second session: about 12 minutes of free roaming in Kokiri Forest, then the picture froze the moment a jar was broken. The process stayed alive (about 4.7 CPU cores busy, Responding = True) until I ended it a minute later.

What the log of the second session shows:

  • The last 20 seconds. VRAM was steady at about 11.9 GB of 14.7 GB allowed for minutes, then 13.0 GB, then vk: write-back diff: VRAM 14706 of 14706 MB: the shadows given back (352 MB). Heap 2 reads used 230 of 230 MB. The fps reports go 50.3, 46.0, 43.8, 49.5, 45.3, 40.6, 19.2.
  • The stop. After the last sead::MainThread and Presentation Thread lines only rmbl::VibrationThread keeps logging. No device lost, no failed (-4), no not made (-13), no write-back timeout. This is the same signature as two comments in #996 (RX 6800 on v2.0.11, and RX 6650 XT on v2.0.12 after closing a menu).
  • Render-target churn. vk: render targets drawn over from another start, let go: 104529 so far (605746 MB) after 29,280 presents, about 3.6 a frame, and it speeds up through the session (3 early on, 8,727 a third of the way in, 49,137 at the half, 97,486 near the end). vk: render target images: 48212 reused from the pool, 57466 made new, 57153 destroyed from it. vk: texture slots registered again at another size: 2000000. Render-target image blocks peaked at 36 blocks 4608 MB, 657 images 4165 MB. Textures reached 7,223 MB against the 6,144 MB budget.
  • For comparison, v2.0.13 on the same PC (bench runs of about 9,000 presents, frame generation off): let go: 167 so far (717 MB) and 289 so far (1335 MB), render target images: 46 reused from the pool, 281 made new, render-target blocks 8 blocks 1024 MB.
  • System memory. vk: memory: ... private goes 18,769 MB, 29,662 MB, 32,459 MB, 33,428 MB on a 32 GB PC (commit nearly exhausted). v2.0.13 shows the same shape about 4.7 GB lower (14.1 GB to 25.6 GB), so this part looks like a higher plateau, not a steady leak.

What I can not tell yet: the two v2.1.0 sessions differ from my v2.0.13 logs in three ways at once (the version, frame generation on, and free roaming instead of a fixed bench route). #2156 reports VRAM pressure in Kokiri Forest that is new in v2.1.0 on another card, which is why I am filing this now instead of after the A/B runs.

Where in the game

Kokiri Forest, free roaming; the freeze came on breaking a jar.

How often

2 bad sessions of 2 on v2.1.0 (one PC reset, one freeze).

Graphics card and driver version

AMD Radeon RX 9070 XT (16 GB), Vulkan 1.4, driver 0x8001a0 as the log reports it.

CPU, RAM and operating system

Intel Core i9-9900K, 32 GB DDR4, Windows 11 Pro 22631, 23.5 GB page file.

Changes from the defaults

  • Display: 3840x2160 HDR10 (log: HDR: an HDR10 surface (format 64), paper white 200 nits, peak 1000 nits), swapchain 3840x2097.
  • Options: quality_preset=0 (Custom), resolution=1, upscaling=2, hdr=2, frame_generation=2 (log: frame interpolation ready: Auto, a frame for each of the display's refreshes (120 Hz; up to 4 a game frame); the session that ended in the PC reset logged 8x the game's frames).
  • Environment: RX_VK_WB_DIFF=1, RX_VK_PRESENT_QUEUE=1, RX_VK_CHUNK=480, RX_VK_PREFETCH_CHUNKS=2, RX_VK_PARALLEL=4, HOOKSHOT_NO_UPDATE_CHECK=1.

Other software hooked into the game

No overlays or injectors. Recording software was closed before the second session.

hookshot_log.txt

I can attach the full log of the freeze session (12 thousand lines). The last lines before the stop:

vk: VRAM: 11926 MB used of 14706 MB allowed (2724 MB of it free in the blocks); textures 4258 MB (budget 6144 MB), 1948 textures
vk: memory: working set 17932 MB (peak 18094), private 33428 MB, staging 128 MB in 2 arenas
vk: memory heaps: heap 0 (device): 106 blocks 11481 MB, 2233 allocations 8526 MB; used 12793 of 14475 MB; ... heap 2 (device): 53 blocks 256 MB, 84 allocations 255 MB; used 230 of 230 MB;
vk: image blocks (render targets): 30 blocks 3840 MB, 313 images 2033 MB; 247 free ranges, the largest 111 MB
vk: render target images: 48212 reused from the pool, 57466 made new, 57153 destroyed from it; it holds 104 (802 MB)
vk: VRAM: 13024 MB used of 14706 MB allowed (2954 MB of it free in the blocks); textures 4501 MB (budget 6144 MB), 2014 textures
vk: render targets drawn over from another start, let go: 104529 so far (605746 MB)
vk: write-back diff: VRAM 14706 of 14706 MB: the shadows given back (352 MB)
vk: compute pipeline of b29688e8c0241504: SLOW compile, 2856 ms (on a worker)
vk: compute pipeline of c3b0ec43dfb6747e: SLOW compile, 3007 ms (on a worker)
nvn: CommandBufferWaitEvent #605000: event 0x101096802c mode 0 value 447544 (now 447506) (lr 0x8028ca9c)
vk: 29280 presents, 19.2 fps; a frame: 1282 draws (0 skipped), 112 dispatches, 225 passes, 209 barriers, 6 submits
vi: 29311 frames presented (26.4 fps over the last 5.0 s, interval 1)
[sead::MainThread] vk: readbacks of GPU results: 508 of 3000 waited for their write-back, 0.06 ms each
[rmbl::VibrationThread] hid: 131072 vibration values, strongest 0.10 since the last count
[rmbl::VibrationThread] hid: 135168 vibration values, strongest 0.00 since the last count
[rmbl::VibrationThread] hid: 139264 vibration values, strongest 0.00 since the last count

Questions

  1. Is "render targets drawn over from another start, let go" at 3 to 4 a frame expected with frame generation on, or is that already a fault?
  2. When the shadows are given back at the VRAM limit, is there a wait on the main or presentation thread that can no longer be satisfied?
  3. Which one capture would help most on the next freeze (thread stacks, RX_VK_CHECKPOINTS=1, something else)?

Next from my side

Same build with frame_generation=0, then the stock renderer, then RX_VK_VRAM_MB=4096 for headroom. Results will go in this issue.

Before you send it

  • I'm on the newest release, or the problem is still there on it.
  • I searched the open issues for this problem (#996, #2156, #2164, #1710 are related; none describes this).
  • I'm not attaching game files, keys, hookshot.exe, the .bin caches or saves.
### Hookshot version v2.1.0 (source 10a10b90), built from source with make_game.py. **Not a stock build**: three local changes (the one-line RGB10A2 format-class workaround from #2038, a host-side sprint patch, and a hook that swaps one tone-map fragment stage for another SPIR-V module at load). I have not yet repeated this on the stock renderer, so please weigh it accordingly; I will post that result here. ### What kind of problem Freeze (picture stops, the process stays alive) ### What happened Two bad sessions out of two on v2.1.0, same PC that has run v2.0.9 and v2.0.13 for days: 1. First session: the whole PC reset a few minutes into play (Windows Kernel-Power 41, bugcheck code 0, no minidump, no LiveKernelEvent 141). The log just ends, no error line. 2. Second session: about 12 minutes of free roaming in Kokiri Forest, then the picture froze the moment a jar was broken. The process stayed alive (about 4.7 CPU cores busy, `Responding = True`) until I ended it a minute later. What the log of the second session shows: - **The last 20 seconds.** VRAM was steady at about 11.9 GB of 14.7 GB allowed for minutes, then 13.0 GB, then `vk: write-back diff: VRAM 14706 of 14706 MB: the shadows given back (352 MB)`. Heap 2 reads `used 230 of 230 MB`. The fps reports go 50.3, 46.0, 43.8, 49.5, 45.3, 40.6, 19.2. - **The stop.** After the last `sead::MainThread` and `Presentation Thread` lines only `rmbl::VibrationThread` keeps logging. No `device lost`, no `failed (-4)`, no `not made (-13)`, no write-back timeout. This is the same signature as two comments in #996 (RX 6800 on v2.0.11, and RX 6650 XT on v2.0.12 after closing a menu). - **Render-target churn.** `vk: render targets drawn over from another start, let go: 104529 so far (605746 MB)` after 29,280 presents, about 3.6 a frame, and it speeds up through the session (3 early on, 8,727 a third of the way in, 49,137 at the half, 97,486 near the end). `vk: render target images: 48212 reused from the pool, 57466 made new, 57153 destroyed from it`. `vk: texture slots registered again at another size: 2000000`. Render-target image blocks peaked at `36 blocks 4608 MB, 657 images 4165 MB`. Textures reached 7,223 MB against the 6,144 MB budget. - **For comparison, v2.0.13 on the same PC** (bench runs of about 9,000 presents, frame generation off): `let go: 167 so far (717 MB)` and `289 so far (1335 MB)`, `render target images: 46 reused from the pool, 281 made new`, render-target blocks `8 blocks 1024 MB`. - **System memory.** `vk: memory: ... private` goes 18,769 MB, 29,662 MB, 32,459 MB, 33,428 MB on a 32 GB PC (commit nearly exhausted). v2.0.13 shows the same shape about 4.7 GB lower (14.1 GB to 25.6 GB), so this part looks like a higher plateau, not a steady leak. What I can not tell yet: the two v2.1.0 sessions differ from my v2.0.13 logs in three ways at once (the version, frame generation on, and free roaming instead of a fixed bench route). #2156 reports VRAM pressure in Kokiri Forest that is new in v2.1.0 on another card, which is why I am filing this now instead of after the A/B runs. ### Where in the game Kokiri Forest, free roaming; the freeze came on breaking a jar. ### How often 2 bad sessions of 2 on v2.1.0 (one PC reset, one freeze). ### Graphics card and driver version AMD Radeon RX 9070 XT (16 GB), Vulkan 1.4, driver 0x8001a0 as the log reports it. ### CPU, RAM and operating system Intel Core i9-9900K, 32 GB DDR4, Windows 11 Pro 22631, 23.5 GB page file. ### Changes from the defaults - Display: 3840x2160 HDR10 (log: `HDR: an HDR10 surface (format 64), paper white 200 nits, peak 1000 nits`), swapchain 3840x2097. - Options: `quality_preset=0` (Custom), `resolution=1`, `upscaling=2`, `hdr=2`, `frame_generation=2` (log: `frame interpolation ready: Auto, a frame for each of the display's refreshes (120 Hz; up to 4 a game frame)`; the session that ended in the PC reset logged `8x the game's frames`). - Environment: `RX_VK_WB_DIFF=1`, `RX_VK_PRESENT_QUEUE=1`, `RX_VK_CHUNK=480`, `RX_VK_PREFETCH_CHUNKS=2`, `RX_VK_PARALLEL=4`, `HOOKSHOT_NO_UPDATE_CHECK=1`. ### Other software hooked into the game No overlays or injectors. Recording software was closed before the second session. ### hookshot_log.txt I can attach the full log of the freeze session (12 thousand lines). The last lines before the stop: ``` vk: VRAM: 11926 MB used of 14706 MB allowed (2724 MB of it free in the blocks); textures 4258 MB (budget 6144 MB), 1948 textures vk: memory: working set 17932 MB (peak 18094), private 33428 MB, staging 128 MB in 2 arenas vk: memory heaps: heap 0 (device): 106 blocks 11481 MB, 2233 allocations 8526 MB; used 12793 of 14475 MB; ... heap 2 (device): 53 blocks 256 MB, 84 allocations 255 MB; used 230 of 230 MB; vk: image blocks (render targets): 30 blocks 3840 MB, 313 images 2033 MB; 247 free ranges, the largest 111 MB vk: render target images: 48212 reused from the pool, 57466 made new, 57153 destroyed from it; it holds 104 (802 MB) vk: VRAM: 13024 MB used of 14706 MB allowed (2954 MB of it free in the blocks); textures 4501 MB (budget 6144 MB), 2014 textures vk: render targets drawn over from another start, let go: 104529 so far (605746 MB) vk: write-back diff: VRAM 14706 of 14706 MB: the shadows given back (352 MB) vk: compute pipeline of b29688e8c0241504: SLOW compile, 2856 ms (on a worker) vk: compute pipeline of c3b0ec43dfb6747e: SLOW compile, 3007 ms (on a worker) nvn: CommandBufferWaitEvent #605000: event 0x101096802c mode 0 value 447544 (now 447506) (lr 0x8028ca9c) vk: 29280 presents, 19.2 fps; a frame: 1282 draws (0 skipped), 112 dispatches, 225 passes, 209 barriers, 6 submits vi: 29311 frames presented (26.4 fps over the last 5.0 s, interval 1) [sead::MainThread] vk: readbacks of GPU results: 508 of 3000 waited for their write-back, 0.06 ms each [rmbl::VibrationThread] hid: 131072 vibration values, strongest 0.10 since the last count [rmbl::VibrationThread] hid: 135168 vibration values, strongest 0.00 since the last count [rmbl::VibrationThread] hid: 139264 vibration values, strongest 0.00 since the last count ``` ### Questions 1. Is "render targets drawn over from another start, let go" at 3 to 4 a frame expected with frame generation on, or is that already a fault? 2. When the shadows are given back at the VRAM limit, is there a wait on the main or presentation thread that can no longer be satisfied? 3. Which one capture would help most on the next freeze (thread stacks, `RX_VK_CHECKPOINTS=1`, something else)? ### Next from my side Same build with `frame_generation=0`, then the stock renderer, then `RX_VK_VRAM_MB=4096` for headroom. Results will go in this issue. ### Before you send it - [x] I'm on the newest release, or the problem is still there on it. - [x] I searched the open issues for this problem (#996, #2156, #2164, #1710 are related; none describes this). - [x] I'm not attaching game files, keys, hookshot.exe, the .bin caches or saves.
bunbeans2-arch commented 2026-11-11 06:33:33 +00:00 (Migrated from github.com)

Correction to point 1 of my report, from the person at the PC (I wrote it from the Windows event log alone, which was wrong):

The first session did not end in a spontaneous reset. The whole PC hung when the Graphics row "Frame pacing" was switched to Off in the settings menu, about 100 seconds after the long first-start preparation had finished (4,800 presents into play): the picture stopped and nothing else on the PC responded either, so it was powered off by hand. That forced power-off is what Windows recorded as Kernel-Power 41 (bugcheck code 0, no minidump, no LiveKernelEvent 141). The game log of that session simply ends, with no error line; a few lines before its end it has frame interpolation ready: 8x the game's frames.

So the two v2.1.0 sessions were:

  1. a whole-PC hang on switching "Frame pacing" to Off in the settings menu (power-off needed);
  2. a game-only freeze on breaking a jar, 12 minutes into roaming (process alive, ended by hand).

Two things that differ from how this PC normally runs the game, so please read the report with them in mind:

  • The logs show the Frame generation row was not Off in either session (frame interpolation ready: 8x the game's frames in the first; Auto ... up to 4 a game frame at the start of the second, and the options file saved 79 s before the freeze has frame_generation=2). The player believes it was off, so the row may have been changed without meaning to; the usual install here runs with it off. In the second session the last frame interpolation: report before the freeze has most frames shown 17-25 ms apart, so few or no made frames were being shown by then.
  • The options file saved after the second session has resolution=1 (100 % render) and frame_generation=2; the usual install runs at 75 % render. I do not know the render percentage of the first session.

Everything else in the report stands. A/B runs under a safety stop have started (frame generation off first, then the freeze settings again, the stock renderer, and a smaller texture budget); the results will follow here.

Correction to point 1 of my report, from the person at the PC (I wrote it from the Windows event log alone, which was wrong): The first session did not end in a spontaneous reset. The **whole PC hung** when the Graphics row "Frame pacing" was switched to Off in the settings menu, about 100 seconds after the long first-start preparation had finished (4,800 presents into play): the picture stopped and nothing else on the PC responded either, so it was **powered off by hand**. That forced power-off is what Windows recorded as Kernel-Power 41 (bugcheck code 0, no minidump, no LiveKernelEvent 141). The game log of that session simply ends, with no error line; a few lines before its end it has `frame interpolation ready: 8x the game's frames`. So the two v2.1.0 sessions were: 1. a whole-PC hang on switching "Frame pacing" to Off in the settings menu (power-off needed); 2. a game-only freeze on breaking a jar, 12 minutes into roaming (process alive, ended by hand). Two things that differ from how this PC normally runs the game, so please read the report with them in mind: - The logs show the Frame generation row was not Off in either session (`frame interpolation ready: 8x the game's frames` in the first; `Auto ... up to 4 a game frame` at the start of the second, and the options file saved 79 s before the freeze has `frame_generation=2`). The player believes it was off, so the row may have been changed without meaning to; the usual install here runs with it off. In the second session the last `frame interpolation:` report before the freeze has most frames shown 17-25 ms apart, so few or no made frames were being shown by then. - The options file saved after the second session has `resolution=1` (100 % render) and `frame_generation=2`; the usual install runs at 75 % render. I do not know the render percentage of the first session. Everything else in the report stands. A/B runs under a safety stop have started (frame generation off first, then the freeze settings again, the stock renderer, and a smaller texture budget); the results will follow here.
bunbeans2-arch commented 2026-11-11 07:24:06 +00:00 (Migrated from github.com)

Update from a night of runs under a safety stop, with three corrections to my report first.

Corrections

  • Place. The freeze was in Hyrule Castle Town (the player's saves there are in the market), not Kokiri Forest. My mistake in the report.
  • The v2.0.13 comparison in the report is not like for like. Those v2.0.13 logs were a standing bench in Kokiri Forest; the freeze was free roaming in the market. I have no v2.0.13 run of the market yet, so please do not read "167 against 104,529 let go" as a regression. The note in vk_texture.cpp about the market's per-frame scratch targets is in v2.0.13 too.
  • Frame generation in the freeze run. I wrote that few or no made frames were shown at the end. Wrong: counting the frames in each frame interpolation: report against the game's fps gives 1.65 to 2.19 shown per game frame in every one of the last 16 reports, most of them 2.00 or 2.01 (for example 504 in a report at 50 fps). Over the whole run the row had been stepped Auto, Off, 2x, 4x, 8x (two reports at 8.1 per game frame, no hang), Off, Auto, 2x. The freeze came in steady 2x, 79 s after the last change. AMD FSR 3.1 was also the upscaler for part of the run (fsr3: 3840x2160 -> 3840x2160) and had been switched back to the game's own by then. #2185 (same card, FSR 3.1 + 2x, "toggling Fullscreen fixes it") may be the same stall; we did not know to try that.

New: the render-target part happens at plain settings, no frame generation needed

Same build, market save, 3840x2160 output, render 75 %, the game's own upscaler, frame generation off, Custom preset (budget 6144 MB), 90 s standing then a scripted walk, 330 s in all. No freeze. From the log:

standing walking
render targets let go, per present 0.42-0.80 1.7-17.0
render target images: ... made new 573 48,480 at the end (38,121 reused from the pool)
image blocks (render targets) 1,024-1,152 MB up to 3,968 MB (3,548 MB of images)

VRAM peaked at 11,738 of 14,581 MB allowed. Hyrule Field with the same settings and walk: 7,354 let go in 21,000 presents, blocks 1,152 MB.

What the blow-ups have in common: the cache is over its budget

In both runs the reports where the target blocks jump are the ones where the textures are over the budget, and no others:

  • freeze run: textures 7201 MB (budget 6144 MB) and 7223 MB, VRAM 92.3 %, blocks 13 -> 36 (1,664 -> 4,608 MB) in one report interval;
  • market run above: textures 6683 MB (budget 6144 MB), the report with 3,968 MB of blocks.

From there the freeze run retires 6,216-15,441 textures per 500 log lines, against 1,124-2,125 before.

Reading texture_frame: with total_bytes > budget the pass is not a sweep, walks the textures oldest first and stops once the excess down to 7/8 of the budget is chosen. The targets another has drawn over are the youngest in that order, so the pass does not reach them: live textures unused for 60 presents go and are uploaded again, while the dead targets stay and keep the total over the budget. That is the behaviour #2198 describes and fixes for the RX_VK_COMPACT hold; here RX_VK_COMPACT was off and it is the budget's own pass.

Next from us (results will follow here, runs only): the market walk with RX_VK_VRAM_MB=9000; the same walk with a local change that lets an over-budget pass take the dead targets first, A/B by a switch on one build; and a v2.0.13 run of the same market save if we can set up a v2.0.13 copy.

Not shown by any of this: why the picture finally stops. The log's last lines are three compute-pipeline compiles of about 3 s each and VRAM at 14,706 of 14,706 MB, then nothing from the Presentation or main thread. A run with RX_VK_HANG_DUMP set is part of the plan.

Update from a night of runs under a safety stop, with three corrections to my report first. **Corrections** - **Place.** The freeze was in Hyrule Castle Town (the player's saves there are in the market), not Kokiri Forest. My mistake in the report. - **The v2.0.13 comparison in the report is not like for like.** Those v2.0.13 logs were a standing bench in Kokiri Forest; the freeze was free roaming in the market. I have no v2.0.13 run of the market yet, so please do not read "167 against 104,529 let go" as a regression. The note in `vk_texture.cpp` about the market's per-frame scratch targets is in v2.0.13 too. - **Frame generation in the freeze run.** I wrote that few or no made frames were shown at the end. Wrong: counting the frames in each `frame interpolation:` report against the game's fps gives 1.65 to 2.19 shown per game frame in every one of the last 16 reports, most of them 2.00 or 2.01 (for example 504 in a report at 50 fps). Over the whole run the row had been stepped Auto, Off, 2x, 4x, 8x (two reports at 8.1 per game frame, no hang), Off, Auto, 2x. The freeze came in steady 2x, 79 s after the last change. AMD FSR 3.1 was also the upscaler for part of the run (`fsr3: 3840x2160 -> 3840x2160`) and had been switched back to the game's own by then. #2185 (same card, FSR 3.1 + 2x, "toggling Fullscreen fixes it") may be the same stall; we did not know to try that. **New: the render-target part happens at plain settings, no frame generation needed** Same build, market save, 3840x2160 output, render 75 %, the game's own upscaler, frame generation off, Custom preset (budget 6144 MB), 90 s standing then a scripted walk, 330 s in all. No freeze. From the log: | | standing | walking | |---|---|---| | render targets let go, per present | 0.42-0.80 | 1.7-17.0 | | `render target images: ... made new` | 573 | 48,480 at the end (38,121 reused from the pool) | | image blocks (render targets) | 1,024-1,152 MB | up to 3,968 MB (3,548 MB of images) | VRAM peaked at 11,738 of 14,581 MB allowed. Hyrule Field with the same settings and walk: 7,354 let go in 21,000 presents, blocks 1,152 MB. **What the blow-ups have in common: the cache is over its budget** In both runs the reports where the target blocks jump are the ones where the textures are over the budget, and no others: - freeze run: `textures 7201 MB (budget 6144 MB)` and `7223 MB`, VRAM 92.3 %, blocks 13 -> 36 (1,664 -> 4,608 MB) in one report interval; - market run above: `textures 6683 MB (budget 6144 MB)`, the report with 3,968 MB of blocks. From there the freeze run retires 6,216-15,441 textures per 500 log lines, against 1,124-2,125 before. Reading `texture_frame`: with `total_bytes > budget` the pass is not a sweep, walks the textures oldest first and stops once the excess down to 7/8 of the budget is chosen. The targets another has drawn over are the youngest in that order, so the pass does not reach them: live textures unused for 60 presents go and are uploaded again, while the dead targets stay and keep the total over the budget. That is the behaviour #2198 describes and fixes for the `RX_VK_COMPACT` hold; here `RX_VK_COMPACT` was off and it is the budget's own pass. **Next from us** (results will follow here, runs only): the market walk with `RX_VK_VRAM_MB=9000`; the same walk with a local change that lets an over-budget pass take the dead targets first, A/B by a switch on one build; and a v2.0.13 run of the same market save if we can set up a v2.0.13 copy. Not shown by any of this: why the picture finally stops. The log's last lines are three compute-pipeline compiles of about 3 s each and VRAM at 14,706 of 14,706 MB, then nothing from the Presentation or main thread. A run with `RX_VK_HANG_DUMP` set is part of the plan.
bunbeans2-arch commented 2026-11-11 08:40:51 +00:00 (Migrated from github.com)

A correction to my last comment, after one more run and a closer read of the same logs.

I wrote that what the target-block jumps have in common is that the cache is over its budget. That reads like a cause, and it is not one:

  • The textures N MB figure includes the render targets' images. Taking away the image blocks (render targets): ... images M MB figure of the same report leaves a flat rest: 2,876 and 3,058 MB in the freeze run's two over-budget reports, 3,135 MB in the market run's one. What went over is the target images themselves: 4,325 MB in 542 images, 4,165 MB in 657, 3,548 MB in 831, where the reports around them have about 210-230 images and 1.0-1.2 GB. So the over-budget report and the block jump are one event, a pile of target images 3 to 4 times the usual size.
  • Hyrule Field went over its budget once through ordinary textures (6,172 of 6,144 MB, target images 849 MB) and nothing jumped.
  • New run, the market walk again with RX_VK_VRAM_MB=9000 and nothing else changed: textures never over the budget (6,973 MB at most), and the target blocks still reached 3,456 MB (3,968 at 6144), with 84,307 targets let go (85,842) and 46,940 made new (48,480). A bigger budget does not stop the blocks growing. It kept about 0.9 GB more of other textures resident (median 4,031 against 3,159 MB), and at what looks like an area change at the end VRAM went to 12,201 of 14,581 MB.
  • I also pointed at the rise in textures retired. Most of those are the let-go targets themselves: 86.0 % in the freeze run, 85.6 % in the 6144 market run, 97.7 % in the 9000 one. What is left over is larger at 6144 (12,549 retirements against 2,002, more than half of them in the one report interval after the over-budget report), which fits an over-budget pass taking other textures first, but with reports 600 presents apart that is a weak sign, not a result.

So: the open question on the memory side is why the pile of drawn-over target images sometimes grows to 3 or 4 times its usual size before it is let go. Next from us are runs that let dead targets go sooner (RX_VK_DEAD_MIN_UNUSED, RX_VK_DEAD_EVERY) and the A/B of the dead-targets-first change at a budget low enough to be over it. Still nothing here explains the picture stopping; that needs the run with frame generation 2x and RX_VK_HANG_DUMP.

A correction to my last comment, after one more run and a closer read of the same logs. I wrote that what the target-block jumps have in common is that the cache is over its budget. That reads like a cause, and it is not one: - The `textures N MB` figure includes the render targets' images. Taking away the `image blocks (render targets): ... images M MB` figure of the same report leaves a flat rest: 2,876 and 3,058 MB in the freeze run's two over-budget reports, 3,135 MB in the market run's one. What went over is the target images themselves: 4,325 MB in 542 images, 4,165 MB in 657, 3,548 MB in 831, where the reports around them have about 210-230 images and 1.0-1.2 GB. So the over-budget report and the block jump are one event, a pile of target images 3 to 4 times the usual size. - Hyrule Field went over its budget once through ordinary textures (6,172 of 6,144 MB, target images 849 MB) and nothing jumped. - New run, the market walk again with `RX_VK_VRAM_MB=9000` and nothing else changed: textures never over the budget (6,973 MB at most), and the target blocks still reached 3,456 MB (3,968 at 6144), with 84,307 targets let go (85,842) and 46,940 made new (48,480). A bigger budget does not stop the blocks growing. It kept about 0.9 GB more of other textures resident (median 4,031 against 3,159 MB), and at what looks like an area change at the end VRAM went to 12,201 of 14,581 MB. - I also pointed at the rise in `textures retired`. Most of those are the let-go targets themselves: 86.0 % in the freeze run, 85.6 % in the 6144 market run, 97.7 % in the 9000 one. What is left over is larger at 6144 (12,549 retirements against 2,002, more than half of them in the one report interval after the over-budget report), which fits an over-budget pass taking other textures first, but with reports 600 presents apart that is a weak sign, not a result. So: the open question on the memory side is why the pile of drawn-over target images sometimes grows to 3 or 4 times its usual size before it is let go. Next from us are runs that let dead targets go sooner (`RX_VK_DEAD_MIN_UNUSED`, `RX_VK_DEAD_EVERY`) and the A/B of the dead-targets-first change at a budget low enough to be over it. Still nothing here explains the picture stopping; that needs the run with frame generation 2x and `RX_VK_HANG_DUMP`.
bunbeans2-arch commented 2026-11-11 11:27:14 +00:00 (Migrated from github.com)

A second, separate cause of a stopped picture on this card, not memory: present ahead (Frame generation 2x) together with RX_VK_PRESENT_QUEUE=1, which was our own opt-in setting. Runs, hang-dump frames and what avoids it are in #1702: #1702

A second, separate cause of a stopped picture on this card, not memory: present ahead (Frame generation 2x) together with `RX_VK_PRESENT_QUEUE=1`, which was our own opt-in setting. Runs, hang-dump frames and what avoids it are in #1702: https://git.magicbean.dev/MagicBeanDev/Hookshot/issues/1702
bunbeans2-arch commented 2026-11-11 16:08:18 +00:00 (Migrated from github.com)

A separate memory factor on Windows, found while chasing a whole-PC hang: the start that builds the shader programs keeps much more RAM than a start that finds them, and keeps it in play.

Same PC (RX 9070 XT 16 GB, 32 GB RAM, Windows 11), v2.1.0 built from source with a few local changes (none of them in the shader build or the heap), same save, same spot.

At the title screen (one run each):

start working set private free RAM on the PC
programs kept (46604 program keys kept) 14,767 MB 20,818 MB 6 GB or more
programs built (0 program keys kept, then prepared 38809 shader programs (46597 new, 70 failed ...)) 16,235 MB rising to 20,225 MB 23,453 MB 3,039 MB, then 1,340 MB (our guard ended that run there, before play)

In play, standing at the same spot (last vk: memory: line of each run; the kept runs are shorter, the built runs stood there 2.5 to 7 minutes):

start working set private lowest free RAM on the PC
programs kept (3 runs, frame generation on) 17,308 to 17,391 MB 28,505 to 28,647 MB 5,930 to 6,079 MB
programs built in this process, frame generation off 22,042 MB 30,656 MB 958 MB
programs built in this process, then Ultra preset and 8x frame generation from the menu 21,993 MB 31,854 MB 1,151 MB
programs built in this process, working set emptied once after the build (see below) 9,273 MB 30,714 MB 9,146 MB

So the process that built the programs holds about 4.7 GB more of the PC's RAM in play, and a 32 GB PC is left with about 1 GB free. Neither of those runs hung. An earlier session that had started the same way did hang the whole PC right after 8x was picked, with nothing in Windows' logs; we could not reproduce that, so we do not claim this is its cause.

The game's log has no malloc_trim line on Windows. In the source the trim after translation is inside #if defined(__linux__) && defined(__GLIBC__) (the vk: memory: block in vk_texture.cpp), and its comment describes this growth ("the heap's growth ... never going back"). Closing the game after the build and starting it again gives the first row of each table.

What we tried as a Windows counterpart, in a local build: once, after precompile_run of a start whose prepare_run ran, _heapmin(), HeapCompact on the process heap, then SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1). One run: working set 13,675 -> 6 MB at that moment, private 18,730 -> 18,724 MB (the heap calls gave back next to nothing, as expected of a fragmented heap); in play the working set settled at 9,273 MB, the PC kept 9.1 GB or more free, and fps and the slowest-frame lines were the same as without it (median of the run's fps lines 46.2 against 45.8; slowest frame per 600 after the load 26.4 to 64.9 ms against 26.5 to 63.2 ms). The private bytes stay (30.7 GB): what the build left is in the page file now, not in RAM.

Is that worth having upstream, or is "restart once after the shader build" the intended answer on 32 GB? Happy to send the few lines if useful.

A separate memory factor on Windows, found while chasing a whole-PC hang: the start that builds the shader programs keeps much more RAM than a start that finds them, and keeps it in play. Same PC (RX 9070 XT 16 GB, 32 GB RAM, Windows 11), v2.1.0 built from source with a few local changes (none of them in the shader build or the heap), same save, same spot. At the title screen (one run each): | start | working set | private | free RAM on the PC | |---|---|---|---| | programs kept (`46604 program keys kept`) | 14,767 MB | 20,818 MB | 6 GB or more | | programs built (`0 program keys kept`, then `prepared 38809 shader programs (46597 new, 70 failed ...)`) | 16,235 MB rising to 20,225 MB | 23,453 MB | 3,039 MB, then 1,340 MB (our guard ended that run there, before play) | In play, standing at the same spot (last `vk: memory:` line of each run; the kept runs are shorter, the built runs stood there 2.5 to 7 minutes): | start | working set | private | lowest free RAM on the PC | |---|---|---|---| | programs kept (3 runs, frame generation on) | 17,308 to 17,391 MB | 28,505 to 28,647 MB | 5,930 to 6,079 MB | | programs built in this process, frame generation off | 22,042 MB | 30,656 MB | 958 MB | | programs built in this process, then Ultra preset and 8x frame generation from the menu | 21,993 MB | 31,854 MB | 1,151 MB | | programs built in this process, working set emptied once after the build (see below) | 9,273 MB | 30,714 MB | 9,146 MB | So the process that built the programs holds about 4.7 GB more of the PC's RAM in play, and a 32 GB PC is left with about 1 GB free. Neither of those runs hung. An earlier session that had started the same way did hang the whole PC right after 8x was picked, with nothing in Windows' logs; we could not reproduce that, so we do not claim this is its cause. The game's log has no `malloc_trim` line on Windows. In the source the trim after translation is inside `#if defined(__linux__) && defined(__GLIBC__)` (the `vk: memory:` block in vk_texture.cpp), and its comment describes this growth ("the heap's growth ... never going back"). Closing the game after the build and starting it again gives the first row of each table. What we tried as a Windows counterpart, in a local build: once, after `precompile_run` of a start whose `prepare_run` ran, `_heapmin()`, `HeapCompact` on the process heap, then `SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1)`. One run: working set 13,675 -> 6 MB at that moment, private 18,730 -> 18,724 MB (the heap calls gave back next to nothing, as expected of a fragmented heap); in play the working set settled at 9,273 MB, the PC kept 9.1 GB or more free, and fps and the slowest-frame lines were the same as without it (median of the run's fps lines 46.2 against 45.8; slowest frame per 600 after the load 26.4 to 64.9 ms against 26.5 to 63.2 ms). The private bytes stay (30.7 GB): what the build left is in the page file now, not in RAM. Is that worth having upstream, or is "restart once after the shader build" the intended answer on 32 GB? Happy to send the few lines if useful.
bunbeans2-arch commented 2026-11-11 16:59:58 +00:00 (Migrated from github.com)

Follow-up to the comment above on the start that builds the shader programs. Two more measurements, same PC (RX 9070 XT 16 GB, 32 GB RAM, Windows 11, commit limit 56,240 MB), same local v2.1.0 build, frame generation off unless said.

1. Emptying the working set fixes the RAM, not the commit.
A save next to an area boundary, then walking across it and back in a loop (input script):

start private before the walk private after the first crossing lowest commit room left on the PC result
programs kept, 2x frame generation 27,227 MB 32,790 MB 7,425 MB 19 crossings in 240 s, private flat at 31.9 to 33.3 GB
programs built in this process + working set emptied (2 runs) 29,887 and 29,772 MB 33,597 and 34,815 MB, still rising 5,630 and 5,653 MB our harness ended both runs at its 6 GB safety line, 7 to 8 s into the walk

So a crossing costs about 5 GB of private bytes in either process (textures went 3,081 -> 6,046 MB in the same seconds; no VRAM full line; free RAM stayed above 7.8 GB in the built runs). The process that built the programs simply goes in about 2.5 GB higher, and on this PC that is the difference between 7.4 GB and under 6 GB of commit room. We did not let it run on, so how low it goes is not measured.

2. "Restart once after the build", done by the game itself.
Tried in the local build: when prepare_run built the programs in this start (2,000 or more), then after precompile_run the process saves the pipeline cache, starts its own command line again and ends. It sets HOS_RESTART_OF the way the host's own restart (hos_relaunch.c) does, so the first log is kept as hookshot_log.1.txt. An environment mark stops the new process from doing it twice.

One run, same save and walk as above:

  • first process: 0 program keys kept, prepared 38809 shader programs (46597 new, 70 failed ...) in 145.4 s, ended by itself 175 s after the start
  • second process: 46604 program keys kept, precompile: 8390 programs, 10829 graphics and 933 compute pipelines ... in 5677 ms, start-up: the shaders took 6.1 s
  • the walk: 25 crossings in 300 s, no stop; private 27,079 MB before the walk, 33,801 MB at most; lowest commit room 6,649 MB; lowest free RAM 3,796 MB

Those are the numbers of a start that found its programs (first row of the table). Cost: the start-up screen is shown twice on the one start that builds.

Not claimed: one run only; and none of this is shown to be the cause of the whole-PC hang this issue started with, which we still have not reproduced.

Happy to describe either change in more detail, or send the lines, if that is useful.

Follow-up to the comment above on the start that builds the shader programs. Two more measurements, same PC (RX 9070 XT 16 GB, 32 GB RAM, Windows 11, commit limit 56,240 MB), same local v2.1.0 build, frame generation off unless said. **1. Emptying the working set fixes the RAM, not the commit.** A save next to an area boundary, then walking across it and back in a loop (input script): | start | private before the walk | private after the first crossing | lowest commit room left on the PC | result | |---|---|---|---|---| | programs kept, 2x frame generation | 27,227 MB | 32,790 MB | 7,425 MB | 19 crossings in 240 s, private flat at 31.9 to 33.3 GB | | programs built in this process + working set emptied (2 runs) | 29,887 and 29,772 MB | 33,597 and 34,815 MB, still rising | 5,630 and 5,653 MB | our harness ended both runs at its 6 GB safety line, 7 to 8 s into the walk | So a crossing costs about 5 GB of private bytes in either process (textures went 3,081 -> 6,046 MB in the same seconds; no `VRAM full` line; free RAM stayed above 7.8 GB in the built runs). The process that built the programs simply goes in about 2.5 GB higher, and on this PC that is the difference between 7.4 GB and under 6 GB of commit room. We did not let it run on, so how low it goes is not measured. **2. "Restart once after the build", done by the game itself.** Tried in the local build: when `prepare_run` built the programs in this start (2,000 or more), then after `precompile_run` the process saves the pipeline cache, starts its own command line again and ends. It sets `HOS_RESTART_OF` the way the host's own restart (hos_relaunch.c) does, so the first log is kept as `hookshot_log.1.txt`. An environment mark stops the new process from doing it twice. One run, same save and walk as above: - first process: `0 program keys kept`, `prepared 38809 shader programs (46597 new, 70 failed ...) in 145.4 s`, ended by itself 175 s after the start - second process: `46604 program keys kept`, `precompile: 8390 programs, 10829 graphics and 933 compute pipelines ... in 5677 ms`, `start-up: the shaders took 6.1 s` - the walk: 25 crossings in 300 s, no stop; private 27,079 MB before the walk, 33,801 MB at most; lowest commit room 6,649 MB; lowest free RAM 3,796 MB Those are the numbers of a start that found its programs (first row of the table). Cost: the start-up screen is shown twice on the one start that builds. Not claimed: one run only; and none of this is shown to be the cause of the whole-PC hang this issue started with, which we still have not reproduced. Happy to describe either change in more detail, or send the lines, if that is useful.
bunbeans2-arch commented 2026-11-11 19:13:00 +00:00 (Migrated from github.com)

The room where the freeze of this issue happened now reproduces the memory side of it on demand, and the log says what the jump is made of. Same PC as above (RX 9070 XT 16 GB, 32 GB RAM, Windows 11), v2.1.0 built from source, 3840x2160, Frame generation Auto, default texture budget (6144 MB), all runs under a safety stop.

Where. Castle Town, the small guard room behind a door near the town gate (one guard, a wall torch, about 15 pots, crates). The player was in this room when the picture froze.

What happens (4 of 4 runs at these settings). Walking in through the door, and in the first run again while moving through the room, the game's video memory (Windows' per-process counter, read once a second) goes up by 1.9 to 2.7 GB within one second:

run peak, game / whole adapter (MB) how it ended
1 14,511 / 15,070 our stop, at "the shadows given back"
2 14,612 / 15,178 our stop at 97.6 % of the allowance, at the door, before any pot
3 14,832 / 15,324 our stop on free commit
4 14,801 / 15,217 our stop, at "the shadows given back"

Outside the room the same stick movements make no jump. Breaking pots is not needed for it; the door is enough.

What the jump is made of (run 2, the vk: VRAM: block before the door against the block at the peak):

before the door at the peak
render-target images 179, 827 MB, in 2,176 MB of blocks 1,465, 5,834 MB, in 6,528 MB of blocks
cache, rendered textures 1,148 MB 4,341 MB
target pool holds 13 (40 MB) holds 696 (1,505 MB), bound 256 MB
"drawn in one frame, kept" 45 420
decoded ASTC 1,755 MB 1,273 MB

Pool counters over that stretch: made new +4,858, reused +4,681, destroyed +3,572; 9,505 textures retired. The eight biggest textures are the same before and after, so nothing big is new: it is about 1,300 mid-size targets. The -> vk lines in that stretch are mostly depth targets (NVN 0x34) at 384x384 and at square sizes whose side changes from frame to frame (404 ... 1515), next to the usual 3840x2160 / 1920x1080 / 960x540 ones. A walk across the drawbridge and market (frame generation 2x, same budget) has none of the 0x34 depth-target lines.

The log of the session that froze (first post) ends with the same picture, about twice as large: 18,719 textures retired in its last 269 lines, 43.9 textures made a frame, the pool at 802 MB, then VRAM 14706 of 14706 MB: the shadows given back.

Why they pile up, as far as I can read vk_texture.cpp.

  1. The retire pass in texture_frame sits behind if (frame_no % 10) return;. A frame's scratch targets are dead after 3 unused frames, but then wait up to 9 more presents for the pass. With 23 to 44 textures made a frame (the frozen session's last blocks) that is several hundred images. (RX_VK_DEAD_EVERY below 10 has no effect because of that line.)
  2. pool_trim destroys at most 16 images a present (64 only above 90 % of the allowance), so a pool at almost six times its bound drains slowly.
  3. The pool hands an image only to a target of exactly the same size and format, and the squares change size every frame, so they never match.

What helped here (local experiment: one build, same route, one run switched off and two switched on). While a regular pass finds that the last ten presents let 64 or more shifted targets go, or made 64 or more target images new, run the dead-target sweep on the presents in between as well (sweep only: targets another has drawn over, never a live texture, no budget cut), and let pool_trim take 64 a present while the pool holds more than twice its bound.

switched off switched on, run 1 switched on, run 2
peak, game / adapter (MB) 14,801 / 15,217 12,615 / 13,032 12,584 / 13,008
private bytes, max (MB) 33,425 30,895 31,551
"the shadows given back" lines 1 0 0

The switched-on runs stayed in the room for about 5 and about 9 minutes with pots picked up and thrown, camera turns and sword swings (the switched-off run was stopped 3 seconds after the door); in play neither has a gap of 100 ms or more between presents (biggest 66 and 81 ms). On the walk across the drawbridge and market the same build shows no cost against the build before it: gaps of 100 ms or more 58 against 58, slow submit lines 73 against 73, mean 46.9 against 46.7 fps. It also changes nothing at that walk's peak (13,787 against 13,844 MB), which is not made of dead targets.

A smaller texture budget also holds the room (RX_VK_VRAM_MB=4096: peak 13,630 / 13,956 MB, one run), but the cache still overshoots it by up to 1.4 GB between two passes there.

Not shown. The stopped picture itself has not come back in this room on our current build: our stop ended the first four runs before it could. Two runs with the change are two runs. One of the three starts with the change (the two room runs and the walk) had a quiet spell right after the save load, before play (0.7 fps over 12.9 s, the game read no controller for 14 s; about 6 s of that was our own tool writing a dump). The dump shows the submitting thread inside the driver under submit_recording and no thread in vk_texture.cpp. The other two starts with the change loaded clean, and so did the four without it that I checked. Not understood. I have not found why this room makes the changing square targets (a guess: one small shadow map per object under the torch, sized by its size on screen).

A side note on the pots. In one run, while pots were thrown and seeds shot in that room, two compute pipelines compiled in play (0.35 s and 3.4 s, on a worker, the dispatch left out meanwhile, so the picture went on); an earlier run with pots thrown had none, so what brings them is not pinned down. The frozen session's log has five (up to 26.9 s, also on a worker). The keys are added to the list of dispatched compute programs and built at the next start, so each costs once. The note in the source expects such a first dispatch to take milliseconds from the caches; here it did not, and I do not know why the caches were cold for them.

Happy to share the diff (one file, vk_texture.cpp, two environment switches to turn it off) if it is of use.

The room where the freeze of this issue happened now reproduces the memory side of it on demand, and the log says what the jump is made of. Same PC as above (RX 9070 XT 16 GB, 32 GB RAM, Windows 11), v2.1.0 built from source, 3840x2160, Frame generation Auto, default texture budget (6144 MB), all runs under a safety stop. **Where.** Castle Town, the small guard room behind a door near the town gate (one guard, a wall torch, about 15 pots, crates). The player was in this room when the picture froze. **What happens (4 of 4 runs at these settings).** Walking in through the door, and in the first run again while moving through the room, the game's video memory (Windows' per-process counter, read once a second) goes up by 1.9 to 2.7 GB within one second: | run | peak, game / whole adapter (MB) | how it ended | |---|---|---| | 1 | 14,511 / 15,070 | our stop, at "the shadows given back" | | 2 | 14,612 / 15,178 | our stop at 97.6 % of the allowance, at the door, before any pot | | 3 | 14,832 / 15,324 | our stop on free commit | | 4 | 14,801 / 15,217 | our stop, at "the shadows given back" | Outside the room the same stick movements make no jump. Breaking pots is not needed for it; the door is enough. **What the jump is made of** (run 2, the `vk: VRAM:` block before the door against the block at the peak): | | before the door | at the peak | |---|---|---| | render-target images | 179, 827 MB, in 2,176 MB of blocks | 1,465, 5,834 MB, in 6,528 MB of blocks | | cache, rendered textures | 1,148 MB | 4,341 MB | | target pool | holds 13 (40 MB) | holds 696 (1,505 MB), bound 256 MB | | "drawn in one frame, kept" | 45 | 420 | | decoded ASTC | 1,755 MB | 1,273 MB | Pool counters over that stretch: made new +4,858, reused +4,681, destroyed +3,572; 9,505 textures retired. The eight biggest textures are the same before and after, so nothing big is new: it is about 1,300 mid-size targets. The `-> vk` lines in that stretch are mostly depth targets (NVN 0x34) at 384x384 and at square sizes whose side changes from frame to frame (404 ... 1515), next to the usual 3840x2160 / 1920x1080 / 960x540 ones. A walk across the drawbridge and market (frame generation 2x, same budget) has none of the 0x34 depth-target lines. The log of the session that froze (first post) ends with the same picture, about twice as large: 18,719 textures retired in its last 269 lines, 43.9 textures made a frame, the pool at 802 MB, then `VRAM 14706 of 14706 MB: the shadows given back`. **Why they pile up, as far as I can read `vk_texture.cpp`.** 1. The retire pass in `texture_frame` sits behind `if (frame_no % 10) return;`. A frame's scratch targets are dead after 3 unused frames, but then wait up to 9 more presents for the pass. With 23 to 44 textures made a frame (the frozen session's last blocks) that is several hundred images. (`RX_VK_DEAD_EVERY` below 10 has no effect because of that line.) 2. `pool_trim` destroys at most 16 images a present (64 only above 90 % of the allowance), so a pool at almost six times its bound drains slowly. 3. The pool hands an image only to a target of exactly the same size and format, and the squares change size every frame, so they never match. **What helped here (local experiment: one build, same route, one run switched off and two switched on).** While a regular pass finds that the last ten presents let 64 or more shifted targets go, or made 64 or more target images new, run the dead-target sweep on the presents in between as well (sweep only: targets another has drawn over, never a live texture, no budget cut), and let `pool_trim` take 64 a present while the pool holds more than twice its bound. | | switched off | switched on, run 1 | switched on, run 2 | |---|---|---|---| | peak, game / adapter (MB) | 14,801 / 15,217 | 12,615 / 13,032 | 12,584 / 13,008 | | private bytes, max (MB) | 33,425 | 30,895 | 31,551 | | "the shadows given back" lines | 1 | 0 | 0 | The switched-on runs stayed in the room for about 5 and about 9 minutes with pots picked up and thrown, camera turns and sword swings (the switched-off run was stopped 3 seconds after the door); in play neither has a gap of 100 ms or more between presents (biggest 66 and 81 ms). On the walk across the drawbridge and market the same build shows no cost against the build before it: gaps of 100 ms or more 58 against 58, `slow submit` lines 73 against 73, mean 46.9 against 46.7 fps. It also changes nothing at that walk's peak (13,787 against 13,844 MB), which is not made of dead targets. A smaller texture budget also holds the room (`RX_VK_VRAM_MB=4096`: peak 13,630 / 13,956 MB, one run), but the cache still overshoots it by up to 1.4 GB between two passes there. **Not shown.** The stopped picture itself has not come back in this room on our current build: our stop ended the first four runs before it could. Two runs with the change are two runs. One of the three starts with the change (the two room runs and the walk) had a quiet spell right after the save load, before play (0.7 fps over 12.9 s, the game read no controller for 14 s; about 6 s of that was our own tool writing a dump). The dump shows the submitting thread inside the driver under `submit_recording` and no thread in `vk_texture.cpp`. The other two starts with the change loaded clean, and so did the four without it that I checked. Not understood. I have not found why this room makes the changing square targets (a guess: one small shadow map per object under the torch, sized by its size on screen). **A side note on the pots.** In one run, while pots were thrown and seeds shot in that room, two compute pipelines compiled in play (0.35 s and 3.4 s, on a worker, the dispatch left out meanwhile, so the picture went on); an earlier run with pots thrown had none, so what brings them is not pinned down. The frozen session's log has five (up to 26.9 s, also on a worker). The keys are added to the list of dispatched compute programs and built at the next start, so each costs once. The note in the source expects such a first dispatch to take milliseconds from the caches; here it did not, and I do not know why the caches were cold for them. Happy to share the diff (one file, `vk_texture.cpp`, two environment switches to turn it off) if it is of use.
bunbeans2-arch commented 2026-11-11 20:09:03 +00:00 (Migrated from github.com)

Follow-up to my comment above: one correction and two more runs (same PC, same settings, same room).

Correction: a smaller texture budget does not reliably hold the room. I wrote that RX_VK_VRAM_MB=4096 holds it (13,630 / 13,956 MB, one run). A second run at 4096, without the change, peaked at 14,511 / 14,930 MB while walking through the room after the door. That is as high as the runs at the default budget (14,511 to 14,832 MB). So please do not read the 4096 line above as a workaround.

The change, third run, this time with the sword. The player tells me he was breaking the pots with the sword when the picture froze, so this run did only that on a fresh room (27 strings of sword swings). Peak 12,442 / 12,861 MB, reached at the entry; 12,084 MB during the sword part. Over three runs with the change: 12,615, 12,584 and 12,442 MB, against 14,511 to 14,832 MB over the four runs without it at the same budget. One-second rises still happen with the change (+2,178 MB at the entry in this run); what changes is where they top out. In play this run has two gaps of 100 ms or more between presents (234 and 143 ms) and none of 1 s; the save load was clean.

Compute pipelines and the sword. About a minute into the sword part (between 53 and 62 s after the first swing, after six strings of swings), four compute pipelines compiled in play within about 3 seconds: 234, 335, 285 and 3,375 ms, all on a worker, with 35 dispatch ... left out lines. The 234 ms gap between presents is at that moment. The run after it, same route, compiled none: the keys had been added to the list of dispatched compute programs. The same holds for the keys of the frozen session: its five are in that list on this install since that night, so no run of ours since has met them cold. The night of the freeze was the first evening on v2.1.0 here, with those compiles still to come in play.

Still not shown: the stopped picture itself.

Follow-up to my comment above: one correction and two more runs (same PC, same settings, same room). **Correction: a smaller texture budget does not reliably hold the room.** I wrote that `RX_VK_VRAM_MB=4096` holds it (13,630 / 13,956 MB, one run). A second run at 4096, without the change, peaked at 14,511 / 14,930 MB while walking through the room after the door. That is as high as the runs at the default budget (14,511 to 14,832 MB). So please do not read the 4096 line above as a workaround. **The change, third run, this time with the sword.** The player tells me he was breaking the pots with the sword when the picture froze, so this run did only that on a fresh room (27 strings of sword swings). Peak 12,442 / 12,861 MB, reached at the entry; 12,084 MB during the sword part. Over three runs with the change: 12,615, 12,584 and 12,442 MB, against 14,511 to 14,832 MB over the four runs without it at the same budget. One-second rises still happen with the change (+2,178 MB at the entry in this run); what changes is where they top out. In play this run has two gaps of 100 ms or more between presents (234 and 143 ms) and none of 1 s; the save load was clean. **Compute pipelines and the sword.** About a minute into the sword part (between 53 and 62 s after the first swing, after six strings of swings), four compute pipelines compiled in play within about 3 seconds: 234, 335, 285 and 3,375 ms, all on a worker, with 35 `dispatch ... left out` lines. The 234 ms gap between presents is at that moment. The run after it, same route, compiled none: the keys had been added to the list of dispatched compute programs. The same holds for the keys of the frozen session: its five are in that list on this install since that night, so no run of ours since has met them cold. The night of the freeze was the first evening on v2.1.0 here, with those compiles still to come in play. Still not shown: the stopped picture itself.
NotRexed commented 2026-11-11 21:26:05 +00:00 (Migrated from github.com)

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

Thanks for the report. Reports of the same problem are now collected in #993, which lists this one with your details and links back here, so one fix closes them together and the open list stays readable. Follow #993 for the fix, and add new details there (or here). If this turns out to be a separate problem it will be reopened. Pull request #2484 works on this.
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#2180
No description provided.