Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
gte-depthcue.c
Go to the documentation of this file.
1// Depth cue instructions: DPCS, DPCT, DCPL, INTPL
2
3// DPCS: depth cue single - interpolates RGBC toward far color using IR0
4// clang-format off
5
7 gte_set_far_color(0x1000, 0x1000, 0x1000); // FC = (4096, 4096, 4096)
8 cop2_put(6, 0x00808080); // RGBC: R=0x80, G=0x80, B=0x80
9 cop2_put(8, 0x0800); // IR0 = 0.5
11 cop2_cmd(COP2_DPCS(1, 0));
12 int32_t mac1, mac2, mac3;
13 uint32_t rgb2;
14 cop2_get(25, mac1);
15 cop2_get(26, mac2);
16 cop2_get(27, mac3);
17 cop2_get(22, rgb2);
18 ramsyscall_printf("DPCS: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
22 cester_assert_uint_eq(0x00c0c0c0, rgb2);
23 // Formula: MAC = R<<16 + IR0*(FC<<12 - R<<16) >> shift
24 // R<<16 = 0x80<<16 = 0x800000
25 // FC<<12 = 0x1000<<12 = 0x1000000
26 // diff = 0x1000000 - 0x800000 = 0x800000
27 // IR0 * diff = 0x800 * 0x800000 ... this is large
28)
29
30// DPCS with IR0=0: no interpolation, output = input color
31CESTER_TEST(dpcs_ir0_zero, gte_tests,
32 gte_set_far_color(0xff00, 0xff00, 0xff00);
33 cop2_put(6, 0x00406080); // R=0x80, G=0x60, B=0x40
34 cop2_put(8, 0); // IR0 = 0
37 uint32_t rgb2;
39 uint8_t r = rgb2 & 0xff;
40 uint8_t g = (rgb2 >> 8) & 0xff;
41 uint8_t b = (rgb2 >> 16) & 0xff;
42 // With IR0=0, interpolation weight is 0, so output = input
46)
47
48// DPCS with IR0=0x1000: full interpolation toward far color
49CESTER_TEST(dpcs_ir0_max, gte_tests,
50 gte_set_far_color(0x1000, 0x800, 0x400); // FC scaled
51 cop2_put(6, 0x00000000); // RGBC: all zero
52 cop2_put(8, 0x1000); // IR0 = 1.0
54 cop2_cmd(COP2_DPCS(1, 0));
55 int32_t mac1, mac2, mac3;
56 cop2_get(25, mac1);
57 cop2_get(26, mac2);
58 cop2_get(27, mac3);
59 ramsyscall_printf("DPCS max: MAC=(%d,%d,%d)\n", mac1, mac2, mac3);
63 // With R=0, MAC = 0 + IR0 * (FC<<12 - 0) = 1.0 * FC<<12 >> 12 = FC
64)
65
66// DPCS color FIFO push and CODE preservation
67CESTER_TEST(dpcs_code_preserved, gte_tests,
69 cop2_put(6, 0xab102030); // CODE=0xAB, R=0x30, G=0x20, B=0x10
70 cop2_put(8, 0);
72 cop2_cmd(COP2_DPCS(1, 0));
73 uint32_t rgb2;
74 cop2_get(22, rgb2);
75 cester_assert_uint_eq(0xab, (rgb2 >> 24) & 0xff); // CODE preserved
76)
77
78// DPCT: depth cue triple - reads from color FIFO front (RGB0), not RGBC
79CESTER_TEST(dpct_reads_fifo, gte_tests,
80 gte_set_far_color(0, 0, 0);
81 // Set up color FIFO with known values
82 cop2_put(20, 0x00102030); // RGB0: R=0x30, G=0x20, B=0x10
83 cop2_put(21, 0x00405060); // RGB1
84 cop2_put(22, 0x00708090); // RGB2
85 cop2_put(6, 0xff000000); // RGBC: CODE=0xff, colors=0 (should NOT be used as input)
86 cop2_put(8, 0); // IR0=0: output = input
88 cop2_cmd(COP2_DPCT(1, 0));
89 // After 3 iterations, the FIFO has been processed
90 uint32_t rgb0, rgb1, rgb2;
91 cop2_get(20, rgb0);
92 cop2_get(21, rgb1);
93 cop2_get(22, rgb2);
94 ramsyscall_printf("DPCT: RGB0=0x%08x RGB1=0x%08x RGB2=0x%08x\n", rgb0, rgb1, rgb2);
95 // Each iteration: reads R0/G0/B0 (front of FIFO), pushes result
96 // With IR0=0, each iteration's output = its input color
97 // Iteration 1: reads RGB0(0x102030), pushes -> FIFO shifts
98 // Iteration 2: reads new RGB0 (was RGB1: 0x405060), pushes
99 // Iteration 3: reads new RGB0 (was RGB2: 0x708090), pushes
100 // Result FIFO should contain the 3 processed colors
101 // CODE comes from RGBC (0xff)
102 cester_assert_uint_eq(0xff102030, rgb0);
103 cester_assert_uint_eq(0xff405060, rgb1);
104 cester_assert_uint_eq(0xff708090, rgb2);
105)
106
107// DCPL: depth cue with pre-computed light
108CESTER_TEST(dcpl_basic, gte_tests,
109 gte_set_far_color(0x1000, 0x1000, 0x1000);
110 cop2_put(6, 0x00808080); // RGBC
111 // Pre-computed light in IR1-3
112 cop2_put(9, 0x1000); // IR1 = 1.0
113 cop2_put(10, 0x0800); // IR2 = 0.5
114 cop2_put(11, 0x0400); // IR3 = 0.25
115 cop2_put(8, 0); // IR0 = 0 (no depth cue)
118 int32_t mac1, mac2, mac3;
119 uint32_t rgb2;
123 cop2_get(22, rgb2);
124 ramsyscall_printf("DCPL: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
129 // With IR0=0: MAC = (R<<4)*IR, no depth cue interpolation
130 // MAC1 = (0x80 << 4) * 0x1000 = 0x800 * 0x1000 = 0x800000
131 // After >>12: 0x800 = 2048 -> IR1, /16 = 128 -> R2
132)
133
134// DCPL with depth cue interpolation
135CESTER_TEST(dcpl_with_depth, gte_tests,
136 gte_set_far_color(0x1000, 0x1000, 0x1000);
137 cop2_put(6, 0x00808080);
138 cop2_put(9, 0x1000);
139 cop2_put(10, 0x1000);
140 cop2_put(11, 0x1000);
141 cop2_put(8, 0x0800); // IR0 = 0.5
143 cop2_cmd(COP2_DCPL(1, 0));
144 int32_t mac1, mac2, mac3;
145 uint32_t flag;
146 cop2_get(25, mac1);
147 cop2_get(26, mac2);
148 cop2_get(27, mac3);
149 flag = gte_read_flag();
150 ramsyscall_printf("DCPL depth: MAC=(%d,%d,%d) FLAG=0x%08x\n", mac1, mac2, mac3, flag);
154 cester_assert_uint_eq(0x00000000, flag);
155)
156
157// INTPL: interpolation (depth cue on IR vector directly)
158CESTER_TEST(intpl_basic, gte_tests,
159 gte_set_far_color(0x1000, 0x2000, 0x3000);
160 cop2_put(9, 0x100); // IR1
161 cop2_put(10, 0x200); // IR2
162 cop2_put(11, 0x300); // IR3
163 cop2_put(8, 0); // IR0 = 0: no interpolation
166 int32_t mac1, mac2, mac3;
167 cop2_get(25, mac1);
168 cop2_get(26, mac2);
169 cop2_get(27, mac3);
170 // With IR0=0: MAC = IR << 12 >> shift = IR (with sf=1)
174)
175
177 gte_set_far_color(0x1000, 0x1000, 0x1000);
178 cop2_put(9, 0);
179 cop2_put(10, 0);
180 cop2_put(11, 0);
181 cop2_put(8, 0x0800); // IR0 = 0.5
183 cop2_cmd(COP2_INTPL(1, 0));
184 int32_t mac1, mac2, mac3;
185 cop2_get(25, mac1);
186 cop2_get(26, mac2);
187 cop2_get(27, mac3);
188 ramsyscall_printf("INTPL half: MAC=(%d,%d,%d)\n", mac1, mac2, mac3);
192 // IR=0, FC=0x1000, IR0=0.5
193 // MAC = 0 + 0.5*(FC - 0) = 0.5 * 0x1000 = 0x800
194)
195
196// INTPL pushes color FIFO
197CESTER_TEST(intpl_color_push, gte_tests,
198 gte_set_far_color(0, 0, 0);
199 cop2_put(9, 0x0ff0); // MAC1=0x0ff0, /16 = 255
200 cop2_put(10, 0x0800); // MAC2=0x0800, /16 = 128
201 cop2_put(11, 0x0010); // MAC3=0x0010, /16 = 1
202 cop2_put(8, 0);
203 cop2_put(6, 0xcc000000); // CODE=0xCC
205 cop2_cmd(COP2_INTPL(1, 0));
206 uint32_t rgb2;
207 cop2_get(22, rgb2);
208 uint8_t cd = (rgb2 >> 24) & 0xff;
209 uint8_t r = rgb2 & 0xff;
210 uint8_t g = (rgb2 >> 8) & 0xff;
211 uint8_t b = (rgb2 >> 16) & 0xff;
212 ramsyscall_printf("INTPL color: R=%u G=%u B=%u CD=0x%02x raw=0x%08x\n", r, g, b, cd, rgb2);
217)
#define COP2_INTPL(sf, lm)
Definition cop2.h:142
#define cop2_cmd(op)
Definition cop2.h:175
#define COP2_DPCT(sf, lm)
Definition cop2.h:140
#define cop2_put(reg, val)
Definition cop2.h:191
#define COP2_DPCS(sf, lm)
Definition cop2.h:139
#define cop2_get(reg, dest)
Definition cop2.h:198
#define COP2_DCPL(sf, lm)
Definition cop2.h:141
int32_t mac1
Definition gte-depthcue.c:118
uint8_t g
Definition gte-depthcue.c:40
uint8_t r
Definition gte-depthcue.c:39
gte_set_far_color(0xff00, 0xff00, 0xff00)
gte_tests
Definition gte-depthcue.c:31
cester_assert_uint_eq(0x80, r)
uint8_t cd
Definition gte-depthcue.c:208
uint8_t b
Definition gte-depthcue.c:41
int32_t mac2
Definition gte-depthcue.c:118
gte_clear_flag()
CESTER_TEST(dpcs_basic, gte_tests, gte_set_far_color(0x1000, 0x1000, 0x1000);cop2_put(6, 0x00808080);cop2_put(8, 0x0800);gte_clear_flag();cop2_cmd(COP2_DPCS(1, 0));int32_t mac1, mac2, mac3;uint32_t rgb2;cop2_get(25, mac1);cop2_get(26, mac2);cop2_get(27, mac3);cop2_get(22, rgb2);ramsyscall_printf("DPCS: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);cester_assert_int_eq(3072, mac1);cester_assert_int_eq(3072, mac2);cester_assert_int_eq(3072, mac3);cester_assert_uint_eq(0x00c0c0c0, rgb2);) CESTER_TEST(dpcs_ir0_zero
int32_t mac3
Definition gte-depthcue.c:118
cester_assert_int_eq(2048, mac1)
uint32_t rgb2
Definition gte-depthcue.c:37
ramsyscall_printf("DCPL: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2)
uint32_t flag
Definition gte-edgecase.c:38
uint32_t rgb1
Definition gte-lighting.c:207
uint32_t rgb0
Definition gte-lighting.c:207