mirror of
https://github.com/HeyPuter/gex.git
synced 2026-11-13 20:12:43 -10:00
Merge merge/unity (Mesa pin 60202246, gllimits=41 default, docs) into merge/unity-seed
One U head for the re-key round:64efd78e(fjit holes, fjit.rs out of the unit key),1bf5ba09(seeded starts) and merge/unitya0f6a8c9(4ed5cad3's page fixes, the Mesa pin1d5b26d9, docs). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_1896c5b302a54696aaa92c5f4047f20b
This commit is contained in:
commit
0ddc93909d
7 files changed
+116
-40
No files matched your search
+9
-9
@@ -51,21 +51,21 @@ push** (rebased onto upstream wink 0dd84167; nothing pushed):
|
||||
- replay it with `replay-run.mjs gpu TRACE --query readback=1`;
|
||||
- bisect the shader variants with `shaders.mjs`;
|
||||
- then re-apply e204fa1b's two web files.
|
||||
2. *Grass is still dots* at GL 4.0 after the -0.0 fix (U mp27; the sea is
|
||||
back). Next: the geometry-shader emulation's output for the grass program
|
||||
(its source is in the Muck trace; `shaders.mjs`). It may resolve with
|
||||
item 1 at GL 4.1+, where Unity's 410 source compiles natively.
|
||||
2. *Grass:* fixed at GL 4.2 by GL 4.1's texture limits with mesa-wink
|
||||
60202246 (U mpg3: blades, 36.6-38.1 presents/s). gex's pin is 60202246
|
||||
and `?gllimits=41` is the default since U's pin commit on merge/unity
|
||||
(`?gllimits=0` turns it off; 43 stays per run, item 1).
|
||||
3. *Noita's world fps* is bound by its job hand-off, not by GL: the main
|
||||
thread is parked about 37% waiting on job threads, and KLock is 0.14%
|
||||
(stream F's area). The page's GL submit is no longer the limit
|
||||
(CLIENT_ARRAY: 55.5 vs 51.1 world fps on the old path, pewasm 47.2).
|
||||
4. Remaining E1: GL draw/pointer calls are on the fast path, but the page
|
||||
gain is below noise.
|
||||
5. *The 4-slot bind-group repro on the rebased tree* (`$G/urep5.sh`, mods
|
||||
tinyu) timed out at 1200 s with no output. Rerun it the way trep2.sh ran
|
||||
the earlier ones (full trace, `--query stream=1`, timeout 1500, no
|
||||
maxframes) before moving gex's pin; expect 0 validation errors from
|
||||
frame 1343 on.
|
||||
5. *The 4-slot bind-group repro on the rebased tree:* done (U,
|
||||
2026-10-09, `scratch/unity/urep-pin.sh` on edger, run like trep2.sh:
|
||||
full trace, `--query stream=1`, timeout 1500): mods/tinyu replays all
|
||||
2,777 frames (3,403 batches) of Noita's trace with 0 validation errors
|
||||
(5f5572e6 and +6d3a4cfd had 2,668 and 2,720 from frame 1343).
|
||||
|
||||
Tooling (unchanged):
|
||||
|
||||
|
||||
+67
-14
@@ -2086,6 +2086,8 @@ Not yet:
|
||||
| hp12 | full fjit + unit | 58e95157 (epochs only where translated) | 128 s | 158 s | 42.4-42.7 |
|
||||
| **hp13** | **full fjit + unit** | **977a2236 (current JIT callees out of batches too)** | **87 s** | **119 s** | **39.6-39.9** |
|
||||
| hb51 | full fjit, no unit | 58e95157 | 222 s | 270 s | 33.9 at 392 s, rising (x11 backend; was black) |
|
||||
| hb52 | full fjit, no unit | merge/unity-rekey d146c248 | - | - | SIGILL at start-up (status 132) |
|
||||
| hb53 | full fjit, no unit | merge/unity-rekey 64efd78e | 178 s | 225 s | 35.7 at 392 s (x11 backend) |
|
||||
|
||||
Native gexc's gate (unit, no fjit): menu at 406.5 s, 30.59
|
||||
presents/s. hp13 against hp7: 52% more presents/s (39.9 vs 26.3),
|
||||
@@ -2095,17 +2097,68 @@ Not yet:
|
||||
the menu rate ranges 39.7-42.7 across these runs. By the menu hp13's
|
||||
JIT has made libasound 20 MiB of wasm (947 functions), libc 4.3 MiB,
|
||||
libudev 3.2 MiB, libcrypto 2.9 MiB; UnityPlayer is out of the top 12.
|
||||
- **Resume (2026-10-09, HEAD after 977a2236; merge/unity has master 41917e73):**
|
||||
HK in the page runs the target configuration (full fjit + the pinned
|
||||
unit, `hk-bisu.sh NAME byobj=1`) to the menu: hp13 above. Fixed today: the
|
||||
black screen and the libxcb crash (stale learned starts across dlclose,
|
||||
763a1538), unit and current JIT callees kept out of batches (5ec43e82,
|
||||
977a2236), mid-function misses to the fallback (a12da54a, 6bc61569).
|
||||
Open: start-up is still ~87 s to the first frame (hp7 without fjit 55 s):
|
||||
profile the main Worker again (ht2's method) to see what the JIT costs
|
||||
now; libasound's 20 MiB of wasm; the native JIT has the same two holes
|
||||
(learned state kept across dlclose, mid-function roots as starts),
|
||||
which want a gex-xlate fix (a re-key: fjit.rs is in
|
||||
GEX_CGEN_RECOVERY_INPUTS although it is runtime-only; build.rs could
|
||||
leave it out, once). Muck's grass needs the mods/gpu Mesa and
|
||||
`?gllimits=41` (not default; GL to decide).
|
||||
- **merge/unity-rekey (64efd78e, one commit on 4ed5cad3, for its own
|
||||
round):** the native JIT's two holes fixed in gex-xlate
|
||||
(`Jit::retire(process, ranges)` from both hosts' on_retire; a miss's
|
||||
root stays a start only if it was a strong one already) and fjit.rs out
|
||||
of GEX_CGEN_RECOVERY_INPUTS (key c6014ffc... with and without an
|
||||
fjit.rs edit, 855acf6a... after a func.rs edit). hb52 (d146c248) died
|
||||
with SIGILL: with misses no longer starts, recovery walked over a JIT
|
||||
entry inside the function, and the page's "served" test was part of
|
||||
`executable`, which fetch asks of every byte, so the bytes decoded as
|
||||
illegal. 64efd78e passes it as `skip` (`Jit::translate_skipping`), the
|
||||
batch bound only. hb53: menu, x11, first frame 178 s, 35.7 presents/s
|
||||
(hb51 on the epoch shim: 222 s, 33.9). Native: tests/fjit-remap (the
|
||||
Oct 8 gexc gets 99,800 of 200,000 wrong under --fjit), fjit-procs,
|
||||
x86-programs (82 ok), embed PASS, gex-xlate tests. The page's unit cache
|
||||
(scratch/unity/units/cgen-page) must be rebuilt after it lands.
|
||||
- **Mesa pin (1d5b26d9): mesa-wink 60202246 and `gllimits=41` by
|
||||
default.** Replays gpu vs this build: Noita 92f095c5, HK 9eece5c5, 0
|
||||
rejects and 0 validation errors each; GL's 4-slot repro (tinyu) 2,777
|
||||
frames with 0 validation errors; browser-gui --gl x86 and x64 12 ok
|
||||
each; HK hp14 (merge/unity shim, this Mesa) menu at 41.8 presents/s.
|
||||
Muck with the default and no `?gllimits` (mk2, the seed shim, no unit):
|
||||
"OpenGL 4.2" context, no "Shader Unsupported", grass blades in
|
||||
`shots/mk2/c013.png`, 36.9 presents/s at 393 s.
|
||||
- **Muck dies with SIGILL at ~25 s on merge/unity's shim (977a2236,
|
||||
4ed5cad3)**, with the unit (mpg5, mk1) and without (mk4). It does not
|
||||
with 64efd78e (mk3, 4 minutes, no unit) or 1bf5ba09 (mk2). The page asked
|
||||
"served by the unit or the JIT" of instruction fetch (part of
|
||||
`executable`); with epochs a JIT entry the current epoch has no start
|
||||
for is read as non-code inside the function being recovered and decoded
|
||||
as illegal. 64efd78e passes it as `skip` (batch bound only).
|
||||
- **Start-up (decision 3).** hp14's main-Worker profile, 10-90 s (unit +
|
||||
fjit): 61% (49.8 of 81 s) in `fjit::translate`: recover_one 27.2 s
|
||||
(jump tables 16.9, discover 9.2, lift 6.9), summaries 17.7, build_runtime
|
||||
8.8, emit 8.4, prepare 5.5; the per-byte `executable` 5.9 (2.3 in
|
||||
elfprov::provided's locks). Audio: the page has no audio device; FMOD's
|
||||
output init fails ("Unknown PCM default", tried twice), after pulse
|
||||
fails to connect. libasound's 20 MiB was mostly copies: the page's JIT
|
||||
had no function starts but those calls name, so a tail jump absorbed the
|
||||
function it reached, and libasound's exported wrappers each carried one.
|
||||
Offline (fjitrepro, all 1,698 exports): 57.2 MiB / 16.4 s unseeded, 9.7
|
||||
MiB / 7.1 s seeded. ALSA with no config (hp15, ALSA_CONFIG_PATH=/dev/null)
|
||||
cut libasound to 11.2 MiB but not the first frame (112 s against hp14's
|
||||
110 s, both profiled), so it is not the path to cut.
|
||||
merge/unity-seed 1bf5ba09 (on 64efd78e) seeds every mapped object's
|
||||
starts (`Jit::add_image`) before a translation and takes the fetch
|
||||
checks once per translation: no unit, hb53 (64efd78e) 178 s first
|
||||
frame, 225 s 100 presents, 35.7 presents/s; hb54 (seeding) 121 s, 171 s,
|
||||
39.1; hb55 (both) 121 s, 166 s, 40.1; libasound 26.0 -> 3.7 MiB.
|
||||
The HK unit re-keyed for 64efd78e (key 7bd87731, byte-identical c.wasm,
|
||||
1,941 s on gooner) is on edger in `units/cgen-page-rk`; Muck's is
|
||||
rebuilt too (4e58f35b, 884 s), also in `cgen-page-rk`.
|
||||
With the unit (target configuration, seed shim 1bf5ba09):
|
||||
- hp16 (HK): first frame 56 s (hp13 87 s), 100 presents 85 s (119 s),
|
||||
41.5 presents/s at 392 s (39.9).
|
||||
- hp17 (HK, profiled 10-90 s): `fjit::translate` 20.7 s of 81 s (25.5%;
|
||||
hp14 49.8 s, 61.5%); the main Worker now waits on its threads 31.6 s.
|
||||
Profiled runs' first frame (110 s both) is held by the profile.
|
||||
- mk5 (Muck): first frame 82 s, 100 presents 95 s, 34.0 presents/s at
|
||||
392 s, OpenGL 4.2, no "Shader Unsupported", grass blades
|
||||
(`shots/mk5/c013.png`).
|
||||
Branches: merge/unity-rekey 64efd78e (own round), merge/unity-seed
|
||||
1bf5ba09 on it (worktree wt/unity-rk); merge/unity 1d5b26d9 (pin).
|
||||
Natively the JIT seeds only the main image too (gexc's
|
||||
FjitTranslator::image); a Translator hook per mapped object would do
|
||||
the same there.
|
||||
Vendored
+1
-1
Submodule third_party/mesa updated: 5f5572e62f...6020224605.
+20
-1
@@ -20,7 +20,26 @@ else
|
||||
fi
|
||||
OUT=${1:-$DEFAULT_OUT}
|
||||
BUILD=$OUT/build
|
||||
EMDAWN=${GEX_EMDAWN_DIR:-$($ROOT/web/fetch-emdawnwebgpu.sh)}
|
||||
# emdawnwebgpu: a Mesa checkout that pins its own (the wink branch:
|
||||
# wink/lib/emdawn.sh, a release matched to its Tint and patched by
|
||||
# wink/tools/patch-emdawnwebgpu.py) supplies it; else gex's own fetch.
|
||||
if [ -z "${GEX_EMDAWN_DIR:-}" ] && [ -f "$MESA/wink/lib/emdawn.sh" ]; then
|
||||
WINK_CACHE=${GEX_MESA_WINK_CACHE:-${TMPDIR:-/tmp}/gex-mesa-wink-cache}
|
||||
EMSDK_ROOT=$(CDPATH='' cd -- "$(dirname "$(command -v emcc)")/../.." && pwd)
|
||||
emdawn_log=$(WINK_ALLOW_ANY_EMSDK=1 bash "$MESA/wink/build.sh" --variant=mt --until=emdawn \
|
||||
--cache="$WINK_CACHE" --build-dir="$WINK_CACHE/build" --emsdk="$EMSDK_ROOT" 2>&1) || {
|
||||
echo "$emdawn_log" | tail -20 >&2
|
||||
exit 1
|
||||
}
|
||||
EMDAWN=$(echo "$emdawn_log" | sed -n 's/^\[emdawn\] \(ready\|cached\) at //p' | tail -1)
|
||||
[ -f "$EMDAWN/webgpu/include/webgpu/webgpu.h" ] || {
|
||||
echo "$emdawn_log" | tail -20 >&2
|
||||
echo "no emdawnwebgpu from wink/build.sh" >&2
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
EMDAWN=${GEX_EMDAWN_DIR:-$($ROOT/web/fetch-emdawnwebgpu.sh)}
|
||||
fi
|
||||
TINT_OUT=${GEX_MESA_TINT:-${TMPDIR:-/tmp}/gex-mesa-wasm/mesa-tint-pthread}
|
||||
TINT_TMP=${GEX_MESA_TINT_TMP:-${TMPDIR:-/tmp}/gex-mesa-tint-build}
|
||||
|
||||
|
||||
@@ -1440,7 +1440,7 @@ self.onmessage = ({ data: m }) => {
|
||||
canvas = m.canvas;
|
||||
presentOverride = m.present ?? null;
|
||||
// The compositor draws with WebGPU on the device Mesa will use.
|
||||
if (m.glLimits) globalThis.GEX_GL_LIMITS = m.glLimits;
|
||||
if (m.glLimits != null) globalThis.GEX_GL_LIMITS = m.glLimits;
|
||||
requestGexDevice().then((gpu) => {
|
||||
comp = new Compositor(m.canvas, m.channel, m.stats ? new Int32Array(m.stats) : null, gpu);
|
||||
comp.setDirect(m.direct);
|
||||
|
||||
@@ -137,10 +137,11 @@ export class Compositor {
|
||||
// is the canvas, fitted to the viewport; compositing only when needed.
|
||||
const direct = pq?.get('direct') === '1';
|
||||
this.#pointerLock = pq?.get('pointerlock') === '1';
|
||||
// `?gllimits=41|43`: the device asks for GL 4.1's texture limits (and
|
||||
// 4.3's compute ones), raising the GL version Mesa's context earns
|
||||
// (gpu-device.js). Off by default: at 4.6 Muck's 3D scene drew black.
|
||||
const glLimits = Number(pq?.get('gllimits')) || 0;
|
||||
// `?gllimits=40|41|43`: the device asks for WebGPU's default limits,
|
||||
// GL 4.1's texture limits (the default), or 4.3's compute ones too,
|
||||
// which decide the GL version Mesa's context earns (gpu-device.js). At
|
||||
// 4.6 Muck's 3D scene drew black, so 43 is only per run.
|
||||
const glLimits = pq?.has('gllimits') ? Number(pq.get('gllimits')) || 0 : null;
|
||||
worker.postMessage(
|
||||
{ kind: 'init', canvas: offscreen, channel, stats: this.#stats, present, direct, glLimits },
|
||||
[offscreen],
|
||||
|
||||
+13
-10
@@ -44,17 +44,20 @@ export function requestGexDevice() {
|
||||
maxStorageBuffersInVertexStage: 16,
|
||||
maxStorageBuffersInFragmentStage: 16,
|
||||
maxColorAttachmentBytesPerSample: 64,
|
||||
// Not by default yet: GL 4.1's texture limits and GL 4.3's compute
|
||||
// ones (all of them make the context GL 4.6) drew Muck's 3D scene
|
||||
// black (U, mp26); `?gllimits=` below asks for them per run.
|
||||
// GL 4.3's compute limits (with them the context is GL 4.6) drew
|
||||
// Muck's 3D scene black (U, mp26), so they are only per run; GL 4.1's
|
||||
// texture limits are the default, below.
|
||||
};
|
||||
// `?gllimits=41|43` (GEX_GL_LIMITS, set by the compositor worker): GL 4.1
|
||||
// wants 16384 texels a side and 2048 array layers, GL 4.3's compute
|
||||
// shaders 1024 invocations a workgroup and 32 KiB of shared memory;
|
||||
// WebGPU's defaults (8192, 256; 256, 16 KiB) keep the context at GL 4.0.
|
||||
// Unity drops shaders whose target the context is below (Muck's grass
|
||||
// geometry shader: "Shader Unsupported ... All passes removed").
|
||||
const glLimits = Number(globalThis.GEX_GL_LIMITS) || 0;
|
||||
// `?gllimits=40|41|43` (GEX_GL_LIMITS, set by the compositor worker;
|
||||
// 41 when unset): GL 4.1 wants 16384 texels a side and 2048 array
|
||||
// layers, GL 4.3's compute shaders 1024 invocations a workgroup and
|
||||
// 32 KiB of shared memory; WebGPU's defaults (8192, 256; 256, 16 KiB)
|
||||
// keep the context at GL 4.0. Unity drops shaders whose target the
|
||||
// context is below: at 4.0 Muck's grass geometry shader ("Shader
|
||||
// Unsupported ... All passes removed") left the grass as dots; at 4.2
|
||||
// with mesa-wink 60202246 it draws blades (U, mpg3).
|
||||
const glLimitsSet = globalThis.GEX_GL_LIMITS;
|
||||
const glLimits = glLimitsSet === undefined ? 41 : Number(glLimitsSet) || 0;
|
||||
if (glLimits >= 41) {
|
||||
Object.assign(want, { maxTextureDimension1D: 16384, maxTextureDimension2D: 16384,
|
||||
maxTextureDimension3D: 2048, maxTextureArrayLayers: 2048 });
|
||||
|
||||
Reference in new issue
Block a user