code wiki / (root) / nx_texpaint_gate.nx

nx_texpaint_gate.nx

buildroot/runtime/nx_texpaint_gate.nx

35320 B548 linesdepth 4pulls 7 transitivereach 0 importersview sourcekind gate/proof
docsdependenciesstructsconstsfunctions

about

nx_texpaint_gate.nx -- the gate for nx_texpaint_lib (/compare/dcc DC7, texture painting). THE HAZARD THIS GATE IS SHAPED AGAINST is the one the task names: a paint function that writes THE WHOLE ATLAS trivially passes "the known texel changed". So the load-bearing cell here is not the positive control on its own -- it is the pair of BOUNDED-WRITE teeth beside it, which count the changed texels against a HAND-COMPUTED disc area and then count the changed texels OUTSIDE the brush and require zero. A whole-atlas painter fails both, a do-nothing painter fails the first, and only a correct one passes both. Every disc area, every texel address and every painted BYTE VALUE below was worked out by hand before the code was run; they are written as literals with their arithmetic in the comment, so a fixture that agrees with a wrong implementation would have to be wrong in exactly the same way. THE ANTI-TEAR PROOF IS A PERMANENT NEGATIVE CONTROL, NOT AN ANECDOTE. tp_stroke_core is the naive painter -- shipped, public, callable -- so the tooth that proves the seam bleed matters RUNS the bleed-free version and shows the far side of the cut untouched, then runs the full stroke and shows it painted. That is a gv_bite that can be re-run by anyone, rather than a claim that the author once deleted the fix and watched a test go red. FIXTURE GEOMETRY, chosen so every boundary is exact and nothing rests on a rounding accident: res 64, grid 4 -> tile width in UV units 65536/4 = 16384, chart bounds 16384*64/65536 = 16 texels. So chart 0 is texels [0,16) x [0,16) and the four charts tile the atlas exactly, with no remainder. A SECOND map set at grid 3 is carried on purpose: 65536/3 truncates to 21845, the charts land at 0,21,42 and stop at 63, so ONE texel column belongs to no chart at all. That is the case where a partition claim could quietly leak, and it is asserted to SUM rather than assumed to. 100% sovereign. No hardware writes (Rule 26). license_tier: ORIGINAL expect_exit: 0

dependencies 5 imports · 0 importers

nx_syscalls.nx nx_gate_verdict.nx nx_vecmath.nx nx_editstack_lib.nx nx_texpaint_lib.nx nx_texpaint_gate.nx

imports: nx_syscalls.nxnx_gate_verdict.nxnx_vecmath.nxnx_editstack_lib.nxnx_texpaint_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main gv_ctr sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ gv_head gv_puts sys_write ↻ tg_black tp_maps_new tp_geom_ok sys_mmap ↻ tp_set_bytes tp_hdr_bytes tp_map_bytes gv_check gv_puts ↻ tg_ne tg_eq tp_geom_ok ↻ tp_res tp_nmaps tp_get tp_map_ptr tp_hdr_bytes ↻ tp_map_bytes ↻ tp_texel_off tp_ch_span_derived

structs

none

consts

31const TG_RES: i64 = 64
32const TG_GRID: i64 = 4
33const TG_GRID_ODD: i64 = 3 // the grid that does NOT divide the UV span evenly
34const TG_NMAPS: i64 = 4 // albedo, specular, gloss, normal -- the shape of ntb_bake_pbr's map set
35const TG_CAP: i64 = 8 // stroke-log capacity for the session fixtures
36const TG_ALL_CH: i64 = 7 // every channel: mask 111
37const TG_CH_G: i64 = 2 // green only: mask 010
38const TG_CH_R: i64 = 1 // red only: mask 001
45const TG_CX: i64 = 8
46const TG_CY: i64 = 8
47const TG_R: i64 = 3
48const TG_DISC_AREA: i64 = 25
51const TG_CENTRE_BYTE: i64 = 255
55const TG_RIM_IN_DX: i64 = 2
56const TG_RIM_IN_BYTE: i64 = 65
58const TG_RIM_OUT_DX: i64 = 3
69const TG_SEAM_CX: i64 = 1
70const TG_SEAM_PLANAR: i64 = 20
71const TG_SEAM_BLEED: i64 = 5
72const TG_SEAM_FAR_X: i64 = 15
74const TG_STRENGTH: i64 = 1000
75const TG_VALUE: i64 = 255
76const TG_HALFSTR: i64 = 500
80const TG_NSTROKES: i64 = 3
82const TG_S2_MAP: i64 = 1
83const TG_S2_STRENGTH: i64 = 600
84const TG_S2_VALUE: i64 = 10
89const TG_S3_CX: i64 = 9
90const TG_S3_CY: i64 = 9
91const TG_S3_R: i64 = 2
92const TG_S3_STRENGTH: i64 = 300
93const TG_S3_VALUE: i64 = 200
94const TG_REEVAL_VALUE: i64 = 100
97const TG_UVSTRIDE_TEXC: i64 = 3
98const TG_UVSTRIDE_PAIR: i64 = 2
99const TG_NVERT: i64 = 3
100const TG_NTRI: i64 = 1
101const TG_U1: i64 = 32768
102const TG_V2: i64 = 32768
103const TG_B0: i64 = 200
104const TG_B1: i64 = 300
105const TG_B2: i64 = 500
106const TG_EXP_U: i64 = 9830 // (200*0 + 300*32768 + 500*0)/1000 = 9830400/1000 = 9830 (floor of 9830.4)
107const TG_EXP_V: i64 = 16384 // (200*0 + 300*0 + 500*32768)/1000 = 16384000/1000 = 16384 exactly
108const TG_EXP_X: i64 = 9 // 9830*64/65536 = 629120/65536 = 9 (floor of 9.5996)
109const TG_EXP_Y: i64 = 16 // 16384*64/65536 = 1048576/65536 = 16 exactly
112const TG_ODD_COVER: i64 = 63
113const TG_ODD_UNCOVERED: i64 = 1

functions

115func tg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 }
called by 1: main
116func tg_ne(a: i64, b: i64) -> i64 { if a != b { return 1 } return 0 }
called by 1: main
117func tg_gt(a: i64, b: i64) -> i64 { if a > b { return 1 } return 0 }
called by 1: main
118func tg_ge(a: i64, b: i64) -> i64 { if a >= b { return 1 } return 0 }
called by 1: main
119func tg_le(a: i64, b: i64) -> i64 { if a <= b { return 1 } return 0 }
called by 1: main
120func tg_say(s: *u8, v: i64) -> i64 { gv_puts(s); gv_num(v); gv_puts("\n" as *u8); return 0 }
called by 1: main calls 2: gv_putsgv_num
124func tg_fill(ms: *i64) -> i64
148func tg_differs(a: *i64, b: *i64, m: i64, x: i64, y: i64) -> i64
156func tg_changed_map(a: *i64, b: *i64, m: i64) -> i64
169func tg_out_of_disc(ms: *i64, cx: i64, cy: i64, r: i64, x: i64, y: i64) -> i64
183func tg_changed_outside(a: *i64, b: *i64, m: i64, cx: i64, cy: i64, r: i64) -> i64
called by 1: main calls 3: tp_restg_differstg_out_of_disc
200func tg_changed_other_maps(a: *i64, b: *i64, m: i64) -> i64
called by 1: main calls 2: tp_nmapstg_changed_map
209func tg_column_changed(a: *i64, b: *i64, m: i64, x: i64) -> i64
called by 1: main calls 2: tp_restg_differs
218func tg_black() -> *i64 { return tp_maps_new(TG_RES, TG_NMAPS, TG_GRID) }
called by 1: main calls 1: tp_maps_new
220func tg_patterned() -> *i64
called by 1: main calls 2: tp_maps_newtg_fill
227func tg_apply_session(ms: *i64, first_value: i64) -> i64
called by 1: main calls 1: tp_stroke
233func tg_record_session(st: *i64, ms: *i64, first_value: i64) -> i64
called by 1: main calls 1: tp_record
240func main(argc: i64, argv: *i64) -> i64