re: the UI blend mode is MEASURED -- the frames are drawn ADDITIVE
Closes the one route t32-blend-mode-not-on-disc.md left open: the executable's
draw path. Canary's UI draw capture now logs RB_BLENDCONTROL0 per draw, and the
game was driven to the main menu and to EXTRAS with F10 at each.
The title-side UI uses two blend states and ONE pixel shader:
0x07010701 src=ONE dst=1-SRC_ALPHA alpha-over (premultiplied)
ptbase, pteff05, the fade quad, ptmsg, ptmsg2, pttitle, buttons
0x01010101 src=ONE dst=ONE ADDITIVE
ptframe1, ptframe2, ptframe3, pteff20, both rotated sweep strips
Two controls, both run before the result was read:
* the NDC->pixel conversion that identifies a draw by its quad size reproduces
1134 and 1303 px for the two rotated sweep strips -- numbers measured by a
different tool in a different session -- on BOTH screens. The tool prints
PASS/FAIL and disclaims its own output on FAIL.
* pixel shader 0xE59B2B3DA4AA9008 is used with BOTH states, 12 draws additive
and 18 alpha-over. ptframe1 and ptbase run the same shader; only the blend
register differs. So this is a blend result, not a shader result.
This confirms the port's independent measurement -- it solved the composite per
pixel from two backgrounds and found additive halves alpha-over's error on both
frames -- by a route with nothing in common with it.
So the blend is no longer authored: 'any blend you choose is authored' was true
of the disc and is not true of the game. What is still unknown is which field
selects it; elements sharing a mode are batched into one draw call, so the
selection happens before the draw.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
43
docs/re/captures/ui-draws/blend-extras-2026-08-31.log
Normal file
43
docs/re/captures/ui-draws/blend-extras-2026-08-31.log
Normal file
@@ -0,0 +1,43 @@
|
||||
# every draw in SUBMISSION ORDER, undeduplicated, frames 1..4
|
||||
# tex dimensions identify the sprite; base is the guest address
|
||||
0 prim=8 indices=3 vs=0x0A6D1DD7767FDF27 ps=0x2E372EA28CC404B7 blend=0x00010001[c:src=1 op=0 dst=0 a:src=1 op=0 dst=0] cc=0x00000000 mask=0xFFFF
|
||||
vb=0x150388F8 stride=28 attrs=[57@0 38@12 ] fmt0=57 v: [-0.50,-0.50,z=0.00000] [1279.50,-0.50,z=0.00000] [1279.50,719.50,z=0.00000]
|
||||
1 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x15038950 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
2 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x150389B0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [1.29,1.58,z=0.00000,col=E2FFFFFF] [1.83,1.02,z=0.00000,col=E2FFFFFF] [0.99,-1.57,z=0.00000,col=E2FFFFFF] [0.45,-1.02,z=0.00000,col=E2FFFFFF]
|
||||
3 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0BFE0000 1280x768 fmt=6]
|
||||
vb=0x15038A10 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.89,1.02,z=0.00000,col=D0FFFFFF] [-1.45,1.81,z=0.00000,col=D0FFFFFF] [0.14,-1.02,z=0.00000,col=D0FFFFFF] [-0.30,-1.81,z=0.00000,col=D0FFFFFF]
|
||||
4 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0C3B0000 1280x768 fmt=6]
|
||||
vb=0x15038A70 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
5 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0x5773DC18083C4C20 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF
|
||||
vb=0x15038AD0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=40000000] [1.00,1.00,z=0.00000,col=40000000] [1.00,-1.00,z=0.00000,col=40000000] [-1.00,-1.00,z=0.00000,col=40000000]
|
||||
6 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0BFE0000 1280x768 fmt=6]
|
||||
vb=0x15038B30 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.64,1.00,z=0.00000,col=FFFFFFFF] [0.64,1.00,z=0.00000,col=FFFFFFFF] [0.64,-1.00,z=0.00000,col=FFFFFFFF] [-0.64,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
7 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x15038B90 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.48,0.67,z=0.00000,col=80FFFFFF] [0.48,0.67,z=0.00000,col=80FFFFFF] [0.48,-0.77,z=0.00000,col=80FFFFFF] [-0.48,-0.77,z=0.00000,col=80FFFFFF] [-0.31,0.36,z=0.00000,col=FFFFFFFF] [0.07,0.36,z=0.00000,col=FFFFFFFF] [0.07,-0.25,z=0.00000,col=FFFFFFFF] [-0.31,-0.25,z=0.00000,col=FFFFFFFF]
|
||||
8 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x15038DD0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.27,-0.51,z=0.00000,col=FFFFFFFF] [0.28,-0.51,z=0.00000,col=FFFFFFFF] [0.28,-0.62,z=0.00000,col=FFFFFFFF] [-0.27,-0.62,z=0.00000,col=FFFFFFFF] [-0.14,0.72,z=0.00000,col=FFFFFFFF] [0.14,0.72,z=0.00000,col=FFFFFFFF] [0.14,0.63,z=0.00000,col=FFFFFFFF] [-0.14,0.63,z=0.00000,col=FFFFFFFF]
|
||||
9 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
10 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
--- frame 3 ---
|
||||
11 prim=8 indices=3 vs=0x0A6D1DD7767FDF27 ps=0x2E372EA28CC404B7 blend=0x00010001[c:src=1 op=0 dst=0 a:src=1 op=0 dst=0] cc=0x00000000 mask=0xFFFF
|
||||
vb=0x15079138 stride=28 attrs=[57@0 38@12 ] fmt0=57 v: [-0.50,-0.50,z=0.00000] [1279.50,-0.50,z=0.00000] [1279.50,719.50,z=0.00000]
|
||||
12 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x15079190 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
13 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x150791F0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [1.33,1.58,z=0.00000,col=E4FFFFFF] [1.87,1.02,z=0.00000,col=E4FFFFFF] [1.02,-1.57,z=0.00000,col=E4FFFFFF] [0.48,-1.02,z=0.00000,col=E4FFFFFF]
|
||||
14 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0BFE0000 1280x768 fmt=6]
|
||||
vb=0x15079250 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.92,1.02,z=0.00000,col=D1FFFFFF] [-1.48,1.81,z=0.00000,col=D1FFFFFF] [0.11,-1.02,z=0.00000,col=D1FFFFFF] [-0.33,-1.81,z=0.00000,col=D1FFFFFF]
|
||||
15 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0C3B0000 1280x768 fmt=6]
|
||||
vb=0x150792B0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
16 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0x5773DC18083C4C20 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF
|
||||
vb=0x15079310 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=40000000] [1.00,1.00,z=0.00000,col=40000000] [1.00,-1.00,z=0.00000,col=40000000] [-1.00,-1.00,z=0.00000,col=40000000]
|
||||
17 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0BFE0000 1280x768 fmt=6]
|
||||
vb=0x15079370 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.64,1.00,z=0.00000,col=FFFFFFFF] [0.64,1.00,z=0.00000,col=FFFFFFFF] [0.64,-1.00,z=0.00000,col=FFFFFFFF] [-0.64,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
18 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x150793D0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.48,0.67,z=0.00000,col=80FFFFFF] [0.48,0.67,z=0.00000,col=80FFFFFF] [0.48,-0.77,z=0.00000,col=80FFFFFF] [-0.48,-0.77,z=0.00000,col=80FFFFFF] [-0.31,0.36,z=0.00000,col=FFFFFFFF] [0.07,0.36,z=0.00000,col=FFFFFFFF] [0.07,-0.25,z=0.00000,col=FFFFFFFF] [-0.31,-0.25,z=0.00000,col=FFFFFFFF]
|
||||
19 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x15079610 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.27,-0.51,z=0.00000,col=FFFFFFFF] [0.28,-0.51,z=0.00000,col=FFFFFFFF] [0.28,-0.62,z=0.00000,col=FFFFFFFF] [-0.27,-0.62,z=0.00000,col=FFFFFFFF] [-0.14,0.72,z=0.00000,col=FFFFFFFF] [0.14,0.72,z=0.00000,col=FFFFFFFF] [0.14,0.63,z=0.00000,col=FFFFFFFF] [-0.14,0.63,z=0.00000,col=FFFFFFFF]
|
||||
20 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
21 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
70
docs/re/captures/ui-draws/blend-main-menu-2026-08-31.log
Normal file
70
docs/re/captures/ui-draws/blend-main-menu-2026-08-31.log
Normal file
@@ -0,0 +1,70 @@
|
||||
# every draw in SUBMISSION ORDER, undeduplicated, frames 2..5
|
||||
# tex dimensions identify the sprite; base is the guest address
|
||||
0 prim=8 indices=3 vs=0x0A6D1DD7767FDF27 ps=0x2E372EA28CC404B7 blend=0x00010001[c:src=1 op=0 dst=0 a:src=1 op=0 dst=0] cc=0x00000000 mask=0xFFFF
|
||||
vb=0x14CF00B8 stride=28 attrs=[57@0 38@12 ] fmt0=57 v: [-0.50,-0.50,z=0.00000] [1279.50,-0.50,z=0.00000] [1279.50,719.50,z=0.00000]
|
||||
1 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14CF0110 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
2 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14CF0170 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [1.54,1.58,z=0.00000,col=EFFFFFFF] [2.08,1.02,z=0.00000,col=EFFFFFFF] [1.23,-1.57,z=0.00000,col=EFFFFFFF] [0.69,-1.02,z=0.00000,col=EFFFFFFF] [-0.61,1.02,z=0.00000,col=9AFFFFFF] [-0.17,1.81,z=0.00000,col=9AFFFFFF] [1.42,-1.02,z=0.00000,col=9AFFFFFF] [0.98,-1.81,z=0.00000,col=9AFFFFFF]
|
||||
3 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0AEF0000 1280x768 fmt=6]
|
||||
vb=0x14CF0230 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
4 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0x5773DC18083C4C20 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF
|
||||
vb=0x14CF0290 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=40000000] [1.00,1.00,z=0.00000,col=40000000] [1.00,-1.00,z=0.00000,col=40000000] [-1.00,-1.00,z=0.00000,col=40000000]
|
||||
5 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14CF02F0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.64,1.00,z=0.00000,col=C0FFFFFF] [0.64,1.00,z=0.00000,col=C0FFFFFF] [0.64,-1.00,z=0.00000,col=C0FFFFFF] [-0.64,-1.00,z=0.00000,col=C0FFFFFF]
|
||||
6 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0BA60000 1280x768 fmt=6]
|
||||
vb=0x14CF0350 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.54,1.00,z=0.00000,col=FFFFFFFF] [0.54,1.00,z=0.00000,col=FFFFFFFF] [0.54,-1.00,z=0.00000,col=FFFFFFFF] [-0.54,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
7 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14CF03B0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.31,0.70,z=0.00000,col=FFFFFFFF] [0.07,0.70,z=0.00000,col=FFFFFFFF] [0.07,-0.08,z=0.00000,col=FFFFFFFF] [-0.31,-0.08,z=0.00000,col=FFFFFFFF] [-0.09,0.26,z=0.00000,col=FFFFFFFF] [0.31,0.26,z=0.00000,col=FFFFFFFF] [0.31,-0.60,z=0.00000,col=FFFFFFFF] [-0.09,-0.60,z=0.00000,col=FFFFFFFF]
|
||||
8 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0B2C0000 1280x768 fmt=6]
|
||||
vb=0x14CF0470 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.18,-0.65,z=0.00000,col=FFFFFFFF] [0.17,-0.65,z=0.00000,col=FFFFFFFF] [0.17,-0.76,z=0.00000,col=FFFFFFFF] [-0.18,-0.76,z=0.00000,col=FFFFFFFF]
|
||||
9 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x14CF04D0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.23,0.45,z=0.00000,col=FFFFFFFF] [-0.22,0.56,z=0.00000,col=FFFFFFFF] [-0.15,0.55,z=0.00000,col=FFFFFFFF] [-0.16,0.43,z=0.00000,col=FFFFFFFF] [-0.16,0.57,z=0.00000,col=FFFFFFFF] [0.17,0.57,z=0.00000,col=FFFFFFFF] [0.17,0.42,z=0.00000,col=FFFFFFFF] [-0.16,0.42,z=0.00000,col=FFFFFFFF]
|
||||
10 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
11 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
--- frame 4 ---
|
||||
12 prim=8 indices=3 vs=0x0A6D1DD7767FDF27 ps=0x2E372EA28CC404B7 blend=0x00010001[c:src=1 op=0 dst=0 a:src=1 op=0 dst=0] cc=0x00000000 mask=0xFFFF
|
||||
vb=0x14D30838 stride=28 attrs=[57@0 38@12 ] fmt0=57 v: [-0.50,-0.50,z=0.00000] [1279.50,-0.50,z=0.00000] [1279.50,719.50,z=0.00000]
|
||||
13 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D30890 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
14 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D308F0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [1.57,1.58,z=0.00000,col=F0FFFFFF] [2.11,1.02,z=0.00000,col=F0FFFFFF] [1.26,-1.57,z=0.00000,col=F0FFFFFF] [0.72,-1.02,z=0.00000,col=F0FFFFFF] [-0.64,1.02,z=0.00000,col=9CFFFFFF] [-0.20,1.81,z=0.00000,col=9CFFFFFF] [1.39,-1.02,z=0.00000,col=9CFFFFFF] [0.95,-1.81,z=0.00000,col=9CFFFFFF]
|
||||
15 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0AEF0000 1280x768 fmt=6]
|
||||
vb=0x14D309B0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
16 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0x5773DC18083C4C20 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF
|
||||
vb=0x14D30A10 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=40000000] [1.00,1.00,z=0.00000,col=40000000] [1.00,-1.00,z=0.00000,col=40000000] [-1.00,-1.00,z=0.00000,col=40000000]
|
||||
17 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D30A70 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.64,1.00,z=0.00000,col=C0FFFFFF] [0.64,1.00,z=0.00000,col=C0FFFFFF] [0.64,-1.00,z=0.00000,col=C0FFFFFF] [-0.64,-1.00,z=0.00000,col=C0FFFFFF]
|
||||
18 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0BA60000 1280x768 fmt=6]
|
||||
vb=0x14D30AD0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.54,1.00,z=0.00000,col=FFFFFFFF] [0.54,1.00,z=0.00000,col=FFFFFFFF] [0.54,-1.00,z=0.00000,col=FFFFFFFF] [-0.54,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
19 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D30B30 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.31,0.70,z=0.00000,col=FFFFFFFF] [0.07,0.70,z=0.00000,col=FFFFFFFF] [0.07,-0.08,z=0.00000,col=FFFFFFFF] [-0.31,-0.08,z=0.00000,col=FFFFFFFF] [-0.09,0.26,z=0.00000,col=FFFFFFFF] [0.31,0.26,z=0.00000,col=FFFFFFFF] [0.31,-0.60,z=0.00000,col=FFFFFFFF] [-0.09,-0.60,z=0.00000,col=FFFFFFFF]
|
||||
20 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0B2C0000 1280x768 fmt=6]
|
||||
vb=0x14D30BF0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.18,-0.65,z=0.00000,col=FFFFFFFF] [0.17,-0.65,z=0.00000,col=FFFFFFFF] [0.17,-0.76,z=0.00000,col=FFFFFFFF] [-0.18,-0.76,z=0.00000,col=FFFFFFFF]
|
||||
21 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x14D30C50 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.24,0.49,z=0.00000,col=FFFFFFFF] [-0.20,0.59,z=0.00000,col=FFFFFFFF] [-0.14,0.51,z=0.00000,col=FFFFFFFF] [-0.18,0.42,z=0.00000,col=FFFFFFFF] [-0.16,0.57,z=0.00000,col=FFFFFFFF] [0.17,0.57,z=0.00000,col=FFFFFFFF] [0.17,0.42,z=0.00000,col=FFFFFFFF] [-0.16,0.42,z=0.00000,col=FFFFFFFF]
|
||||
22 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
23 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
--- frame 5 ---
|
||||
24 prim=8 indices=3 vs=0x0A6D1DD7767FDF27 ps=0x2E372EA28CC404B7 blend=0x00010001[c:src=1 op=0 dst=0 a:src=1 op=0 dst=0] cc=0x00000000 mask=0xFFFF
|
||||
vb=0x14D50F38 stride=28 attrs=[57@0 38@12 ] fmt0=57 v: [-0.50,-0.50,z=0.00000] [1279.50,-0.50,z=0.00000] [1279.50,719.50,z=0.00000]
|
||||
25 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D50F90 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
26 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D50FF0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [1.61,1.58,z=0.00000,col=F2FFFFFF] [2.15,1.02,z=0.00000,col=F2FFFFFF] [1.30,-1.57,z=0.00000,col=F2FFFFFF] [0.76,-1.02,z=0.00000,col=F2FFFFFF] [-0.68,1.02,z=0.00000,col=9DFFFFFF] [-0.24,1.81,z=0.00000,col=9DFFFFFF] [1.35,-1.02,z=0.00000,col=9DFFFFFF] [0.91,-1.81,z=0.00000,col=9DFFFFFF]
|
||||
27 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0AEF0000 1280x768 fmt=6]
|
||||
vb=0x14D510B0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,1.00,z=0.00000,col=FFFFFFFF] [1.00,-1.00,z=0.00000,col=FFFFFFFF] [-1.00,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
28 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0x5773DC18083C4C20 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF
|
||||
vb=0x14D51110 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000,col=40000000] [1.00,1.00,z=0.00000,col=40000000] [1.00,-1.00,z=0.00000,col=40000000] [-1.00,-1.00,z=0.00000,col=40000000]
|
||||
29 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D51170 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.64,1.00,z=0.00000,col=C0FFFFFF] [0.64,1.00,z=0.00000,col=C0FFFFFF] [0.64,-1.00,z=0.00000,col=C0FFFFFF] [-0.64,-1.00,z=0.00000,col=C0FFFFFF]
|
||||
30 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0BA60000 1280x768 fmt=6]
|
||||
vb=0x14D511D0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.54,1.00,z=0.00000,col=FFFFFFFF] [0.54,1.00,z=0.00000,col=FFFFFFFF] [0.54,-1.00,z=0.00000,col=FFFFFFFF] [-0.54,-1.00,z=0.00000,col=FFFFFFFF]
|
||||
31 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x01010101[c:src=1 op=0 dst=1 a:src=1 op=0 dst=1] cc=0x8700000C mask=0xF tex[base=0x0C340000 1280x768 fmt=6]
|
||||
vb=0x14D51230 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.31,0.70,z=0.00000,col=FFFFFFFF] [0.07,0.70,z=0.00000,col=FFFFFFFF] [0.07,-0.08,z=0.00000,col=FFFFFFFF] [-0.31,-0.08,z=0.00000,col=FFFFFFFF] [-0.09,0.26,z=0.00000,col=FFFFFFFF] [0.31,0.26,z=0.00000,col=FFFFFFFF] [0.31,-0.60,z=0.00000,col=FFFFFFFF] [-0.09,-0.60,z=0.00000,col=FFFFFFFF]
|
||||
32 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x0B2C0000 1280x768 fmt=6]
|
||||
vb=0x14D512F0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.18,-0.65,z=0.00000,col=FFFFFFFF] [0.17,-0.65,z=0.00000,col=FFFFFFFF] [0.17,-0.76,z=0.00000,col=FFFFFFFF] [-0.18,-0.76,z=0.00000,col=FFFFFFFF]
|
||||
33 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x11C30000 1280x768 fmt=6]
|
||||
vb=0x14D51350 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.23,0.55,z=0.00000,col=FFFFFFFF] [-0.17,0.58,z=0.00000,col=FFFFFFFF] [-0.15,0.46,z=0.00000,col=FFFFFFFF] [-0.21,0.43,z=0.00000,col=FFFFFFFF] [-0.16,0.57,z=0.00000,col=FFFFFFFF] [0.17,0.57,z=0.00000,col=FFFFFFFF] [0.17,0.42,z=0.00000,col=FFFFFFFF] [-0.16,0.42,z=0.00000,col=FFFFFFFF]
|
||||
34 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
35 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 blend=0x07010701[c:src=1 op=0 dst=7 a:src=1 op=0 dst=7] cc=0x8700000C mask=0xF tex[base=0x10000000 1x1 fmt=26]
|
||||
109
docs/re/data/ui-blend-mode-measured.txt
Normal file
109
docs/re/data/ui-blend-mode-measured.txt
Normal file
@@ -0,0 +1,109 @@
|
||||
# The UI blend mode, MEASURED from the running game. 2026-08-31.
|
||||
#
|
||||
# Question: the port's renderer composites every UI element with straight
|
||||
# alpha-over, and four elements come out too dark against the capture --
|
||||
# ptframe1/ptframe2 on the main menu and ptframe3/ptframe4 on EXTRAS -- with the
|
||||
# shortfall correlating with the BACKGROUND. Nothing on the disc selects a
|
||||
# per-element mode (docs/re/structures/t32-blend-mode-not-on-disc.md, reach:
|
||||
# declaration entry, T8aD header word- and bit-wise, keyframe record).
|
||||
#
|
||||
# Method: Canary's CaptureUiDrawForRE was extended to log RB_BLENDCONTROL0,
|
||||
# RB_COLORCONTROL and RB_COLOR_MASK per draw. One emulator, driven to the main
|
||||
# menu and then to EXTRAS, F10 at each. Elements are identified by the PIXEL SIZE
|
||||
# of their quad (NDC extents x the 1280x720 surface) against sprite dimensions
|
||||
# read off the disc -- the log names no elements.
|
||||
#
|
||||
# Xenos enum (xenos.h): BlendFactor kZero=0 kOne=1 kSrcAlpha=6 kOneMinusSrcAlpha=7;
|
||||
# BlendOp kAdd=0. RB_BLENDCONTROL0 = src | op<<5 | dst<<8, colour in the low half
|
||||
# and alpha in the high half.
|
||||
#
|
||||
# 0x00010001 src=ONE dst=ZERO opaque -- blending effectively off
|
||||
# 0x07010701 src=ONE dst=ONE_MINUS_SRC_A alpha-over, PREMULTIPLIED (src is ONE)
|
||||
# 0x01010101 src=ONE dst=ONE ADDITIVE
|
||||
#
|
||||
# CONTROL, run before reading anything below: the two rotated sweep strips were
|
||||
# measured independently at 1134 and 1303 px tall
|
||||
# (docs/re/data/title-sweep-drawn-at-rest.txt). The NDC->pixel conversion here
|
||||
# reproduces BOTH, on BOTH screens. The tool prints PASS/FAIL and refuses to be
|
||||
# trusted otherwise.
|
||||
#
|
||||
# SECOND CONTROL, and it is the one that makes this a blend result rather than a
|
||||
# shader result: ONE pixel shader, 0xE59B2B3DA4AA9008, is used with BOTH states
|
||||
# on the main menu -- 12 draws additive and 18 alpha-over. The frames and ptbase
|
||||
# run the same shader. Only the blend register differs.
|
||||
|
||||
=== main menu (GP_TITLE build 5), 36 draws over 5 frames ===
|
||||
draw prim idx blend state quad px (w x h) best name match
|
||||
1 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
2 13 8 0x01010101 ADDITIVE 889.6 x 1134.0 (no match, nearest pteff12.t32 @2x off 610)
|
||||
2 13 8 0x01010101 ADDITIVE 1299.2 x 1303.2 (no match, nearest ptbase.t32 @2x off 602)
|
||||
3 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
4 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
5 13 4 0x01010101 ADDITIVE 819.2 x 720.0 (no match, nearest pteff12.t32 @2x off 125)
|
||||
6 13 4 0x01010101 ADDITIVE 691.2 x 720.0 pteff12.t32 @2x
|
||||
7 13 8 0x01010101 ADDITIVE 243.2 x 280.8 ptframe1.t32 @1x
|
||||
7 13 8 0x01010101 ADDITIVE 256.0 x 309.6 ptframe2.t32 @1x
|
||||
8 13 4 0x07010701 alpha-over(premul) 224.0 x 39.6 ptmsg.t32 @1x
|
||||
9 13 24 0x07010701 alpha-over(premul) 51.2 x 46.8 (no match, nearest ptbtneff01.t32 @1x off 10)
|
||||
9 13 24 0x07010701 alpha-over(premul) 211.2 x 54.0 ptbtn01f.t32 @1x
|
||||
13 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
14 13 8 0x01010101 ADDITIVE 889.6 x 1134.0 (no match, nearest pteff12.t32 @2x off 610)
|
||||
14 13 8 0x01010101 ADDITIVE 1299.2 x 1303.2 (no match, nearest ptbase.t32 @2x off 602)
|
||||
15 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
16 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
17 13 4 0x01010101 ADDITIVE 819.2 x 720.0 (no match, nearest pteff12.t32 @2x off 125)
|
||||
18 13 4 0x01010101 ADDITIVE 691.2 x 720.0 pteff12.t32 @2x
|
||||
19 13 8 0x01010101 ADDITIVE 243.2 x 280.8 ptframe1.t32 @1x
|
||||
19 13 8 0x01010101 ADDITIVE 256.0 x 309.6 ptframe2.t32 @1x
|
||||
20 13 4 0x07010701 alpha-over(premul) 224.0 x 39.6 ptmsg.t32 @1x
|
||||
21 13 24 0x07010701 alpha-over(premul) 64.0 x 61.2 (no match, nearest ptbtneff01.t32 @1x off 37)
|
||||
21 13 24 0x07010701 alpha-over(premul) 211.2 x 54.0 ptbtn01f.t32 @1x
|
||||
25 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
26 13 8 0x01010101 ADDITIVE 889.6 x 1134.0 (no match, nearest pteff12.t32 @2x off 610)
|
||||
26 13 8 0x01010101 ADDITIVE 1299.2 x 1303.2 (no match, nearest ptbase.t32 @2x off 602)
|
||||
27 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
28 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
29 13 4 0x01010101 ADDITIVE 819.2 x 720.0 (no match, nearest pteff12.t32 @2x off 125)
|
||||
30 13 4 0x01010101 ADDITIVE 691.2 x 720.0 pteff12.t32 @2x
|
||||
31 13 8 0x01010101 ADDITIVE 243.2 x 280.8 ptframe1.t32 @1x
|
||||
31 13 8 0x01010101 ADDITIVE 256.0 x 309.6 ptframe2.t32 @1x
|
||||
32 13 4 0x07010701 alpha-over(premul) 224.0 x 39.6 ptmsg.t32 @1x
|
||||
33 13 24 0x07010701 alpha-over(premul) 51.2 x 54.0 (no match, nearest ptbtneff01.t32 @1x off 17)
|
||||
33 13 24 0x07010701 alpha-over(premul) 211.2 x 54.0 ptbtn01f.t32 @1x
|
||||
|
||||
CONTROL — the two rotated sweep strips measured independently at 1134 and 1303 px:
|
||||
tall quads found: ['1134', '1303']
|
||||
PASS
|
||||
|
||||
=== EXTRAS (GP_TITLE build 6), 22 draws over 4 frames ===
|
||||
draw prim idx blend state quad px (w x h) best name match
|
||||
1 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
2 13 4 0x01010101 ADDITIVE 883.2 x 1134.0 (no match, nearest ptbase.t32 @2x off 811)
|
||||
3 13 4 0x01010101 ADDITIVE 1299.2 x 1303.2 (no match, nearest ptbase.t32 @2x off 602)
|
||||
4 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
5 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
6 13 4 0x01010101 ADDITIVE 819.2 x 720.0 (no match, nearest pteff03.t32 @2x off 381)
|
||||
7 13 24 0x01010101 ADDITIVE 614.4 x 518.4 pteff20.t32 @2x
|
||||
7 13 24 0x01010101 ADDITIVE 243.2 x 219.6 ptframe3.t32 @1x
|
||||
8 13 24 0x07010701 alpha-over(premul) 352.0 x 39.6 ptmsg2.t32 @1x
|
||||
8 13 24 0x07010701 alpha-over(premul) 179.2 x 32.4 pttitle.t32 @1x
|
||||
12 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
13 13 4 0x01010101 ADDITIVE 889.6 x 1134.0 (no match, nearest ptbase.t32 @2x off 804)
|
||||
14 13 4 0x01010101 ADDITIVE 1299.2 x 1303.2 (no match, nearest ptbase.t32 @2x off 602)
|
||||
15 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
16 13 4 0x07010701 alpha-over(premul) 1280.0 x 720.0 ptbase.t32 @2x
|
||||
17 13 4 0x01010101 ADDITIVE 819.2 x 720.0 (no match, nearest pteff03.t32 @2x off 381)
|
||||
18 13 24 0x01010101 ADDITIVE 614.4 x 518.4 pteff20.t32 @2x
|
||||
18 13 24 0x01010101 ADDITIVE 243.2 x 219.6 ptframe3.t32 @1x
|
||||
19 13 24 0x07010701 alpha-over(premul) 352.0 x 39.6 ptmsg2.t32 @1x
|
||||
19 13 24 0x07010701 alpha-over(premul) 179.2 x 32.4 pttitle.t32 @1x
|
||||
|
||||
CONTROL — the two rotated sweep strips measured independently at 1134 and 1303 px:
|
||||
tall quads found: ['1134', '1303']
|
||||
PASS
|
||||
|
||||
=== shader x blend cross-tab, main menu ===
|
||||
3 ps=0x2E372EA28CC404B7 blend=0x00010001
|
||||
3 ps=0x5773DC18083C4C20 blend=0x07010701
|
||||
12 ps=0xE59B2B3DA4AA9008 blend=0x01010101
|
||||
18 ps=0xE59B2B3DA4AA9008 blend=0x07010701
|
||||
105
docs/re/structures/ui-blend-mode-measured.md
Normal file
105
docs/re/structures/ui-blend-mode-measured.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# The UI blend mode — ✅ **MEASURED**: the frames are drawn **ADDITIVE**
|
||||
|
||||
**Status:** ✅ `CONFIRMED`, classification **measured** — nothing on the disc
|
||||
selects it, and this is what the running game tells the GPU, per draw, on two
|
||||
screens. 2026-08-31.
|
||||
|
||||
Closes the one route
|
||||
[`t32-blend-mode-not-on-disc.md`](t32-blend-mode-not-on-disc.md) left open: *"the
|
||||
executable's draw path, which is where a mode selected in code rather than data
|
||||
would live. That is a route, and it is the one left."*
|
||||
|
||||
## The answer
|
||||
|
||||
The title-side UI uses **two blend states, and one pixel shader**:
|
||||
|
||||
| `RB_BLENDCONTROL0` | src | op | dst | what it is | drawn this way |
|
||||
|---|---|---|---|---|---|
|
||||
| `0x07010701` | `ONE` | ADD | `1−SRC_ALPHA` | **alpha-over, premultiplied** | `ptbase`, `pteff05`, the fade quad, `ptmsg`, `ptmsg2`, `pttitle`, every button |
|
||||
| `0x01010101` | `ONE` | ADD | `ONE` | **ADDITIVE** | **`ptframe1`, `ptframe2`, `ptframe3`**, `pteff20`, both rotated sweep strips |
|
||||
| `0x00010001` | `ONE` | ADD | `ZERO` | opaque, blending off | the one non-UI blit that opens the frame |
|
||||
|
||||
Reference data and both raw logs:
|
||||
[`data/ui-blend-mode-measured.txt`](../data/ui-blend-mode-measured.txt) ·
|
||||
[`captures/ui-draws/blend-main-menu-2026-08-31.log`](../captures/ui-draws/blend-main-menu-2026-08-31.log) ·
|
||||
[`captures/ui-draws/blend-extras-2026-08-31.log`](../captures/ui-draws/blend-extras-2026-08-31.log)
|
||||
|
||||
## How it was measured
|
||||
|
||||
Canary's `CaptureUiDrawForRE` already dumped every UI draw in submission order
|
||||
with its shaders and bound texture. It was extended to log `RB_BLENDCONTROL0`,
|
||||
`RB_COLORCONTROL` and `RB_COLOR_MASK` as well — **raw and decoded**, so a decode
|
||||
bug here cannot quietly become the answer. One emulator, driven to the main menu
|
||||
and then into `EXTRAS`, F10 at each.
|
||||
|
||||
The log names no elements, so a draw is identified by the **pixel size of its
|
||||
quad**: NDC extents × the 1280×720 surface, matched against sprite dimensions
|
||||
read straight off the disc ([`tools/re-capture/ui_blend_map.py`](../../../tools/re-capture/ui_blend_map.py)).
|
||||
|
||||
### The controls, both run before the result was read
|
||||
|
||||
**1. The size conversion reproduces two independently measured numbers.** The
|
||||
title's two rotated sweep strips were measured at **1134** and **1303** px tall
|
||||
in [`data/title-sweep-drawn-at-rest.txt`](../data/title-sweep-drawn-at-rest.txt),
|
||||
by a different tool in a different session. This conversion produces `1134.0` and
|
||||
`1303.2` — **on both screens**. The tool prints `PASS`/`FAIL` and says outright
|
||||
that its sizes are worthless if the check fails.
|
||||
|
||||
**2. It is the blend register, not a different shader.** Pixel shader
|
||||
`0xE59B2B3DA4AA9008` is used with **both** states on the main menu — 12 draws
|
||||
additive, 18 alpha-over. `ptframe1` and `ptbase` run the *same shader*; only the
|
||||
blend differs. Without this the result could have been "the frames use a
|
||||
different shader", which is a different finding.
|
||||
|
||||
## The identification, from the artefact
|
||||
|
||||
| draw | quad px | disc sprite | blend |
|
||||
|---|---|---|---|
|
||||
| menu 7 | 243.2 × 280.8 | `ptframe1.t32` **247×281** | **ADDITIVE** |
|
||||
| menu 7 | 256.0 × 309.6 | `ptframe2.t32` **257×311** | **ADDITIVE** |
|
||||
| menu 8 | 224.0 × 39.6 | `ptmsg.t32` **223×38** | alpha-over |
|
||||
| menu 9 | 211.2 × 54.0 | `ptbtn01f.t32` **216×56** | alpha-over |
|
||||
| extras 7 | 243.2 × 219.6 | `ptframe3.t32` **246×220** | **ADDITIVE** |
|
||||
| extras 7 | 614.4 × 518.4 | `pteff20.t32` **309×259** @2× | **ADDITIVE** |
|
||||
| extras 8 | 352.0 × 39.6 | `ptmsg2.t32` **354×38** | alpha-over |
|
||||
| extras 8 | 179.2 × 32.4 | `pttitle.t32` **182×34** | alpha-over |
|
||||
|
||||
`ptframe1` and `ptframe2` are in **one draw call**; so are `pteff20` and
|
||||
`ptframe3`. A draw call carries one blend state, so elements that share a mode
|
||||
are **batched together** — which is also why `ptframe4` needs no separate
|
||||
argument: it is inside `EXTRAS`' 24-index additive batch with `ptframe3`.
|
||||
|
||||
## What this settles, and what it does not
|
||||
|
||||
✅ **The port's independent measurement is confirmed by the oracle.** It solved
|
||||
the composite per pixel from two backgrounds and found additive halves
|
||||
alpha-over's error on both frames (34.305/28.948 against 65.046/71.299). Two
|
||||
methods with nothing in common — a solved composite against a capture, and the
|
||||
register the GPU was handed — give the same answer.
|
||||
|
||||
✅ **This is no longer authored.** The [not-on-disc page](t32-blend-mode-not-on-disc.md)
|
||||
concluded *"any blend you choose is authored and must carry that label"*. That was
|
||||
true of the **disc**; it is not true any more of the **game**. Additive is
|
||||
measured, and the port can transcribe it.
|
||||
|
||||
⚠️ **`src = ONE`, not `SRC_ALPHA`, in BOTH states.** The fixed-function blend
|
||||
multiplies the pixel shader's output by 1, so whatever alpha weighting happens,
|
||||
the *shader* does it. This says nothing about whether the `.t32` texels are
|
||||
stored premultiplied — that is a separate question, and the shader is unread.
|
||||
|
||||
❔ **Where the mode is selected is still unknown.** This measures *what* the GPU
|
||||
was told, not *which field* decided it. The disc-side search found nothing
|
||||
([reach here](t32-blend-mode-not-on-disc.md)), and the batching means the
|
||||
selection happens before the draw, in whatever sorts the elements. So the port
|
||||
should read this table as a per-element fact it can transcribe, **not** as a rule
|
||||
it can extend to elements not in it.
|
||||
|
||||
❔ **Two additive draws on the menu are unidentified** — 819.2×720 and 691.2×720.
|
||||
The second is within 8 px of `pteff12` @2×; the first matches nothing on the
|
||||
screen at either scale. Both are additive, so they do not change the answer, and
|
||||
neither is guessed at here.
|
||||
|
||||
⚠️ **Reach.** Two screens, one session, one emulator. Every element on the two
|
||||
screens the port ships is in the table except the two above and `pteff10`, which
|
||||
did not appear as an identifiable quad. The title screen (build 4) was **not**
|
||||
captured.
|
||||
@@ -92,12 +92,19 @@ def main():
|
||||
w = (max(xs) - min(xs)) / 2 * W
|
||||
h = (max(ys) - min(ys)) / 2 * H
|
||||
heights.append(h)
|
||||
best, bd = "-", 1e9
|
||||
# A sprite is drawn at its native size or at 2x: the screen is
|
||||
# 1280x720 and the design space is 640x360, so `ptbase` (640x360)
|
||||
# covers the screen while `pteff05` (1280x720) is 1:1. Both are
|
||||
# tried and the scale is reported, because guessing one would
|
||||
# silently mis-name half the draws.
|
||||
best, bd, bs = "-", 1e9, 1
|
||||
for n, (sw, sh) in sizes.items():
|
||||
d = abs(sw - w) + abs(sh - h)
|
||||
if d < bd:
|
||||
best, bd = n, d
|
||||
tag = best if bd <= 6 else "(no match, nearest %s off %.0f)" % (best, bd)
|
||||
for sc in (1, 2):
|
||||
d = abs(sw * sc - w) + abs(sh * sc - h)
|
||||
if d < bd:
|
||||
best, bd, bs = n, d, sc
|
||||
tag = ("%s @%dx" % (best, bs)) if bd <= 8 else \
|
||||
"(no match, nearest %s @%dx off %.0f)" % (best, bs, bd)
|
||||
print("%4d %4d %4d 0x%08X %-20s %7.1f x %7.1f %s"
|
||||
% (idx, prim, nidx, raw, blend_name(raw), w, h, tag))
|
||||
tall = sorted(h for h in heights if h > 900)
|
||||
|
||||
Reference in New Issue
Block a user