mirror of
https://github.com/HeyPuter/gex.git
synced 2026-11-13 20:12:43 -10:00
web: Mesa's WebGPU call counter only when asked for (?wgpustats=1)
countWebGpu wrapped every WebGPU call Mesa makes with a performance.now pair and a Map update, always: 2.5% of the compositor worker's time in Noita's page (F's co1 profile), 13% of a replayed frame's CPU. The stats line keeps its per-frame call table when the page asks for it. The eject site's launcher forwards ?glcapture and ?wgpustats to nt.html. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_d2453757b8a84fdbb4ee7c9e093141df
This commit is contained in:
1 parent
5a066f670f
commit
21baa051c1
4 files changed
+22
-6
No files matched your search
@@ -93,7 +93,7 @@
|
||||
// `?direct=0` composites always.
|
||||
if (m.direct && q.get('direct') !== '0') p.set('direct', '1');
|
||||
// Diagnostics for the page itself, passed through.
|
||||
for (const k of ['present', 'pointerlock', 'wgslcache', 'mesaenv', 'trapstack', 'sharetrace']) if (q.has(k)) p.set(k, q.get(k));
|
||||
for (const k of ['present', 'pointerlock', 'wgslcache', 'mesaenv', 'trapstack', 'sharetrace', 'glcapture', 'wgpustats']) if (q.has(k)) p.set(k, q.get(k));
|
||||
location.replace(`nt.html?${p}`);
|
||||
} catch (e) {
|
||||
fail(String(e?.message ?? e));
|
||||
|
||||
@@ -1404,6 +1404,7 @@ async function startGl(m, canvas) {
|
||||
env: m.mesaEnv,
|
||||
capture: m.glCapture,
|
||||
wgslCache: m.wgslCache,
|
||||
wgpuStats: m.wgpuStats,
|
||||
gpu: await requestGexDevice(),
|
||||
});
|
||||
if (!glDevice.ok) throw new Error(glDevice.error || 'the GL device would not start');
|
||||
|
||||
@@ -73,8 +73,12 @@ export class Compositor {
|
||||
// `?wgslcache=all|site|0`: which shader translations Mesa starts with
|
||||
// (mesa-gl.js #loadWgslCache).
|
||||
const wgslCache = q?.get('wgslcache');
|
||||
// `?wgpustats=1`: count Mesa's WebGPU calls for the stats line
|
||||
// (mesa-gl.js countWebGpu); off by default, it costs time.
|
||||
const wgpuStats = q?.get('wgpustats') === '1';
|
||||
this.#worker.postMessage({ kind: 'gl', channel, ...opts, ...(mesaEnv ? { mesaEnv } : {}),
|
||||
...(glCapture ? { glCapture } : {}), ...(wgslCache ? { wgslCache } : {}) });
|
||||
...(glCapture ? { glCapture } : {}), ...(wgslCache ? { wgslCache } : {}),
|
||||
...(wgpuStats ? { wgpuStats } : {}) });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+15
-4
@@ -63,9 +63,10 @@ async function loadGlue(url) {
|
||||
|
||||
/** The driver's WebGPU calls by name: [calls, ms inside, bytes, ms waited]
|
||||
* ("waited" is a promise's time to settle: mapAsync, onSubmittedWorkDone).
|
||||
* Mesa's own wasm is a few percent of a frame; its cost is these calls, so
|
||||
* they are counted always -- one performance.now pair per call -- and
|
||||
* `glState` reports them per frame since it was last asked. */
|
||||
* `glState` reports them per frame since it was last asked. Only when asked
|
||||
* for (`?wgpustats=1`, the `wgpuStats` option): the wrapper is a
|
||||
* performance.now pair and a Map lookup on each of a few thousand calls a
|
||||
* frame, which was 2.5% of the GL worker's time in Noita's page. */
|
||||
const wgpuCalls = new Map();
|
||||
function countWebGpu() {
|
||||
if (countWebGpu.done || typeof GPUQueue === 'undefined') return;
|
||||
@@ -124,6 +125,16 @@ function countWebGpu() {
|
||||
* message to whatever is listening (DevTools, a harness over CDP), on the
|
||||
* thread that runs Mesa: two thousand batches in a seven-minute Noita run.
|
||||
* `?gltrace=1` keeps them all. */
|
||||
/** A page's `?NAME=1`. In a Worker `location` is the worker script's, so
|
||||
* the compositor passes its page's switches in as options instead. */
|
||||
function pageFlag(name) {
|
||||
try {
|
||||
return globalThis.document !== undefined && new URLSearchParams(location.search).get(name) === '1';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function quietReports(out) {
|
||||
let all = false;
|
||||
try {
|
||||
@@ -224,7 +235,7 @@ export class MesaGlDevice {
|
||||
const { adapter, device } = options.gpu ?? await requestGexDevice();
|
||||
out.#adapter = adapter;
|
||||
out.#device = device;
|
||||
countWebGpu();
|
||||
if (options.wgpuStats ?? pageFlag('wgpustats')) countWebGpu();
|
||||
// And out of reach of the collector for as long as the page lives.
|
||||
//
|
||||
// The fields above were supposed to be enough, and are not: the device
|
||||
|
||||
Reference in new issue
Block a user