fix(vk): restore Deku Tree floor web lighting on NVIDIA #1442
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!1442
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/deku-tree-web-lighting"
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?
Summary
Restore lighting on the circular floor web in the Great Deku Tree on NVIDIA. Request SPIR-V
Inlinefor the 128-bit global-load helper in vertex shaderb449bcdb69b36a8a(draw927f31eddda79218). This reuses the existingEDEN_NX2_GM_INLINEswitch and applies the same workaround used for a related task and mesh shader miscompile in #1334.The original report is #455. The floor-web follow-up in #1002 reports that the underground web still renders black.
Cause
The grid dimensions and origin matched the values in memory, and the emitted SPIR-V used the dimensions load for the X and Z coordinate clamps. The NVIDIA shader readback showed those clamps using the origin load instead. That produced coarse cell index
0x4ccffff9where the captured position should select cell0. Requesting inlining restored cell0, subdivision32, and all eight expected fine-probe offsets.Testing
9a2e80e, using LLVM-MinGW andRX_VK_ONLY=1. The game-free IR regression verifies that the workaround switches the vertex shader's 128-bit helper toInlinewhile the 32-bit helper staysDontInline. All 22 emitted fixture modules passedspirv-valfor Vulkan 1.3.python -I -B tests/run_all.pylocally on Windows. 187 passed, 16 were skipped, and the same five failures reproduced on unmodified upstream main in this environment.AI assistance
OpenAI Codex assisted with diagnosis, implementation, the game-free test, and this write-up. The investigation used existing Claude-assisted IR probes. I ran the in-game checks and confirmed the visual result. The commit includes both AI attribution trailers.
Before the fix
After the fix
This landed in the v2.0.12 branch (merged there for testing; it reaches
mainwith that release), so closing. Thanks!Reopened: closing this was a mistake on my side. It was tested in the v2.0.12 branch, and it will be merged into main here, so it shows as merged. Sorry for the noise.
Thanks, this is a clean, well-scoped workaround and the write-up is very good.
On AMD/Intel: no effect at all.
inline_global_128_loadsis only set whenvendorID == 0x10DEand the vertex key isb449bcdb69b36a8a, so other vendors (and every other shader on NVIDIA) still emit the same SPIR-V they do today.Inlineis only a hint and doesn't change semantics, so even if it reached another vendor it wouldn't break anything. The cache side is fine as well, sincevk_shader.cppand the eden tree are both inHOOKSHOT_SHADER_STAMP, andEDEN_NX2_GM_INLINE=0still turns it off.On root cause: this works around a driver miscompile, it doesn't fix one. I couldn't find anything in the helper bodies (no shared Private state, nothing call-order dependent) that would let a correct compiler swap one call's result for another's. It's the same failure as #1334 (one call's result used in place of another's), so I think treating it as an NVIDIA bug is right. The open question is whether to scope it this narrowly, see the inline note.
The new fixture looks right: the 32-bit helper stays
DontInlineand only the 128-bit one changes. It runs in the existing source-regressions job. No CI ran on this PR (fork workflows waiting for approval), so a maintainer should kick it off before merging. No overlap with what's landed on main since the base.@ -1520,0 +1520,4 @@// Deku Tree web (#455): with DontInline, NVIDIA's compiled vertex shader substitutes the grid-origin// load result for the grid dimensions in the coordinate clamps. The SPIR-V names the right result.constexpr uint64_t kDekuWebVertexCode = 0xb449bcdb69b36a8aull;vrt.inline_global_128_loads = dev.props.vendorID == 0x10DE && vsc->key == kDekuWebVertexCode;Non-blocking: gating on one shader hash fixes this draw, but any other vertex shader with the same pattern (several 128-bit global loads feeding each other) will still miscompile on NVIDIA, and nobody will notice until someone reports a black mesh. The 41 s compile-time problem that kept
DontInlineonly came from the culling compute programs with hundreds of loads. Vertex shaders have very few, so turning on inlining for every vertex stage on NVIDIA (or every vendor, since it's only a hint) should be cheap and would cover the whole class. If you'd rather keep it narrow for now, that's fine, maybe just add a short comment saying so.