Prevent Castle Town guard-house crashes with a larger render-target pool #1202
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!1202
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/guardhouse-render-target-pool"
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?
Talking to the soldier in Castle Town’s guard house while rotating the camera repeatedly crashed at 2560×1440 with the 305 MiB render-target pool. Reserving 512 MiB resolved the reported reproduction.
This gives the pool a 512 MiB minimum while preserving existing 4K/ultrawide growth and explicit
HOS_RT_POOL_MBoverrides. The existing graphics-heap/budget hooks use the same sizing function, so the backing allocation grows with it. The base reservation increases by 207 MiB.The initial stop was
native NVN: texture handle ids -1/264. The companion handle correction matches the original SDK: sign-extend both IDs, combine them, and return zero when the texture ID is zero. That correction alone did not resolve the room: it exposed a subsequent allocator crash inf_8005ed00. Disabling write-back diff and the separate present queue also did not resolve it. Raising the pool to 512 MiB with those changes retained did.Validation
python -I -B tests/run_all.py --jobs 1 --strict nvn rt_pool: 5 passed.source ed212f62), Linux, RX 7800 XT/RADV, docked 2560×1440 at 100% resolution, frame generation off. The same soldier/camera action passed after setting the pool to 512 MiB. Steam’s overlay remained enabled for the working controller setup.The complete game has not been rebuilt from this exact branch, and Windows runtime behavior has not been tested. The pool recommendation is based on the repeatable allocation failure and the successful larger-pool test; peak pool use has not been instrumented. No game files, saves, settings files, binaries, caches, or SDK code are included.
Thanks, this looks good to me. What I checked:
hos_rt_pool_sizeis the only sizing source for the pool config store, the Graphics heap growth, the module budget correction and the f_80b72340 heap trim innx2/oot_patches.py. So the 512 MB floor applies to all four consistently. At 1440p those patches used to do nothing (growth was 0). Now they add 207 MB, which is less than the 382 MB the 4K path already uses, so it stays inside a configuration that already works.texture_of,sampler_ofandtexture_slot_versionall bounds-check those, so it falls back to the dummy texture and default sampler instead of indexing out of range.block()helper, they're picked up byrun_all.py, and the main cases fail against the old code (die -> exit 86, and 305 instead of 512). I checked the expected numbers in the fixtures by hand.Two non-blocking notes are inline: (1) the floor is applied after scaling, so 4K doesn't get the same headroom the guard house needed at 1440p, and (2) a one-time log for negative texture ids would keep pool exhaustion visible now that the
die()is gone.@ -134,1 +134,4 @@const uint64_t scaled = px > 2560 * 1440 ? (game * px / (2560 * 1440) + 0xfffff) & ~0xfffffULL : game;const uint64_t minimum = 512ULL << 20;const uint64_t v = e ? strtoull(e, NULL, 0) << 20 : scaled < minimum ? minimum : scaled;static int logged;Something to consider: the floor is applied after scaling. If the guard house needs more than 305 MB at 1440p because of render targets, it would need roughly 2.25x that at 4K, but 4K still gets 687 MB (305 scaled). Applying the floor to the base first (
game < minimum ? minimum : game, then scale) would give 4K the same relative headroom, at about +465 MB at 4K. Not tested at 4K either way, so I'm fine leaving it as is for now. It's just worth knowing if a 4K report of the same room comes in.@ -207,2 +207,4 @@rather than stopping the game here. Keep the signed ids, including their upper bits. */RET(t ? (uint64_t)t | (uint64_t)s << 20 : 0);}NV(nvnDeviceGetTexelFetchHandle) { RET((uint64_t)I(1)); }Matching the SDK makes sense. One small thing: the old
die("texture handle ids -1/...")was the only clear sign that the render-target pool had run out (issue 1031 was diagnosed from it, and the comment abovehos_rt_pool_sizestill names it as the symptom). Maybe a one-timehos_logwhent < 0, so a future pool exhaustion shows up in the log before the allocator crash in f_8005ed00?Feel free to open follow-up