Repository navigation
Textures in a sparse pool get stand-ins read through the page table, so PRAGMATA's cut to the tablet no longer shows a dark frame - #2477
Open
computerguy526 wants to merge 1 commit into
Conversation
…e page table, so PRAGMATA's cut to the tablet no longer shows a dark frame The stand-ins of seedds#2075 left out every texture in a sparse pool, whose address range must be read through its page table (an unmapped page stops the host with SIGBUS). PRAGMATA puts all its streamed textures in sparse pools and is past the walk's budget from its first scene, so the materials first read at a scene cut still found the dummy: the whole-picture luma at the cut from the tower to the tablet fell from 65 to 22 for a frame. stand_fill gathers each layer's bytes from the stand-in's first level to the layer's end through the page table (nvn_sparse_copy, at most 256 KB a layer) and decodes them with nvn_deswizzle_from / nvn_deswizzle_pick. A texture with the SPARSE flag gets one only from its mip tail on. A page behind those levels not mapped yet: the ID keeps the dummy and stays open (stand_no 0), so it is looked at again when a mapping over its pages notes it (treg_sparse_notes) or at its next walk, where it was refused for the registration's life before. Such a refusal counts toward the 512 stand-ins a frame, so a game that maps every frame retries at most that many. Test: t_pool_standin_sparse (new, Metal validation), 23 checks, including a mapping in the same frame with no walk; with a refused ID kept closed, as on main, that check fails. t_pool_standin and t_pool_notes pass. Reference entry in rendering.md, and a line in PRAGMATA's note. Co-authored-by: uncraftablexd <352372032+uncraftablexd@users.noreply.github.com>
computerguy526
force-pushed
the
sparse-standin
branch
from
November 13, 2026 11:21
03149a0 to
875bace
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
At PRAGMATA's cut from the tower to the tablet, the picture drops to a dark frame for one or two frames. On a
main-line host, the whole-picture luma read 65 before the cut, 22 on the cut frame and 50 after. That happened in both runs without this change. With it, both runs read 65 / 65 / 65, with no frame over 100 ms, 60 fps, and a resident peak 0.1 GB lower.Related to the PRAGMATA bring-up, ccd834e (@seedds).
Cause
The stand-ins of #2075 left out every texture in a sparse pool. Such a pool's address range has to be read through its page table, because reading an unmapped page directly stops the host with SIGBUS. PRAGMATA puts all its streamed textures in sparse pools, and it is past the walk's budget from its first scene (about 12 GB allocated against a budget of about 0.9 GB). So the materials first read at a scene cut still found the dummy. On an earlier branch with a G-buffer dump, the base colour on the cut frame was 0.068, against 0.18 on the next frame.
What changes
stand_fillgathers each layer's bytes, from the stand-in's first level to the layer's end, through the page table (nvn_sparse_copy, at most 256 KB a layer). It decodes them withnvn_deswizzle_from/nvn_deswizzle_pick.sparse_makereads it).stand_no0), so it is looked at again when a mapping over its pages notes it (treg_sparse_notes, Refresh cached texture bindings after sparse mapping changes #1721) or at its next walk. PRAGMATA registers some materials long before a cut and maps their small levels later.pool stand-ins up to frameline also counts those made in a sparse pool and those not made for an unmapped page.DM_NVN_POOL_STANDIN=0still turns all stand-ins off.Tests
t_pool_standin_sparse(new, under Metal validation, 23 checks, through the real NVN entry points) covers:main(no sparse stand-ins). With a refused ID kept closed, asmainkeeps it, the same-frame check fails.t_pool_standinis unchanged: 51 checks, and 31 withDM_NVN_POOL_STANDIN=0, all pass.t_pool_notespasses.Regression
regress.py impactlists The Legend of Zelda: Breath of the Wild, Pokémon Scarlet and The Legend of Zelda: Tears of the Kingdom as affected (throughnvn_mtl.m). None was run, and none of them is known to use sparse pools.main-line host, two runs a side, with the sparse stand-ins switched off on the test host for the runs without):Rebased on main 3084f7a, full local CI
@@ci@@
Co-authored with UncraftableXD.