Optimize CPU deswizzle copies and host symbol lookup (#261)
Hoist block-linear row and slice addressing out of segment copies, and index HLE, forced-takeover and missing-import names while retaining existing duplicate precedence and stub identity. Add byte-address differential tests and direct collision, duplicate, growth and reuse checks. Correct the ASTC-tail and loader-serialization comments and document independent CPU microbenchmarks. Keep TotK prewarm data in a separate change. Validation: 5,334 texture checks; symbol-index and NRO lifecycle tests; AddressSanitizer/UBSan; documentation checks; Mac host build and changed iOS source compilation. No new gameplay validation. Co-authored-by: draco-cong <71372970+draco-cong@users.noreply.github.com> Co-authored-by: laobeibei <laobeibei@users.noreply.github.com>
This commit is contained in:
1 parent
f7345d9a00
commit
5632203274
11 files changed
+275
-27
No files matched your search
@@ -182,6 +182,14 @@ Games read this count as a position in their own command memory and size their h
|
||||
|
||||
## CPU-written textures
|
||||
|
||||
### CPU deswizzle copies use slice and row offsets
|
||||
|
||||
- **Symptom:** CPU texture uploads spend time recalculating block-linear addresses and calling variable-length `memcpy` for every 16-byte segment.
|
||||
- **Cause:** `move` called `nvn_bl_offset` inside its innermost loop, repeating slice/row calculations and division by runtime block dimensions.
|
||||
- **Fix:** hoist slice and row offsets, express power-of-two block dimensions as shifts/masks, and use the four fixed x offsets and eight fixed y offsets within a GOB. Full segments use constant-size 16-byte copies; byte counts not divisible by 16 retain a tail copy. ASTC blocks are always 16 bytes irrespective of their texel dimensions. Both copy directions preserve the layout, sparse row padding and mip/layer offsets.
|
||||
- **Found on:** [The Legend of Zelda: Breath of the Wild](../../dm/games/01007EF00011E000/README.md#found-on-this-game), reported in [PR #261](https://github.com/seedds/nxnative/pull/261).
|
||||
- **Check:** `t_tex` compares both directions against the byte-address formula for 1,029 deterministic layouts, including 1D/2D/3D, arrays/cubes, packaged block dimensions, sparse mip tails, 1/2/3/4/6/8/12/16-byte formats, padded pitches and partial segments. All 5,334 checks pass, including under AddressSanitizer and UBSan. A local arm64 Mac comparison against the old implementation, Apple clang 21 at the host's `-O1`, measured 7.4–7.7 GB/s before and 35.1–37.6 GB/s after (4.6–5.1x) across 1024x1024 sparse ASTC 6x6, 2048x2048 BC7, 1920x1080 RGBA8 and 1280x720 RGBA16F. Each result is the median of seven runs copying about 128 MiB, with implementation order alternated. This is a CPU microbenchmark; no new gameplay run here.
|
||||
|
||||
### Packaged texture block dimensions and linear storage rows
|
||||
|
||||
- **Symptom:** driver comparisons report the wrong block dimensions for packaged 2D / 3D textures, or too little storage for linear block-compressed textures (64x64 BC1 with stride 128: 2048 bytes instead of 8192).
|
||||
|
||||
@@ -549,6 +549,14 @@ Most service calls can be found before they crash, before the first boot or the
|
||||
|
||||
## Modules and symbols
|
||||
|
||||
### Host symbol indexes avoid repeated name scans
|
||||
|
||||
- **Symptom:** relocation repeatedly scans all HLE and forced-takeover entries, and named-stub reuse becomes quadratic as more imports are missing.
|
||||
- **Cause:** module exports already had a name index, but `resolve_import`, `hle_implements`, `force_lookup` and stub reuse still searched their tables linearly.
|
||||
- **Fix:** open-addressed name indexes store entry numbers. HLE duplicates retain the first entry; forced-takeover duplicates still abort. Stub insertion grows its index above half capacity and retains existing stub numbers. Resolution is serialized at startup and by the module write lock during runtime NRO loading; module string tables stay mapped across unload.
|
||||
- **Found on:** [The Legend of Zelda: Breath of the Wild](../../dm/games/01007EF00011E000/README.md#found-on-this-game), reported in [PR #261](https://github.com/seedds/nxnative/pull/261).
|
||||
- **Check:** `make -C dm/host/tests GAME=010015100B514000 symbols nro` covers collisions that wrap around the table, duplicate precedence/rejection, absent sections and names, counting-wrapper selection, all 4,096 stubs through growth and reuse at capacity, and NRO relocation/lifecycle. The symbol test also passes AddressSanitizer and UBSan. A local arm64 Mac synthetic 270-entry HLE table with 25% misses, Apple clang 21 at `-O1`, took 375–442 ns per linear lookup versus 15 ns indexed (25–29x; three runs of 360,000 lookups). This measures lookup cost, not overall game loading time; no new gameplay run here.
|
||||
|
||||
### Global symbol resolution in load order
|
||||
|
||||
- **Symptom:** a library's `free` rejects a pointer (`CentralHeap::Free` → `NotNMallocPtrError`).
|
||||
|
||||
Reference in new issue
Block a user