gpu-atlas 0.2.1 → 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 +137 -130
- package/dist/gpu-atlas.js.map +1 -1
- package/package.json +1 -1
package/dist/gpu-atlas.js
CHANGED
|
@@ -4,7 +4,7 @@ class D extends Error {
|
|
|
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,9 +96,11 @@ 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
|
}
|
|
@@ -116,16 +118,16 @@ async function Ae() {
|
|
|
116
118
|
devicePixelRatio: typeof devicePixelRatio == "number" ? devicePixelRatio : 1
|
|
117
119
|
};
|
|
118
120
|
}
|
|
119
|
-
function
|
|
121
|
+
function ae(e) {
|
|
120
122
|
const t = e?.filter((r) => !/Not.?A.?Brand/i.test(r.brand));
|
|
121
123
|
if (t?.length)
|
|
122
124
|
return t.find((r) => !/^Chromium$/i.test(r.brand)) ?? t[0];
|
|
123
125
|
}
|
|
124
126
|
function $e(e) {
|
|
125
|
-
return /Mobi|Android|iPhone|iPad|iPod/i.test(e) ? !0 :
|
|
127
|
+
return /Mobi|Android|iPhone|iPad|iPod/i.test(e) ? !0 : we(e);
|
|
126
128
|
}
|
|
127
129
|
function Re(e) {
|
|
128
|
-
if (
|
|
130
|
+
if (we(e)) return "iPadOS";
|
|
129
131
|
if (/iPhone|iPod/i.test(e)) return "iOS";
|
|
130
132
|
if (/iPad/i.test(e)) return "iPadOS";
|
|
131
133
|
if (/Android/i.test(e)) return "Android";
|
|
@@ -133,14 +135,19 @@ function Re(e) {
|
|
|
133
135
|
if (/Windows/i.test(e)) return "Windows";
|
|
134
136
|
if (/Linux/i.test(e)) return "Linux";
|
|
135
137
|
}
|
|
136
|
-
function
|
|
138
|
+
function we(e) {
|
|
137
139
|
return /Macintosh|Mac OS X/i.test(e) ? (typeof navigator < "u" ? navigator.maxTouchPoints ?? 0 : 0) > 1 : !1;
|
|
138
140
|
}
|
|
139
141
|
function _e(e) {
|
|
140
142
|
const t = [
|
|
141
143
|
["Edge", /Edg(?:e|A|iOS)?\/([\d.]+)/],
|
|
142
144
|
["Opera", /OPR\/([\d.]+)/],
|
|
143
|
-
["
|
|
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.]+)/],
|
|
144
151
|
["Chrome", /(?:Chrome|CriOS)\/([\d.]+)/],
|
|
145
152
|
["Safari", /Version\/([\d.]+).*Safari/]
|
|
146
153
|
];
|
|
@@ -150,17 +157,17 @@ function _e(e) {
|
|
|
150
157
|
}
|
|
151
158
|
return { browser: "unknown", version: "" };
|
|
152
159
|
}
|
|
153
|
-
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 = [
|
|
154
161
|
// ── 8-bit ──
|
|
155
|
-
d("r8unorm", "f32", !0,
|
|
162
|
+
d("r8unorm", "f32", !0, B),
|
|
156
163
|
d("r8snorm", "f32", !0, I),
|
|
157
164
|
d("r8uint", "u32", !1, y),
|
|
158
165
|
d("r8sint", "i32", !1, y),
|
|
159
166
|
// ── 16-bit ──
|
|
160
167
|
d("r16uint", "u32", !1, y),
|
|
161
168
|
d("r16sint", "i32", !1, y),
|
|
162
|
-
d("r16float", "f32", !0,
|
|
163
|
-
d("rg8unorm", "f32", !0,
|
|
169
|
+
d("r16float", "f32", !0, B),
|
|
170
|
+
d("rg8unorm", "f32", !0, B),
|
|
164
171
|
d("rg8snorm", "f32", !0, I),
|
|
165
172
|
d("rg8uint", "u32", !1, y),
|
|
166
173
|
d("rg8sint", "i32", !1, y),
|
|
@@ -171,16 +178,16 @@ const d = (e, t, r, n, i) => ({ format: e, kind: "color", texel: t, filterable:
|
|
|
171
178
|
d("r32float", "f32", !1, x),
|
|
172
179
|
d("rg16uint", "u32", !1, y),
|
|
173
180
|
d("rg16sint", "i32", !1, y),
|
|
174
|
-
d("rg16float", "f32", !0,
|
|
175
|
-
d("rgba8unorm", "f32", !0,
|
|
176
|
-
d("rgba8unorm-srgb", "f32", !0,
|
|
181
|
+
d("rg16float", "f32", !0, B),
|
|
182
|
+
d("rgba8unorm", "f32", !0, se),
|
|
183
|
+
d("rgba8unorm-srgb", "f32", !0, B),
|
|
177
184
|
d("rgba8snorm", "f32", !0, Ge),
|
|
178
185
|
d("rgba8uint", "u32", !1, x),
|
|
179
186
|
d("rgba8sint", "i32", !1, x),
|
|
180
|
-
d("bgra8unorm", "f32", !0,
|
|
181
|
-
d("bgra8unorm-srgb", "f32", !0,
|
|
187
|
+
d("bgra8unorm", "f32", !0, B),
|
|
188
|
+
d("bgra8unorm-srgb", "f32", !0, B),
|
|
182
189
|
d("rgb10a2uint", "u32", !1, y),
|
|
183
|
-
d("rgb10a2unorm", "f32", !0,
|
|
190
|
+
d("rgb10a2unorm", "f32", !0, B),
|
|
184
191
|
// rg11b10ufloat rendering sits behind its own feature gate
|
|
185
192
|
d("rg11b10ufloat", "f32", !0, I),
|
|
186
193
|
// ── 64-bit ──
|
|
@@ -189,7 +196,7 @@ const d = (e, t, r, n, i) => ({ format: e, kind: "color", texel: t, filterable:
|
|
|
189
196
|
d("rg32float", "f32", !1, x),
|
|
190
197
|
d("rgba16uint", "u32", !1, x),
|
|
191
198
|
d("rgba16sint", "i32", !1, x),
|
|
192
|
-
d("rgba16float", "f32", !0,
|
|
199
|
+
d("rgba16float", "f32", !0, se),
|
|
193
200
|
// ── 128-bit ──
|
|
194
201
|
d("rgba32uint", "u32", !1, x),
|
|
195
202
|
d("rgba32sint", "i32", !1, x),
|
|
@@ -279,7 +286,7 @@ function N(e, t, r) {
|
|
|
279
286
|
function Fe(e) {
|
|
280
287
|
return ie.find((t) => t.format === e);
|
|
281
288
|
}
|
|
282
|
-
const
|
|
289
|
+
const ue = /* @__PURE__ */ new Set([
|
|
283
290
|
"r8unorm",
|
|
284
291
|
"r8snorm",
|
|
285
292
|
"r8uint",
|
|
@@ -300,7 +307,7 @@ const se = /* @__PURE__ */ new Set([
|
|
|
300
307
|
]), Ue = /* @__PURE__ */ new Set(["r32float", "rg32float", "rgba32float"]);
|
|
301
308
|
function Ce(e, t) {
|
|
302
309
|
const r = { ...e.expect };
|
|
303
|
-
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;
|
|
304
311
|
}
|
|
305
312
|
function Oe(e) {
|
|
306
313
|
return e.has("texture-formats-tier1") || e.has("texture-formats-tier2");
|
|
@@ -311,33 +318,33 @@ function qe(e) {
|
|
|
311
318
|
function Le(e) {
|
|
312
319
|
return e.kind === "depth" && e.hasDepth ? "texture_depth_2d" : `texture_2d<${e.texel}>`;
|
|
313
320
|
}
|
|
314
|
-
const
|
|
315
|
-
async function
|
|
316
|
-
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);
|
|
317
324
|
let n = null;
|
|
318
325
|
const i = [];
|
|
319
326
|
try {
|
|
320
327
|
n = await t();
|
|
321
328
|
} catch (a) {
|
|
322
|
-
i.push({ kind: "exception", message:
|
|
329
|
+
i.push({ kind: "exception", message: X(a) });
|
|
323
330
|
}
|
|
324
331
|
if (r && i.length === 0)
|
|
325
332
|
try {
|
|
326
333
|
await e.queue.onSubmittedWorkDone();
|
|
327
334
|
} catch (a) {
|
|
328
|
-
i.push({ kind: "queue", message:
|
|
335
|
+
i.push({ kind: "queue", message: X(a) });
|
|
329
336
|
}
|
|
330
|
-
for (let a =
|
|
337
|
+
for (let a = K.length - 1; a >= 0; a--)
|
|
331
338
|
try {
|
|
332
339
|
const s = await e.popErrorScope();
|
|
333
|
-
s && i.push({ kind:
|
|
340
|
+
s && i.push({ kind: K[a], message: s.message });
|
|
334
341
|
} catch (s) {
|
|
335
|
-
i.push({ kind: "scope-unavailable", message:
|
|
342
|
+
i.push({ kind: "scope-unavailable", message: X(s) });
|
|
336
343
|
}
|
|
337
344
|
return { value: n, errors: i, ok: i.length === 0 && n !== null };
|
|
338
345
|
}
|
|
339
346
|
async function M(e, t, r = !1) {
|
|
340
|
-
const n = await
|
|
347
|
+
const n = await z(e, async () => {
|
|
341
348
|
const i = await t();
|
|
342
349
|
return i === void 0 ? !0 : i;
|
|
343
350
|
}, r);
|
|
@@ -349,7 +356,7 @@ function _(e, t) {
|
|
|
349
356
|
function O(e) {
|
|
350
357
|
return e[0]?.message ?? "no error reported";
|
|
351
358
|
}
|
|
352
|
-
function
|
|
359
|
+
function X(e) {
|
|
353
360
|
return e instanceof Error ? `${e.name}: ${e.message}` : String(e);
|
|
354
361
|
}
|
|
355
362
|
function v(...e) {
|
|
@@ -386,7 +393,7 @@ async function De(e, t, r, n) {
|
|
|
386
393
|
storageWritable: !1,
|
|
387
394
|
multisample4x: !1,
|
|
388
395
|
errors: []
|
|
389
|
-
}, [a, s] = t.block ?? [4, 4], o = await
|
|
396
|
+
}, [a, s] = t.block ?? [4, 4], o = await z(
|
|
390
397
|
e,
|
|
391
398
|
() => e.createTexture({
|
|
392
399
|
size: [a, s],
|
|
@@ -398,21 +405,21 @@ async function De(e, t, r, n) {
|
|
|
398
405
|
return i.errors.push(..._("create", o.errors)), i;
|
|
399
406
|
const u = o.value, c = await Ie(e, t, u, n);
|
|
400
407
|
if (i.sampleable = c.ok, c.ok || i.errors.push(..._("sample", c.errors)), v(u), t.kind !== "compressed") if (t.kind === "depth") {
|
|
401
|
-
const l = await
|
|
408
|
+
const l = await Ve(e, t);
|
|
402
409
|
i.renderable = l.ok, l.ok || i.errors.push(..._("render", l.errors));
|
|
403
410
|
} else {
|
|
404
|
-
const l = await
|
|
411
|
+
const l = await ce(e, t, !1);
|
|
405
412
|
if (i.renderable = l.ok, l.ok || i.errors.push(..._("render", l.errors)), i.renderable) {
|
|
406
|
-
const f = await
|
|
413
|
+
const f = await ce(e, t, !0);
|
|
407
414
|
i.blendable = f.ok, f.ok || i.errors.push(..._("blend", f.errors));
|
|
408
415
|
}
|
|
409
416
|
}
|
|
410
417
|
if (t.kind === "color") {
|
|
411
|
-
const l = await
|
|
418
|
+
const l = await We(e, t);
|
|
412
419
|
i.storageWritable = l.ok, l.ok || i.errors.push(..._("storage", l.errors));
|
|
413
420
|
}
|
|
414
421
|
if (i.renderable) {
|
|
415
|
-
const l = await
|
|
422
|
+
const l = await ze(e, t);
|
|
416
423
|
i.multisample4x = l.ok, l.ok || i.errors.push(..._("msaa4x", l.errors));
|
|
417
424
|
}
|
|
418
425
|
return i;
|
|
@@ -456,7 +463,7 @@ async function Ie(e, t, r, n) {
|
|
|
456
463
|
return g.setPipeline(c), g.setBindGroup(0, h), g.draw(3), g.end(), e.queue.submit([w.finish()]), !0;
|
|
457
464
|
}, !0);
|
|
458
465
|
}
|
|
459
|
-
async function
|
|
466
|
+
async function ce(e, t, r) {
|
|
460
467
|
let n = null;
|
|
461
468
|
const i = await M(e, async () => {
|
|
462
469
|
const a = e.createTexture({
|
|
@@ -469,7 +476,7 @@ async function ue(e, t, r) {
|
|
|
469
476
|
alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" }
|
|
470
477
|
});
|
|
471
478
|
const o = e.createShaderModule({
|
|
472
|
-
code: H +
|
|
479
|
+
code: H + xe(t)
|
|
473
480
|
}), u = e.createRenderPipeline({
|
|
474
481
|
layout: "auto",
|
|
475
482
|
vertex: { module: o, entryPoint: "vs" },
|
|
@@ -486,7 +493,7 @@ async function ue(e, t, r) {
|
|
|
486
493
|
}, !0);
|
|
487
494
|
return v(n), i;
|
|
488
495
|
}
|
|
489
|
-
async function
|
|
496
|
+
async function Ve(e, t) {
|
|
490
497
|
let r = null;
|
|
491
498
|
const n = await M(e, async () => {
|
|
492
499
|
const i = e.createTexture({
|
|
@@ -511,7 +518,7 @@ async function We(e, t) {
|
|
|
511
518
|
}, !0);
|
|
512
519
|
return v(r), n;
|
|
513
520
|
}
|
|
514
|
-
async function
|
|
521
|
+
async function We(e, t) {
|
|
515
522
|
let r = null;
|
|
516
523
|
const n = await M(e, async () => {
|
|
517
524
|
const i = e.createTexture({
|
|
@@ -535,7 +542,7 @@ async function ze(e, t) {
|
|
|
535
542
|
}, !0);
|
|
536
543
|
return v(r), n;
|
|
537
544
|
}
|
|
538
|
-
async function
|
|
545
|
+
async function ze(e, t) {
|
|
539
546
|
let r = null;
|
|
540
547
|
const n = await M(e, async () => {
|
|
541
548
|
const i = e.createTexture({
|
|
@@ -544,7 +551,7 @@ async function Ve(e, t) {
|
|
|
544
551
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
545
552
|
sampleCount: 4
|
|
546
553
|
}), a = e.createShaderModule({
|
|
547
|
-
code: H + (t.kind === "depth" ? "" :
|
|
554
|
+
code: H + (t.kind === "depth" ? "" : xe(t))
|
|
548
555
|
}), s = {
|
|
549
556
|
layout: "auto",
|
|
550
557
|
vertex: { module: a, entryPoint: "vs" },
|
|
@@ -589,7 +596,7 @@ ${i}
|
|
|
589
596
|
${a}
|
|
590
597
|
}`;
|
|
591
598
|
}
|
|
592
|
-
function
|
|
599
|
+
function xe(e) {
|
|
593
600
|
return e.texel === "u32" ? `
|
|
594
601
|
@fragment fn fs() -> @location(0) vec4u {
|
|
595
602
|
return vec4u(1u, 0u, 0u, 1u);
|
|
@@ -767,11 +774,11 @@ async function He(e, t, r) {
|
|
|
767
774
|
});
|
|
768
775
|
continue;
|
|
769
776
|
}
|
|
770
|
-
n.push(await
|
|
777
|
+
n.push(await Ye(e, a));
|
|
771
778
|
}
|
|
772
779
|
return n;
|
|
773
780
|
}
|
|
774
|
-
async function
|
|
781
|
+
async function Ye(e, t) {
|
|
775
782
|
const r = {
|
|
776
783
|
id: t.id,
|
|
777
784
|
description: t.description,
|
|
@@ -780,9 +787,9 @@ async function Ke(e, t) {
|
|
|
780
787
|
pipelineCreated: !1,
|
|
781
788
|
messages: [],
|
|
782
789
|
compileMs: 0
|
|
783
|
-
}, n = performance.now(), i = await
|
|
790
|
+
}, n = performance.now(), i = await z(e, () => e.createShaderModule({ code: t.code }));
|
|
784
791
|
if (!i.ok || !i.value)
|
|
785
|
-
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;
|
|
786
793
|
let a = null;
|
|
787
794
|
try {
|
|
788
795
|
a = await i.value.getCompilationInfo();
|
|
@@ -797,7 +804,7 @@ async function Ke(e, t) {
|
|
|
797
804
|
lineNum: o.lineNum
|
|
798
805
|
});
|
|
799
806
|
if (r.compiled = !r.messages.some((o) => o.type === "error"), !r.compiled) return r;
|
|
800
|
-
const s = await
|
|
807
|
+
const s = await z(e, () => t.pipeline === "compute" ? e.createComputePipelineAsync({
|
|
801
808
|
layout: "auto",
|
|
802
809
|
compute: { module: i.value, entryPoint: "cs" }
|
|
803
810
|
}) : e.createRenderPipelineAsync({
|
|
@@ -809,12 +816,12 @@ async function Ke(e, t) {
|
|
|
809
816
|
targets: [{ format: "rgba8unorm" }]
|
|
810
817
|
}
|
|
811
818
|
}));
|
|
812
|
-
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;
|
|
813
820
|
}
|
|
814
|
-
function
|
|
821
|
+
function le(e) {
|
|
815
822
|
return { type: "error", message: e.message, lineNum: 0 };
|
|
816
823
|
}
|
|
817
|
-
const
|
|
824
|
+
const Ke = 10, Z = [
|
|
818
825
|
{
|
|
819
826
|
limit: "maxBufferSize",
|
|
820
827
|
floor: 256 * 1024 * 1024,
|
|
@@ -848,7 +855,7 @@ const Xe = 10, Z = [
|
|
|
848
855
|
floor: 16 * 1024,
|
|
849
856
|
test: (e, t) => M(e, () => {
|
|
850
857
|
const r = e.createBuffer({
|
|
851
|
-
size:
|
|
858
|
+
size: fe(t),
|
|
852
859
|
usage: GPUBufferUsage.UNIFORM
|
|
853
860
|
}), n = e.createBindGroupLayout({
|
|
854
861
|
entries: [{
|
|
@@ -858,7 +865,7 @@ const Xe = 10, Z = [
|
|
|
858
865
|
}]
|
|
859
866
|
}), i = e.createBindGroup({
|
|
860
867
|
layout: n,
|
|
861
|
-
entries: [{ binding: 0, resource: { buffer: r, size:
|
|
868
|
+
entries: [{ binding: 0, resource: { buffer: r, size: fe(t) } }]
|
|
862
869
|
});
|
|
863
870
|
return queueMicrotask(() => v(r)), i;
|
|
864
871
|
})
|
|
@@ -925,7 +932,7 @@ var<workgroup> scratch: array<vec4f, ${r}>;
|
|
|
925
932
|
})
|
|
926
933
|
}
|
|
927
934
|
];
|
|
928
|
-
async function
|
|
935
|
+
async function Xe(e, t, r) {
|
|
929
936
|
const n = [];
|
|
930
937
|
for (let i = 0; i < Z.length; i++) {
|
|
931
938
|
const a = Z[i];
|
|
@@ -963,13 +970,13 @@ async function Qe(e, t, r, n) {
|
|
|
963
970
|
i = Math.floor(i / 2), a = (await t.test(e, i)).ok;
|
|
964
971
|
if (!a) return 0;
|
|
965
972
|
let s = n;
|
|
966
|
-
for (let o = 0; o <
|
|
973
|
+
for (let o = 0; o < Ke && s - i > 1; o++) {
|
|
967
974
|
const u = i + Math.floor((s - i) / 2);
|
|
968
975
|
(await t.test(e, u)).ok ? i = u : s = u;
|
|
969
976
|
}
|
|
970
977
|
return i;
|
|
971
978
|
}
|
|
972
|
-
const J = (e) => Math.floor(e / 4) * 4,
|
|
979
|
+
const J = (e) => Math.floor(e / 4) * 4, fe = (e) => Math.floor(e / 16) * 16;
|
|
973
980
|
class j {
|
|
974
981
|
constructor(t) {
|
|
975
982
|
this.available = t;
|
|
@@ -1072,19 +1079,19 @@ function ot(e) {
|
|
|
1072
1079
|
const a = Math.min(r, i);
|
|
1073
1080
|
return !Number.isFinite(a) || a <= 0 ? null : nt(t, a) ? a : null;
|
|
1074
1081
|
}
|
|
1075
|
-
const P = 1024, it = 3, ee = 10, at = 100, st = 60, ut = 20,
|
|
1082
|
+
const P = 1024, it = 3, ee = 10, at = 100, st = 60, ut = 20, de = 2048, V = `
|
|
1076
1083
|
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
|
|
1077
1084
|
var p = array<vec2f, 3>(vec2f(-1., -1.), vec2f(3., -1.), vec2f(-1., 3.));
|
|
1078
1085
|
return vec4f(p[i], 0., 1.);
|
|
1079
1086
|
}`, te = `
|
|
1080
1087
|
@vertex fn vs() -> @builtin(position) vec4f {
|
|
1081
1088
|
return vec4f(2., 2., 0.5, 1.);
|
|
1082
|
-
}`,
|
|
1089
|
+
}`, W = `
|
|
1083
1090
|
@fragment fn fs() -> @location(0) vec4f { return vec4f(0.25, 0.5, 0.75, 1.); }`, re = {
|
|
1084
1091
|
color: { srcFactor: "one", dstFactor: "one", operation: "add" },
|
|
1085
1092
|
alpha: { srcFactor: "one", dstFactor: "one", operation: "add" }
|
|
1086
|
-
},
|
|
1087
|
-
function
|
|
1093
|
+
}, pe = "rgba8unorm";
|
|
1094
|
+
function A(e, t, r) {
|
|
1088
1095
|
const n = typeof t == "string" ? e.createShaderModule({ code: t }) : t;
|
|
1089
1096
|
return e.createRenderPipelineAsync({
|
|
1090
1097
|
layout: "auto",
|
|
@@ -1092,11 +1099,11 @@ function B(e, t, r) {
|
|
|
1092
1099
|
fragment: {
|
|
1093
1100
|
module: n,
|
|
1094
1101
|
entryPoint: "fs",
|
|
1095
|
-
targets: [r ? { format:
|
|
1102
|
+
targets: [r ? { format: pe, blend: r } : { format: pe }]
|
|
1096
1103
|
}
|
|
1097
1104
|
});
|
|
1098
1105
|
}
|
|
1099
|
-
const C = 2e3,
|
|
1106
|
+
const C = 2e3, me = 1e5, ne = [
|
|
1100
1107
|
{
|
|
1101
1108
|
id: "drawcall-overhead",
|
|
1102
1109
|
description: "Empty draw calls — browser validation and driver call cost",
|
|
@@ -1104,7 +1111,7 @@ const C = 2e3, pe = 1e5, ne = [
|
|
|
1104
1111
|
unit: "draws/s",
|
|
1105
1112
|
timingMode: "wall-clock-only",
|
|
1106
1113
|
setup: async (e, t) => {
|
|
1107
|
-
const r = await
|
|
1114
|
+
const r = await A(e, te + W);
|
|
1108
1115
|
return {
|
|
1109
1116
|
record(n, i, a) {
|
|
1110
1117
|
const s = $(n, t, a);
|
|
@@ -1125,7 +1132,7 @@ const C = 2e3, pe = 1e5, ne = [
|
|
|
1125
1132
|
setup: async (e, t) => {
|
|
1126
1133
|
const r = [];
|
|
1127
1134
|
for (let n = 0; n < 8; n++)
|
|
1128
|
-
r.push(await
|
|
1135
|
+
r.push(await A(e, te + `
|
|
1129
1136
|
@fragment fn fs() -> @location(0) vec4f { return vec4f(${(n / 8).toFixed(3)}, 0.5, 0.75, 1.); }`));
|
|
1130
1137
|
return {
|
|
1131
1138
|
record(n, i, a) {
|
|
@@ -1144,7 +1151,7 @@ const C = 2e3, pe = 1e5, ne = [
|
|
|
1144
1151
|
unit: "binds/s",
|
|
1145
1152
|
timingMode: "wall-clock-only",
|
|
1146
1153
|
setup: async (e, t) => {
|
|
1147
|
-
const r = await
|
|
1154
|
+
const r = await A(e, `
|
|
1148
1155
|
struct U { tint: vec4f };
|
|
1149
1156
|
@group(0) @binding(0) var<uniform> u: U;
|
|
1150
1157
|
${te}
|
|
@@ -1179,7 +1186,7 @@ ${te}
|
|
|
1179
1186
|
unit: "MPixel/s",
|
|
1180
1187
|
timingMode: "gpu-preferred",
|
|
1181
1188
|
setup: async (e, t) => {
|
|
1182
|
-
const r = await
|
|
1189
|
+
const r = await A(e, V + W, re);
|
|
1183
1190
|
return {
|
|
1184
1191
|
record(n, i, a) {
|
|
1185
1192
|
const s = $(n, t, a);
|
|
@@ -1199,7 +1206,7 @@ ${te}
|
|
|
1199
1206
|
timingMode: "gpu-preferred",
|
|
1200
1207
|
setup: async (e, t) => {
|
|
1201
1208
|
const r = e.createShaderModule({
|
|
1202
|
-
code:
|
|
1209
|
+
code: V + `
|
|
1203
1210
|
@fragment fn fs(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
1204
1211
|
var p = pos.xyz * 0.001;
|
|
1205
1212
|
var acc = 0.;
|
|
@@ -1209,7 +1216,7 @@ ${te}
|
|
|
1209
1216
|
}
|
|
1210
1217
|
return vec4f(acc * 0.01, p.y, p.z, 1.);
|
|
1211
1218
|
}`
|
|
1212
|
-
}), n = await
|
|
1219
|
+
}), n = await A(e, r, re);
|
|
1213
1220
|
return {
|
|
1214
1221
|
record(i, a, s) {
|
|
1215
1222
|
const o = $(i, t, s);
|
|
@@ -1223,7 +1230,7 @@ ${te}
|
|
|
1223
1230
|
{
|
|
1224
1231
|
id: "triangle-throughput",
|
|
1225
1232
|
description: "Many small triangles — geometry throughput",
|
|
1226
|
-
unitWorkload:
|
|
1233
|
+
unitWorkload: me,
|
|
1227
1234
|
unit: "MTri/s",
|
|
1228
1235
|
timingMode: "gpu-preferred",
|
|
1229
1236
|
setup: async (e, t) => {
|
|
@@ -1238,13 +1245,13 @@ ${te}
|
|
|
1238
1245
|
var off = array<vec2f, 3>(vec2f(0., 0.), vec2f(0.0015, 0.), vec2f(0., 0.0015));
|
|
1239
1246
|
return vec4f(gx + off[corner].x, gy + off[corner].y, 0.5, 1.);
|
|
1240
1247
|
}
|
|
1241
|
-
${
|
|
1242
|
-
}), n = await
|
|
1248
|
+
${W}`
|
|
1249
|
+
}), n = await A(e, r);
|
|
1243
1250
|
return {
|
|
1244
1251
|
record(i, a, s) {
|
|
1245
1252
|
const o = $(i, t, s);
|
|
1246
1253
|
o.setPipeline(n);
|
|
1247
|
-
for (let u = 0; u < a; u++) o.draw(
|
|
1254
|
+
for (let u = 0; u < a; u++) o.draw(me * 3);
|
|
1248
1255
|
o.end();
|
|
1249
1256
|
}
|
|
1250
1257
|
};
|
|
@@ -1268,7 +1275,7 @@ ${z}`
|
|
|
1268
1275
|
code: `
|
|
1269
1276
|
@group(0) @binding(0) var t: texture_2d<f32>;
|
|
1270
1277
|
@group(0) @binding(1) var s: sampler;
|
|
1271
|
-
${
|
|
1278
|
+
${V}
|
|
1272
1279
|
@fragment fn fs(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
1273
1280
|
var acc = vec4f(0.);
|
|
1274
1281
|
let base = pos.xy / ${P}.;
|
|
@@ -1279,7 +1286,7 @@ ${W}
|
|
|
1279
1286
|
}
|
|
1280
1287
|
return acc * 0.03125;
|
|
1281
1288
|
}`
|
|
1282
|
-
}), a = await
|
|
1289
|
+
}), a = await A(e, i, re), s = e.createSampler({ magFilter: "linear", minFilter: "linear" }), o = e.createBindGroup({
|
|
1283
1290
|
layout: a.getBindGroupLayout(0),
|
|
1284
1291
|
entries: [
|
|
1285
1292
|
{ binding: 0, resource: r.createView() },
|
|
@@ -1317,7 +1324,7 @@ async function lt(e, t) {
|
|
|
1317
1324
|
}), n = r.createView();
|
|
1318
1325
|
let i;
|
|
1319
1326
|
try {
|
|
1320
|
-
i = await
|
|
1327
|
+
i = await A(e, V + W);
|
|
1321
1328
|
} catch {
|
|
1322
1329
|
return v(r), null;
|
|
1323
1330
|
}
|
|
@@ -1377,32 +1384,32 @@ async function dt(e, t, r, n, i, a, s) {
|
|
|
1377
1384
|
try {
|
|
1378
1385
|
u = await t.setup(e, r);
|
|
1379
1386
|
} catch (l) {
|
|
1380
|
-
return { ...o, failed: `setup failed: ${
|
|
1387
|
+
return { ...o, failed: `setup failed: ${ge(l)}` };
|
|
1381
1388
|
}
|
|
1382
1389
|
const c = t.timingMode === "gpu-preferred" && n.available;
|
|
1383
1390
|
try {
|
|
1384
1391
|
for (let m = 0; m < it; m++) {
|
|
1385
|
-
const
|
|
1386
|
-
u.record(
|
|
1392
|
+
const k = e.createCommandEncoder();
|
|
1393
|
+
u.record(k, 1), e.queue.submit([k.finish()]);
|
|
1387
1394
|
}
|
|
1388
1395
|
await e.queue.onSubmittedWorkDone();
|
|
1389
1396
|
const l = c ? a ? Math.max(ee, a * at / 1e6) : ee : Math.max(ee, s * st);
|
|
1390
1397
|
let f = 1;
|
|
1391
1398
|
for (let m = 0; m < 8; m++) {
|
|
1392
|
-
const { ms:
|
|
1393
|
-
if (
|
|
1394
|
-
const U =
|
|
1395
|
-
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)));
|
|
1396
1403
|
}
|
|
1397
1404
|
const p = [];
|
|
1398
1405
|
let h = 0;
|
|
1399
1406
|
for (let m = 0; m < i; m++) {
|
|
1400
|
-
const { ms:
|
|
1401
|
-
p.push(
|
|
1407
|
+
const { ms: k, fromGpu: U } = await he(e, u, f, n, c);
|
|
1408
|
+
p.push(k), U && h++;
|
|
1402
1409
|
}
|
|
1403
1410
|
if (u.dispose?.(), p.length === 0)
|
|
1404
1411
|
return { ...o, failed: "no measurements were obtained" };
|
|
1405
|
-
const w = h > p.length / 2, g = w ? p : pt(p), T = Ze(g), E = t.unitWorkload * f,
|
|
1412
|
+
const w = h > p.length / 2, g = w ? p : pt(p), T = Ze(g), E = t.unitWorkload * f, S = {
|
|
1406
1413
|
...o,
|
|
1407
1414
|
medianMs: q(T, 4),
|
|
1408
1415
|
minMs: q(Math.min(...g), 4),
|
|
@@ -1413,18 +1420,18 @@ async function dt(e, t, r, n, i, a, s) {
|
|
|
1413
1420
|
}, R = w ? a != null ? a / 1e6 : null : s > 0 ? s : null;
|
|
1414
1421
|
if (R) {
|
|
1415
1422
|
const m = T / R;
|
|
1416
|
-
|
|
1423
|
+
S.ticks = q(m, 1), S.quantized = m < ut;
|
|
1417
1424
|
}
|
|
1418
1425
|
if (T > 0) {
|
|
1419
1426
|
const m = E / (T / 1e3);
|
|
1420
|
-
|
|
1427
|
+
S.throughput = q(mt(m, t.unit), 2), S.throughputUnit = t.unit;
|
|
1421
1428
|
}
|
|
1422
|
-
return
|
|
1429
|
+
return S;
|
|
1423
1430
|
} catch (l) {
|
|
1424
|
-
return u.dispose?.(), { ...o, failed: `run failed: ${
|
|
1431
|
+
return u.dispose?.(), { ...o, failed: `run failed: ${ge(l)}` };
|
|
1425
1432
|
}
|
|
1426
1433
|
}
|
|
1427
|
-
async function
|
|
1434
|
+
async function he(e, t, r, n, i) {
|
|
1428
1435
|
const a = e.createCommandEncoder(), s = i ? n.writes() : void 0, o = performance.now();
|
|
1429
1436
|
t.record(a, r, s), s && n.resolve(a), e.queue.submit([a.finish()]), await e.queue.onSubmittedWorkDone();
|
|
1430
1437
|
const u = performance.now() - o;
|
|
@@ -1455,7 +1462,7 @@ function q(e, t) {
|
|
|
1455
1462
|
const r = 10 ** t;
|
|
1456
1463
|
return Math.round(e * r) / r;
|
|
1457
1464
|
}
|
|
1458
|
-
function
|
|
1465
|
+
function ge(e) {
|
|
1459
1466
|
return e instanceof Error ? `${e.name}: ${e.message}` : String(e);
|
|
1460
1467
|
}
|
|
1461
1468
|
function ht(e, t, r, n, i) {
|
|
@@ -1511,7 +1518,7 @@ function ht(e, t, r, n, i) {
|
|
|
1511
1518
|
a.push({
|
|
1512
1519
|
kind: "limit-not-honored",
|
|
1513
1520
|
subject: o.limit,
|
|
1514
|
-
detail: `declares ${
|
|
1521
|
+
detail: `declares ${ve(o.declared)} but only reaches ${ve(o.achieved)}` + ` (${(u * 100).toFixed(0)}%). ${o.error?.message ?? ""}`.trimEnd(),
|
|
1515
1522
|
// Below half, code written against the declared value simply dies.
|
|
1516
1523
|
severity: u < 0.5 ? "breaking" : "degraded"
|
|
1517
1524
|
});
|
|
@@ -1520,12 +1527,12 @@ function ht(e, t, r, n, i) {
|
|
|
1520
1527
|
o.skipped || (o.compiled ? o.pipelineCreated || a.push({
|
|
1521
1528
|
kind: "shader-pipeline-failure",
|
|
1522
1529
|
subject: o.id,
|
|
1523
|
-
detail: `${o.description} — compiled, but pipeline creation failed: ${
|
|
1530
|
+
detail: `${o.description} — compiled, but pipeline creation failed: ${be(o)}`,
|
|
1524
1531
|
severity: "breaking"
|
|
1525
1532
|
}) : a.push({
|
|
1526
1533
|
kind: "shader-compile-failure",
|
|
1527
1534
|
subject: o.id,
|
|
1528
|
-
detail: `${o.description} — compilation failed: ${
|
|
1535
|
+
detail: `${o.description} — compilation failed: ${be(o)}`,
|
|
1529
1536
|
severity: "breaking"
|
|
1530
1537
|
}));
|
|
1531
1538
|
if (n)
|
|
@@ -1548,10 +1555,10 @@ function ht(e, t, r, n, i) {
|
|
|
1548
1555
|
});
|
|
1549
1556
|
return a;
|
|
1550
1557
|
}
|
|
1551
|
-
function
|
|
1558
|
+
function be(e) {
|
|
1552
1559
|
return e.messages.find((t) => t.type === "error")?.message ?? "no error message";
|
|
1553
1560
|
}
|
|
1554
|
-
function
|
|
1561
|
+
function ve(e) {
|
|
1555
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);
|
|
1556
1563
|
}
|
|
1557
1564
|
const gt = 16;
|
|
@@ -1566,7 +1573,7 @@ function bt(e) {
|
|
|
1566
1573
|
e.description
|
|
1567
1574
|
].join("|");
|
|
1568
1575
|
}
|
|
1569
|
-
async function
|
|
1576
|
+
async function ye(e) {
|
|
1570
1577
|
const t = bt(e), r = globalThis.crypto?.subtle;
|
|
1571
1578
|
if (r)
|
|
1572
1579
|
try {
|
|
@@ -1611,12 +1618,12 @@ async function _t(e = {}) {
|
|
|
1611
1618
|
};
|
|
1612
1619
|
let c;
|
|
1613
1620
|
try {
|
|
1614
|
-
c = await
|
|
1621
|
+
c = await Me(t);
|
|
1615
1622
|
} catch (b) {
|
|
1616
1623
|
return {
|
|
1617
1624
|
...u,
|
|
1618
1625
|
unavailable: b instanceof D ? b.message : oe(b),
|
|
1619
|
-
fingerprint: await
|
|
1626
|
+
fingerprint: await ye({
|
|
1620
1627
|
browser: o.browser,
|
|
1621
1628
|
browserVersion: o.browserVersion,
|
|
1622
1629
|
vendor: "",
|
|
@@ -1634,28 +1641,28 @@ async function _t(e = {}) {
|
|
|
1634
1641
|
});
|
|
1635
1642
|
const T = new Set(p.features);
|
|
1636
1643
|
let E = 0;
|
|
1637
|
-
const
|
|
1644
|
+
const S = (b, Y) => {
|
|
1638
1645
|
try {
|
|
1639
|
-
n?.(b,
|
|
1646
|
+
n?.(b, Y);
|
|
1640
1647
|
} catch {
|
|
1641
1648
|
}
|
|
1642
|
-
}, R = (b,
|
|
1649
|
+
}, R = (b, Y) => (ke) => S(b, E + Y * ke), m = {
|
|
1643
1650
|
formats: [],
|
|
1644
1651
|
shaders: [],
|
|
1645
1652
|
limits: [],
|
|
1646
1653
|
deviceLost: !1
|
|
1647
1654
|
};
|
|
1648
1655
|
try {
|
|
1649
|
-
|
|
1656
|
+
S("formats", E), m.formats = await Ne(
|
|
1650
1657
|
l,
|
|
1651
1658
|
T,
|
|
1652
1659
|
i,
|
|
1653
1660
|
R("formats", F.formats)
|
|
1654
|
-
), E += F.formats,
|
|
1661
|
+
), E += F.formats, S("shaders", E), m.shaders = await He(
|
|
1655
1662
|
l,
|
|
1656
1663
|
T,
|
|
1657
1664
|
R("shaders", F.shaders)
|
|
1658
|
-
), E += F.shaders,
|
|
1665
|
+
), E += F.shaders, S("limits", E), m.limits = await Xe(
|
|
1659
1666
|
l,
|
|
1660
1667
|
p.limits,
|
|
1661
1668
|
R("limits", F.limits)
|
|
@@ -1663,21 +1670,21 @@ async function _t(e = {}) {
|
|
|
1663
1670
|
} catch (b) {
|
|
1664
1671
|
m.deviceLost = !0, m.deviceLostReason = g ?? oe(b);
|
|
1665
1672
|
}
|
|
1666
|
-
let
|
|
1673
|
+
let k = null;
|
|
1667
1674
|
if (r && !m.deviceLost) {
|
|
1668
|
-
|
|
1675
|
+
S("benchmarks", E);
|
|
1669
1676
|
try {
|
|
1670
|
-
|
|
1677
|
+
k = await ft(l, a, R("benchmarks", F.bench));
|
|
1671
1678
|
} catch (b) {
|
|
1672
1679
|
m.deviceLostReason = g ?? oe(b);
|
|
1673
1680
|
}
|
|
1674
1681
|
}
|
|
1675
|
-
|
|
1682
|
+
S("done", 1), g && (m.deviceLost = !0, m.deviceLostReason = g);
|
|
1676
1683
|
const U = ht(
|
|
1677
1684
|
m.formats,
|
|
1678
1685
|
m.shaders,
|
|
1679
1686
|
m.limits,
|
|
1680
|
-
|
|
1687
|
+
k,
|
|
1681
1688
|
T
|
|
1682
1689
|
);
|
|
1683
1690
|
for (const b of h)
|
|
@@ -1687,9 +1694,9 @@ async function _t(e = {}) {
|
|
|
1687
1694
|
detail: "requestDevice refused values the adapter itself advertised",
|
|
1688
1695
|
severity: "degraded"
|
|
1689
1696
|
});
|
|
1690
|
-
const
|
|
1697
|
+
const Se = {
|
|
1691
1698
|
...u,
|
|
1692
|
-
fingerprint: await
|
|
1699
|
+
fingerprint: await ye({
|
|
1693
1700
|
browser: o.browser,
|
|
1694
1701
|
browserVersion: o.browserVersion,
|
|
1695
1702
|
vendor: f.vendor,
|
|
@@ -1700,11 +1707,11 @@ async function _t(e = {}) {
|
|
|
1700
1707
|
adapter: f,
|
|
1701
1708
|
declared: p,
|
|
1702
1709
|
verified: m,
|
|
1703
|
-
benchmarks:
|
|
1710
|
+
benchmarks: k,
|
|
1704
1711
|
discrepancies: U,
|
|
1705
1712
|
elapsedMs: Math.round(performance.now() - s)
|
|
1706
1713
|
};
|
|
1707
|
-
return l.destroy(),
|
|
1714
|
+
return l.destroy(), Se;
|
|
1708
1715
|
}
|
|
1709
1716
|
function wt(e, t, r) {
|
|
1710
1717
|
return Number.isFinite(e) ? Math.min(r, Math.max(t, Math.round(e))) : t;
|
|
@@ -1721,14 +1728,14 @@ function xt(e) {
|
|
|
1721
1728
|
benchmarks: new Map((e.benchmarks?.results ?? []).map((t) => [t.id, t]))
|
|
1722
1729
|
};
|
|
1723
1730
|
}
|
|
1724
|
-
const
|
|
1731
|
+
const St = [
|
|
1725
1732
|
"creatable",
|
|
1726
1733
|
"sampleable",
|
|
1727
1734
|
"renderable",
|
|
1728
1735
|
"blendable",
|
|
1729
1736
|
"storageWritable",
|
|
1730
1737
|
"multisample4x"
|
|
1731
|
-
],
|
|
1738
|
+
], kt = 0.15;
|
|
1732
1739
|
function Gt(e) {
|
|
1733
1740
|
const t = [], r = [], n = [], i = /* @__PURE__ */ new Set();
|
|
1734
1741
|
e.forEach((s, o) => {
|
|
@@ -1764,12 +1771,12 @@ function Gt(e) {
|
|
|
1764
1771
|
...Pt(a),
|
|
1765
1772
|
formats: Et(a),
|
|
1766
1773
|
limits: Tt(a),
|
|
1767
|
-
benchmarks:
|
|
1774
|
+
benchmarks: Bt(a),
|
|
1768
1775
|
excluded: n
|
|
1769
1776
|
};
|
|
1770
1777
|
}
|
|
1771
1778
|
function Mt(e) {
|
|
1772
|
-
const t = [e.adapter?.vendor, e.adapter?.architecture].filter(Boolean).join(" ") || e.adapter?.description || "unknown GPU", r = [e.environment.browser,
|
|
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(" ");
|
|
1773
1780
|
return r ? `${t} / ${r}` : t;
|
|
1774
1781
|
}
|
|
1775
1782
|
function Pt(e) {
|
|
@@ -1790,7 +1797,7 @@ function Et(e) {
|
|
|
1790
1797
|
for (const i of n.formats.keys()) t.add(i);
|
|
1791
1798
|
const r = [];
|
|
1792
1799
|
for (const n of [...t].sort())
|
|
1793
|
-
for (const i of
|
|
1800
|
+
for (const i of St) {
|
|
1794
1801
|
const a = [], s = [];
|
|
1795
1802
|
for (const o of e) {
|
|
1796
1803
|
const u = o.formats.get(n);
|
|
@@ -1817,7 +1824,7 @@ function Tt(e) {
|
|
|
1817
1824
|
}
|
|
1818
1825
|
return r.sort((n, i) => i.ratio - n.ratio);
|
|
1819
1826
|
}
|
|
1820
|
-
function
|
|
1827
|
+
function Bt(e) {
|
|
1821
1828
|
const t = /* @__PURE__ */ new Map();
|
|
1822
1829
|
for (const n of e)
|
|
1823
1830
|
for (const [i, a] of n.benchmarks)
|
|
@@ -1831,7 +1838,7 @@ function At(e) {
|
|
|
1831
1838
|
a[p] = null;
|
|
1832
1839
|
continue;
|
|
1833
1840
|
}
|
|
1834
|
-
a[p] = h.throughput, ((f.profile.schema ?? 0) < 2 || h.quantized || h.variation >
|
|
1841
|
+
a[p] = h.throughput, ((f.profile.schema ?? 0) < 2 || h.quantized || h.variation > kt) && s.push(p);
|
|
1835
1842
|
}
|
|
1836
1843
|
const o = Object.entries(a).filter((f) => f[1] != null);
|
|
1837
1844
|
let u = null, c = null, l = null;
|
|
@@ -1912,7 +1919,7 @@ function Ft(e, t = {}) {
|
|
|
1912
1919
|
return n.join(`
|
|
1913
1920
|
`);
|
|
1914
1921
|
}
|
|
1915
|
-
function
|
|
1922
|
+
function At(e) {
|
|
1916
1923
|
return e.split(".")[0] ?? "";
|
|
1917
1924
|
}
|
|
1918
1925
|
function Ut(e) {
|