mesa: pin mesa-wink 60202246 (wink head); GL 4.1's texture limits by default

third_party/mesa moves from 5f5572e6 to 60202246, the wink branch's head
(gl/perf rebased onto upstream wink 0dd84167). Its webgpu.cpp needs
emdawnwebgpu v20250822 (WGPUTextureFormat_R16Unorm, std::span), which
the wink branch pins and patches itself: web/build-mesa-wasm.sh now gets
it from the checkout's wink/build.sh (--until=emdawn) when the checkout
has wink/lib/emdawn.sh, and keeps fetch-emdawnwebgpu.sh otherwise (as it
already does for Tint). The page build's JS is byte-identical to GL's
mods/gpu build of the same commit.

gpu-device.js asks for GL 4.1's texture limits (16384 texels a side,
2048 array layers; clamped to the adapter's) unless the page says
otherwise: `?gllimits=0` is WebGPU's defaults (GL 4.0), 43 adds GL 4.3's
compute limits (GL 4.6, which drew Muck's 3D scene black: per run only).
At 4.0 Unity drops Muck's grass geometry shader and the grass is dots;
with this Mesa at 4.2 it draws blades (mpg3).

Checks on edger:
- Replays, GL's mods/gpu against this build (upin), 300 frames with
  readback: Noita 92f095c5 for both, HK 9eece5c5 for both; 0 rejects
  and 0 validation errors each.
- GL's 4-slot bind-group repro (mods/tinyu, the rebased tree with a
  4-slot cache), full Noita trace with --query stream=1: 2,777 frames,
  0 validation errors (5f5572e6 had 2,668 from frame 1343).
- browser-gui --gl --arch x86 and --arch x64 with this build and the new
  default: 12 ok and 0 failures each (234 and 213 frames).
- HK in the page (hp14, full fjit + the unit, this Mesa, no ?gllimits):
  the menu at 41.8 presents/s (hp13 on 5f5572e6: 39.6-39.9); first frame
  110 s with a CPU profile of 80 s running (hp13: 87 s without one).
- Muck (mpg5, fjit + unit) died with SIGILL at ~30 s, before any GL:
  the function JIT, not Mesa (being run down separately); the grass
  check with the default is still to come.

docs/gl-path.md: open items 2 (grass) and 5 (the repro) closed.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_1896c5b302a54696aaa92c5f4047f20b
This commit is contained in:
velzieandClaude Opus 5.5 committed 2026-10-09 06:06:18 -04:00
1 parent 997f95612d
commit 1d5b26d9fc
6 files changed
+49 -26

No files matched your search

+9 -9
View File
@@ -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):
+20 -1
View File
@@ -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}
+1 -1
View File
@@ -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);
+5 -4
View File
@@ -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
View File
@@ -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 });