Skip to content

perf(vk): 6 GB cards mirror a quarter of the card (1536 MB), on Auto and on the Low preset - #2834

Open
i12bp8 wants to merge 3 commits into
NotRexed:mainfrom
i12bp8:perf/low-vram-laptop-image-pool
Open

i12bp8 wants to merge 3 commits into
NotRexed:mainfrom
i12bp8:perf/low-vram-laptop-image-pool

Conversation

@i12bp8

@i12bp8 i12bp8 commented Nov 12, 2026 •

Copy link
Copy Markdown

6 GB cards (the RTX 3060 Laptop, 2060, 1660 and the like) start on the Low preset, whose 512 MB of mirrors leaves most of the game's memory pools out of VRAM: the GPU reads them over PCIe, 30-32 GB of bound ranges every 600 submits in Hyrule Field on an RTX 3060 Laptop. This gives those cards a quarter of the card, 1536 MB, on Low and on Auto alike: in Castle Town Market 20 → 22.4 fps, GPU 32 → 25 ms a frame, half the frames over 50 ms.

What changed

  • The VRAM budget row's 3.6 GB step mirrors 1536 MB, not 512 (gpu/vk/vk_menu.cpp). It is the Low (6GB) preset's, which menu_first_start_for_gpu gives every dedicated card of 4.5-6.5 GB.
  • Auto agrees (gpu/vk/mirror_budget.h, auto_bytes, used by mirror_budget in vk_memory.cpp): cards over 4.5 GB and up to 6.5 GB get a quarter (1536 MB on 6 GB; it was an eighth, 768). Cards of 4.5 GB or less keep an eighth (512 MB on 4 GB), larger ones a quarter up to 3 GB as before. The eighth on 6 GB cards was there because the image blocks made at the start sat empty beside the mirrors; since fix(vk): make the blocks at the start in the pool the textures are made in (#2690) #2711 they are made in the textures' pool.
  • A preset's mirrors never pass Auto's on the card (preset_bytes, when a Quality preset set the budgets): Low on a 4 GB card, which preset_caps_memory lets through, or Minimum with the row moved to 3.6 GB, stays at 512. A budget chosen on the VRAM budget row itself stays the player's on any card (feat(menu): a VRAM budget row of its own (builds on #1358) #1859).
  • tests/test_mirror_budget.py runs the rules and checks that mirror_budget uses them; tests/test_vram_budget_row.py has Low's 1536. docs/development.md says what RX_VK_MIRROR_MB defaults to.

Tested

Windows 11, RTX 3060 Laptop 6 GB (5.0-5.1 GB allowed), NVIDIA 621.14, Ryzen 7 6800HS, 16 GB. The first start's Low (6GB) budget, DLSS (1152x648 → 1536x864), Reflex on, Game speed Per frame (HOS_REALTIME_STEP=0). No window (HOS_HEADLESS), input through the control bridge: the debug teleport, then standing with the camera turning for 60 s. A = 51da046 + #2711, B = that + this; both renderers built with llvm-mingw (RX_VK_ONLY, RX_RELEASE=1, NVIDIA DLSS). main's own renderer (API 20, a new translator stamp) does not run against this PC's game and program cache, so the base is the installed build's plus #2711. Two runs each, in turn:

A B
Castle Town Market fps 20.2, 20.1 22.5, 22.3
GPU ms a frame 31.4, 33.5 24.6, 25.2
frames over 50 ms 1252, 1287 571, 616
driver's count at most / allowed (MB) 4669 / 5096, 4671 / 5064 5039 / 5096, 5233 / 5099
textures' budget (held) 1.98 (2.25), 1.99 (2.31) GB 1.08 (1.86), 1.03 (1.90) GB
textures made again empty 0, 3 0, 3
Hyrule Field fps 28.8, 29.3 29.1, 32.3
GPU ms a frame 24.0, 23.5 21.0, 18.7
frames over 50 ms 165, 134 34, 148
driver's count at most / allowed (MB) 5469 / 5039, 5359 / 5039 4988 / 5097, 4982 / 5103
textures' budget (held) 2.67 (1.82), 3.00 (1.89) GB 0.87 (1.29), 0.88 (1.29) GB
textures made again empty 6, 4 11, 11

The cost is the textures' budget: about 1 GB in the market and under 0.9 GB in Hyrule Field, where twice as many textures were made again in 60 s (headless: not looked at on screen). Earlier, on a scripted walk (main before #2711, the preallocation off by switch): 1536 MB took ~0 GB over PCIe every 600 submits against 30-32 GB, GPU 27 → 19.5 ms; 1024 MB gave 26.5 and 31.3 fps with the budget full and which pools stayed out varying.

  • No device lost, no new error lines; the program cache kept (47866 keys).
  • python -I -B tests/run_all.py on Windows: 472 passed, 10 failed, 41 skipped. The same 10 fail on main on this PC (symlink privilege, dotnet restore, no gcc, and test_readme_menu_rows: the Skip opening row has no README line).
  • Rows in docs/tested-configurations.md.
  • Nothing on screen changes: no screenshots.

Not tested: another 6 GB card (a desktop one with a display attached has less allowed), AMD (GCN keeps its mirrors off) and Intel, Linux, 4 GB cards (the cap keeps them at 512).

Overlap

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings November 12, 2026 15:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@i12bp8
i12bp8 force-pushed the perf/low-vram-laptop-image-pool branch from f0a61fd to a620ba1 Compare November 12, 2026 17:59
i12bp8 added a commit to i12bp8/Hookshot that referenced this pull request Nov 12, 2026
…irrors never pass Auto's

Review of NotRexed#2834: Low's 1536 MB and Auto's 768 MB disagreed on the same
6 GB card, and preset_caps_memory lets Low's budgets through on cards up
to 6.75 GB, so a 4 GB card on Low (or on Minimum with the row at 3.6
GB) would have asked for 1.5 GB of mirrors where it had 512.

gpu/vk/mirror_budget.h holds the rule, apart from Vulkan:
- auto_bytes: a quarter of the card, at most 3 GB, as before above
  6.5 GB; an eighth on cards of 4.5 GB or less (512 MB on 4 GB), as
  before; a quarter between (1536 MB on 6 GB, was an eighth). The
  eighth there was for the empty image blocks the images' pool made at
  the start, which NotRexed#2711 now makes in the textures' pool.
- preset_bytes: a Quality preset's mirrors never more than Auto's on
  the card. A budget chosen on the VRAM budget row itself stays the
  player's on any card.

tests/test_mirror_budget.py runs the rules and checks that
mirror_budget uses them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
i12bp8 added a commit to i12bp8/Hookshot that referenced this pull request Nov 12, 2026
 with NotRexed#2834, Hyrule Field and Castle Town Market

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@i12bp8
i12bp8 force-pushed the perf/low-vram-laptop-image-pool branch from a620ba1 to 45cec91 Compare November 12, 2026 18:03
i12bp8 added a commit to i12bp8/Hookshot that referenced this pull request Nov 12, 2026
…irrors never pass Auto's

Review of NotRexed#2834: Low's 1536 MB and Auto's 768 MB disagreed on the same
6 GB card, and preset_caps_memory lets Low's budgets through on cards up
to 6.75 GB, so a 4 GB card on Low (or on Minimum with the row at 3.6
GB) would have asked for 1.5 GB of mirrors where it had 512.

gpu/vk/mirror_budget.h holds the rule, apart from Vulkan:
- auto_bytes: a quarter of the card, at most 3 GB, as before above
  6.5 GB; an eighth on cards of 4.5 GB or less (512 MB on 4 GB), as
  before; a quarter between (1536 MB on 6 GB, was an eighth). The
  eighth there was for the empty image blocks the images' pool made at
  the start, which NotRexed#2711 now makes in the textures' pool.
- preset_bytes: a Quality preset's mirrors never more than Auto's on
  the card. A budget chosen on the VRAM budget row itself stays the
  player's on any card.

tests/test_mirror_budget.py runs the rules and checks that
mirror_budget uses them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
i12bp8 added a commit to i12bp8/Hookshot that referenced this pull request Nov 12, 2026
 with NotRexed#2834, Hyrule Field and Castle Town Market

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@i12bp8 i12bp8 changed the title perf(vk): 6 GB cards mirror the game's memory in the VRAM the images' pool held empty perf(vk): 6 GB cards mirror a quarter of the card (1536 MB), on Auto and on the Low preset Nov 12, 2026
i12bp8 and others added 3 commits November 12, 2026 19:05
…, not 512

Every 6 GB card starts on the Low (6GB) preset, whose 512 MB of mirrors
left most of the game's memory pools out of VRAM: the GPU read them
over PCIe and the game's readbacks waited for whole submissions.

RTX 3060 Laptop (6 GB), Hyrule Field, a scripted walk, two runs each:
30-32 GB of bound ranges read over PCIe every 600 submits at 512 MB,
~0 at 1536. Main: 25.4, 25.4 fps, GPU 26.7-27.2 ms a frame, 525-645
frames over 50 ms. With this and the commit before (a build of them,
no switches): 30.1, 31.8 fps, GPU 18.4-19.1 ms, 161-285 frames over
50 ms, VRAM at most 5.7-5.8 GB against 5.9. 1024 MB was not enough:
26.5 and 31.3 fps, the budget full and which pools stayed out varying.

The row's 3.6 GB step (the Low preset's) only: a preset's budget
applies on the card it is for (preset_caps_memory). The 1.5 GB comes
out of what the images' pool no longer holds empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…irrors never pass Auto's

Review of NotRexed#2834: Low's 1536 MB and Auto's 768 MB disagreed on the same
6 GB card, and preset_caps_memory lets Low's budgets through on cards up
to 6.75 GB, so a 4 GB card on Low (or on Minimum with the row at 3.6
GB) would have asked for 1.5 GB of mirrors where it had 512.

gpu/vk/mirror_budget.h holds the rule, apart from Vulkan:
- auto_bytes: a quarter of the card, at most 3 GB, as before above
  6.5 GB; an eighth on cards of 4.5 GB or less (512 MB on 4 GB), as
  before; a quarter between (1536 MB on 6 GB, was an eighth). The
  eighth there was for the empty image blocks the images' pool made at
  the start, which NotRexed#2711 now makes in the textures' pool.
- preset_bytes: a Quality preset's mirrors never more than Auto's on
  the card. A budget chosen on the VRAM budget row itself stays the
  player's on any card.

tests/test_mirror_budget.py runs the rules and checks that
mirror_budget uses them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
 with NotRexed#2834, Hyrule Field and Castle Town Market

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@i12bp8
i12bp8 force-pushed the perf/low-vram-laptop-image-pool branch from 45cec91 to 14b92e2 Compare November 12, 2026 18:06
@i12bp8

i12bp8 commented Nov 12, 2026

Copy link
Copy Markdown
Author

Thanks for the review. Updated:

#2711 alone (A) against #2711 + this (B), RTX 3060 Laptop, Low, DLSS, standing with the camera turning for 60 s, two runs each in turn. Built on 51da046 + #2711: main's renderer is API 20 with a new translator stamp, which this PC's game and program cache don't take.

A B
Castle Town Market fps 20.2, 20.1 22.5, 22.3
GPU ms a frame 31.4, 33.5 24.6, 25.2
frames over 50 ms 1252, 1287 571, 616
driver's count at most / allowed (MB) 4669 / 5096, 4671 / 5064 5039 / 5096, 5233 / 5099
textures' budget (held) 1.98 (2.25), 1.99 (2.31) GB 1.08 (1.86), 1.03 (1.90) GB
textures made again empty 0, 3 0, 3
Hyrule Field fps 28.8, 29.3 29.1, 32.3
GPU ms a frame 24.0, 23.5 21.0, 18.7
frames over 50 ms 165, 134 34, 148
driver's count at most / allowed (MB) 5469 / 5039, 5359 / 5039 4988 / 5097, 4982 / 5103
textures' budget (held) 2.67 (1.82), 3.00 (1.89) GB 0.87 (1.29), 0.88 (1.29) GB
textures made again empty 6, 4 11, 11

You were right that the textures' budget is what gives: about 1 GB in the market and under 0.9 GB in Hyrule Field, where twice as many textures were made again (11 against 4-6 in 60 s; headless, so I haven't looked at them on screen). The market, the heavier spot, is the clearer win: +11% fps, GPU -24%, half the long frames, no more textures made again. With #2711 alone the driver's count went past the allowance in Hyrule Field (5.36-5.47 of 5.04 GB); with this it stayed under there and reached it in the market.

Not done: another 6 GB card, or AMD. I can't run those here; a tester with a 2060, a 1660 or an RX 5600 XT on the same two spots would settle it. If the texture side needs holding back, the two things I'd measure next are RX_VK_MIRROR_TIGHT on for these cards, or 1024 MB (26.5 and 31.3 fps on my first walk, with the budget full and which pools stayed out varying).

@i12bp8
i12bp8 requested a review from hckrman101 November 12, 2026 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants