perf(vk): texture_answer asks a flat table by slot, not a hash map #2439
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!2439
Loading…
Reference in a new issue
No description provided.
Delete branch "perf-texture-answer-flat"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Every draw's variant check calls
texture_answer()for each texture it samples. The thread-localunordered_mapbehind it was ~16% of the back end's time on the replay thread in a profile of an RX 7800 XT run. Slots are the texture pool's indices (~33k in OoT), so a vector indexed by slot (8 bytes a slot, capped at 2^20 entries) replaces it. The version check is unchanged, so the answers are the same; only the lookup changes. No behaviour switch.Tested: the Vulkan back end builds (llvm-mingw,
RX_VK_ONLY) on top of v2.1.0, and a full build of that tree boots to the title at 60 fps on an RX 7800 XT / Ryzen 7 5800X3D (Windows 11, driver 0x8001a0) with the new log lines present. The repository test suite was not run, and I have not yet played a long session on this build, so the effect in real play is not shown. Related data: #995.🤖 Generated with Claude Code
Looks good to me. The table is indexed by
handle & 0xFFFFF, soid + 1never exceeds the1u << 20cap, and thesetflag keeps a zero-initialised entry from passing for a cached answer when a slot's version is 0 (an unregistered slot, or an id outsidekSlotVersions, wheretexture_slot_versionreturns 0). The version check is the same as before, so a re-registered slot still gets a fresh answer.<vector>and<algorithm>are already included, and no check intests/cutstexture_answerout ofvk_shader.cpp(test_program_answer_domains.pyonly stubs it), so nothing there needs updating.A few small things, none blocking:
gpu/vk/vk_shader.cpp:731: the handle comes from a constant-bank word, so a garbage handle with a high slot grows that thread's table straight to the cap: 2^20 × 8 bytes = 8 MB, zero-filled and committed, on every thread that calls this (the replay thread, plus whatever runsrecord_answers). The old map's cost grew with the number of distinct ids, not with the largest one. In practice slots stay around 33k (about 264 KB), so this is fine. If you want to rule out the worst case, you could size to the texture pool's real slot count instead of 2^20, or skip caching ids above it.github-sync referenced this pull request2026-11-12 06:22:54 +00:00