gpu-atlas 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -2
- package/dist/gpu-atlas.js +222 -210
- package/dist/gpu-atlas.js.map +1 -1
- package/package.json +1 -1
package/dist/gpu-atlas.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const
|
|
1
|
+
const $t = 5, Rt = 2;
|
|
2
2
|
class D extends Error {
|
|
3
3
|
constructor(t) {
|
|
4
4
|
super(t), this.name = "WebGPUUnavailable";
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
|
-
async function
|
|
7
|
+
async function Me(e) {
|
|
8
8
|
if (typeof navigator > "u" || !navigator.gpu)
|
|
9
9
|
throw new D("navigator.gpu is missing — this browser has no WebGPU");
|
|
10
10
|
const t = await navigator.gpu.requestAdapter(
|
|
@@ -14,7 +14,7 @@ async function Se(e) {
|
|
|
14
14
|
throw new D(
|
|
15
15
|
"requestAdapter returned null — the WebGPU API exists but no usable adapter does"
|
|
16
16
|
);
|
|
17
|
-
const r = await
|
|
17
|
+
const r = await Pe(t, e), n = [...t.features], i = Ee(t.limits), a = [];
|
|
18
18
|
let s = await L(t, n, i);
|
|
19
19
|
if (s || (a.push("requiredLimits (all)"), s = await L(t, n, void 0)), !s) {
|
|
20
20
|
a.push("requiredFeatures (all)");
|
|
@@ -32,7 +32,7 @@ async function Se(e) {
|
|
|
32
32
|
const o = {
|
|
33
33
|
features: [...t.features].sort(),
|
|
34
34
|
limits: i,
|
|
35
|
-
preferredCanvasFormat:
|
|
35
|
+
preferredCanvasFormat: Be()
|
|
36
36
|
};
|
|
37
37
|
return { adapter: t, device: s, identity: r, declared: o, denied: a, lost: s.lost };
|
|
38
38
|
}
|
|
@@ -44,7 +44,7 @@ async function L(e, t, r) {
|
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
async function
|
|
47
|
+
async function Pe(e, t) {
|
|
48
48
|
let r = e.info;
|
|
49
49
|
if (!r) {
|
|
50
50
|
const n = e;
|
|
@@ -65,15 +65,15 @@ async function Me(e, t) {
|
|
|
65
65
|
powerPreference: t ?? "default"
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
-
function
|
|
68
|
+
function Ee(e) {
|
|
69
69
|
const t = {};
|
|
70
|
-
for (const r of
|
|
70
|
+
for (const r of Te(e)) {
|
|
71
71
|
const n = e[r];
|
|
72
72
|
typeof n == "number" && Number.isFinite(n) && (t[r] = n);
|
|
73
73
|
}
|
|
74
74
|
return t;
|
|
75
75
|
}
|
|
76
|
-
function
|
|
76
|
+
function Te(e) {
|
|
77
77
|
const t = /* @__PURE__ */ new Set();
|
|
78
78
|
let r = Object.getPrototypeOf(e);
|
|
79
79
|
for (; r && r !== Object.prototype; ) {
|
|
@@ -84,7 +84,7 @@ function Ee(e) {
|
|
|
84
84
|
for (const n of Object.keys(e)) t.add(n);
|
|
85
85
|
return [...t].sort();
|
|
86
86
|
}
|
|
87
|
-
function
|
|
87
|
+
function Be() {
|
|
88
88
|
try {
|
|
89
89
|
return navigator.gpu.getPreferredCanvasFormat();
|
|
90
90
|
} catch {
|
|
@@ -96,31 +96,38 @@ async function Ae() {
|
|
|
96
96
|
let r, n, i, a;
|
|
97
97
|
if (t) {
|
|
98
98
|
n = t.mobile, r = t.platform;
|
|
99
|
+
const o = ae(t.brands);
|
|
100
|
+
o && (i = o.brand, a = o.version);
|
|
99
101
|
try {
|
|
100
|
-
const
|
|
101
|
-
c && (i = c.brand, a = c.version),
|
|
102
|
+
const u = await t.getHighEntropyValues(["platformVersion", "fullVersionList"]), c = ae(u.fullVersionList);
|
|
103
|
+
c && (i = c.brand, a = c.version), u.platformVersion && (r = `${r} ${u.platformVersion}`);
|
|
102
104
|
} catch {
|
|
103
105
|
}
|
|
104
106
|
}
|
|
105
|
-
const s =
|
|
107
|
+
const s = _e(e);
|
|
106
108
|
return {
|
|
107
109
|
// The UA string is parsed above but deliberately not kept: everything the
|
|
108
110
|
// profile needs from it is already broken out, and the raw value only adds
|
|
109
111
|
// identifying detail to something people are asked to share.
|
|
110
|
-
platform: r ??
|
|
112
|
+
platform: r ?? Re(e),
|
|
111
113
|
browser: i ?? s.browser,
|
|
112
114
|
browserVersion: a ?? s.version,
|
|
113
|
-
mobile: n ??
|
|
115
|
+
mobile: n ?? $e(e),
|
|
114
116
|
deviceMemoryGB: navigator.deviceMemory,
|
|
115
117
|
hardwareConcurrency: navigator.hardwareConcurrency,
|
|
116
118
|
devicePixelRatio: typeof devicePixelRatio == "number" ? devicePixelRatio : 1
|
|
117
119
|
};
|
|
118
120
|
}
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
+
function ae(e) {
|
|
122
|
+
const t = e?.filter((r) => !/Not.?A.?Brand/i.test(r.brand));
|
|
123
|
+
if (t?.length)
|
|
124
|
+
return t.find((r) => !/^Chromium$/i.test(r.brand)) ?? t[0];
|
|
121
125
|
}
|
|
122
126
|
function $e(e) {
|
|
123
|
-
|
|
127
|
+
return /Mobi|Android|iPhone|iPad|iPod/i.test(e) ? !0 : we(e);
|
|
128
|
+
}
|
|
129
|
+
function Re(e) {
|
|
130
|
+
if (we(e)) return "iPadOS";
|
|
124
131
|
if (/iPhone|iPod/i.test(e)) return "iOS";
|
|
125
132
|
if (/iPad/i.test(e)) return "iPadOS";
|
|
126
133
|
if (/Android/i.test(e)) return "Android";
|
|
@@ -128,14 +135,19 @@ function $e(e) {
|
|
|
128
135
|
if (/Windows/i.test(e)) return "Windows";
|
|
129
136
|
if (/Linux/i.test(e)) return "Linux";
|
|
130
137
|
}
|
|
131
|
-
function
|
|
138
|
+
function we(e) {
|
|
132
139
|
return /Macintosh|Mac OS X/i.test(e) ? (typeof navigator < "u" ? navigator.maxTouchPoints ?? 0 : 0) > 1 : !1;
|
|
133
140
|
}
|
|
134
|
-
function
|
|
141
|
+
function _e(e) {
|
|
135
142
|
const t = [
|
|
136
143
|
["Edge", /Edg(?:e|A|iOS)?\/([\d.]+)/],
|
|
137
144
|
["Opera", /OPR\/([\d.]+)/],
|
|
138
|
-
["
|
|
145
|
+
["Samsung Internet", /SamsungBrowser\/([\d.]+)/],
|
|
146
|
+
["Vivaldi", /Vivaldi\/([\d.]+)/],
|
|
147
|
+
["Yandex", /YaBrowser\/([\d.]+)/],
|
|
148
|
+
["UC Browser", /UCBrowser\/([\d.]+)/],
|
|
149
|
+
// Firefox on iOS is a WebKit shell and says FxiOS, never Firefox.
|
|
150
|
+
["Firefox", /(?:Firefox|FxiOS)\/([\d.]+)/],
|
|
139
151
|
["Chrome", /(?:Chrome|CriOS)\/([\d.]+)/],
|
|
140
152
|
["Safari", /Version\/([\d.]+).*Safari/]
|
|
141
153
|
];
|
|
@@ -145,17 +157,17 @@ function Re(e) {
|
|
|
145
157
|
}
|
|
146
158
|
return { browser: "unknown", version: "" };
|
|
147
159
|
}
|
|
148
|
-
const d = (e, t, r, n, i) => ({ format: e, kind: "color", texel: t, filterable: r, expect: n, requiresFeature: i }), I = { renderable: !1, blendable: !1, storage: !1 },
|
|
160
|
+
const d = (e, t, r, n, i) => ({ format: e, kind: "color", texel: t, filterable: r, expect: n, requiresFeature: i }), I = { renderable: !1, blendable: !1, storage: !1 }, B = { renderable: !0, blendable: !0, storage: !1 }, y = { renderable: !0, blendable: !1, storage: !1 }, se = { renderable: !0, blendable: !0, storage: !0 }, x = { renderable: !0, blendable: !1, storage: !0 }, Ge = { renderable: !1, blendable: !1, storage: !0 }, ie = [
|
|
149
161
|
// ── 8-bit ──
|
|
150
|
-
d("r8unorm", "f32", !0,
|
|
162
|
+
d("r8unorm", "f32", !0, B),
|
|
151
163
|
d("r8snorm", "f32", !0, I),
|
|
152
164
|
d("r8uint", "u32", !1, y),
|
|
153
165
|
d("r8sint", "i32", !1, y),
|
|
154
166
|
// ── 16-bit ──
|
|
155
167
|
d("r16uint", "u32", !1, y),
|
|
156
168
|
d("r16sint", "i32", !1, y),
|
|
157
|
-
d("r16float", "f32", !0,
|
|
158
|
-
d("rg8unorm", "f32", !0,
|
|
169
|
+
d("r16float", "f32", !0, B),
|
|
170
|
+
d("rg8unorm", "f32", !0, B),
|
|
159
171
|
d("rg8snorm", "f32", !0, I),
|
|
160
172
|
d("rg8uint", "u32", !1, y),
|
|
161
173
|
d("rg8sint", "i32", !1, y),
|
|
@@ -166,16 +178,16 @@ const d = (e, t, r, n, i) => ({ format: e, kind: "color", texel: t, filterable:
|
|
|
166
178
|
d("r32float", "f32", !1, x),
|
|
167
179
|
d("rg16uint", "u32", !1, y),
|
|
168
180
|
d("rg16sint", "i32", !1, y),
|
|
169
|
-
d("rg16float", "f32", !0,
|
|
170
|
-
d("rgba8unorm", "f32", !0,
|
|
171
|
-
d("rgba8unorm-srgb", "f32", !0,
|
|
172
|
-
d("rgba8snorm", "f32", !0,
|
|
181
|
+
d("rg16float", "f32", !0, B),
|
|
182
|
+
d("rgba8unorm", "f32", !0, se),
|
|
183
|
+
d("rgba8unorm-srgb", "f32", !0, B),
|
|
184
|
+
d("rgba8snorm", "f32", !0, Ge),
|
|
173
185
|
d("rgba8uint", "u32", !1, x),
|
|
174
186
|
d("rgba8sint", "i32", !1, x),
|
|
175
|
-
d("bgra8unorm", "f32", !0,
|
|
176
|
-
d("bgra8unorm-srgb", "f32", !0,
|
|
187
|
+
d("bgra8unorm", "f32", !0, B),
|
|
188
|
+
d("bgra8unorm-srgb", "f32", !0, B),
|
|
177
189
|
d("rgb10a2uint", "u32", !1, y),
|
|
178
|
-
d("rgb10a2unorm", "f32", !0,
|
|
190
|
+
d("rgb10a2unorm", "f32", !0, B),
|
|
179
191
|
// rg11b10ufloat rendering sits behind its own feature gate
|
|
180
192
|
d("rg11b10ufloat", "f32", !0, I),
|
|
181
193
|
// ── 64-bit ──
|
|
@@ -184,7 +196,7 @@ const d = (e, t, r, n, i) => ({ format: e, kind: "color", texel: t, filterable:
|
|
|
184
196
|
d("rg32float", "f32", !1, x),
|
|
185
197
|
d("rgba16uint", "u32", !1, x),
|
|
186
198
|
d("rgba16sint", "i32", !1, x),
|
|
187
|
-
d("rgba16float", "f32", !0,
|
|
199
|
+
d("rgba16float", "f32", !0, se),
|
|
188
200
|
// ── 128-bit ──
|
|
189
201
|
d("rgba32uint", "u32", !1, x),
|
|
190
202
|
d("rgba32sint", "i32", !1, x),
|
|
@@ -271,10 +283,10 @@ function N(e, t, r) {
|
|
|
271
283
|
expect: I
|
|
272
284
|
}));
|
|
273
285
|
}
|
|
274
|
-
function
|
|
286
|
+
function Fe(e) {
|
|
275
287
|
return ie.find((t) => t.format === e);
|
|
276
288
|
}
|
|
277
|
-
const
|
|
289
|
+
const ue = /* @__PURE__ */ new Set([
|
|
278
290
|
"r8unorm",
|
|
279
291
|
"r8snorm",
|
|
280
292
|
"r8uint",
|
|
@@ -292,47 +304,47 @@ const se = /* @__PURE__ */ new Set([
|
|
|
292
304
|
"rgb10a2unorm",
|
|
293
305
|
"rgb10a2uint",
|
|
294
306
|
"rg11b10ufloat"
|
|
295
|
-
]),
|
|
296
|
-
function
|
|
307
|
+
]), Ue = /* @__PURE__ */ new Set(["r32float", "rg32float", "rgba32float"]);
|
|
308
|
+
function Ce(e, t) {
|
|
297
309
|
const r = { ...e.expect };
|
|
298
|
-
return t.has("texture-formats-tier1") &&
|
|
310
|
+
return t.has("texture-formats-tier1") && ue.has(e.format) && (r.storage = !0), t.has("rg11b10ufloat-renderable") && e.format === "rg11b10ufloat" && (r.renderable = !0, r.blendable = !0), t.has("bgra8unorm-storage") && e.format === "bgra8unorm" && (r.storage = !0), t.has("float32-blendable") && Ue.has(e.format) && (r.blendable = !0), t.has("texture-formats-tier2") && e.kind === "color" && (r.storage = r.storage || ue.has(e.format)), r;
|
|
299
311
|
}
|
|
300
|
-
function
|
|
312
|
+
function Oe(e) {
|
|
301
313
|
return e.has("texture-formats-tier1") || e.has("texture-formats-tier2");
|
|
302
314
|
}
|
|
303
|
-
function
|
|
315
|
+
function qe(e) {
|
|
304
316
|
return e.kind === "depth" ? e.hasDepth ? "depth" : "uint" : e.texel === "u32" ? "uint" : e.texel === "i32" ? "sint" : e.filterable ? "float" : "unfilterable-float";
|
|
305
317
|
}
|
|
306
|
-
function
|
|
318
|
+
function Le(e) {
|
|
307
319
|
return e.kind === "depth" && e.hasDepth ? "texture_depth_2d" : `texture_2d<${e.texel}>`;
|
|
308
320
|
}
|
|
309
|
-
const
|
|
310
|
-
async function
|
|
311
|
-
for (const a of
|
|
321
|
+
const K = ["validation", "out-of-memory", "internal"];
|
|
322
|
+
async function z(e, t, r = !1) {
|
|
323
|
+
for (const a of K) e.pushErrorScope(a);
|
|
312
324
|
let n = null;
|
|
313
325
|
const i = [];
|
|
314
326
|
try {
|
|
315
327
|
n = await t();
|
|
316
328
|
} catch (a) {
|
|
317
|
-
i.push({ kind: "exception", message:
|
|
329
|
+
i.push({ kind: "exception", message: X(a) });
|
|
318
330
|
}
|
|
319
331
|
if (r && i.length === 0)
|
|
320
332
|
try {
|
|
321
333
|
await e.queue.onSubmittedWorkDone();
|
|
322
334
|
} catch (a) {
|
|
323
|
-
i.push({ kind: "queue", message:
|
|
335
|
+
i.push({ kind: "queue", message: X(a) });
|
|
324
336
|
}
|
|
325
|
-
for (let a =
|
|
337
|
+
for (let a = K.length - 1; a >= 0; a--)
|
|
326
338
|
try {
|
|
327
339
|
const s = await e.popErrorScope();
|
|
328
|
-
s && i.push({ kind:
|
|
340
|
+
s && i.push({ kind: K[a], message: s.message });
|
|
329
341
|
} catch (s) {
|
|
330
|
-
i.push({ kind: "scope-unavailable", message:
|
|
342
|
+
i.push({ kind: "scope-unavailable", message: X(s) });
|
|
331
343
|
}
|
|
332
344
|
return { value: n, errors: i, ok: i.length === 0 && n !== null };
|
|
333
345
|
}
|
|
334
346
|
async function M(e, t, r = !1) {
|
|
335
|
-
const n = await
|
|
347
|
+
const n = await z(e, async () => {
|
|
336
348
|
const i = await t();
|
|
337
349
|
return i === void 0 ? !0 : i;
|
|
338
350
|
}, r);
|
|
@@ -344,7 +356,7 @@ function _(e, t) {
|
|
|
344
356
|
function O(e) {
|
|
345
357
|
return e[0]?.message ?? "no error reported";
|
|
346
358
|
}
|
|
347
|
-
function
|
|
359
|
+
function X(e) {
|
|
348
360
|
return e instanceof Error ? `${e.name}: ${e.message}` : String(e);
|
|
349
361
|
}
|
|
350
362
|
function v(...e) {
|
|
@@ -359,17 +371,17 @@ const H = `
|
|
|
359
371
|
var p = array<vec2f, 3>(vec2f(-1., -1.), vec2f(3., -1.), vec2f(-1., 3.));
|
|
360
372
|
return vec4f(p[i], 0., 1.);
|
|
361
373
|
}`;
|
|
362
|
-
async function
|
|
374
|
+
async function Ne(e, t, r, n) {
|
|
363
375
|
const i = r ? ie.filter((u) => r.includes(u.format)) : ie, a = e.createTexture({
|
|
364
376
|
size: [4, 4],
|
|
365
377
|
format: "rgba8unorm",
|
|
366
378
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
367
379
|
}), s = { view: a.createView() }, o = [];
|
|
368
380
|
for (let u = 0; u < i.length; u++)
|
|
369
|
-
o.push(await
|
|
381
|
+
o.push(await De(e, i[u], t, s)), n?.((u + 1) / i.length);
|
|
370
382
|
return v(a), o;
|
|
371
383
|
}
|
|
372
|
-
async function
|
|
384
|
+
async function De(e, t, r, n) {
|
|
373
385
|
const i = {
|
|
374
386
|
format: t.format,
|
|
375
387
|
requiresFeature: t.requiresFeature,
|
|
@@ -381,7 +393,7 @@ async function Ne(e, t, r, n) {
|
|
|
381
393
|
storageWritable: !1,
|
|
382
394
|
multisample4x: !1,
|
|
383
395
|
errors: []
|
|
384
|
-
}, [a, s] = t.block ?? [4, 4], o = await
|
|
396
|
+
}, [a, s] = t.block ?? [4, 4], o = await z(
|
|
385
397
|
e,
|
|
386
398
|
() => e.createTexture({
|
|
387
399
|
size: [a, s],
|
|
@@ -391,14 +403,14 @@ async function Ne(e, t, r, n) {
|
|
|
391
403
|
);
|
|
392
404
|
if (i.creatable = o.ok, !o.ok)
|
|
393
405
|
return i.errors.push(..._("create", o.errors)), i;
|
|
394
|
-
const u = o.value, c = await
|
|
406
|
+
const u = o.value, c = await Ie(e, t, u, n);
|
|
395
407
|
if (i.sampleable = c.ok, c.ok || i.errors.push(..._("sample", c.errors)), v(u), t.kind !== "compressed") if (t.kind === "depth") {
|
|
396
|
-
const l = await
|
|
408
|
+
const l = await Ve(e, t);
|
|
397
409
|
i.renderable = l.ok, l.ok || i.errors.push(..._("render", l.errors));
|
|
398
410
|
} else {
|
|
399
|
-
const l = await
|
|
411
|
+
const l = await ce(e, t, !1);
|
|
400
412
|
if (i.renderable = l.ok, l.ok || i.errors.push(..._("render", l.errors)), i.renderable) {
|
|
401
|
-
const f = await
|
|
413
|
+
const f = await ce(e, t, !0);
|
|
402
414
|
i.blendable = f.ok, f.ok || i.errors.push(..._("blend", f.errors));
|
|
403
415
|
}
|
|
404
416
|
}
|
|
@@ -412,8 +424,8 @@ async function Ne(e, t, r, n) {
|
|
|
412
424
|
}
|
|
413
425
|
return i;
|
|
414
426
|
}
|
|
415
|
-
async function
|
|
416
|
-
const i = t.kind === "compressed", a =
|
|
427
|
+
async function Ie(e, t, r, n) {
|
|
428
|
+
const i = t.kind === "compressed", a = qe(t);
|
|
417
429
|
return M(e, async () => {
|
|
418
430
|
const s = [{
|
|
419
431
|
binding: 0,
|
|
@@ -426,7 +438,7 @@ async function De(e, t, r, n) {
|
|
|
426
438
|
sampler: { type: t.filterable ? "filtering" : "non-filtering" }
|
|
427
439
|
});
|
|
428
440
|
const o = e.createBindGroupLayout({ entries: s }), u = e.createShaderModule({
|
|
429
|
-
code: H +
|
|
441
|
+
code: H + je(t, i)
|
|
430
442
|
}), c = e.createRenderPipeline({
|
|
431
443
|
layout: e.createPipelineLayout({ bindGroupLayouts: [o] }),
|
|
432
444
|
vertex: { module: u, entryPoint: "vs" },
|
|
@@ -451,7 +463,7 @@ async function De(e, t, r, n) {
|
|
|
451
463
|
return g.setPipeline(c), g.setBindGroup(0, h), g.draw(3), g.end(), e.queue.submit([w.finish()]), !0;
|
|
452
464
|
}, !0);
|
|
453
465
|
}
|
|
454
|
-
async function
|
|
466
|
+
async function ce(e, t, r) {
|
|
455
467
|
let n = null;
|
|
456
468
|
const i = await M(e, async () => {
|
|
457
469
|
const a = e.createTexture({
|
|
@@ -464,7 +476,7 @@ async function ue(e, t, r) {
|
|
|
464
476
|
alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" }
|
|
465
477
|
});
|
|
466
478
|
const o = e.createShaderModule({
|
|
467
|
-
code: H +
|
|
479
|
+
code: H + xe(t)
|
|
468
480
|
}), u = e.createRenderPipeline({
|
|
469
481
|
layout: "auto",
|
|
470
482
|
vertex: { module: o, entryPoint: "vs" },
|
|
@@ -481,7 +493,7 @@ async function ue(e, t, r) {
|
|
|
481
493
|
}, !0);
|
|
482
494
|
return v(n), i;
|
|
483
495
|
}
|
|
484
|
-
async function
|
|
496
|
+
async function Ve(e, t) {
|
|
485
497
|
let r = null;
|
|
486
498
|
const n = await M(e, async () => {
|
|
487
499
|
const i = e.createTexture({
|
|
@@ -539,7 +551,7 @@ async function ze(e, t) {
|
|
|
539
551
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
540
552
|
sampleCount: 4
|
|
541
553
|
}), a = e.createShaderModule({
|
|
542
|
-
code: H + (t.kind === "depth" ? "" :
|
|
554
|
+
code: H + (t.kind === "depth" ? "" : xe(t))
|
|
543
555
|
}), s = {
|
|
544
556
|
layout: "auto",
|
|
545
557
|
vertex: { module: a, entryPoint: "vs" },
|
|
@@ -572,8 +584,8 @@ async function ze(e, t) {
|
|
|
572
584
|
}, !0);
|
|
573
585
|
return v(r), n;
|
|
574
586
|
}
|
|
575
|
-
function
|
|
576
|
-
const n = `@group(0) @binding(0) var t: ${
|
|
587
|
+
function je(e, t) {
|
|
588
|
+
const n = `@group(0) @binding(0) var t: ${Le(e)};`, i = t ? "@group(0) @binding(1) var s: sampler;" : "";
|
|
577
589
|
let a;
|
|
578
590
|
return t ? a = "return textureSample(t, s, vec2f(0.5, 0.5));" : e.kind === "depth" && e.hasDepth ? a = `let v = textureLoad(t, vec2i(0, 0), 0);
|
|
579
591
|
return vec4f(v, 0., 0., 1.);` : e.texel === "f32" ? a = "return textureLoad(t, vec2i(0, 0), 0);" : a = `let v = textureLoad(t, vec2i(0, 0), 0);
|
|
@@ -584,7 +596,7 @@ ${i}
|
|
|
584
596
|
${a}
|
|
585
597
|
}`;
|
|
586
598
|
}
|
|
587
|
-
function
|
|
599
|
+
function xe(e) {
|
|
588
600
|
return e.texel === "u32" ? `
|
|
589
601
|
@fragment fn fs() -> @location(0) vec4u {
|
|
590
602
|
return vec4u(1u, 0u, 0u, 1u);
|
|
@@ -742,7 +754,7 @@ ${G}
|
|
|
742
754
|
}`
|
|
743
755
|
}
|
|
744
756
|
];
|
|
745
|
-
async function
|
|
757
|
+
async function He(e, t, r) {
|
|
746
758
|
const n = [];
|
|
747
759
|
for (let i = 0; i < Q.length; i++) {
|
|
748
760
|
const a = Q[i];
|
|
@@ -762,11 +774,11 @@ async function je(e, t, r) {
|
|
|
762
774
|
});
|
|
763
775
|
continue;
|
|
764
776
|
}
|
|
765
|
-
n.push(await
|
|
777
|
+
n.push(await Ye(e, a));
|
|
766
778
|
}
|
|
767
779
|
return n;
|
|
768
780
|
}
|
|
769
|
-
async function
|
|
781
|
+
async function Ye(e, t) {
|
|
770
782
|
const r = {
|
|
771
783
|
id: t.id,
|
|
772
784
|
description: t.description,
|
|
@@ -775,9 +787,9 @@ async function He(e, t) {
|
|
|
775
787
|
pipelineCreated: !1,
|
|
776
788
|
messages: [],
|
|
777
789
|
compileMs: 0
|
|
778
|
-
}, n = performance.now(), i = await
|
|
790
|
+
}, n = performance.now(), i = await z(e, () => e.createShaderModule({ code: t.code }));
|
|
779
791
|
if (!i.ok || !i.value)
|
|
780
|
-
return r.compileMs = performance.now() - n, r.messages.push(...i.errors.map(
|
|
792
|
+
return r.compileMs = performance.now() - n, r.messages.push(...i.errors.map(le)), r;
|
|
781
793
|
let a = null;
|
|
782
794
|
try {
|
|
783
795
|
a = await i.value.getCompilationInfo();
|
|
@@ -792,7 +804,7 @@ async function He(e, t) {
|
|
|
792
804
|
lineNum: o.lineNum
|
|
793
805
|
});
|
|
794
806
|
if (r.compiled = !r.messages.some((o) => o.type === "error"), !r.compiled) return r;
|
|
795
|
-
const s = await
|
|
807
|
+
const s = await z(e, () => t.pipeline === "compute" ? e.createComputePipelineAsync({
|
|
796
808
|
layout: "auto",
|
|
797
809
|
compute: { module: i.value, entryPoint: "cs" }
|
|
798
810
|
}) : e.createRenderPipelineAsync({
|
|
@@ -804,9 +816,9 @@ async function He(e, t) {
|
|
|
804
816
|
targets: [{ format: "rgba8unorm" }]
|
|
805
817
|
}
|
|
806
818
|
}));
|
|
807
|
-
return r.pipelineCreated = s.ok, s.ok || r.messages.push(...s.errors.map(
|
|
819
|
+
return r.pipelineCreated = s.ok, s.ok || r.messages.push(...s.errors.map(le)), r;
|
|
808
820
|
}
|
|
809
|
-
function
|
|
821
|
+
function le(e) {
|
|
810
822
|
return { type: "error", message: e.message, lineNum: 0 };
|
|
811
823
|
}
|
|
812
824
|
const Ke = 10, Z = [
|
|
@@ -843,7 +855,7 @@ const Ke = 10, Z = [
|
|
|
843
855
|
floor: 16 * 1024,
|
|
844
856
|
test: (e, t) => M(e, () => {
|
|
845
857
|
const r = e.createBuffer({
|
|
846
|
-
size:
|
|
858
|
+
size: fe(t),
|
|
847
859
|
usage: GPUBufferUsage.UNIFORM
|
|
848
860
|
}), n = e.createBindGroupLayout({
|
|
849
861
|
entries: [{
|
|
@@ -853,7 +865,7 @@ const Ke = 10, Z = [
|
|
|
853
865
|
}]
|
|
854
866
|
}), i = e.createBindGroup({
|
|
855
867
|
layout: n,
|
|
856
|
-
entries: [{ binding: 0, resource: { buffer: r, size:
|
|
868
|
+
entries: [{ binding: 0, resource: { buffer: r, size: fe(t) } }]
|
|
857
869
|
});
|
|
858
870
|
return queueMicrotask(() => v(r)), i;
|
|
859
871
|
})
|
|
@@ -937,7 +949,7 @@ async function Xe(e, t, r) {
|
|
|
937
949
|
});
|
|
938
950
|
continue;
|
|
939
951
|
}
|
|
940
|
-
const u = await
|
|
952
|
+
const u = await Qe(e, a, Math.min(a.floor, s), s);
|
|
941
953
|
n.push({
|
|
942
954
|
limit: a.limit,
|
|
943
955
|
declared: s,
|
|
@@ -952,7 +964,7 @@ async function Xe(e, t, r) {
|
|
|
952
964
|
}
|
|
953
965
|
return n;
|
|
954
966
|
}
|
|
955
|
-
async function
|
|
967
|
+
async function Qe(e, t, r, n) {
|
|
956
968
|
let i = r, a = (await t.test(e, i)).ok;
|
|
957
969
|
for (; !a && i > 1; )
|
|
958
970
|
i = Math.floor(i / 2), a = (await t.test(e, i)).ok;
|
|
@@ -964,7 +976,7 @@ async function Ye(e, t, r, n) {
|
|
|
964
976
|
}
|
|
965
977
|
return i;
|
|
966
978
|
}
|
|
967
|
-
const J = (e) => Math.floor(e / 4) * 4,
|
|
979
|
+
const J = (e) => Math.floor(e / 4) * 4, fe = (e) => Math.floor(e / 16) * 16;
|
|
968
980
|
class j {
|
|
969
981
|
constructor(t) {
|
|
970
982
|
this.available = t;
|
|
@@ -1034,52 +1046,52 @@ class j {
|
|
|
1034
1046
|
this.querySet = null, this.resolveBuf = null, this.readBuf = null;
|
|
1035
1047
|
}
|
|
1036
1048
|
}
|
|
1037
|
-
function
|
|
1049
|
+
function Ze(e) {
|
|
1038
1050
|
if (e.length === 0) return 0;
|
|
1039
1051
|
const t = [...e].sort((n, i) => n - i), r = t.length >> 1;
|
|
1040
1052
|
return t.length % 2 ? t[r] : (t[r - 1] + t[r]) / 2;
|
|
1041
1053
|
}
|
|
1042
|
-
function
|
|
1054
|
+
function Je(e) {
|
|
1043
1055
|
if (e.length < 2) return 0;
|
|
1044
1056
|
const t = e.reduce((n, i) => n + i, 0) / e.length;
|
|
1045
1057
|
if (t === 0) return 0;
|
|
1046
1058
|
const r = e.reduce((n, i) => n + (i - t) ** 2, 0) / (e.length - 1);
|
|
1047
1059
|
return Math.sqrt(r) / t;
|
|
1048
1060
|
}
|
|
1049
|
-
const
|
|
1050
|
-
function
|
|
1061
|
+
const et = 0.9, tt = 0.02, rt = 4;
|
|
1062
|
+
function nt(e, t) {
|
|
1051
1063
|
if (t <= 0 || e.length === 0) return !1;
|
|
1052
|
-
const r = t *
|
|
1064
|
+
const r = t * tt;
|
|
1053
1065
|
let n = 0;
|
|
1054
1066
|
for (const i of e) {
|
|
1055
1067
|
const a = i % t;
|
|
1056
1068
|
(a <= r || a >= t - r) && n++;
|
|
1057
1069
|
}
|
|
1058
|
-
return n / e.length >=
|
|
1070
|
+
return n / e.length >= et;
|
|
1059
1071
|
}
|
|
1060
|
-
function
|
|
1072
|
+
function ot(e) {
|
|
1061
1073
|
const t = e.filter((s) => s > 0 && Number.isFinite(s));
|
|
1062
|
-
if (t.length <
|
|
1074
|
+
if (t.length < rt) return null;
|
|
1063
1075
|
const r = Math.min(...t), n = [...new Set(t)].sort((s, o) => s - o);
|
|
1064
1076
|
let i = 1 / 0;
|
|
1065
1077
|
for (let s = 1; s < n.length; s++)
|
|
1066
1078
|
i = Math.min(i, n[s] - n[s - 1]);
|
|
1067
1079
|
const a = Math.min(r, i);
|
|
1068
|
-
return !Number.isFinite(a) || a <= 0 ? null :
|
|
1080
|
+
return !Number.isFinite(a) || a <= 0 ? null : nt(t, a) ? a : null;
|
|
1069
1081
|
}
|
|
1070
|
-
const P = 1024,
|
|
1082
|
+
const P = 1024, it = 3, ee = 10, at = 100, st = 60, ut = 20, de = 2048, V = `
|
|
1071
1083
|
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
|
|
1072
1084
|
var p = array<vec2f, 3>(vec2f(-1., -1.), vec2f(3., -1.), vec2f(-1., 3.));
|
|
1073
1085
|
return vec4f(p[i], 0., 1.);
|
|
1074
1086
|
}`, te = `
|
|
1075
1087
|
@vertex fn vs() -> @builtin(position) vec4f {
|
|
1076
1088
|
return vec4f(2., 2., 0.5, 1.);
|
|
1077
|
-
}`,
|
|
1089
|
+
}`, W = `
|
|
1078
1090
|
@fragment fn fs() -> @location(0) vec4f { return vec4f(0.25, 0.5, 0.75, 1.); }`, re = {
|
|
1079
1091
|
color: { srcFactor: "one", dstFactor: "one", operation: "add" },
|
|
1080
1092
|
alpha: { srcFactor: "one", dstFactor: "one", operation: "add" }
|
|
1081
|
-
},
|
|
1082
|
-
function
|
|
1093
|
+
}, pe = "rgba8unorm";
|
|
1094
|
+
function A(e, t, r) {
|
|
1083
1095
|
const n = typeof t == "string" ? e.createShaderModule({ code: t }) : t;
|
|
1084
1096
|
return e.createRenderPipelineAsync({
|
|
1085
1097
|
layout: "auto",
|
|
@@ -1087,11 +1099,11 @@ function B(e, t, r) {
|
|
|
1087
1099
|
fragment: {
|
|
1088
1100
|
module: n,
|
|
1089
1101
|
entryPoint: "fs",
|
|
1090
|
-
targets: [r ? { format:
|
|
1102
|
+
targets: [r ? { format: pe, blend: r } : { format: pe }]
|
|
1091
1103
|
}
|
|
1092
1104
|
});
|
|
1093
1105
|
}
|
|
1094
|
-
const C = 2e3,
|
|
1106
|
+
const C = 2e3, me = 1e5, ne = [
|
|
1095
1107
|
{
|
|
1096
1108
|
id: "drawcall-overhead",
|
|
1097
1109
|
description: "Empty draw calls — browser validation and driver call cost",
|
|
@@ -1099,7 +1111,7 @@ const C = 2e3, pe = 1e5, ne = [
|
|
|
1099
1111
|
unit: "draws/s",
|
|
1100
1112
|
timingMode: "wall-clock-only",
|
|
1101
1113
|
setup: async (e, t) => {
|
|
1102
|
-
const r = await
|
|
1114
|
+
const r = await A(e, te + W);
|
|
1103
1115
|
return {
|
|
1104
1116
|
record(n, i, a) {
|
|
1105
1117
|
const s = $(n, t, a);
|
|
@@ -1120,7 +1132,7 @@ const C = 2e3, pe = 1e5, ne = [
|
|
|
1120
1132
|
setup: async (e, t) => {
|
|
1121
1133
|
const r = [];
|
|
1122
1134
|
for (let n = 0; n < 8; n++)
|
|
1123
|
-
r.push(await
|
|
1135
|
+
r.push(await A(e, te + `
|
|
1124
1136
|
@fragment fn fs() -> @location(0) vec4f { return vec4f(${(n / 8).toFixed(3)}, 0.5, 0.75, 1.); }`));
|
|
1125
1137
|
return {
|
|
1126
1138
|
record(n, i, a) {
|
|
@@ -1139,7 +1151,7 @@ const C = 2e3, pe = 1e5, ne = [
|
|
|
1139
1151
|
unit: "binds/s",
|
|
1140
1152
|
timingMode: "wall-clock-only",
|
|
1141
1153
|
setup: async (e, t) => {
|
|
1142
|
-
const r = await
|
|
1154
|
+
const r = await A(e, `
|
|
1143
1155
|
struct U { tint: vec4f };
|
|
1144
1156
|
@group(0) @binding(0) var<uniform> u: U;
|
|
1145
1157
|
${te}
|
|
@@ -1174,7 +1186,7 @@ ${te}
|
|
|
1174
1186
|
unit: "MPixel/s",
|
|
1175
1187
|
timingMode: "gpu-preferred",
|
|
1176
1188
|
setup: async (e, t) => {
|
|
1177
|
-
const r = await
|
|
1189
|
+
const r = await A(e, V + W, re);
|
|
1178
1190
|
return {
|
|
1179
1191
|
record(n, i, a) {
|
|
1180
1192
|
const s = $(n, t, a);
|
|
@@ -1194,7 +1206,7 @@ ${te}
|
|
|
1194
1206
|
timingMode: "gpu-preferred",
|
|
1195
1207
|
setup: async (e, t) => {
|
|
1196
1208
|
const r = e.createShaderModule({
|
|
1197
|
-
code:
|
|
1209
|
+
code: V + `
|
|
1198
1210
|
@fragment fn fs(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
1199
1211
|
var p = pos.xyz * 0.001;
|
|
1200
1212
|
var acc = 0.;
|
|
@@ -1204,7 +1216,7 @@ ${te}
|
|
|
1204
1216
|
}
|
|
1205
1217
|
return vec4f(acc * 0.01, p.y, p.z, 1.);
|
|
1206
1218
|
}`
|
|
1207
|
-
}), n = await
|
|
1219
|
+
}), n = await A(e, r, re);
|
|
1208
1220
|
return {
|
|
1209
1221
|
record(i, a, s) {
|
|
1210
1222
|
const o = $(i, t, s);
|
|
@@ -1218,7 +1230,7 @@ ${te}
|
|
|
1218
1230
|
{
|
|
1219
1231
|
id: "triangle-throughput",
|
|
1220
1232
|
description: "Many small triangles — geometry throughput",
|
|
1221
|
-
unitWorkload:
|
|
1233
|
+
unitWorkload: me,
|
|
1222
1234
|
unit: "MTri/s",
|
|
1223
1235
|
timingMode: "gpu-preferred",
|
|
1224
1236
|
setup: async (e, t) => {
|
|
@@ -1233,13 +1245,13 @@ ${te}
|
|
|
1233
1245
|
var off = array<vec2f, 3>(vec2f(0., 0.), vec2f(0.0015, 0.), vec2f(0., 0.0015));
|
|
1234
1246
|
return vec4f(gx + off[corner].x, gy + off[corner].y, 0.5, 1.);
|
|
1235
1247
|
}
|
|
1236
|
-
${
|
|
1237
|
-
}), n = await
|
|
1248
|
+
${W}`
|
|
1249
|
+
}), n = await A(e, r);
|
|
1238
1250
|
return {
|
|
1239
1251
|
record(i, a, s) {
|
|
1240
1252
|
const o = $(i, t, s);
|
|
1241
1253
|
o.setPipeline(n);
|
|
1242
|
-
for (let u = 0; u < a; u++) o.draw(
|
|
1254
|
+
for (let u = 0; u < a; u++) o.draw(me * 3);
|
|
1243
1255
|
o.end();
|
|
1244
1256
|
}
|
|
1245
1257
|
};
|
|
@@ -1263,7 +1275,7 @@ ${z}`
|
|
|
1263
1275
|
code: `
|
|
1264
1276
|
@group(0) @binding(0) var t: texture_2d<f32>;
|
|
1265
1277
|
@group(0) @binding(1) var s: sampler;
|
|
1266
|
-
${
|
|
1278
|
+
${V}
|
|
1267
1279
|
@fragment fn fs(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
1268
1280
|
var acc = vec4f(0.);
|
|
1269
1281
|
let base = pos.xy / ${P}.;
|
|
@@ -1274,7 +1286,7 @@ ${W}
|
|
|
1274
1286
|
}
|
|
1275
1287
|
return acc * 0.03125;
|
|
1276
1288
|
}`
|
|
1277
|
-
}), a = await
|
|
1289
|
+
}), a = await A(e, i, re), s = e.createSampler({ magFilter: "linear", minFilter: "linear" }), o = e.createBindGroup({
|
|
1278
1290
|
layout: a.getBindGroupLayout(0),
|
|
1279
1291
|
entries: [
|
|
1280
1292
|
{ binding: 0, resource: r.createView() },
|
|
@@ -1293,7 +1305,7 @@ ${W}
|
|
|
1293
1305
|
}
|
|
1294
1306
|
}
|
|
1295
1307
|
];
|
|
1296
|
-
function
|
|
1308
|
+
function ct() {
|
|
1297
1309
|
let e = 1 / 0;
|
|
1298
1310
|
for (let t = 0; t < 24; t++) {
|
|
1299
1311
|
const r = performance.now();
|
|
@@ -1303,7 +1315,7 @@ function ut() {
|
|
|
1303
1315
|
}
|
|
1304
1316
|
return Number.isFinite(e) && e > 0 ? e : 0;
|
|
1305
1317
|
}
|
|
1306
|
-
async function
|
|
1318
|
+
async function lt(e, t) {
|
|
1307
1319
|
if (!t.available) return null;
|
|
1308
1320
|
const r = e.createTexture({
|
|
1309
1321
|
size: [256, 256],
|
|
@@ -1312,7 +1324,7 @@ async function ct(e, t) {
|
|
|
1312
1324
|
}), n = r.createView();
|
|
1313
1325
|
let i;
|
|
1314
1326
|
try {
|
|
1315
|
-
i = await
|
|
1327
|
+
i = await A(e, V + W);
|
|
1316
1328
|
} catch {
|
|
1317
1329
|
return v(r), null;
|
|
1318
1330
|
}
|
|
@@ -1331,16 +1343,16 @@ async function ct(e, t) {
|
|
|
1331
1343
|
if (u >= 4 && new Set(a.filter((c) => c > 0)).size >= 2) break;
|
|
1332
1344
|
s *= 4;
|
|
1333
1345
|
}
|
|
1334
|
-
return v(r),
|
|
1346
|
+
return v(r), ot(a);
|
|
1335
1347
|
}
|
|
1336
|
-
async function
|
|
1348
|
+
async function ft(e, t, r) {
|
|
1337
1349
|
const n = performance.now(), i = j.create(e), a = e.createTexture({
|
|
1338
1350
|
size: [P, P],
|
|
1339
1351
|
format: "rgba8unorm",
|
|
1340
1352
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1341
|
-
}), s = a.createView(), o = await
|
|
1353
|
+
}), s = a.createView(), o = await lt(e, i), u = ct(), c = [];
|
|
1342
1354
|
for (let l = 0; l < ne.length; l++)
|
|
1343
|
-
c.push(await
|
|
1355
|
+
c.push(await dt(
|
|
1344
1356
|
e,
|
|
1345
1357
|
ne[l],
|
|
1346
1358
|
s,
|
|
@@ -1357,7 +1369,7 @@ async function lt(e, t, r) {
|
|
|
1357
1369
|
totalMs: Math.round(performance.now() - n)
|
|
1358
1370
|
};
|
|
1359
1371
|
}
|
|
1360
|
-
async function
|
|
1372
|
+
async function dt(e, t, r, n, i, a, s) {
|
|
1361
1373
|
const o = {
|
|
1362
1374
|
id: t.id,
|
|
1363
1375
|
description: t.description,
|
|
@@ -1372,54 +1384,54 @@ async function ft(e, t, r, n, i, a, s) {
|
|
|
1372
1384
|
try {
|
|
1373
1385
|
u = await t.setup(e, r);
|
|
1374
1386
|
} catch (l) {
|
|
1375
|
-
return { ...o, failed: `setup failed: ${
|
|
1387
|
+
return { ...o, failed: `setup failed: ${ge(l)}` };
|
|
1376
1388
|
}
|
|
1377
1389
|
const c = t.timingMode === "gpu-preferred" && n.available;
|
|
1378
1390
|
try {
|
|
1379
|
-
for (let m = 0; m <
|
|
1380
|
-
const
|
|
1381
|
-
u.record(
|
|
1391
|
+
for (let m = 0; m < it; m++) {
|
|
1392
|
+
const k = e.createCommandEncoder();
|
|
1393
|
+
u.record(k, 1), e.queue.submit([k.finish()]);
|
|
1382
1394
|
}
|
|
1383
1395
|
await e.queue.onSubmittedWorkDone();
|
|
1384
|
-
const l = c ? a ? Math.max(ee, a *
|
|
1396
|
+
const l = c ? a ? Math.max(ee, a * at / 1e6) : ee : Math.max(ee, s * st);
|
|
1385
1397
|
let f = 1;
|
|
1386
1398
|
for (let m = 0; m < 8; m++) {
|
|
1387
|
-
const { ms:
|
|
1388
|
-
if (
|
|
1389
|
-
const U =
|
|
1390
|
-
f = Math.min(
|
|
1399
|
+
const { ms: k } = await he(e, u, f, n, c);
|
|
1400
|
+
if (k >= l || f >= de) break;
|
|
1401
|
+
const U = k > 1e-3 ? Math.ceil(l / k) : 8;
|
|
1402
|
+
f = Math.min(de, f * Math.max(2, Math.min(16, U)));
|
|
1391
1403
|
}
|
|
1392
1404
|
const p = [];
|
|
1393
1405
|
let h = 0;
|
|
1394
1406
|
for (let m = 0; m < i; m++) {
|
|
1395
|
-
const { ms:
|
|
1396
|
-
p.push(
|
|
1407
|
+
const { ms: k, fromGpu: U } = await he(e, u, f, n, c);
|
|
1408
|
+
p.push(k), U && h++;
|
|
1397
1409
|
}
|
|
1398
1410
|
if (u.dispose?.(), p.length === 0)
|
|
1399
1411
|
return { ...o, failed: "no measurements were obtained" };
|
|
1400
|
-
const w = h > p.length / 2, g = w ? p :
|
|
1412
|
+
const w = h > p.length / 2, g = w ? p : pt(p), T = Ze(g), E = t.unitWorkload * f, S = {
|
|
1401
1413
|
...o,
|
|
1402
1414
|
medianMs: q(T, 4),
|
|
1403
1415
|
minMs: q(Math.min(...g), 4),
|
|
1404
|
-
variation: q(
|
|
1416
|
+
variation: q(Je(g), 3),
|
|
1405
1417
|
timing: w ? "timestamp-query" : "wall-clock",
|
|
1406
1418
|
samples: g.length,
|
|
1407
1419
|
repetitions: f
|
|
1408
1420
|
}, R = w ? a != null ? a / 1e6 : null : s > 0 ? s : null;
|
|
1409
1421
|
if (R) {
|
|
1410
1422
|
const m = T / R;
|
|
1411
|
-
|
|
1423
|
+
S.ticks = q(m, 1), S.quantized = m < ut;
|
|
1412
1424
|
}
|
|
1413
1425
|
if (T > 0) {
|
|
1414
1426
|
const m = E / (T / 1e3);
|
|
1415
|
-
|
|
1427
|
+
S.throughput = q(mt(m, t.unit), 2), S.throughputUnit = t.unit;
|
|
1416
1428
|
}
|
|
1417
|
-
return
|
|
1429
|
+
return S;
|
|
1418
1430
|
} catch (l) {
|
|
1419
|
-
return u.dispose?.(), { ...o, failed: `run failed: ${
|
|
1431
|
+
return u.dispose?.(), { ...o, failed: `run failed: ${ge(l)}` };
|
|
1420
1432
|
}
|
|
1421
1433
|
}
|
|
1422
|
-
async function
|
|
1434
|
+
async function he(e, t, r, n, i) {
|
|
1423
1435
|
const a = e.createCommandEncoder(), s = i ? n.writes() : void 0, o = performance.now();
|
|
1424
1436
|
t.record(a, r, s), s && n.resolve(a), e.queue.submit([a.finish()]), await e.queue.onSubmittedWorkDone();
|
|
1425
1437
|
const u = performance.now() - o;
|
|
@@ -1429,7 +1441,7 @@ async function me(e, t, r, n, i) {
|
|
|
1429
1441
|
}
|
|
1430
1442
|
return { ms: u, fromGpu: !1 };
|
|
1431
1443
|
}
|
|
1432
|
-
function
|
|
1444
|
+
function pt(e) {
|
|
1433
1445
|
return e.length < 5 ? e : [...e].sort((r, n) => r - n).slice(1, -1);
|
|
1434
1446
|
}
|
|
1435
1447
|
function $(e, t, r) {
|
|
@@ -1443,20 +1455,20 @@ function $(e, t, r) {
|
|
|
1443
1455
|
};
|
|
1444
1456
|
return r && (n.timestampWrites = r), e.beginRenderPass(n);
|
|
1445
1457
|
}
|
|
1446
|
-
function
|
|
1458
|
+
function mt(e, t) {
|
|
1447
1459
|
return t.startsWith("M") ? e / 1e6 : t.startsWith("G") ? e / 1e9 : e;
|
|
1448
1460
|
}
|
|
1449
1461
|
function q(e, t) {
|
|
1450
1462
|
const r = 10 ** t;
|
|
1451
1463
|
return Math.round(e * r) / r;
|
|
1452
1464
|
}
|
|
1453
|
-
function
|
|
1465
|
+
function ge(e) {
|
|
1454
1466
|
return e instanceof Error ? `${e.name}: ${e.message}` : String(e);
|
|
1455
1467
|
}
|
|
1456
|
-
function
|
|
1457
|
-
const a = [], s =
|
|
1468
|
+
function ht(e, t, r, n, i) {
|
|
1469
|
+
const a = [], s = Oe(i);
|
|
1458
1470
|
for (const o of e) {
|
|
1459
|
-
const u =
|
|
1471
|
+
const u = Fe(o.format);
|
|
1460
1472
|
if (o.featureDeclared && !o.creatable) {
|
|
1461
1473
|
a.push({
|
|
1462
1474
|
kind: "format-declared-not-usable",
|
|
@@ -1477,7 +1489,7 @@ function mt(e, t, r, n, i) {
|
|
|
1477
1489
|
detail: `${o.requiresFeature} is not declared, yet texture creation succeeds`,
|
|
1478
1490
|
severity: "note"
|
|
1479
1491
|
}), !u || !o.creatable) continue;
|
|
1480
|
-
const c =
|
|
1492
|
+
const c = Ce(u, i);
|
|
1481
1493
|
c.renderable && !o.renderable && a.push({
|
|
1482
1494
|
kind: "format-declared-not-usable",
|
|
1483
1495
|
subject: o.format,
|
|
@@ -1506,7 +1518,7 @@ function mt(e, t, r, n, i) {
|
|
|
1506
1518
|
a.push({
|
|
1507
1519
|
kind: "limit-not-honored",
|
|
1508
1520
|
subject: o.limit,
|
|
1509
|
-
detail: `declares ${
|
|
1521
|
+
detail: `declares ${ve(o.declared)} but only reaches ${ve(o.achieved)}` + ` (${(u * 100).toFixed(0)}%). ${o.error?.message ?? ""}`.trimEnd(),
|
|
1510
1522
|
// Below half, code written against the declared value simply dies.
|
|
1511
1523
|
severity: u < 0.5 ? "breaking" : "degraded"
|
|
1512
1524
|
});
|
|
@@ -1515,12 +1527,12 @@ function mt(e, t, r, n, i) {
|
|
|
1515
1527
|
o.skipped || (o.compiled ? o.pipelineCreated || a.push({
|
|
1516
1528
|
kind: "shader-pipeline-failure",
|
|
1517
1529
|
subject: o.id,
|
|
1518
|
-
detail: `${o.description} — compiled, but pipeline creation failed: ${
|
|
1530
|
+
detail: `${o.description} — compiled, but pipeline creation failed: ${be(o)}`,
|
|
1519
1531
|
severity: "breaking"
|
|
1520
1532
|
}) : a.push({
|
|
1521
1533
|
kind: "shader-compile-failure",
|
|
1522
1534
|
subject: o.id,
|
|
1523
|
-
detail: `${o.description} — compilation failed: ${
|
|
1535
|
+
detail: `${o.description} — compilation failed: ${be(o)}`,
|
|
1524
1536
|
severity: "breaking"
|
|
1525
1537
|
}));
|
|
1526
1538
|
if (n)
|
|
@@ -1543,14 +1555,14 @@ function mt(e, t, r, n, i) {
|
|
|
1543
1555
|
});
|
|
1544
1556
|
return a;
|
|
1545
1557
|
}
|
|
1546
|
-
function
|
|
1558
|
+
function be(e) {
|
|
1547
1559
|
return e.messages.find((t) => t.type === "error")?.message ?? "no error message";
|
|
1548
1560
|
}
|
|
1549
|
-
function
|
|
1561
|
+
function ve(e) {
|
|
1550
1562
|
return e >= 1024 * 1024 * 1024 ? `${(e / 1024 / 1024 / 1024).toFixed(2)}GB` : e >= 1024 * 1024 ? `${(e / 1024 / 1024).toFixed(1)}MB` : e >= 1024 ? `${(e / 1024).toFixed(1)}KB` : String(e);
|
|
1551
1563
|
}
|
|
1552
|
-
const
|
|
1553
|
-
function
|
|
1564
|
+
const gt = 16;
|
|
1565
|
+
function bt(e) {
|
|
1554
1566
|
const t = e.browserVersion.split(".")[0] ?? "";
|
|
1555
1567
|
return [
|
|
1556
1568
|
e.browser,
|
|
@@ -1561,17 +1573,17 @@ function gt(e) {
|
|
|
1561
1573
|
e.description
|
|
1562
1574
|
].join("|");
|
|
1563
1575
|
}
|
|
1564
|
-
async function
|
|
1565
|
-
const t =
|
|
1576
|
+
async function ye(e) {
|
|
1577
|
+
const t = bt(e), r = globalThis.crypto?.subtle;
|
|
1566
1578
|
if (r)
|
|
1567
1579
|
try {
|
|
1568
1580
|
const n = await r.digest("SHA-256", new TextEncoder().encode(t));
|
|
1569
|
-
return
|
|
1581
|
+
return yt(new Uint8Array(n).subarray(0, gt));
|
|
1570
1582
|
} catch {
|
|
1571
1583
|
}
|
|
1572
|
-
return
|
|
1584
|
+
return vt(t);
|
|
1573
1585
|
}
|
|
1574
|
-
function
|
|
1586
|
+
function vt(e) {
|
|
1575
1587
|
const r = [2166136261, 16777619, 3421674724, 2216829733];
|
|
1576
1588
|
for (let n = 0; n < e.length; n++) {
|
|
1577
1589
|
const i = e.charCodeAt(n);
|
|
@@ -1580,19 +1592,19 @@ function bt(e) {
|
|
|
1580
1592
|
}
|
|
1581
1593
|
return r.map((n) => n.toString(16).padStart(8, "0")).join("");
|
|
1582
1594
|
}
|
|
1583
|
-
function
|
|
1595
|
+
function yt(e) {
|
|
1584
1596
|
let t = "";
|
|
1585
1597
|
for (const r of e) t += r.toString(16).padStart(2, "0");
|
|
1586
1598
|
return t;
|
|
1587
1599
|
}
|
|
1588
1600
|
const F = { formats: 0.25, shaders: 0.1, limits: 0.15, bench: 0.5 };
|
|
1589
|
-
async function
|
|
1601
|
+
async function _t(e = {}) {
|
|
1590
1602
|
const {
|
|
1591
1603
|
powerPreference: t,
|
|
1592
1604
|
benchmark: r = !0,
|
|
1593
1605
|
onProgress: n,
|
|
1594
1606
|
formats: i
|
|
1595
|
-
} = e, a =
|
|
1607
|
+
} = e, a = wt(e.benchSamples ?? 7, 1, 99), s = performance.now(), o = await Ae(), u = {
|
|
1596
1608
|
schema: 5,
|
|
1597
1609
|
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1598
1610
|
fingerprint: "",
|
|
@@ -1606,12 +1618,12 @@ async function Rt(e = {}) {
|
|
|
1606
1618
|
};
|
|
1607
1619
|
let c;
|
|
1608
1620
|
try {
|
|
1609
|
-
c = await
|
|
1621
|
+
c = await Me(t);
|
|
1610
1622
|
} catch (b) {
|
|
1611
1623
|
return {
|
|
1612
1624
|
...u,
|
|
1613
1625
|
unavailable: b instanceof D ? b.message : oe(b),
|
|
1614
|
-
fingerprint: await
|
|
1626
|
+
fingerprint: await ye({
|
|
1615
1627
|
browser: o.browser,
|
|
1616
1628
|
browserVersion: o.browserVersion,
|
|
1617
1629
|
vendor: "",
|
|
@@ -1629,28 +1641,28 @@ async function Rt(e = {}) {
|
|
|
1629
1641
|
});
|
|
1630
1642
|
const T = new Set(p.features);
|
|
1631
1643
|
let E = 0;
|
|
1632
|
-
const
|
|
1644
|
+
const S = (b, Y) => {
|
|
1633
1645
|
try {
|
|
1634
|
-
n?.(b,
|
|
1646
|
+
n?.(b, Y);
|
|
1635
1647
|
} catch {
|
|
1636
1648
|
}
|
|
1637
|
-
}, R = (b,
|
|
1649
|
+
}, R = (b, Y) => (ke) => S(b, E + Y * ke), m = {
|
|
1638
1650
|
formats: [],
|
|
1639
1651
|
shaders: [],
|
|
1640
1652
|
limits: [],
|
|
1641
1653
|
deviceLost: !1
|
|
1642
1654
|
};
|
|
1643
1655
|
try {
|
|
1644
|
-
|
|
1656
|
+
S("formats", E), m.formats = await Ne(
|
|
1645
1657
|
l,
|
|
1646
1658
|
T,
|
|
1647
1659
|
i,
|
|
1648
1660
|
R("formats", F.formats)
|
|
1649
|
-
), E += F.formats,
|
|
1661
|
+
), E += F.formats, S("shaders", E), m.shaders = await He(
|
|
1650
1662
|
l,
|
|
1651
1663
|
T,
|
|
1652
1664
|
R("shaders", F.shaders)
|
|
1653
|
-
), E += F.shaders,
|
|
1665
|
+
), E += F.shaders, S("limits", E), m.limits = await Xe(
|
|
1654
1666
|
l,
|
|
1655
1667
|
p.limits,
|
|
1656
1668
|
R("limits", F.limits)
|
|
@@ -1658,21 +1670,21 @@ async function Rt(e = {}) {
|
|
|
1658
1670
|
} catch (b) {
|
|
1659
1671
|
m.deviceLost = !0, m.deviceLostReason = g ?? oe(b);
|
|
1660
1672
|
}
|
|
1661
|
-
let
|
|
1673
|
+
let k = null;
|
|
1662
1674
|
if (r && !m.deviceLost) {
|
|
1663
|
-
|
|
1675
|
+
S("benchmarks", E);
|
|
1664
1676
|
try {
|
|
1665
|
-
|
|
1677
|
+
k = await ft(l, a, R("benchmarks", F.bench));
|
|
1666
1678
|
} catch (b) {
|
|
1667
1679
|
m.deviceLostReason = g ?? oe(b);
|
|
1668
1680
|
}
|
|
1669
1681
|
}
|
|
1670
|
-
|
|
1671
|
-
const U =
|
|
1682
|
+
S("done", 1), g && (m.deviceLost = !0, m.deviceLostReason = g);
|
|
1683
|
+
const U = ht(
|
|
1672
1684
|
m.formats,
|
|
1673
1685
|
m.shaders,
|
|
1674
1686
|
m.limits,
|
|
1675
|
-
|
|
1687
|
+
k,
|
|
1676
1688
|
T
|
|
1677
1689
|
);
|
|
1678
1690
|
for (const b of h)
|
|
@@ -1682,9 +1694,9 @@ async function Rt(e = {}) {
|
|
|
1682
1694
|
detail: "requestDevice refused values the adapter itself advertised",
|
|
1683
1695
|
severity: "degraded"
|
|
1684
1696
|
});
|
|
1685
|
-
const
|
|
1697
|
+
const Se = {
|
|
1686
1698
|
...u,
|
|
1687
|
-
fingerprint: await
|
|
1699
|
+
fingerprint: await ye({
|
|
1688
1700
|
browser: o.browser,
|
|
1689
1701
|
browserVersion: o.browserVersion,
|
|
1690
1702
|
vendor: f.vendor,
|
|
@@ -1695,19 +1707,19 @@ async function Rt(e = {}) {
|
|
|
1695
1707
|
adapter: f,
|
|
1696
1708
|
declared: p,
|
|
1697
1709
|
verified: m,
|
|
1698
|
-
benchmarks:
|
|
1710
|
+
benchmarks: k,
|
|
1699
1711
|
discrepancies: U,
|
|
1700
1712
|
elapsedMs: Math.round(performance.now() - s)
|
|
1701
1713
|
};
|
|
1702
|
-
return l.destroy(),
|
|
1714
|
+
return l.destroy(), Se;
|
|
1703
1715
|
}
|
|
1704
|
-
function
|
|
1716
|
+
function wt(e, t, r) {
|
|
1705
1717
|
return Number.isFinite(e) ? Math.min(r, Math.max(t, Math.round(e))) : t;
|
|
1706
1718
|
}
|
|
1707
1719
|
function oe(e) {
|
|
1708
1720
|
return e instanceof Error ? `${e.name}: ${e.message}` : String(e);
|
|
1709
1721
|
}
|
|
1710
|
-
function
|
|
1722
|
+
function xt(e) {
|
|
1711
1723
|
return {
|
|
1712
1724
|
profile: e,
|
|
1713
1725
|
features: new Set(e.declared.features),
|
|
@@ -1716,7 +1728,7 @@ function wt(e) {
|
|
|
1716
1728
|
benchmarks: new Map((e.benchmarks?.results ?? []).map((t) => [t.id, t]))
|
|
1717
1729
|
};
|
|
1718
1730
|
}
|
|
1719
|
-
const
|
|
1731
|
+
const St = [
|
|
1720
1732
|
"creatable",
|
|
1721
1733
|
"sampleable",
|
|
1722
1734
|
"renderable",
|
|
@@ -1724,7 +1736,7 @@ const xt = [
|
|
|
1724
1736
|
"storageWritable",
|
|
1725
1737
|
"multisample4x"
|
|
1726
1738
|
], kt = 0.15;
|
|
1727
|
-
function
|
|
1739
|
+
function Gt(e) {
|
|
1728
1740
|
const t = [], r = [], n = [], i = /* @__PURE__ */ new Set();
|
|
1729
1741
|
e.forEach((s, o) => {
|
|
1730
1742
|
if (s.unavailable) {
|
|
@@ -1746,28 +1758,28 @@ function _t(e) {
|
|
|
1746
1758
|
const u = typeof s.schema == "number" ? s.schema : 0;
|
|
1747
1759
|
t.push({
|
|
1748
1760
|
fingerprint: s.fingerprint,
|
|
1749
|
-
label:
|
|
1761
|
+
label: Mt(s),
|
|
1750
1762
|
mobile: s.environment.mobile,
|
|
1751
1763
|
index: o,
|
|
1752
1764
|
schema: u,
|
|
1753
1765
|
staleBenchmarks: u < 2
|
|
1754
1766
|
}), r.push(s);
|
|
1755
1767
|
});
|
|
1756
|
-
const a = r.map(
|
|
1768
|
+
const a = r.map(xt);
|
|
1757
1769
|
return {
|
|
1758
1770
|
devices: t,
|
|
1759
|
-
...
|
|
1760
|
-
formats:
|
|
1761
|
-
limits:
|
|
1762
|
-
benchmarks:
|
|
1771
|
+
...Pt(a),
|
|
1772
|
+
formats: Et(a),
|
|
1773
|
+
limits: Tt(a),
|
|
1774
|
+
benchmarks: Bt(a),
|
|
1763
1775
|
excluded: n
|
|
1764
1776
|
};
|
|
1765
1777
|
}
|
|
1766
|
-
function
|
|
1778
|
+
function Mt(e) {
|
|
1767
1779
|
const t = [e.adapter?.vendor, e.adapter?.architecture].filter(Boolean).join(" ") || e.adapter?.description || "unknown GPU", r = [e.environment.browser, At(e.environment.browserVersion)].filter(Boolean).join(" ");
|
|
1768
1780
|
return r ? `${t} / ${r}` : t;
|
|
1769
1781
|
}
|
|
1770
|
-
function
|
|
1782
|
+
function Pt(e) {
|
|
1771
1783
|
const t = /* @__PURE__ */ new Set();
|
|
1772
1784
|
for (const i of e) for (const a of i.features) t.add(a);
|
|
1773
1785
|
const r = [], n = [];
|
|
@@ -1779,13 +1791,13 @@ function Mt(e) {
|
|
|
1779
1791
|
}
|
|
1780
1792
|
return { features: r, sharedFeatures: n };
|
|
1781
1793
|
}
|
|
1782
|
-
function
|
|
1794
|
+
function Et(e) {
|
|
1783
1795
|
const t = /* @__PURE__ */ new Set();
|
|
1784
1796
|
for (const n of e)
|
|
1785
1797
|
for (const i of n.formats.keys()) t.add(i);
|
|
1786
1798
|
const r = [];
|
|
1787
1799
|
for (const n of [...t].sort())
|
|
1788
|
-
for (const i of
|
|
1800
|
+
for (const i of St) {
|
|
1789
1801
|
const a = [], s = [];
|
|
1790
1802
|
for (const o of e) {
|
|
1791
1803
|
const u = o.formats.get(n);
|
|
@@ -1795,7 +1807,7 @@ function Pt(e) {
|
|
|
1795
1807
|
}
|
|
1796
1808
|
return r;
|
|
1797
1809
|
}
|
|
1798
|
-
function
|
|
1810
|
+
function Tt(e) {
|
|
1799
1811
|
const t = /* @__PURE__ */ new Set();
|
|
1800
1812
|
for (const n of e) for (const i of n.limits.keys()) t.add(i);
|
|
1801
1813
|
const r = [];
|
|
@@ -1812,7 +1824,7 @@ function Et(e) {
|
|
|
1812
1824
|
}
|
|
1813
1825
|
return r.sort((n, i) => i.ratio - n.ratio);
|
|
1814
1826
|
}
|
|
1815
|
-
function
|
|
1827
|
+
function Bt(e) {
|
|
1816
1828
|
const t = /* @__PURE__ */ new Map();
|
|
1817
1829
|
for (const n of e)
|
|
1818
1830
|
for (const [i, a] of n.benchmarks)
|
|
@@ -1849,7 +1861,7 @@ function Tt(e) {
|
|
|
1849
1861
|
}
|
|
1850
1862
|
return r.sort((n, i) => (i.ratio ?? 0) - (n.ratio ?? 0));
|
|
1851
1863
|
}
|
|
1852
|
-
function
|
|
1864
|
+
function Ft(e, t = {}) {
|
|
1853
1865
|
const r = Math.max(1, t.limit ?? 20), n = [], i = (o) => o.slice(0, 8), a = (o) => ({
|
|
1854
1866
|
shown: o.slice(0, r),
|
|
1855
1867
|
hidden: Math.max(0, o.length - r)
|
|
@@ -1910,19 +1922,19 @@ function Gt(e, t = {}) {
|
|
|
1910
1922
|
function At(e) {
|
|
1911
1923
|
return e.split(".")[0] ?? "";
|
|
1912
1924
|
}
|
|
1913
|
-
function
|
|
1925
|
+
function Ut(e) {
|
|
1914
1926
|
return e.unavailable !== void 0;
|
|
1915
1927
|
}
|
|
1916
|
-
function
|
|
1928
|
+
function Ct(e) {
|
|
1917
1929
|
return e.discrepancies.filter((t) => t.severity === "breaking");
|
|
1918
1930
|
}
|
|
1919
|
-
function
|
|
1931
|
+
function Ot(e) {
|
|
1920
1932
|
return (e.verified?.formats ?? []).filter((t) => t.renderable).map((t) => t.format);
|
|
1921
1933
|
}
|
|
1922
|
-
function
|
|
1934
|
+
function qt(e) {
|
|
1923
1935
|
return (e.verified?.formats ?? []).filter((t) => t.sampleable).map((t) => t.format);
|
|
1924
1936
|
}
|
|
1925
|
-
function
|
|
1937
|
+
function Lt(e, t, r = "render") {
|
|
1926
1938
|
const n = e.verified?.formats ?? [];
|
|
1927
1939
|
for (const i of t) {
|
|
1928
1940
|
const a = n.find((s) => s.format === i);
|
|
@@ -1931,23 +1943,23 @@ function qt(e, t, r = "render") {
|
|
|
1931
1943
|
}
|
|
1932
1944
|
return null;
|
|
1933
1945
|
}
|
|
1934
|
-
function
|
|
1946
|
+
function Nt(e, t) {
|
|
1935
1947
|
return e.benchmarks?.results.find((r) => r.id === t) ?? null;
|
|
1936
1948
|
}
|
|
1937
1949
|
export {
|
|
1938
1950
|
ie as FORMATS,
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1951
|
+
Rt as MIN_COMPARABLE_BENCHMARK_SCHEMA,
|
|
1952
|
+
$t as SCHEMA_VERSION,
|
|
1953
|
+
Nt as benchmark,
|
|
1954
|
+
Ct as breakingIssues,
|
|
1955
|
+
Gt as compareProfiles,
|
|
1956
|
+
Mt as describeDevice,
|
|
1957
|
+
Fe as findMeta,
|
|
1958
|
+
Ft as formatComparison,
|
|
1959
|
+
Ut as isUnavailable,
|
|
1960
|
+
Lt as pickFormat,
|
|
1961
|
+
_t as probe,
|
|
1962
|
+
Ot as renderableFormats,
|
|
1963
|
+
qt as sampleableFormats
|
|
1952
1964
|
};
|
|
1953
1965
|
//# sourceMappingURL=gpu-atlas.js.map
|