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}