core: manual buffer sync with sync-rows, reuse unchanged buffers and pipelines across activations

Also lets the screenshot suite point at another reference directory and settle longer.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0b2dd-db32-712d-99ce-12ce4a86d979
Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
Amp
2026-09-18 05:53:44 +00:00
co-authored by heaust
parent 49c80a209e
commit 31d3ae21ff
15 changed files with 185 additions and 48 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ export type GraphBuffer = {
id: string;
array: string;
usage?: string[];
sync?: "frame" | "loadout";
sync?: "frame" | "manual";
};
export type GraphTexture = {
+4 -3
View File
@@ -990,6 +990,7 @@ export class Scene {
this.#geometry.get(geometry) ??
this.#geometry.set(geometry, new Map()).get(geometry)!
).set(kind, data);
await this.core.syncRows(name, 0, rowCount);
if (updateGraph) await this.updateRenderGraph();
}
@@ -1248,7 +1249,7 @@ export class Scene {
id: vertex,
array: `geometry.${mesh.geometryId}.positions`,
usage: ["vertex"],
sync: "loadout",
sync: "manual",
});
const normal = `geometry-${mesh.geometryId}-normals`;
const uv = `geometry-${mesh.geometryId}-uvs`;
@@ -1272,7 +1273,7 @@ export class Scene {
id,
array: `geometry.${mesh.geometryId}.${kind}`,
usage: ["vertex"],
sync: "loadout",
sync: "manual",
});
const indexed = mesh.indexCount > 0;
if (indexed)
@@ -1280,7 +1281,7 @@ export class Scene {
id: `geometry-${mesh.geometryId}-indices`,
array: `geometry.${mesh.geometryId}.indices`,
usage: ["index"],
sync: "loadout",
sync: "manual",
});
const draws =
indexed && mesh.faceMaterials.size
+4
View File
@@ -184,6 +184,10 @@ export class YawnCore {
return Promise.resolve();
}
syncRows() {
return Promise.resolve();
}
array(name: string) {
const rows = this.#arrays.get(name);
if (!rows) throw new Error(`UNKNOWN_ARRAY: ${name}`);
@@ -9,6 +9,11 @@ uses headed Chromium on a private Xvfb display and SwiftShader WebGPU at a fixed
The first run downloads roughly 215 MB of GLBs into
`~/.cache/yawn/gltf-sample-models`. Set `YAWN_GLTF_FIXTURES` to use another
cache directory, or `YAWN_SCREENSHOT_MODELS=Box,BoomBox` to run a subset.
`YAWN_SCREENSHOT_BASELINES` points at another reference directory (for example
one captured from a known-good commit on a machine whose software renderer does
not match the reviewed references), and `YAWN_SCREENSHOT_SETTLE_MS` (default
1200) is how long the viewer gets to settle after the model loads before the
capture; raise it on slow software renderers.
Failed full-size captures and visual diffs are written to `output/`.
To intentionally replace references after reviewing full-size renders, run:
+6 -3
View File
@@ -25,7 +25,10 @@ import { promisify } from "node:util";
const execute = promisify(execFile);
const directory = dirname(fileURLToPath(import.meta.url));
const root = resolve(directory, "../../../..");
const baselines = join(directory, "baselines");
const baselines = resolve(
process.env.YAWN_SCREENSHOT_BASELINES ?? join(directory, "baselines"),
);
const settleMilliseconds = Number(process.env.YAWN_SCREENSHOT_SETTLE_MS ?? 1200);
const output = resolve(
process.env.YAWN_SCREENSHOT_OUTPUT ?? join(directory, "output"),
);
@@ -44,7 +47,7 @@ const update = process.env.UPDATE_SCREENSHOTS === "1";
const session = `yawn-gltf-screenshots-${process.pid}`;
const temporary = await mkdtemp(join(tmpdir(), "yawn-gltf-screenshots-"));
const imageSize = { width: 250, height: 180 };
const allModels = (await readdir(baselines))
const allModels = (await readdir(join(directory, "baselines")))
.filter((name) => name.endsWith(".png") && name !== "initial.png")
.map((name) => basename(name, ".png"))
.sort()
@@ -366,7 +369,7 @@ for (const model of models) {
);
await browser("upload", "#file-picker", model.path);
await browser("wait", "--fn", "window.__yawnScreenshotReady === true");
await browser("wait", "1200");
await browser("wait", String(settleMilliseconds));
const state = await browser(
"eval",