@ludicon/spark.js 0.0.12 → 0.0.14
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/dist/spark.esm.js +433 -284
- package/dist/{utils-u276vchj.js → utils-BigAnOxg.js} +74 -5
- package/package.json +1 -1
package/dist/spark.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
Object.entries(
|
|
3
|
-
),
|
|
1
|
+
const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import("./spark_astc_rgb-DaSIMKXW.js"), "./spark_astc_rgba.wgsl": () => import("./spark_astc_rgba-BToA2Rcq.js"), "./spark_bc1_rgb.wgsl": () => import("./spark_bc1_rgb-DZwuM1tO.js"), "./spark_bc4_r.wgsl": () => import("./spark_bc4_r-DjThizCH.js"), "./spark_bc5_rg.wgsl": () => import("./spark_bc5_rg-6bO0Gvo9.js"), "./spark_bc7_rgb.wgsl": () => import("./spark_bc7_rgb-FXpBw9fE.js"), "./spark_bc7_rgba.wgsl": () => import("./spark_bc7_rgba-C8Hi2pUY.js"), "./spark_eac_r.wgsl": () => import("./spark_eac_r-D8HGiglc.js"), "./spark_eac_rg.wgsl": () => import("./spark_eac_rg-DvsrLP9h.js"), "./spark_etc2_rgb.wgsl": () => import("./spark_etc2_rgb-C-j5FZpn.js"), "./utils.wgsl": () => import("./utils-BigAnOxg.js") }), I = Object.fromEntries(
|
|
2
|
+
Object.entries(V).map(([c, e]) => [c.replace("./", ""), async () => (await e()).default])
|
|
3
|
+
), i = {
|
|
4
4
|
ASTC_4x4_RGB: 0,
|
|
5
5
|
ASTC_4x4_RGBA: 1,
|
|
6
6
|
// ASTC_4x4_RGBM: 2,
|
|
@@ -19,7 +19,7 @@ const z = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
19
19
|
// BC6H_RGB: 15,
|
|
20
20
|
BC7_RGB: 16,
|
|
21
21
|
BC7_RGBA: 17
|
|
22
|
-
},
|
|
22
|
+
}, G = [
|
|
23
23
|
/* 0 */
|
|
24
24
|
"astc-4x4-rgb",
|
|
25
25
|
// ASTC_4x4_RGB
|
|
@@ -113,7 +113,7 @@ const z = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
113
113
|
/* 17 */
|
|
114
114
|
"spark_bc7_rgba.wgsl"
|
|
115
115
|
// BC7_RGBA
|
|
116
|
-
],
|
|
116
|
+
], W = [
|
|
117
117
|
/* 0 */
|
|
118
118
|
16,
|
|
119
119
|
// ASTC_4x4_RGB
|
|
@@ -160,7 +160,7 @@ const z = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
160
160
|
/* 17 */
|
|
161
161
|
16
|
|
162
162
|
// BC7_RGB
|
|
163
|
-
],
|
|
163
|
+
], Y = [
|
|
164
164
|
/* 0 */
|
|
165
165
|
4,
|
|
166
166
|
// ASTC_4x4_RGB
|
|
@@ -207,34 +207,34 @@ const z = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
207
207
|
/* 17 */
|
|
208
208
|
4
|
|
209
209
|
// BC7_RGB
|
|
210
|
-
],
|
|
211
|
-
"astc-4x4-rgb":
|
|
212
|
-
"astc-4x4-rgba":
|
|
213
|
-
"eac-r":
|
|
214
|
-
"eac-rg":
|
|
215
|
-
"etc2-rgb":
|
|
216
|
-
"bc1-rgb":
|
|
217
|
-
"bc4-r":
|
|
218
|
-
"bc5-rg":
|
|
219
|
-
"bc7-rgb":
|
|
220
|
-
"bc7-rgba":
|
|
210
|
+
], P = Object.freeze({
|
|
211
|
+
"astc-4x4-rgb": i.ASTC_4x4_RGB,
|
|
212
|
+
"astc-4x4-rgba": i.ASTC_4x4_RGBA,
|
|
213
|
+
"eac-r": i.EAC_R,
|
|
214
|
+
"eac-rg": i.EAC_RG,
|
|
215
|
+
"etc2-rgb": i.ETC2_RGB,
|
|
216
|
+
"bc1-rgb": i.BC1_RGB,
|
|
217
|
+
"bc4-r": i.BC4_R,
|
|
218
|
+
"bc5-rg": i.BC5_RG,
|
|
219
|
+
"bc7-rgb": i.BC7_RGB,
|
|
220
|
+
"bc7-rgba": i.BC7_RGBA,
|
|
221
221
|
// aliases:
|
|
222
|
-
"astc-rgb":
|
|
223
|
-
"astc-rgba":
|
|
222
|
+
"astc-rgb": i.ASTC_4x4_RGB,
|
|
223
|
+
"astc-rgba": i.ASTC_4x4_RGBA,
|
|
224
224
|
// webgpu aliases:
|
|
225
|
-
"bc1-rgba-unorm":
|
|
226
|
-
"bc1-rgba-unorm-srgb":
|
|
227
|
-
"bc4-r-unorm":
|
|
228
|
-
"bc5-rg-unorm":
|
|
229
|
-
"bc7-rgba-unorm":
|
|
230
|
-
"bc7-rgba-unorm-srgb":
|
|
231
|
-
"etc2-rgb8unorm":
|
|
232
|
-
"etc2-rgb8unorm-srgb":
|
|
233
|
-
"eac-r11unorm":
|
|
234
|
-
"eac-rg11unorm":
|
|
235
|
-
"astc-4x4-unorm":
|
|
236
|
-
"astc-4x4-unorm-srgb":
|
|
237
|
-
}),
|
|
225
|
+
"bc1-rgba-unorm": i.BC1_RGB,
|
|
226
|
+
"bc1-rgba-unorm-srgb": i.BC1_RGB,
|
|
227
|
+
"bc4-r-unorm": i.BC4_R,
|
|
228
|
+
"bc5-rg-unorm": i.BC5_RG,
|
|
229
|
+
"bc7-rgba-unorm": i.BC7_RGBA,
|
|
230
|
+
"bc7-rgba-unorm-srgb": i.BC7_RGBA,
|
|
231
|
+
"etc2-rgb8unorm": i.ETC2_RGB,
|
|
232
|
+
"etc2-rgb8unorm-srgb": i.ETC2_RGB,
|
|
233
|
+
"eac-r11unorm": i.EAC_R,
|
|
234
|
+
"eac-rg11unorm": i.EAC_RG,
|
|
235
|
+
"astc-4x4-unorm": i.ASTC_4x4_RGBA,
|
|
236
|
+
"astc-4x4-unorm-srgb": i.ASTC_4x4_RGBA
|
|
237
|
+
}), $ = [
|
|
238
238
|
/* 0 */
|
|
239
239
|
"astc-4x4-unorm",
|
|
240
240
|
// ASTC_4x4_RGB
|
|
@@ -281,7 +281,7 @@ const z = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
281
281
|
/* 17 */
|
|
282
282
|
"bc7-rgba-unorm"
|
|
283
283
|
// BC7_RGB
|
|
284
|
-
],
|
|
284
|
+
], X = [
|
|
285
285
|
/* 0 */
|
|
286
286
|
!0,
|
|
287
287
|
// ASTC_4x4_RGB
|
|
@@ -329,63 +329,63 @@ const z = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
329
329
|
!0
|
|
330
330
|
// BC7_RGB
|
|
331
331
|
];
|
|
332
|
-
function w(
|
|
333
|
-
if (!
|
|
332
|
+
function w(c, e) {
|
|
333
|
+
if (!c)
|
|
334
334
|
throw new Error(e);
|
|
335
335
|
}
|
|
336
|
-
function
|
|
337
|
-
return typeof GPUDevice < "u" &&
|
|
336
|
+
function H(c) {
|
|
337
|
+
return typeof GPUDevice < "u" && c instanceof GPUDevice;
|
|
338
338
|
}
|
|
339
|
-
function
|
|
339
|
+
function j() {
|
|
340
340
|
return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(navigator.platform) || // iPad on iOS 13 detection
|
|
341
341
|
navigator.userAgent.includes("Mac") && "ontouchend" in document;
|
|
342
342
|
}
|
|
343
|
-
function
|
|
344
|
-
const
|
|
345
|
-
return
|
|
343
|
+
function O() {
|
|
344
|
+
const c = navigator.userAgent.match(/Safari\/(\d+(\.\d+)?)/);
|
|
345
|
+
return c && parseFloat(c[1]);
|
|
346
346
|
}
|
|
347
|
-
function
|
|
348
|
-
const
|
|
349
|
-
return
|
|
347
|
+
function k() {
|
|
348
|
+
const c = navigator.userAgent.match(/Firefox\/(\d+(\.\d+)?)/);
|
|
349
|
+
return c && parseFloat(c[1]);
|
|
350
350
|
}
|
|
351
|
-
function
|
|
351
|
+
function Q(c) {
|
|
352
352
|
const e = /* @__PURE__ */ new Set(), r = {
|
|
353
353
|
"texture-compression-bc": [
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
354
|
+
i.BC1_RGB,
|
|
355
|
+
i.BC4_R,
|
|
356
|
+
i.BC5_RG,
|
|
357
|
+
i.BC7_RGB,
|
|
358
|
+
i.BC7_RGBA
|
|
359
359
|
],
|
|
360
|
-
"texture-compression-etc2": [
|
|
361
|
-
"texture-compression-astc": [
|
|
360
|
+
"texture-compression-etc2": [i.ETC2_RGB, i.EAC_R, i.EAC_RG],
|
|
361
|
+
"texture-compression-astc": [i.ASTC_4x4_RGB, i.ASTC_4x4_RGBA]
|
|
362
362
|
};
|
|
363
|
-
for (const [t,
|
|
364
|
-
if (
|
|
365
|
-
for (const
|
|
366
|
-
e.add(
|
|
363
|
+
for (const [t, s] of Object.entries(r))
|
|
364
|
+
if (c.features.has(t))
|
|
365
|
+
for (const n of s)
|
|
366
|
+
e.add(n);
|
|
367
367
|
return e;
|
|
368
368
|
}
|
|
369
|
-
function Z(
|
|
369
|
+
function Z(c) {
|
|
370
370
|
const e = document.createElement("canvas");
|
|
371
|
-
e.width =
|
|
371
|
+
e.width = c.width, e.height = c.height;
|
|
372
372
|
const r = e.getContext("2d");
|
|
373
|
-
r.drawImage(
|
|
374
|
-
const t = r.getImageData(0, 0,
|
|
373
|
+
r.drawImage(c, 0, 0);
|
|
374
|
+
const t = r.getImageData(0, 0, c.width, c.height);
|
|
375
375
|
return new Uint8Array(t.data.buffer);
|
|
376
376
|
}
|
|
377
|
-
function J(
|
|
378
|
-
return /\.svg(?:$|\?)/i.test(
|
|
377
|
+
function J(c) {
|
|
378
|
+
return /\.svg(?:$|\?)/i.test(c) || /^data:image\/svg\+xml[,;]/i.test(c);
|
|
379
379
|
}
|
|
380
|
-
function K(
|
|
380
|
+
function K(c) {
|
|
381
381
|
return new Promise((e, r) => {
|
|
382
382
|
const t = new Image();
|
|
383
|
-
t.crossOrigin = "anonymous", t.decoding = "async", t.onload = () => e(t), t.onerror = r, t.src =
|
|
383
|
+
t.crossOrigin = "anonymous", t.decoding = "async", t.onload = () => e(t), t.onerror = r, t.src = c;
|
|
384
384
|
});
|
|
385
385
|
}
|
|
386
|
-
async function ee(
|
|
387
|
-
const r = await fetch(
|
|
388
|
-
if (!r.ok) throw new Error(`HTTP ${r.status} for ${
|
|
386
|
+
async function ee(c, e = {}) {
|
|
387
|
+
const r = await fetch(c, { mode: "cors" });
|
|
388
|
+
if (!r.ok) throw new Error(`HTTP ${r.status} for ${c}`);
|
|
389
389
|
const t = await r.blob();
|
|
390
390
|
return createImageBitmap(t, {
|
|
391
391
|
imageOrientation: e.flipY ? "flipY" : "none",
|
|
@@ -393,35 +393,36 @@ async function ee(n, e = {}) {
|
|
|
393
393
|
premultiplyAlpha: "none"
|
|
394
394
|
});
|
|
395
395
|
}
|
|
396
|
-
const te =
|
|
397
|
-
function
|
|
398
|
-
return J(
|
|
396
|
+
const te = O();
|
|
397
|
+
function N(c) {
|
|
398
|
+
return J(c) || te ? K(c) : ee(c);
|
|
399
399
|
}
|
|
400
|
-
const
|
|
401
|
-
function re(
|
|
402
|
-
let
|
|
403
|
-
const
|
|
400
|
+
const L = 256, F = 4;
|
|
401
|
+
function re(c, e, r, t) {
|
|
402
|
+
let s = 0, n = 0;
|
|
403
|
+
const a = [];
|
|
404
404
|
do {
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
} while (t && (
|
|
408
|
-
return { mipmapCount:
|
|
405
|
+
const o = Math.ceil(c / 4), u = Math.ceil(e / 4), l = Math.ceil(o * r / L) * L, f = u * l;
|
|
406
|
+
s++, a.push({ offset: n, alignedSize: f, w: c, h: e, bw: o, bh: u, bytesPerRow: l }), n += f, c = Math.max(1, Math.floor(c / 2)), e = Math.max(1, Math.floor(e / 2));
|
|
407
|
+
} while (t && (c >= F || e >= F));
|
|
408
|
+
return { mipmapCount: s, outputSize: n, bufferRanges: a };
|
|
409
409
|
}
|
|
410
|
-
class
|
|
410
|
+
class D {
|
|
411
411
|
#e;
|
|
412
|
-
#
|
|
413
|
-
#
|
|
414
|
-
#l;
|
|
415
|
-
#c;
|
|
416
|
-
#m;
|
|
412
|
+
#f;
|
|
413
|
+
#l = [];
|
|
417
414
|
#g;
|
|
415
|
+
#a = !1;
|
|
416
|
+
#s;
|
|
417
|
+
#o;
|
|
418
418
|
#u;
|
|
419
|
-
#
|
|
419
|
+
#m;
|
|
420
|
+
#i;
|
|
420
421
|
#n = new Array(3);
|
|
421
422
|
#r;
|
|
422
|
-
#
|
|
423
|
-
#
|
|
424
|
-
#
|
|
423
|
+
#p;
|
|
424
|
+
#c;
|
|
425
|
+
#G = 0;
|
|
425
426
|
/**
|
|
426
427
|
* Initialize the encoder by detecting available compression formats.
|
|
427
428
|
* @param {GPUDevice} device - WebGPU device.
|
|
@@ -430,7 +431,7 @@ class L {
|
|
|
430
431
|
* @returns {Promise<void>} Resolves when initialization is complete.
|
|
431
432
|
*/
|
|
432
433
|
static async create(e, r = {}) {
|
|
433
|
-
const t = new
|
|
434
|
+
const t = new D();
|
|
434
435
|
return await t.#B(e, r.preload ?? !1, r.useTimestampQueries ?? !1), t;
|
|
435
436
|
}
|
|
436
437
|
/**
|
|
@@ -461,10 +462,10 @@ class L {
|
|
|
461
462
|
"bc7-rgba"
|
|
462
463
|
], r = [];
|
|
463
464
|
for (const t of e) {
|
|
464
|
-
const
|
|
465
|
-
if (this.#t(
|
|
466
|
-
const
|
|
467
|
-
r.push({ format: t, ratio:
|
|
465
|
+
const s = P[t];
|
|
466
|
+
if (this.#t(s)) {
|
|
467
|
+
const n = Y[s];
|
|
468
|
+
r.push({ format: t, ratio: n });
|
|
468
469
|
}
|
|
469
470
|
}
|
|
470
471
|
return r;
|
|
@@ -489,7 +490,7 @@ class L {
|
|
|
489
490
|
*/
|
|
490
491
|
static getRequiredFeatures(e) {
|
|
491
492
|
const r = [];
|
|
492
|
-
return !
|
|
493
|
+
return !j() && e.features.has("texture-compression-bc") && r.push("texture-compression-bc"), e.features.has("texture-compression-etc2") && r.push("texture-compression-etc2"), e.features.has("texture-compression-astc") && r.push("texture-compression-astc"), e.features.has("shader-f16") && r.push("shader-f16"), e.features.has("timestamp-query") && r.push("timestamp-query"), r;
|
|
493
494
|
}
|
|
494
495
|
/**
|
|
495
496
|
* Try to determine the best compression options automatically. Do not use this in production, this is
|
|
@@ -501,10 +502,10 @@ class L {
|
|
|
501
502
|
*/
|
|
502
503
|
async selectPreferredOptions(e, r = {}) {
|
|
503
504
|
if (r.format == null || r.format == "auto") {
|
|
504
|
-
const t = e instanceof Image || e instanceof ImageBitmap || e instanceof GPUTexture ? e : await
|
|
505
|
+
const t = e instanceof Image || e instanceof ImageBitmap || e instanceof GPUTexture ? e : await N(e);
|
|
505
506
|
r.format = "auto";
|
|
506
|
-
const
|
|
507
|
-
r.format =
|
|
507
|
+
const s = await this.#d(r, t);
|
|
508
|
+
r.format = G[s], t instanceof GPUTexture && t.format.endsWith("-srgb") && (r.srgb = !0), (s == i.EAC_RG || s == i.BC5_RG) && (r.normal = !0);
|
|
508
509
|
}
|
|
509
510
|
return r;
|
|
510
511
|
}
|
|
@@ -549,25 +550,26 @@ class L {
|
|
|
549
550
|
*/
|
|
550
551
|
async encodeTexture(e, r = {}) {
|
|
551
552
|
w(this.#e, "Spark is not initialized");
|
|
552
|
-
const t = e instanceof Image || e instanceof ImageBitmap || e instanceof GPUTexture ? e : await
|
|
553
|
+
const t = e instanceof Image || e instanceof ImageBitmap || e instanceof GPUTexture ? e : await N(e);
|
|
553
554
|
console.log("Loaded image", t);
|
|
554
|
-
const
|
|
555
|
+
const s = await this.#d(r, t), n = this.#h(s), a = Math.ceil(t.width / 4) * 4, o = Math.ceil(t.height / 4) * 4, u = W[s], l = r.generateMipmaps || r.mips, { mipmapCount: f, outputSize: h, bufferRanges: m } = re(a, o, u, l), b = (r.srgb || r.format?.endsWith("srgb")) && X[s], _ = b ? 1 : r.normal ? 2 : 0, B = $[s] + (b ? "-srgb" : ""), A = b ? ["rgba8unorm", "rgba8unorm-srgb"] : ["rgba8unorm"], x = this.#G++;
|
|
555
556
|
console.time("create input texture #" + x);
|
|
556
|
-
let
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
557
|
+
let C = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST;
|
|
558
|
+
this.#a ? C |= GPUTextureUsage.RENDER_ATTACHMENT : C |= GPUTextureUsage.STORAGE_BINDING;
|
|
559
|
+
const y = r.flipY || a != t.width || o != t.height;
|
|
560
|
+
!y && !(t instanceof GPUTexture) && (C |= GPUTextureUsage.RENDER_ATTACHMENT);
|
|
561
|
+
const p = this.#e.createCommandEncoder();
|
|
562
|
+
p.pushDebugGroup?.("spark process texture"), this.#r && typeof p.writeTimestamp == "function" && p.writeTimestamp(this.#r, 0);
|
|
563
|
+
let d;
|
|
564
|
+
(y || !(t instanceof GPUTexture && !l)) && (d = this.#e.createTexture({
|
|
565
|
+
size: [a, o, 1],
|
|
566
|
+
mipLevelCount: f,
|
|
565
567
|
format: "rgba8unorm",
|
|
566
|
-
usage:
|
|
568
|
+
usage: C,
|
|
567
569
|
viewFormats: A
|
|
568
570
|
}));
|
|
569
|
-
let
|
|
570
|
-
|
|
571
|
+
let R;
|
|
572
|
+
y ? t instanceof GPUTexture ? this.#_(p, t, d, a, o, b, r.flipY) : (R = this.#e.createTexture({
|
|
571
573
|
size: [t.width, t.height, 1],
|
|
572
574
|
mipLevelCount: 1,
|
|
573
575
|
format: "rgba8unorm",
|
|
@@ -576,76 +578,76 @@ class L {
|
|
|
576
578
|
viewFormats: A
|
|
577
579
|
}), this.#e.queue.copyExternalImageToTexture(
|
|
578
580
|
{ source: t },
|
|
579
|
-
{ texture:
|
|
581
|
+
{ texture: R },
|
|
580
582
|
{ width: t.width, height: t.height }
|
|
581
|
-
), this.#
|
|
582
|
-
const
|
|
583
|
-
size: [
|
|
584
|
-
mipLevelCount:
|
|
585
|
-
format:
|
|
583
|
+
), this.#_(p, R, d, a, o, _, r.flipY)) : t instanceof GPUTexture ? l ? p.copyTextureToTexture({ texture: t }, { texture: d }, { width: a, height: o }) : d = t : this.#e.queue.copyExternalImageToTexture({ source: t }, { texture: d }, { width: a, height: o }), l && this.#w(p, d, f, a, o, _), p.popDebugGroup?.(), console.timeEnd("create input texture #" + x);
|
|
584
|
+
const E = this.#e.createTexture({
|
|
585
|
+
size: [a, o, 1],
|
|
586
|
+
mipLevelCount: f,
|
|
587
|
+
format: B,
|
|
586
588
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
|
|
587
|
-
}),
|
|
588
|
-
size:
|
|
589
|
+
}), U = this.#e.createBuffer({
|
|
590
|
+
size: h,
|
|
589
591
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
|
|
590
|
-
}),
|
|
591
|
-
console.time(
|
|
592
|
+
}), S = `dispatch compute shader '${G[s]}' #${x}`;
|
|
593
|
+
console.time(S), p.pushDebugGroup?.("spark encode texture");
|
|
592
594
|
let M = {};
|
|
593
|
-
this.#r && typeof
|
|
595
|
+
this.#r && typeof p.writeTimestamp != "function" && (M = {
|
|
594
596
|
writeTimestamps: {
|
|
595
597
|
querySet: this.#r,
|
|
596
598
|
beginningOfPassWriteIndex: 0,
|
|
597
599
|
endOfPassWriteIndex: 1
|
|
598
600
|
}
|
|
599
601
|
});
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
for (let
|
|
603
|
-
const
|
|
604
|
-
layout:
|
|
602
|
+
const v = await n, T = p.beginComputePass(M);
|
|
603
|
+
T.setPipeline(v);
|
|
604
|
+
for (let g = 0; g < f; g++) {
|
|
605
|
+
const z = this.#e.createBindGroup({
|
|
606
|
+
layout: v.getBindGroupLayout(0),
|
|
605
607
|
entries: [
|
|
606
608
|
{
|
|
607
609
|
binding: 0,
|
|
608
|
-
resource:
|
|
609
|
-
baseMipLevel:
|
|
610
|
+
resource: d.createView({
|
|
611
|
+
baseMipLevel: g,
|
|
610
612
|
mipLevelCount: 1
|
|
611
613
|
})
|
|
612
614
|
},
|
|
613
615
|
{
|
|
614
616
|
binding: 1,
|
|
615
|
-
resource: this.#
|
|
617
|
+
resource: this.#i
|
|
616
618
|
},
|
|
617
619
|
{
|
|
618
620
|
binding: 2,
|
|
619
621
|
resource: {
|
|
620
|
-
buffer:
|
|
621
|
-
offset: m[
|
|
622
|
-
size: m[
|
|
622
|
+
buffer: U,
|
|
623
|
+
offset: m[g].offset,
|
|
624
|
+
size: m[g].size
|
|
623
625
|
}
|
|
624
626
|
}
|
|
625
627
|
]
|
|
626
628
|
});
|
|
627
|
-
|
|
629
|
+
T.setBindGroup(0, z), T.dispatchWorkgroups(Math.ceil(m[g].bw / 16), Math.ceil(m[g].bh / 16));
|
|
628
630
|
}
|
|
629
|
-
|
|
630
|
-
for (let
|
|
631
|
-
|
|
631
|
+
T.end();
|
|
632
|
+
for (let g = 0; g < f; g++)
|
|
633
|
+
p.copyBufferToTexture(
|
|
632
634
|
{
|
|
633
|
-
buffer:
|
|
634
|
-
offset: m[
|
|
635
|
-
bytesPerRow: m[
|
|
636
|
-
rowsPerImage: m[
|
|
635
|
+
buffer: U,
|
|
636
|
+
offset: m[g].offset,
|
|
637
|
+
bytesPerRow: m[g].bytesPerRow,
|
|
638
|
+
rowsPerImage: m[g].bh
|
|
637
639
|
},
|
|
638
640
|
{
|
|
639
|
-
texture:
|
|
640
|
-
mipLevel:
|
|
641
|
+
texture: E,
|
|
642
|
+
mipLevel: g
|
|
641
643
|
},
|
|
642
644
|
{
|
|
643
|
-
width: m[
|
|
644
|
-
height: m[
|
|
645
|
+
width: m[g].bw * 4,
|
|
646
|
+
height: m[g].bh * 4,
|
|
645
647
|
depthOrArrayLayers: 1
|
|
646
648
|
}
|
|
647
649
|
);
|
|
648
|
-
return this.#r && typeof
|
|
650
|
+
return this.#r && typeof p.writeTimestamp == "function" && p.writeTimestamp(this.#r, 1), p.popDebugGroup?.(), this.#e.queue.submit([p.finish()]), console.timeEnd(S), R?.destroy(), d != t && d?.destroy(), U?.destroy(), E;
|
|
649
651
|
}
|
|
650
652
|
/**
|
|
651
653
|
* Returns the time (in milliseconds) it took to perform the most recent `encodeTexture()` call.
|
|
@@ -670,77 +672,132 @@ class L {
|
|
|
670
672
|
if (!this.#r)
|
|
671
673
|
return 0;
|
|
672
674
|
const e = this.#e.createCommandEncoder();
|
|
673
|
-
e.resolveQuerySet(this.#r, 0, 2, this.#
|
|
674
|
-
const r = this.#
|
|
675
|
-
return this.#
|
|
675
|
+
e.resolveQuerySet(this.#r, 0, 2, this.#p, 0), e.copyBufferToBuffer(this.#p, 0, this.#c, 0, 16), this.#e.queue.submit([e.finish()]), await this.#e.queue.onSubmittedWorkDone(), await this.#c.mapAsync(GPUMapMode.READ);
|
|
676
|
+
const r = this.#c.getMappedRange(), t = new BigUint64Array(r), s = t[0], n = t[1];
|
|
677
|
+
return this.#c.unmap(), Number(n - s) / 1e6;
|
|
676
678
|
}
|
|
677
679
|
async #B(e, r, t) {
|
|
678
|
-
w(e, "device is required"), w(
|
|
680
|
+
w(e, "device is required"), w(H(e), "device is not a WebGPU device"), this.#e = e, this.#f = Q(this.#e), this.#i = this.#e.createSampler({
|
|
679
681
|
magFilter: "linear",
|
|
680
682
|
minFilter: "linear"
|
|
681
683
|
});
|
|
682
|
-
for (let
|
|
683
|
-
this.#n[
|
|
684
|
+
for (let s = 0; s < 3; s++)
|
|
685
|
+
this.#n[s] = this.#e.createBuffer({
|
|
684
686
|
size: 4,
|
|
685
687
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
686
|
-
}), this.#e.queue.writeBuffer(this.#n[
|
|
688
|
+
}), this.#e.queue.writeBuffer(this.#n[s], 0, new Uint32Array([s]));
|
|
687
689
|
if (t && this.#e.features.has("timestamp-query")) {
|
|
688
|
-
const
|
|
689
|
-
(!
|
|
690
|
+
const s = O(), n = k();
|
|
691
|
+
(!s || s >= 26) && !n && (this.#r = this.#e.createQuerySet({
|
|
690
692
|
type: "timestamp",
|
|
691
693
|
count: 2
|
|
692
|
-
}), this.#
|
|
694
|
+
}), this.#p = this.#e.createBuffer({
|
|
693
695
|
size: 16,
|
|
694
696
|
// 2 timestamps × 8 bytes each
|
|
695
697
|
usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.QUERY_RESOLVE
|
|
696
|
-
}), this.#
|
|
698
|
+
}), this.#c = this.#e.createBuffer({
|
|
697
699
|
size: 16,
|
|
698
700
|
// 2 timestamps × 8 bytes each
|
|
699
701
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
700
702
|
}));
|
|
701
703
|
}
|
|
702
|
-
if (this.#
|
|
703
|
-
let
|
|
704
|
-
Array.isArray(r) ?
|
|
705
|
-
for (const
|
|
706
|
-
|
|
707
|
-
console.error(`Failed to preload pipeline for format ${
|
|
704
|
+
if (this.#g = this.#e.features.has("shader-f16"), await this.#C(), r) {
|
|
705
|
+
let s;
|
|
706
|
+
Array.isArray(r) ? s = r.map((n) => this.#b(n, !1)) : s = this.#f;
|
|
707
|
+
for (const n of s)
|
|
708
|
+
n !== void 0 && !this.#l[n] && this.#h(n).catch((a) => {
|
|
709
|
+
console.error(`Failed to preload pipeline for format ${n}:`, a);
|
|
708
710
|
});
|
|
709
711
|
}
|
|
710
712
|
}
|
|
711
|
-
async #
|
|
713
|
+
async #C() {
|
|
712
714
|
const e = this.#e.createShaderModule({
|
|
713
|
-
code: await
|
|
715
|
+
code: await I["utils.wgsl"](),
|
|
714
716
|
label: "utils"
|
|
715
717
|
});
|
|
716
718
|
if (typeof e.compilationInfo == "function") {
|
|
717
|
-
const
|
|
718
|
-
if (
|
|
719
|
+
const t = await e.compilationInfo();
|
|
720
|
+
if (t.messages.some((s) => s.type == "error")) {
|
|
719
721
|
console.error("WGSL compilation errors:");
|
|
720
|
-
for (const
|
|
721
|
-
console.error(
|
|
722
|
+
for (const s of t.messages)
|
|
723
|
+
console.error(s);
|
|
722
724
|
throw new Error("Shader compilation failed");
|
|
723
725
|
}
|
|
724
726
|
}
|
|
725
|
-
this.#
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
727
|
+
if (k() && (this.#a = !0), this.#a) {
|
|
728
|
+
this.#s = {}, this.#o = {}, this.#u = {};
|
|
729
|
+
const t = ["rgba8unorm-srgb", "rgba8unorm"];
|
|
730
|
+
for (const s of t)
|
|
731
|
+
this.#s[s] = this.#e.createRenderPipeline({
|
|
732
|
+
label: `mipmap-pipeline-${s}`,
|
|
733
|
+
layout: "auto",
|
|
734
|
+
vertex: {
|
|
735
|
+
module: e,
|
|
736
|
+
entryPoint: "fullscreen_vs"
|
|
737
|
+
},
|
|
738
|
+
fragment: {
|
|
739
|
+
module: e,
|
|
740
|
+
entryPoint: "mipmap_fs",
|
|
741
|
+
targets: [{ format: s }]
|
|
742
|
+
},
|
|
743
|
+
primitive: {
|
|
744
|
+
topology: "triangle-strip",
|
|
745
|
+
stripIndexFormat: "uint32"
|
|
746
|
+
}
|
|
747
|
+
}), this.#o[s] = this.#e.createRenderPipeline({
|
|
748
|
+
label: `resize-pipeline-${s}`,
|
|
749
|
+
layout: "auto",
|
|
750
|
+
vertex: {
|
|
751
|
+
module: e,
|
|
752
|
+
entryPoint: "fullscreen_vs"
|
|
753
|
+
},
|
|
754
|
+
fragment: {
|
|
755
|
+
module: e,
|
|
756
|
+
entryPoint: "resize_fs",
|
|
757
|
+
targets: [{ format: s }]
|
|
758
|
+
},
|
|
759
|
+
primitive: {
|
|
760
|
+
topology: "triangle-strip",
|
|
761
|
+
stripIndexFormat: "uint32"
|
|
762
|
+
}
|
|
763
|
+
}), this.#u[s] = this.#e.createRenderPipeline({
|
|
764
|
+
label: `flip-y-pipeline-${s}`,
|
|
765
|
+
layout: "auto",
|
|
766
|
+
vertex: {
|
|
767
|
+
module: e,
|
|
768
|
+
entryPoint: "fullscreen_vs"
|
|
769
|
+
},
|
|
770
|
+
fragment: {
|
|
771
|
+
module: e,
|
|
772
|
+
entryPoint: "flipy_fs",
|
|
773
|
+
targets: [{ format: s }]
|
|
774
|
+
},
|
|
775
|
+
primitive: {
|
|
776
|
+
topology: "triangle-strip",
|
|
777
|
+
stripIndexFormat: "uint32"
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
} else
|
|
781
|
+
this.#s = this.#e.createComputePipeline({
|
|
782
|
+
layout: "auto",
|
|
783
|
+
compute: {
|
|
784
|
+
module: e,
|
|
785
|
+
entryPoint: "mipmap"
|
|
786
|
+
}
|
|
787
|
+
}), this.#o = this.#e.createComputePipeline({
|
|
788
|
+
layout: "auto",
|
|
789
|
+
compute: {
|
|
790
|
+
module: e,
|
|
791
|
+
entryPoint: "resize"
|
|
792
|
+
}
|
|
793
|
+
}), this.#u = this.#e.createComputePipeline({
|
|
794
|
+
layout: "auto",
|
|
795
|
+
compute: {
|
|
796
|
+
module: e,
|
|
797
|
+
entryPoint: "flipy"
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
this.#m = await this.#e.createComputePipelineAsync({
|
|
744
801
|
layout: "auto",
|
|
745
802
|
compute: {
|
|
746
803
|
module: e,
|
|
@@ -748,47 +805,47 @@ class L {
|
|
|
748
805
|
}
|
|
749
806
|
});
|
|
750
807
|
}
|
|
751
|
-
async #
|
|
752
|
-
if (this.#
|
|
753
|
-
return this.#
|
|
808
|
+
async #h(e) {
|
|
809
|
+
if (this.#l[e])
|
|
810
|
+
return this.#l[e];
|
|
754
811
|
const r = (async () => {
|
|
755
|
-
console.time("loadPipeline " +
|
|
812
|
+
console.time("loadPipeline " + G[e]);
|
|
756
813
|
const t = q[e];
|
|
757
|
-
w(t, `No shader available for format ${
|
|
758
|
-
let
|
|
759
|
-
this.#
|
|
760
|
-
const
|
|
761
|
-
code:
|
|
762
|
-
label:
|
|
814
|
+
w(t, `No shader available for format ${G[e]}`);
|
|
815
|
+
let s = await I[t]();
|
|
816
|
+
this.#g || (s = s.replace(/^enable f16;\s*/m, "").replace(/\bf16\b/g, "f32").replace(/\bvec([234])h\b/g, "vec$1f").replace(/\bmat([234]x[234])h/g, "mat$1f").replace(/\b(\d*\.\d+|\d+\.)h\b/g, "$1"));
|
|
817
|
+
const n = this.#e.createShaderModule({
|
|
818
|
+
code: s,
|
|
819
|
+
label: G[e]
|
|
763
820
|
});
|
|
764
|
-
if (typeof
|
|
765
|
-
const
|
|
766
|
-
if (
|
|
821
|
+
if (typeof n.getCompilationInfo == "function") {
|
|
822
|
+
const o = await n.getCompilationInfo();
|
|
823
|
+
if (o.messages.some((u) => u.type == "error")) {
|
|
767
824
|
console.error("WGSL compilation errors:");
|
|
768
|
-
for (const u of
|
|
825
|
+
for (const u of o.messages)
|
|
769
826
|
console.error(u);
|
|
770
827
|
throw new Error("Shader compilation failed");
|
|
771
828
|
}
|
|
772
829
|
}
|
|
773
|
-
const
|
|
830
|
+
const a = await this.#e.createComputePipelineAsync({
|
|
774
831
|
layout: "auto",
|
|
775
832
|
compute: {
|
|
776
|
-
module:
|
|
833
|
+
module: n,
|
|
777
834
|
entryPoint: "main"
|
|
778
835
|
}
|
|
779
836
|
});
|
|
780
|
-
return console.timeEnd("loadPipeline " +
|
|
837
|
+
return console.timeEnd("loadPipeline " + G[e]), a;
|
|
781
838
|
})();
|
|
782
|
-
return this.#
|
|
839
|
+
return this.#l[e] = r, r;
|
|
783
840
|
}
|
|
784
841
|
#t(e) {
|
|
785
|
-
return this.#
|
|
842
|
+
return this.#f.has(e);
|
|
786
843
|
}
|
|
787
|
-
#
|
|
788
|
-
const t =
|
|
844
|
+
#b(e, r) {
|
|
845
|
+
const t = P[e];
|
|
789
846
|
if (t != null && this.#t(t))
|
|
790
847
|
return t;
|
|
791
|
-
const
|
|
848
|
+
const s = r ? [
|
|
792
849
|
"bc4-r",
|
|
793
850
|
"eac-r",
|
|
794
851
|
"bc5-rg",
|
|
@@ -815,100 +872,104 @@ class L {
|
|
|
815
872
|
"astc-rgba",
|
|
816
873
|
"astc-4x4-rgba"
|
|
817
874
|
];
|
|
818
|
-
for (const
|
|
819
|
-
if (
|
|
820
|
-
return
|
|
875
|
+
for (const n of s)
|
|
876
|
+
if (n.includes(e) && this.#t(P[n]))
|
|
877
|
+
return P[n];
|
|
821
878
|
}
|
|
822
|
-
async #
|
|
879
|
+
async #d(e, r) {
|
|
823
880
|
if (e.format == null)
|
|
824
881
|
e.format = "rgb";
|
|
825
882
|
else if (e.format == "auto") {
|
|
826
883
|
if (e.alpha) {
|
|
827
|
-
if (this.#t(
|
|
828
|
-
if (this.#t(
|
|
884
|
+
if (this.#t(i.BC7_RGBA)) return i.BC7_RGBA;
|
|
885
|
+
if (this.#t(i.ASTC_4x4_RGBA)) return i.ASTC_4x4_RGBA;
|
|
829
886
|
} else if (e.srgb) {
|
|
830
|
-
if (this.#t(
|
|
831
|
-
if (this.#t(
|
|
832
|
-
if (this.#t(
|
|
833
|
-
if (this.#t(
|
|
887
|
+
if (this.#t(i.BC7_RGB)) return i.BC7_RGB;
|
|
888
|
+
if (this.#t(i.ASTC_4x4_RGB)) return i.ASTC_4x4_RGB;
|
|
889
|
+
if (this.#t(i.BC1_RGB)) return i.BC1_RGB;
|
|
890
|
+
if (this.#t(i.ETC2_RGB)) return i.ETC2_RGB;
|
|
834
891
|
} else if (e.normal) {
|
|
835
|
-
if (this.#t(
|
|
836
|
-
if (this.#t(
|
|
892
|
+
if (this.#t(i.BC5_RG)) return i.BC5_RG;
|
|
893
|
+
if (this.#t(i.EAC_RG)) return i.EAC_RG;
|
|
837
894
|
} else {
|
|
838
|
-
let
|
|
895
|
+
let s;
|
|
839
896
|
if (r instanceof GPUTexture)
|
|
840
|
-
r.format == "r8unorm" || r.format == "r16unorm" ?
|
|
897
|
+
r.format == "r8unorm" || r.format == "r16unorm" ? s = 1 : r.format == "rg8unorm" || r.format == "rg16unorm" ? s = 2 : s = await this.#T(r);
|
|
841
898
|
else {
|
|
842
|
-
const
|
|
843
|
-
|
|
899
|
+
const n = Z(r);
|
|
900
|
+
s = this.#R(n);
|
|
844
901
|
}
|
|
845
|
-
if (
|
|
846
|
-
if (this.#t(
|
|
847
|
-
if (this.#t(
|
|
848
|
-
} else if (
|
|
849
|
-
if (this.#t(
|
|
850
|
-
if (this.#t(
|
|
851
|
-
if (this.#t(
|
|
852
|
-
if (this.#t(
|
|
853
|
-
} else if (
|
|
854
|
-
if (this.#t(
|
|
855
|
-
if (this.#t(
|
|
856
|
-
} else if (
|
|
857
|
-
if (this.#t(
|
|
858
|
-
if (this.#t(
|
|
902
|
+
if (s == 4) {
|
|
903
|
+
if (this.#t(i.BC7_RGBA)) return i.BC7_RGBA;
|
|
904
|
+
if (this.#t(i.ASTC_4x4_RGBA)) return i.ASTC_4x4_RGBA;
|
|
905
|
+
} else if (s == 3) {
|
|
906
|
+
if (this.#t(i.BC7_RGB)) return i.BC7_RGB;
|
|
907
|
+
if (this.#t(i.ASTC_4x4_RGB)) return i.ASTC_4x4_RGB;
|
|
908
|
+
if (this.#t(i.BC1_RGB)) return i.BC1_RGB;
|
|
909
|
+
if (this.#t(i.ETC2_RGB)) return i.ETC2_RGB;
|
|
910
|
+
} else if (s == 2) {
|
|
911
|
+
if (this.#t(i.BC5_RG)) return i.BC5_RG;
|
|
912
|
+
if (this.#t(i.EAC_RG)) return i.EAC_RG;
|
|
913
|
+
} else if (s == 1) {
|
|
914
|
+
if (this.#t(i.BC4_R)) return i.BC4_R;
|
|
915
|
+
if (this.#t(i.EAC_R)) return i.EAC_R;
|
|
859
916
|
}
|
|
860
917
|
}
|
|
861
918
|
throw new Error("No supported format found.");
|
|
862
919
|
}
|
|
863
|
-
const t = this.#
|
|
920
|
+
const t = this.#b(e.format, e.preferLowQuality);
|
|
864
921
|
if (t === void 0)
|
|
865
922
|
throw new Error(`Unsupported format: ${e.format}`);
|
|
866
923
|
return t;
|
|
867
924
|
}
|
|
868
|
-
#
|
|
869
|
-
let r = !0, t = !0,
|
|
870
|
-
const
|
|
871
|
-
for (let
|
|
872
|
-
const
|
|
873
|
-
e[
|
|
874
|
-
const
|
|
875
|
-
(Math.abs(
|
|
925
|
+
#R(e) {
|
|
926
|
+
let r = !0, t = !0, s = 0;
|
|
927
|
+
const n = Math.min(1024 * 128, e.length);
|
|
928
|
+
for (let a = 0; a < n; a += 4) {
|
|
929
|
+
const o = e[a] / 255, u = e[a + 1] / 255, l = e[a + 2] / 255;
|
|
930
|
+
e[a + 3] < 255 && (r = !1), (o != u || u != l) && (t = !1);
|
|
931
|
+
const h = 2 * o - 1, m = 2 * u - 1, b = 2 * l - 1, _ = h * h + m * m + b * b, B = Math.sqrt(_);
|
|
932
|
+
(Math.abs(B - 1) > 0.2 || b < -0.1) && (s += 1);
|
|
876
933
|
}
|
|
877
|
-
return r ? t ? 1 : 16 *
|
|
934
|
+
return r ? t ? 1 : 16 * s < n ? 2 : 3 : 4;
|
|
878
935
|
}
|
|
879
|
-
async #
|
|
936
|
+
async #T(e) {
|
|
880
937
|
const t = this.#e.createBuffer({
|
|
881
938
|
size: 12,
|
|
882
939
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
|
|
883
|
-
}),
|
|
940
|
+
}), s = this.#e.createBuffer({
|
|
884
941
|
size: 12,
|
|
885
942
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
886
|
-
}),
|
|
887
|
-
layout: this.#
|
|
943
|
+
}), n = this.#e.createBindGroup({
|
|
944
|
+
layout: this.#m.getBindGroupLayout(0),
|
|
888
945
|
entries: [
|
|
889
946
|
{ binding: 0, resource: e.createView() },
|
|
890
947
|
{ binding: 1, resource: { buffer: t } }
|
|
891
948
|
]
|
|
892
|
-
}),
|
|
893
|
-
|
|
894
|
-
const { width: u, height:
|
|
895
|
-
|
|
896
|
-
const m = new Uint32Array(
|
|
897
|
-
return
|
|
949
|
+
}), a = this.#e.createCommandEncoder(), o = a.beginComputePass();
|
|
950
|
+
o.setPipeline(this.#m), o.setBindGroup(0, n);
|
|
951
|
+
const { width: u, height: l } = e, f = Math.ceil(u / 8), h = Math.ceil(l / 8);
|
|
952
|
+
o.dispatchWorkgroups(f, h), o.end(), a.copyBufferToBuffer(t, 0, s, 0, 12), this.#e.queue.submit([a.finish()]), await this.#e.queue.onSubmittedWorkDone(), await s.mapAsync(GPUMapMode.READ);
|
|
953
|
+
const m = new Uint32Array(s.getMappedRange()), b = m[0] == 0, _ = m[1] == 0, B = m[2];
|
|
954
|
+
return s.unmap(), s.destroy(), t.destroy(), b ? _ ? 1 : 4 * B < u * l ? 2 : 3 : 4;
|
|
898
955
|
}
|
|
899
956
|
// Apply scaling and flipY transform.
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
957
|
+
#_(e, r, t, s, n, a, o) {
|
|
958
|
+
if (this.#a) {
|
|
959
|
+
this.#P(e, r, t, s, n, a, o);
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
const u = e.beginComputePass(), l = o ? this.#u : this.#o;
|
|
963
|
+
u.setPipeline(l);
|
|
964
|
+
const f = this.#e.createBindGroup({
|
|
965
|
+
layout: l.getBindGroupLayout(0),
|
|
905
966
|
entries: [
|
|
906
967
|
{
|
|
907
968
|
binding: 0,
|
|
908
969
|
resource: r.createView({
|
|
909
970
|
baseMipLevel: 0,
|
|
910
971
|
mipLevelCount: 1,
|
|
911
|
-
format:
|
|
972
|
+
format: a == 1 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
912
973
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
913
974
|
})
|
|
914
975
|
},
|
|
@@ -924,41 +985,89 @@ class L {
|
|
|
924
985
|
},
|
|
925
986
|
{
|
|
926
987
|
binding: 2,
|
|
927
|
-
resource: this.#
|
|
988
|
+
resource: this.#i
|
|
928
989
|
},
|
|
929
990
|
{
|
|
930
991
|
binding: 3,
|
|
931
|
-
resource: { buffer: this.#n[
|
|
992
|
+
resource: { buffer: this.#n[a] }
|
|
932
993
|
}
|
|
933
994
|
]
|
|
934
995
|
});
|
|
935
|
-
u.setBindGroup(0,
|
|
996
|
+
u.setBindGroup(0, f), u.dispatchWorkgroups(Math.ceil(s / 8), Math.ceil(n / 8)), u.end();
|
|
936
997
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
998
|
+
// Apply scaling and flipY transform.
|
|
999
|
+
#P(e, r, t, s, n, a, o) {
|
|
1000
|
+
const u = a == 1 ? "rgba8unorm-srgb" : "rgba8unorm", l = t.createView({
|
|
1001
|
+
baseMipLevel: 0,
|
|
1002
|
+
mipLevelCount: 1,
|
|
1003
|
+
dimension: "2d",
|
|
1004
|
+
format: u,
|
|
1005
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1006
|
+
}), f = e.beginRenderPass({
|
|
1007
|
+
colorAttachments: [
|
|
1008
|
+
{
|
|
1009
|
+
view: l,
|
|
1010
|
+
loadOp: "clear",
|
|
1011
|
+
storeOp: "store",
|
|
1012
|
+
clearValue: [0, 0, 0, 0]
|
|
1013
|
+
}
|
|
1014
|
+
]
|
|
1015
|
+
}), h = o ? this.#u[u] : this.#o[u];
|
|
1016
|
+
f.setPipeline(h);
|
|
1017
|
+
const m = this.#e.createBindGroup({
|
|
1018
|
+
layout: h.getBindGroupLayout(0),
|
|
1019
|
+
entries: [
|
|
1020
|
+
{
|
|
1021
|
+
binding: 0,
|
|
1022
|
+
resource: r.createView({
|
|
1023
|
+
baseMipLevel: 0,
|
|
1024
|
+
mipLevelCount: 1,
|
|
1025
|
+
format: a == 1 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
1026
|
+
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1027
|
+
})
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
binding: 2,
|
|
1031
|
+
resource: this.#i
|
|
1032
|
+
},
|
|
1033
|
+
{
|
|
1034
|
+
binding: 3,
|
|
1035
|
+
resource: { buffer: this.#n[a] }
|
|
1036
|
+
}
|
|
1037
|
+
]
|
|
1038
|
+
});
|
|
1039
|
+
f.setBindGroup(0, m), f.draw(4, 1, 0, 0), f.end();
|
|
1040
|
+
}
|
|
1041
|
+
async #w(e, r, t, s, n, a) {
|
|
1042
|
+
let o = s, u = n;
|
|
1043
|
+
if (this.#a)
|
|
1044
|
+
for (let l = 0; l < t - 1; l++)
|
|
1045
|
+
o = Math.max(1, Math.floor(o / 2)), u = Math.max(1, Math.floor(u / 2)), this.#y(e, r, l, l + 1, o, u, a);
|
|
1046
|
+
else {
|
|
1047
|
+
const l = e.beginComputePass();
|
|
1048
|
+
l.setPipeline(this.#s);
|
|
1049
|
+
for (let f = 0; f < t - 1; f++)
|
|
1050
|
+
o = Math.max(1, Math.floor(o / 2)), u = Math.max(1, Math.floor(u / 2)), this.#x(l, r, f, f + 1, o, u, a);
|
|
1051
|
+
l.end();
|
|
1052
|
+
}
|
|
944
1053
|
}
|
|
945
|
-
#
|
|
1054
|
+
#x(e, r, t, s, n, a, o) {
|
|
946
1055
|
const u = this.#e.createBindGroup({
|
|
947
|
-
layout: this.#
|
|
1056
|
+
layout: this.#s.getBindGroupLayout(0),
|
|
948
1057
|
entries: [
|
|
949
1058
|
{
|
|
950
1059
|
binding: 0,
|
|
951
1060
|
resource: r.createView({
|
|
952
1061
|
baseMipLevel: t,
|
|
953
1062
|
mipLevelCount: 1,
|
|
954
|
-
format:
|
|
1063
|
+
format: o == 1 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
955
1064
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
956
1065
|
})
|
|
957
1066
|
},
|
|
958
1067
|
{
|
|
959
1068
|
binding: 1,
|
|
960
1069
|
resource: r.createView({
|
|
961
|
-
baseMipLevel:
|
|
1070
|
+
baseMipLevel: s,
|
|
962
1071
|
mipLevelCount: 1,
|
|
963
1072
|
dimension: "2d",
|
|
964
1073
|
format: "rgba8unorm",
|
|
@@ -967,17 +1076,57 @@ class L {
|
|
|
967
1076
|
},
|
|
968
1077
|
{
|
|
969
1078
|
binding: 2,
|
|
970
|
-
resource: this.#
|
|
1079
|
+
resource: this.#i
|
|
971
1080
|
},
|
|
972
1081
|
{
|
|
973
1082
|
binding: 3,
|
|
974
|
-
resource: { buffer: this.#n[
|
|
1083
|
+
resource: { buffer: this.#n[o] }
|
|
1084
|
+
}
|
|
1085
|
+
]
|
|
1086
|
+
});
|
|
1087
|
+
e.setBindGroup(0, u), e.dispatchWorkgroups(Math.ceil(n / 8), Math.ceil(a / 8));
|
|
1088
|
+
}
|
|
1089
|
+
#y(e, r, t, s, n, a, o) {
|
|
1090
|
+
const u = o == 1 ? "rgba8unorm-srgb" : "rgba8unorm", l = r.createView({
|
|
1091
|
+
baseMipLevel: s,
|
|
1092
|
+
mipLevelCount: 1,
|
|
1093
|
+
dimension: "2d",
|
|
1094
|
+
format: u,
|
|
1095
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1096
|
+
}), f = e.beginRenderPass({
|
|
1097
|
+
colorAttachments: [
|
|
1098
|
+
{
|
|
1099
|
+
view: l,
|
|
1100
|
+
loadOp: "clear",
|
|
1101
|
+
storeOp: "store",
|
|
1102
|
+
clearValue: [0, 0, 0, 0]
|
|
1103
|
+
}
|
|
1104
|
+
]
|
|
1105
|
+
}), h = this.#e.createBindGroup({
|
|
1106
|
+
layout: this.#s[u].getBindGroupLayout(0),
|
|
1107
|
+
entries: [
|
|
1108
|
+
{
|
|
1109
|
+
binding: 0,
|
|
1110
|
+
resource: r.createView({
|
|
1111
|
+
baseMipLevel: t,
|
|
1112
|
+
mipLevelCount: 1,
|
|
1113
|
+
format: u,
|
|
1114
|
+
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1115
|
+
})
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
binding: 2,
|
|
1119
|
+
resource: this.#i
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
binding: 3,
|
|
1123
|
+
resource: { buffer: this.#n[o] }
|
|
975
1124
|
}
|
|
976
1125
|
]
|
|
977
1126
|
});
|
|
978
|
-
|
|
1127
|
+
f.setPipeline(this.#s[u]), f.setBindGroup(0, h), f.draw(4, 1, 0, 0), f.end();
|
|
979
1128
|
}
|
|
980
1129
|
}
|
|
981
1130
|
export {
|
|
982
|
-
|
|
1131
|
+
D as Spark
|
|
983
1132
|
};
|
|
@@ -20,7 +20,13 @@ fn linear_to_srgb_vec4(c: vec4<f32>) -> vec4<f32> {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
fn normalize_vec4(c: vec4<f32>) -> vec4<f32> {
|
|
23
|
-
|
|
23
|
+
if (c.z == 0.0) {
|
|
24
|
+
// If the normal is stored with only the XY components, there's no need to normalize.
|
|
25
|
+
return c;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return vec4<f32>(saturate(0.5 * normalize(2 * c.xyz - 1) + 0.5), c.w);
|
|
29
|
+
}
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
@compute @workgroup_size(8, 8)
|
|
@@ -42,7 +48,7 @@ fn mipmap(@builtin(global_invocation_id) id : vec3<u32>) {
|
|
|
42
48
|
color += textureSampleLevel(src, smp, vec2f(uv1.x, uv0.y), 0);
|
|
43
49
|
color += textureSampleLevel(src, smp, vec2f(uv0.x, uv1.y), 0);
|
|
44
50
|
color += textureSampleLevel(src, smp, vec2f(uv1.x, uv1.y), 0);
|
|
45
|
-
color *= 0.25;
|
|
51
|
+
color *= 0.25;
|
|
46
52
|
|
|
47
53
|
// This would be the single sample implementation:
|
|
48
54
|
// let uv = (vec2f(id.xy) + vec2f(0.5)) * size_rcp;
|
|
@@ -95,6 +101,71 @@ fn flipy(@builtin(global_invocation_id) id : vec3<u32>) {
|
|
|
95
101
|
textureStore(dst, id.xy, color);
|
|
96
102
|
}
|
|
97
103
|
|
|
104
|
+
// Fullscreen vertex shader
|
|
105
|
+
struct VSOutput {
|
|
106
|
+
@builtin(position) pos: vec4<f32>,
|
|
107
|
+
@location(0) tex : vec2<f32>
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
@vertex
|
|
111
|
+
fn fullscreen_vs(@builtin(vertex_index) vertexIndex : u32) -> VSOutput {
|
|
112
|
+
|
|
113
|
+
var pos = array<vec2<f32>, 4>(
|
|
114
|
+
vec2<f32>(-1.0, 1.0),
|
|
115
|
+
vec2<f32>( 1.0, 1.0),
|
|
116
|
+
vec2<f32>(-1.0, -1.0),
|
|
117
|
+
vec2<f32>( 1.0, -1.0)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
var tex = array<vec2<f32>, 4>(
|
|
121
|
+
vec2<f32>(0.0, 0.0),
|
|
122
|
+
vec2<f32>(1.0, 0.0),
|
|
123
|
+
vec2<f32>(0.0, 1.0),
|
|
124
|
+
vec2<f32>(1.0, 1.0)
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
var vs_output : VSOutput;
|
|
128
|
+
vs_output.tex = tex[vertexIndex];
|
|
129
|
+
vs_output.pos = vec4<f32>(pos[vertexIndex], 0.0, 1.0);
|
|
130
|
+
return vs_output;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@fragment
|
|
134
|
+
fn mipmap_fs(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
135
|
+
|
|
136
|
+
var color = textureSample(src, smp, uv);
|
|
137
|
+
|
|
138
|
+
if (params.colorMode == 2) {
|
|
139
|
+
color = normalize_vec4(color);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return color;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@fragment
|
|
146
|
+
fn resize_fs(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
147
|
+
|
|
148
|
+
var color = textureSample(src, smp, uv);
|
|
149
|
+
|
|
150
|
+
if (params.colorMode == 2) {
|
|
151
|
+
color = normalize_vec4(color);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return color;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@fragment
|
|
158
|
+
fn flipy_fs(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
159
|
+
|
|
160
|
+
var color = textureSample(src, smp, vec2(uv.x, 1 - uv.y));
|
|
161
|
+
|
|
162
|
+
if (params.colorMode == 2) {
|
|
163
|
+
color = normalize_vec4(color);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return color;
|
|
167
|
+
}
|
|
168
|
+
|
|
98
169
|
|
|
99
170
|
@group(0) @binding(1) var<storage, read_write> global_counters: array<atomic<u32>, 3>;
|
|
100
171
|
|
|
@@ -105,7 +176,7 @@ var<workgroup> local_invalid_normals: atomic<u32>;
|
|
|
105
176
|
@compute @workgroup_size(8, 8)
|
|
106
177
|
fn detect_channel_count(@builtin(global_invocation_id) global_id: vec3<u32>,
|
|
107
178
|
@builtin(local_invocation_index) local_id: u32) {
|
|
108
|
-
|
|
179
|
+
|
|
109
180
|
if (local_id == 0u) {
|
|
110
181
|
atomicStore(&local_opaque, 1u);
|
|
111
182
|
atomicStore(&local_grayscale, 1u);
|
|
@@ -157,8 +228,6 @@ fn detect_channel_count(@builtin(global_invocation_id) global_id: vec3<u32>,
|
|
|
157
228
|
|
|
158
229
|
|
|
159
230
|
// @@ Compute RMSE?
|
|
160
|
-
|
|
161
|
-
|
|
162
231
|
`;
|
|
163
232
|
export {
|
|
164
233
|
n as default
|