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}