fix(vk): shorten the rendered-texture keep near the VRAM limit on AMD too #961

Merged
ZurielAtr merged 1 commit from fix/keep-rendered-at-limit into main 2026-11-09 08:47:09 +00:00
ZurielAtr commented 2026-11-09 03:19:52 +00:00 (Migrated from github.com)

What changed

An unused texture the GPU drew (a render target the game may sample later) is kept for 3600 presents before the eviction
pass lets it go, or for 600 when the process is "over what the driver allows":

const uint64_t keep_rendered = known && used > allowed ? 600 : 3600;

AMD's driver never reports the process's use of the device heap above what it allows. Once the VRAM is full it reports
exactly the limit (VRAM: 6940 MB used of 6940 MB allowed in the log, line after line, while VMA alone held up to 6.4 GB
and the rest of the process's VRAM came on top). So used > allowed is never true on AMD, and the shorter keep never
applies there.

The 600 now starts at the same line the texture budget already uses, 97% of what the driver allows. The rule is in
gpu/vk/keep_rendered.h. RX_VK_KEEP_RENDERED_OVER=1 restores the old condition. Nothing changes below 97%, and nothing
changes on drivers that report usage past the limit.

Why

Without it, an 8 GB AMD card slowly fills up during play. In a ~12-minute session (Hyrule Field, Lon Lon Ranch, Hyrule
Castle Town) the log showed:

  • the VRAM pinned at 6940 of 6940 MB for most of the session;
  • 3.8 GB of textures (1.6 GB of them rendered by the GPU), of which only 2.4 GB had been used in the last 8 presents;
  • with the same draw count (~1600 draws), GPU time going from 11-14 ms to 24-34 ms after several minutes. The driver was
    paging VRAM to system memory, and the game went to stutters until the area was reloaded.

How it was tested

RX 7700S Laptop (8 GB, 6.9-7.1 GB allowed by the driver), Ryzen 7 7735HS, Adrenalin 26.10.1, Windows 11, v2.0.5. Played
normally (field, ranch, market) for about 12 minutes per build.

The local build that fixed it carried this condition together with other VRAM changes that are separate PRs (#899's
3-frame update and BC3 for large ASTC textures on 8 GB cards). I can't isolate this one's share of the fps. What this
change does on its own, the logs show directly: before it, the rendered textures were never let go under the 600-present
rule while the VRAM sat at the limit; with it, they go, and the GPU time no longer creeps up over the session (median
9.3 ms, p90 13.2 ms, no paging slowdowns). The player reported no degradation over time.

Game-free check: tests/test_keep_rendered.py compiles tests/test_keep_rendered.cpp against the rule (unknown usage, far
from the limit, under and at 97%, the clamped report, past the limit, and the old rule behind the switch). It also checks
that the eviction pass still uses the rule. It is listed in tests/run_all.py with --cxx g++, in a different spot from
#899 and #900 so they don't conflict.

🤖 Generated with Claude Code

## What changed An unused texture the GPU drew (a render target the game may sample later) is kept for 3600 presents before the eviction pass lets it go, or for 600 when the process is "over what the driver allows": ```cpp const uint64_t keep_rendered = known && used > allowed ? 600 : 3600; ``` AMD's driver never reports the process's use of the device heap above what it allows. Once the VRAM is full it reports exactly the limit (`VRAM: 6940 MB used of 6940 MB allowed` in the log, line after line, while VMA alone held up to 6.4 GB and the rest of the process's VRAM came on top). So `used > allowed` is never true on AMD, and the shorter keep never applies there. The 600 now starts at the same line the texture budget already uses, 97% of what the driver allows. The rule is in `gpu/vk/keep_rendered.h`. `RX_VK_KEEP_RENDERED_OVER=1` restores the old condition. Nothing changes below 97%, and nothing changes on drivers that report usage past the limit. ## Why Without it, an 8 GB AMD card slowly fills up during play. In a ~12-minute session (Hyrule Field, Lon Lon Ranch, Hyrule Castle Town) the log showed: - the VRAM pinned at `6940 of 6940 MB` for most of the session; - 3.8 GB of textures (1.6 GB of them rendered by the GPU), of which only 2.4 GB had been used in the last 8 presents; - with the same draw count (~1600 draws), GPU time going from 11-14 ms to 24-34 ms after several minutes. The driver was paging VRAM to system memory, and the game went to stutters until the area was reloaded. ## How it was tested RX 7700S Laptop (8 GB, 6.9-7.1 GB allowed by the driver), Ryzen 7 7735HS, Adrenalin 26.10.1, Windows 11, v2.0.5. Played normally (field, ranch, market) for about 12 minutes per build. The local build that fixed it carried this condition together with other VRAM changes that are separate PRs (#899's 3-frame update and BC3 for large ASTC textures on 8 GB cards). I can't isolate this one's share of the fps. What this change does on its own, the logs show directly: before it, the rendered textures were never let go under the 600-present rule while the VRAM sat at the limit; with it, they go, and the GPU time no longer creeps up over the session (median 9.3 ms, p90 13.2 ms, no paging slowdowns). The player reported no degradation over time. Game-free check: `tests/test_keep_rendered.py` compiles `tests/test_keep_rendered.cpp` against the rule (unknown usage, far from the limit, under and at 97%, the clamped report, past the limit, and the old rule behind the switch). It also checks that the eviction pass still uses the rule. It is listed in `tests/run_all.py` with `--cxx g++`, in a different spot from #899 and #900 so they don't conflict. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Commenting is not possible because the repository is archived.
No description provided.