fix(shaders): lower TLD.MS (multisampled texel fetch) to Maxwell TLDS 2D.LZ.MS #1769
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!1769
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/lower-tld-ms"
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?
Three of OoT's fragment programs fail to translate ("does not lower ... native texel fetch mode or descriptor binding") because the Ampere → Maxwell lowering refuses TLD with bit 78 set: a texel fetch from a multisampled texture. Whatever those programs draw is missing on every PC.
The encodings (from the startup pipeline build, the same on a Radeon 890M v2.0.13 log in #bug-reporting):
All three are TLD.SCR 2D,
.LZ, RGB into Rd/Rd+1 plus a second destination, the descriptor at 0x8 of buffer 2. The only refused bit is 78 (.MS). Ra is even in all three (R0, R4, R16), and the first two share Rb (R9) at different Ra. That matches Maxwell's TLDS 2D.LZ.MS layout: x, y in Ra/Ra+1, the sample index in Rb. It is also how this lowering already treats bit 76 (offsets: Ra pair, offsets in Rb).Change (
lower_to_maxwell.h, case 0xb66): accept bit 78 for 2D at level zero and emit Maxwell TLDS encoding 6 (2D.LZ.MS). The Maxwell frontend already reads that as anImageFetchwith a sample (texture_load_swizzled.cpp), andtexture_passthen marks the descriptoris_multisample, so SPIR-V declares an MS image and passes theSampleoperand. Still refused: other dimensions,.LL, offsets together with.MS, an odd Ra, RZ as the sample, and.MSthrough a second descriptor buffer.Tests
tests/test_lower_tld_ms.py(inrun_all.py): the three encodings lower to the expected TLDS 2D.LZ.MS and bind buffer 2; without bit 78 the same fetch lowers to plain 2D.LZ as before; the refused forms stay refused. It fails onmainand passes here.run_all.py: 246 passed, 0 failed.0 programs (0 failed)).I haven't yet found a scene that visibly uses these programs, so there's no before/after screenshot. If someone knows which effect reads a multisampled target in a fragment shader (an MSAA resolve or edge pass?), that's where to look.
🤖 Generated with Claude Code
Looks right to me. I checked the encoding against the Maxwell side:
texture_load_swizzled.cppreads TLDS encoding 6 as Color2D with x, y in Ra, Ra+1 and the sample in Rb, which is what this emits. The test's bit positions also line up (bit 78 = word 2 bit 14,& ~5Ustill lets only 76 and 78 through). MS arrays, 1D/3D,.LL, offsets with.MS, odd Ra and RZ as the sample all still fall through to the existing failure instead of being lowered wrong.Downstream is fine too:
texture_passsetsis_multisamplefrom the fetch's sample arg,EmitImageFetchdrops the Lod operand when there's a sample, so no illegal Lod+Sample on an MS image, andTextureDescriptoris serialized as POD, so the flag survives the program cache. On the host, guest MSAA textures becomesamples > 1images with SAMPLED usage, and the dummy is a null descriptor, so the fallback doesn't introduce a sample-count mismatch.Small things, none blocking:
d.is_multisampleagainst the view it binds. That's fine as long as the game binds a real MSAA texture here, but when you find the scene that uses these programs, one run with the validation layer would confirm the bound view really is multisampled.CI is still running at the moment.
Nit: this
multisamplerefusal for a second descriptor buffer isn't covered bytest_lower_tld_ms.py. A case that binds buffer 2 with a plain TLD first and then the MS fetch from another buffer would pin it down. The TLD.B fallback below would otherwise silently drop the sample index.