fix(shaders): R2UR's source is one register, not a pair (a vertex program refused) #1806
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!1806
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/lower-r2ur-one-register"
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?
One of OoT's vertex programs (
65dd5ce0adbe3b64) fails to translate ("native program uses lowering scratch registers") at an R2UR that reads R238. Nothing in it uses a scratch register: the lowering assumes R2UR's source may be a register pair.Cause.
R2UR UR6, R238(ee0673c2 00000000 000e0000 000e2200). With the uniform bank in use, R238 is a high GPR.FieldSpanhas no entry for R2UR, so the source's span came from its alignment: an even register, R4n+2, is taken as a pair, R238-R239. R239 is the lowering's own scratch, and R2UR lowers to eight words that use it, so that's a conflict. R2UR reads one 32-bit register.Change (
lower_to_maxwell.h,FieldSpan): R2UR's source spans one register, as MUFU's and CS2R's entries do for theirs.Tests
tests/test_lower_r2ur_one_register.py:R2UR UR6, R238is refused onmainand lowers here;R236lowers either way.run_all.py: all pass exceptnx2/test_nup_stand_in.py, red onmain(fixed by #1790).🤖 Generated with Claude Code
Looks right to me. R2UR reads one register: the lowering only accepts the plain form (
insn.words[1] == 0 && insn.words[2] == 0x000e0000, anything else is refused as "native register-to-uniform mode"), so no wider/modifier variant can reach the 1-register span. The SHFL it emits reads onlyBits(24, 8), and its own words use R250/R251 and the target UR's home, not R238. The change is scoped to opcode 0x3c2 field 1, only on the extended-renaming retry. Fields 0/2/3 keep the old behavior: the UR destination never gets nearreserved_base, and in the accepted form the bits at 32 and 64 are zero. R239 and R246+ still conflict (high_239/high_in_scratchwith words > 1), so real scratch overlaps are still refused.No overlap with #1800: it changes the register_field loop (~L211-241), not
FieldSpan. And bit 24 is a register field either way, so itscontinuedoesn't skip this one.Two small things:
tests/run_all.py: main addedtests/test_lower_tld_ms.pyon the same line aftertest_lower_suld_1d.py. It's a trivial rebase, keep both entries.LowerToMaxwellonR2UR UR6, Rn: R236 is refused on main too (4-aligned, so its span was taken as a quad, R236-R239). So were R238, R239, R244 and R246. R230-R235, R237 and R240 lowered. So this PR also fixes R236 and R244. Worth fixing the comment/description, and maybe adding a negative check that R239 is still refused.@ -0,0 +1,57 @@"""The Ampere -> Maxwell lowering takes R2UR's source as one register, not a pair (native op 0x3c2).Nit: on main this one is refused too. R236 is 4-aligned, so its span was taken as R236-R239, which reaches R239 (I checked by running main's lowering). So it's a second case this PR fixes, not an unchanged control. Maybe relabel it, and add
CHECK(!lower(insn(0xef0673c2, 0x00000000, 0x000e0000, 0x000e2200))); // R239: still the scratchso the one-register span can't hide a real overlap.Thanks, you're right about R236: it's 4-aligned, so main took it for the quad R236-R239 and refused it too. The test now calls it a second case this fixes, and checks that
R2UR UR6, R239is still refused (R239 itself is the scratch). Rebased onto main (therun_all.pyconflict);run_all.pypasses apart fromnx2/test_nup_stand_in.py, which #1790 fixes.Heads-up: this conflicts with main now (a lot landed today). Could you merge main into the branch (or rebase) and resolve the conflicts? Thanks!