code wiki / _hdl_build / nx_d3d_interp_gate.nx
nx_d3d_interp_gate.nx source
↩ module page · 85 lines · 4626 B
1// nx_d3d_interp_gate.nx -- D3b: attribute INTERPOLATION conformance vs WARP. A triangle with per-vertex color
2// (v0 red / v1 green / v2 blue); our barycentric interpolation (pixel-center, D3D-UNORM rounding) vs WARP's actual
3// gradient (knowledge/warp_gradient.ppm). Grades our rasterizer's varying interpolation against Microsoft.
4// license_tier: ORIGINAL expect_exit: 0
5import "nx_syscalls.nx"
6
7func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
8func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 }
9func edge(ax: i64, ay: i64, bx: i64, by: i64, px: i64, py: i64) -> i64 { return (bx-ax)*(py-ay) - (by-ay)*(px-ax) }
10func iabs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
11func rnd_div(num: i64, den: i64) -> i64 { return (num + den/2) / den } // round(num/den), den>0, num>=0
12
13func main() -> i64 {
14 hw("=== nx_d3d_interp_gate -- D3b: barycentric interpolation conformance vs WARP (RGB gradient) ===\n" as *u8)
15 var fails: i64 = 0
16 let szp: *i64 = sys_mmap(16) as *i64
17 let ppm: *u8 = sys_read_file("knowledge/warp_gradient.ppm" as *u8, szp)
18 if (ppm as i64) == 0 { hw("FAIL no warp_gradient.ppm\n" as *u8); sys_exit(1); return 1 }
19 var hdr: i64 = 0; var nl: i64 = 0; var i: i64 = 0
20 while i < 40 { if ppm[i] == (10 as u8) { nl = nl + 1; if nl == 3 { hdr = i + 1; i = 40 } } i = i + 1 }
21
22 // 2x screen verts: v0(32,96)=red, v1(64,32)=green, v2(96,96)=blue
23 let area: i64 = iabs(edge(32,96,64,32,96,96))
24 var sgn: i64 = 1
25 if edge(32,96,64,32,96,96) < 0 { sgn = 0 - 1 }
26
27 var exact: i64 = 0
28 var within1: i64 = 0
29 var within2: i64 = 0
30 var cov: i64 = 0
31 var wcov: i64 = 0
32 var y: i64 = 0
33 while y < 64 {
34 var x: i64 = 0
35 while x < 64 {
36 let sx: i64 = 2*x + 1
37 let sy: i64 = 2*y + 1
38 let w0: i64 = edge(64,32,96,96,sx,sy) * sgn // weight of v0 (red)
39 let w1: i64 = edge(96,96,32,96,sx,sy) * sgn // weight of v1 (green)
40 let w2: i64 = edge(32,96,64,32,sx,sy) * sgn // weight of v2 (blue)
41 var orr: i64 = 0; var ogg: i64 = 0; var obb: i64 = 0
42 var inside: i64 = 0
43 if w0 >= 0 { if w1 >= 0 { if w2 >= 0 { inside = 1 } } }
44 if inside == 1 {
45 orr = rnd_div(w0 * 255, area)
46 ogg = rnd_div(w1 * 255, area)
47 obb = rnd_div(w2 * 255, area)
48 cov = cov + 1
49 }
50 let o3: i64 = (y*64 + x)*3
51 let wr: i64 = ppm[hdr + o3] as i64
52 let wg: i64 = ppm[hdr + o3 + 1] as i64
53 let wb: i64 = ppm[hdr + o3 + 2] as i64
54 if wr != 0 { wcov = wcov + 1 }
55 if wg != 0 { if wr == 0 { wcov = wcov } }
56 let dr: i64 = iabs(orr - wr)
57 let dg: i64 = iabs(ogg - wg)
58 let db: i64 = iabs(obb - wb)
59 if dr == 0 { if dg == 0 { if db == 0 { exact = exact + 1 } } }
60 if dr <= 1 { if dg <= 1 { if db <= 1 { within1 = within1 + 1 } } }
61 if dr <= 2 { if dg <= 2 { if db <= 2 { within2 = within2 + 1 } } }
62 x = x + 1
63 }
64 y = y + 1
65 }
66 hw(" coverage ours="); pn(cov); hw(" exact="); pn(exact); hw("/4096 within-1="); pn(within1); hw("/4096 within-2="); pn(within2); hw("/4096\n" as *u8)
67
68 // T1 coverage matches WARP (triangle area 512)
69 var t1: i64 = 0
70 if cov >= 500 { if cov <= 524 { t1 = 1 } }
71 if t1 == 1 { hw("T1 PASS coverage matches (~512)\n" as *u8) } else { fails=fails+1; hw("T1 FAIL cov="); pn(cov); hw("\n" as *u8) }
72 // T2 interpolation within 1 LSB of WARP on essentially every pixel
73 var t2: i64 = 0
74 if within1 >= 4090 { t2 = 1 }
75 if t2 == 1 { hw("T2 PASS interpolation within 1 LSB of WARP on >=4090/4096 pixels\n" as *u8) } else { fails=fails+1; hw("T2 FAIL within1="); pn(within1); hw("\n" as *u8) }
76 // T3 within 2 LSB EVERYWHERE (no gross mismatch)
77 var t3: i64 = 0
78 if within2 == 4096 { t3 = 1 }
79 if t3 == 1 { hw("T3 PASS every pixel within 2 LSB of WARP (no gross error)\n" as *u8) } else { fails=fails+1; hw("T3 FAIL within2="); pn(within2); hw("\n" as *u8) }
80
81 if fails == 0 { hw("NX-D3D-INTERP GREEN -- barycentric attribute interpolation matches Microsoft WARP within rounding\n" as *u8); sys_exit(0); return 0 }
82 hw("NX-D3D-INTERP RED fails="); pn(fails); hw("\n" as *u8)
83 sys_exit(1)
84 return 1
85}