code wiki / (root) / nx_enginelab.nx

nx_enginelab.nx source

↩ module page · 534 lines · 25925 B

1// nx_enginelab.nx -- THE DRIVER: attach the sovereign engine instrument to a REAL renderer. 2// 3// WHAT WAS MISSING AND WHY IT MATTERED. nx_enginelab_lib (the spine), nx_enginelab_store (EL1 4// persistence), nx_enginelab_golden (the O3DE class) and nx_enginelab_analysis (replay, shader 5// binding, sampling, call tree) are roughly 69 KB of gate-proven library. The gate that proves them 6// says so in its own verdict: every tooth asserts an arithmetic property "on fixtures whose answers 7// are known by construction". That is a proof about the INSTRUMENT and it is worth having -- but 8// until this file existed NOTHING drove the instrument over a real frame, so the estate owned a 9// profiler that had never profiled anything. A measurement capability with no driver is 10// BUILT-AND-UNWIRED, and a green gate makes that invisible: the gate passes exactly as well with 11// zero real subjects as with a thousand. 12// 13// THE SUBJECT, AND WHY THIS ONE. nx_wasm_craft is the estate real renderer -- a per-pixel integer 14// DDA raycast over a voxel world plus a skinned-mesh character composite -- and it is the ONE render 15// path reachable natively with no browser (nx_world_snap already drives it that way, which is the 16// standing evidence that init_impl_v / tick_impl / render_impl compose outside a page). Attaching 17// here therefore needs no GUI, no capture harness and no second copy of the engine. 18// 19// WHAT THIS DRIVER MEASURES, AND WHAT IT REFUSES TO. It owns the call sites it wraps: the arena 20// allocation, init, and per frame a tick zone and a render zone. Everything derived from those is a 21// real observation of a real frame. It does NOT own the inside of render_impl, so: 22// - THE DRAW CLASS IS UNMEASURABLE HERE AND SAYS SO BY NAME. The engine emits no draw stream -- 23// there is no el_draw call anywhere in nx_wasm_craft -- so draws, redundant binds, pipeline 24// state hashes, capture diff and replay divergence have NO SUBJECT. This driver reports draws=0 25// with the reason attached and the exact emission site the engine lane owes. It does NOT 26// reconstruct the engine visibility test from outside: mob_draw culls on 200 < vz < 40*256, and 27// copying that predicate here would be a duplicate ruler that drifts silently the day the engine 28// changes it. A NAMED ABSENCE IS A BUILD CONTRACT; A RECONSTRUCTED NUMBER IS A LIE WITH A 29// DENOMINATOR. 30// - THE BOUND VERDICT ABSTAINS. This renderer is a CPU integer raycaster; nothing is submitted to 31// a GPU queue, so el_bound_verdict correctly returns UNKNOWN. Manufacturing a GPU signal to make 32// the verdict decide would be the acquit-on-no-evidence defect the spine exists to prevent. 33// What it CAN answer, and nothing else in this estate could before: how long a real frame costs, 34// how that cost splits between simulation and rasterisation, what the cost per RAY is, whether the 35// pacing stutters, and whether two independent runs of the same seed produce the same pixels. 36// 37// RAYS ARE THE UNIT OF WORK, AND THE COUNT IS ENGINE-OWNED. wc_rw/wc_rh are the engine own single 38// owner of the written extent (its source says so), so rays-per-frame is READ from the engine rather 39// than recomputed here. ns-per-ray is the figure that survives a resolution change; a bare frame 40// time does not. 41// 42// license_tier: ORIGINAL No hardware writes (Rule 26): this reads a framebuffer and computes. 43import "nx_syscalls.nx" 44import "nx_enginelab_lib.nx" 45import "nx_enginelab_store.nx" 46import "nx_enginelab_golden.nx" 47import "nx_wasm_craft.nx" 48 49// ---- named parameters. Every bar and every literal below has a name, because a number a reader 50// cannot find again is a number nobody can change on evidence. 51const ELD_ARENA_PAD: i64 = 4096 // the same head-room nx_world_snap allocates beside CRAFT_TOTAL 52const ELD_TID_MAIN: i64 = 1 // one thread: this driver is single-threaded by construction 53const ELD_N_ARENA: i64 = 1 // interned zone/alloc name ids -- ids, never strings, in a hot loop 54const ELD_N_INIT: i64 = 2 55const ELD_N_TICK: i64 = 3 56const ELD_N_RENDER: i64 = 4 57// DERIVED, not guessed: one FRAME record plus a tick zone plus a render zone per frame, and a 58// prologue of arena-alloc + init-zone + the trailing frame mark that closes the last frame. If this 59// arithmetic is ever wrong the store REFUSES the overflow and el_complete reports 0 -- the coverage 60// line below carries it, so an undersized store can never read as a complete measurement. 61const ELD_REC_PER_FRAME: i64 = 3 62const ELD_REC_PROLOGUE: i64 = 8 63const ELD_FRAMES_DEFAULT: i64 = 4 64const ELD_TICK_MS: i64 = 16 // one 60Hz step, the same dt nx_world_snap ticks with 65const ELD_TARGET_FPS_DEFAULT: i64 = 60 66const ELD_SEED_DEFAULT: i64 = 20260728 // the beach seed the acceptance corpus already uses 67const ELD_Q_DEFAULT: i64 = 1 // native resolution: a capture reduced by a load-sensitive 68 // governor makes every verdict a function of box load 69const ELD_Q_GOVERNOR_ARG: i64 = 0 // q=0 asks for the engine own adaptive controller instead 70const ELD_MIN_CLOSED_FRAMES: i64 = 2 // fewer than two boundaries is not a pacing measurement 71const ELD_GRID_DEFAULT: i64 = 16 // golden grid, cells per axis 72const ELD_THRESH_DEFAULT: i64 = 4 // per-cell mean tolerance 73const ELD_DEC: i64 = 10 74const ELD_ASCII_0: i64 = 48 75const ELD_DIGIT_TOP: i64 = 9 76const ELD_NUMBUF: i64 = 32 77const ELD_RGB_CH: i64 = 3 78const ELD_BYTE_MASK: i64 = 255 79const ELD_G_SHIFT: i64 = 8 80const ELD_B_SHIFT: i64 = 16 81const ELD_NS_PER_US: i64 = 1000 82const ELD_PERMIL: i64 = 1000 83const ELD_SCRATCH_SLOTS: i64 = 32 84const ELD_ARGV_VERB: i64 = 1 85const ELD_EXIT_OK: i64 = 0 86const ELD_EXIT_FAIL: i64 = 1 87const ELD_EXIT_USAGE: i64 = 2 88const ELD_EXIT_UNMEASURABLE: i64 = 3 89 90// ---- output primitives --------------------------------------------------------------------------- 91func eld_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 92func eld_puts(s: *u8) -> i64 { sys_write(1, s, eld_slen(s)); return 0 } 93func eld_pn(v: i64) -> i64 { 94 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 95 var m: i64 = v 96 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 97 let t: *u8 = sys_mmap(ELD_NUMBUF) 98 var k: i64 = 0 99 while m > 0 { t[k] = (ELD_ASCII_0 + (m % ELD_DEC)) as u8; m = m / ELD_DEC; k = k + 1 } 100 let o: *u8 = sys_mmap(ELD_NUMBUF) 101 var i: i64 = 0 102 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 103 sys_write(1, o, k) 104 sys_munmap(t, ELD_NUMBUF) 105 sys_munmap(o, ELD_NUMBUF) 106 return 0 107} 108func eld_kv(label: *u8, v: i64) -> i64 { eld_puts(label); eld_pn(v); eld_puts(" " as *u8); return 0 } 109func eld_nl() -> i64 { eld_puts("\n" as *u8); return 0 } 110func eld_int(s: *u8) -> i64 { 111 var v: i64 = 0 112 var i: i64 = 0 113 while s[i] != (0 as u8) { 114 let c: i64 = s[i] as i64 115 if c >= ELD_ASCII_0 { if c <= ELD_ASCII_0 + ELD_DIGIT_TOP { v = v*ELD_DEC + (c - ELD_ASCII_0) } } 116 i = i + 1 117 } 118 return v 119} 120func eld_streq(a: *u8, b: *u8) -> i64 { 121 var i: i64 = 0 122 while a[i] != (0 as u8) { 123 if a[i] != b[i] { return 0 } 124 i = i + 1 125 } 126 if b[i] != (0 as u8) { return 0 } 127 return 1 128} 129func eld_scratch() -> *i64 { return sys_mmap(ELD_SCRATCH_SLOTS * EL_I64) as *i64 } 130// The interned ids above are printed back as names here, in ONE place, so a report can never name a 131// zone the driver does not actually open. 132func eld_name(id: i64) -> i64 { 133 if id == ELD_N_ARENA { eld_puts("arena" as *u8); return 0 } 134 if id == ELD_N_INIT { eld_puts("init" as *u8); return 0 } 135 if id == ELD_N_TICK { eld_puts("tick" as *u8); return 0 } 136 if id == ELD_N_RENDER { eld_puts("render" as *u8); return 0 } 137 eld_puts("none" as *u8) 138 return 0 139} 140 141// ---- the attachment ------------------------------------------------------------------------------ 142func eld_arena_bytes() -> i64 { return CRAFT_TOTAL + ELD_ARENA_PAD } 143func eld_store_cap(frames: i64) -> i64 { return ELD_REC_PROLOGUE + frames * ELD_REC_PER_FRAME } 144// The engine native pixel count, from the engine own frame extent. Read rather than restated, so a 145// change to the engine frame size cannot leave a stale denominator here. 146func eld_native_pixels() -> i64 { return W * H } 147 148// THE FRAME RECORD SPARE PAYLOAD CARRIES THIS DRIVER TWO PER-FRAME FACTS. The spine documents 149// EL_F_C for a FRAME as the ordinal and leaves A and B unused; this driver writes A = the quality 150// level the frame was actually rendered at and B = the rays that quality implies. Declared here 151// rather than discovered by a later reader of a capture. 152const ELD_FRAME_A_Q: i64 = 5 // == EL_F_A, restated at its meaning 153const ELD_FRAME_B_RAYS: i64 = 6 // == EL_F_B 154 155// Run `frames` real frames of the real engine through the instrument. Returns the arena, or 0. 156func eld_run(st: *i64, v: i64, seed: i64, q: i64, frames: i64) -> i64 { 157 let base: i64 = sys_mmap(eld_arena_bytes()) as i64 158 if base == 0 { return 0 } 159 // A REAL allocation, recorded as one. This is the whole engine arena and by far the largest 160 // single allocation on the path, so a memory report that omitted it would be fiction. 161 el_alloc(st, sys_now_us(), ELD_TID_MAIN, ELD_N_ARENA, eld_arena_bytes(), base) 162 el_zone_begin(st, sys_now_us(), ELD_TID_MAIN, ELD_N_INIT) 163 init_impl_v(base, v, seed) 164 el_zone_end(st, sys_now_us()) 165 var i: i64 = 0 166 while i < frames { 167 let fi: i64 = el_frame_mark(st, sys_now_us()) 168 el_zone_begin(st, sys_now_us(), ELD_TID_MAIN, ELD_N_TICK) 169 tick_impl(base, ELD_TICK_MS) 170 el_zone_end(st, sys_now_us()) 171 // QUALITY IS PINNED AFTER THE TICK, NOT BEFORE IT. The engine adaptive controller writes 172 // S_Q during the tick, so a value written before it would be overwritten and the announced 173 // quality would not be the quality rendered. q=0 deliberately leaves the governor in charge 174 // and the driver RECORDS what it chose instead of dictating one. 175 let s: *i64 = wst(base) 176 if q > ELD_Q_GOVERNOR_ARG { 177 var qq: i64 = q 178 if qq > Q_MAX { qq = Q_MAX } 179 s[S_Q] = qq 180 } 181 el_zone_begin(st, sys_now_us(), ELD_TID_MAIN, ELD_N_RENDER) 182 render_impl(base) 183 el_zone_end(st, sys_now_us()) 184 if fi >= 0 { 185 el_set(st, fi, ELD_FRAME_A_Q, wc_q(base)) 186 el_set(st, fi, ELD_FRAME_B_RAYS, wc_rw(base) * wc_rh(base)) 187 } 188 i = i + 1 189 } 190 // THE TRAILING MARK CLOSES THE LAST FRAME. A frame cost is the distance to the next boundary, 191 // so without this the final frame has no successor, is reported OPEN, and is excluded from every 192 // statistic -- a measurement that silently loses its last sample. 193 el_frame_mark(st, sys_now_us()) 194 return base 195} 196 197// ---- the report ---------------------------------------------------------------------------------- 198func eld_zone_line(st: *i64, name: i64) -> i64 { 199 let a: *i64 = eld_scratch() 200 el_zone_agg(st, name, a) 201 eld_kv("calls=" as *u8, a[EL_AGG_CALLS]) 202 eld_kv("incl_us=" as *u8, a[EL_AGG_INCL]) 203 eld_kv("self_us=" as *u8, a[EL_AGG_SELF]) 204 eld_kv("max_us=" as *u8, a[EL_AGG_MAX]) 205 eld_kv("open=" as *u8, a[EL_AGG_OPEN]) 206 eld_nl() 207 return a[EL_AGG_SELF] 208} 209 210func eld_report(st: *i64, base: i64, v: i64, seed: i64, q_arg: i64, frames: i64, target_fps: i64) -> i64 { 211 let rw: i64 = wc_rw(base) 212 let rh: i64 = wc_rh(base) 213 let rays: i64 = rw * rh 214 var q_reason: i64 = EL_Q_EXPLICIT 215 if q_arg == ELD_Q_GOVERNOR_ARG { q_reason = EL_Q_GOVERNOR } 216 // permil of the engine OWN native pixel count, so a reduced capture can never pass as a full one 217 let q_permil: i64 = rays * ELD_PERMIL / eld_native_pixels() 218 219 eld_puts("ENGINELAB-SUBJECT organ=nx_wasm_craft entry=render_impl " as *u8) 220 eld_kv("v=" as *u8, v) 221 eld_kv("seed=" as *u8, seed) 222 eld_kv("frames_requested=" as *u8, frames) 223 eld_kv("q=" as *u8, wc_q(base)) 224 eld_kv("rw=" as *u8, rw) 225 eld_kv("rh=" as *u8, rh) 226 eld_kv("rays_per_frame=" as *u8, rays) 227 eld_kv("native_permil=" as *u8, q_permil) 228 eld_nl() 229 230 // COVERAGE FIRST, ALWAYS. Every number below is a claim about a population, and this line is the 231 // only thing that says whether the population is whole. 232 eld_puts("ENGINELAB-COVERAGE " as *u8) 233 eld_kv("events=" as *u8, el_count(st)) 234 eld_kv("dropped=" as *u8, el_dropped(st)) 235 eld_kv("complete=" as *u8, el_complete(st)) 236 eld_kv("errors=" as *u8, el_errors(st)) 237 eld_nl() 238 239 let fs: *i64 = eld_scratch() 240 let closed: i64 = el_frame_stats(st, EL_STUTTER_NUM_DEFAULT, EL_STUTTER_DEN_DEFAULT, fs) 241 eld_puts("ENGINELAB-PACING " as *u8) 242 if closed < ELD_MIN_CLOSED_FRAMES { 243 // A PACING VERDICT ON FEWER THAN TWO CLOSED FRAMES IS THE EMPTY-SET PASS. Refuse it by name. 244 eld_kv("closed_frames=" as *u8, closed) 245 eld_puts("verdict=UNMEASURABLE reason=fewer-than-two-closed-frames-is-not-a-series\n" as *u8) 246 } else { 247 eld_kv("closed_frames=" as *u8, fs[EL_FS_FRAMES]) 248 eld_kv("open=" as *u8, fs[EL_FS_OPEN]) 249 eld_kv("span_us=" as *u8, fs[EL_FS_SPAN]) 250 eld_kv("avgfps_x1000=" as *u8, fs[EL_FS_AVGFPS]) 251 eld_kv("median_us=" as *u8, fs[EL_FS_MEDIAN]) 252 eld_kv("worst_us=" as *u8, fs[EL_FS_WORST]) 253 eld_kv("low1_x1000=" as *u8, fs[EL_FS_LOW1]) 254 eld_kv("low01_x1000=" as *u8, fs[EL_FS_LOW01]) 255 eld_kv("stutter=" as *u8, fs[EL_FS_STUTTER]) 256 eld_nl() 257 } 258 259 // THE JOIN, PER FRAME. One call per frame answers what five separate capture formats cannot: 260 // this frame cost N us, of which so much was CPU root time, so much GPU queue, so many draws, 261 // so many bytes -- on one clock, from one record layout. 262 let fa: *i64 = eld_scratch() 263 var k: i64 = 0 264 while k < frames { 265 if el_frame_attr(st, k, fa) == 1 { 266 eld_puts("ENGINELAB-JOIN " as *u8) 267 eld_kv("ord=" as *u8, k) 268 eld_kv("dur_us=" as *u8, fa[EL_FA_DUR]) 269 eld_kv("cpu_us=" as *u8, fa[EL_FA_CPUUS]) 270 eld_kv("gpu_us=" as *u8, fa[EL_FA_GPUUS]) 271 eld_kv("lock_us=" as *u8, fa[EL_FA_LOCKUS]) 272 eld_kv("draws=" as *u8, fa[EL_FA_DRAWS]) 273 eld_kv("alloc_bytes=" as *u8, fa[EL_FA_ALLOCB]) 274 eld_kv("events=" as *u8, fa[EL_FA_EVENTS]) 275 let fr: i64 = el_frame_rec(st, k) 276 if fr >= 0 { 277 eld_kv("q=" as *u8, el_get(st, fr, ELD_FRAME_A_Q)) 278 eld_kv("rays=" as *u8, el_get(st, fr, ELD_FRAME_B_RAYS)) 279 } 280 eld_puts("hot=" as *u8) 281 eld_name(fa[EL_FA_HOTNAME]) 282 eld_nl() 283 } 284 k = k + 1 285 } 286 287 eld_puts("ENGINELAB-ZONE name=init " as *u8) 288 let init_us: i64 = eld_zone_line(st, ELD_N_INIT) 289 eld_puts("ENGINELAB-ZONE name=tick " as *u8) 290 let tick_us: i64 = eld_zone_line(st, ELD_N_TICK) 291 eld_puts("ENGINELAB-ZONE name=render " as *u8) 292 let rend_us: i64 = eld_zone_line(st, ELD_N_RENDER) 293 let hot: *i64 = eld_scratch() 294 let hotname: i64 = el_zone_hottest(st, hot) 295 eld_puts("ENGINELAB-HOTTEST name=" as *u8) 296 eld_name(hotname) 297 eld_puts(" " as *u8) 298 eld_kv("self_us=" as *u8, hot[0]) 299 eld_nl() 300 301 // NS-PER-RAY IS THE FIGURE THAT SURVIVES A RESOLUTION CHANGE. A frame time alone cannot be 302 // compared across two quality levels; a per-unit-of-work cost can. 303 eld_puts("ENGINELAB-RAYS " as *u8) 304 eld_kv("rays_per_frame=" as *u8, rays) 305 eld_kv("render_self_us_total=" as *u8, rend_us) 306 if rays > 0 { 307 if frames > 0 { 308 eld_kv("ns_per_ray=" as *u8, rend_us * ELD_NS_PER_US / (rays * frames)) 309 } 310 } 311 eld_kv("sim_us_total=" as *u8, tick_us) 312 eld_kv("init_us=" as *u8, init_us) 313 eld_nl() 314 315 // THE BOUND VERDICT MUST ABSTAIN HERE AND THE REASON TRAVELS WITH IT. 316 let bv: *i64 = eld_scratch() 317 let bvr: i64 = el_bound_verdict(st, 0, EL_OCC_HI_DEFAULT, bv) 318 eld_puts("ENGINELAB-BOUND " as *u8) 319 if bvr == EL_BOUND_UNKNOWN { 320 eld_kv("code=" as *u8, bvr) 321 eld_puts("verdict=UNKNOWN reason=no-GPU-evidence-this-renderer-is-a-CPU-integer-raycaster-nothing-is-submitted-to-a-queue\n" as *u8) 322 } else { 323 eld_kv("code=" as *u8, bvr) 324 eld_kv("gpu_occ_permil=" as *u8, bv[EL_BV_GPUOCC]) 325 eld_kv("cpu_occ_permil=" as *u8, bv[EL_BV_CPUOCC]) 326 eld_nl() 327 } 328 329 let mm: *i64 = eld_scratch() 330 el_mem_stats(st, mm) 331 eld_puts("ENGINELAB-MEM " as *u8) 332 eld_kv("allocs=" as *u8, mm[EL_MEM_NALLOC]) 333 eld_kv("frees=" as *u8, mm[EL_MEM_NFREE]) 334 eld_kv("bytes_alloc=" as *u8, mm[EL_MEM_BALLOC]) 335 eld_kv("bytes_free=" as *u8, mm[EL_MEM_BFREE]) 336 eld_kv("orphan_frees=" as *u8, mm[EL_MEM_ORPHAN]) 337 eld_kv("live_bytes=" as *u8, mm[EL_MEM_BALLOC] - mm[EL_MEM_BFREE]) 338 eld_nl() 339 340 // THE NAMED ABSENCE. Reported every run, in the same block as the numbers, so a reader can never 341 // mistake draws=0 for a frame that issued no work. 342 eld_puts("ENGINELAB-UNMEASURABLE draws=0 redundant_binds=0 pipeline_state=0 capture_diff=UNMEASURABLE replay=UNMEASURABLE " as *u8) 343 eld_puts("reason=the-engine-emits-no-draw-stream " as *u8) 344 eld_puts("owed=one-el_draw-call-inside-the-mob_draw-vis-branch-and-one-per-voxel-pass-in-render_impl " as *u8) 345 eld_puts("owner=engine-lane-nx_wasm_craft\n" as *u8) 346 347 let ov: *u8 = sys_mmap(EL_OV_TEXT_MAX) 348 let ovn: i64 = el_overlay_emit(st, target_fps, q_permil, q_reason, rays, ov, EL_OV_TEXT_MAX) 349 if ovn > 0 { sys_write(1, ov, ovn) } 350 return closed 351} 352 353// ---- framebuffer -> image, for the golden verb --------------------------------------------------- 354// The renderer strips its depth plane after the mob composite, so the framebuffer holds packed 355// r | g<<8 | b<<16 and nothing else. Bound by the ENGINE extent (wc_rw x wc_rh), never by W x H: 356// a consumer that assumes the full grid reads unwritten memory and calls it a measurement. 357func eld_img(base: i64) -> *VdImg { 358 let rw: i64 = wc_rw(base) 359 let rh: i64 = wc_rh(base) 360 let f: *i64 = wfb(base) 361 let n: i64 = rw * rh 362 let im: *VdImg = sys_mmap(VD_IMG_BYTES) as *VdImg 363 let px: *u8 = sys_mmap(n * ELD_RGB_CH) 364 var i: i64 = 0 365 while i < n { 366 let c: i64 = f[i] 367 px[i*ELD_RGB_CH] = (c & ELD_BYTE_MASK) as u8 368 px[i*ELD_RGB_CH + 1] = ((c >> ELD_G_SHIFT) & ELD_BYTE_MASK) as u8 369 px[i*ELD_RGB_CH + 2] = ((c >> ELD_B_SHIFT) & ELD_BYTE_MASK) as u8 370 i = i + 1 371 } 372 im.px = px 373 im.w = rw 374 im.h = rh 375 im.nc = ELD_RGB_CH 376 return im 377} 378 379func eld_usage() -> i64 { 380 eld_puts("usage: nx_enginelab frame [v] [seed] [frames] [q] [target_fps]\n" as *u8) 381 eld_puts(" nx_enginelab capture <out> [v] [seed] [frames] [q] -- persist, reopen, prove identical\n" as *u8) 382 eld_puts(" nx_enginelab golden [v] [seed] [frames] [q] [grid] [thresh] -- two runs, per-cell parity\n" as *u8) 383 eld_puts("q=0 leaves the engine adaptive controller in charge and RECORDS what it chose; q>=1 pins it.\n" as *u8) 384 return ELD_EXIT_USAGE 385} 386 387func main(argc: i64, argv: *i64) -> i64 { 388 if argc < ELD_ARGV_VERB + 1 { sys_exit(eld_usage()) } 389 let verb: *u8 = argv[ELD_ARGV_VERB] as *u8 390 var ao: i64 = ELD_ARGV_VERB 391 var outp: *u8 = 0 as *u8 392 var mode_frame: i64 = 0 393 var mode_cap: i64 = 0 394 var mode_gold: i64 = 0 395 if eld_streq(verb, "frame" as *u8) == 1 { mode_frame = 1 } 396 if eld_streq(verb, "capture" as *u8) == 1 { mode_cap = 1 } 397 if eld_streq(verb, "golden" as *u8) == 1 { mode_gold = 1 } 398 if mode_frame + mode_cap + mode_gold == 0 { sys_exit(eld_usage()) } 399 if mode_cap == 1 { 400 if argc < ao + 2 { sys_exit(eld_usage()) } 401 outp = argv[ao + 1] as *u8 402 ao = ao + 1 403 } 404 var v: i64 = 0 405 if argc > ao + 1 { v = eld_int(argv[ao + 1] as *u8) } 406 var seed: i64 = ELD_SEED_DEFAULT 407 if argc > ao + 2 { seed = eld_int(argv[ao + 2] as *u8) } 408 var frames: i64 = ELD_FRAMES_DEFAULT 409 if argc > ao + 3 { frames = eld_int(argv[ao + 3] as *u8) } 410 var q: i64 = ELD_Q_DEFAULT 411 if argc > ao + 4 { q = eld_int(argv[ao + 4] as *u8) } 412 var target_fps: i64 = ELD_TARGET_FPS_DEFAULT 413 var grid: i64 = ELD_GRID_DEFAULT 414 var thresh: i64 = ELD_THRESH_DEFAULT 415 if mode_frame == 1 { if argc > ao + 5 { target_fps = eld_int(argv[ao + 5] as *u8) } } 416 if mode_gold == 1 { 417 if argc > ao + 5 { grid = eld_int(argv[ao + 5] as *u8) } 418 if argc > ao + 6 { thresh = eld_int(argv[ao + 6] as *u8) } 419 } 420 421 // NEG-CONTROL BY CONSTRUCTION: a run with no frames has no subject, and the driver refuses rather 422 // than reporting a healthy-looking zero. 423 if frames < 1 { 424 eld_puts("ENGINELAB-REFUSED verdict=UNMEASURABLE frames=0 reason=a-run-with-no-frames-has-no-subject\n" as *u8) 425 sys_exit(ELD_EXIT_UNMEASURABLE) 426 } 427 428 let st: *i64 = el_new(eld_store_cap(frames)) 429 if el_ok(st) == 0 { 430 eld_puts("ENGINELAB-REFUSED verdict=UNMEASURABLE reason=store-allocation-failed\n" as *u8) 431 sys_exit(ELD_EXIT_UNMEASURABLE) 432 } 433 let base: i64 = eld_run(st, v, seed, q, frames) 434 if base == 0 { 435 eld_puts("ENGINELAB-REFUSED verdict=UNMEASURABLE reason=engine-arena-allocation-failed\n" as *u8) 436 sys_exit(ELD_EXIT_UNMEASURABLE) 437 } 438 let closed: i64 = eld_report(st, base, v, seed, q, frames, target_fps) 439 440 if mode_cap == 1 { 441 // EL1 ON REAL DATA. Write the capture, reopen it, and compare EVERY field of EVERY record 442 // plus the header counters. A round-trip that only checked the count would pass a capture 443 // whose payload was scrambled. 444 let wr: i64 = el_capture_write(st, outp) 445 eld_puts("ENGINELAB-CAPTURE " as *u8) 446 eld_kv("write_rc=" as *u8, wr) 447 if wr != ELS_OK { 448 eld_puts("verdict=WRITE-REFUSED\n" as *u8) 449 sys_exit(ELD_EXIT_FAIL) 450 } 451 let rs: *i64 = eld_scratch() 452 let rd: *i64 = el_capture_read(outp, rs) 453 if (rd as i64) == 0 { 454 eld_kv("read_reason=" as *u8, rs[ELS_R_CODE]) 455 eld_kv("declared=" as *u8, rs[ELS_R_DECLARED]) 456 eld_kv("actual=" as *u8, rs[ELS_R_ACTUAL]) 457 eld_puts("verdict=READ-REFUSED\n" as *u8) 458 sys_exit(ELD_EXIT_FAIL) 459 } 460 var same: i64 = 1 461 if el_count(rd) != el_count(st) { same = 0 } 462 if el_dropped(rd) != el_dropped(st) { same = 0 } 463 if el_complete(rd) != el_complete(st) { same = 0 } 464 var ci: i64 = 0 465 while ci < el_count(st) { 466 var cf: i64 = 0 467 while cf < EL_REC { 468 if el_get(rd, ci, cf) != el_get(st, ci, cf) { same = 0 } 469 cf = cf + 1 470 } 471 ci = ci + 1 472 } 473 // AND THE DERIVED FIGURES TOO: identical records that produced a different median would mean 474 // the analysis depends on something the capture does not carry. 475 let ka: *i64 = eld_scratch() 476 let kb: *i64 = eld_scratch() 477 el_frame_stats(st, EL_STUTTER_NUM_DEFAULT, EL_STUTTER_DEN_DEFAULT, ka) 478 el_frame_stats(rd, EL_STUTTER_NUM_DEFAULT, EL_STUTTER_DEN_DEFAULT, kb) 479 var derived_same: i64 = 1 480 var sx: i64 = 0 481 while sx < EL_FS_SLOTS { 482 if ka[sx] != kb[sx] { derived_same = 0 } 483 sx = sx + 1 484 } 485 eld_kv("records=" as *u8, el_count(st)) 486 eld_kv("records_identical=" as *u8, same) 487 eld_kv("derived_identical=" as *u8, derived_same) 488 if same == 1 { if derived_same == 1 { eld_puts("verdict=ROUNDTRIP-IDENTICAL\n" as *u8) } } 489 if same == 0 { 490 eld_puts("verdict=ROUNDTRIP-DIVERGENT\n" as *u8) 491 sys_exit(ELD_EXIT_FAIL) 492 } 493 if derived_same == 0 { 494 eld_puts("verdict=DERIVED-DIVERGENT\n" as *u8) 495 sys_exit(ELD_EXIT_FAIL) 496 } 497 } 498 499 if mode_gold == 1 { 500 // DETERMINISM OF THE REAL RENDERER, PER CELL. Two INDEPENDENT runs in two separate arenas, 501 // same v and seed: the estate character bench lists bit-determinism as a HAVE axis, and this 502 // is the first time it has been measured on the real render path with a per-cell ruler 503 // rather than asserted. A whole-image compare would say only same or different; a grid says 504 // WHERE, which is the only form a regression report can act on. 505 let ia: *VdImg = eld_img(base) 506 let st2: *i64 = el_new(eld_store_cap(frames)) 507 let base2: i64 = eld_run(st2, v, seed, q, frames) 508 if base2 == 0 { 509 eld_puts("ENGINELAB-GOLDEN verdict=UNMEASURABLE reason=second-arena-allocation-failed\n" as *u8) 510 sys_exit(ELD_EXIT_UNMEASURABLE) 511 } 512 let ib: *VdImg = eld_img(base2) 513 let g: *i64 = eld_scratch() 514 let gr: i64 = el_golden(ia, 0, ib, 0, ia.w, ia.h, grid, grid, thresh, 515 EL_GOLD_PASS_PERMIL_DEFAULT, g) 516 eld_puts("ENGINELAB-GOLDEN " as *u8) 517 eld_kv("w=" as *u8, ia.w) 518 eld_kv("h=" as *u8, ia.h) 519 eld_kv("grid=" as *u8, grid) 520 eld_kv("thresh=" as *u8, thresh) 521 eld_kv("cells_total=" as *u8, g[EL_GD_TOTAL]) 522 eld_kv("cells_matched=" as *u8, g[EL_GD_MATCH]) 523 eld_kv("permil=" as *u8, g[EL_GD_PERMIL]) 524 if gr == EL_GOLD_PASS { eld_puts("verdict=PASS subject=engine-determinism-same-seed-two-arenas\n" as *u8) } 525 if gr == EL_GOLD_FAIL { eld_puts("verdict=FAIL subject=engine-determinism-same-seed-two-arenas\n" as *u8) } 526 if gr == EL_GOLD_UNMEASURABLE { eld_puts("verdict=UNMEASURABLE reason=no-comparable-window\n" as *u8) } 527 if gr == EL_GOLD_FAIL { sys_exit(ELD_EXIT_FAIL) } 528 if gr == EL_GOLD_UNMEASURABLE { sys_exit(ELD_EXIT_UNMEASURABLE) } 529 } 530 531 if closed < ELD_MIN_CLOSED_FRAMES { sys_exit(ELD_EXIT_UNMEASURABLE) } 532 sys_exit(ELD_EXIT_OK) 533 return ELD_EXIT_OK 534}