fix(vk): slow resume and black HUD hearts on 4 GB cards: the texture squeeze waits while VMA's blocks have room #1506

Merged
rakefire-impala merged 1 commit from fix/slow-resume-black-hearts-texture-squeeze into main 2026-11-10 16:44:35 +00:00
rakefire-impala commented 2026-11-10 05:43:19 +00:00 (Migrated from github.com)

At the driver's VRAM limit, the 97% texture "squeeze" kept shrinking the budget every 10 frames, even while VMA's blocks had plenty of free room. On a 4 GB card a paused game lost 1.7 GB of textures in seconds. This makes the rule wait while the blocks hold room.

A VRAM policy change, as the review of #1023 noted, so it's split out on its own. Tested on a 4 GB card; reports from other low-VRAM cards are welcome. Part of splitting up #1023.

Problem

At the driver's limit, texture_frame's 97% rule set the texture budget below what the textures held, every 10 frames. Evicting a texture frees space inside VMA's blocks, but the driver still counts those blocks. So the count stayed at the limit, the rule fired again, and the budget shrank again: a ratchet.

On an RX 5500M (3337 of 3337 MB used, with 1224 MB free inside the blocks), a paused game, whose scene draws nothing:

  • lost 1700 MB of textures in seconds (2851 → 1137 MB);
  • made them all again on unpausing, a long wait after pause or alt-tab;
  • drew the HUD's GPU-drawn textures as black glyphs (hearts, the minimap's view cone) until an area change, because those were evicted too.

Change

  • The 97% rule waits while the blocks hold an eighth of the allowance free. New images take that space, so the driver's count doesn't grow. The other rule, which judges pressure net of the free block space, still evicts as before.
  • The VRAM log line says (at the driver's limit, room in the blocks: not squeezed) when the rule waits.
  • RX_VK_SQUEEZE_ALWAYS=1 brings the old behaviour back.

How to check

Pause the game for a minute on a low-VRAM card, or alt-tab away, then resume. Textures stay resident and resume is quick. The periodic vk: VRAM: log lines show the "not squeezed" note while the blocks have room.

Risk

The change only applies at the driver's limit with room in the blocks. Cards that never reach the limit behave as before, and the env var restores the old rule anywhere.

Tests

tests/test_texture_squeeze.py (new) checks the rule, its switch and the log line. It fails on main without this change.

Tested on

GPU AMD Radeon RX 5500M (RDNA1, 4 GB VRAM), laptop
Driver AMD Windows driver, Windows 11
Result Pausing and alt-tab no longer drain the textures; hearts and the minimap cone stay drawn (tested on an earlier base; rebased on current main, game-free tests pass)
At the driver's VRAM limit, the 97% texture "squeeze" kept shrinking the budget every 10 frames, even while VMA's blocks had plenty of free room. On a 4 GB card a paused game lost 1.7 GB of textures in seconds. This makes the rule wait while the blocks hold room. A VRAM policy change, as the review of #1023 noted, so it's split out on its own. Tested on a 4 GB card; reports from other low-VRAM cards are welcome. Part of splitting up #1023. ## Problem At the driver's limit, `texture_frame`'s 97% rule set the texture budget below what the textures held, every 10 frames. Evicting a texture frees space **inside** VMA's blocks, but the driver still counts those blocks. So the count stayed at the limit, the rule fired again, and the budget shrank again: a ratchet. On an RX 5500M (3337 of 3337 MB used, with **1224 MB free inside the blocks**), a paused game, whose scene draws nothing: - lost 1700 MB of textures in seconds (2851 → 1137 MB); - made them all again on unpausing, a long wait after pause or alt-tab; - drew the HUD's GPU-drawn textures as black glyphs (hearts, the minimap's view cone) until an area change, because those were evicted too. ## Change - The 97% rule waits while the blocks hold **an eighth of the allowance** free. New images take that space, so the driver's count doesn't grow. The other rule, which judges pressure net of the free block space, still evicts as before. - The VRAM log line says `(at the driver's limit, room in the blocks: not squeezed)` when the rule waits. - `RX_VK_SQUEEZE_ALWAYS=1` brings the old behaviour back. ## How to check Pause the game for a minute on a low-VRAM card, or alt-tab away, then resume. Textures stay resident and resume is quick. The periodic `vk: VRAM:` log lines show the "not squeezed" note while the blocks have room. ## Risk The change only applies at the driver's limit **with** room in the blocks. Cards that never reach the limit behave as before, and the env var restores the old rule anywhere. ## Tests `tests/test_texture_squeeze.py` (new) checks the rule, its switch and the log line. It fails on main without this change. ## Tested on | | | |---|---| | GPU | AMD Radeon RX 5500M (RDNA1, 4 GB VRAM), laptop | | Driver | AMD Windows driver, Windows 11 | | Result | Pausing and alt-tab no longer drain the textures; hearts and the minimap cone stay drawn (tested on an earlier base; rebased on current main, game-free tests pass) |
hckrman101 (Migrated from github.com) approved these changes 2026-11-10 16:38:52 +00:00
hckrman101 (Migrated from github.com) left a comment

Looks good. The 97% squeeze now waits while block_free >= allowed/8, which breaks the evict -> count-stays-at-limit -> evict-again ratchet. The net-of-free-blocks 90% rule is untouched, so real pressure still evicts. block_free and known are in scope, the env switch matches the existing RX_VK_BUDGET_BY_BLOCKS pattern, and the log note uses the same condition. CI is green, and the new test is picked up by run_all's tests/ discovery.

Nits only: the test is a source-string check (fine for a policy tweak like this), and the 1/8 threshold is a judgment call that would be good to hear back on from other low-VRAM cards. Heads-up: #1637 also touches the 97% squeeze, so whichever lands second will need a look at the interaction.

Looks good. The 97% squeeze now waits while block_free >= allowed/8, which breaks the evict -> count-stays-at-limit -> evict-again ratchet. The net-of-free-blocks 90% rule is untouched, so real pressure still evicts. `block_free` and `known` are in scope, the env switch matches the existing RX_VK_BUDGET_BY_BLOCKS pattern, and the log note uses the same condition. CI is green, and the new test is picked up by run_all's tests/ discovery. Nits only: the test is a source-string check (fine for a policy tweak like this), and the 1/8 threshold is a judgment call that would be good to hear back on from other low-VRAM cards. Heads-up: #1637 also touches the 97% squeeze, so whichever lands second will need a look at the interaction.
Commenting is not possible because the repository is archived.
No description provided.