Skip to content

texture_cache: let large cards fill 5/8 of their memory budget before collecting - #268

Merged
capy-ai[bot] merged 1 commit into
zortos293:nx2from
atk3001:pr/tc-budget-cap
Nov 8, 2026
Merged

capy-ai[bot] merged 1 commit into
zortos293:nx2from
atk3001:pr/tc-budget-cap

Conversation

@atk3001

@atk3001 atk3001 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Changes

texture_cache: on GPUs with a large memory budget, the collector's critical threshold is now 5/8 of the driver's budget instead of a fixed 5 GiB. It never goes below 5 GiB.

4d8a962 capped the threshold at 5 GiB on every GPU so that Mario Kart World (0400C3F00006E000) would stop filling 8 GB cards. On a 16 GB card, its races then sit at that cap. In every 600 frames the collector evicts ~4400 images, ~4100 are created again and uploaded from guest memory (5 GiB, almost all screen-sized render targets such as 1688×948 and 834×468), and texture upload takes ~120 ms of each second on the GPU back thread (218 µs per upload).

  • The cap is max(5 GiB, budget * 5/8). With an 8 GB card (budget ~7 GB) it stays at 5 GiB, so the case 4d8a962 fixed is unchanged.
  • It uses GetDeviceMemoryBudget(), not GetDeviceLocalMemory(): the latter is capped near 6 GiB plus the resolution scaler's share, so 5/8 of it never exceeds 5 GiB.
  • The budget tracking that keeps the thresholds below the budget (margin, out-of-memory and block-slack reserves) and the EDEN_NX2_TC_*_MIB overrides work as before.

Testing

Build checks:

  • Windows, MSVC 14.50, Release: builds. Built on a local branch that has this commit on top of nx2 55532f2 plus other open PRs; this branch is the same commit cherry-picked onto nx2 without conflicts.
  • git diff --check: clean.
  • Not run: unit tests (local build has YUZU_TESTS=OFF), clang or Linux builds.

Gameplay (Mario Kart World, Time Trial → Wario Stadium → watching the staff ghost, 37 s of the race; RTX 5080 16 GB, driver 616.64; 2 runs each):

fps p90 p99 GPU back thread per frame
before 53.0 / 52.9 26.7 ms 45 ms 13.1 ms
after (critical 9505 MiB) 58.6 / 58.7 18.4 ms 30 ms 11.0 ms
before + EDEN_NX2_TC_CRITICAL_MIB=10240 59.4 / 59.2 18.1 ms 27 ms 10.9 ms
after, 8 GB card simulated (EDEN_NX2_VRAM_LIMIT_MIB=8192) 53.0 / 53.0 26.1 ms 44 ms 13.1 ms
  • With the simulated 8 GB card the threshold stays at 5120 MiB and no out-of-memory warning is logged.
  • Screenshots during the race show no missing or garbage textures. Also played by hand on this build: no issues found.
  • Not tested: real 8–12 GB cards, AMD and Intel GPUs, and long sessions with many track changes.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements
    • Critical texture memory thresholds now account for the driver-reported device-memory budget on supported systems. For graphics cards with more than 8 GiB, the threshold may scale to five-eighths of the reported budget, subject to the existing threshold. Expected and minimum memory calculations remain unchanged.

@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The critical-memory threshold now uses a ceiling based on MaxCriticalMemory and, when available, five-eighths of the reported device memory budget. Comments describe the threshold behavior for cards up to and above 8 GiB.

Changes: Texture cache memory threshold

Layer / File(s) Summary
Critical-memory ceiling
src/video_core/texture_cache/texture_cache.h, src/video_core/texture_cache/texture_cache_base.h
ApplyThresholdOverrides sets the ceiling to the greater of MaxCriticalMemory and five-eighths of the device memory budget when that budget is available. It caps critical_memory at the lower of this ceiling and its existing value. Comments describe the threshold for cards up to 8 GiB and larger cards.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related issues

Possibly related PRs

  • zortos293/Lichii#573 — Both PRs change the critical-memory cap in ApplyThresholdOverrides based on GetDeviceMemoryBudget(). The other PR uses three-fifths of the budget; this PR uses five-eighths.

Suggested reviewers: camillelavey, takoroka

Merge Risk: Minimal · up to 33c51

The change raises the texture cache's critical collection threshold on larger-memory GPUs while keeping the 5 GiB value where no budget is reported. No concrete merge-blocking risk remains. Wider hardware testing on 8–12 GB cards, AMD and Intel GPUs, and long sessions is still outstanding, but that is normal validation rather than an identified defect.

Pre-merge checks: Passed 5

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the primary change: the texture cache critical-collection threshold on large cards now allows 5/8 of the device-memory budget before collecting. The raw summary confirms that ApplyThre…
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the primary change: the texture cache critical-collection threshold on large cards now allows 5/8 of the device-memory budget before collecting. The raw summary confirms that ApplyThresholdOverrides caps critical_memory using five-eighths of the driver's device-memory budget when available, with MaxCriticalMemory as the floor, and that the DEFAULT_CRITICAL_MEMORY comment was updated to match. The title is specific and concise, and it does not describe anything absent from the changeset.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 2 files.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 670c2c6d-9207-48e9-9024-f8a2244a33ab
Commits

Reviewing files that changed from the base of the PR and between 4262a99 and 33c51d2.

Files selected for processing: 2

  • src/video_core/texture_cache/texture_cache.h
  • src/video_core/texture_cache/texture_cache_base.h
Files skipped from review as they are similar to previous changes: 1

  • src/video_core/texture_cache/texture_cache_base.h

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

sexyboomer888-gif added a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 6, 2026
… collecting

From upstream PR zortos293#268 (4262a99).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QUZ8rZ57CNjfLaMPNXV3UU
sexyboomer888-gif added a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 6, 2026
From upstream PR zortos293#268 (4262a99).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QUZ8rZ57CNjfLaMPNXV3UU
ENPFakeDeveloper added a commit to ENPFakeDeveloper/Lichii that referenced this pull request Nov 6, 2026
ENPFakeDeveloper added a commit to ENPFakeDeveloper/Lichii that referenced this pull request Nov 6, 2026
github-actions Bot pushed a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 7, 2026
… collecting

From upstream PR zortos293#268 (4262a99).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QUZ8rZ57CNjfLaMPNXV3UU
(cherry picked from commit b67c4b7)
github-actions Bot pushed a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 7, 2026
From upstream PR zortos293#268 (4262a99).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QUZ8rZ57CNjfLaMPNXV3UU
(cherry picked from commit 9d32141)
conongnang added a commit to conongnang/Lichii that referenced this pull request Nov 7, 2026
… collecting (zortos293#268)

Port of zortos293#268 by atk3001.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sexyboomer888-gif added a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 7, 2026
github-actions Bot pushed a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 7, 2026
sexyboomer888-gif added a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 8, 2026
github-actions Bot pushed a commit to sexyboomer888-gif/Lichii that referenced this pull request Nov 8, 2026
… collecting

4d8a962 capped the collector's critical threshold at 5 GiB on every GPU. On a 16 GB card
Mario Kart World's races then sit at the cap: the collector evicts render targets every frame,
which are recreated and uploaded from guest memory again (~4100 uploads, 5 GiB per 600 frames).
The cap is now 5/8 of the driver's memory budget, at least 5 GiB, so cards up to 8 GB are
unchanged. GetDeviceLocalMemory is not used: it is capped near 7 GiB.

Mario Kart World, Wario Stadium staff ghost replay, RTX 5080 (16 GB, critical 9.3 GiB), 2 runs:
53.0 -> 58.7 fps, p90 26.7 -> 18.4 ms, p99 45 -> 30 ms, GPU back thread 13.1 -> 11.0 ms a frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@capy-ai
capy-ai Bot force-pushed the pr/tc-budget-cap branch from 4262a99 to 33c51d2 Compare November 8, 2026 08:37
@capy-ai
capy-ai Bot merged commit 69695aa into zortos293:nx2 Nov 8, 2026
4 checks passed
Mtbolanos pushed a commit to Mtbolanos/Lichii that referenced this pull request Nov 8, 2026
… collecting (zortos293#268)

4d8a962 capped the collector's critical threshold at 5 GiB on every GPU. On a 16 GB card
Mario Kart World's races then sit at the cap: the collector evicts render targets every frame,
which are recreated and uploaded from guest memory again (~4100 uploads, 5 GiB per 600 frames).
The cap is now 5/8 of the driver's memory budget, at least 5 GiB, so cards up to 8 GB are
unchanged. GetDeviceLocalMemory is not used: it is capped near 7 GiB.

Mario Kart World, Wario Stadium staff ghost replay, RTX 5080 (16 GB, critical 9.3 GiB), 2 runs:
53.0 -> 58.7 fps, p90 26.7 -> 18.4 ms, p99 45 -> 30 ms, GPU back thread 13.1 -> 11.0 ms a frame.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 69695aa)
pavelgajdo pushed a commit to pavelgajdo/Hokkaido that referenced this pull request Nov 8, 2026
… collecting (zortos293#268)

4d8a962 capped the collector's critical threshold at 5 GiB on every GPU. On a 16 GB card
Mario Kart World's races then sit at the cap: the collector evicts render targets every frame,
which are recreated and uploaded from guest memory again (~4100 uploads, 5 GiB per 600 frames).
The cap is now 5/8 of the driver's memory budget, at least 5 GiB, so cards up to 8 GB are
unchanged. GetDeviceLocalMemory is not used: it is capped near 7 GiB.

Mario Kart World, Wario Stadium staff ghost replay, RTX 5080 (16 GB, critical 9.3 GiB), 2 runs:
53.0 -> 58.7 fps, p90 26.7 -> 18.4 ms, p99 45 -> 30 ms, GPU back thread 13.1 -> 11.0 ms a frame.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 69695aa)
pavelgajdo added a commit to pavelgajdo/Hokkaido that referenced this pull request Nov 8, 2026
Three upstream changes trade memory for speed on PCs. On a phone the GPU
shares RAM with the game and Android's low-memory killer, so keep the
previous behaviour there:

- Cold guest memory is still paged out with MADV_PAGEOUT (zram only)
  instead of MADV_COLD (zortos293#756).
- Idle upload staging buffers of 16 MiB and up are still freed (zortos293#778
  keeps two per level up to 32 MiB).
- The texture cache's collect threshold stays capped at 5 GiB instead
  of 5/8 of the driver's budget (zortos293#268).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DahBard pushed a commit to DahBard/Lichii that referenced this pull request Nov 8, 2026
Upstream's final versions replace the earlier copies tuned4 carried: zortos293#816 (store extent; the
Cap64K mark mode goes), zortos293#815 and zortos293#591 (pipeline cache: a key's first record is built, exact
duplicates and incomplete records are removed from the file, which replaces round 16's
newest-record retry and failed-record set), zortos293#817 and zortos293#818 (join copies that write a whole
image; StalePages), zortos293#778 (Fritchii v4 imports: storage-pointer texture handles and idle staging
buffers without a switch, per-engine switch reads), zortos293#268 (collect from 5/8 of the VRAM budget),
zortos293#621, zortos293#687, zortos293#488. Kept from tuned4: the record conversions for other drivers and dynamic state
forms, the vertex attribute keys (zortos293#408), now deduplicated in memory only so the file keeps
every record other builds key apart, EXP8's copy-overwrite skip, banded untiles and no cold
hints, batched collector downloads, the front's write tracking and mixed macro reads, the host
pacer's genlock beside zortos293#655's timer pacing, and the raw Dynamic FPS step, applied now to zortos293#655's
FPS Unlock patch too (it shares the routine's head). Upstream zortos293#841 builds task/mesh records
without VK_EXT_mesh_shader, so their drop goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RqR9236AYzEMch9rerR4iU
notquiteog pushed a commit to notquiteog/Elysium that referenced this pull request Nov 8, 2026
… collecting

The collector's critical threshold was capped at 5 GiB on every GPU. On a 16 GB
card Mario Kart World's races then sit at the cap: the collector evicts render
targets every frame, which are recreated and uploaded from guest memory again
(~4100 uploads, 5 GiB per 600 frames). The cap is now 5/8 of the driver's
memory budget, at least 5 GiB, so cards up to 8 GB are unchanged.
GetDeviceLocalMemory is not used: it is capped near 7 GiB.

Cherry-picked from Lichii's 69695aa53e (zortos293/Lichii#268), authorship kept.
Its measured result, Mario Kart World, Wario Stadium staff ghost replay, RTX
5080 (16 GB, critical 9.3 GiB), 2 runs: 53.0 -> 58.7 fps, p90 26.7 -> 18.4 ms,
p99 45 -> 30 ms, GPU back thread 13.1 -> 11.0 ms a frame.

Verified against our tree before taking: runtime.GetDeviceMemoryBudget() is
already what TickFrame follows the driver's budget with, through the same
`if constexpr (requires ...)` guard, so the null-runtime instantiations are
unaffected. Our ApplyThresholdOverrides has no budget_critical/budget_expected
locals the upstream context shows; nothing else in the hunk depended on them.

Not covered by a test: TextureCache<P> needs a full runtime, image and
framebuffer trait set to instantiate, and a mock built for this would only
restate the two lines of arithmetic. Builds clean and 919 test cases pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
anthonyloukinas pushed a commit to anthonyloukinas/Lichii that referenced this pull request Nov 9, 2026
… collecting (zortos293#268)

4d8a962 capped the collector's critical threshold at 5 GiB on every GPU. On a 16 GB card
Mario Kart World's races then sit at the cap: the collector evicts render targets every frame,
which are recreated and uploaded from guest memory again (~4100 uploads, 5 GiB per 600 frames).
The cap is now 5/8 of the driver's memory budget, at least 5 GiB, so cards up to 8 GB are
unchanged. GetDeviceLocalMemory is not used: it is capped near 7 GiB.

Mario Kart World, Wario Stadium staff ghost replay, RTX 5080 (16 GB, critical 9.3 GiB), 2 runs:
53.0 -> 58.7 fps, p90 26.7 -> 18.4 ms, p99 45 -> 30 ms, GPU back thread 13.1 -> 11.0 ms a frame.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 69695aa)
Frizti pushed a commit to Frizti/Fritchii that referenced this pull request Nov 9, 2026
… collecting

Hand port of zortos293#268 (squash merge 69695aa on zortos nx2), by atk3001.

4d8a962 capped the collector's critical threshold at 5 GiB on every GPU. On a 16 GB card
Mario Kart World's races then sit at the cap: the collector evicts render targets every frame,
which are recreated and uploaded from guest memory again (~4100 uploads, 5 GiB per 600 frames).
The cap is now 5/8 of the driver's memory budget, at least 5 GiB, so cards up to 8 GB are
unchanged. GetDeviceLocalMemory is not used: it is capped near 7 GiB.

Upstream: Mario Kart World, Wario Stadium staff ghost replay, RTX 5080 (16 GB, critical
9.3 GiB), 2 runs: 53.0 -> 58.7 fps, p90 26.7 -> 18.4 ms, p99 45 -> 30 ms.

Port notes: only the cap changed. Upstream's function also clamps the EDEN_NX2_TC_*_MIB
overrides to the device budget (a separate change we don't have); ours keep setting the
thresholds outright after the cap, as before. The new cap only differs from 5 GiB when
budget * 5/8 > 5 GiB (budget above 8 GiB), so cards up to 8 GB and integrated GPUs (budget
capped at 4-6 GiB) keep today's behaviour.

(cherry picked from commit 69695aa, hand-applied)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Frizti added a commit to Frizti/Fritchii that referenced this pull request Nov 9, 2026
…zortos293#268 (5/8 VRAM budget on >8 GiB cards), zortos293#337 (fence-flagged reports, EXP33 off), zortos293#779 (HMMA on Intel Xe2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant