Skip to content

import: vk: small ranges the CPU reads back are bound in guest memory (upstream #1150) - #106

Draft
soltros wants to merge 1 commit into
mainfrom
upstream/pr-1150
Draft

soltros wants to merge 1 commit into
mainfrom
upstream/pr-1150

Conversation

@soltros

@soltros soltros commented Nov 10, 2026

Copy link
Copy Markdown
Owner

Longshot is preserving this upstream proposal for review. This draft is not an adopted or functionally verified fix.

Source: NotRexed/Hookshot#1150
Original contributor: azlekayn.
Original head: a5bee1bec1484c9e10f07a799ee5ae216414d0b8.
Exact source tree: 658db0e6700a1784757914a95e87031fb1fe9366.
Import parent: 7dbdcdc00889ccf038ad95c7481ad6e10397f8a5 (common ancestor with the migration base).

The source-tree checksum matches exactly. Original commits after the common ancestor are represented by one reconstructed import commit; source links and authorship are recorded. This snapshot can contain prerequisites beyond our migration base. Review its complete diff and overlapping proposals before merging.

Validation here: copying fidelity only. Platform builds, gameplay, functional behavior and the upstream author's claims have not been independently verified. Keep draft until reviewed, rebased and tested.

Original proposal

Draft: reworked after review. It still needs an NVIDIA retest before it can be considered.

What

A range the game invalidates to read (nvnMemoryPoolInvalidateMappedRange, nvnBufferInvalidateMappedRange) holds GPU results. From a range's first invalidate on, a binding wholly inside it is bound in guest memory instead of the VRAM mirror, and the guest page table points there too. Ranges are rounded to pages.

  • A written direct binding calls wb_pages_note, so the CPU's read still waits for that submission.
  • Only ranges up to 64 KB go direct. A binding that only partly overlaps a range stays mirrored.
  • Write-backs are not cut. Mirror bindings keep their write-backs.
  • A retired pool's ranges and pages are dropped, and their slots are reused.

RX_VK_RB_DIRECT=0 restores the old behaviour. It only applies when mirrors are on.

Measurements

RX 7800 XT, RADV (Mesa 26.2.6), Ryzen 7 7800X3D, Linux, ~2150-draw Kokiri Forest balcony view, default settings, base 7dbdcdc. Only the renderer .so differs, runs were alternated, and frames were presented through a headless weston on the same GPU.

build fps per run big flashes brightness spikes over 2%
main (RX_VK_RB_DIRECT=0) 51.3, 51.6, 49.9 0 0
this PR 56.9, 54.2, 54.2 0 0

A 4-minute run averaged 54.7 fps over 13,146 frames with 0 flashes and no device loss. Direct bindings average 3.4 KB, against about 400 KB in the first version. The spike count takes every frame's mean brightness. With the read-back wait removed (RX_VK_NO_READBACK_WAIT=1) it reports 270-360 spikes a minute, so it can see the bug.

Limits

  • NVIDIA is untested and may still be slow. The first version made the GPU 13-18x slower on NVIDIA/Windows, per the reports below. The cap removes the large bindings, but if the cost comes from shaders reaching even small ranges in imported memory, this version will still be slow there.
  • One scene on one AMD GPU on Linux. The spike count is from a static view.
  • Up to 512 ranges at a time. Past that, a range stays mirrored and is logged once.
  • If fix(vulkan): track writes from direct buffer bindings NotRexed/Hookshot#1133 lands first, this early return needs its direct_write_epoch update.

Tests

tests/test_rb_direct.py checks which bindings go direct, the range list's limits and reuse, and (from the source) the read-back wait, the size cap and the pool retirement. tests/run_all.py has the same two failures as main (nx2/test_nup_read_name.py and the byte-compile step), plus this test passing.

🤖 Generated with Claude Code

Source: NotRexed/Hookshot#1150
Original proposal by: azlekayn
Original head: a5bee1bec1484c9e10f07a799ee5ae216414d0b8
Verified source tree: 658db0e

Reconstructed import commit, not a claim of original authorship.
Source head author: AzleKayn <azlekayn@gitlab.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