Skip to content

Aether 0.841.0, aephysics ce2ea25 and aether-ui ac75c750 (builds on feat/aether-0839) - #864

Merged
paul-hammant merged 10 commits into
mainfrom
feat/aether-0841
Oct 23, 2026
Merged

paul-hammant merged 10 commits into
mainfrom
feat/aether-0841

Conversation

@paul-hammant

Copy link
Copy Markdown
Collaborator

This moves ae3d from Aether 0.834.0 to 0.841.0 and aephysics from f0bd6d6 to ce2ea25. It also moves aether-ui to ac75c750. It undoes the hold in c521cef ("Back to Aether 0.834.0 and aephysics f0bd6d6 until Aether guards AVX at -O0 on Win64"). The Win64 -O0 AVX fix (aether#3023) has been released since 0.836.0.

It builds on Nic's feat/aether-0839 (91029ac) and supersedes it once he agrees. That commit carries the ownership rules of 0.836–0.839:

  • @into accessors;
  • @keep fn slots for set_skybox/set_overlay and the net makers;
  • os.args_*;
  • kept struct parameters.

I didn't push to or rewrite his branch. This branch is his commit plus four:

  1. Aether 0.841.0 and aephysics ce2ea25.
    • 0.840 treats a borrowed ptr put in a list or map as kept (aether#3079/#3086). So these declare @keep: skin.skeleton_add_mesh's mesh, the texture worker's done closure, and the three net maker parameters (@keep fn(...)).
    • Audio's start phase is a C function pointer, so it can't keep its argument. It now lists the state as the object's component holds it (held_state).
    • 0.841 is 0.840 plus aether#3123. Without it, net's if maker == null is a clang -Wparentheses-equality in 17 programs. No workaround is needed on 0.841.
    • aephysics ce2ea25 is its main. It contains my test-only fix to test_parallel. The check "more than one worker took blocks" failed about 4 runs in 10 on an idle M6, on 0.840 and 0.841 alike, because one pool thread could take every block before the calling thread took one.
    • ci.yml has the version entries. ae3d pins no aeb.
  2. vkspirv: only SEA_QUOTED_HASH and LIT_QUOTED_HASH change. 0.839+ gives a vec2/vec3 local read in a branch condition its written type instead of f32x4. The trees differ in exactly those ten type tags. GLSL, SPIR-V and MSL are byte-identical.
  3. editor: aether-ui ac75c750 (aether-ui#221: every kept fn/ptr parameter declares @keep, so ui compiles on 0.838+). The inspector's slots are typed fn(ptr, @keep ptr, ...).
  4. clusterlod: merge_groups takes an empty input as partition does. On 0.840+, gcc -O2 on x86_64 clones it and threads a negative n into calloc (-Walloc-size-larger-than, 28 hits on the lane).

There are no E0305 hits in ae3d, and no E0202 (formerly W1005).

Verification, on 0.841.0 unless noted

  • generate_shaders --check passes with glslang 16.6.0 (95 files, 53 shaders). msl_check: 41 files clean.
  • frames_against.sh origin/main: 59 frames, 0 differ.
  • Parity at 1x and 4x, Vulkan and GL: byte-identical except clouds_over_the_skybox (test_backend_parity: 'clouds over the skybox' is not the same frame twice on the same commit #793, at most 198 channels, worst 1).
  • Khronos validation with sync, nothing excluded: 0 errors, 0 warnings. Runs: parity, zombie_city and street_drive at 1x and 4x, plus test_water_sky and test_crowd_render.
  • The full local ./ci.sh on the M6, under the test lock: everything passed (8 hardware skips).
  • aether-linux-x64 lanes: lane_some 108 builds, 0 failed, 0 warnings. lane_all gcc and clang: 266 built, 0 failed, 0 warnings each. The Linux editor build against aether-ui ac75c750 (GTK4 backend, -O2 -Wall -Wextra) has 0 warnings.
  • win11 (MSYS2 UCRT64, GCC 16.1.0), the Windows job's tier, AE3D_CI_TIER=platform AE3D_CI_GPU=0 ./ci.sh with the suites at -O0: everything passed, and no ICE in any build log. 14 programs there link aephysics, and 12 carry its @target("avx2") copies.
    • Negative control: building test_determinism with -O0 -D__OPTIMIZE__ switches #3023's guard off. That brings back the exact ICE: internal compiler error: in expand_one_stack_var_1, at cfgexpand.cc:1747, at aephysics/sat/module.ae:130.
  • All 266 programs compile at -O0 on macOS with no error or warning.
  • aephysics scripts/test.sh and the golden trace pass (1250 steps, bit for bit).

Not merged.

🤖 Generated with Claude Code

nicolas-maman and others added 10 commits October 21, 2026 23:54
…f 0.836 to 0.839

Not ready to merge: the editor does not build yet (see the deps issue).

Done here, and every program but the editor compiles on 0.839 with it:
- 0.836 (E0902, aether#2990): a pointer returned from a borrowed
  parameter is declared @into (blob.slice, vkdesc.cluster_at); fn slots
  whose function keeps its argument say @keep (the renderers' set_skybox
  and set_overlay, the net maker slots); os.args_count/args_get; dead
  returns.
- 0.837: a closure compared with null (aether#3062).
- 0.839: kept struct parameters declare @keep (engine.bind_backend's
  backend; the VKImage that vkddgi.keep_image, vktargets.kept and
  vktexture.adopt_target take over).
- ci.yml AETHER_REF v0.839.0 with the version log; aephysics 9490d2b
  (its own 0.839 move, same bits).

Left:
- editor/lib/inspector's slots typed fn(ptr, @keep ptr, string, string,
  string) and fn(ptr, @keep ptr, string, string, bool), for
  component_edited and component_structure (0.838's @keep fn rule);
- aether-ui#221: ui.background, background_for and background_detached
  keep fn parameters without @keep, so the editor's pinned aether-ui
  (c55a375a) fails on 0.839; AETHER_UI_REF moves once it is fixed.
…2ea25

This builds on Nic's feat/aether-0839 (91029ac), which moves to 0.839.0
with the ownership rules of 0.836 to 0.839. This commit takes it to
0.841.0. That release still carries the Win64 -O0 AVX fix the move was
held for (aether#3023, 0.836.0).

0.840.0 declares std's list and map stores @retain (aether#3079, #3086),
so a borrowed ptr put in one is E0902:
- skin.skeleton_add_mesh keeps its mesh, so it is @keep.
- The texture worker's done closure keeps its image
  (`|image: @keep ptr|`; worker.run's done is fn(@keep ptr)).
- The net makers are stored, so set_player_maker,
  set_player_object_maker and object_kind take `@keep fn(...)`.
- Audio's start phase is a C function pointer, whose argument only
  borrows: component phases and scripts' phases come from a library. So
  it lists the state as the object's component holds it (held_state),
  rather than the argument.

0.841.0 adds aether#3123. 0.840.0 wrote net.make_player's
`if maker == null` as `if (((maker).fn == 0))`, which is clang's
-Wparentheses-equality in 17 programs. 0.841.0 writes it with one pair
of parentheses, so the net module stays as it was.

aephysics moves from 9490d2b to ce2ea25, its main. That is a test-only
fix of mine: test_parallel's pool check failed about four runs in ten
on an idle M6, because one pool thread could take every block before the
calling thread took one. ae3d pins no aeb. There is no
E0305 and no E0202 (was W1005) anywhere in ae3d. All 266 programs ci.sh
builds compile on 0.841.0 at -O0 (the suites' flags) without an error
or a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…them

Two quoted pixel shaders' tree hashes move on Aether 0.840.0. sea_quoted
and lit_quoted read a vec2 or vec3 local's lane inside a branch condition
(ruv.x, uv.y, projected.z). 0.834 typed those LOCAL nodes f32x4, the
lane type, and 0.840 types them with the type they were written with:
0.839's "a written type is the type of a local bound in several
branches". The trees from 0.834 and 0.840 differ in those ten type tags
and nothing else, so the GLSL, the SPIR-V (53 shaders, 892276 B) and the
MSL are byte-identical. Only SEA_QUOTED_HASH and LIT_QUOTED_HASH are
regenerated. Without this, vkquote.fresh stops the renderer at those
shaders. generate_shaders --check passes on 0.840.0 with glslang 16.6.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aether-ui c55a375a does not compile on Aether 0.838+ (aether-ui#221:
ui.background and the setters that keep their callbacks lacked @keep);
ac75c750 declares them, and its ci.sh passes on macOS and Linux on
0.840.0. The inspector's on_change and on_structure slots hold
component_edited and component_structure, which keep the object they
are told of, so the slots are typed fn(ptr, @keep ptr, ...) and
inspector_new takes them as `@keep fn` (0.838's rule for a kept closure
parameter). The editor builds on 0.840.0 with no warnings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Aether 0.840.0, gcc -O2 on x86_64 warned in street_drive:
`byg = calloc(n, 4)`, argument 1 range [-2^31, -1] exceeds the maximum
object size (-Walloc-size-larger-than), in
clusterlod_merge_groups.constprop.isra. merge_groups had no guard on
`n`; its only caller, partition, returns before it when n <= 0. 0.840
writes a second, view body of partition, and the different inlining that
follows let GCC thread a negative n into the calloc. merge_groups now
answers an empty input (no clusters or no groups) as partition does,
starts[0] = 0 and no groups, so every calloc it makes is of a positive
count. No caller reaches the new branch, so no frame or count moves.
Verified: street_drive builds with gcc -O2 on the aether-linux-x64 lane
with no warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the 900 s backstop killed drive_editor, its output, block-buffered
into a file, was lost. The runner's log of the run had only the editor's
"listening" and no check, so a drive that stopped halfway read the same
as one that never started. It now runs under stdbuf -oL where coreutils
has it, and a failure prints the last eight lines it reached, without
the editor's ALSA and toolkit chatter. On the aether-linux lane the same
drive, line-buffered, showed each check as it passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When `timeout 900` ends drive_editor, its editor is left running, and
nothing showed why it stopped answering. Where gdb is (the Linux
runners install it), the step now attaches to that editor and prints
every thread's stack before stopping it. It attaches through `sudo -n`
where that asks for no password, since Yama refuses to attach to a
process that is not gdb's child. On the aether-linux lane the same probe
shows the main thread in draw_frame, then vkreadback_read, then
vkWaitForFences, on a submitted frame's fence that lavapipe never
signals, with every lavapipe thread idle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a frame; a frame's fence is waited on for 30 s at most

The linux-editor job stopped at Add Terrain. The editor was not hung: a frame
is 250 ms there and ac75c750's driver ran the main loop 32 rounds, a frame each,
before every request, so each request took eight seconds and the drive's 3 s
timeout fired on all of them. 51d1ae75 stops that settling after 30 ms.

frame_wait and the frame-begin wait had no timeout, which is what made the
stall read as a hang; they now give up after 30 s with the frame, the fence
and the slots' begun and submitted counts in the device error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cks passed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@paul-hammant
paul-hammant merged commit b39f534 into main Oct 23, 2026
18 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants