Skip to content

vk: descriptor slotgen and sampler cache - #1330

Merged
hckrman101 merged 1 commit into
NotRexed:mainfrom
bibigurl-yum:pr/vk-descriptor-slotgen
Nov 10, 2026
Merged

hckrman101 merged 1 commit into
NotRexed:mainfrom
bibigurl-yum:pr/vk-descriptor-slotgen

Conversation

@bibigurl-yum

@bibigurl-yum bibigurl-yum commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

What

Replay-thread optimizations for descriptor and sampler resolution, default off and switchable by menu row and environment variable (one shared code path).

1. Descriptor slotgen (RX_VK_DESC_SLOTGEN=1, menu: Graphics → Descriptor reuse)

Descriptor reuse currently keys on the global registrations' generation, so any texture registration anywhere (the game streams constantly) rebuilds every draw's descriptors. A draw now keeps its descriptors while the texture slots it actually samples are unchanged: the build records (slot, version) for every handle it resolved and the same draw revalidates by slot version instead of the global generation. Draws that sampled an unregistered slot keep the old global-generation check (a registration is the only thing that could make such a handle resolve). An eviction sweep (destroy_later) retires views behind the slots' backs without bumping any slot or sampler version, so the keep-check revalidates texture_destroy_generation() as well — this also covers the texture_view_of staleness question.

2. Sampler cache (RX_VK_SAMPLER_CACHE, menu: Graphics → Sampler cache)

Each texture of each draw resolved its sampler through reg_mu + a copy of the registration + hash + map lookup (~48k times per frame at 3000 draws). Sampler ids now answer from a per-thread table keyed on the id's slot version (the samp_versions table in vk_bank, like the texture slots' slot_versions): resolving an id that was not registered anew takes no lock. One switch, documented at the declaration: RX_VK_SAMPLER_CACHE=0 turns off both the outer id table and the inner parameters' cache; =1 or the menu row turns the inner cache on (the outer table stays on, exactly as it is without the option — so the menu row never silently changes the old default-on path).

Measurements (RTX 4090, 5120x1440, TOTK)

Same binary, environment variables off = the old path (A/B identity):

replay ms/frame peak RSS
items 1 + 2 on 4.64 ms 11.6 GB
items 1 + 2 off 11.87 ms 43.6 GB

(median "a frame's replay time" over 240 s scripted gameplay runs, ~3200 draws/frame; the replay thread is the fps ceiling — at 1000/4.64 ms it moves from ~84 to ~215 fps of headroom. Item-2-alone numbers follow in a comment.)

Response to the review

  • Eviction: texture_destroy_generation() now participates in the slotgen keep-check, so a destroy_later sweep invalidates the kept descriptors on its own.
  • seen map in sampler_make: dropped the unreachable size() > 4096 clear (ids are < 4096, the map cannot outgrow them).
  • Rebased on current main; merged with the mesh-fallback descriptor fix (vk: bring back #640 with mesh stages kept on mesh-shader GPUs #792) in draw().

@bibigurl-yum
bibigurl-yum force-pushed the pr/vk-descriptor-slotgen branch from 6460cd5 to 452e4f3 Compare November 9, 2026 22:08
bronze-ff added a commit to bronze-ff/Hookshot that referenced this pull request Nov 9, 2026
Leave option 10 free for the Frame rate row in NotRexed#1330.

Assisted-by: OpenAI Codex

Co-authored-by: Codex <codex@openai.com>
…s while the slots it samples are unchanged, and sampler ids answer their parameters without the registrations' lock
@bibigurl-yum
bibigurl-yum force-pushed the pr/vk-descriptor-slotgen branch from c7acdca to 9861144 Compare November 9, 2026 23:24
@bibigurl-yum bibigurl-yum changed the title vk: descriptor slotgen and sampler cache, and the Frame rate row vk: descriptor slotgen and sampler cache Nov 9, 2026
@bibigurl-yum

Copy link
Copy Markdown
Contributor Author

Split as requested: this PR is now only the slotgen + sampler cache (rebased on current main, merged with the #792 fallback fix in draw()); the Frame rate row is #1367.

Your points, in this branch:

  • Eviction / texture_view_of staleness: the keep-check now also revalidates texture_destroy_generation() — a destroy_later sweep bumps only that, so kept descriptors cover it. last_desc_* needs no reset across a sweep for the same reason: the versions the keep-check reads (texture_slot_version) survive eviction, and anything the sweep retired shows up in the destroy generation.
  • seen.clear(): dropped, ids are < 4096.
  • RX_VK_SAMPLER_CACHE: one switch, stated at the declaration: =0 turns off both the outer id table and the inner parameters' cache; =1 or the menu row turns the inner cache on and leaves the outer table exactly as it is without the option (the row therefore never changes the old default-on path).
  • Item-2-alone numbers: running now (sweep config with RX_VK_DESC_SLOTGEN=0, RX_VK_SAMPLER_CACHE=1), I will post them here.

@hckrman101
hckrman101 merged commit fd553b4 into NotRexed:main Nov 10, 2026
10 checks passed
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