Nugget
Loading...
Searching...
No Matches
gouraud-color.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// Gouraud color precision suite. PS1 GPU gouraud interpolation uses
28// integer-truncated per-row and per-pixel-X color deltas. This suite
29// probes the resulting truncation behavior in three independent
30// dimensions:
31//
32// 1. Triangle size sweep (small / medium / large). Small triangles
33// have lossy per-row deltas; large triangles drift across many
34// rows. Same shape, different precision pressure.
35//
36// 2. R-only single-axis gradients (vertical and horizontal). Strip
37// one axis of variation so the OBS log directly shows where the
38// accumulator landed at each step.
39//
40// 3. Vertex-order permutations. Hardware should be order-independent
41// and the soft renderer's longest-edge sort should produce the
42// same accumulators regardless of caller-supplied ordering.
43
45
46// --------------------------------------------------------------------------
47// GC: Canonical RGB-vertex triangle at three sizes
48// --------------------------------------------------------------------------
49
50static void drawGC1(void) {
51 rasterReset();
52 rasterClearTestRegion(0, 0, 16, 16);
53 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
54 RASTER_CMD_GREEN, 7, 0,
55 RASTER_CMD_BLUE, 0, 7);
56 rasterFlushPrimitive();
57}
58
59static void drawGC2(void) {
60 rasterReset();
61 rasterClearTestRegion(0, 0, 48, 48);
62 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
63 RASTER_CMD_GREEN, 31, 0,
64 RASTER_CMD_BLUE, 0, 31);
65 rasterFlushPrimitive();
66}
67
68static void drawGC3(void) {
69 rasterReset();
70 /* Draw region just over 128x128 so we can probe out-of-tri sentinels too. */
71 rasterClearTestRegion(0, 0, 144, 144);
72 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
73 RASTER_CMD_GREEN, 127, 0,
74 RASTER_CMD_BLUE, 0, 127);
75 rasterFlushPrimitive();
76}
77
78// --------------------------------------------------------------------------
79// GV: R-only vertical gradient. Apex (0,0) at max R, base at R=0.
80// Width matches height so the triangle is the same shape as GC but
81// only the R channel varies. Probe column x=0 to read the left-edge
82// accumulator directly.
83// --------------------------------------------------------------------------
84
85static void drawGV(int n) {
86 /* R apex, R=0 elsewhere. */
87 rasterReset();
88 rasterClearTestRegion(0, 0, 32, 32);
89 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
90 0u, (int16_t)n, 0,
91 0u, 0, (int16_t)n);
92 rasterFlushPrimitive();
93}
94
95// --------------------------------------------------------------------------
96// GH: R-only horizontal gradient. Top edge interpolates R 31->0 across
97// W. Left edge stays at R=31 down the height (apex and v2 both R=31).
98// --------------------------------------------------------------------------
99
100static void drawGH(int n) {
101 rasterReset();
102 rasterClearTestRegion(0, 0, 32, 32);
103 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
104 0u, (int16_t)n, 0,
105 RASTER_CMD_RED, 0, (int16_t)n);
106 rasterFlushPrimitive();
107}
108
109// --------------------------------------------------------------------------
110// GS: Saturation / vertex-exactness probes.
111// --------------------------------------------------------------------------
112
113static void drawGSNearMax(void) {
114 /* Apex R=31, others R=30 (1 LSB below max in 5-bit space). 16x16. */
115 rasterReset();
116 rasterClearTestRegion(0, 0, 32, 32);
117 rasterGouraudTri(rasterCmdColor(31, 0, 0), 0, 0,
118 rasterCmdColor(30, 0, 0), 16, 0,
119 rasterCmdColor(30, 0, 0), 0, 16);
120 rasterFlushPrimitive();
121}
122
123static void drawGSNearMin(void) {
124 /* Apex R=0, others R=1 (1 LSB above min). 16x16. */
125 rasterReset();
126 rasterClearTestRegion(0, 0, 32, 32);
127 rasterGouraudTri(rasterCmdColor(0, 0, 0), 0, 0,
128 rasterCmdColor(1, 0, 0), 16, 0,
129 rasterCmdColor(1, 0, 0), 0, 16);
130 rasterFlushPrimitive();
131}
132
133static void drawGSHalfOfLSB(void) {
134 /* Apex R=1, others R=0. 8x8. The accumulator drops smoothly past
135 the 5-bit truncation point - hardware may keep R=1 for the first
136 few rows and quantize to 0 below. */
137 rasterReset();
138 rasterClearTestRegion(0, 0, 16, 16);
139 rasterGouraudTri(rasterCmdColor(1, 0, 0), 0, 0,
140 rasterCmdColor(0, 0, 0), 8, 0,
141 rasterCmdColor(0, 0, 0), 0, 8);
142 rasterFlushPrimitive();
143}
144
145// --------------------------------------------------------------------------
146// GD: Dither ON for the canonical 32x32 triangle.
147// --------------------------------------------------------------------------
148
149static void drawGD(void) {
150 rasterReset();
151 rasterClearTestRegion(0, 0, 48, 48);
152 rasterSetDither(1);
153 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
154 RASTER_CMD_GREEN, 31, 0,
155 RASTER_CMD_BLUE, 0, 31);
156 rasterFlushPrimitive();
157 rasterSetDither(0);
158}
159
160// --------------------------------------------------------------------------
161// GO: Vertex-order permutations of the GC1 triangle.
162// Same three vertex/color pairs, six orderings.
163// --------------------------------------------------------------------------
164
165#define GO_TRI_R_FIRST_GB() \
166 rasterGouraudTri(RASTER_CMD_RED, 0, 0, RASTER_CMD_GREEN, 7, 0, RASTER_CMD_BLUE, 0, 7)
167#define GO_TRI_R_FIRST_BG() \
168 rasterGouraudTri(RASTER_CMD_RED, 0, 0, RASTER_CMD_BLUE, 0, 7, RASTER_CMD_GREEN, 7, 0)
169#define GO_TRI_G_FIRST_RB() \
170 rasterGouraudTri(RASTER_CMD_GREEN, 7, 0, RASTER_CMD_RED, 0, 0, RASTER_CMD_BLUE, 0, 7)
171#define GO_TRI_G_FIRST_BR() \
172 rasterGouraudTri(RASTER_CMD_GREEN, 7, 0, RASTER_CMD_BLUE, 0, 7, RASTER_CMD_RED, 0, 0)
173#define GO_TRI_B_FIRST_RG() \
174 rasterGouraudTri(RASTER_CMD_BLUE, 0, 7, RASTER_CMD_RED, 0, 0, RASTER_CMD_GREEN, 7, 0)
175#define GO_TRI_B_FIRST_GR() \
176 rasterGouraudTri(RASTER_CMD_BLUE, 0, 7, RASTER_CMD_GREEN, 7, 0, RASTER_CMD_RED, 0, 0)
177
178static void drawGOPerm(int perm) {
179 rasterReset();
180 rasterClearTestRegion(0, 0, 16, 16);
181 switch (perm) {
182 case 0: GO_TRI_R_FIRST_GB(); break;
183 case 1: GO_TRI_R_FIRST_BG(); break;
184 case 2: GO_TRI_G_FIRST_RB(); break;
185 case 3: GO_TRI_G_FIRST_BR(); break;
186 case 4: GO_TRI_B_FIRST_RG(); break;
187 case 5: GO_TRI_B_FIRST_GR(); break;
188 }
189 rasterFlushPrimitive();
190}
191
192) // CESTER_BODY
193
194// --------------------------------------------------------------------------
195// GC1: 8x8 canonical RGB triangle
196// --------------------------------------------------------------------------
197
198CESTER_TEST(gc1_v0_apex_red, gpu_raster_phase7,
199 drawGC1();
200 /* Apex pixel = pure R at vertex 0. */
202)
203
204CESTER_TEST(gc1_top_x4, gpu_raster_phase7,
205 drawGC1();
206 /* Mid R-G edge at (4, 0). Top-left rule includes top edge. */
208)
209
210CESTER_TEST(gc1_left_y4, gpu_raster_phase7,
211 drawGC1();
212 /* Mid R-B edge at (0, 4). Left edge included. */
214)
215
216CESTER_TEST(gc1_interior_1_1, gpu_raster_phase7,
217 drawGC1();
219)
220
221CESTER_TEST(gc1_interior_2_2, gpu_raster_phase7,
222 drawGC1();
224)
225
226CESTER_TEST(gc1_interior_3_3, gpu_raster_phase7,
227 drawGC1();
229)
230
231CESTER_TEST(gc1_interior_1_3, gpu_raster_phase7,
232 drawGC1();
233 /* Below diagonal: more B weight than G. */
235)
236
237CESTER_TEST(gc1_interior_3_1, gpu_raster_phase7,
238 drawGC1();
239 /* Above diagonal: more G weight than B. */
241)
242
243// --------------------------------------------------------------------------
244// GC2: 32x32 canonical RGB triangle
245// --------------------------------------------------------------------------
246
247CESTER_TEST(gc2_v0_apex_red, gpu_raster_phase7,
248 drawGC2();
250)
251
252CESTER_TEST(gc2_top_x16, gpu_raster_phase7,
253 drawGC2();
255)
256
257CESTER_TEST(gc2_left_y16, gpu_raster_phase7,
258 drawGC2();
260)
261
262CESTER_TEST(gc2_interior_8_8, gpu_raster_phase7,
263 drawGC2();
265)
266
267CESTER_TEST(gc2_interior_16_8, gpu_raster_phase7,
268 drawGC2();
270)
271
272CESTER_TEST(gc2_interior_8_16, gpu_raster_phase7,
273 drawGC2();
275)
276
277CESTER_TEST(gc2_interior_1_1, gpu_raster_phase7,
278 drawGC2();
280)
281
282CESTER_TEST(gc2_interior_30_0, gpu_raster_phase7,
283 drawGC2();
284 /* Near right vertex (32,0). Top edge included, top-left includes
285 this pixel if right xmax includes it. */
287)
288
289// --------------------------------------------------------------------------
290// GC3: 128x128 canonical RGB triangle
291// --------------------------------------------------------------------------
292
293CESTER_TEST(gc3_v0_apex_red, gpu_raster_phase7,
294 drawGC3();
296)
297
298CESTER_TEST(gc3_top_x64, gpu_raster_phase7,
299 drawGC3();
301)
302
303CESTER_TEST(gc3_left_y64, gpu_raster_phase7,
304 drawGC3();
306)
307
308CESTER_TEST(gc3_interior_32_32, gpu_raster_phase7,
309 drawGC3();
311)
312
313CESTER_TEST(gc3_interior_1_1, gpu_raster_phase7,
314 drawGC3();
316)
317
318CESTER_TEST(gc3_interior_64_32, gpu_raster_phase7,
319 drawGC3();
321)
322
323CESTER_TEST(gc3_interior_32_64, gpu_raster_phase7,
324 drawGC3();
326)
327
328CESTER_TEST(gc3_interior_96_16, gpu_raster_phase7,
329 drawGC3();
331)
332
333// --------------------------------------------------------------------------
334// GV: Vertical R-only gradient
335// --------------------------------------------------------------------------
336
337CESTER_TEST(gv3_x0_y0, gpu_raster_phase7,
338 drawGV(3);
340)
341CESTER_TEST(gv3_x0_y1, gpu_raster_phase7,
342 drawGV(3);
344)
345CESTER_TEST(gv3_x0_y2, gpu_raster_phase7,
346 drawGV(3);
348)
349
350CESTER_TEST(gv5_x0_y0, gpu_raster_phase7,
351 drawGV(5);
353)
354CESTER_TEST(gv5_x0_y1, gpu_raster_phase7,
355 drawGV(5);
357)
358CESTER_TEST(gv5_x0_y2, gpu_raster_phase7,
359 drawGV(5);
361)
362CESTER_TEST(gv5_x0_y3, gpu_raster_phase7,
363 drawGV(5);
365)
366CESTER_TEST(gv5_x0_y4, gpu_raster_phase7,
367 drawGV(5);
369)
370
371CESTER_TEST(gv7_x0_y0, gpu_raster_phase7, drawGV(7); ASSERT_PIXEL_EQ(GV7_X0_Y0, 0, 0); )
372CESTER_TEST(gv7_x0_y1, gpu_raster_phase7, drawGV(7); ASSERT_PIXEL_EQ(GV7_X0_Y1, 0, 1); )
373CESTER_TEST(gv7_x0_y2, gpu_raster_phase7, drawGV(7); ASSERT_PIXEL_EQ(GV7_X0_Y2, 0, 2); )
374CESTER_TEST(gv7_x0_y3, gpu_raster_phase7, drawGV(7); ASSERT_PIXEL_EQ(GV7_X0_Y3, 0, 3); )
375CESTER_TEST(gv7_x0_y4, gpu_raster_phase7, drawGV(7); ASSERT_PIXEL_EQ(GV7_X0_Y4, 0, 4); )
376CESTER_TEST(gv7_x0_y5, gpu_raster_phase7, drawGV(7); ASSERT_PIXEL_EQ(GV7_X0_Y5, 0, 5); )
377CESTER_TEST(gv7_x0_y6, gpu_raster_phase7, drawGV(7); ASSERT_PIXEL_EQ(GV7_X0_Y6, 0, 6); )
378
379CESTER_TEST(gv11_x0_y0, gpu_raster_phase7, drawGV(11); ASSERT_PIXEL_EQ(GV11_X0_Y0, 0, 0); )
380CESTER_TEST(gv11_x0_y2, gpu_raster_phase7, drawGV(11); ASSERT_PIXEL_EQ(GV11_X0_Y2, 0, 2); )
381CESTER_TEST(gv11_x0_y4, gpu_raster_phase7, drawGV(11); ASSERT_PIXEL_EQ(GV11_X0_Y4, 0, 4); )
382CESTER_TEST(gv11_x0_y6, gpu_raster_phase7, drawGV(11); ASSERT_PIXEL_EQ(GV11_X0_Y6, 0, 6); )
383CESTER_TEST(gv11_x0_y8, gpu_raster_phase7, drawGV(11); ASSERT_PIXEL_EQ(GV11_X0_Y8, 0, 8); )
384CESTER_TEST(gv11_x0_y10, gpu_raster_phase7, drawGV(11); ASSERT_PIXEL_EQ(GV11_X0_Y10, 0, 10); )
385
386// --------------------------------------------------------------------------
387// GH: Horizontal R-only gradient
388// --------------------------------------------------------------------------
389
390CESTER_TEST(gh3_y0_x0, gpu_raster_phase7, drawGH(3); ASSERT_PIXEL_EQ(GH3_Y0_X0, 0, 0); )
391CESTER_TEST(gh3_y0_x1, gpu_raster_phase7, drawGH(3); ASSERT_PIXEL_EQ(GH3_Y0_X1, 1, 0); )
392CESTER_TEST(gh3_y0_x2, gpu_raster_phase7, drawGH(3); ASSERT_PIXEL_EQ(GH3_Y0_X2, 2, 0); )
393
394CESTER_TEST(gh5_y0_x0, gpu_raster_phase7, drawGH(5); ASSERT_PIXEL_EQ(GH5_Y0_X0, 0, 0); )
395CESTER_TEST(gh5_y0_x1, gpu_raster_phase7, drawGH(5); ASSERT_PIXEL_EQ(GH5_Y0_X1, 1, 0); )
396CESTER_TEST(gh5_y0_x2, gpu_raster_phase7, drawGH(5); ASSERT_PIXEL_EQ(GH5_Y0_X2, 2, 0); )
397CESTER_TEST(gh5_y0_x3, gpu_raster_phase7, drawGH(5); ASSERT_PIXEL_EQ(GH5_Y0_X3, 3, 0); )
398CESTER_TEST(gh5_y0_x4, gpu_raster_phase7, drawGH(5); ASSERT_PIXEL_EQ(GH5_Y0_X4, 4, 0); )
399
400CESTER_TEST(gh7_y0_x0, gpu_raster_phase7, drawGH(7); ASSERT_PIXEL_EQ(GH7_Y0_X0, 0, 0); )
401CESTER_TEST(gh7_y0_x1, gpu_raster_phase7, drawGH(7); ASSERT_PIXEL_EQ(GH7_Y0_X1, 1, 0); )
402CESTER_TEST(gh7_y0_x2, gpu_raster_phase7, drawGH(7); ASSERT_PIXEL_EQ(GH7_Y0_X2, 2, 0); )
403CESTER_TEST(gh7_y0_x3, gpu_raster_phase7, drawGH(7); ASSERT_PIXEL_EQ(GH7_Y0_X3, 3, 0); )
404CESTER_TEST(gh7_y0_x4, gpu_raster_phase7, drawGH(7); ASSERT_PIXEL_EQ(GH7_Y0_X4, 4, 0); )
405CESTER_TEST(gh7_y0_x5, gpu_raster_phase7, drawGH(7); ASSERT_PIXEL_EQ(GH7_Y0_X5, 5, 0); )
406CESTER_TEST(gh7_y0_x6, gpu_raster_phase7, drawGH(7); ASSERT_PIXEL_EQ(GH7_Y0_X6, 6, 0); )
407
408CESTER_TEST(gh11_y0_x0, gpu_raster_phase7, drawGH(11); ASSERT_PIXEL_EQ(GH11_Y0_X0, 0, 0); )
409CESTER_TEST(gh11_y0_x2, gpu_raster_phase7, drawGH(11); ASSERT_PIXEL_EQ(GH11_Y0_X2, 2, 0); )
410CESTER_TEST(gh11_y0_x4, gpu_raster_phase7, drawGH(11); ASSERT_PIXEL_EQ(GH11_Y0_X4, 4, 0); )
411CESTER_TEST(gh11_y0_x6, gpu_raster_phase7, drawGH(11); ASSERT_PIXEL_EQ(GH11_Y0_X6, 6, 0); )
412CESTER_TEST(gh11_y0_x8, gpu_raster_phase7, drawGH(11); ASSERT_PIXEL_EQ(GH11_Y0_X8, 8, 0); )
413CESTER_TEST(gh11_y0_x10, gpu_raster_phase7, drawGH(11); ASSERT_PIXEL_EQ(GH11_Y0_X10, 10, 0); )
414
415// --------------------------------------------------------------------------
416// GS: Saturation / vertex-exactness
417// --------------------------------------------------------------------------
418
419CESTER_TEST(gs_near_max_apex, gpu_raster_phase7,
420 drawGSNearMax();
422)
423
424CESTER_TEST(gs_near_max_interior, gpu_raster_phase7,
425 drawGSNearMax();
426 /* Deep interior should be R=30 (the base color), not drift up to 31. */
428)
429
430CESTER_TEST(gs_near_min_apex, gpu_raster_phase7,
431 drawGSNearMin();
433)
434
435CESTER_TEST(gs_near_min_interior, gpu_raster_phase7,
436 drawGSNearMin();
437 /* Deep interior should be R=1, not underflow to 31. */
439)
440
441CESTER_TEST(gs_half_of_lsb_apex, gpu_raster_phase7,
442 drawGSHalfOfLSB();
444)
445
446CESTER_TEST(gs_half_of_lsb_y2, gpu_raster_phase7,
447 drawGSHalfOfLSB();
449)
450
451CESTER_TEST(gs_half_of_lsb_y4, gpu_raster_phase7,
452 drawGSHalfOfLSB();
454)
455
456CESTER_TEST(gs_half_of_lsb_y6, gpu_raster_phase7,
457 drawGSHalfOfLSB();
459)
460
461// --------------------------------------------------------------------------
462// GD: Dither overlay - 4x4 Bayer pattern probe
463// --------------------------------------------------------------------------
464
465CESTER_TEST(gd_8_8, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_8_8, 8, 8); )
466CESTER_TEST(gd_9_8, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_9_8, 9, 8); )
467CESTER_TEST(gd_10_8, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_10_8, 10, 8); )
468CESTER_TEST(gd_11_8, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_11_8, 11, 8); )
469CESTER_TEST(gd_8_9, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_8_9, 8, 9); )
470CESTER_TEST(gd_9_9, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_9_9, 9, 9); )
471CESTER_TEST(gd_10_9, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_10_9, 10, 9); )
472CESTER_TEST(gd_11_9, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_11_9, 11, 9); )
473CESTER_TEST(gd_8_10, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_8_10, 8, 10); )
474CESTER_TEST(gd_9_10, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_9_10, 9, 10); )
475CESTER_TEST(gd_10_10, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_10_10, 10, 10); )
476CESTER_TEST(gd_11_10, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_11_10, 11, 10); )
477CESTER_TEST(gd_8_11, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_8_11, 8, 11); )
478CESTER_TEST(gd_9_11, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_9_11, 9, 11); )
479CESTER_TEST(gd_10_11, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_10_11, 10, 11); )
480CESTER_TEST(gd_11_11, gpu_raster_phase7, drawGD(); ASSERT_PIXEL_EQ(GD_11_11, 11, 11); )
481
482// --------------------------------------------------------------------------
483// GO: Vertex-order permutations
484// All six permutations should produce identical interior pixels.
485// --------------------------------------------------------------------------
486
487CESTER_TEST(go_perm0_R_GB_2_2, gpu_raster_phase7,
488 drawGOPerm(0); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_2_2, 2, 2);
489)
490CESTER_TEST(go_perm1_R_BG_2_2, gpu_raster_phase7,
491 drawGOPerm(1); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_2_2, 2, 2);
492)
493CESTER_TEST(go_perm2_G_RB_2_2, gpu_raster_phase7,
494 drawGOPerm(2); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_2_2, 2, 2);
495)
496CESTER_TEST(go_perm3_G_BR_2_2, gpu_raster_phase7,
497 drawGOPerm(3); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_2_2, 2, 2);
498)
499CESTER_TEST(go_perm4_B_RG_2_2, gpu_raster_phase7,
500 drawGOPerm(4); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_2_2, 2, 2);
501)
502CESTER_TEST(go_perm5_B_GR_2_2, gpu_raster_phase7,
503 drawGOPerm(5); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_2_2, 2, 2);
504)
505
506CESTER_TEST(go_perm0_R_GB_1_3, gpu_raster_phase7,
507 drawGOPerm(0); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_1_3, 1, 3);
508)
509CESTER_TEST(go_perm1_R_BG_1_3, gpu_raster_phase7,
510 drawGOPerm(1); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_1_3, 1, 3);
511)
512CESTER_TEST(go_perm2_G_RB_1_3, gpu_raster_phase7,
513 drawGOPerm(2); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_1_3, 1, 3);
514)
515CESTER_TEST(go_perm3_G_BR_1_3, gpu_raster_phase7,
516 drawGOPerm(3); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_1_3, 1, 3);
517)
518CESTER_TEST(go_perm4_B_RG_1_3, gpu_raster_phase7,
519 drawGOPerm(4); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_1_3, 1, 3);
520)
521CESTER_TEST(go_perm5_B_GR_1_3, gpu_raster_phase7,
522 drawGOPerm(5); ASSERT_PIXEL_EQ(GO_PERM_INTERIOR_1_3, 1, 3);
523)
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 GO_TRI_G_FIRST_BR()
#define GO_TRI_B_FIRST_RG()
#define GO_TRI_G_FIRST_RB()
#define GO_TRI_R_FIRST_BG()
#define GO_TRI_B_FIRST_GR()
#define GO_TRI_R_FIRST_GB()
#define GC3_TOP_X64
Definition raster-expected-phase7.h:112
#define GV3_X0_Y1
Definition raster-expected-phase7.h:129
#define GV5_X0_Y3
Definition raster-expected-phase7.h:136
#define GC2_INTERIOR_1_1
Definition raster-expected-phase7.h:107
#define GC3_INTERIOR_32_64
Definition raster-expected-phase7.h:117
#define GC2_INTERIOR_8_8
Definition raster-expected-phase7.h:104
#define GC1_INTERIOR_2_2
Definition raster-expected-phase7.h:95
#define GS_NEAR_MIN_INTERIOR
Definition raster-expected-phase7.h:217
#define GH7_Y0_X5
Definition raster-expected-phase7.h:185
#define GD_10_11
Definition raster-expected-phase7.h:247
#define GV11_X0_Y10
Definition raster-expected-phase7.h:157
#define GS_NEAR_MIN_APEX
Definition raster-expected-phase7.h:216
#define GD_8_10
Definition raster-expected-phase7.h:241
#define GC1_LEFT_Y4
Definition raster-expected-phase7.h:93
#define GD_11_10
Definition raster-expected-phase7.h:244
#define GV5_X0_Y4
Definition raster-expected-phase7.h:137
#define GS_HALF_OF_LSB_Y4
Definition raster-expected-phase7.h:220
#define GH11_Y0_X10
Definition raster-expected-phase7.h:194
#define GV7_X0_Y4
Definition raster-expected-phase7.h:147
#define GV7_X0_Y1
Definition raster-expected-phase7.h:144
#define GD_11_11
Definition raster-expected-phase7.h:248
#define GV3_X0_Y0
Definition raster-expected-phase7.h:128
#define GV7_X0_Y2
Definition raster-expected-phase7.h:145
#define GC2_INTERIOR_16_8
Definition raster-expected-phase7.h:105
#define GH7_Y0_X6
Definition raster-expected-phase7.h:186
#define GV7_X0_Y3
Definition raster-expected-phase7.h:146
#define GC2_V0_R
Definition raster-expected-phase7.h:101
#define GS_HALF_OF_LSB_Y6
Definition raster-expected-phase7.h:221
#define GV7_X0_Y5
Definition raster-expected-phase7.h:148
#define GV11_X0_Y0
Definition raster-expected-phase7.h:152
#define GV11_X0_Y8
Definition raster-expected-phase7.h:156
#define GH3_Y0_X0
Definition raster-expected-phase7.h:168
#define GC2_INTERIOR_8_16
Definition raster-expected-phase7.h:106
#define GC3_INTERIOR_1_1
Definition raster-expected-phase7.h:115
#define GD_9_11
Definition raster-expected-phase7.h:246
#define GC3_INTERIOR_96_16
Definition raster-expected-phase7.h:118
#define GH5_Y0_X0
Definition raster-expected-phase7.h:173
#define GH11_Y0_X2
Definition raster-expected-phase7.h:190
#define GV11_X0_Y4
Definition raster-expected-phase7.h:154
#define GH5_Y0_X2
Definition raster-expected-phase7.h:175
#define GD_8_9
Definition raster-expected-phase7.h:237
#define GS_HALF_OF_LSB_Y2
Definition raster-expected-phase7.h:219
#define GD_8_11
Definition raster-expected-phase7.h:245
#define GH5_Y0_X4
Definition raster-expected-phase7.h:177
#define GH7_Y0_X2
Definition raster-expected-phase7.h:182
#define GC2_TOP_X16
Definition raster-expected-phase7.h:102
#define GS_NEAR_MAX_INTERIOR
Definition raster-expected-phase7.h:215
#define GV5_X0_Y1
Definition raster-expected-phase7.h:134
#define GO_PERM_INTERIOR_2_2
Definition raster-expected-phase7.h:256
#define GC3_INTERIOR_32_32
Definition raster-expected-phase7.h:114
#define GD_10_8
Definition raster-expected-phase7.h:235
#define GV7_X0_Y6
Definition raster-expected-phase7.h:149
#define GV11_X0_Y6
Definition raster-expected-phase7.h:155
#define GH7_Y0_X0
Definition raster-expected-phase7.h:180
#define GS_HALF_OF_LSB_APEX
Definition raster-expected-phase7.h:218
#define GD_10_10
Definition raster-expected-phase7.h:243
#define GD_10_9
Definition raster-expected-phase7.h:239
#define GC1_INTERIOR_1_1
Definition raster-expected-phase7.h:94
#define GH5_Y0_X1
Definition raster-expected-phase7.h:174
#define GH11_Y0_X6
Definition raster-expected-phase7.h:192
#define GC3_LEFT_Y64
Definition raster-expected-phase7.h:113
#define GV7_X0_Y0
Definition raster-expected-phase7.h:143
#define GV11_X0_Y2
Definition raster-expected-phase7.h:153
#define GV5_X0_Y2
Definition raster-expected-phase7.h:135
#define GC1_INTERIOR_3_1
Definition raster-expected-phase7.h:98
#define GD_11_9
Definition raster-expected-phase7.h:240
#define GV3_X0_Y2
Definition raster-expected-phase7.h:130
#define GC2_INTERIOR_30_0
Definition raster-expected-phase7.h:108
#define GD_11_8
Definition raster-expected-phase7.h:236
#define GC1_INTERIOR_3_3
Definition raster-expected-phase7.h:96
#define GC2_LEFT_Y16
Definition raster-expected-phase7.h:103
#define GC1_V0_R
Definition raster-expected-phase7.h:91
#define GH7_Y0_X1
Definition raster-expected-phase7.h:181
#define GC3_INTERIOR_64_32
Definition raster-expected-phase7.h:116
#define GH11_Y0_X4
Definition raster-expected-phase7.h:191
#define GD_9_10
Definition raster-expected-phase7.h:242
#define GH5_Y0_X3
Definition raster-expected-phase7.h:176
#define GD_9_8
Definition raster-expected-phase7.h:234
#define GH7_Y0_X4
Definition raster-expected-phase7.h:184
#define GH7_Y0_X3
Definition raster-expected-phase7.h:183
#define GH11_Y0_X0
Definition raster-expected-phase7.h:189
#define GS_NEAR_MAX_APEX
Definition raster-expected-phase7.h:214
#define GC1_TOP_X4
Definition raster-expected-phase7.h:92
#define GO_PERM_INTERIOR_1_3
Definition raster-expected-phase7.h:257
#define GH11_Y0_X8
Definition raster-expected-phase7.h:193
#define GH3_Y0_X2
Definition raster-expected-phase7.h:170
#define GC1_INTERIOR_1_3
Definition raster-expected-phase7.h:97
#define GH3_Y0_X1
Definition raster-expected-phase7.h:169
#define GV5_X0_Y0
Definition raster-expected-phase7.h:133
#define GD_9_9
Definition raster-expected-phase7.h:238
#define GD_8_8
Definition raster-expected-phase7.h:233
#define GC3_V0_R
Definition raster-expected-phase7.h:111
#define RASTER_CMD_BLUE
Definition raster-helpers.h:127
#define RASTER_CMD_RED
Definition raster-helpers.h:123
#define RASTER_CMD_GREEN
Definition raster-helpers.h:125
#define ASSERT_PIXEL_EQ(expected, x_, y_)
Definition raster-helpers.h:472