@motion-core/motion-gpu 0.5.0 → 0.7.0
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 +35 -2
- package/dist/core/compute-bindgroup-cache.d.ts +13 -0
- package/dist/core/compute-bindgroup-cache.d.ts.map +1 -0
- package/dist/core/compute-bindgroup-cache.js +45 -0
- package/dist/core/compute-bindgroup-cache.js.map +1 -0
- package/dist/core/compute-shader.d.ts +48 -0
- package/dist/core/compute-shader.d.ts.map +1 -1
- package/dist/core/compute-shader.js +34 -1
- package/dist/core/compute-shader.js.map +1 -1
- package/dist/core/error-diagnostics.d.ts +8 -1
- package/dist/core/error-diagnostics.d.ts.map +1 -1
- package/dist/core/error-diagnostics.js +7 -3
- package/dist/core/error-diagnostics.js.map +1 -1
- package/dist/core/error-report.d.ts.map +1 -1
- package/dist/core/error-report.js +19 -1
- package/dist/core/error-report.js.map +1 -1
- package/dist/core/material.d.ts.map +1 -1
- package/dist/core/material.js +2 -1
- package/dist/core/material.js.map +1 -1
- package/dist/core/pointer.d.ts +96 -0
- package/dist/core/pointer.d.ts.map +1 -0
- package/dist/core/pointer.js +71 -0
- package/dist/core/pointer.js.map +1 -0
- package/dist/core/renderer.d.ts.map +1 -1
- package/dist/core/renderer.js +150 -85
- package/dist/core/renderer.js.map +1 -1
- package/dist/core/runtime-loop.d.ts.map +1 -1
- package/dist/core/runtime-loop.js +26 -14
- package/dist/core/runtime-loop.js.map +1 -1
- package/dist/core/shader.d.ts +7 -2
- package/dist/core/shader.d.ts.map +1 -1
- package/dist/core/shader.js +1 -0
- package/dist/core/shader.js.map +1 -1
- package/dist/core/textures.d.ts +4 -0
- package/dist/core/textures.d.ts.map +1 -1
- package/dist/core/textures.js +2 -1
- package/dist/core/textures.js.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/react/advanced.js +2 -1
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -1
- package/dist/react/use-pointer.d.ts +94 -0
- package/dist/react/use-pointer.d.ts.map +1 -0
- package/dist/react/use-pointer.js +285 -0
- package/dist/react/use-pointer.js.map +1 -0
- package/dist/svelte/advanced.js +2 -1
- package/dist/svelte/index.d.ts +2 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +2 -1
- package/dist/svelte/use-pointer.d.ts +94 -0
- package/dist/svelte/use-pointer.d.ts.map +1 -0
- package/dist/svelte/use-pointer.js +292 -0
- package/dist/svelte/use-pointer.js.map +1 -0
- package/package.json +1 -1
- package/src/lib/core/compute-bindgroup-cache.ts +73 -0
- package/src/lib/core/compute-shader.ts +86 -0
- package/src/lib/core/error-diagnostics.ts +29 -4
- package/src/lib/core/error-report.ts +26 -1
- package/src/lib/core/material.ts +2 -1
- package/src/lib/core/pointer.ts +177 -0
- package/src/lib/core/renderer.ts +198 -92
- package/src/lib/core/runtime-loop.ts +37 -16
- package/src/lib/core/shader.ts +13 -2
- package/src/lib/core/textures.ts +6 -1
- package/src/lib/core/types.ts +1 -1
- package/src/lib/react/index.ts +10 -0
- package/src/lib/react/use-pointer.ts +515 -0
- package/src/lib/svelte/index.ts +10 -0
- package/src/lib/svelte/use-pointer.ts +507 -0
package/dist/core/renderer.js
CHANGED
|
@@ -5,7 +5,8 @@ import { attachShaderCompilationDiagnostics } from "./error-diagnostics.js";
|
|
|
5
5
|
import { buildShaderSourceWithMap, formatShaderSourceLocation } from "./shader.js";
|
|
6
6
|
import { buildRenderTargetSignature, resolveRenderTargetDefinitions } from "./render-targets.js";
|
|
7
7
|
import { planRenderGraph } from "./render-graph.js";
|
|
8
|
-
import {
|
|
8
|
+
import { buildComputeShaderSourceWithMap, buildPingPongComputeShaderSourceWithMap, extractWorkgroupSize, storageTextureSampleScalarType } from "./compute-shader.js";
|
|
9
|
+
import { createComputeStorageBindGroupCache } from "./compute-bindgroup-cache.js";
|
|
9
10
|
//#region src/lib/core/renderer.ts
|
|
10
11
|
/**
|
|
11
12
|
* Binding index for frame uniforms (`time`, `delta`, `resolution`).
|
|
@@ -74,10 +75,13 @@ async function assertCompilation(module, options) {
|
|
|
74
75
|
if (contextLabel.length === 0) return diagnostic.message;
|
|
75
76
|
return `[${contextLabel.join(" | ")}] ${diagnostic.message}`;
|
|
76
77
|
}).join("\n");
|
|
77
|
-
|
|
78
|
+
const prefix = options?.errorPrefix ?? "WGSL compilation failed";
|
|
79
|
+
throw attachShaderCompilationDiagnostics(/* @__PURE__ */ new Error(`${prefix}:\n${summary}`), {
|
|
78
80
|
kind: "shader-compilation",
|
|
81
|
+
...options?.shaderStage !== void 0 ? { shaderStage: options.shaderStage } : {},
|
|
79
82
|
diagnostics,
|
|
80
83
|
fragmentSource: options?.fragmentSource ?? "",
|
|
84
|
+
...options?.computeSource !== void 0 ? { computeSource: options.computeSource } : {},
|
|
81
85
|
includeSources: options?.includeSources ?? {},
|
|
82
86
|
...options?.defineBlockSource !== void 0 ? { defineBlockSource: options.defineBlockSource } : {},
|
|
83
87
|
materialSource: options?.materialSource ?? null,
|
|
@@ -87,6 +91,41 @@ async function assertCompilation(module, options) {
|
|
|
87
91
|
function toSortedUniqueStrings(values) {
|
|
88
92
|
return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));
|
|
89
93
|
}
|
|
94
|
+
function extractGeneratedLineFromComputeError(message) {
|
|
95
|
+
const lineMatch = message.match(/\bline\s+(\d+)\b/i);
|
|
96
|
+
if (lineMatch) {
|
|
97
|
+
const parsed = Number.parseInt(lineMatch[1] ?? "", 10);
|
|
98
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
99
|
+
}
|
|
100
|
+
const colonMatch = message.match(/:(\d+):\d+/);
|
|
101
|
+
if (colonMatch) {
|
|
102
|
+
const parsed = Number.parseInt(colonMatch[1] ?? "", 10);
|
|
103
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function toComputeCompilationError(input) {
|
|
108
|
+
const baseError = input.error instanceof Error ? input.error : new Error(String(input.error ?? "Unknown error"));
|
|
109
|
+
const generatedLine = extractGeneratedLineFromComputeError(baseError.message) ?? 0;
|
|
110
|
+
const sourceLocation = generatedLine > 0 ? input.lineMap[generatedLine] ?? null : null;
|
|
111
|
+
const diagnostics = [{
|
|
112
|
+
generatedLine,
|
|
113
|
+
message: baseError.message,
|
|
114
|
+
sourceLocation
|
|
115
|
+
}];
|
|
116
|
+
const contextLabel = [formatShaderSourceLocation(sourceLocation), generatedLine > 0 ? `generated WGSL line ${generatedLine}` : null].filter((value) => Boolean(value));
|
|
117
|
+
const summary = contextLabel.length > 0 ? `[${contextLabel.join(" | ")}] ${baseError.message}` : baseError.message;
|
|
118
|
+
return attachShaderCompilationDiagnostics(/* @__PURE__ */ new Error(`Compute shader compilation failed:\n${summary}`), {
|
|
119
|
+
kind: "shader-compilation",
|
|
120
|
+
shaderStage: "compute",
|
|
121
|
+
diagnostics,
|
|
122
|
+
fragmentSource: "",
|
|
123
|
+
computeSource: input.computeSource,
|
|
124
|
+
includeSources: {},
|
|
125
|
+
materialSource: null,
|
|
126
|
+
runtimeContext: input.runtimeContext
|
|
127
|
+
});
|
|
128
|
+
}
|
|
90
129
|
function buildPassGraphSnapshot(passes) {
|
|
91
130
|
const declaredPasses = passes ?? [];
|
|
92
131
|
let enabledPassCount = 0;
|
|
@@ -397,7 +436,8 @@ async function createRenderer(options) {
|
|
|
397
436
|
try {
|
|
398
437
|
const runtimeContext = buildShaderCompilationRuntimeContext(options);
|
|
399
438
|
const convertLinearToSrgb = shouldConvertLinearToSrgb(options.outputColorSpace, format);
|
|
400
|
-
const
|
|
439
|
+
const fragmentTextureKeys = options.textureKeys.filter((key) => options.textureDefinitions[key]?.fragmentVisible !== false);
|
|
440
|
+
const builtShader = buildShaderSourceWithMap(options.fragmentWgsl, options.uniformLayout, fragmentTextureKeys, {
|
|
401
441
|
convertLinearToSrgb,
|
|
402
442
|
fragmentLineMap: options.fragmentLineMap,
|
|
403
443
|
...options.storageBufferKeys !== void 0 ? { storageBufferKeys: options.storageBufferKeys } : {},
|
|
@@ -417,10 +457,13 @@ async function createRenderer(options) {
|
|
|
417
457
|
const storageBufferDefinitions = options.storageBufferDefinitions ?? {};
|
|
418
458
|
const storageTextureKeys = options.storageTextureKeys ?? [];
|
|
419
459
|
const storageTextureKeySet = new Set(storageTextureKeys);
|
|
420
|
-
const
|
|
460
|
+
const fragmentTextureIndexByKey = new Map(fragmentTextureKeys.map((key, index) => [key, index]));
|
|
461
|
+
const textureBindings = options.textureKeys.map((key) => {
|
|
421
462
|
const config = normalizedTextureDefinitions[key];
|
|
422
463
|
if (!config) throw new Error(`Missing texture definition for "${key}"`);
|
|
423
|
-
const
|
|
464
|
+
const fragmentTextureIndex = fragmentTextureIndexByKey.get(key);
|
|
465
|
+
const fragmentVisible = fragmentTextureIndex !== void 0;
|
|
466
|
+
const { samplerBinding, textureBinding } = getTextureBindings(fragmentTextureIndex ?? 0);
|
|
424
467
|
const sampler = device.createSampler({
|
|
425
468
|
magFilter: config.filter,
|
|
426
469
|
minFilter: config.filter,
|
|
@@ -438,6 +481,7 @@ async function createRenderer(options) {
|
|
|
438
481
|
key,
|
|
439
482
|
samplerBinding,
|
|
440
483
|
textureBinding,
|
|
484
|
+
fragmentVisible,
|
|
441
485
|
sampler,
|
|
442
486
|
fallbackTexture,
|
|
443
487
|
fallbackView,
|
|
@@ -481,7 +525,33 @@ async function createRenderer(options) {
|
|
|
481
525
|
}
|
|
482
526
|
return runtimeBinding;
|
|
483
527
|
});
|
|
484
|
-
const
|
|
528
|
+
const textureBindingByKey = new Map(textureBindings.map((binding) => [binding.key, binding]));
|
|
529
|
+
const fragmentTextureBindings = textureBindings.filter((binding) => binding.fragmentVisible);
|
|
530
|
+
const computeStorageBufferLayoutEntries = storageBufferKeys.map((key, index) => {
|
|
531
|
+
const bufferType = (storageBufferDefinitions[key]?.access ?? "read-write") === "read" ? "read-only-storage" : "storage";
|
|
532
|
+
return {
|
|
533
|
+
binding: index,
|
|
534
|
+
visibility: GPUShaderStage.COMPUTE,
|
|
535
|
+
buffer: { type: bufferType }
|
|
536
|
+
};
|
|
537
|
+
});
|
|
538
|
+
const computeStorageBufferTopologyKey = storageBufferKeys.map((key) => `${key}:${storageBufferDefinitions[key]?.access ?? "read-write"}`).join("|");
|
|
539
|
+
const computeStorageTextureLayoutEntries = storageTextureKeys.map((key, index) => {
|
|
540
|
+
const config = normalizedTextureDefinitions[key];
|
|
541
|
+
return {
|
|
542
|
+
binding: index,
|
|
543
|
+
visibility: GPUShaderStage.COMPUTE,
|
|
544
|
+
storageTexture: {
|
|
545
|
+
access: "write-only",
|
|
546
|
+
format: config?.format ?? "rgba8unorm",
|
|
547
|
+
viewDimension: "2d"
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
});
|
|
551
|
+
const computeStorageTextureTopologyKey = storageTextureKeys.map((key) => `${key}:${normalizedTextureDefinitions[key]?.format ?? "rgba8unorm"}`).join("|");
|
|
552
|
+
const computeStorageBufferBindGroupCache = createComputeStorageBindGroupCache(device);
|
|
553
|
+
const computeStorageTextureBindGroupCache = createComputeStorageBindGroupCache(device);
|
|
554
|
+
const bindGroupLayout = device.createBindGroupLayout({ entries: createBindGroupLayoutEntries(fragmentTextureBindings) });
|
|
485
555
|
const fragmentStorageBindGroupLayout = storageBufferKeys.length > 0 ? device.createBindGroupLayout({ entries: storageBufferKeys.map((_, index) => ({
|
|
486
556
|
binding: index,
|
|
487
557
|
visibility: GPUShaderStage.FRAGMENT,
|
|
@@ -625,7 +695,9 @@ async function createRenderer(options) {
|
|
|
625
695
|
viewA: textureA.createView(),
|
|
626
696
|
textureB,
|
|
627
697
|
viewB: textureB.createView(),
|
|
628
|
-
bindGroupLayout
|
|
698
|
+
bindGroupLayout,
|
|
699
|
+
readAWriteBBindGroup: null,
|
|
700
|
+
readBWriteABindGroup: null
|
|
629
701
|
};
|
|
630
702
|
pingPongTexturePairs.set(target, pair);
|
|
631
703
|
return pair;
|
|
@@ -652,14 +724,14 @@ async function createRenderer(options) {
|
|
|
652
724
|
if (texDef?.format) storageTextureDefs[key] = { format: texDef.format };
|
|
653
725
|
}
|
|
654
726
|
const isPingPongPipeline = Boolean(buildOptions.pingPongTarget && buildOptions.pingPongFormat);
|
|
655
|
-
const
|
|
727
|
+
const builtComputeShader = isPingPongPipeline ? buildPingPongComputeShaderSourceWithMap({
|
|
656
728
|
compute: buildOptions.computeSource,
|
|
657
729
|
uniformLayout: options.uniformLayout,
|
|
658
730
|
storageBufferKeys,
|
|
659
731
|
storageBufferDefinitions: storageBufferDefs,
|
|
660
732
|
target: buildOptions.pingPongTarget,
|
|
661
733
|
targetFormat: buildOptions.pingPongFormat
|
|
662
|
-
}) :
|
|
734
|
+
}) : buildComputeShaderSourceWithMap({
|
|
663
735
|
compute: buildOptions.computeSource,
|
|
664
736
|
uniformLayout: options.uniformLayout,
|
|
665
737
|
storageBufferKeys,
|
|
@@ -667,7 +739,7 @@ async function createRenderer(options) {
|
|
|
667
739
|
storageTextureKeys,
|
|
668
740
|
storageTextureDefinitions: storageTextureDefs
|
|
669
741
|
});
|
|
670
|
-
const computeShaderModule = device.createShaderModule({ code:
|
|
742
|
+
const computeShaderModule = device.createShaderModule({ code: builtComputeShader.code });
|
|
671
743
|
const workgroupSize = extractWorkgroupSize(buildOptions.computeSource);
|
|
672
744
|
const computeUniformBGL = device.createBindGroupLayout({ entries: [{
|
|
673
745
|
binding: FRAME_BINDING,
|
|
@@ -681,15 +753,7 @@ async function createRenderer(options) {
|
|
|
681
753
|
visibility: GPUShaderStage.COMPUTE,
|
|
682
754
|
buffer: { type: "uniform" }
|
|
683
755
|
}] });
|
|
684
|
-
const
|
|
685
|
-
const bufferType = (storageBufferDefinitions[key]?.access ?? "read-write") === "read" ? "read-only-storage" : "storage";
|
|
686
|
-
return {
|
|
687
|
-
binding: index,
|
|
688
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
689
|
-
buffer: { type: bufferType }
|
|
690
|
-
};
|
|
691
|
-
});
|
|
692
|
-
const storageBGL = storageBGLEntries.length > 0 ? device.createBindGroupLayout({ entries: storageBGLEntries }) : null;
|
|
756
|
+
const storageBGL = computeStorageBufferLayoutEntries.length > 0 ? device.createBindGroupLayout({ entries: computeStorageBufferLayoutEntries }) : null;
|
|
693
757
|
const storageTextureBGLEntries = isPingPongPipeline ? [{
|
|
694
758
|
binding: 0,
|
|
695
759
|
visibility: GPUShaderStage.COMPUTE,
|
|
@@ -706,41 +770,42 @@ async function createRenderer(options) {
|
|
|
706
770
|
format: buildOptions.pingPongFormat,
|
|
707
771
|
viewDimension: "2d"
|
|
708
772
|
}
|
|
709
|
-
}] :
|
|
710
|
-
const texDef = options.textureDefinitions[key];
|
|
711
|
-
return {
|
|
712
|
-
binding: index,
|
|
713
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
714
|
-
storageTexture: {
|
|
715
|
-
access: "write-only",
|
|
716
|
-
format: texDef?.format ?? "rgba8unorm",
|
|
717
|
-
viewDimension: "2d"
|
|
718
|
-
}
|
|
719
|
-
};
|
|
720
|
-
});
|
|
773
|
+
}] : computeStorageTextureLayoutEntries;
|
|
721
774
|
const storageTextureBGL = storageTextureBGLEntries.length > 0 ? device.createBindGroupLayout({ entries: storageTextureBGLEntries }) : null;
|
|
722
775
|
const bindGroupLayouts = [computeUniformBGL];
|
|
723
776
|
if (storageBGL || storageTextureBGL) bindGroupLayouts.push(storageBGL ?? device.createBindGroupLayout({ entries: [] }));
|
|
724
777
|
if (storageTextureBGL) bindGroupLayouts.push(storageTextureBGL);
|
|
725
778
|
const computePipelineLayout = device.createPipelineLayout({ bindGroupLayouts });
|
|
726
|
-
|
|
727
|
-
|
|
779
|
+
let pipeline;
|
|
780
|
+
try {
|
|
781
|
+
pipeline = device.createComputePipeline({
|
|
728
782
|
layout: computePipelineLayout,
|
|
729
783
|
compute: {
|
|
730
784
|
module: computeShaderModule,
|
|
731
785
|
entryPoint: "compute"
|
|
732
786
|
}
|
|
733
|
-
})
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
787
|
+
});
|
|
788
|
+
} catch (error) {
|
|
789
|
+
throw toComputeCompilationError({
|
|
790
|
+
error,
|
|
791
|
+
lineMap: builtComputeShader.lineMap,
|
|
792
|
+
computeSource: buildOptions.computeSource,
|
|
793
|
+
runtimeContext
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
const computeUniformBindGroup = device.createBindGroup({
|
|
797
|
+
layout: computeUniformBGL,
|
|
798
|
+
entries: [{
|
|
799
|
+
binding: FRAME_BINDING,
|
|
800
|
+
resource: { buffer: frameBuffer }
|
|
801
|
+
}, {
|
|
802
|
+
binding: UNIFORM_BINDING,
|
|
803
|
+
resource: { buffer: uniformBuffer }
|
|
804
|
+
}]
|
|
805
|
+
});
|
|
806
|
+
const entry = {
|
|
807
|
+
pipeline,
|
|
808
|
+
bindGroup: computeUniformBindGroup,
|
|
744
809
|
workgroupSize,
|
|
745
810
|
computeSource: buildOptions.computeSource
|
|
746
811
|
};
|
|
@@ -748,71 +813,71 @@ async function createRenderer(options) {
|
|
|
748
813
|
return entry;
|
|
749
814
|
};
|
|
750
815
|
const getComputeStorageBindGroup = () => {
|
|
751
|
-
if (
|
|
752
|
-
const
|
|
753
|
-
const bufferType = (storageBufferDefinitions[key]?.access ?? "read-write") === "read" ? "read-only-storage" : "storage";
|
|
754
|
-
return {
|
|
755
|
-
binding: index,
|
|
756
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
757
|
-
buffer: { type: bufferType }
|
|
758
|
-
};
|
|
759
|
-
});
|
|
760
|
-
const storageBGL = device.createBindGroupLayout({ entries: storageBGLEntries });
|
|
761
|
-
const storageEntries = storageBufferKeys.map((key, index) => {
|
|
816
|
+
if (computeStorageBufferLayoutEntries.length === 0) return null;
|
|
817
|
+
const resources = storageBufferKeys.map((key) => {
|
|
762
818
|
const buffer = storageBufferMap.get(key);
|
|
763
819
|
if (!buffer) throw new Error(`Storage buffer "${key}" not allocated.`);
|
|
820
|
+
return buffer;
|
|
821
|
+
});
|
|
822
|
+
const storageEntries = resources.map((buffer, index) => {
|
|
764
823
|
return {
|
|
765
824
|
binding: index,
|
|
766
825
|
resource: { buffer }
|
|
767
826
|
};
|
|
768
827
|
});
|
|
769
|
-
return
|
|
770
|
-
|
|
771
|
-
|
|
828
|
+
return computeStorageBufferBindGroupCache.getOrCreate({
|
|
829
|
+
topologyKey: computeStorageBufferTopologyKey,
|
|
830
|
+
layoutEntries: computeStorageBufferLayoutEntries,
|
|
831
|
+
bindGroupEntries: storageEntries,
|
|
832
|
+
resourceRefs: resources
|
|
772
833
|
});
|
|
773
834
|
};
|
|
774
835
|
const getComputeStorageTextureBindGroup = () => {
|
|
775
|
-
if (
|
|
776
|
-
const
|
|
777
|
-
const
|
|
778
|
-
return {
|
|
779
|
-
binding: index,
|
|
780
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
781
|
-
storageTexture: {
|
|
782
|
-
access: "write-only",
|
|
783
|
-
format: texDef?.format ?? "rgba8unorm",
|
|
784
|
-
viewDimension: "2d"
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
});
|
|
788
|
-
const bgl = device.createBindGroupLayout({ entries });
|
|
789
|
-
const bgEntries = storageTextureKeys.map((key, index) => {
|
|
790
|
-
const binding = textureBindings.find((b) => b.key === key);
|
|
836
|
+
if (computeStorageTextureLayoutEntries.length === 0) return null;
|
|
837
|
+
const resources = storageTextureKeys.map((key) => {
|
|
838
|
+
const binding = textureBindingByKey.get(key);
|
|
791
839
|
if (!binding || !binding.texture) throw new Error(`Storage texture "${key}" not allocated.`);
|
|
840
|
+
return binding.view;
|
|
841
|
+
});
|
|
842
|
+
const bgEntries = resources.map((view, index) => {
|
|
792
843
|
return {
|
|
793
844
|
binding: index,
|
|
794
|
-
resource:
|
|
845
|
+
resource: view
|
|
795
846
|
};
|
|
796
847
|
});
|
|
797
|
-
return
|
|
798
|
-
|
|
799
|
-
|
|
848
|
+
return computeStorageTextureBindGroupCache.getOrCreate({
|
|
849
|
+
topologyKey: computeStorageTextureTopologyKey,
|
|
850
|
+
layoutEntries: computeStorageTextureLayoutEntries,
|
|
851
|
+
bindGroupEntries: bgEntries,
|
|
852
|
+
resourceRefs: resources
|
|
800
853
|
});
|
|
801
854
|
};
|
|
802
855
|
const getPingPongStorageTextureBindGroup = (target, readFromA) => {
|
|
803
856
|
const pair = ensurePingPongTexturePair(target);
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
857
|
+
if (readFromA) {
|
|
858
|
+
if (!pair.readAWriteBBindGroup) pair.readAWriteBBindGroup = device.createBindGroup({
|
|
859
|
+
layout: pair.bindGroupLayout,
|
|
860
|
+
entries: [{
|
|
861
|
+
binding: 0,
|
|
862
|
+
resource: pair.viewA
|
|
863
|
+
}, {
|
|
864
|
+
binding: 1,
|
|
865
|
+
resource: pair.viewB
|
|
866
|
+
}]
|
|
867
|
+
});
|
|
868
|
+
return pair.readAWriteBBindGroup;
|
|
869
|
+
}
|
|
870
|
+
if (!pair.readBWriteABindGroup) pair.readBWriteABindGroup = device.createBindGroup({
|
|
807
871
|
layout: pair.bindGroupLayout,
|
|
808
872
|
entries: [{
|
|
809
873
|
binding: 0,
|
|
810
|
-
resource:
|
|
874
|
+
resource: pair.viewB
|
|
811
875
|
}, {
|
|
812
876
|
binding: 1,
|
|
813
|
-
resource:
|
|
877
|
+
resource: pair.viewA
|
|
814
878
|
}]
|
|
815
879
|
});
|
|
880
|
+
return pair.readBWriteABindGroup;
|
|
816
881
|
};
|
|
817
882
|
const frameBuffer = device.createBuffer({
|
|
818
883
|
size: 16,
|
|
@@ -843,7 +908,7 @@ async function createRenderer(options) {
|
|
|
843
908
|
binding: UNIFORM_BINDING,
|
|
844
909
|
resource: { buffer: uniformBuffer }
|
|
845
910
|
}];
|
|
846
|
-
for (const binding of
|
|
911
|
+
for (const binding of fragmentTextureBindings) {
|
|
847
912
|
entries.push({
|
|
848
913
|
binding: binding.samplerBinding,
|
|
849
914
|
resource: binding.sampler
|
|
@@ -1211,7 +1276,7 @@ async function createRenderer(options) {
|
|
|
1211
1276
|
let bindGroupDirty = false;
|
|
1212
1277
|
for (const binding of textureBindings) {
|
|
1213
1278
|
if (storageTextureKeySet.has(binding.key)) continue;
|
|
1214
|
-
if (updateTextureBinding(binding, textures[binding.key] ?? normalizedTextureDefinitions[binding.key]?.source ?? null, renderMode)) bindGroupDirty = true;
|
|
1279
|
+
if (updateTextureBinding(binding, textures[binding.key] ?? normalizedTextureDefinitions[binding.key]?.source ?? null, renderMode) && binding.fragmentVisible) bindGroupDirty = true;
|
|
1215
1280
|
}
|
|
1216
1281
|
if (bindGroupDirty) bindGroup = createBindGroup();
|
|
1217
1282
|
if (pendingStorageWrites) for (const write of pendingStorageWrites) {
|