Nugget
Loading...
Searching...
No Matches
stride-sweep.c
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// Phase-18 affine UV stride-magnitude sweep. Six triangles, identical
28// 10x10 screen footprint, varying K controls the per-axis UV stride:
29//
30// T_AXIS_K: A=(5, 5)/(0, 0) B=(15, 5)/(K, 0) C=(5, 15)/(0, K)
31//
32// Per-axis stride is K/10 (equal for U and V). K covers a wide range so
33// the hardware-sampled (u, v) plotted against K reveals which bias
34// model the GPU implements. Five probes per K, identical screen
35// positions across all K.
36
38
39// ---- T_AXIS_K01: dU/dx = dV/dy = 0.1 (very compressed) -----------------
40static void drawT_AXIS_K01(void) {
41 rasterReset();
42 rasterClearTestRegion(0, 0, 24, 16);
43 setTexpage(TEX17_TX, TEX17_TY, 2);
44 setTextureWindow(0, 0, 0, 0);
45 rasterTexTri(TEX_MOD_NEUTRAL,
46 5, 5, 0, 0,
47 15, 5, 1, 0,
48 5, 15, 0, 1,
50 rasterFlushPrimitive();
51}
52
53// ---- T_AXIS_K02: dU/dx = dV/dy = 0.2 ----------------------------------
54static void drawT_AXIS_K02(void) {
55 rasterReset();
56 rasterClearTestRegion(0, 0, 24, 16);
57 setTexpage(TEX17_TX, TEX17_TY, 2);
58 setTextureWindow(0, 0, 0, 0);
59 rasterTexTri(TEX_MOD_NEUTRAL,
60 5, 5, 0, 0,
61 15, 5, 2, 0,
62 5, 15, 0, 2,
64 rasterFlushPrimitive();
65}
66
67// ---- T_AXIS_K03: dU/dx = dV/dy = 0.3 ----------------------------------
68static void drawT_AXIS_K03(void) {
69 rasterReset();
70 rasterClearTestRegion(0, 0, 24, 16);
71 setTexpage(TEX17_TX, TEX17_TY, 2);
72 setTextureWindow(0, 0, 0, 0);
73 rasterTexTri(TEX_MOD_NEUTRAL,
74 5, 5, 0, 0,
75 15, 5, 3, 0,
76 5, 15, 0, 3,
78 rasterFlushPrimitive();
79}
80
81// ---- T_AXIS_K05: dU/dx = dV/dy = 0.5 (right at the half-step boundary) -
82static void drawT_AXIS_K05(void) {
83 rasterReset();
84 rasterClearTestRegion(0, 0, 24, 16);
85 setTexpage(TEX17_TX, TEX17_TY, 2);
86 setTextureWindow(0, 0, 0, 0);
87 rasterTexTri(TEX_MOD_NEUTRAL,
88 5, 5, 0, 0,
89 15, 5, 5, 0,
90 5, 15, 0, 5,
92 rasterFlushPrimitive();
93}
94
95// ---- T_AXIS_K08: dU/dx = dV/dy = 0.8 (near 1:1) ------------------------
96static void drawT_AXIS_K08(void) {
97 rasterReset();
98 rasterClearTestRegion(0, 0, 24, 16);
99 setTexpage(TEX17_TX, TEX17_TY, 2);
100 setTextureWindow(0, 0, 0, 0);
101 rasterTexTri(TEX_MOD_NEUTRAL,
102 5, 5, 0, 0,
103 15, 5, 8, 0,
104 5, 15, 0, 8,
106 rasterFlushPrimitive();
107}
108
109// ---- T_AXIS_K16: dU/dx = dV/dy = 1.6 (stretched) -----------------------
110static void drawT_AXIS_K16(void) {
111 rasterReset();
112 rasterClearTestRegion(0, 0, 24, 16);
113 setTexpage(TEX17_TX, TEX17_TY, 2);
114 setTextureWindow(0, 0, 0, 0);
115 rasterTexTri(TEX_MOD_NEUTRAL,
116 5, 5, 0, 0,
117 15, 5, 16, 0,
118 5, 15, 0, 16,
120 rasterFlushPrimitive();
121}
122
123) // CESTER_BODY
124
125// --------------------------------------------------------------------------
126// K=1 probes (stride = 0.1 per axis)
127// --------------------------------------------------------------------------
128
129CESTER_TEST(ar_axis_k01_vertex, gpu_raster_phase18,
130 drawT_AXIS_K01();
132)
133
134CESTER_TEST(ar_axis_k01_top_near, gpu_raster_phase18,
135 drawT_AXIS_K01();
137)
138
139CESTER_TEST(ar_axis_k01_left_near, gpu_raster_phase18,
140 drawT_AXIS_K01();
142)
143
144CESTER_TEST(ar_axis_k01_interior, gpu_raster_phase18,
145 drawT_AXIS_K01();
147)
148
149CESTER_TEST(ar_axis_k01_top_far, gpu_raster_phase18,
150 drawT_AXIS_K01();
152)
153
154// --------------------------------------------------------------------------
155// K=2 probes (stride = 0.2 per axis)
156// --------------------------------------------------------------------------
157
158CESTER_TEST(ar_axis_k02_vertex, gpu_raster_phase18,
159 drawT_AXIS_K02();
161)
162
163CESTER_TEST(ar_axis_k02_top_near, gpu_raster_phase18,
164 drawT_AXIS_K02();
166)
167
168CESTER_TEST(ar_axis_k02_left_near, gpu_raster_phase18,
169 drawT_AXIS_K02();
171)
172
173CESTER_TEST(ar_axis_k02_interior, gpu_raster_phase18,
174 drawT_AXIS_K02();
176)
177
178CESTER_TEST(ar_axis_k02_top_far, gpu_raster_phase18,
179 drawT_AXIS_K02();
181)
182
183// --------------------------------------------------------------------------
184// K=3 probes (stride = 0.3 per axis)
185// --------------------------------------------------------------------------
186
187CESTER_TEST(ar_axis_k03_vertex, gpu_raster_phase18,
188 drawT_AXIS_K03();
190)
191
192CESTER_TEST(ar_axis_k03_top_near, gpu_raster_phase18,
193 drawT_AXIS_K03();
195)
196
197CESTER_TEST(ar_axis_k03_left_near, gpu_raster_phase18,
198 drawT_AXIS_K03();
200)
201
202CESTER_TEST(ar_axis_k03_interior, gpu_raster_phase18,
203 drawT_AXIS_K03();
205)
206
207CESTER_TEST(ar_axis_k03_top_far, gpu_raster_phase18,
208 drawT_AXIS_K03();
210)
211
212// --------------------------------------------------------------------------
213// K=5 probes (stride = 0.5 per axis - right at the half-step boundary)
214// --------------------------------------------------------------------------
215
216CESTER_TEST(ar_axis_k05_vertex, gpu_raster_phase18,
217 drawT_AXIS_K05();
219)
220
221CESTER_TEST(ar_axis_k05_top_near, gpu_raster_phase18,
222 drawT_AXIS_K05();
224)
225
226CESTER_TEST(ar_axis_k05_left_near, gpu_raster_phase18,
227 drawT_AXIS_K05();
229)
230
231CESTER_TEST(ar_axis_k05_interior, gpu_raster_phase18,
232 drawT_AXIS_K05();
234)
235
236CESTER_TEST(ar_axis_k05_top_far, gpu_raster_phase18,
237 drawT_AXIS_K05();
239)
240
241// --------------------------------------------------------------------------
242// K=8 probes (stride = 0.8 per axis - near 1:1)
243// --------------------------------------------------------------------------
244
245CESTER_TEST(ar_axis_k08_vertex, gpu_raster_phase18,
246 drawT_AXIS_K08();
248)
249
250CESTER_TEST(ar_axis_k08_top_near, gpu_raster_phase18,
251 drawT_AXIS_K08();
253)
254
255CESTER_TEST(ar_axis_k08_left_near, gpu_raster_phase18,
256 drawT_AXIS_K08();
258)
259
260CESTER_TEST(ar_axis_k08_interior, gpu_raster_phase18,
261 drawT_AXIS_K08();
263)
264
265CESTER_TEST(ar_axis_k08_top_far, gpu_raster_phase18,
266 drawT_AXIS_K08();
268)
269
270// --------------------------------------------------------------------------
271// K=16 probes (stride = 1.6 per axis - stretched)
272// --------------------------------------------------------------------------
273
274CESTER_TEST(ar_axis_k16_vertex, gpu_raster_phase18,
275 drawT_AXIS_K16();
277)
278
279CESTER_TEST(ar_axis_k16_top_near, gpu_raster_phase18,
280 drawT_AXIS_K16();
282)
283
284CESTER_TEST(ar_axis_k16_left_near, gpu_raster_phase18,
285 drawT_AXIS_K16();
287)
288
289CESTER_TEST(ar_axis_k16_interior, gpu_raster_phase18,
290 drawT_AXIS_K16();
292)
293
294CESTER_TEST(ar_axis_k16_top_far, gpu_raster_phase18,
295 drawT_AXIS_K16();
297)
CESTER_BODY(static int s_got40;static int s_got80;static uint32_t s_cause;static uint32_t s_epc;static uint32_t s_from;static uint32_t *s_resume;static uint32_t *s_regs;static uint32_t(*s_customhandler)()=NULL;static uint32_t s_oldIMASK;static uint32_t s_oldDPCR;static uint32_t s_oldDICR;uint32_t handler(uint32_t *regs, uint32_t from) { if(from==0x40) s_got40=1;if(from==0x80) s_got80=1;uint32_t cause;uint32_t epc;s_from=from;asm("mfc0 %0, $13\nnop\nmfc0 %1, $14\nnop" :"=r"(cause), "=r"(epc));s_cause=cause;s_epc=epc;if(s_customhandler) { return s_customhandler();} else { return s_resume ?((uint32_t) s_resume) :(epc+4);} } void installExceptionHandlers(uint32_t(*handler)(uint32_t *regs, uint32_t from));void uninstallExceptionHandlers();uint32_t branchbranch1();uint32_t branchbranch2();uint32_t jumpjump1();uint32_t jumpjump2();uint32_t cpu_LWR_LWL_half(uint32_t buff[], uint32_t initial);uint32_t cpu_LWR_LWL_nodelay(uint32_t buff[], uint32_t initial);uint32_t cpu_LWR_LWL_delayed(uint32_t buff[], uint32_t initial);uint32_t cpu_LWR_LWL_load_different(uint32_t buff[], uint32_t initial);uint32_t cpu_LW_LWR(uint32_t buff[], uint32_t initial);uint32_t cpu_delayed_load(uint32_t buff[], uint32_t override);uint32_t cpu_delayed_load_cancelled(uint32_t buff[], uint32_t override);uint64_t cpu_delayed_load_load(uint32_t buff[], uint32_t override);uint32_t linkandload();uint32_t lwandlink();uint32_t nolink();static int s_interruptsWereEnabled;) CESTER_BEFORE_EACH(cpu_tests
CESTER_TEST(cpu_cop0_basic_write_bp, cpu_tests, uint32_t expectedEPC;uint32_t t;volatile uint32_t *ptr=(volatile uint32_t *) 0x58; *ptr=1;__asm__ volatile("" " lui %0, 0b1100101010000000\n" " mtc0 %0, $7\n" " li %0, 0x58\n" " mtc0 %0, $5\n" " li %0, 0xfffffff0\n" " mtc0 %0, $9\n" :"=r"(t));cester_assert_uint_eq(1, *ptr);__asm__ volatile("la %0, 1f\n1:\nsw $0, 0x58($0)" :"=r"(expectedEPC));__asm__ volatile("mtc0 $0, $7\n");cester_assert_uint_eq(0, *ptr);cester_assert_uint_eq(1, s_got40);cester_assert_uint_eq(0, s_got80);cester_assert_uint_eq(0x40, s_from);cester_assert_uint_eq(expectedEPC, s_epc);) CESTER_TEST(cpu_cop0_kseg_write_bp
#define EXPECT_K01_LEFT_NEAR
Definition raster-expected-phase18.h:87
#define EXPECT_K05_VERTEX
Definition raster-expected-phase18.h:130
#define EXPECT_K05_TOP_NEAR
Definition raster-expected-phase18.h:131
#define EXPECT_K16_LEFT_NEAR
Definition raster-expected-phase18.h:162
#define EXPECT_K08_TOP_NEAR
Definition raster-expected-phase18.h:146
#define EXPECT_K01_TOP_NEAR
Definition raster-expected-phase18.h:86
#define EXPECT_K08_LEFT_NEAR
Definition raster-expected-phase18.h:147
#define EXPECT_K16_INTERIOR
Definition raster-expected-phase18.h:163
#define EXPECT_K03_INTERIOR
Definition raster-expected-phase18.h:118
#define EXPECT_K03_LEFT_NEAR
Definition raster-expected-phase18.h:117
#define EXPECT_K16_VERTEX
Definition raster-expected-phase18.h:160
#define EXPECT_K02_INTERIOR
Definition raster-expected-phase18.h:103
#define EXPECT_K05_TOP_FAR
Definition raster-expected-phase18.h:134
#define EXPECT_K02_TOP_NEAR
Definition raster-expected-phase18.h:101
#define EXPECT_K02_TOP_FAR
Definition raster-expected-phase18.h:104
#define EXPECT_K01_VERTEX
Definition raster-expected-phase18.h:85
#define EXPECT_K03_VERTEX
Definition raster-expected-phase18.h:115
#define EXPECT_K08_VERTEX
Definition raster-expected-phase18.h:145
#define EXPECT_K08_INTERIOR
Definition raster-expected-phase18.h:148
#define EXPECT_K02_LEFT_NEAR
Definition raster-expected-phase18.h:102
#define EXPECT_K03_TOP_NEAR
Definition raster-expected-phase18.h:116
#define EXPECT_K02_VERTEX
Definition raster-expected-phase18.h:100
#define EXPECT_K08_TOP_FAR
Definition raster-expected-phase18.h:149
#define EXPECT_K01_TOP_FAR
Definition raster-expected-phase18.h:89
#define EXPECT_K16_TOP_NEAR
Definition raster-expected-phase18.h:161
#define EXPECT_K03_TOP_FAR
Definition raster-expected-phase18.h:119
#define EXPECT_K05_LEFT_NEAR
Definition raster-expected-phase18.h:132
#define EXPECT_K05_INTERIOR
Definition raster-expected-phase18.h:133
#define EXPECT_K16_TOP_FAR
Definition raster-expected-phase18.h:164
#define EXPECT_K01_INTERIOR
Definition raster-expected-phase18.h:88
#define TEX17_TY
Definition texture-fixture-phase17.h:58
#define TEX17_TPAGE
Definition texture-fixture-phase17.h:65
#define TEX17_TX
Definition texture-fixture-phase17.h:57
#define PHASE17_ASSERT_PIXEL_EQ(expected, x_, y_)
Definition texture-fixture-phase17.h:102
#define TEX17_CLUT_FIELD
Definition texture-fixture-phase17.h:66
#define TEX_MOD_NEUTRAL
Definition texture-fixtures.h:328