Nugget
Loading...
Searching...
No Matches
raster-expected-phase17.h
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2026 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29// Phase-17 expected hardware-truth values for affine UV-mapping
30// characterization on SCPH-5501 silicon.
31//
32// HARDWARE FINDING (refined across rounds, 2026-05-19):
33// The 3-vertex textured-triangle sampler uses 16.16 fixed-point edge
34// accumulation with a +0x8000 (half-LSB) bias applied before the
35// shift-right to integer texel coordinates. This is functionally
36// pixel-center sampling: U/V at the row's pixel position equal
37// floor((m_leftV + delta * step + 0x8000) >> 16). T2 AR_COMPRESS
38// at (10, 7) returning V=1 (not the 0 a pure-truncate-of-0.6 would
39// give) is the cleanest probe of this rule: dV/dY = 3/10 per row,
40// V_accum at Y=7 in 16.16 is 39320, +0x8000 = 72088, >>16 = 1.
41//
42// This means phase-8's 4-vert finding ("hardware applies pixel-center
43// bias, Redux misses it") wasn't 3-vert-vs-4-vert hardware asymmetry.
44// The 3-vert sampler in soft.cc already had the bias; the 4-vert
45// sweep was missing it. Both paths converge on the same hardware
46// model after the phase-8 fix (commit b89abc47).
47//
48// Implication for the retire-4-vert-sweep proposal: routing quads
49// through (1,3,2)+(0,1,2) triangle decomposition (as untextured +
50// gouraud-textured quad paths already do) inherits the 3-vert
51// sampler which is already hardware-correct. The 4-vert sweep path
52// is structurally redundant with two 3-vert calls - decomposition is
53// the simpler form, no special bias mechanics needed. Hardware
54// itself decomposes quads to triangles internally, so decomposition
55// is also the more silicon-faithful form. This is the data Pixel
56// asked for: retiring the 4-vert sweep simplifies code and preserves
57// hardware-matching output.
58//
59// Workflow (since cester's malloc'd error queue caps detailed FAIL
60// output around 24 entries, the patch lands in batches):
61// 1. Run hardware. Capture first 24 EvaluationError lines.
62// 2. Patch HW_TODO -> HW_VERIFIED with captured values.
63// 3. Re-run. Now those 24 pass; cester emits details for next 24.
64// 4. Repeat until all macros are HW_VERIFIED.
65//
66// Shape battery (see affine-triangles.c / affine-quads.c):
67//
68// Triangles (8):
69// T1 AR_AXIS_BASE axis-aligned 1:1 sanity
70// T2 AR_COMPRESS UV span < screen span
71// T3 AR_STRETCH UV span > screen span
72// T4 AR_TWIST_90 UV axes swapped
73// T5 AR_TWIST_45 UV rotated 45 degrees
74// T6 AR_NATURAL arbitrary triangle + UV
75// T7 AR_NARROW_TALL cross-span step dominates (Round 2 capture)
76// T8 AR_FLAT_WIDE row edge step dominates (Round 2 capture)
77//
78// Quads (5) - decomposition validation: (Round 2/3 capture)
79// Q1 AQ_AXIS_BASE axis-aligned 1:1
80// Q2 AQ_TWIST_90 90 degree UV rotation
81// Q3 AQ_TRAPEZOID non-parallelogram
82// Q4 AQ_SKEW_NP skewed (seam-class probe)
83// Q5 AQ_COMPRESS_UV compressed UV on large quad
84
85#include "raster-helpers.h"
87
88#define HW_TODO 0xCAFEu
89
90// --------------------------------------------------------------------------
91// T1 AR_AXIS_BASE: A=(5,5)/(0,0) B=(25,5)/(20,0) C=(5,15)/(0,10)
92// 1:1 UV-to-screen mapping. Sampler at integer pixel = UV(x-5, y-5).
93// --------------------------------------------------------------------------
94
95#define EXPECT_AR_AXIS_BASE_10_8 0x2465u /* HW_VERIFIED: UV(5, 3) naive */
96#define EXPECT_AR_AXIS_BASE_20_6 0x442Fu /* HW_VERIFIED: UV(15, 1) naive */
97#define EXPECT_AR_AXIS_BASE_8_12 0x2CE3u /* HW_VERIFIED: UV(3, 7) naive */
98#define EXPECT_AR_AXIS_BASE_24_5 0x4C13u /* HW_VERIFIED: UV(19, 0) top-edge drawn */
99#define EXPECT_AR_AXIS_BASE_25_5 RASTER_SENTINEL /* HW_VERIFIED: B vertex excluded */
100
101// --------------------------------------------------------------------------
102// T2 AR_COMPRESS: A=(5,5)/(0,0) B=(35,5)/(6,0) C=(5,15)/(0,3)
103// dU/dx=0.2, dV/dy=0.3 sub-unit step. HW samples at integer pixel.
104// --------------------------------------------------------------------------
105
106#define EXPECT_AR_COMPRESS_10_7 0x0C21u /* HW_VERIFIED: UV(1, 1) */
107#define EXPECT_AR_COMPRESS_20_8 0x1423u /* HW_VERIFIED: UV(3, 1) */
108#define EXPECT_AR_COMPRESS_15_10 0x0C22u /* HW_VERIFIED: UV(2, 1) */
109#define EXPECT_AR_COMPRESS_30_5 0x1405u /* HW_VERIFIED: UV(5, 0) */
110
111// --------------------------------------------------------------------------
112// T3 AR_STRETCH: A=(5,5)/(0,0) B=(15,5)/(30,0) C=(5,10)/(0,20)
113// dU/dx=3, dV/dy=4 super-unit step. HW exactly naive (no pixel-center
114// bias) - probe (6,6) returns UV(3,4), not the (4,6) a pixel-center
115// model would produce. Confirms 3-vert naive-sampler rule.
116// --------------------------------------------------------------------------
117
118#define EXPECT_AR_STRETCH_6_6 0x1C83u /* HW_VERIFIED: UV(3, 4) */
119#define EXPECT_AR_STRETCH_10_7 0x5D0Fu /* HW_VERIFIED: UV(15, 8) */
120#define EXPECT_AR_STRETCH_8_8 0x5589u /* HW_VERIFIED: UV(9, 12) */
121#define EXPECT_AR_STRETCH_5_5 0x0400u /* HW_VERIFIED: UV(0, 0) A vertex drawn */
122
123// --------------------------------------------------------------------------
124// T4 AR_TWIST_90: A=(4,4)/(0,0) B=(20,4)/(0,16) C=(4,20)/(16,0)
125// UV axes swapped. UV(x, y) = (y - 4, x - 4) inside triangle. Matched
126// mechanical pre-run prediction exactly: probe (10,10) -> 0x34C6.
127// --------------------------------------------------------------------------
128
129#define EXPECT_AR_TWIST_90_10_10 0x34C6u /* HW_VERIFIED: UV(6, 6) - pre-run trace match */
130#define EXPECT_AR_TWIST_90_6_10 0x2446u /* HW_VERIFIED: UV(6, 2) */
131#define EXPECT_AR_TWIST_90_10_6 0x24C2u /* HW_VERIFIED: UV(2, 6) */
132#define EXPECT_AR_TWIST_90_4_4 0x0400u /* HW_VERIFIED: UV(0, 0) A vertex drawn */
133
134// --------------------------------------------------------------------------
135// T5 AR_TWIST_45: A=(4,4)/(8,0) B=(20,4)/(16,8) C=(4,20)/(0,8)
136// UV rotated 45 degrees. UV(x, y) = (8 + 0.5(x-y), 0.5(x+y-8)).
137// --------------------------------------------------------------------------
138
139#define EXPECT_AR_TWIST_45_12_4 0x448Cu /* HW_VERIFIED: UV(12, 4) AB mid */
140#define EXPECT_AR_TWIST_45_4_12 0x2484u /* HW_VERIFIED: UV(4, 4) AC mid */
141#define EXPECT_AR_TWIST_45_8_8 0x3488u /* HW_VERIFIED: UV(8, 4) interior */
142#define EXPECT_AR_TWIST_45_12_12 RASTER_SENTINEL /* HW_VERIFIED: (12,12) on hypotenuse BC, excluded (top-left rule on right edge) */
143
144// --------------------------------------------------------------------------
145// T6 AR_NATURAL: A=(5,5)/(3,2) B=(25,9)/(20,5) C=(8,22)/(8,22)
146// Arbitrary triangle, arbitrary UV. Affine via inverse linear map.
147// --------------------------------------------------------------------------
148
149#define EXPECT_AR_NATURAL_12_10 0x44E9u /* HW_VERIFIED: UV(9, 7) */
150#define EXPECT_AR_NATURAL_18_15 RASTER_SENTINEL /* HW_VERIFIED: (18,15) outside tri (right of edge BC) */
151#define EXPECT_AR_NATURAL_10_18 0x6E29u /* HW_VERIFIED: UV(9, 17) */
152#define EXPECT_AR_NATURAL_5_5 RASTER_SENTINEL /* HW_VERIFIED: A vertex excluded (top-left rule for non-axis-aligned A) */
153
154// --------------------------------------------------------------------------
155// T7 AR_NARROW_TALL: A=(10,4)/(0,0) B=(14,4)/(20,0) C=(12,24)/(10,30)
156// Tall+thin triangle (4 wide, 20 tall). Cross-span UV step >> row edge step.
157// --------------------------------------------------------------------------
158
159#define EXPECT_AR_NARROW_TALL_11_8 0x2CC5u /* HW_VERIFIED: UV(5, 6) */
160#define EXPECT_AR_NARROW_TALL_12_14 0x65EAu /* HW_VERIFIED: UV(10, 15) */
161#define EXPECT_AR_NARROW_TALL_11_20 RASTER_SENTINEL /* HW_VERIFIED: pixel (11,20) outside narrow tri (left of left edge) */
162#define EXPECT_AR_NARROW_TALL_13_6 0x4C6Fu /* HW_VERIFIED: UV(15, 3) */
163
164// --------------------------------------------------------------------------
165// T8 AR_FLAT_WIDE: A=(4,8)/(0,0) B=(34,9)/(30,0) C=(4,11)/(0,4)
166// Wide+flat triangle (30 wide, 3 tall). Row edge step >> cross-span step.
167// --------------------------------------------------------------------------
168
169#define EXPECT_AR_FLAT_WIDE_8_9 0x1424u /* HW_VERIFIED: UV(4, 1) */
170#define EXPECT_AR_FLAT_WIDE_20_9 0x4430u /* HW_VERIFIED: UV(16, 1) */
171#define EXPECT_AR_FLAT_WIDE_30_9 0x6C1Au /* HW_VERIFIED: UV(26, 0) */
172#define EXPECT_AR_FLAT_WIDE_6_10 0x1462u /* HW_VERIFIED: UV(2, 3) */
173
174// --------------------------------------------------------------------------
175// Q1 AQ_AXIS_BASE: v0=(5,5)/(0,0) v1=(20,5)/(15,0) v2=(5,15)/(0,10) v3=(20,15)/(15,10)
176// 4-vert flat-textured quad output matches hardware at axis-aligned 1:1.
177// --------------------------------------------------------------------------
178
179#define EXPECT_AQ_AXIS_BASE_8_8 0x1C63u /* HW_VERIFIED: UV(3, 3) */
180#define EXPECT_AQ_AXIS_BASE_15_10 0x3CAAu /* HW_VERIFIED: UV(10, 5) */
181#define EXPECT_AQ_AXIS_BASE_5_14 0x2520u /* HW_VERIFIED: UV(0, 9) */
182#define EXPECT_AQ_AXIS_BASE_20_5 RASTER_SENTINEL /* HW_VERIFIED: v1 column excluded */
183
184// --------------------------------------------------------------------------
185// Q2 AQ_TWIST_90: v0=(5,5)/(0,0) v1=(20,5)/(0,15) v2=(5,18)/(13,0) v3=(20,18)/(13,15)
186// 90-degree UV rotation. Decomposition's UV interp through the seam.
187// --------------------------------------------------------------------------
188
189#define EXPECT_AQ_TWIST_90_8_10 0x2465u /* HW_VERIFIED: UV(5, 3) */
190#define EXPECT_AQ_TWIST_90_15_13 0x4D48u /* HW_VERIFIED: UV(8, 10) */
191#define EXPECT_AQ_TWIST_90_12_8 0x2CE3u /* HW_VERIFIED: UV(3, 7) near seam */
192#define EXPECT_AQ_TWIST_90_12_11 0x34E6u /* HW_VERIFIED: UV(6, 7) near seam */
193
194// --------------------------------------------------------------------------
195// Q3 AQ_TRAPEZOID: v0=(8,5)/(0,0) v1=(20,5)/(15,0) v2=(5,18)/(0,13) v3=(23,18)/(15,13)
196// Non-parallelogram. Per-row pixel-count varies linearly.
197// --------------------------------------------------------------------------
198
199#define EXPECT_AQ_TRAPEZOID_12_8 0x2466u /* HW_VERIFIED: UV(6, 3) */
200#define EXPECT_AQ_TRAPEZOID_14_13 0x4508u /* HW_VERIFIED: UV(8, 8) */
201#define EXPECT_AQ_TRAPEZOID_8_15 0x3543u /* HW_VERIFIED: UV(3, 10) */
202#define EXPECT_AQ_TRAPEZOID_20_15 0x5D4Du /* HW_VERIFIED: UV(13, 10) */
203
204// --------------------------------------------------------------------------
205// Q4 AQ_SKEW_NP: v0=(5,5)/(0,0) v1=(20,8)/(12,0) v2=(8,22)/(0,12) v3=(25,18)/(12,12)
206// Skewed non-parallelogram. Every edge non-axis-aligned. Diagonal seam.
207// --------------------------------------------------------------------------
208
209#define EXPECT_AQ_SKEW_NP_12_10 0x2465u /* HW_VERIFIED: UV(5, 3) */
210#define EXPECT_AQ_SKEW_NP_15_14 0x34A7u /* HW_VERIFIED: UV(7, 5) */
211#define EXPECT_AQ_SKEW_NP_10_15 0x2CE3u /* HW_VERIFIED: UV(3, 7) */
212#define EXPECT_AQ_SKEW_NP_18_12 0x3489u /* HW_VERIFIED: UV(9, 4) along diagonal seam */
213
214// --------------------------------------------------------------------------
215// Q5 AQ_COMPRESS_UV: v0=(5,5)/(0,0) v1=(30,5)/(8,0) v2=(5,22)/(0,5) v3=(30,22)/(8,5)
216// 25x17 screen -> 8x5 UV. Texture stretched. (Round-3 capture for 3 remain.)
217// --------------------------------------------------------------------------
218
219#define EXPECT_AQ_COMPRESS_UV_10_8 0x0C22u /* HW_VERIFIED: UV(2, 1) */
220#define EXPECT_AQ_COMPRESS_UV_20_15 0x2465u /* HW_VERIFIED: UV(5, 3) */
221#define EXPECT_AQ_COMPRESS_UV_15_10 0x1423u /* HW_VERIFIED: UV(3, 1) */
222#define EXPECT_AQ_COMPRESS_UV_29_21 0x34A8u /* HW_VERIFIED: UV(8, 5) near corner */