Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
triangle-edges.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// Triangle-edges suite for the gpu-raster test binary.
28//
29// This file is #included from gpu-raster.c (cester is single-TU). It uses
30// helpers defined in raster-helpers.h and expected-value macros defined in
31// raster-expected.h, both of which gpu-raster.c includes before pulling in
32// this file.
33//
34// Each CESTER_TEST is one pixel-of-interest. Tests are self-contained: they
35// reset the GPU, fill the test region with the sentinel, draw the triangle
36// under test, and read back exactly one pixel. cester reports failures as
37// "expected X, received Y at file:line" and the ASSERT_PIXEL_EQ macro also
38// emits an OBS line so a hardware capture run produces a complete log
39// independent of cester's pass/fail accounting.
40
41// --------------------------------------------------------------------------
42// Per-triangle draw helpers
43// --------------------------------------------------------------------------
44//
45// All static helpers must be wrapped in CESTER_BODY(...) because cester
46// re-#includes __BASE_FILE__ multiple times during its forward-declaration
47// + array-build + function-body passes. CESTER_BODY's expansion is empty
48// on the early passes and contains its argument only on the final pass,
49// so a static helper inside CESTER_BODY is defined exactly once. See
50// cop0/cester-cop0.c for the canonical pattern.
51
52// clang-format off
53
55
56// Triangle A: 4x4 right-angle, vertices (0,0),(4,0),(0,4), color RED.
57static void rasterDrawTriA(void) {
58 rasterReset();
59 rasterClearTestRegion(0, 0, 16, 16);
60 rasterFlatTri(RASTER_CMD_RED, 0, 0, 4, 0, 0, 4);
61 rasterFlushPrimitive();
62}
63
64// Triangle B: 1-pixel degenerate at near corner, (0,0),(1,0),(0,1), RED.
65static void rasterDrawTriB(void) {
66 rasterReset();
67 rasterClearTestRegion(0, 0, 4, 4);
68 rasterFlatTri(RASTER_CMD_RED, 0, 0, 1, 0, 0, 1);
69 rasterFlushPrimitive();
70}
71
72// Triangle C: 1-pixel degenerate at far corner.
73static void rasterDrawTriC(void) {
74 rasterReset();
75 rasterClearTestRegion(1016, 504, 8, 8);
76 rasterFlatTri(RASTER_CMD_BLUE, 1019, 507, 1020, 507, 1019, 508);
77 rasterFlushPrimitive();
78}
79
80// Triangle D: vertical-right-edge, (0,0),(4,0),(4,4), GREEN.
81static void rasterDrawTriD(void) {
82 rasterReset();
83 rasterClearTestRegion(0, 0, 16, 16);
84 rasterFlatTri(RASTER_CMD_GREEN, 0, 0, 4, 0, 4, 4);
85 rasterFlushPrimitive();
86}
87
88// Triangle E: horizontal-top-edge isoceles, (0,0),(4,0),(2,4), RED.
89static void rasterDrawTriE(void) {
90 rasterReset();
91 rasterClearTestRegion(0, 0, 16, 16);
92 rasterFlatTri(RASTER_CMD_RED, 0, 0, 4, 0, 2, 4);
93 rasterFlushPrimitive();
94}
95
96// Triangle F: collinear-diagonal, (0,0),(2,2),(4,4), WHITE.
97static void rasterDrawTriF(void) {
98 rasterReset();
99 rasterClearTestRegion(0, 0, 16, 16);
100 rasterFlatTri(RASTER_CMD_WHITE, 0, 0, 2, 2, 4, 4);
101 rasterFlushPrimitive();
102}
103
104// Triangle G: collinear-horizontal, (0,0),(10,0),(5,0), WHITE.
105static void rasterDrawTriG(void) {
106 rasterReset();
107 rasterClearTestRegion(0, 0, 16, 8);
108 rasterFlatTri(RASTER_CMD_WHITE, 0, 0, 10, 0, 5, 0);
109 rasterFlushPrimitive();
110}
111
112// Triangle H: collinear-vertical, (0,0),(0,10),(0,5), WHITE.
113static void rasterDrawTriH(void) {
114 rasterReset();
115 rasterClearTestRegion(0, 0, 8, 16);
116 rasterFlatTri(RASTER_CMD_WHITE, 0, 0, 0, 10, 0, 5);
117 rasterFlushPrimitive();
118}
119
120// Triangle I: xmax==xmin single-pixel span at top. (0,0),(2,1),(0,2), WHITE.
121// This is the audit's soft.cc:2547/2593 critical case: the top row of this
122// triangle has the right-edge xmax equal to xmin (single-pixel span). Soft
123// renderer fast path keeps the pixel; slow path drops it.
124static void rasterDrawTriI(void) {
125 rasterReset();
126 rasterClearTestRegion(0, 0, 8, 8);
127 rasterFlatTri(RASTER_CMD_WHITE, 0, 0, 2, 1, 0, 2);
128 rasterFlushPrimitive();
129}
130
131) // CESTER_BODY
132
133// --------------------------------------------------------------------------
134// Triangle A: 4x4 right-angle - full interior + complement
135// --------------------------------------------------------------------------
136
137CESTER_TEST(triA_pixel_0_0, gpu_raster_phase1,
138 rasterDrawTriA();
140)
141
142CESTER_TEST(triA_pixel_1_0, gpu_raster_phase1,
143 rasterDrawTriA();
145)
146
147CESTER_TEST(triA_pixel_2_0, gpu_raster_phase1,
148 rasterDrawTriA();
150)
151
152CESTER_TEST(triA_pixel_3_0, gpu_raster_phase1,
153 rasterDrawTriA();
155)
156
157CESTER_TEST(triA_pixel_4_0_right_edge, gpu_raster_phase1,
158 rasterDrawTriA();
160)
161
162CESTER_TEST(triA_pixel_0_1, gpu_raster_phase1,
163 rasterDrawTriA();
165)
166
167CESTER_TEST(triA_pixel_2_1, gpu_raster_phase1,
168 rasterDrawTriA();
170)
171
172CESTER_TEST(triA_pixel_3_1_hypotenuse, gpu_raster_phase1,
173 rasterDrawTriA();
175)
176
177CESTER_TEST(triA_pixel_1_2, gpu_raster_phase1,
178 rasterDrawTriA();
180)
181
182CESTER_TEST(triA_pixel_2_2_hypotenuse, gpu_raster_phase1,
183 rasterDrawTriA();
185)
186
187CESTER_TEST(triA_pixel_0_3, gpu_raster_phase1,
188 rasterDrawTriA();
190)
191
192CESTER_TEST(triA_pixel_1_3_hypotenuse, gpu_raster_phase1,
193 rasterDrawTriA();
195)
196
197CESTER_TEST(triA_pixel_0_4_bottom_edge, gpu_raster_phase1,
198 rasterDrawTriA();
200)
201
202// --------------------------------------------------------------------------
203// Triangle B: 1-pixel degenerate at near corner
204// --------------------------------------------------------------------------
205
206CESTER_TEST(triB_pixel_0_0, gpu_raster_phase1,
207 rasterDrawTriB();
209)
210
211CESTER_TEST(triB_pixel_1_0, gpu_raster_phase1,
212 rasterDrawTriB();
214)
215
216CESTER_TEST(triB_pixel_0_1, gpu_raster_phase1,
217 rasterDrawTriB();
219)
220
221CESTER_TEST(triB_pixel_1_1, gpu_raster_phase1,
222 rasterDrawTriB();
224)
225
226// --------------------------------------------------------------------------
227// Triangle C: 1-pixel degenerate at far corner of draw area
228// --------------------------------------------------------------------------
229
230CESTER_TEST(triC_pixel_1019_507, gpu_raster_phase1,
231 rasterDrawTriC();
233)
234
235CESTER_TEST(triC_pixel_1020_507, gpu_raster_phase1,
236 rasterDrawTriC();
238)
239
240CESTER_TEST(triC_pixel_1019_508, gpu_raster_phase1,
241 rasterDrawTriC();
243)
244
245CESTER_TEST(triC_pixel_1020_508, gpu_raster_phase1,
246 rasterDrawTriC();
248)
249
250// --------------------------------------------------------------------------
251// Triangle D: vertical right edge - tests right-edge inclusion
252// --------------------------------------------------------------------------
253
254CESTER_TEST(triD_pixel_0_0_top_left, gpu_raster_phase1,
255 rasterDrawTriD();
257)
258
259CESTER_TEST(triD_pixel_3_0_top_inner, gpu_raster_phase1,
260 rasterDrawTriD();
262)
263
264CESTER_TEST(triD_pixel_4_0_top_right_corner, gpu_raster_phase1,
265 rasterDrawTriD();
267)
268
269CESTER_TEST(triD_pixel_0_1_left_of_diag, gpu_raster_phase1,
270 rasterDrawTriD();
272)
273
274CESTER_TEST(triD_pixel_1_1, gpu_raster_phase1,
275 rasterDrawTriD();
277)
278
279CESTER_TEST(triD_pixel_3_1, gpu_raster_phase1,
280 rasterDrawTriD();
282)
283
284CESTER_TEST(triD_pixel_4_1_right_edge, gpu_raster_phase1,
285 rasterDrawTriD();
287)
288
289CESTER_TEST(triD_pixel_3_3_bottom_right_interior, gpu_raster_phase1,
290 rasterDrawTriD();
292)
293
294CESTER_TEST(triD_pixel_4_4_bottom_right_vertex, gpu_raster_phase1,
295 rasterDrawTriD();
297)
298
299// --------------------------------------------------------------------------
300// Triangle E: horizontal top edge - tests top-edge inclusion
301// --------------------------------------------------------------------------
302
303CESTER_TEST(triE_pixel_0_0_top_left_of_top, gpu_raster_phase1,
304 rasterDrawTriE();
306)
307
308CESTER_TEST(triE_pixel_3_0_top_inner, gpu_raster_phase1,
309 rasterDrawTriE();
311)
312
313CESTER_TEST(triE_pixel_4_0_top_right_vertex, gpu_raster_phase1,
314 rasterDrawTriE();
316)
317
318CESTER_TEST(triE_pixel_1_1, gpu_raster_phase1,
319 rasterDrawTriE();
321)
322
323CESTER_TEST(triE_pixel_3_1, gpu_raster_phase1,
324 rasterDrawTriE();
326)
327
328CESTER_TEST(triE_pixel_2_2_center, gpu_raster_phase1,
329 rasterDrawTriE();
331)
332
333CESTER_TEST(triE_pixel_2_3_near_apex, gpu_raster_phase1,
334 rasterDrawTriE();
336)
337
338CESTER_TEST(triE_pixel_2_4_apex, gpu_raster_phase1,
339 rasterDrawTriE();
341)
342
343// --------------------------------------------------------------------------
344// Triangle F: collinear-diagonal - expects zero fill
345// --------------------------------------------------------------------------
346
347CESTER_TEST(triF_collinear_diag_pixel_0_0, gpu_raster_phase1,
348 rasterDrawTriF();
350)
351
352CESTER_TEST(triF_collinear_diag_pixel_1_1, gpu_raster_phase1,
353 rasterDrawTriF();
355)
356
357CESTER_TEST(triF_collinear_diag_pixel_2_2, gpu_raster_phase1,
358 rasterDrawTriF();
360)
361
362CESTER_TEST(triF_collinear_diag_pixel_4_4, gpu_raster_phase1,
363 rasterDrawTriF();
365)
366
367// --------------------------------------------------------------------------
368// Triangle G: collinear-horizontal - expects zero fill
369// --------------------------------------------------------------------------
370
371CESTER_TEST(triG_collinear_horiz_pixel_0_0, gpu_raster_phase1,
372 rasterDrawTriG();
374)
375
376CESTER_TEST(triG_collinear_horiz_pixel_5_0, gpu_raster_phase1,
377 rasterDrawTriG();
379)
380
381CESTER_TEST(triG_collinear_horiz_pixel_10_0, gpu_raster_phase1,
382 rasterDrawTriG();
384)
385
386// --------------------------------------------------------------------------
387// Triangle H: collinear-vertical - expects zero fill
388// --------------------------------------------------------------------------
389
390CESTER_TEST(triH_collinear_vert_pixel_0_0, gpu_raster_phase1,
391 rasterDrawTriH();
393)
394
395CESTER_TEST(triH_collinear_vert_pixel_0_5, gpu_raster_phase1,
396 rasterDrawTriH();
398)
399
400CESTER_TEST(triH_collinear_vert_pixel_0_10, gpu_raster_phase1,
401 rasterDrawTriH();
403)
404
405// --------------------------------------------------------------------------
406// Triangle I: xmax==xmin top row - CRITICAL audit case (soft.cc:2547/2593)
407// --------------------------------------------------------------------------
408
409CESTER_TEST(triI_xmax_eq_xmin_pixel_0_0, gpu_raster_phase1,
410 rasterDrawTriI();
412)
413
414CESTER_TEST(triI_xmax_eq_xmin_pixel_1_0, gpu_raster_phase1,
415 rasterDrawTriI();
417)
418
419CESTER_TEST(triI_xmax_eq_xmin_pixel_0_1, gpu_raster_phase1,
420 rasterDrawTriI();
422)
423
424CESTER_TEST(triI_xmax_eq_xmin_pixel_1_1, gpu_raster_phase1,
425 rasterDrawTriI();
427)
428
429CESTER_TEST(triI_xmax_eq_xmin_pixel_0_2_bottom_excluded, gpu_raster_phase1,
430 rasterDrawTriI();
432)
CESTER_TEST(cddaLevelHalf, test_instances, static const uint8_t atv[4]={0x40, 0x00, 0x40, 0x00};unsigned changes=0;int peak=cddaPeak(atv, 1, &changes);ramsyscall_printf("CD-DA level at half ATV: peak %i, %u sign changes\n", peak, changes);cester_assert_int_ge(peak, 11300);cester_assert_int_le(peak, 11800);cester_assert_uint_ge(changes, 4);) CESTER_TEST(cddaLevelClipped
CESTER_BODY(static uint16_t s_cddaCapture;static int cddaSpuDma(uint32_t spuAddr, void *buf, uint32_t bytes, int isRead) { const uint16_t tsa=spuAddr > > 3;const uint16_t mode=isRead ? 0x30 :0x20;SPU_RAM_DTA=tsa;for(int i=0;i< 0xf01 &&SPU_RAM_DTA !=tsa;i++);SPU_CTRL=(SPU_CTRL &~0x30)|mode;for(volatile int i=0;i< 60;i++);for(int i=0;i< 0xf01 &&(SPU_STATUS &0x30) !=mode;i++);CDDA_SPU_DELAY=(CDDA_SPU_DELAY &0xf0ffffff)|(isRead ? 0x22000000 :0x20000000);DMA_CTRL[DMA_SPU].MADR=(uint32_t) buf &0x1fffffff;DMA_CTRL[DMA_SPU].BCR=((bytes > > 6)<< 16)|0x10;DMA_CTRL[DMA_SPU].CHCR=isRead ? 0x01000200 :0x01000201;int ok=0;for(unsigned t=0;t< 4000000u;t++) { if((DMA_CTRL[DMA_SPU].CHCR &0x01000000)==0) { ok=1;break;} } SPU_CTRL=SPU_CTRL &~0x30;for(volatile int i=0;i< 60;i++);return ok;} static int cddaSimpleCmd(uint8_t cmd) { uint8_t response[16];CDROM_REG0=0;CDROM_REG1=cmd;uint32_t timeout=2000000;int ok=waitCDRomIRQWithTimeout(&timeout);ackCDRomCause();readResponse(response);return ok;} static void cddaWaitPauseComplete() { initializeTime();uint32_t elapsed=0;while(elapsed< 5000000u) { uint32_t budget=200000u;int ok=waitCDRomIRQWithTimeout(&budget);elapsed=budget;if(!ok) continue;uint8_t cause=ackCDRomCause();uint8_t response[16];readResponse(response);if(cause==2) return;} } static int cddaAudioSetup(const uint8_t atv[4], int demute) { if(!resetCDRom()) return 0;DPCR|=0x000b0000;SPU_CTRL=0;for(volatile int i=0;i< 20000;i++);SPU_VOL_MAIN_LEFT=0;SPU_VOL_MAIN_RIGHT=0;SPU_KEY_OFF_LOW=0xffff;SPU_KEY_OFF_HIGH=0xffff;SPU_RAM_DTC=4;SPU_CTRL=0x8001;for(volatile int i=0;i< 20000;i++);for(int i=0;i< 0x400;i++) s_cddaCapture[i]=CDDA_MARKER;if(!cddaSpuDma(0x000, s_cddaCapture, 0x800, 0)) return 0;if(!cddaSimpleCmd(demute ? CDL_DEMUTE :CDL_MUTE)) return 0;CDROM_REG0=2;CDROM_REG2=atv[0];CDROM_REG3=atv[1];CDROM_REG0=3;CDROM_REG1=atv[2];CDROM_REG2=atv[3];CDROM_REG0=3;CDROM_REG3=0x20;CDROM_REG0=0;SPU_VOL_CD_LEFT=0x7fff;SPU_VOL_CD_RIGHT=0x7fff;SPU_CTRL=SPU_CTRL|0x8001;return 1;} static int cddaBufferPeak(unsigned *signChanges) { int peak=0;unsigned changes=0;int prev=0;for(int i=0;i< 0x200;i++) { int v=(int16_t) s_cddaCapture[i];int a=v< 0 ? -v :v;if(a > peak) peak=a;int sign=v >=0 ? 1 :-1;if(i &&sign !=prev) changes++;prev=sign;} *signChanges=changes;return peak;} static int cddaCapturePeak(unsigned *signChanges) { int peak=0;for(unsigned attempt=0;attempt< 8;attempt++) { if(attempt) { initializeTime();while(updateTime()< 250000u);} if(!cddaSpuDma(0x000, s_cddaCapture, 0x800, 1)) return -1;peak=cddaBufferPeak(signChanges);if(peak) { if(attempt) ramsyscall_printf("capture was empty %u time(s) before audio\n", attempt);break;} } return peak;} static int cddaPeak(const uint8_t atv[4], int demute, unsigned *signChanges) { if(!cddaAudioSetup(atv, demute)) return -1;if(!setMode(0)) return -1;CDROM_REG0=0;CDROM_REG2=0x02;if(!cddaSimpleCmd(CDL_PLAY)) return -1;initializeTime();while(updateTime()< 1500000u);int peak=cddaCapturePeak(signChanges);CDROM_REG0=0;CDROM_REG1=CDL_PAUSE;cddaWaitPauseComplete();CDROM_REG0=0;CDROM_REG2=0x00;CDROM_REG2=0x02;CDROM_REG2=0x16;if(cddaSimpleCmd(CDL_SETLOC) &&cddaSimpleCmd(CDL_SEEKL)) cddaWaitPauseComplete();return peak;}[0x400])
Definition cdda.c:37
#define EXPECT_TRI_D_PIXEL_4_1
Definition raster-expected.h:121
#define EXPECT_TRI_B_PIXEL_0_0
Definition raster-expected.h:90
#define EXPECT_TRI_D_PIXEL_0_1
Definition raster-expected.h:118
#define EXPECT_TRI_I_PIXEL_0_2
Definition raster-expected.h:181
#define EXPECT_TRI_I_PIXEL_0_1
Definition raster-expected.h:179
#define EXPECT_TRI_I_PIXEL_1_0
Definition raster-expected.h:178
#define EXPECT_TRI_A_PIXEL_1_0
Definition raster-expected.h:73
#define EXPECT_TRI_G_PIXEL_10_0
Definition raster-expected.h:154
#define EXPECT_TRI_B_PIXEL_1_1
Definition raster-expected.h:93
#define EXPECT_TRI_A_PIXEL_1_3
Definition raster-expected.h:83
#define EXPECT_TRI_B_PIXEL_1_0
Definition raster-expected.h:91
#define EXPECT_TRI_F_PIXEL_1_1
Definition raster-expected.h:148
#define EXPECT_TRI_H_PIXEL_0_5
Definition raster-expected.h:159
#define EXPECT_TRI_F_PIXEL_4_4
Definition raster-expected.h:147
#define EXPECT_TRI_A_PIXEL_3_0
Definition raster-expected.h:75
#define EXPECT_TRI_D_PIXEL_0_0
Definition raster-expected.h:115
#define EXPECT_TRI_D_PIXEL_3_0
Definition raster-expected.h:116
#define EXPECT_TRI_D_PIXEL_3_3
Definition raster-expected.h:122
#define EXPECT_TRI_D_PIXEL_4_4
Definition raster-expected.h:123
#define EXPECT_TRI_E_PIXEL_3_1
Definition raster-expected.h:138
#define EXPECT_TRI_I_PIXEL_0_0
Definition raster-expected.h:177
#define EXPECT_TRI_F_PIXEL_2_2
Definition raster-expected.h:146
#define EXPECT_TRI_E_PIXEL_2_2
Definition raster-expected.h:139
#define EXPECT_TRI_D_PIXEL_4_0
Definition raster-expected.h:117
#define EXPECT_TRI_A_PIXEL_2_0
Definition raster-expected.h:74
#define EXPECT_TRI_A_PIXEL_0_1
Definition raster-expected.h:77
#define EXPECT_TRI_A_PIXEL_0_3
Definition raster-expected.h:82
#define EXPECT_TRI_H_PIXEL_0_10
Definition raster-expected.h:160
#define EXPECT_TRI_E_PIXEL_0_0
Definition raster-expected.h:134
#define EXPECT_TRI_A_PIXEL_3_1
Definition raster-expected.h:79
#define EXPECT_TRI_E_PIXEL_4_0
Definition raster-expected.h:136
#define EXPECT_TRI_E_PIXEL_1_1
Definition raster-expected.h:137
#define EXPECT_TRI_E_PIXEL_2_3
Definition raster-expected.h:140
#define EXPECT_TRI_A_PIXEL_1_2
Definition raster-expected.h:80
#define EXPECT_TRI_F_PIXEL_0_0
Definition raster-expected.h:145
#define EXPECT_TRI_B_PIXEL_0_1
Definition raster-expected.h:92
#define EXPECT_TRI_A_PIXEL_0_0
Definition raster-expected.h:72
#define EXPECT_TRI_E_PIXEL_3_0
Definition raster-expected.h:135
#define EXPECT_TRI_D_PIXEL_1_1
Definition raster-expected.h:119
#define EXPECT_TRI_C_PIXEL_1020_507
Definition raster-expected.h:99
#define EXPECT_TRI_H_PIXEL_0_0
Definition raster-expected.h:158
#define EXPECT_TRI_C_PIXEL_1019_507
Definition raster-expected.h:98
#define EXPECT_TRI_A_PIXEL_4_0
Definition raster-expected.h:76
#define EXPECT_TRI_A_PIXEL_2_2
Definition raster-expected.h:81
#define EXPECT_TRI_C_PIXEL_1019_508
Definition raster-expected.h:100
#define EXPECT_TRI_D_PIXEL_3_1
Definition raster-expected.h:120
#define EXPECT_TRI_G_PIXEL_0_0
Definition raster-expected.h:152
#define EXPECT_TRI_C_PIXEL_1020_508
Definition raster-expected.h:101
#define EXPECT_TRI_I_PIXEL_1_1
Definition raster-expected.h:180
#define EXPECT_TRI_E_PIXEL_2_4
Definition raster-expected.h:141
#define EXPECT_TRI_A_PIXEL_2_1
Definition raster-expected.h:78
#define EXPECT_TRI_G_PIXEL_5_0
Definition raster-expected.h:153
#define EXPECT_TRI_A_PIXEL_0_4
Definition raster-expected.h:84
#define RASTER_CMD_BLUE
Definition raster-helpers.h:128
#define RASTER_CMD_RED
Definition raster-helpers.h:124
#define RASTER_CMD_WHITE
Definition raster-helpers.h:130
#define RASTER_CMD_GREEN
Definition raster-helpers.h:126
#define ASSERT_PIXEL_EQ(expected, x_, y_)
Definition raster-helpers.h:473