Linux AMD (RADV): grass and small plants flicker in and out; pools over udmabuf's 64 MB limit are not imported #2239

Closed
opened 2026-11-11 10:26:20 +00:00 by davkdavk · 5 comments
davkdavk commented 2026-11-11 10:26:20 +00:00 (Migrated from github.com)

Hookshot version

v2.1.0 (source e561602e)

What kind of problem

Graphics (missing, black or wrong-coloured things, lighting, flicker)

What happened

Grass and small ground plants flicker in and out a few times a second, all at once. Fine on NVIDIA.

The log shows pools over 64 MB failing to import, and the foliage culling's storage buffers unbound:

vk: dma-bufs of at most 64 MB (udmabuf's limit 64 MB); larger pools are host-pointer imports (no sparse binding)
vk: pool 0x108b338000+0x9596000 not imported (VkResult -13)
vk: storage buffer NOT bound (reads zeros): program 3e6fe279463b020e stage 5 c0+0xa0 addr 0x117ee4d000 size 0x232c00 (written)

Work-around that fixed it here (game closed, then restart):

echo 2048 | sudo tee /sys/module/udmabuf/parameters/size_limit_mb

Likely cause: in gpu/vk/vk_main.cpp, dev.sparse_buffers only checks the replay's queue family for VK_QUEUE_SPARSE_BINDING_BIT. RADV keeps sparse binding on a queue family of its own, so the sparse dma-buf path in import_dma_buf_pieces is never used, and the host-pointer fallback cannot import the memfd window's shared pages. Suggested fix: when the replay's family has no sparse bit, create a queue from a family that does and call vkQueueBindSparse on it; and when a pool still cannot be imported, log the work-around above.

Related: the reporter of #1903 (Radeon 780M, RADV) had already raised size_limit_mb to 16384 by hand, which is why they did not see this.

RX_VK_BATCH=0, RX_VK_WAIT_GPU=1 and RX_VK_MESH_OPT=1 made no difference.

Full log (and patch, if present): https://gist.github.com/davkdavk/6b205d42ee5cc04397e15448306f65c9

A proposed patch is in the gist. It was written with Claude and is NOT built or tested; it needs a run on RADV with the default 64 MB limit.

Where in the game

Kokiri Forest, standing still or walking.

How often

Every time

Graphics card and driver version

AMD Radeon RX 7800 XT, RADV NAVI32, Mesa 25.0.7

CPU, RAM and operating system

32 GB RAM, Debian 13

Changes from the defaults

hookshot_env.txt: RX_VK_WAIT_GPU=1 (no effect on this either way)

Other software hooked into the game

No, nothing hooked in

### Hookshot version v2.1.0 (source e561602e) ### What kind of problem Graphics (missing, black or wrong-coloured things, lighting, flicker) ### What happened Grass and small ground plants flicker in and out a few times a second, all at once. Fine on NVIDIA. The log shows pools over 64 MB failing to import, and the foliage culling's storage buffers unbound: ``` vk: dma-bufs of at most 64 MB (udmabuf's limit 64 MB); larger pools are host-pointer imports (no sparse binding) vk: pool 0x108b338000+0x9596000 not imported (VkResult -13) vk: storage buffer NOT bound (reads zeros): program 3e6fe279463b020e stage 5 c0+0xa0 addr 0x117ee4d000 size 0x232c00 (written) ``` Work-around that fixed it here (game closed, then restart): ``` echo 2048 | sudo tee /sys/module/udmabuf/parameters/size_limit_mb ``` Likely cause: in gpu/vk/vk_main.cpp, `dev.sparse_buffers` only checks the replay's queue family for `VK_QUEUE_SPARSE_BINDING_BIT`. RADV keeps sparse binding on a queue family of its own, so the sparse dma-buf path in `import_dma_buf_pieces` is never used, and the host-pointer fallback cannot import the memfd window's shared pages. Suggested fix: when the replay's family has no sparse bit, create a queue from a family that does and call `vkQueueBindSparse` on it; and when a pool still cannot be imported, log the work-around above. Related: the reporter of #1903 (Radeon 780M, RADV) had already raised size_limit_mb to 16384 by hand, which is why they did not see this. `RX_VK_BATCH=0`, `RX_VK_WAIT_GPU=1` and `RX_VK_MESH_OPT=1` made no difference. Full log (and patch, if present): https://gist.github.com/davkdavk/6b205d42ee5cc04397e15448306f65c9 A proposed patch is in the gist. It was written with Claude and is NOT built or tested; it needs a run on RADV with the default 64 MB limit. ### Where in the game Kokiri Forest, standing still or walking. ### How often Every time ### Graphics card and driver version AMD Radeon RX 7800 XT, RADV NAVI32, Mesa 25.0.7 ### CPU, RAM and operating system 32 GB RAM, Debian 13 ### Changes from the defaults `hookshot_env.txt`: `RX_VK_WAIT_GPU=1` (no effect on this either way) ### Other software hooked into the game No, nothing hooked in
Arkex-ai commented 2026-11-11 12:39:47 +00:00 (Migrated from github.com)

I can help turn the sparse-buffer queue proposal into a built and tested contribution. Are you already preparing a PR? If not, is it OK to reuse your patch under the project's license with attribution, then add executed queue-selection/lifetime tests and the platform builds?

I'd keep this to buffer imports: preserve the existing sparse-image policy, handle replay/present/sparse queue-family aliases without duplicate device requests, and verify queue locking plus the bind-completion fence. I can test Windows/NVIDIA and authored Linux fixtures; the default-limit RADV gameplay case would still need your machine. Would you be available to check that candidate?

I can help turn the sparse-buffer queue proposal into a built and tested contribution. Are you already preparing a PR? If not, is it OK to reuse your patch under the project's license with attribution, then add executed queue-selection/lifetime tests and the platform builds? I'd keep this to buffer imports: preserve the existing sparse-image policy, handle replay/present/sparse queue-family aliases without duplicate device requests, and verify queue locking plus the bind-completion fence. I can test Windows/NVIDIA and authored Linux fixtures; the default-limit RADV gameplay case would still need your machine. Would you be available to check that candidate?
Fortich commented 2026-11-11 19:59:35 +00:00 (Migrated from github.com)

The sparse-queue patch fixes it on an RX 6800 XT (RADV NAVI21), with udmabuf still at its 64 MB default

I took your hookshot-radv-sparse-queue-plant-flicker.patch to a machine with the same symptom and
ran both sides of it on the same GPU, same spot (Kokiri Forest, standing still), same switches. The
only difference between the two runs is the patch.

How the two runs differ. Both are main v2.0.11-871-g9447e1d with RX_VK_FORCE_MESH_FALLBACK=1
(needed on this card for #2245) and RX_VK_CHECKPOINTS=1. The first build has no patch; the second
has yours. udmabuf's size_limit_mb stayed at 64 MB in both — no sysctl change — so the limit
the report points at was in force for both.

Without the patch (log attached as hookshot_log-before-flicker-extracto.txt, cut from a 989 MB
container dump so only the symptom's lines travel):

vk: dma-bufs of at most 64 MB (udmabuf's limit 64 MB); larger pools are host-pointer imports (no sparse binding)
pool 0x108c6e8000+0x4acb000 not imported (VkResult -13)
pool 0x117b40b000+0xf33080 not imported (VkResult -13)
storage buffer NOT bound (reads zeros): program 7650519f88e59b19 stage 5 c0+0x70 addr 0x117ffa1000 size 0x232c00 (written)
storage buffer NOT bound (reads zeros): program 22063ecfa481a731 stage 7 c0+0x770 addr 0x117b40b000 size 0xf33080

Eight distinct pools failed to import over that session, and twelve distinct storage buffers were
reported unbound; two of each are above. On screen: grass and small ground plants flickering in and
out a few times a second, exactly as reported.

With the patch (log attached as hookshot_log-after.txt, the whole session):

vk: sparse buffers are bound on a queue of family 4 (the replay's family 0 binds no sparse memory)
vk: dma-bufs of at most 64 MB (udmabuf's limit 64 MB); larger pools are several, in a sparse buffer
pool ... not imported: 0
storage buffer NOT bound: 40

The 40 are all the same line, program da7a7ab28b8e73d9 stage 1 c5+0 addr 0x4180000000000200 size 0x20, and it also shows up in runs without the patch — a separate single case, not the pools. The
pools over the limit now go in as several dma-bufs, and the flicker is gone at the same spot.

Nothing else moved. No device lost and no GPU reset in the session; 72 frame-rate reports. In a
dense Kokiri Forest scene it held 37–43 fps with GPU time at 9.6 ms a frame, so the patch costs
nothing measurable here.

On the patch itself. tests/test_sparse_queue.py passes, and so does the rest of the
repository's Python suite. I built inside the image that runs the game (glibc 2.41) so the binary
matches its container, and the warning you added for a pool that still cannot be imported never
fires in this run, as expected. RX_VK_SPARSE_QUEUE=0 reproduces the old behaviour exactly, which is
how the two runs were made comparable.

This also answers @Arkex-ai above: the patch is built, run and measured on RADV now, so a PR can
carry it with the evidence instead of a proposal.

Before

https://github.com/user-attachments/assets/6bc40322-9738-4e2d-85a9-9fb112766264

After

https://github.com/user-attachments/assets/d831a142-a528-4762-851f-d7e1cb738668

Files attached

**The sparse-queue patch fixes it on an RX 6800 XT (RADV NAVI21), with udmabuf still at its 64 MB default** I took your [hookshot-radv-sparse-queue-plant-flicker.patch](https://gist.github.com/davkdavk/6b205d42ee5cc04397e15448306f65c9) to a machine with the same symptom and ran both sides of it on the same GPU, same spot (Kokiri Forest, standing still), same switches. The only difference between the two runs is the patch. **How the two runs differ.** Both are `main` v2.0.11-871-g9447e1d with `RX_VK_FORCE_MESH_FALLBACK=1` (needed on this card for #2245) and `RX_VK_CHECKPOINTS=1`. The first build has no patch; the second has yours. udmabuf's `size_limit_mb` stayed at **64 MB** in both — no sysctl change — so the limit the report points at was in force for both. **Without the patch** (log attached as [hookshot_log-before-flicker-extracto.txt](https://github.com/user-attachments/files/34703156/hookshot_log-before-flicker-extracto.txt), cut from a 989 MB container dump so only the symptom's lines travel): ``` vk: dma-bufs of at most 64 MB (udmabuf's limit 64 MB); larger pools are host-pointer imports (no sparse binding) pool 0x108c6e8000+0x4acb000 not imported (VkResult -13) pool 0x117b40b000+0xf33080 not imported (VkResult -13) storage buffer NOT bound (reads zeros): program 7650519f88e59b19 stage 5 c0+0x70 addr 0x117ffa1000 size 0x232c00 (written) storage buffer NOT bound (reads zeros): program 22063ecfa481a731 stage 7 c0+0x770 addr 0x117b40b000 size 0xf33080 ``` Eight distinct pools failed to import over that session, and twelve distinct storage buffers were reported unbound; two of each are above. On screen: grass and small ground plants flickering in and out a few times a second, exactly as reported. **With the patch** (log attached as [hookshot_log-after.txt](https://github.com/user-attachments/files/34703194/hookshot_log-after.txt), the whole session): ``` vk: sparse buffers are bound on a queue of family 4 (the replay's family 0 binds no sparse memory) vk: dma-bufs of at most 64 MB (udmabuf's limit 64 MB); larger pools are several, in a sparse buffer pool ... not imported: 0 storage buffer NOT bound: 40 ``` The 40 are all the same line, `program da7a7ab28b8e73d9 stage 1 c5+0 addr 0x4180000000000200 size 0x20`, and it also shows up in runs without the patch — a separate single case, not the pools. The pools over the limit now go in as several dma-bufs, and the flicker is gone at the same spot. **Nothing else moved.** No device lost and no GPU reset in the session; 72 frame-rate reports. In a dense Kokiri Forest scene it held 37–43 fps with GPU time at 9.6 ms a frame, so the patch costs nothing measurable here. **On the patch itself.** `tests/test_sparse_queue.py` passes, and so does the rest of the repository's Python suite. I built inside the image that runs the game (glibc 2.41) so the binary matches its container, and the warning you added for a pool that still cannot be imported never fires in this run, as expected. `RX_VK_SPARSE_QUEUE=0` reproduces the old behaviour exactly, which is how the two runs were made comparable. This also answers @Arkex-ai above: the patch is built, run and measured on RADV now, so a PR can carry it with the evidence instead of a proposal. Before https://github.com/user-attachments/assets/6bc40322-9738-4e2d-85a9-9fb112766264 After https://github.com/user-attachments/assets/d831a142-a528-4762-851f-d7e1cb738668 **Files attached** - [hookshot_log-before-flicker-extracto.txt](https://github.com/user-attachments/files/34703156/hookshot_log-before-flicker-extracto.txt) — the lines quoted above, from the run without the patch (cut out of a 989 MB container dump, so only the symptom travels). - [hookshot_log-after.txt](https://github.com/user-attachments/files/34703194/hookshot_log-after.txt) — the whole session on the patched build (~5,800 lines). - [before-sparse-queue-0.mp4](https://github.com/user-attachments/assets/6bc40322-9738-4e2d-85a9-9fb112766264) — 8 s at the spot, run with `RX_VK_SPARSE_QUEUE=0`. - [after-default.mp4](https://github.com/user-attachments/assets/d831a142-a528-4762-851f-d7e1cb738668) — 8 s at the same area, default build.
NotRexed commented 2026-11-11 21:27:36 +00:00 (Migrated from github.com)

Thanks for the report. Reports of the same problem are now collected in #1000, which lists this one with your details and links back here, so one fix closes them together and the open list stays readable. Follow #1000 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 #1000, which lists this one with your details and links back here, so one fix closes them together and the open list stays readable. Follow #1000 for the fix, and add new details there (or here). If this turns out to be a separate problem it will be reopened.
davkdavk commented 2026-11-11 23:03:26 +00:00 (Migrated from github.com)

A temporary workaround on Linux is running the following before launching
Hookshot.

echo 2048 | sudo tee /sys/module/udmabuf/parameters/size_limit_mb

On Thu, Nov 12, 2026 at 7:57 AM NotRexed @.***> wrote:

Closed #2239 https://git.magicbean.dev/MagicBeanDev/Hookshot/issues/2239 as
duplicate.

—
Reply to this email directly, view it on GitHub
https://git.magicbean.dev/MagicBeanDev/Hookshot/issues/2239?email_source=notifications&email_token=BVLH7STCWOBUSQFRV2EMD635YTKV5A5CNFSNUABQM5UWIORPF5TWS5BNNB2WEL2JONZXKZKFOZSW45CON52GSZTJMNQXI2LPNYXTGNJYGQ2DQNJWHEZDPJTSMVQXG33OUZQXK5DIN5ZKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#event-35844856927,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/BVLH7SVCOBL5KY6PTXI6J335YTKV5AVCNFSNUABGKJSXA33TNF2G64TZHMYTINBWHE3DENJSGA5US43TOVSTWNRTGI3DINJUG44TRILWAI
.
You are receiving this because you authored the thread.Message ID:
@.***>

A temporary workaround on Linux is running the following before launching Hookshot. echo 2048 | sudo tee /sys/module/udmabuf/parameters/size_limit_mb On Thu, Nov 12, 2026 at 7:57 AM NotRexed ***@***.***> wrote: > Closed #2239 <https://git.magicbean.dev/MagicBeanDev/Hookshot/issues/2239> as > duplicate. > > — > Reply to this email directly, view it on GitHub > <https://git.magicbean.dev/MagicBeanDev/Hookshot/issues/2239?email_source=notifications&email_token=BVLH7STCWOBUSQFRV2EMD635YTKV5A5CNFSNUABQM5UWIORPF5TWS5BNNB2WEL2JONZXKZKFOZSW45CON52GSZTJMNQXI2LPNYXTGNJYGQ2DQNJWHEZDPJTSMVQXG33OUZQXK5DIN5ZKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#event-35844856927>, > or unsubscribe > <https://github.com/notifications/unsubscribe-auth/BVLH7SVCOBL5KY6PTXI6J335YTKV5AVCNFSNUABGKJSXA33TNF2G64TZHMYTINBWHE3DENJSGA5US43TOVSTWNRTGI3DINJUG44TRILWAI> > . > You are receiving this because you authored the thread.Message ID: > ***@***.***> >
Fortich commented 2026-11-12 01:08:47 +00:00 (Migrated from github.com)

@NotRexed flagging that this still reproduces on current main, in case it's useful for tracking.

On 6ff87f59 (RX 6800 XT, RADV NAVI21, Mesa 25.0.7, kernel 7.0.0-42):

  • without the patch: 56 pool ... not imported / storage buffer NOT bound lines, grass flickering;
  • with davkdavk's sparse-queue patch: sparse buffers are bound on a queue of family 4,
    0 not imported, no flicker;
  • udmabuf size_limit_mb left at 64 MB in both runs.

The patch no longer applies as posted (queue creation changed in #2325), so I rebased it onto
6ff87f59: 5 files, 119 lines, tests/test_sparse_queue.py passes. Credit to @davkdavk for the original.

hookshot-sparse-queue-radv.patch

@NotRexed flagging that this still reproduces on current main, in case it's useful for tracking. On 6ff87f59 (RX 6800 XT, RADV NAVI21, Mesa 25.0.7, kernel 7.0.0-42): - without the patch: 56 `pool ... not imported` / `storage buffer NOT bound` lines, grass flickering; - with davkdavk's sparse-queue patch: `sparse buffers are bound on a queue of family 4`, 0 not imported, no flicker; - udmabuf `size_limit_mb` left at 64 MB in both runs. The patch no longer applies as posted (queue creation changed in #2325), so I rebased it onto 6ff87f59: 5 files, 119 lines, `tests/test_sparse_queue.py` passes. Credit to @davkdavk for the original. [hookshot-sparse-queue-radv.patch](https://github.com/user-attachments/files/34721947/hookshot-sparse-queue-radv.patch)
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#2239
No description provided.