perf(vk): a 6 GB card mirrors a quarter of its VRAM, not an eighth or 512 MB #237

Open
i12bp8 wants to merge 5 commits from i12bp8/Longshot:perf/low-vram-mirror-budget into main
First-time contributor

Why

On 6 GB cards, Hyrule Field runs at about 18 fps on the Low (6GB) preset, which every 6 GB card with mesh shaders starts on. The game's largest memory pools don't fit in its 512 MB of VRAM mirrors (768 MB on Auto), so the GPU reads them over PCIe. Giving these cards a quarter of their VRAM, as larger cards get, more than doubles the frame rate. It costs VRAM headroom: on the card measured, the process then uses about 95% of what the driver allows, against 82% on main (below).

Ported from https://github.com/NotRexed/Hookshot/pull/2834 (Hookshot, before the move).

What changed

  • vk: new gpu/vk/mirror_budget.h (budget_bytes was named preset_bytes until 091daa9):
    • auto_bytes() is Auto's rule: a quarter of the card, at most 3 GB, and an eighth only on a small card, 4.5 GB or less (small_card()). It was an eighth on cards of 6.5 GB or less.
    • budget_bytes() caps a budget's mirrors at Auto's. That applies to a budget set by a Quality preset on any card. It also applies to one chosen on the VRAM budget row itself on a small card, so a 4 GB card on the row's 3.6 GB step stays at 512 MB as before. Its 4.8 GB-and-up steps, past what such a card has, also keep 512 now (1024-3072 on main).
  • vk: mirror_budget() in gpu/vk/vk_memory.cpp uses both, with the card's size from device_vram_bytes(). RX_VK_MIRROR_MB still wins over both. The comment above mirror_on() no longer names a 3072 MB default.
  • menu: kVramMirrorMb in gpu/vk/vk_menu.cpp: the 3.6 GB VRAM budget step (the Low (6GB) preset's) asks for 1536 MB of mirrors, not 512. Through budget_bytes() a 6 GB card gets Auto's quarter (1498 MB on the card measured, which reports 5992 MB), and a 4 GB card gets 512.
  • tests: tests/test_mirror_budget.{py,cpp} compiles and checks both rules, including the small-card cap on the row, and checks that mirror_budget() uses them. tests/test_vram_budget_row.py now expects Low's 1536.
  • docs: RX_VK_MIRROR_MB in docs/development.md says what the default is. docs/tested-configurations.md has the three runs below.

Out of scope, on purpose: the row's mirrors are now non-monotonic. The 3.6 GB step (Low) asks for 1536 MB, more than the 4.8 GB step's (Balanced) 1024. Hyrule Field mirrors 1.3-1.5 GB here, so 8 GB cards on Auto or Balanced (RTX 3070, 4060, RX 6600) may still leave a pool in system memory. That is a question for a follow-up with measurements on an 8 GB card.

Flags and settings

Flag What it does Default now Recommendation Helps on Doesn't help on Untested on
Auto's mirror budget (mirror_budget.h auto_bytes; RX_VK_MIRROR_MB=<MB> overrides it) How much VRAM the game's pools are mirrored in A quarter of a 4.5-6.5 GB card (about 1.5 GB on 6 GB), was an eighth (768 MB). Unchanged above and below On by default RTX 3060 Laptop 6 GB at the Low preset: 17.6 → 39.2 fps (measured) Cards of 8 GB or more and of 4.5 GB or less (unchanged) 6 GB cards that start on the Minimum tier because they have no mesh shaders, where preset_caps_memory() is false so Auto's rule applies (768 → 1536 MB): GTX 1060 6 GB (the README's minimum card) and RX 5600 XT (RDNA1, mirrors on). They run the compute fallback, with the least GPU headroom. Desktop 6 GB cards that drive monitors (RTX 2060, 1660 Super), whose allowance is smaller than this laptop's
VRAM budget row, 3.6 GB step (the Low (6GB) preset) The mirrors of that step Asks 1536 MB (was 512), capped at Auto's on every card a preset set it on, and on small cards when chosen on the row On 6 GB cards - 4 GB cards in the game (the test covers the cap)

To go back to main's sizes for a run: RX_VK_MIRROR_MB=512 (Low's former) or 768 (Auto's former on 6 GB).

Measurements

main: fbd4202 (2026-11-13)
this PR: perf/low-vram-mirror-budget @ c17b339, on main fbd4202 (the code measured). Since rebased onto main d964886 as 38c1a48: the same diff, plus a comment and the tested-configurations row.
Why the numbers still hold after the rebase: main's 9 commits since fbd4202 don't touch the mirrors, their budget or the VRAM budget row (mirror_budget(), kVramMirrorMb, preset_caps_memory and device_vram_bytes are unchanged, as is MKWVK_API_VERSION 21). They do touch occlusion queries and pipelines, which could move both sides' fps alike, not the gap between them.
Hardware: NVIDIA GeForce RTX 3060 Laptop GPU 6 GB (Optimus: it drives no desktop; the driver reports 5992 MB and allows the process about 5.0 GB), driver 621.14, AMD Ryzen 7 6800HS, 16 GB RAM, Windows 11 Home (26200)
Scene: Hyrule Field, walking the same route, about 2 minutes a run; output 2048x1152; Quality preset Low (6GB), with its own settings: VRAM budget 3.6 GB, DLSS render size 1152x648 in every run (no Auto stepping); frame generation off, no cap
Method: the launcher's v3.0.0-rc.3 game (source cb01b5a3, MKWVK_API_VERSION 21 as main) with its renderer, longshot_vk.dll, built alone from each commit (RX_VK_ONLY=1 RX_RELEASE=1 python -I nx2/build.py --standalone, llvm-mingw, NVIDIA DLSS SDK) and swapped in before each run. 6 runs, alternated main, PR, PR at 1024 MB (RX_VK_MIRROR_MB=1024), twice. Frame rates come from longshot_log.txt's "N presents, X fps" lines (every 120 presents), counting only in-field lines (over 1000 draws a frame) and dropping the first one (loading). VRAM comes from the in-field vk: VRAM: ... used of ... allowed lines (every 600 frames). The median is taken per run and over both runs.
How to reproduce: build the renderer alone as above from each commit, put it in a copy of a game folder's bin/, choose Quality preset Low (6GB), and walk through Hyrule Field.

main @ fbd4202 this PR @ c17b339 this PR @ c17b339, RX_VK_MIRROR_MB=1024
fps, run 1 / run 2 (median) 16.7 / 18.6 39.2 / 38.9 22.4 / 33.1
fps, both runs (median) 17.6 39.2 30.7
Mirrors' budget 512 MB 1498 MB 1024 MB
Largest pool left in system memory 224 MB 92 MB 152 MB
VRAM used of allowed, median (max) 4085 of 4998 MB, 82% (90%) 4818 of 5037 MB, 95% (98%) 4432 of 5007 MB, 89% (92%)
Textures held, median 1619 MB 1560 MB 1624 MB
Textures evicted and uploaded again from the game's memory (the always-on counter; the per-texture log, RX_VK_LOG_REMADE, was off) 20 or more in run 1, 0 in run 2 0, 0 0, 0
commit limit near lines (system RAM: this PC has 16 GB), the least commit left 7 and 2, 495 MB 3 and 4, 575 MB 2 and 3, 1015 MB
Render-target pool "VRAM short: given back" lines 0 5 0
VRAM compactions 6 4 2
Vulkan errors, device lost, out of memory none none none

What it costs. The extra GB comes out of the headroom. On this card the process goes from 82% to 95% of the driver's allowance, at most 98%, and the render-target pool gives images back when VRAM runs short (5 times in two runs, never on main). The textures' budget reads 0 MB on both sides because of system RAM, not VRAM: every run, main and PR alike, hit the commit-limit path (commit limit near) on this 16 GB PC, which sets the textures' budget down to 0. So "textures held" says little about the VRAM squeeze. What does: no texture was evicted and uploaded again in the PR's runs (20 or more in main's first run), as far as the always-on counter shows. The mirrors themselves are not squeezed when VRAM runs short, because RX_VK_MIRROR_TIGHT is opt-in. The texture cache takes the squeeze (Risk, below). No texture went missing and nothing failed here, but this laptop is close to a best case: its GPU drives no desktop. A desktop 6 GB card that drives monitors and shares VRAM with a browser has less allowance, and gets closer to the situation in #130 sooner (T-NWN5 asks for one).

1024 MB as a middle. It keeps more headroom (89%) and still gains (30.7 fps median), but it is uneven: 22.4 in one run, 33.1 in the other. The pools are filled first come, first served, so which large pool is left out varies (152 MB in one run, 40 MB in the other). Auto's quarter is the size at which the scene's pools fit every time here. If reviewers prefer the headroom, 1024 on 6 GB cards is the alternative.

Earlier runs, kept in docs/tested-configurations.md: the same card at a 33% render size (Auto's step-down) with main 0edc137's and this branch's renderers, 20.1 against 42.2 fps. Also rc.3's own renderer with only RX_VK_MIRROR_MB set, 18.8 against 38.6.

rev_main_2: vk: pool 0x108c000000 (224 MB) stays in system memory: the mirrors have 480 MB of 512
rev_main_1: vk: VRAM: 4085 MB used of 4987 MB allowed (699 MB of it free in the blocks); textures 1706 MB (budget 0 MB), ...
rev_pr_2:   vk: VRAM: 4940 MB used of 5022 MB allowed (603 MB of it free in the blocks); textures 1486 MB (budget 0 MB), ...
rev_pr_2:   vk: render target images: 0 reused from the pool, 260 made new, 142 destroyed from it; it holds 0 (0 MB), VRAM short: given back
rev_pr_1:   vk: 59 pools mirrored in VRAM (1496 MB)
rev_1gb_1:  vk: VRAM: 4320 MB used of 5007 MB allowed (509 MB of it free in the blocks); textures 1588 MB (budget 142 MB), ...
median of the in-field "N presents, X fps" lines over both runs: main 17.6 (26 lines), PR 39.2 (34), 1024 MB 30.7 (25)

Testing

Tested:

  • python -I -B tests/run_all.py on Windows 11 with the launcher's llvm-mingw, at the branch's head 091daa9 (on main d964886): 451 passed, 10 failed, 73 skipped. tests/test_menu_i18n.py fails on main d964886 itself (a pt_BR string no longer in vk_menu.cpp). The other 9 failed on main fbd4202 as well (447 passed there): test_release, test_check_third_party, test_lift_cache, test_spawn_emit, test_portable_builder_home, test_portable_builder_startup, test_fpx_sticky, test_bake_portability and nx2/test_nup_paths. None of them reads the files this PR changes. test_mirror_budget and test_vram_budget_row pass.
  • python -I scripts/check_third_party.py: 11 parts as their notes say.
  • Built on Windows: the renderer alone from this branch and from main with llvm-mingw (RX_VK_ONLY, RX_RELEASE, with NVIDIA DLSS), 0 failed, linked.
  • Built on Linux: the renderer alone (longshot_vk.so, as scripts/linux/appimage.sh builds it, with tools.lock's linux-x64 tools and RX_MARCH=x86-64-v3 RX_VK_ONLY=1 RX_RELEASE=1) in scripts/linux/Dockerfile's Ubuntu 22.04 image, at a5ee84d (this branch's head, with the small-card cap): 0 failed, linked. test_mirror_budget passes there with g++.
  • In the game: 6 alternated runs on the Low preset and 4 earlier ones, in Hyrule Field on an RTX 3060 Laptop 6 GB (above). No crashes, no Vulkan errors, no texture problems seen.

Not tested:

  • In the game on Linux, and a full game build of this branch (the renderer was built alone and run in rc.3's game).
  • Desktop 6 GB cards driving monitors, with a smaller allowance.
  • 6 GB cards without mesh shaders (GTX 1060 6 GB, RX 5600 XT) on the Minimum tier.
  • AMD and Intel 6 GB cards.
  • 4 GB cards in the game.
  • 8 GB cards' unchanged budgets (out of scope).

Needs other testers:

  • A 6 GB card that drives a monitor, or an AMD or Intel one (RTX 2060, GTX 1660 Super/Ti, RX 5600 XT, RX 6600M, Arc A580): Hyrule Field on Low, main against this PR, with the VRAM: lines, the render-target pool lines and RX_VK_LOG_REMADE=1, expecting no device lost, no VRAM-full stutter and VRAM under the allowance (T-XFT3, replacing T-NWN5)
  • 4 GB card (GTX 1650, RX 5500M): Low preset, expecting the log's mirrors at 512 MB as on main (T-9799)

Screenshots

Nothing on screen

Risk and rollback

  • What could break. The mirrors take up to about 1 GB more VRAM on 4.5-6.5 GB cards, and nothing gives that back when VRAM runs short. mirrors_trim only cuts away the parts of a mirror outside every game pool while VRAM is over 80%, and the 90% rule for mirrors exists only behind RX_VK_MIRROR_TIGHT, which is opt-in. What gives memory back is the texture cache (its 90% rule, and the compaction's hold at 85%) and the render-target pool. So the trade-off is "mirrors take the extra GB, and textures take the squeeze". The worst case is a desktop 6 GB card with a small allowance: textures re-uploaded more often or held at lower detail, or the driver over its limit as in #130.
  • How to turn it off. For one run, RX_VK_MIRROR_MB=768 (Auto's former) or 512 (Low's former). Otherwise, reverting the commit is enough.

Reviewer notes

Start with gpu/vk/mirror_budget.h, where the rules and the reasons sit together. On cards of 8 GB or more nothing changes. On small cards (4.5 GB or less) Auto and the presets are unchanged, and the VRAM budget row is now capped at Auto's, which lowers its 4.8 GB-and-up steps there. Only the band between 4.5 and 6.5 GB moves from an eighth to a quarter.

Issues

See https://github.com/NotRexed/Hookshot/pull/2834
See #130

Checklist

For everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description).
  • Rebased on current main.
  • python -I -B tests/run_all.py run and passing (any failure that also fails on main is named above).
  • Tested in the game, or what wasn't is named under Testing.
  • Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests).
  • Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported.
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

If applicable

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • Flags noted, and the switch reference updated (docs/development.md, the README).
  • A row in docs/tested-configurations.md for each measured run.
  • A check under tests/ that reads changed source updated in this PR, not weakened.
  • Docs updated.
  • Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths.
## Why On 6 GB cards, Hyrule Field runs at about 18 fps on the Low (6GB) preset, which every 6 GB card with mesh shaders starts on. The game's largest memory pools don't fit in its 512 MB of VRAM mirrors (768 MB on Auto), so the GPU reads them over PCIe. Giving these cards a quarter of their VRAM, as larger cards get, more than doubles the frame rate. It costs VRAM headroom: on the card measured, the process then uses about 95% of what the driver allows, against 82% on main (below). Ported from https://github.com/NotRexed/Hookshot/pull/2834 (Hookshot, before the move). ## What changed - vk: new `gpu/vk/mirror_budget.h` (`budget_bytes` was named `preset_bytes` until 091daa9): - `auto_bytes()` is Auto's rule: a quarter of the card, at most 3 GB, and an eighth only on a small card, 4.5 GB or less (`small_card()`). It was an eighth on cards of 6.5 GB or less. - `budget_bytes()` caps a budget's mirrors at Auto's. That applies to a budget set by a Quality preset on any card. It also applies to one chosen on the VRAM budget row itself on a small card, so a 4 GB card on the row's 3.6 GB step stays at 512 MB as before. Its 4.8 GB-and-up steps, past what such a card has, also keep 512 now (1024-3072 on main). - vk: `mirror_budget()` in `gpu/vk/vk_memory.cpp` uses both, with the card's size from `device_vram_bytes()`. `RX_VK_MIRROR_MB` still wins over both. The comment above `mirror_on()` no longer names a 3072 MB default. - menu: `kVramMirrorMb` in `gpu/vk/vk_menu.cpp`: the 3.6 GB VRAM budget step (the Low (6GB) preset's) asks for 1536 MB of mirrors, not 512. Through `budget_bytes()` a 6 GB card gets Auto's quarter (1498 MB on the card measured, which reports 5992 MB), and a 4 GB card gets 512. - tests: `tests/test_mirror_budget.{py,cpp}` compiles and checks both rules, including the small-card cap on the row, and checks that `mirror_budget()` uses them. `tests/test_vram_budget_row.py` now expects Low's 1536. - docs: `RX_VK_MIRROR_MB` in `docs/development.md` says what the default is. `docs/tested-configurations.md` has the three runs below. **Out of scope, on purpose:** the row's mirrors are now non-monotonic. The 3.6 GB step (Low) asks for 1536 MB, more than the 4.8 GB step's (Balanced) 1024. Hyrule Field mirrors 1.3-1.5 GB here, so 8 GB cards on Auto or Balanced (RTX 3070, 4060, RX 6600) may still leave a pool in system memory. That is a question for a follow-up with measurements on an 8 GB card. ## Flags and settings | Flag | What it does | Default now | Recommendation | Helps on | Doesn't help on | Untested on | |---|---|---|---|---|---|---| | Auto's mirror budget (`mirror_budget.h` `auto_bytes`; `RX_VK_MIRROR_MB=<MB>` overrides it) | How much VRAM the game's pools are mirrored in | A quarter of a 4.5-6.5 GB card (about 1.5 GB on 6 GB), was an eighth (768 MB). Unchanged above and below | On by default | RTX 3060 Laptop 6 GB at the Low preset: 17.6 → 39.2 fps (measured) | Cards of 8 GB or more and of 4.5 GB or less (unchanged) | 6 GB cards that start on the Minimum tier because they have no mesh shaders, where `preset_caps_memory()` is false so Auto's rule applies (768 → 1536 MB): **GTX 1060 6 GB** (the README's minimum card) and **RX 5600 XT** (RDNA1, mirrors on). They run the compute fallback, with the least GPU headroom. Desktop 6 GB cards that drive monitors (RTX 2060, 1660 Super), whose allowance is smaller than this laptop's | | VRAM budget row, 3.6 GB step (the Low (6GB) preset) | The mirrors of that step | Asks 1536 MB (was 512), capped at Auto's on every card a preset set it on, and on small cards when chosen on the row | On | 6 GB cards | - | 4 GB cards in the game (the test covers the cap) | To go back to main's sizes for a run: `RX_VK_MIRROR_MB=512` (Low's former) or `768` (Auto's former on 6 GB). ## Measurements main: fbd4202 (2026-11-13) this PR: perf/low-vram-mirror-budget @ c17b339, on main fbd4202 (the code measured). Since rebased onto main d964886 as 38c1a48: the same diff, plus a comment and the tested-configurations row. Why the numbers still hold after the rebase: main's 9 commits since fbd4202 don't touch the mirrors, their budget or the VRAM budget row (`mirror_budget()`, `kVramMirrorMb`, `preset_caps_memory` and `device_vram_bytes` are unchanged, as is `MKWVK_API_VERSION` 21). They do touch occlusion queries and pipelines, which could move both sides' fps alike, not the gap between them. Hardware: NVIDIA GeForce RTX 3060 Laptop GPU 6 GB (Optimus: it drives no desktop; the driver reports 5992 MB and allows the process about 5.0 GB), driver 621.14, AMD Ryzen 7 6800HS, 16 GB RAM, Windows 11 Home (26200) Scene: Hyrule Field, walking the same route, about 2 minutes a run; output 2048x1152; **Quality preset Low (6GB)**, with its own settings: VRAM budget 3.6 GB, DLSS render size 1152x648 in every run (no Auto stepping); frame generation off, no cap Method: the launcher's v3.0.0-rc.3 game (source cb01b5a3, `MKWVK_API_VERSION` 21 as main) with its renderer, `longshot_vk.dll`, built alone from each commit (`RX_VK_ONLY=1 RX_RELEASE=1 python -I nx2/build.py --standalone`, llvm-mingw, NVIDIA DLSS SDK) and swapped in before each run. 6 runs, alternated main, PR, PR at 1024 MB (`RX_VK_MIRROR_MB=1024`), twice. Frame rates come from `longshot_log.txt`'s "N presents, X fps" lines (every 120 presents), counting only in-field lines (over 1000 draws a frame) and dropping the first one (loading). VRAM comes from the in-field `vk: VRAM: ... used of ... allowed` lines (every 600 frames). The median is taken per run and over both runs. How to reproduce: build the renderer alone as above from each commit, put it in a copy of a game folder's `bin/`, choose Quality preset Low (6GB), and walk through Hyrule Field. | | main @ fbd4202 | this PR @ c17b339 | this PR @ c17b339, `RX_VK_MIRROR_MB=1024` | |---|---|---|---| | fps, run 1 / run 2 (median) | 16.7 / 18.6 | 39.2 / 38.9 | 22.4 / 33.1 | | **fps, both runs (median)** | **17.6** | **39.2** | **30.7** | | Mirrors' budget | 512 MB | 1498 MB | 1024 MB | | Largest pool left in system memory | 224 MB | 92 MB | 152 MB | | **VRAM used of allowed, median (max)** | **4085 of 4998 MB, 82% (90%)** | **4818 of 5037 MB, 95% (98%)** | **4432 of 5007 MB, 89% (92%)** | | Textures held, median | 1619 MB | 1560 MB | 1624 MB | | Textures evicted and uploaded again from the game's memory (the always-on counter; the per-texture log, `RX_VK_LOG_REMADE`, was off) | 20 or more in run 1, 0 in run 2 | 0, 0 | 0, 0 | | `commit limit near` lines (system RAM: this PC has 16 GB), the least commit left | 7 and 2, 495 MB | 3 and 4, 575 MB | 2 and 3, 1015 MB | | Render-target pool "VRAM short: given back" lines | 0 | 5 | 0 | | VRAM compactions | 6 | 4 | 2 | | Vulkan errors, device lost, out of memory | none | none | none | **What it costs.** The extra GB comes out of the headroom. On this card the process goes from 82% to 95% of the driver's allowance, at most 98%, and the render-target pool gives images back when VRAM runs short (5 times in two runs, never on main). The textures' budget reads 0 MB on both sides because of system RAM, not VRAM: every run, main and PR alike, hit the commit-limit path (`commit limit near`) on this 16 GB PC, which sets the textures' budget down to 0. So "textures held" says little about the VRAM squeeze. What does: no texture was evicted and uploaded again in the PR's runs (20 or more in main's first run), as far as the always-on counter shows. The mirrors themselves are not squeezed when VRAM runs short, because `RX_VK_MIRROR_TIGHT` is opt-in. The texture cache takes the squeeze (Risk, below). No texture went missing and nothing failed here, but this laptop is close to a best case: its GPU drives no desktop. A desktop 6 GB card that drives monitors and shares VRAM with a browser has less allowance, and gets closer to the situation in https://git.magicbean.dev/MagicBeanDev/Longshot/issues/130 sooner (T-NWN5 asks for one). **1024 MB as a middle.** It keeps more headroom (89%) and still gains (30.7 fps median), but it is uneven: 22.4 in one run, 33.1 in the other. The pools are filled first come, first served, so which large pool is left out varies (152 MB in one run, 40 MB in the other). Auto's quarter is the size at which the scene's pools fit every time here. If reviewers prefer the headroom, 1024 on 6 GB cards is the alternative. Earlier runs, kept in `docs/tested-configurations.md`: the same card at a 33% render size (Auto's step-down) with main 0edc137's and this branch's renderers, 20.1 against 42.2 fps. Also rc.3's own renderer with only `RX_VK_MIRROR_MB` set, 18.8 against 38.6. ``` rev_main_2: vk: pool 0x108c000000 (224 MB) stays in system memory: the mirrors have 480 MB of 512 rev_main_1: vk: VRAM: 4085 MB used of 4987 MB allowed (699 MB of it free in the blocks); textures 1706 MB (budget 0 MB), ... rev_pr_2: vk: VRAM: 4940 MB used of 5022 MB allowed (603 MB of it free in the blocks); textures 1486 MB (budget 0 MB), ... rev_pr_2: vk: render target images: 0 reused from the pool, 260 made new, 142 destroyed from it; it holds 0 (0 MB), VRAM short: given back rev_pr_1: vk: 59 pools mirrored in VRAM (1496 MB) rev_1gb_1: vk: VRAM: 4320 MB used of 5007 MB allowed (509 MB of it free in the blocks); textures 1588 MB (budget 142 MB), ... median of the in-field "N presents, X fps" lines over both runs: main 17.6 (26 lines), PR 39.2 (34), 1024 MB 30.7 (25) ``` ## Testing **Tested:** - `python -I -B tests/run_all.py` on Windows 11 with the launcher's llvm-mingw, at the branch's head 091daa9 (on main d964886): 451 passed, 10 failed, 73 skipped. `tests/test_menu_i18n.py` fails on main d964886 itself (a pt_BR string no longer in `vk_menu.cpp`). The other 9 failed on main fbd4202 as well (447 passed there): `test_release`, `test_check_third_party`, `test_lift_cache`, `test_spawn_emit`, `test_portable_builder_home`, `test_portable_builder_startup`, `test_fpx_sticky`, `test_bake_portability` and `nx2/test_nup_paths`. None of them reads the files this PR changes. `test_mirror_budget` and `test_vram_budget_row` pass. - `python -I scripts/check_third_party.py`: 11 parts as their notes say. - Built on Windows: the renderer alone from this branch and from main with llvm-mingw (`RX_VK_ONLY`, `RX_RELEASE`, with NVIDIA DLSS), 0 failed, linked. - Built on Linux: the renderer alone (`longshot_vk.so`, as `scripts/linux/appimage.sh` builds it, with tools.lock's linux-x64 tools and `RX_MARCH=x86-64-v3 RX_VK_ONLY=1 RX_RELEASE=1`) in `scripts/linux/Dockerfile`'s Ubuntu 22.04 image, at a5ee84d (this branch's head, with the small-card cap): 0 failed, linked. `test_mirror_budget` passes there with g++. - In the game: 6 alternated runs on the Low preset and 4 earlier ones, in Hyrule Field on an RTX 3060 Laptop 6 GB (above). No crashes, no Vulkan errors, no texture problems seen. **Not tested:** - In the game on Linux, and a full game build of this branch (the renderer was built alone and run in rc.3's game). - Desktop 6 GB cards driving monitors, with a smaller allowance. - 6 GB cards without mesh shaders (GTX 1060 6 GB, RX 5600 XT) on the Minimum tier. - AMD and Intel 6 GB cards. - 4 GB cards in the game. - 8 GB cards' unchanged budgets (out of scope). **Needs other testers:** - A 6 GB card that drives a monitor, or an AMD or Intel one (RTX 2060, GTX 1660 Super/Ti, RX 5600 XT, RX 6600M, Arc A580): Hyrule Field on Low, main against this PR, with the `VRAM:` lines, the render-target pool lines and `RX_VK_LOG_REMADE=1`, expecting no device lost, no VRAM-full stutter and VRAM under the allowance (T-XFT3, replacing T-NWN5) - 4 GB card (GTX 1650, RX 5500M): Low preset, expecting the log's mirrors at 512 MB as on main (T-9799) ## Screenshots Nothing on screen ## Risk and rollback - **What could break.** The mirrors take up to about 1 GB more VRAM on 4.5-6.5 GB cards, and nothing gives that back when VRAM runs short. `mirrors_trim` only cuts away the parts of a mirror outside every game pool while VRAM is over 80%, and the 90% rule for mirrors exists only behind `RX_VK_MIRROR_TIGHT`, which is opt-in. What gives memory back is the texture cache (its 90% rule, and the compaction's hold at 85%) and the render-target pool. So the trade-off is "mirrors take the extra GB, and textures take the squeeze". The worst case is a desktop 6 GB card with a small allowance: textures re-uploaded more often or held at lower detail, or the driver over its limit as in https://git.magicbean.dev/MagicBeanDev/Longshot/issues/130. - **How to turn it off.** For one run, `RX_VK_MIRROR_MB=768` (Auto's former) or `512` (Low's former). Otherwise, reverting the commit is enough. ## Reviewer notes Start with `gpu/vk/mirror_budget.h`, where the rules and the reasons sit together. On cards of 8 GB or more nothing changes. On small cards (4.5 GB or less) Auto and the presets are unchanged, and the VRAM budget row is now capped at Auto's, which lowers its 4.8 GB-and-up steps there. Only the band between 4.5 and 6.5 GB moves from an eighth to a quarter. ## Issues See https://github.com/NotRexed/Hookshot/pull/2834 See https://git.magicbean.dev/MagicBeanDev/Longshot/issues/130 ## Checklist ### For everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`). - [x] Rebased on current `main`. - [x] `python -I -B tests/run_all.py` run and passing (any failure that also fails on `main` is named above). - [x] Tested in the game, or what wasn't is named under Testing. - [x] Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests). - [x] Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### If applicable - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] Flags noted, and the switch reference updated (docs/development.md, the README). - [x] A row in `docs/tested-configurations.md` for each measured run. - [x] A check under `tests/` that reads changed source updated in this PR, not weakened. - [x] Docs updated. - [x] Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths.
perf(vk): a 6 GB card mirrors a quarter of its VRAM, 1536 MB, not 512
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 17s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
d27a462793
On a 6 GB card (RTX 3060 Laptop, RTX 2060) Auto gave the game's memory pools an
eighth of the card (768 MB) and the Low (6GB) preset, every 6 GB card's from its
first start, 512 MB. The game's largest pools then stayed in system memory and
the GPU read them over PCIe.

- gpu/vk/mirror_budget.h: Auto's rule (a quarter, at most 3 GB, an eighth only
  on cards of 4.5 GB or less) and a preset's cap (never more than Auto's).
- gpu/vk/vk_memory.cpp: mirror_budget() uses them.
- gpu/vk/vk_menu.cpp: the 3.6 GB VRAM budget step (Low) mirrors 1536 MB.
- tests/test_mirror_budget.{py,cpp}: the rules and their use; the VRAM budget
  row check updated.

Ported from https://github.com/NotRexed/Hookshot/pull/2834

Co-Authored-By: Claude Opus 5.5 <[email protected]>
docs(tested): RTX 3060 Laptop, main's and this branch's renderers built and swapped in Hyrule Field
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 24s
Website / Website on Cloudflare (pull_request_target) Has been skipped
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
2320b958e4
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Author
First-time contributor

Measured with builds: main 0edc137's and this branch's d27a462 renderers built alone (llvm-mingw, DLSS) and swapped into rc.3's game, 4 alternated runs in Hyrule Field on an RTX 3060 Laptop 6 GB: 20.1 fps median on main against 42.2 here; the budget 1498 MB (a quarter of the card as the driver reports it). Rows added to docs/tested-configurations.md (2320b95).

Measured with builds: main 0edc137's and this branch's d27a462 renderers built alone (llvm-mingw, DLSS) and swapped into rc.3's game, 4 alternated runs in Hyrule Field on an RTX 3060 Laptop 6 GB: 20.1 fps median on main against 42.2 here; the budget 1498 MB (a quarter of the card as the driver reports it). Rows added to docs/tested-configurations.md (2320b95).
Author
First-time contributor

Test requests opened: T-NWN5 (6 GB AMD or Intel) and T-9799 (4 GB card: mirrors stay at 512 MB). They need the testing wanted label to be claimable.

Test requests opened: T-NWN5 (6 GB AMD or Intel) and T-9799 (4 GB card: mirrors stay at 512 MB). They need the testing wanted label to be claimable.
Author
First-time contributor

Built on Linux: longshot_vk.so from 2320b95 in scripts/linux/Dockerfile's Ubuntu 22.04 image with tools.lock's tools, 0 failed; the two touched checks pass there with g++. Host-builds box ticked.

Built on Linux: longshot_vk.so from 2320b95 in scripts/linux/Dockerfile's Ubuntu 22.04 image with tools.lock's tools, 0 failed; the two touched checks pass there with g++. Host-builds box ticked.
i12bp8 changed title from WIP: perf(vk): a 6 GB card mirrors a quarter of its VRAM, 1536 MB, not 512 to perf(vk): a 6 GB card mirrors a quarter of its VRAM, 1536 MB, not 512 2026-11-13 17:02:35 +00:00
HumanBean added this to the v3.0.0 milestone 2026-11-13 17:37:39 +00:00
HumanBean force-pushed perf/low-vram-mirror-budget from 2320b958e4
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 24s
Website / Website on Cloudflare (pull_request_target) Has been skipped
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
to b2a011cfa2
All checks were successful
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 5s
CI / Workflow lint (actionlint) (pull_request) Successful in 8s
Third-party parts / As their notes say (pull_request) Successful in 8s
PR description / Description follows the template (pull_request_target) Successful in 3s
2026-11-13 17:40:38 +00:00
Compare
Owner

I rebased this onto main @ fbd42024 to clear the conflicts; it's pushed as b2a011cf. Your two commits are unchanged apart from the rebase. The code applied cleanly. Both conflicts were in docs/tested-configurations.md, where main had added a row at the same place as yours, and I kept every row. No tests were run here. Forgejo now shows it as mergeable.

I rebased this onto main @ fbd42024 to clear the conflicts; it's pushed as b2a011cf. Your two commits are unchanged apart from the rebase. The code applied cleanly. Both conflicts were in `docs/tested-configurations.md`, where main had added a row at the same place as yours, and I kept every row. No tests were run here. Forgejo now shows it as mergeable.
HumanBean left a comment

The change is clean. Auto's rule and the preset cap now live in mirror_budget.h, where they are tested on their own, and mirror_budget() still reads RX_VK_MIRROR_MB first, so the override wins as before. The fps gain on the RTX 3060 Laptop is large and was measured A/B: 20.1 against 42.2 fps, main, PR, main, PR. I checked the other sizes against the code:

  • Unchanged: Auto on cards of 4.5 GB or less (512 MB on 4 GB). Every card of 8 GB or more, on Auto and on every preset: preset_bytes can only lower a preset's value, never raise it. The Steam Deck and iGPUs, which have no mirrors (mirror_on is for discrete cards only), and GCN cards, which have them off. Low on a 4 GB card, capped back to 512. Low on an 8 GB PC with under 12 GB of RAM: preset_caps_memory is false there, so it gets Auto's 2048 as before.
  • Refusal paths: MIRROR_REFUSED is still set for a pool over 1 GB and for a failed allocation. A pool over the budget is still MIRROR_NONE and tried again. mirrors_trim and mirrors_give_back compare against the same mirror_budget(). The PR leaves all of these alone.
  • Checks: test_vram_budget_row is updated, not weakened, and test_mirror_trim's cut text is unchanged. No API or shader changes.

Must change

  1. The Risk section says something the code doesn't do. It says the extra GB is safe because "the existing VRAM pressure rules (mirror trim, the 90% rule) give memory back". Neither one shrinks the mirrors. The 90% rule for mirrors only exists behind RX_VK_MIRROR_TIGHT, which is opt-in, so it is off by default (vk_memory.cpp mirror_make). Mirror trim only cuts away the parts of a mirror that lie outside every game pool, while VRAM is over 80%. Live mirrors stay at their budget whatever the driver allows. What gives memory back is the texture cache: the 90% rule in the texture budget, and the compaction's hold at 85%. Please correct the description. The real trade-off is "mirrors take the extra GB, and textures take the squeeze".
  2. The budget arithmetic isn't measured, and the run was a best case.
    • Estimate for this laptop. On the Low (3.6 GB) budget, the preset's texture budget is min(3600 MB, 75% of the allowance). Assuming the driver allows roughly 5.5 GB of the 5992 MB, that gives 3600 MB of textures plus 1498 MB of mirrors, about 5.1 GB, or about 92% of the allowance. That is before render targets, DLSS, the swapchain and staging. On main it was 3600 + 512, about 4.1 GB. The 90% and 85% lines will therefore cut the texture budget.
    • Why the run hid it. It was taken at 33% render resolution (683x384), which is below what Auto/Low sets (DLSS Performance, or 75% without DLSS). It was also on an Optimus laptop, where the dGPU drives no desktop, so the allowance is about as large as it gets.
    • Why it matters. A desktop RTX 2060, 1660 Super or RX 5600 XT that drives monitors and shares VRAM with a browser has a smaller allowance. That is the situation in #130 (an 8 GB card, 1024 MB of mirrors, the allowance down to about 6 GB, the textures squeezed to a 1260 MB budget, device lost). A 6 GB card with 1.5 GB of fixed mirrors gets close to that situation sooner.
    • What I'm asking for. Please report memory from the runs already done: the VRAM: X MB used of Y allowed ... textures ... (budget ...) status lines, and the texture eviction and re-upload counts, main against PR. Please also add one A/B pair at the tier's own render resolution. AGENTS.md asks a new default to say what it costs where it wasn't measured. Right now the description doesn't say what happens to textures and VRAM use.
  3. "Cards of 4.5 GB or less get exactly what they got before" isn't true for the VRAM budget row. When a player chooses 3.6 GB on the row itself, opts.budget is 0. preset_bytes(…, false, …) then returns 1536 uncapped, and preset_caps_memory() is true when budget is 0. A 4 GB card on that step goes from 512 MB of mirrors to 1536, next to a 3600 MB texture budget that is clamped only to 75% of the allowance. That is past the card. tests/test_mirror_budget.cpp:26 pins this behaviour. Please either cap the row's choice at auto_bytes on cards of 4.5 GB or less, or keep the behaviour on purpose and say so in the description and the Flags table.

Should change

  • More cards get the new size than the Flags table names. Cards without mesh shaders start on the Minimum tier: the GTX 1060 6 GB (the README's minimum card), and the RX 5600 XT (RDNA1, so mirrors are on). preset_caps_memory() is false for a 6 GB card on Minimum, so these get Auto's rule, which goes from 768 to 1536 MB. Their texture budget is Auto's 45%. Please name them under "Helps on / Untested on". They run the compute fallback, so they have the least GPU headroom.
  • AMD and desktop 6 GB evidence is still outstanding. T-NWN5 (6 GB AMD or Intel) and T-9799 (4 GB) are open but can't be claimed without the testing wanted label. For a default that reaches every 6 GB card, a result from one 6 GB AMD card (or one desktop 6 GB card driving a monitor) should come in before merge.
  • The row is now non-monotonic. The 3.6 GB step (Low) mirrors 1536 MB and the 4.8 GB step (Balanced) 1024. Your own logs show Hyrule Field mirroring 1.27 to 1.48 GB, so 8 GB cards on Auto/Balanced (tier 3: RTX 3070, 4060, RX 6600) probably still leave a pool in system memory. This is a follow-up question rather than a blocker, but please say in the description that it is out of scope.
  • Nit, outside the diff. The comment above mirror_on() in vk_memory.cpp still says "RX_VK_MIRROR_MB: their budget (default 3072)".

Not checked: I ran nothing (no build, no tests, no game). Allowance figures are estimates from the code's rules, not from logs.

The change is clean. Auto's rule and the preset cap now live in `mirror_budget.h`, where they are tested on their own, and `mirror_budget()` still reads `RX_VK_MIRROR_MB` first, so the override wins as before. The fps gain on the RTX 3060 Laptop is large and was measured A/B: 20.1 against 42.2 fps, main, PR, main, PR. I checked the other sizes against the code: - **Unchanged:** Auto on cards of 4.5 GB or less (512 MB on 4 GB). Every card of 8 GB or more, on Auto and on every preset: `preset_bytes` can only lower a preset's value, never raise it. The Steam Deck and iGPUs, which have no mirrors (`mirror_on` is for discrete cards only), and GCN cards, which have them off. Low on a 4 GB card, capped back to 512. Low on an 8 GB PC with under 12 GB of RAM: `preset_caps_memory` is false there, so it gets Auto's 2048 as before. - **Refusal paths:** `MIRROR_REFUSED` is still set for a pool over 1 GB and for a failed allocation. A pool over the budget is still `MIRROR_NONE` and tried again. `mirrors_trim` and `mirrors_give_back` compare against the same `mirror_budget()`. The PR leaves all of these alone. - **Checks:** `test_vram_budget_row` is updated, not weakened, and `test_mirror_trim`'s cut text is unchanged. No API or shader changes. ## Must change 1. **The Risk section says something the code doesn't do.** It says the extra GB is safe because "the existing VRAM pressure rules (mirror trim, the 90% rule) give memory back". Neither one shrinks the mirrors. The 90% rule for mirrors only exists behind `RX_VK_MIRROR_TIGHT`, which is opt-in, so it is off by default (`vk_memory.cpp` `mirror_make`). Mirror trim only cuts away the parts of a mirror that lie outside every game pool, while VRAM is over 80%. Live mirrors stay at their budget whatever the driver allows. What gives memory back is the **texture cache**: the 90% rule in the texture budget, and the compaction's hold at 85%. Please correct the description. The real trade-off is "mirrors take the extra GB, and textures take the squeeze". 2. **The budget arithmetic isn't measured, and the run was a best case.** - **Estimate for this laptop.** On the Low (3.6 GB) budget, the preset's texture budget is min(3600 MB, 75% of the allowance). Assuming the driver allows roughly 5.5 GB of the 5992 MB, that gives 3600 MB of textures plus 1498 MB of mirrors, about 5.1 GB, or about 92% of the allowance. That is before render targets, DLSS, the swapchain and staging. On main it was 3600 + 512, about 4.1 GB. The 90% and 85% lines will therefore cut the texture budget. - **Why the run hid it.** It was taken at 33% render resolution (683x384), which is below what Auto/Low sets (DLSS Performance, or 75% without DLSS). It was also on an Optimus laptop, where the dGPU drives no desktop, so the allowance is about as large as it gets. - **Why it matters.** A desktop RTX 2060, 1660 Super or RX 5600 XT that drives monitors and shares VRAM with a browser has a smaller allowance. That is the situation in https://git.magicbean.dev/MagicBeanDev/Longshot/issues/130 (an 8 GB card, 1024 MB of mirrors, the allowance down to about 6 GB, the textures squeezed to a 1260 MB budget, device lost). A 6 GB card with 1.5 GB of fixed mirrors gets close to that situation sooner. - **What I'm asking for.** Please report memory from the runs already done: the `VRAM: X MB used of Y allowed ... textures ... (budget ...)` status lines, and the texture eviction and re-upload counts, main against PR. Please also add one A/B pair at the tier's own render resolution. AGENTS.md asks a new default to say what it costs where it wasn't measured. Right now the description doesn't say what happens to textures and VRAM use. 3. **"Cards of 4.5 GB or less get exactly what they got before" isn't true for the VRAM budget row.** When a player chooses 3.6 GB on the row itself, `opts.budget` is 0. `preset_bytes(…, false, …)` then returns 1536 uncapped, and `preset_caps_memory()` is true when `budget` is 0. A 4 GB card on that step goes from 512 MB of mirrors to 1536, next to a 3600 MB texture budget that is clamped only to 75% of the allowance. That is past the card. `tests/test_mirror_budget.cpp:26` pins this behaviour. Please either cap the row's choice at `auto_bytes` on cards of 4.5 GB or less, or keep the behaviour on purpose and say so in the description and the Flags table. ## Should change - **More cards get the new size than the Flags table names.** Cards without mesh shaders start on the Minimum tier: the GTX 1060 6 GB (the README's minimum card), and the RX 5600 XT (RDNA1, so mirrors are on). `preset_caps_memory()` is false for a 6 GB card on Minimum, so these get Auto's rule, which goes from 768 to 1536 MB. Their texture budget is Auto's 45%. Please name them under "Helps on / Untested on". They run the compute fallback, so they have the least GPU headroom. - **AMD and desktop 6 GB evidence is still outstanding.** T-NWN5 (6 GB AMD or Intel) and T-9799 (4 GB) are open but can't be claimed without the `testing wanted` label. For a default that reaches every 6 GB card, a result from one 6 GB AMD card (or one desktop 6 GB card driving a monitor) should come in before merge. - **The row is now non-monotonic.** The 3.6 GB step (Low) mirrors 1536 MB and the 4.8 GB step (Balanced) 1024. Your own logs show Hyrule Field mirroring 1.27 to 1.48 GB, so 8 GB cards on Auto/Balanced (tier 3: RTX 3070, 4060, RX 6600) probably still leave a pool in system memory. This is a follow-up question rather than a blocker, but please say in the description that it is out of scope. - **Nit, outside the diff.** The comment above `mirror_on()` in `vk_memory.cpp` still says "RX_VK_MIRROR_MB: their budget (default 3072)". Not checked: I ran nothing (no build, no tests, no game). Allowance figures are estimates from the code's rules, not from logs.
@ -0,0 +22,4 @@
/// The mirrors when a Quality preset set the budgets (by_preset): never more than Auto gives the card, so a preset made for a
/// larger card (Low's 1536 MB on a 4 GB one, preset_caps_memory lets Low's budgets through up to 6.75 GB) keeps a small card at
/// Auto's. A budget chosen on the VRAM budget row itself is the player's on any card, as chosen
inline uint64_t preset_bytes(uint64_t asked, bool by_preset, uint64_t vram) {
Owner

by_preset is opts.budget > 0, so a 3.6 GB step chosen on the VRAM budget row itself (budget 0) gets 1536 MB uncapped, on a 4 GB card too: it was 512 there. The description says cards of 4.5 GB or less get exactly what they got before. Either cap the row's choice at auto_bytes(vram) on cards of 4.5 GB or less, or keep this on purpose and say so in the description and the Flags table.

`by_preset` is `opts.budget > 0`, so a 3.6 GB step chosen on the VRAM budget row itself (budget 0) gets 1536 MB uncapped, on a 4 GB card too: it was 512 there. The description says cards of 4.5 GB or less get exactly what they got before. Either cap the row's choice at `auto_bytes(vram)` on cards of 4.5 GB or less, or keep this on purpose and say so in the description and the Flags table.
@ -2486,3 +2483,1 @@
// percent and the frame stuttering)
if (vram && vram <= (6ull << 30) + (512ull << 20)) return vram / 8;
return vram ? std::min<uint64_t>(vram / 4, 3072ull << 20) : (uint64_t)(3072ull << 20);
return mirror_rule::auto_bytes(device_vram_bytes());
Owner

This Auto path also reaches 6 GB cards without mesh shaders. They start on the Minimum tier, where preset_caps_memory() is false: the GTX 1060 6 GB (the README's minimum card) and the RX 5600 XT. These go from 768 to 1536 MB, unmeasured. Please name them in the Flags table.

This Auto path also reaches 6 GB cards without mesh shaders. They start on the Minimum tier, where `preset_caps_memory()` is false: the GTX 1060 6 GB (the README's minimum card) and the RX 5600 XT. These go from 768 to 1536 MB, unmeasured. Please name them in the Flags table.
@ -853,0 +854,4 @@
// PCIe, 30-32 GB of bound ranges every 600 submits in Hyrule Field on an RTX 3060 Laptop (6 GB), the GPU's frame 27 ms. A preset's
// mirrors are never more than Auto's on the card (mirror_budget.h preset_bytes): Low on a 4 GB card, which preset_caps_memory lets
// through, keeps 512
constexpr int kVramMirrorMb[kVramBudgets] = {0, 256, 1536, 1024, 1536, 2048, 2560, 3072};
Owner

Low (1536) now mirrors more than Balanced (1024). Your logs show Hyrule Field mirroring 1.27 to 1.48 GB, so 8 GB cards on Auto/Balanced (tier 3) probably still leave a pool in system memory. Fine as a follow-up, but please say in the description that it is out of scope.

Low (1536) now mirrors more than Balanced (1024). Your logs show Hyrule Field mirroring 1.27 to 1.48 GB, so 8 GB cards on Auto/Balanced (tier 3) probably still leave a pool in system memory. Fine as a follow-up, but please say in the description that it is out of scope.
@ -0,0 +23,4 @@
CHECK(preset_bytes(256 * MB, true, 4 * GB) == 256 * MB); // (Minimum: its own, smaller)
CHECK(preset_bytes(1024 * MB, true, 8 * GB) == 1024 * MB); // (Balanced on an 8 GB card: its own)
CHECK(preset_bytes(3072 * MB, true, 16 * GB) == 3072 * MB); // (Ultra on a 16 GB card)
CHECK(preset_bytes(1536 * MB, false, 4 * GB) == 1536 * MB); // (3.6 GB chosen on the row on a 4 GB card: the player's)
Owner

This pins 1536 MB of mirrors on a 4 GB card, next to a 3600 MB texture budget (clamped only to 75% of the allowance) when the row's 3.6 GB step is picked. If that behaviour changes (see the comment on preset_bytes), update this check to match.

This pins 1536 MB of mirrors on a 4 GB card, next to a 3600 MB texture budget (clamped only to 75% of the allowance) when the row's 3.6 GB step is picked. If that behaviour changes (see the comment on `preset_bytes`), update this check to match.
i12bp8 changed title from perf(vk): a 6 GB card mirrors a quarter of its VRAM, 1536 MB, not 512 to WIP: perf(vk): a 6 GB card mirrors a quarter of its VRAM, 1536 MB, not 512 2026-11-13 17:50:39 +00:00
On a card of 4.5 GB or less, a budget chosen on the VRAM budget row itself is
capped at Auto's mirrors as a preset's is: the row's 3.6 GB step on a 4 GB card
stays at 512 MB, where it was before Low's mirrors went to 1536. The comment
above mirror_on() no longer names a 3072 MB default.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
docs(vk): the mirrors' cost on a 6 GB laptop at the Low preset's own render size, against main and 1024 MB
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 7s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
a5ee84d90e
Co-Authored-By: Claude Opus 5.5 <[email protected]>
i12bp8 changed title from WIP: perf(vk): a 6 GB card mirrors a quarter of its VRAM, 1536 MB, not 512 to WIP: perf(vk): a 6 GB card mirrors a quarter of its VRAM, not an eighth or 512 MB 2026-11-13 18:36:53 +00:00
Author
First-time contributor

Pushed c17b339 and a5ee84d after HumanBean's review: the VRAM budget row is capped at Auto's mirrors on small cards; the Risk section is corrected; new runs on the Low preset's own settings (main, PR, 1024 MB, alternated) with VRAM use. Title no longer says 1536 MB (a 6 GB card gets a quarter as the driver reports it, 1498 MB here). Point-by-point reply follows.

Pushed c17b339 and a5ee84d after HumanBean's review: the VRAM budget row is capped at Auto's mirrors on small cards; the Risk section is corrected; new runs on the Low preset's own settings (main, PR, 1024 MB, alternated) with VRAM use. Title no longer says 1536 MB (a 6 GB card gets a quarter as the driver reports it, 1498 MB here). Point-by-point reply follows.
i12bp8 force-pushed perf/low-vram-mirror-budget from a5ee84d90e
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 7s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
to 38c1a4898b
Some checks failed
Website / Website on Cloudflare (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 9s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
2026-11-13 18:40:57 +00:00
Compare
Author
First-time contributor

Rebased onto main d964886 (one conflict in docs/tested-configurations.md, all rows kept), pushed as 38c1a48. run_all: 451 passed, 10 failed; test_menu_i18n is new and fails on main d964886 itself. The description says why the fbd4202 measurements still hold.

Rebased onto main d964886 (one conflict in docs/tested-configurations.md, all rows kept), pushed as 38c1a48. run_all: 451 passed, 10 failed; test_menu_i18n is new and fails on main d964886 itself. The description says why the fbd4202 measurements still hold.
Author
First-time contributor

Thanks for the careful review, and for the rebase. Point by point:

Must change

  1. Risk section. You're right, and I've rewritten it. Nothing gives the mirrors' extra GB back when VRAM runs short: mirrors_trim only cuts the parts outside every game pool, and the 90% rule for mirrors is behind the opt-in RX_VK_MIRROR_TIGHT. It is the texture cache (its 90% rule and the compaction's hold at 85%) and the render-target pool that give way. The section now says "mirrors take the extra GB, and textures take the squeeze", names the worst case (a desktop 6 GB card with a small allowance, as in #130), and gives the switches to go back.

  2. Memory, and a run at the tier's own settings. I made new runs on the Low (6GB) preset with its own settings (DLSS render size 1152x648, fixed in every run, no Auto step-down), alternated main fbd4202, this PR c17b339, and this PR at RX_VK_MIRROR_MB=1024, twice each. From the in-field VRAM: lines:

    • main: 4085 of 4998 MB, 82% (max 90%), 17.6 fps, textures 1619 MB
    • PR: 4818 of 5037 MB, 95% (max 98%), 39.2 fps, textures 1560 MB, the render-target pool "VRAM short: given back" 5 times (never on main)
    • 1024 MB: 89% (max 92%), 30.7 fps but uneven (22.4 and 33.1)

    So your estimate was right: the PR takes this card to the edge of its allowance, with about 4% less held in textures. Nothing failed here, but this laptop is a best case (Optimus, it drives no desktop), and the description now says so. 1024 MB is listed as the alternative if you prefer the headroom. It gains less, and unevenly, because the pools are filled first come, first served. I'd keep the quarter, but it's your call: tell me and I'll switch 6 GB cards to 1024.

  3. 4 GB cards and the VRAM budget row. That was a real bug, thanks. c17b339 caps a budget chosen on the row itself at Auto's mirrors on a small card (small_card(), 4.5 GB or less), as a preset's already was. So a 4 GB card on the row's 3.6 GB step stays at 512 MB. tests/test_mirror_budget.cpp now checks that (and a smaller choice, and 6 and 8 GB cards on the row) instead of pinning 1536. One side effect: the row's 4.8 GB-and-up steps on a 4 GB card now also keep 512 (1024-3072 on main). That is said in What changed and Reviewer notes.

Should change

  • More cards. The Flags table now names the GTX 1060 6 GB and the RX 5600 XT on the Minimum tier, where Auto's rule applies (768 to 1536 MB), as untested, along with desktop 6 GB cards driving monitors.
  • AMD and desktop evidence. T-NWN5 (6 GB AMD or Intel) and T-9799 (4 GB) are claimable now that the label is on. Thanks.
  • Non-monotonic row. It's now stated as out of scope in What changed, with 8 GB cards on Auto or Balanced as the follow-up question.
  • Nit. The comment above mirror_on() now points to auto_bytes instead of saying "default 3072".

Also rebased onto main d964886 and pushed as 38c1a48. The title no longer says 1536 MB: a 6 GB card gets a quarter of what the driver reports, 1498 MB here.

Builds and checks:

  • run_all: 451 passed, 10 failed. The failures are the same as on main, plus test_menu_i18n, which fails on main d964886 itself.
  • The renderer builds with llvm-mingw on Windows, and in the Ubuntu 22.04 container on Linux with the small-card cap.
Thanks for the careful review, and for the rebase. Point by point: **Must change** 1. **Risk section.** You're right, and I've rewritten it. Nothing gives the mirrors' extra GB back when VRAM runs short: `mirrors_trim` only cuts the parts outside every game pool, and the 90% rule for mirrors is behind the opt-in `RX_VK_MIRROR_TIGHT`. It is the texture cache (its 90% rule and the compaction's hold at 85%) and the render-target pool that give way. The section now says "mirrors take the extra GB, and textures take the squeeze", names the worst case (a desktop 6 GB card with a small allowance, as in https://git.magicbean.dev/MagicBeanDev/Longshot/issues/130), and gives the switches to go back. 2. **Memory, and a run at the tier's own settings.** I made new runs on the Low (6GB) preset with its own settings (DLSS render size 1152x648, fixed in every run, no Auto step-down), alternated main fbd4202, this PR c17b339, and this PR at `RX_VK_MIRROR_MB=1024`, twice each. From the in-field `VRAM:` lines: - main: 4085 of 4998 MB, 82% (max 90%), 17.6 fps, textures 1619 MB - PR: 4818 of 5037 MB, 95% (max 98%), 39.2 fps, textures 1560 MB, the render-target pool "VRAM short: given back" 5 times (never on main) - 1024 MB: 89% (max 92%), 30.7 fps but uneven (22.4 and 33.1) So your estimate was right: the PR takes this card to the edge of its allowance, with about 4% less held in textures. Nothing failed here, but this laptop is a best case (Optimus, it drives no desktop), and the description now says so. 1024 MB is listed as the alternative if you prefer the headroom. It gains less, and unevenly, because the pools are filled first come, first served. I'd keep the quarter, but it's your call: tell me and I'll switch 6 GB cards to 1024. 3. **4 GB cards and the VRAM budget row.** That was a real bug, thanks. c17b339 caps a budget chosen on the row itself at Auto's mirrors on a small card (`small_card()`, 4.5 GB or less), as a preset's already was. So a 4 GB card on the row's 3.6 GB step stays at 512 MB. `tests/test_mirror_budget.cpp` now checks that (and a smaller choice, and 6 and 8 GB cards on the row) instead of pinning 1536. One side effect: the row's 4.8 GB-and-up steps on a 4 GB card now also keep 512 (1024-3072 on main). That is said in What changed and Reviewer notes. **Should change** - **More cards.** The Flags table now names the GTX 1060 6 GB and the RX 5600 XT on the Minimum tier, where Auto's rule applies (768 to 1536 MB), as untested, along with desktop 6 GB cards driving monitors. - **AMD and desktop evidence.** T-NWN5 (6 GB AMD or Intel) and T-9799 (4 GB) are claimable now that the label is on. Thanks. - **Non-monotonic row.** It's now stated as out of scope in What changed, with 8 GB cards on Auto or Balanced as the follow-up question. - **Nit.** The comment above `mirror_on()` now points to `auto_bytes` instead of saying "default 3072". Also rebased onto main d964886 and pushed as 38c1a48. The title no longer says 1536 MB: a 6 GB card gets a quarter of what the driver reports, 1498 MB here. Builds and checks: - `run_all`: 451 passed, 10 failed. The failures are the same as on main, plus `test_menu_i18n`, which fails on main d964886 itself. - The renderer builds with llvm-mingw on Windows, and in the Ubuntu 22.04 container on Linux with the small-card cap.
i12bp8 changed title from WIP: perf(vk): a 6 GB card mirrors a quarter of its VRAM, not an eighth or 512 MB to perf(vk): a 6 GB card mirrors a quarter of its VRAM, not an eighth or 512 MB 2026-11-13 18:41:33 +00:00
HumanBean left a comment

Re-review at 38c1a48. Code only: I didn't build it, run the tests or run the game.

Earlier points

  1. Risk section: addressed. It now says what the code does: the mirrors keep their budget, and the texture cache and the render-target pool give way. The same note is in mirror_budget.h.
  2. Memory, and a run at the tier's own settings: addressed. The new runs use Low's own DLSS 1152x648, alternate main, PR and 1024 MB, and report VRAM use, textures held, compactions and the render-target pool. The cost is now plain: 82% to 95% of the allowance, 98% at peak, on a best-case laptop. The eviction and re-upload counts I asked for aren't there (question below).
  3. The VRAM budget row on small cards: fixed in code. preset_bytes now caps a row choice at Auto's on a card of 4.5 GB or less. I checked the menu: picking a step on the row sets opts.budget = 0, and a preset sets it to the preset. So 4 GB cards are back to 512 on the 3.6 GB step, and the cards of 8 GB or more still get what they chose on the row. The side effect on the row's 4.8 GB and higher steps on a 4 GB card is stated. test_mirror_budget.cpp checks it now instead of pinning 1536.
  • More cards (GTX 1060 6 GB, RX 5600 XT on Minimum): addressed, named in the Flags table and under Not tested.
  • AMD or desktop 6 GB evidence: not yet. T-NWN5 and T-9799 are claimable now, but nobody has tested either one yet.
  • Non-monotonic row: addressed, stated as out of scope.
  • Nit on mirror_on(): addressed.

New since b2a011cf

  • The rebase is fine. Main's commits since fbd4202 don't touch mirror_budget(), preset_caps_memory(), device_vram_bytes() or kVramMirrorMb, so the reason given for keeping the fbd4202 numbers holds. The Measurements section names main @ and this PR @ hashes, and it says which hardware was measured and what the change costs elsewhere.
  • The checklist boxes hold, as far as I can read them off the diff and the description. The test_menu_i18n failure also happens on main.
  • Question: the quoted VRAM: lines show the textures' budget at 0 MB on both sides (textures 1706 MB (budget 0 MB) on main, 1486 MB (budget 0 MB) on the PR). Is that the commit-limit path (commit limit near lines) on this 16 GB PC? If so, system RAM sets the texture numbers at those moments, not VRAM, and "textures held" is a weak measure of the squeeze. The texture eviction and re-upload counts, main against PR, would settle it.
  • Suggestion for T-NWN5: ask the tester for the vk: VRAM: ... used of ... allowed lines and the render-target pool line too, not only fps and the mirrors. Also accept a desktop NVIDIA 6 GB card that drives a monitor (RTX 2060, 1660 Super). The risk is about memory, so fps alone won't show it.

1024 or a quarter

I'd keep the quarter. The 1024 runs gain less and unevenly (22.4 and 33.1), and the quarter's cost falls on the texture cache, which is built to give way. But 98% at peak on a laptop that drives no desktop is close. If a desktop 6 GB card's run shows device lost, heavy re-uploads or VRAM-full stutter, 6 GB cards should go to 1024.

Verdict

Comment, not approve yet. The code is right and every earlier point is addressed, except the one that needs hardware we don't have. I'll approve once T-NWN5 (or a desktop 6 GB run) comes back clean. If one has come back by then, please answer the question about the 0 MB budget too.

Re-review at 38c1a48. Code only: I didn't build it, run the tests or run the game. ## Earlier points 1. **Risk section:** addressed. It now says what the code does: the mirrors keep their budget, and the texture cache and the render-target pool give way. The same note is in `mirror_budget.h`. 2. **Memory, and a run at the tier's own settings:** addressed. The new runs use Low's own DLSS 1152x648, alternate main, PR and 1024 MB, and report VRAM use, textures held, compactions and the render-target pool. The cost is now plain: 82% to 95% of the allowance, 98% at peak, on a best-case laptop. The eviction and re-upload counts I asked for aren't there (question below). 3. **The VRAM budget row on small cards:** fixed in code. `preset_bytes` now caps a row choice at Auto's on a card of 4.5 GB or less. I checked the menu: picking a step on the row sets `opts.budget = 0`, and a preset sets it to the preset. So 4 GB cards are back to 512 on the 3.6 GB step, and the cards of 8 GB or more still get what they chose on the row. The side effect on the row's 4.8 GB and higher steps on a 4 GB card is stated. `test_mirror_budget.cpp` checks it now instead of pinning 1536. - **More cards (GTX 1060 6 GB, RX 5600 XT on Minimum):** addressed, named in the Flags table and under Not tested. - **AMD or desktop 6 GB evidence:** not yet. T-NWN5 and T-9799 are claimable now, but nobody has tested either one yet. - **Non-monotonic row:** addressed, stated as out of scope. - **Nit on `mirror_on()`:** addressed. ## New since b2a011cf - The rebase is fine. Main's commits since fbd4202 don't touch `mirror_budget()`, `preset_caps_memory()`, `device_vram_bytes()` or `kVramMirrorMb`, so the reason given for keeping the fbd4202 numbers holds. The Measurements section names `main @` and `this PR @` hashes, and it says which hardware was measured and what the change costs elsewhere. - The checklist boxes hold, as far as I can read them off the diff and the description. The `test_menu_i18n` failure also happens on main. - **Question:** the quoted `VRAM:` lines show the textures' budget at 0 MB on both sides (`textures 1706 MB (budget 0 MB)` on main, `1486 MB (budget 0 MB)` on the PR). Is that the commit-limit path (`commit limit near` lines) on this 16 GB PC? If so, system RAM sets the texture numbers at those moments, not VRAM, and "textures held" is a weak measure of the squeeze. The texture eviction and re-upload counts, main against PR, would settle it. - **Suggestion for T-NWN5:** ask the tester for the `vk: VRAM: ... used of ... allowed` lines and the render-target pool line too, not only fps and the mirrors. Also accept a desktop NVIDIA 6 GB card that drives a monitor (RTX 2060, 1660 Super). The risk is about memory, so fps alone won't show it. ## 1024 or a quarter I'd keep the quarter. The 1024 runs gain less and unevenly (22.4 and 33.1), and the quarter's cost falls on the texture cache, which is built to give way. But 98% at peak on a laptop that drives no desktop is close. If a desktop 6 GB card's run shows device lost, heavy re-uploads or VRAM-full stutter, 6 GB cards should go to 1024. ## Verdict Comment, not approve yet. The code is right and every earlier point is addressed, except the one that needs hardware we don't have. I'll approve once T-NWN5 (or a desktop 6 GB run) comes back clean. If one has come back by then, please answer the question about the 0 MB budget too.
@ -0,0 +30,4 @@
/// a small card at Auto's. Chosen on the VRAM budget row itself: the player's, except on a small card, where it is capped at Auto's
/// too (the row's 3.6 GB step on a 4 GB card was 512 MB before Low's mirrors went to 1536; its steps of 4.8 GB and more, past
/// what such a card has, now keep 512 as well)
inline uint64_t preset_bytes(uint64_t asked, bool by_preset, uint64_t vram) {
Owner

Nit: since c17b339 this also caps a budget chosen on the row (by_preset false, small card), so preset_bytes no longer says what it does. Something like budget_bytes would read better. Optional.

Nit: since c17b339 this also caps a budget chosen on the row (`by_preset` false, small card), so `preset_bytes` no longer says what it does. Something like `budget_bytes` would read better. Optional.
Author
First-time contributor

Pushed 091daa9: preset_bytes renamed budget_bytes (HumanBean's nit). Description: the 0 MB texture budget is the commit-limit path on this 16 GB PC on both sides; eviction counts added. T-NWN5 replaced by T-XFT3, which asks for the VRAM and render-target pool lines and accepts desktop NVIDIA 6 GB cards.

Pushed 091daa9: preset_bytes renamed budget_bytes (HumanBean's nit). Description: the 0 MB texture budget is the commit-limit path on this 16 GB PC on both sides; eviction counts added. T-NWN5 replaced by T-XFT3, which asks for the VRAM and render-target pool lines and accepts desktop NVIDIA 6 GB cards.
refactor(vk): mirror_budget.h's preset_bytes is budget_bytes: it caps a row's choice on a small card too
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 2s
091daa9505
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Author
First-time contributor

Thanks for the re-review.

The 0 MB texture budget: yes, it's the commit-limit path, on both sides. Every run, main and PR alike, logged commit limit near on this 16 GB PC (main 7 and 2 times, PR 3 and 4, 1024 MB 2 and 3). The least commit left was 495 MB on main and 575 MB on the PR, and that set the textures' budget to 0 MB at those moments. So, as you say, "textures held" doesn't measure the VRAM squeeze. The description now says that.

Evictions: the per-texture log (RX_VK_LOG_REMADE) was off in these runs, so I only have the always-on counter of evicted textures that were uploaded again from the game's memory:

  • main: 20 or more in run 1 (the counter's first 20 lines), 0 in run 2
  • PR: 0 and 0
  • 1024 MB: 0 and 0

So nothing points to the PR thrashing textures on this card. This laptop is still the best case, though, so the desktop run decides.

T-NWN5: replaced by T-XFT3, with your suggestions. It accepts a desktop NVIDIA 6 GB card that drives a monitor (RTX 2060, 1660 Super/Ti) as well as AMD and Intel. It asks for every VRAM: ... used of ... allowed line, the render-target pool lines, any commit limit near, device lost or VK_ERROR, and a run with RX_VK_LOG_REMADE=1. Its pass criteria are no device lost, no VRAM-full stutter, and VRAM under the allowance.

Nit: done in 091daa9. preset_bytes is now budget_bytes. run_all is unchanged: 451 passed, and the same 10 fail as on main.

Agreed on the fallback: if the desktop 6 GB run shows device lost, heavy re-uploads or VRAM-full stutter, I'll move 6 GB cards to 1024.

Thanks for the re-review. **The 0 MB texture budget:** yes, it's the commit-limit path, on both sides. Every run, main and PR alike, logged `commit limit near` on this 16 GB PC (main 7 and 2 times, PR 3 and 4, 1024 MB 2 and 3). The least commit left was 495 MB on main and 575 MB on the PR, and that set the textures' budget to 0 MB at those moments. So, as you say, "textures held" doesn't measure the VRAM squeeze. The description now says that. **Evictions:** the per-texture log (`RX_VK_LOG_REMADE`) was off in these runs, so I only have the always-on counter of evicted textures that were uploaded again from the game's memory: - main: 20 or more in run 1 (the counter's first 20 lines), 0 in run 2 - PR: 0 and 0 - 1024 MB: 0 and 0 So nothing points to the PR thrashing textures on this card. This laptop is still the best case, though, so the desktop run decides. **T-NWN5:** replaced by T-XFT3, with your suggestions. It accepts a desktop NVIDIA 6 GB card that drives a monitor (RTX 2060, 1660 Super/Ti) as well as AMD and Intel. It asks for every `VRAM: ... used of ... allowed` line, the render-target pool lines, any `commit limit near`, device lost or VK_ERROR, and a run with `RX_VK_LOG_REMADE=1`. Its pass criteria are no device lost, no VRAM-full stutter, and VRAM under the allowance. **Nit:** done in 091daa9. `preset_bytes` is now `budget_bytes`. `run_all` is unchanged: 451 passed, and the same 10 fail as on main. Agreed on the fallback: if the desktop 6 GB run shows device lost, heavy re-uploads or VRAM-full stutter, I'll move 6 GB cards to 1024.
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 2s
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
Some workflows are waiting to be reviewed.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'perf/low-vram-mirror-budget:i12bp8-perf/low-vram-mirror-budget'
git switch 'i12bp8-perf/low-vram-mirror-budget'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
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/Longshot!237
No description provided.