Super Mario Galaxy 2's half-white Mario on the iPhone (GitHub issue 72): min / max / clamp with a NaN operand give the other operand on every GPU, in the Vulkan, GL and NVN shader chains
- Cause: Galaxy 2's GX vertex lighting (Hagi's SPIR-V) normalizes the light directions the game leaves at (0, 0, 0) for its characters' key and fill lights and takes fast::max(0.0, dot(ldir, NaN)) as the spot term. fast:: leaves a NaN operand's result to the GPU: the Switch's and the M4 Pro's return 0, so the attenuation is 1; the A20 Pro's did not, and the half of Mario that the fill light faces came out white (the fill light sits at the camera's left in view space, so its terminator runs down the middle of a character facing the camera). Found on the Mac by dumping the light uniforms of the character draws (every one has both directions at zero) and a Metal test of the expression on the M4 Pro. - vk_shaders.py, gl_shaders.py and dmsh_build.py (precise): spirv-cross's fast::min / max / clamp are written as precise:: (IEEE fmin / fmax, which give Maxwell's FMNMX and saturation results); the iOS Vulkan and GL libraries are compiled with -fmetal-math-mode=relaxed, as the NVN chain's are. Plain or fast:: min / max / clamp compile to the fast_ intrinsics in every Metal math mode, so relaxed alone does not do it. The NVN chain had the same calls, unguarded by its isnan selects (Paper Mario: The Thousand-Year Door: 124,000 fast::max, 98,000 fast::clamp, 41,000 fast::min). - dmsh_geometry.py capture: clip distances as spirv-cross writes them (gl_ClipDistance [[clip_distance]] [8], and gl_ClipDistance_N [[user(clipN)]] for the pixel stage); sincebb585cdthe shader build stopped for every game with such vertex shaders (Luigi's Mansion 3, Monster Hunter Rise). Checked against all 1,423 distinct vertex output lines of the games' libraries on this Mac. - Shader chain: every profile's dmsh_chain.h rewritten, Mario Kart 8 Deluxe's included (bb585cdhad left 45 of the 46 before it on the version before it, which dmsh_build.py refuses, so the NSP script's iOS shader step stopped for those games). Rebuilt for the Mac and iOS from shader packages checked record by record against the profiles' maps: Luigi's Mansion 3 and Monster Hunter Rise on this chain; Paper Mario: The Thousand-Year Door, 13 Sentinels, ANIMAL WELL, FINAL FANTASY TACTICS, Raging Loop, Metroid Dread, Three Houses, DARK SOULS: REMASTERED, Cuphead and Fire Emblem Engage on the one before the capture fix (none of their vertex shaders writes clip distances). Every shader builds but Monster Hunter Rise's 2 (55 before). Their c1_full / cb_extent lists changed only by rows of geometry shaders built as compute kernels sincebb585cd(Monster Hunter Rise's cb_extent and the other profiles' lists carried over, each header line naming what was checked). - Verified: Galaxy 2 on an iPhone (A20 Pro), Mario lit as on the Switch; Galaxy 2 on the Mac along the storybook route, same red lines; Paper Mario on the Mac with fast:: and precise:: libraries from the same MSL: same pictures and red line, GPU time p50 6.73 / 7.00 ms and p95 9.77 / 9.09 ms (the Mac was busy with shader builds during both)
This commit is contained in:
1 parent
11be43d882
commit
56704a0be1
133 files changed
+220
-137
No files matched your search
@@ -1,4 +1,4 @@
|
||||
# chain b-1f45f2814b3b 2026-10-23T08:37:08+08:00 (list carried over from b-f48652b0908b: that chain change did not touch any c1 read)
|
||||
# chain b-130bc16dd3e5 2026-10-23T20:36:21+08:00 (list carried over from b-1f45f2814b3b: the precise:: min / max / clamp change touches no c1 read; its geometry shaders, built as compute kernels since bb585cd, were not checked)
|
||||
026f2479adc13489
|
||||
10b8a90504eb68ad
|
||||
2a0fa3cfc6a8391f
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# chain b-1f45f2814b3b 2026-10-23T08:37:08+08:00 (list carried over from b-f48652b0908b: that chain change did not touch any uniform read)
|
||||
# chain b-130bc16dd3e5 2026-10-23T20:36:21+08:00 (list carried over from b-1f45f2814b3b: the precise:: min / max / clamp change touches no uniform read; its geometry shaders, built as compute kernels since bb585cd, were not checked)
|
||||
# shader key, then reg:bytes for each uniform slot whose reads stay inside its first bytes, and s<reg> for each storage slot it never writes (cb_extent.py)
|
||||
0000cefe47f6c37f 0:1936 1:176 2:16
|
||||
000369ccbda98f21 0:2096 1:256 2:32
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1,2 +1,2 @@
|
||||
// Generated file (dm/gfx/tools/dmsh_chain.py --header, game 01006C300E9F0000): the B shader library translation chain version this source tree expects (default options); the host loads only <library dir>/b-<V>/
|
||||
#define DMSH_CHAIN "1f45f2814b3b"
|
||||
#define DMSH_CHAIN "130bc16dd3e5"
|
||||
Reference in new issue
Block a user