@luma.gl/webgpu 9.2.6 → 9.3.0-alpha.11
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/adapter/helpers/cpu-hotspot-profiler.d.ts +54 -0
- package/dist/adapter/helpers/cpu-hotspot-profiler.d.ts.map +1 -0
- package/dist/adapter/helpers/cpu-hotspot-profiler.js +26 -0
- package/dist/adapter/helpers/cpu-hotspot-profiler.js.map +1 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.d.ts +7 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.d.ts.map +1 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.js +490 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.js.map +1 -0
- package/dist/adapter/helpers/get-bind-group.d.ts +8 -6
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +110 -30
- package/dist/adapter/helpers/get-bind-group.js.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts +3 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +17 -12
- package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.js +1 -0
- package/dist/adapter/helpers/webgpu-parameters.js.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.d.ts +7 -0
- package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.js +58 -15
- package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-command-buffer.js +1 -1
- package/dist/adapter/resources/webgpu-command-buffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.d.ts +7 -16
- package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.js +89 -32
- package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.d.ts +3 -3
- package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js +30 -12
- package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +7 -9
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.js +30 -17
- package/dist/adapter/resources/webgpu-compute-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgpu-fence.d.ts +13 -0
- package/dist/adapter/resources/webgpu-fence.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-fence.js +33 -0
- package/dist/adapter/resources/webgpu-fence.js.map +1 -0
- package/dist/adapter/resources/webgpu-framebuffer.d.ts +6 -0
- package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.js +16 -0
- package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-pipeline-layout.d.ts +1 -1
- package/dist/adapter/resources/webgpu-pipeline-layout.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-pipeline-layout.js +11 -18
- package/dist/adapter/resources/webgpu-pipeline-layout.js.map +1 -1
- package/dist/adapter/resources/webgpu-query-set.d.ts +33 -4
- package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-query-set.js +145 -4
- package/dist/adapter/resources/webgpu-query-set.js.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.d.ts +6 -3
- package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.js +78 -34
- package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts +14 -10
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.js +62 -35
- package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.js +4 -0
- package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
- package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-shader.js +17 -1
- package/dist/adapter/resources/webgpu-shader.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture-view.d.ts +6 -0
- package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture-view.js +47 -11
- package/dist/adapter/resources/webgpu-texture-view.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture.d.ts +25 -3
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +211 -43
- package/dist/adapter/resources/webgpu-texture.js.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -1
- package/dist/adapter/webgpu-adapter.d.ts.map +1 -1
- package/dist/adapter/webgpu-adapter.js +35 -35
- package/dist/adapter/webgpu-adapter.js.map +1 -1
- package/dist/adapter/webgpu-canvas-context.d.ts +6 -3
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +90 -30
- package/dist/adapter/webgpu-canvas-context.js.map +1 -1
- package/dist/adapter/webgpu-device.d.ts +12 -2
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +176 -19
- package/dist/adapter/webgpu-device.js.map +1 -1
- package/dist/adapter/webgpu-presentation-context.d.ts +25 -0
- package/dist/adapter/webgpu-presentation-context.d.ts.map +1 -0
- package/dist/adapter/webgpu-presentation-context.js +144 -0
- package/dist/adapter/webgpu-presentation-context.js.map +1 -0
- package/dist/dist.dev.js +8160 -551
- package/dist/dist.min.js +171 -6
- package/dist/index.cjs +2001 -414
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/wgsl/get-shader-layout-wgsl.d.ts +8 -0
- package/dist/wgsl/get-shader-layout-wgsl.d.ts.map +1 -0
- package/dist/wgsl/get-shader-layout-wgsl.js +144 -0
- package/dist/wgsl/get-shader-layout-wgsl.js.map +1 -0
- package/package.json +6 -5
- package/src/adapter/helpers/cpu-hotspot-profiler.ts +70 -0
- package/src/adapter/helpers/generate-mipmaps-webgpu.ts +583 -0
- package/src/adapter/helpers/get-bind-group.ts +182 -42
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +31 -12
- package/src/adapter/helpers/webgpu-parameters.ts +2 -0
- package/src/adapter/resources/webgpu-buffer.ts +61 -15
- package/src/adapter/resources/webgpu-command-buffer.ts +1 -1
- package/src/adapter/resources/webgpu-command-encoder.ts +129 -50
- package/src/adapter/resources/webgpu-compute-pass.ts +48 -13
- package/src/adapter/resources/webgpu-compute-pipeline.ts +49 -18
- package/src/adapter/resources/webgpu-fence.ts +38 -0
- package/src/adapter/resources/webgpu-framebuffer.ts +21 -0
- package/src/adapter/resources/webgpu-pipeline-layout.ts +18 -17
- package/src/adapter/resources/webgpu-query-set.ts +185 -9
- package/src/adapter/resources/webgpu-render-pass.ts +92 -40
- package/src/adapter/resources/webgpu-render-pipeline.ts +90 -44
- package/src/adapter/resources/webgpu-sampler.ts +5 -0
- package/src/adapter/resources/webgpu-shader.ts +16 -1
- package/src/adapter/resources/webgpu-texture-view.ts +51 -11
- package/src/adapter/resources/webgpu-texture.ts +281 -101
- package/src/adapter/resources/webgpu-vertex-array.ts +1 -1
- package/src/adapter/webgpu-adapter.ts +41 -43
- package/src/adapter/webgpu-canvas-context.ts +108 -41
- package/src/adapter/webgpu-device.ts +243 -25
- package/src/adapter/webgpu-presentation-context.ts +180 -0
- package/src/index.ts +3 -0
- package/src/wgsl/get-shader-layout-wgsl.ts +165 -0
- package/dist/adapter/helpers/accessor-to-format.d.ts +0 -1
- package/dist/adapter/helpers/accessor-to-format.d.ts.map +0 -1
- package/dist/adapter/helpers/accessor-to-format.js +0 -105
- package/dist/adapter/helpers/accessor-to-format.js.map +0 -1
- package/src/adapter/helpers/accessor-to-format.ts +0 -104
package/dist/index.cjs
CHANGED
|
@@ -7,8 +7,8 @@ var __esm = (fn, res) => function __init() {
|
|
|
7
7
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
8
|
};
|
|
9
9
|
var __export = (target, all) => {
|
|
10
|
-
for (var
|
|
11
|
-
__defProp(target,
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
12
|
};
|
|
13
13
|
var __copyProps = (to, from, except, desc) => {
|
|
14
14
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -30,13 +30,15 @@ var init_webgpu_buffer = __esm({
|
|
|
30
30
|
device;
|
|
31
31
|
handle;
|
|
32
32
|
byteLength;
|
|
33
|
+
paddedByteLength;
|
|
33
34
|
constructor(device, props) {
|
|
34
35
|
var _a, _b;
|
|
35
36
|
super(device, props);
|
|
36
37
|
this.device = device;
|
|
37
38
|
this.byteLength = props.byteLength || ((_a = props.data) == null ? void 0 : _a.byteLength) || 0;
|
|
39
|
+
this.paddedByteLength = Math.ceil(this.byteLength / 4) * 4;
|
|
38
40
|
const mappedAtCreation = Boolean(this.props.onMapped || props.data);
|
|
39
|
-
const size =
|
|
41
|
+
const size = this.paddedByteLength;
|
|
40
42
|
this.device.pushErrorScope("out-of-memory");
|
|
41
43
|
this.device.pushErrorScope("validation");
|
|
42
44
|
this.handle = this.props.handle || this.device.handle.createBuffer({
|
|
@@ -72,11 +74,24 @@ var init_webgpu_buffer = __esm({
|
|
|
72
74
|
this.device.reportError(new Error(`${this} creation failed ${error.message}`), this)();
|
|
73
75
|
this.device.debug();
|
|
74
76
|
});
|
|
77
|
+
if (!this.props.handle) {
|
|
78
|
+
this.trackAllocatedMemory(size);
|
|
79
|
+
} else {
|
|
80
|
+
this.trackReferencedMemory(size, "Buffer");
|
|
81
|
+
}
|
|
75
82
|
}
|
|
76
83
|
destroy() {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
if (!this.destroyed && this.handle) {
|
|
85
|
+
this.removeStats();
|
|
86
|
+
if (!this.props.handle) {
|
|
87
|
+
this.trackDeallocatedMemory();
|
|
88
|
+
this.handle.destroy();
|
|
89
|
+
} else {
|
|
90
|
+
this.trackDeallocatedReferencedMemory("Buffer");
|
|
91
|
+
}
|
|
92
|
+
this.destroyed = true;
|
|
93
|
+
this.handle = null;
|
|
94
|
+
}
|
|
80
95
|
}
|
|
81
96
|
write(data, byteOffset = 0) {
|
|
82
97
|
const arrayBuffer = ArrayBuffer.isView(data) ? data.buffer : data;
|
|
@@ -89,18 +104,21 @@ var init_webgpu_buffer = __esm({
|
|
|
89
104
|
});
|
|
90
105
|
}
|
|
91
106
|
async mapAndWriteAsync(callback, byteOffset = 0, byteLength = this.byteLength - byteOffset) {
|
|
107
|
+
const alignedByteLength = Math.ceil(byteLength / 4) * 4;
|
|
92
108
|
const isMappable = (this.usage & import_core.Buffer.MAP_WRITE) !== 0;
|
|
93
|
-
const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_WRITE | import_core.Buffer.COPY_SRC, 0, this.
|
|
109
|
+
const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_WRITE | import_core.Buffer.COPY_SRC, 0, this.paddedByteLength) : null;
|
|
94
110
|
const writeBuffer = mappableBuffer || this;
|
|
95
111
|
this.device.pushErrorScope("validation");
|
|
96
112
|
try {
|
|
97
113
|
await this.device.handle.queue.onSubmittedWorkDone();
|
|
98
|
-
await writeBuffer.handle.mapAsync(GPUMapMode.WRITE, byteOffset,
|
|
99
|
-
const
|
|
114
|
+
await writeBuffer.handle.mapAsync(GPUMapMode.WRITE, byteOffset, alignedByteLength);
|
|
115
|
+
const mappedRange = writeBuffer.handle.getMappedRange(byteOffset, alignedByteLength);
|
|
116
|
+
const arrayBuffer = mappedRange.slice(0, byteLength);
|
|
100
117
|
await callback(arrayBuffer, "mapped");
|
|
118
|
+
new Uint8Array(mappedRange).set(new Uint8Array(arrayBuffer), 0);
|
|
101
119
|
writeBuffer.handle.unmap();
|
|
102
120
|
if (mappableBuffer) {
|
|
103
|
-
this._copyBuffer(mappableBuffer, byteOffset,
|
|
121
|
+
this._copyBuffer(mappableBuffer, byteOffset, alignedByteLength);
|
|
104
122
|
}
|
|
105
123
|
} finally {
|
|
106
124
|
this.device.popErrorScope((error) => {
|
|
@@ -114,24 +132,37 @@ var init_webgpu_buffer = __esm({
|
|
|
114
132
|
return this.mapAndReadAsync((arrayBuffer) => new Uint8Array(arrayBuffer.slice(0)), byteOffset, byteLength);
|
|
115
133
|
}
|
|
116
134
|
async mapAndReadAsync(callback, byteOffset = 0, byteLength = this.byteLength - byteOffset) {
|
|
135
|
+
const requestedEnd = byteOffset + byteLength;
|
|
136
|
+
if (requestedEnd > this.byteLength) {
|
|
137
|
+
throw new Error("Mapping range exceeds buffer size");
|
|
138
|
+
}
|
|
139
|
+
let mappedByteOffset = byteOffset;
|
|
140
|
+
let mappedByteLength = byteLength;
|
|
141
|
+
let sliceByteOffset = 0;
|
|
142
|
+
let lifetime = "mapped";
|
|
117
143
|
if (byteOffset % 8 !== 0 || byteLength % 4 !== 0) {
|
|
118
|
-
|
|
144
|
+
mappedByteOffset = Math.floor(byteOffset / 8) * 8;
|
|
145
|
+
const alignedEnd = Math.ceil(requestedEnd / 4) * 4;
|
|
146
|
+
mappedByteLength = alignedEnd - mappedByteOffset;
|
|
147
|
+
sliceByteOffset = byteOffset - mappedByteOffset;
|
|
148
|
+
lifetime = "copied";
|
|
119
149
|
}
|
|
120
|
-
if (
|
|
150
|
+
if (mappedByteOffset + mappedByteLength > this.paddedByteLength) {
|
|
121
151
|
throw new Error("Mapping range exceeds buffer size");
|
|
122
152
|
}
|
|
123
153
|
const isMappable = (this.usage & import_core.Buffer.MAP_READ) !== 0;
|
|
124
|
-
const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_READ | import_core.Buffer.COPY_DST, 0, this.
|
|
154
|
+
const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_READ | import_core.Buffer.COPY_DST, 0, this.paddedByteLength) : null;
|
|
125
155
|
const readBuffer = mappableBuffer || this;
|
|
126
156
|
this.device.pushErrorScope("validation");
|
|
127
157
|
try {
|
|
128
158
|
await this.device.handle.queue.onSubmittedWorkDone();
|
|
129
159
|
if (mappableBuffer) {
|
|
130
|
-
mappableBuffer._copyBuffer(this);
|
|
160
|
+
mappableBuffer._copyBuffer(this, mappedByteOffset, mappedByteLength);
|
|
131
161
|
}
|
|
132
|
-
await readBuffer.handle.mapAsync(GPUMapMode.READ,
|
|
133
|
-
const arrayBuffer = readBuffer.handle.getMappedRange(
|
|
134
|
-
const
|
|
162
|
+
await readBuffer.handle.mapAsync(GPUMapMode.READ, mappedByteOffset, mappedByteLength);
|
|
163
|
+
const arrayBuffer = readBuffer.handle.getMappedRange(mappedByteOffset, mappedByteLength);
|
|
164
|
+
const mappedRange = lifetime === "mapped" ? arrayBuffer : arrayBuffer.slice(sliceByteOffset, sliceByteOffset + byteLength);
|
|
165
|
+
const result = await callback(mappedRange, lifetime);
|
|
135
166
|
readBuffer.handle.unmap();
|
|
136
167
|
return result;
|
|
137
168
|
} finally {
|
|
@@ -208,18 +239,47 @@ var init_webgpu_sampler = __esm({
|
|
|
208
239
|
this.handle.label = this.props.id;
|
|
209
240
|
}
|
|
210
241
|
destroy() {
|
|
242
|
+
if (this.destroyed) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
this.destroyResource();
|
|
211
246
|
this.handle = null;
|
|
212
247
|
}
|
|
213
248
|
};
|
|
214
249
|
}
|
|
215
250
|
});
|
|
216
251
|
|
|
252
|
+
// dist/adapter/helpers/cpu-hotspot-profiler.js
|
|
253
|
+
function getCpuHotspotProfiler(owner) {
|
|
254
|
+
const profiler = owner.userData[CPU_HOTSPOT_PROFILER_MODULE];
|
|
255
|
+
return (profiler == null ? void 0 : profiler.enabled) ? profiler : null;
|
|
256
|
+
}
|
|
257
|
+
function getCpuHotspotSubmitReason(owner) {
|
|
258
|
+
return owner.userData[CPU_HOTSPOT_SUBMIT_REASON] || null;
|
|
259
|
+
}
|
|
260
|
+
function setCpuHotspotSubmitReason(owner, submitReason) {
|
|
261
|
+
owner.userData[CPU_HOTSPOT_SUBMIT_REASON] = submitReason;
|
|
262
|
+
}
|
|
263
|
+
function getTimestamp() {
|
|
264
|
+
var _a, _b;
|
|
265
|
+
return ((_b = (_a = globalThis.performance) == null ? void 0 : _a.now) == null ? void 0 : _b.call(_a)) ?? Date.now();
|
|
266
|
+
}
|
|
267
|
+
var CPU_HOTSPOT_PROFILER_MODULE, CPU_HOTSPOT_SUBMIT_REASON;
|
|
268
|
+
var init_cpu_hotspot_profiler = __esm({
|
|
269
|
+
"dist/adapter/helpers/cpu-hotspot-profiler.js"() {
|
|
270
|
+
"use strict";
|
|
271
|
+
CPU_HOTSPOT_PROFILER_MODULE = "cpu-hotspot-profiler";
|
|
272
|
+
CPU_HOTSPOT_SUBMIT_REASON = "cpu-hotspot-submit-reason";
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
217
276
|
// dist/adapter/resources/webgpu-texture-view.js
|
|
218
277
|
var import_core3, WebGPUTextureView;
|
|
219
278
|
var init_webgpu_texture_view = __esm({
|
|
220
279
|
"dist/adapter/resources/webgpu-texture-view.js"() {
|
|
221
280
|
"use strict";
|
|
222
281
|
import_core3 = require("@luma.gl/core");
|
|
282
|
+
init_cpu_hotspot_profiler();
|
|
223
283
|
WebGPUTextureView = class extends import_core3.TextureView {
|
|
224
284
|
device;
|
|
225
285
|
handle;
|
|
@@ -229,8 +289,7 @@ var init_webgpu_texture_view = __esm({
|
|
|
229
289
|
this.device = device;
|
|
230
290
|
this.texture = props.texture;
|
|
231
291
|
this.device.pushErrorScope("validation");
|
|
232
|
-
this.handle =
|
|
233
|
-
this.texture.handle.createView({
|
|
292
|
+
this.handle = this.texture.handle.createView({
|
|
234
293
|
format: this.props.format || this.texture.format,
|
|
235
294
|
dimension: this.props.dimension || this.texture.dimension,
|
|
236
295
|
aspect: this.props.aspect,
|
|
@@ -246,8 +305,42 @@ var init_webgpu_texture_view = __esm({
|
|
|
246
305
|
this.handle.label = this.props.id;
|
|
247
306
|
}
|
|
248
307
|
destroy() {
|
|
308
|
+
if (this.destroyed) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
this.destroyResource();
|
|
249
312
|
this.handle = null;
|
|
250
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Internal-only hook for the cached CanvasContext/PresentationContext swapchain path.
|
|
316
|
+
* Rebuilds the default view when the per-frame canvas texture handle changes, without
|
|
317
|
+
* replacing the long-lived luma.gl wrapper object.
|
|
318
|
+
*/
|
|
319
|
+
_reinitialize(texture) {
|
|
320
|
+
this.texture = texture;
|
|
321
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
322
|
+
this.device.pushErrorScope("validation");
|
|
323
|
+
const createViewStartTime = profiler ? getTimestamp() : 0;
|
|
324
|
+
const handle = this.texture.handle.createView({
|
|
325
|
+
format: this.props.format || this.texture.format,
|
|
326
|
+
dimension: this.props.dimension || this.texture.dimension,
|
|
327
|
+
aspect: this.props.aspect,
|
|
328
|
+
baseMipLevel: this.props.baseMipLevel,
|
|
329
|
+
mipLevelCount: this.props.mipLevelCount,
|
|
330
|
+
baseArrayLayer: this.props.baseArrayLayer,
|
|
331
|
+
arrayLayerCount: this.props.arrayLayerCount
|
|
332
|
+
});
|
|
333
|
+
if (profiler) {
|
|
334
|
+
profiler.textureViewReinitializeCount = (profiler.textureViewReinitializeCount || 0) + 1;
|
|
335
|
+
profiler.textureViewReinitializeTimeMs = (profiler.textureViewReinitializeTimeMs || 0) + (getTimestamp() - createViewStartTime);
|
|
336
|
+
}
|
|
337
|
+
this.device.popErrorScope((error) => {
|
|
338
|
+
this.device.reportError(new Error(`TextureView constructor: ${error.message}`), this)();
|
|
339
|
+
this.device.debug();
|
|
340
|
+
});
|
|
341
|
+
handle.label = this.props.id;
|
|
342
|
+
this.handle = handle;
|
|
343
|
+
}
|
|
251
344
|
};
|
|
252
345
|
}
|
|
253
346
|
});
|
|
@@ -266,11 +359,17 @@ var init_webgpu_texture = __esm({
|
|
|
266
359
|
handle;
|
|
267
360
|
sampler;
|
|
268
361
|
view;
|
|
362
|
+
_allocatedByteLength = 0;
|
|
269
363
|
constructor(device, props) {
|
|
270
|
-
super(device, props);
|
|
364
|
+
super(device, props, { byteAlignment: 256 });
|
|
271
365
|
this.device = device;
|
|
272
|
-
if (
|
|
273
|
-
this.
|
|
366
|
+
if (props.sampler instanceof WebGPUSampler) {
|
|
367
|
+
this.sampler = props.sampler;
|
|
368
|
+
} else if (props.sampler === void 0) {
|
|
369
|
+
this.sampler = this.device.getDefaultSampler();
|
|
370
|
+
} else {
|
|
371
|
+
this.sampler = new WebGPUSampler(this.device, props.sampler || {});
|
|
372
|
+
this.attachResource(this.sampler);
|
|
274
373
|
}
|
|
275
374
|
this.device.pushErrorScope("out-of-memory");
|
|
276
375
|
this.device.pushErrorScope("validation");
|
|
@@ -300,7 +399,6 @@ var init_webgpu_texture = __esm({
|
|
|
300
399
|
this.width = this.handle.width;
|
|
301
400
|
this.height = this.handle.height;
|
|
302
401
|
}
|
|
303
|
-
this.sampler = props.sampler instanceof WebGPUSampler ? props.sampler : new WebGPUSampler(this.device, props.sampler || {});
|
|
304
402
|
this.view = new WebGPUTextureView(this.device, {
|
|
305
403
|
...this.props,
|
|
306
404
|
texture: this,
|
|
@@ -308,46 +406,31 @@ var init_webgpu_texture = __esm({
|
|
|
308
406
|
// Note: arrayLayerCount controls the view of array textures, but does not apply to 3d texture depths
|
|
309
407
|
arrayLayerCount: this.dimension !== "3d" ? this.depth : 1
|
|
310
408
|
});
|
|
409
|
+
this.attachResource(this.view);
|
|
311
410
|
this._initializeData(props.data);
|
|
411
|
+
this._allocatedByteLength = this.getAllocatedByteLength();
|
|
412
|
+
if (!this.props.handle) {
|
|
413
|
+
this.trackAllocatedMemory(this._allocatedByteLength, "Texture");
|
|
414
|
+
} else {
|
|
415
|
+
this.trackReferencedMemory(this._allocatedByteLength, "Texture");
|
|
416
|
+
}
|
|
312
417
|
}
|
|
313
418
|
destroy() {
|
|
314
|
-
|
|
315
|
-
|
|
419
|
+
if (this.destroyed) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (!this.props.handle && this.handle) {
|
|
423
|
+
this.trackDeallocatedMemory("Texture");
|
|
424
|
+
this.handle.destroy();
|
|
425
|
+
} else if (this.handle) {
|
|
426
|
+
this.trackDeallocatedReferencedMemory("Texture");
|
|
427
|
+
}
|
|
428
|
+
this.destroyResource();
|
|
316
429
|
this.handle = null;
|
|
317
430
|
}
|
|
318
431
|
createView(props) {
|
|
319
432
|
return new WebGPUTextureView(this.device, { ...props, texture: this });
|
|
320
433
|
}
|
|
321
|
-
copyImageData(options_) {
|
|
322
|
-
const { width, height, depth } = this;
|
|
323
|
-
const options = this._normalizeCopyImageDataOptions(options_);
|
|
324
|
-
this.device.pushErrorScope("validation");
|
|
325
|
-
this.device.handle.queue.writeTexture(
|
|
326
|
-
// destination: GPUImageCopyTexture
|
|
327
|
-
{
|
|
328
|
-
// texture subresource
|
|
329
|
-
texture: this.handle,
|
|
330
|
-
mipLevel: options.mipLevel,
|
|
331
|
-
aspect: options.aspect,
|
|
332
|
-
// origin to write to
|
|
333
|
-
origin: [options.x, options.y, options.z]
|
|
334
|
-
},
|
|
335
|
-
// data
|
|
336
|
-
options.data,
|
|
337
|
-
// dataLayout: GPUImageDataLayout
|
|
338
|
-
{
|
|
339
|
-
offset: options.byteOffset,
|
|
340
|
-
bytesPerRow: options.bytesPerRow,
|
|
341
|
-
rowsPerImage: options.rowsPerImage
|
|
342
|
-
},
|
|
343
|
-
// size: GPUExtent3D - extents of the content to write
|
|
344
|
-
[width, height, depth]
|
|
345
|
-
);
|
|
346
|
-
this.device.popErrorScope((error) => {
|
|
347
|
-
this.device.reportError(new Error(`copyImageData: ${error.message}`), this)();
|
|
348
|
-
this.device.debug();
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
434
|
copyExternalImage(options_) {
|
|
352
435
|
const options = this._normalizeCopyExternalImageOptions(options_);
|
|
353
436
|
this.device.pushErrorScope("validation");
|
|
@@ -356,20 +439,21 @@ var init_webgpu_texture = __esm({
|
|
|
356
439
|
{
|
|
357
440
|
source: options.image,
|
|
358
441
|
origin: [options.sourceX, options.sourceY],
|
|
359
|
-
flipY:
|
|
442
|
+
flipY: false
|
|
443
|
+
// options.flipY
|
|
360
444
|
},
|
|
361
445
|
// destination: GPUImageCopyTextureTagged
|
|
362
446
|
{
|
|
363
447
|
texture: this.handle,
|
|
364
|
-
origin: [options.x, options.y,
|
|
365
|
-
// options.depth],
|
|
448
|
+
origin: [options.x, options.y, options.z],
|
|
366
449
|
mipLevel: options.mipLevel,
|
|
367
450
|
aspect: options.aspect,
|
|
368
451
|
colorSpace: options.colorSpace,
|
|
369
452
|
premultipliedAlpha: options.premultipliedAlpha
|
|
370
453
|
},
|
|
371
454
|
// copySize: GPUExtent3D
|
|
372
|
-
[options.width, options.height,
|
|
455
|
+
[options.width, options.height, options.depth]
|
|
456
|
+
// depth is always 1 for 2D textures
|
|
373
457
|
);
|
|
374
458
|
this.device.popErrorScope((error) => {
|
|
375
459
|
this.device.reportError(new Error(`copyExternalImage: ${error.message}`), this)();
|
|
@@ -380,6 +464,168 @@ var init_webgpu_texture = __esm({
|
|
|
380
464
|
generateMipmapsWebGL() {
|
|
381
465
|
import_core4.log.warn(`${this}: generateMipmaps not supported in WebGPU`)();
|
|
382
466
|
}
|
|
467
|
+
getImageDataLayout(options) {
|
|
468
|
+
return {
|
|
469
|
+
byteLength: 0,
|
|
470
|
+
bytesPerRow: 0,
|
|
471
|
+
rowsPerImage: 0
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
readBuffer(options = {}, buffer) {
|
|
475
|
+
if (!buffer) {
|
|
476
|
+
throw new Error(`${this} readBuffer requires a destination buffer`);
|
|
477
|
+
}
|
|
478
|
+
const { x, y, z, width, height, depthOrArrayLayers, mipLevel, aspect } = this._getSupportedColorReadOptions(options);
|
|
479
|
+
const byteOffset = options.byteOffset ?? 0;
|
|
480
|
+
const layout = this.computeMemoryLayout({ width, height, depthOrArrayLayers, mipLevel });
|
|
481
|
+
const { byteLength } = layout;
|
|
482
|
+
if (buffer.byteLength < byteOffset + byteLength) {
|
|
483
|
+
throw new Error(`${this} readBuffer target is too small (${buffer.byteLength} < ${byteOffset + byteLength})`);
|
|
484
|
+
}
|
|
485
|
+
const gpuDevice = this.device.handle;
|
|
486
|
+
this.device.pushErrorScope("validation");
|
|
487
|
+
const commandEncoder = gpuDevice.createCommandEncoder();
|
|
488
|
+
this.copyToBuffer(commandEncoder, { x, y, z, width, height, depthOrArrayLayers, mipLevel, aspect, byteOffset }, buffer);
|
|
489
|
+
const commandBuffer = commandEncoder.finish();
|
|
490
|
+
this.device.handle.queue.submit([commandBuffer]);
|
|
491
|
+
this.device.popErrorScope((error) => {
|
|
492
|
+
this.device.reportError(new Error(`${this} readBuffer: ${error.message}`), this)();
|
|
493
|
+
this.device.debug();
|
|
494
|
+
});
|
|
495
|
+
return buffer;
|
|
496
|
+
}
|
|
497
|
+
async readDataAsync(options = {}) {
|
|
498
|
+
throw new Error(`${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`);
|
|
499
|
+
}
|
|
500
|
+
copyToBuffer(commandEncoder, options = {}, buffer) {
|
|
501
|
+
const { byteOffset = 0, bytesPerRow: requestedBytesPerRow, rowsPerImage: requestedRowsPerImage, ...textureReadOptions } = options;
|
|
502
|
+
const { x, y, z, width, height, depthOrArrayLayers, mipLevel, aspect } = this._getSupportedColorReadOptions(textureReadOptions);
|
|
503
|
+
const layout = this.computeMemoryLayout({ width, height, depthOrArrayLayers, mipLevel });
|
|
504
|
+
const effectiveBytesPerRow = requestedBytesPerRow ?? layout.bytesPerRow;
|
|
505
|
+
const effectiveRowsPerImage = requestedRowsPerImage ?? layout.rowsPerImage;
|
|
506
|
+
const webgpuBuffer = buffer;
|
|
507
|
+
commandEncoder.copyTextureToBuffer({
|
|
508
|
+
texture: this.handle,
|
|
509
|
+
origin: { x, y, z },
|
|
510
|
+
mipLevel,
|
|
511
|
+
aspect
|
|
512
|
+
}, {
|
|
513
|
+
buffer: webgpuBuffer.handle,
|
|
514
|
+
offset: byteOffset,
|
|
515
|
+
bytesPerRow: effectiveBytesPerRow,
|
|
516
|
+
rowsPerImage: effectiveRowsPerImage
|
|
517
|
+
}, {
|
|
518
|
+
width,
|
|
519
|
+
height,
|
|
520
|
+
depthOrArrayLayers
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
writeBuffer(buffer, options_ = {}) {
|
|
524
|
+
const options = this._normalizeTextureWriteOptions(options_);
|
|
525
|
+
const { x, y, z, width, height, depthOrArrayLayers, mipLevel, aspect, byteOffset, bytesPerRow, rowsPerImage } = options;
|
|
526
|
+
const gpuDevice = this.device.handle;
|
|
527
|
+
this.device.pushErrorScope("validation");
|
|
528
|
+
const commandEncoder = gpuDevice.createCommandEncoder();
|
|
529
|
+
commandEncoder.copyBufferToTexture({
|
|
530
|
+
buffer: buffer.handle,
|
|
531
|
+
offset: byteOffset,
|
|
532
|
+
bytesPerRow,
|
|
533
|
+
rowsPerImage
|
|
534
|
+
}, {
|
|
535
|
+
texture: this.handle,
|
|
536
|
+
origin: { x, y, z },
|
|
537
|
+
mipLevel,
|
|
538
|
+
aspect
|
|
539
|
+
}, { width, height, depthOrArrayLayers });
|
|
540
|
+
const commandBuffer = commandEncoder.finish();
|
|
541
|
+
this.device.handle.queue.submit([commandBuffer]);
|
|
542
|
+
this.device.popErrorScope((error) => {
|
|
543
|
+
this.device.reportError(new Error(`${this} writeBuffer: ${error.message}`), this)();
|
|
544
|
+
this.device.debug();
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
writeData(data, options_ = {}) {
|
|
548
|
+
const device = this.device;
|
|
549
|
+
const options = this._normalizeTextureWriteOptions(options_);
|
|
550
|
+
const { x, y, z, width, height, depthOrArrayLayers, mipLevel, aspect, byteOffset } = options;
|
|
551
|
+
const source = data;
|
|
552
|
+
const formatInfo = this.device.getTextureFormatInfo(this.format);
|
|
553
|
+
const packedSourceLayout = import_core4.textureFormatDecoder.computeMemoryLayout({
|
|
554
|
+
format: this.format,
|
|
555
|
+
width,
|
|
556
|
+
height,
|
|
557
|
+
depth: depthOrArrayLayers,
|
|
558
|
+
byteAlignment: 1
|
|
559
|
+
});
|
|
560
|
+
const bytesPerRow = options_.bytesPerRow ?? packedSourceLayout.bytesPerRow;
|
|
561
|
+
const rowsPerImage = options_.rowsPerImage ?? packedSourceLayout.rowsPerImage;
|
|
562
|
+
let copyWidth = width;
|
|
563
|
+
let copyHeight = height;
|
|
564
|
+
if (formatInfo.compressed) {
|
|
565
|
+
const blockWidth = formatInfo.blockWidth || 1;
|
|
566
|
+
const blockHeight = formatInfo.blockHeight || 1;
|
|
567
|
+
copyWidth = Math.ceil(width / blockWidth) * blockWidth;
|
|
568
|
+
copyHeight = Math.ceil(height / blockHeight) * blockHeight;
|
|
569
|
+
}
|
|
570
|
+
this.device.pushErrorScope("validation");
|
|
571
|
+
device.handle.queue.writeTexture({
|
|
572
|
+
texture: this.handle,
|
|
573
|
+
mipLevel,
|
|
574
|
+
aspect,
|
|
575
|
+
origin: { x, y, z }
|
|
576
|
+
}, source, {
|
|
577
|
+
offset: byteOffset,
|
|
578
|
+
bytesPerRow,
|
|
579
|
+
rowsPerImage
|
|
580
|
+
}, { width: copyWidth, height: copyHeight, depthOrArrayLayers });
|
|
581
|
+
this.device.popErrorScope((error) => {
|
|
582
|
+
this.device.reportError(new Error(`${this} writeData: ${error.message}`), this)();
|
|
583
|
+
this.device.debug();
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Internal-only hook for the cached CanvasContext/PresentationContext swapchain path.
|
|
588
|
+
* Rebinds this handle-backed texture wrapper to the current per-frame canvas texture
|
|
589
|
+
* without allocating a new luma.gl Texture or TextureView wrapper.
|
|
590
|
+
*/
|
|
591
|
+
_reinitialize(handle, props) {
|
|
592
|
+
const nextWidth = (props == null ? void 0 : props.width) ?? handle.width ?? this.width;
|
|
593
|
+
const nextHeight = (props == null ? void 0 : props.height) ?? handle.height ?? this.height;
|
|
594
|
+
const nextDepth = (props == null ? void 0 : props.depth) ?? this.depth;
|
|
595
|
+
const nextFormat = (props == null ? void 0 : props.format) ?? this.format;
|
|
596
|
+
const allocationMayHaveChanged = nextWidth !== this.width || nextHeight !== this.height || nextDepth !== this.depth || nextFormat !== this.format;
|
|
597
|
+
handle.label ||= this.id;
|
|
598
|
+
this.handle = handle;
|
|
599
|
+
this.width = nextWidth;
|
|
600
|
+
this.height = nextHeight;
|
|
601
|
+
if ((props == null ? void 0 : props.depth) !== void 0) {
|
|
602
|
+
this.depth = nextDepth;
|
|
603
|
+
}
|
|
604
|
+
if ((props == null ? void 0 : props.format) !== void 0) {
|
|
605
|
+
this.format = nextFormat;
|
|
606
|
+
}
|
|
607
|
+
this.props.handle = handle;
|
|
608
|
+
if ((props == null ? void 0 : props.width) !== void 0) {
|
|
609
|
+
this.props.width = props.width;
|
|
610
|
+
}
|
|
611
|
+
if ((props == null ? void 0 : props.height) !== void 0) {
|
|
612
|
+
this.props.height = props.height;
|
|
613
|
+
}
|
|
614
|
+
if ((props == null ? void 0 : props.depth) !== void 0) {
|
|
615
|
+
this.props.depth = props.depth;
|
|
616
|
+
}
|
|
617
|
+
if ((props == null ? void 0 : props.format) !== void 0) {
|
|
618
|
+
this.props.format = props.format;
|
|
619
|
+
}
|
|
620
|
+
if (allocationMayHaveChanged) {
|
|
621
|
+
const nextAllocation = this.getAllocatedByteLength();
|
|
622
|
+
if (nextAllocation !== this._allocatedByteLength) {
|
|
623
|
+
this._allocatedByteLength = nextAllocation;
|
|
624
|
+
this.trackReferencedMemory(nextAllocation, "Texture");
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
this.view._reinitialize(this);
|
|
628
|
+
}
|
|
383
629
|
};
|
|
384
630
|
}
|
|
385
631
|
});
|
|
@@ -460,7 +706,19 @@ var init_webgpu_shader = __esm({
|
|
|
460
706
|
}
|
|
461
707
|
/** Returns compilation info for this shader */
|
|
462
708
|
async getCompilationInfo() {
|
|
463
|
-
const
|
|
709
|
+
const handle = this.handle;
|
|
710
|
+
if (!handle) {
|
|
711
|
+
return [];
|
|
712
|
+
}
|
|
713
|
+
let compilationInfo;
|
|
714
|
+
try {
|
|
715
|
+
compilationInfo = await handle.getCompilationInfo();
|
|
716
|
+
} catch (error) {
|
|
717
|
+
if (this.device.shouldIgnoreDroppedInstanceError(error, "getCompilationInfo")) {
|
|
718
|
+
return [];
|
|
719
|
+
}
|
|
720
|
+
throw error;
|
|
721
|
+
}
|
|
464
722
|
return compilationInfo.messages;
|
|
465
723
|
}
|
|
466
724
|
};
|
|
@@ -551,6 +809,7 @@ var init_webgpu_parameters = __esm({
|
|
|
551
809
|
const depthStencil = addDepthStencil(descriptor);
|
|
552
810
|
depthStencil.format = value;
|
|
553
811
|
},
|
|
812
|
+
clearDepth: notSupported,
|
|
554
813
|
depthBias: (_, value, descriptor) => {
|
|
555
814
|
const depthStencil = addDepthStencil(descriptor);
|
|
556
815
|
depthStencil.depthBias = value;
|
|
@@ -689,90 +948,6 @@ var init_webgpu_parameters = __esm({
|
|
|
689
948
|
}
|
|
690
949
|
});
|
|
691
950
|
|
|
692
|
-
// dist/adapter/helpers/get-bind-group.js
|
|
693
|
-
function getBindGroup(device, bindGroupLayout, shaderLayout, bindings) {
|
|
694
|
-
const entries = getBindGroupEntries(bindings, shaderLayout);
|
|
695
|
-
device.pushErrorScope("validation");
|
|
696
|
-
const bindGroup = device.createBindGroup({
|
|
697
|
-
layout: bindGroupLayout,
|
|
698
|
-
entries
|
|
699
|
-
});
|
|
700
|
-
device.popErrorScope().then((error) => {
|
|
701
|
-
if (error) {
|
|
702
|
-
import_core8.log.error(`bindGroup creation: ${error.message}`, bindGroup)();
|
|
703
|
-
}
|
|
704
|
-
});
|
|
705
|
-
return bindGroup;
|
|
706
|
-
}
|
|
707
|
-
function getShaderLayoutBinding(shaderLayout, bindingName, options) {
|
|
708
|
-
const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName || `${binding.name.toLocaleLowerCase()}uniforms` === bindingName.toLocaleLowerCase());
|
|
709
|
-
if (!bindingLayout && !(options == null ? void 0 : options.ignoreWarnings)) {
|
|
710
|
-
import_core8.log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
|
|
711
|
-
}
|
|
712
|
-
return bindingLayout || null;
|
|
713
|
-
}
|
|
714
|
-
function getBindGroupEntries(bindings, shaderLayout) {
|
|
715
|
-
const entries = [];
|
|
716
|
-
for (const [bindingName, value] of Object.entries(bindings)) {
|
|
717
|
-
let bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
|
|
718
|
-
if (bindingLayout) {
|
|
719
|
-
const entry = getBindGroupEntry(value, bindingLayout.location);
|
|
720
|
-
if (entry) {
|
|
721
|
-
entries.push(entry);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
if (value instanceof import_core8.Texture) {
|
|
725
|
-
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`, {
|
|
726
|
-
ignoreWarnings: true
|
|
727
|
-
});
|
|
728
|
-
if (bindingLayout) {
|
|
729
|
-
const entry = getBindGroupEntry(value, bindingLayout.location, { sampler: true });
|
|
730
|
-
if (entry) {
|
|
731
|
-
entries.push(entry);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
return entries;
|
|
737
|
-
}
|
|
738
|
-
function getBindGroupEntry(binding, index, options) {
|
|
739
|
-
if (binding instanceof import_core8.Buffer) {
|
|
740
|
-
return {
|
|
741
|
-
binding: index,
|
|
742
|
-
resource: {
|
|
743
|
-
buffer: binding.handle
|
|
744
|
-
}
|
|
745
|
-
};
|
|
746
|
-
}
|
|
747
|
-
if (binding instanceof import_core8.Sampler) {
|
|
748
|
-
return {
|
|
749
|
-
binding: index,
|
|
750
|
-
resource: binding.handle
|
|
751
|
-
};
|
|
752
|
-
}
|
|
753
|
-
if (binding instanceof import_core8.Texture) {
|
|
754
|
-
if (options == null ? void 0 : options.sampler) {
|
|
755
|
-
return {
|
|
756
|
-
binding: index,
|
|
757
|
-
resource: binding.sampler.handle
|
|
758
|
-
};
|
|
759
|
-
}
|
|
760
|
-
return {
|
|
761
|
-
binding: index,
|
|
762
|
-
resource: binding.view.handle
|
|
763
|
-
};
|
|
764
|
-
}
|
|
765
|
-
import_core8.log.warn(`invalid binding ${name}`, binding);
|
|
766
|
-
return null;
|
|
767
|
-
}
|
|
768
|
-
var import_core8;
|
|
769
|
-
var init_get_bind_group = __esm({
|
|
770
|
-
"dist/adapter/helpers/get-bind-group.js"() {
|
|
771
|
-
"use strict";
|
|
772
|
-
import_core8 = require("@luma.gl/core");
|
|
773
|
-
}
|
|
774
|
-
});
|
|
775
|
-
|
|
776
951
|
// dist/adapter/helpers/get-vertex-buffer-layout.js
|
|
777
952
|
function getWebGPUVertexFormat(format) {
|
|
778
953
|
if (format.endsWith("-webgl")) {
|
|
@@ -780,9 +955,10 @@ function getWebGPUVertexFormat(format) {
|
|
|
780
955
|
}
|
|
781
956
|
return format;
|
|
782
957
|
}
|
|
783
|
-
function getVertexBufferLayout(shaderLayout, bufferLayout) {
|
|
958
|
+
function getVertexBufferLayout(shaderLayout, bufferLayout, options) {
|
|
784
959
|
const vertexBufferLayouts = [];
|
|
785
960
|
const usedAttributes = /* @__PURE__ */ new Set();
|
|
961
|
+
const shaderAttributes = shaderLayout.attributes || [];
|
|
786
962
|
for (const mapping of bufferLayout) {
|
|
787
963
|
const vertexAttributes = [];
|
|
788
964
|
let stepMode = "vertex";
|
|
@@ -791,7 +967,7 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
|
|
|
791
967
|
if (mapping.attributes) {
|
|
792
968
|
for (const attributeMapping of mapping.attributes) {
|
|
793
969
|
const attributeName = attributeMapping.attribute;
|
|
794
|
-
const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
|
|
970
|
+
const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes, options);
|
|
795
971
|
const location = attributeLayout == null ? void 0 : attributeLayout.location;
|
|
796
972
|
format = attributeMapping.format || mapping.format;
|
|
797
973
|
stepMode = (attributeLayout == null ? void 0 : attributeLayout.stepMode) || ((attributeLayout == null ? void 0 : attributeLayout.name.startsWith("instance")) ? "instance" : "vertex");
|
|
@@ -800,14 +976,14 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
|
|
|
800
976
|
offset: attributeMapping.byteOffset,
|
|
801
977
|
shaderLocation: location
|
|
802
978
|
});
|
|
803
|
-
byteStride +=
|
|
979
|
+
byteStride += import_core8.vertexFormatDecoder.getVertexFormatInfo(format).byteLength;
|
|
804
980
|
}
|
|
805
981
|
} else {
|
|
806
|
-
const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);
|
|
982
|
+
const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes, options);
|
|
807
983
|
if (!attributeLayout) {
|
|
808
984
|
continue;
|
|
809
985
|
}
|
|
810
|
-
byteStride =
|
|
986
|
+
byteStride = import_core8.vertexFormatDecoder.getVertexFormatInfo(format).byteLength;
|
|
811
987
|
stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
|
|
812
988
|
vertexAttributes.push({
|
|
813
989
|
format: getWebGPUVertexFormat(format),
|
|
@@ -822,10 +998,10 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
|
|
|
822
998
|
attributes: vertexAttributes
|
|
823
999
|
});
|
|
824
1000
|
}
|
|
825
|
-
for (const attribute of
|
|
1001
|
+
for (const attribute of shaderAttributes) {
|
|
826
1002
|
if (!usedAttributes.has(attribute.name)) {
|
|
827
1003
|
vertexBufferLayouts.push({
|
|
828
|
-
arrayStride:
|
|
1004
|
+
arrayStride: import_core8.vertexFormatDecoder.getVertexFormatInfo("float32x3").byteLength,
|
|
829
1005
|
stepMode: attribute.stepMode || (attribute.name.startsWith("instance") ? "instance" : "vertex"),
|
|
830
1006
|
attributes: [
|
|
831
1007
|
{
|
|
@@ -844,90 +1020,122 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
|
|
|
844
1020
|
});
|
|
845
1021
|
return vertexBufferLayouts;
|
|
846
1022
|
}
|
|
847
|
-
function findAttributeLayout(shaderLayout,
|
|
848
|
-
|
|
1023
|
+
function findAttributeLayout(shaderLayout, name, attributeNames, options) {
|
|
1024
|
+
var _a;
|
|
1025
|
+
const attribute = (_a = shaderLayout.attributes) == null ? void 0 : _a.find((attribute_) => attribute_.name === name);
|
|
849
1026
|
if (!attribute) {
|
|
850
|
-
|
|
1027
|
+
const pipelineContext = (options == null ? void 0 : options.pipelineId) ? `RenderPipeline(${options.pipelineId})` : "RenderPipeline";
|
|
1028
|
+
import_core8.log.warn(`${pipelineContext}: Ignoring "${name}" attribute, since it is not present in shader layout.`)();
|
|
851
1029
|
return null;
|
|
852
1030
|
}
|
|
853
1031
|
if (attributeNames) {
|
|
854
|
-
if (attributeNames.has(
|
|
855
|
-
throw new Error(`Found multiple entries for attribute: ${
|
|
1032
|
+
if (attributeNames.has(name)) {
|
|
1033
|
+
throw new Error(`Found multiple entries for attribute: ${name}`);
|
|
856
1034
|
}
|
|
857
|
-
attributeNames.add(
|
|
1035
|
+
attributeNames.add(name);
|
|
858
1036
|
}
|
|
859
1037
|
return attribute;
|
|
860
1038
|
}
|
|
861
|
-
var
|
|
1039
|
+
var import_core8;
|
|
862
1040
|
var init_get_vertex_buffer_layout = __esm({
|
|
863
1041
|
"dist/adapter/helpers/get-vertex-buffer-layout.js"() {
|
|
864
1042
|
"use strict";
|
|
865
|
-
|
|
1043
|
+
import_core8 = require("@luma.gl/core");
|
|
866
1044
|
}
|
|
867
1045
|
});
|
|
868
1046
|
|
|
869
1047
|
// dist/adapter/resources/webgpu-render-pipeline.js
|
|
870
|
-
|
|
1048
|
+
function createBindGroupCacheKeys(bindingsByGroup) {
|
|
1049
|
+
const bindGroupCacheKeys = {};
|
|
1050
|
+
for (const [groupKey, groupBindings] of Object.entries(bindingsByGroup)) {
|
|
1051
|
+
if (groupBindings && Object.keys(groupBindings).length > 0) {
|
|
1052
|
+
bindGroupCacheKeys[Number(groupKey)] = {};
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
return bindGroupCacheKeys;
|
|
1056
|
+
}
|
|
1057
|
+
var import_core9, WebGPURenderPipeline;
|
|
871
1058
|
var init_webgpu_render_pipeline = __esm({
|
|
872
1059
|
"dist/adapter/resources/webgpu-render-pipeline.js"() {
|
|
873
1060
|
"use strict";
|
|
874
|
-
|
|
1061
|
+
import_core9 = require("@luma.gl/core");
|
|
875
1062
|
init_webgpu_parameters();
|
|
876
1063
|
init_convert_texture_format();
|
|
877
|
-
init_get_bind_group();
|
|
878
1064
|
init_get_vertex_buffer_layout();
|
|
879
|
-
WebGPURenderPipeline = class extends
|
|
1065
|
+
WebGPURenderPipeline = class extends import_core9.RenderPipeline {
|
|
880
1066
|
device;
|
|
881
1067
|
handle;
|
|
1068
|
+
descriptor;
|
|
882
1069
|
vs;
|
|
883
1070
|
fs = null;
|
|
884
|
-
/**
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
_bindGroup = null;
|
|
1071
|
+
/** Compatibility path for direct pipeline.setBindings() usage */
|
|
1072
|
+
_bindingsByGroup;
|
|
1073
|
+
_bindGroupCacheKeysByGroup = {};
|
|
888
1074
|
get [Symbol.toStringTag]() {
|
|
889
1075
|
return "WebGPURenderPipeline";
|
|
890
1076
|
}
|
|
891
1077
|
constructor(device, props) {
|
|
892
1078
|
super(device, props);
|
|
893
1079
|
this.device = device;
|
|
1080
|
+
this.shaderLayout ||= this.device.getShaderLayout(props.vs.source) || {
|
|
1081
|
+
attributes: [],
|
|
1082
|
+
bindings: []
|
|
1083
|
+
};
|
|
894
1084
|
this.handle = this.props.handle;
|
|
1085
|
+
let descriptor = null;
|
|
895
1086
|
if (!this.handle) {
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1087
|
+
descriptor = this._getRenderPipelineDescriptor();
|
|
1088
|
+
import_core9.log.groupCollapsed(1, `new WebGPURenderPipeline(${this.id})`)();
|
|
1089
|
+
import_core9.log.probe(1, JSON.stringify(descriptor, null, 2))();
|
|
1090
|
+
import_core9.log.groupEnd(1)();
|
|
900
1091
|
this.device.pushErrorScope("validation");
|
|
901
1092
|
this.handle = this.device.handle.createRenderPipeline(descriptor);
|
|
902
1093
|
this.device.popErrorScope((error) => {
|
|
1094
|
+
this.linkStatus = "error";
|
|
903
1095
|
this.device.reportError(new Error(`${this} creation failed:
|
|
904
1096
|
"${error.message}"`), this)();
|
|
905
1097
|
this.device.debug();
|
|
906
1098
|
});
|
|
907
1099
|
}
|
|
1100
|
+
this.descriptor = descriptor;
|
|
908
1101
|
this.handle.label = this.props.id;
|
|
1102
|
+
this.linkStatus = "success";
|
|
909
1103
|
this.vs = props.vs;
|
|
910
1104
|
this.fs = props.fs;
|
|
911
|
-
this.
|
|
1105
|
+
this._bindingsByGroup = props.bindGroups || (0, import_core9.normalizeBindingsByGroup)(this.shaderLayout, props.bindings);
|
|
1106
|
+
this._bindGroupCacheKeysByGroup = createBindGroupCacheKeys(this._bindingsByGroup);
|
|
912
1107
|
}
|
|
913
1108
|
destroy() {
|
|
914
1109
|
this.handle = null;
|
|
915
1110
|
}
|
|
916
1111
|
/**
|
|
917
|
-
*
|
|
918
|
-
*
|
|
1112
|
+
* Compatibility shim for code paths that still set bindings on the pipeline.
|
|
1113
|
+
* The shared-model path passes bindings per draw and does not rely on this state.
|
|
919
1114
|
*/
|
|
920
1115
|
setBindings(bindings) {
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
1116
|
+
const nextBindingsByGroup = (0, import_core9.normalizeBindingsByGroup)(this.shaderLayout, bindings);
|
|
1117
|
+
for (const [groupKey, groupBindings] of Object.entries(nextBindingsByGroup)) {
|
|
1118
|
+
const group = Number(groupKey);
|
|
1119
|
+
for (const [name, binding] of Object.entries(groupBindings || {})) {
|
|
1120
|
+
const currentGroupBindings = this._bindingsByGroup[group] || {};
|
|
1121
|
+
if (currentGroupBindings[name] !== binding) {
|
|
1122
|
+
if (!this._bindingsByGroup[group] || this._bindingsByGroup[group] === currentGroupBindings) {
|
|
1123
|
+
this._bindingsByGroup[group] = { ...currentGroupBindings };
|
|
1124
|
+
}
|
|
1125
|
+
this._bindingsByGroup[group][name] = binding;
|
|
1126
|
+
this._bindGroupCacheKeysByGroup[group] = {};
|
|
1127
|
+
}
|
|
924
1128
|
}
|
|
925
1129
|
}
|
|
926
|
-
Object.assign(this._bindings, bindings);
|
|
927
1130
|
}
|
|
928
1131
|
/** @todo - should this be moved to renderpass? */
|
|
929
1132
|
draw(options) {
|
|
1133
|
+
if (this.isErrored) {
|
|
1134
|
+
import_core9.log.info(2, `RenderPipeline:${this.id}.draw() aborted - pipeline initialization failed`)();
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
930
1137
|
const webgpuRenderPass = options.renderPass;
|
|
1138
|
+
const instanceCount = options.instanceCount && options.instanceCount > 0 ? options.instanceCount : 1;
|
|
931
1139
|
this.device.pushErrorScope("validation");
|
|
932
1140
|
webgpuRenderPass.handle.setPipeline(this.handle);
|
|
933
1141
|
this.device.popErrorScope((error) => {
|
|
@@ -935,32 +1143,27 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
935
1143
|
"${error.message}"`), this)();
|
|
936
1144
|
this.device.debug();
|
|
937
1145
|
});
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
1146
|
+
const hasExplicitBindings = Boolean(options.bindGroups || options.bindings);
|
|
1147
|
+
const bindGroups = (0, import_core9._getDefaultBindGroupFactory)(this.device).getBindGroups(this, hasExplicitBindings ? options.bindGroups || options.bindings : this._bindingsByGroup, hasExplicitBindings ? options._bindGroupCacheKeys : this._bindGroupCacheKeysByGroup);
|
|
1148
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1149
|
+
if (bindGroup) {
|
|
1150
|
+
webgpuRenderPass.handle.setBindGroup(Number(group), bindGroup);
|
|
1151
|
+
}
|
|
941
1152
|
}
|
|
942
1153
|
options.vertexArray.bindBeforeRender(options.renderPass);
|
|
943
1154
|
if (options.indexCount) {
|
|
944
|
-
webgpuRenderPass.handle.drawIndexed(options.indexCount,
|
|
1155
|
+
webgpuRenderPass.handle.drawIndexed(options.indexCount, instanceCount, options.firstIndex || 0, options.baseVertex || 0, options.firstInstance || 0);
|
|
945
1156
|
} else {
|
|
946
|
-
webgpuRenderPass.handle.draw(
|
|
947
|
-
options.vertexCount || 0,
|
|
948
|
-
options.instanceCount || 1,
|
|
949
|
-
// If 0, nothing will be drawn
|
|
950
|
-
options.firstInstance
|
|
951
|
-
);
|
|
1157
|
+
webgpuRenderPass.handle.draw(options.vertexCount || 0, instanceCount, options.firstVertex || 0, options.firstInstance || 0);
|
|
952
1158
|
}
|
|
953
1159
|
options.vertexArray.unbindAfterRender(options.renderPass);
|
|
954
1160
|
return true;
|
|
955
1161
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
|
|
962
|
-
this._bindGroup = this._bindGroup || getBindGroup(this.device.handle, this._bindGroupLayout, this.shaderLayout, this._bindings);
|
|
963
|
-
return this._bindGroup;
|
|
1162
|
+
_getBindingsByGroupWebGPU() {
|
|
1163
|
+
return this._bindingsByGroup;
|
|
1164
|
+
}
|
|
1165
|
+
_getBindGroupCacheKeysWebGPU() {
|
|
1166
|
+
return this._bindGroupCacheKeysByGroup;
|
|
964
1167
|
}
|
|
965
1168
|
/**
|
|
966
1169
|
* Populate the complex WebGPU GPURenderPipelineDescriptor
|
|
@@ -969,7 +1172,9 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
969
1172
|
const vertex = {
|
|
970
1173
|
module: this.props.vs.handle,
|
|
971
1174
|
entryPoint: this.props.vertexEntryPoint || "main",
|
|
972
|
-
buffers: getVertexBufferLayout(this.shaderLayout, this.props.bufferLayout
|
|
1175
|
+
buffers: getVertexBufferLayout(this.shaderLayout, this.props.bufferLayout, {
|
|
1176
|
+
pipelineId: this.id
|
|
1177
|
+
})
|
|
973
1178
|
};
|
|
974
1179
|
const targets = [];
|
|
975
1180
|
if (this.props.colorAttachmentFormats) {
|
|
@@ -1009,12 +1214,12 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
1009
1214
|
});
|
|
1010
1215
|
|
|
1011
1216
|
// dist/adapter/resources/webgpu-framebuffer.js
|
|
1012
|
-
var
|
|
1217
|
+
var import_core10, WebGPUFramebuffer;
|
|
1013
1218
|
var init_webgpu_framebuffer = __esm({
|
|
1014
1219
|
"dist/adapter/resources/webgpu-framebuffer.js"() {
|
|
1015
1220
|
"use strict";
|
|
1016
|
-
|
|
1017
|
-
WebGPUFramebuffer = class extends
|
|
1221
|
+
import_core10 = require("@luma.gl/core");
|
|
1222
|
+
WebGPUFramebuffer = class extends import_core10.Framebuffer {
|
|
1018
1223
|
device;
|
|
1019
1224
|
handle = null;
|
|
1020
1225
|
colorAttachments = [];
|
|
@@ -1026,25 +1231,37 @@ var init_webgpu_framebuffer = __esm({
|
|
|
1026
1231
|
}
|
|
1027
1232
|
updateAttachments() {
|
|
1028
1233
|
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Internal-only hook for the cached CanvasContext/PresentationContext swapchain path.
|
|
1236
|
+
* Rebinds the long-lived default framebuffer wrapper to the current per-frame color view
|
|
1237
|
+
* and optional depth attachment without allocating a new luma.gl Framebuffer object.
|
|
1238
|
+
*/
|
|
1239
|
+
_reinitialize(colorAttachment, depthStencilAttachment) {
|
|
1240
|
+
this.colorAttachments[0] = colorAttachment;
|
|
1241
|
+
this.depthStencilAttachment = depthStencilAttachment;
|
|
1242
|
+
this.width = colorAttachment.texture.width;
|
|
1243
|
+
this.height = colorAttachment.texture.height;
|
|
1244
|
+
this.props.width = this.width;
|
|
1245
|
+
this.props.height = this.height;
|
|
1246
|
+
this.props.colorAttachments = [colorAttachment.texture];
|
|
1247
|
+
this.props.depthStencilAttachment = (depthStencilAttachment == null ? void 0 : depthStencilAttachment.texture) || null;
|
|
1248
|
+
}
|
|
1029
1249
|
};
|
|
1030
1250
|
}
|
|
1031
1251
|
});
|
|
1032
1252
|
|
|
1033
1253
|
// dist/adapter/resources/webgpu-compute-pipeline.js
|
|
1034
|
-
var
|
|
1254
|
+
var import_core11, EMPTY_BIND_GROUPS, WebGPUComputePipeline;
|
|
1035
1255
|
var init_webgpu_compute_pipeline = __esm({
|
|
1036
1256
|
"dist/adapter/resources/webgpu-compute-pipeline.js"() {
|
|
1037
1257
|
"use strict";
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
WebGPUComputePipeline = class extends
|
|
1258
|
+
import_core11 = require("@luma.gl/core");
|
|
1259
|
+
EMPTY_BIND_GROUPS = {};
|
|
1260
|
+
WebGPUComputePipeline = class extends import_core11.ComputePipeline {
|
|
1041
1261
|
device;
|
|
1042
1262
|
handle;
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
_bindGroup = null;
|
|
1046
|
-
/** For internal use to create BindGroups */
|
|
1047
|
-
_bindings = {};
|
|
1263
|
+
_bindingsByGroup;
|
|
1264
|
+
_bindGroupCacheKeysByGroup;
|
|
1048
1265
|
constructor(device, props) {
|
|
1049
1266
|
super(device, props);
|
|
1050
1267
|
this.device = device;
|
|
@@ -1058,34 +1275,53 @@ var init_webgpu_compute_pipeline = __esm({
|
|
|
1058
1275
|
},
|
|
1059
1276
|
layout: "auto"
|
|
1060
1277
|
});
|
|
1278
|
+
this._bindingsByGroup = EMPTY_BIND_GROUPS;
|
|
1279
|
+
this._bindGroupCacheKeysByGroup = {};
|
|
1061
1280
|
}
|
|
1062
1281
|
/**
|
|
1063
1282
|
* @todo Use renderpass.setBindings() ?
|
|
1064
1283
|
* @todo Do we want to expose BindGroups in the API and remove this?
|
|
1065
1284
|
*/
|
|
1066
1285
|
setBindings(bindings) {
|
|
1067
|
-
|
|
1286
|
+
const nextBindingsByGroup = (0, import_core11.normalizeBindingsByGroup)(this.shaderLayout, bindings);
|
|
1287
|
+
for (const [groupKey, groupBindings] of Object.entries(nextBindingsByGroup)) {
|
|
1288
|
+
const group = Number(groupKey);
|
|
1289
|
+
for (const [name, binding] of Object.entries(groupBindings || {})) {
|
|
1290
|
+
const currentGroupBindings = this._bindingsByGroup[group] || {};
|
|
1291
|
+
if (currentGroupBindings[name] !== binding) {
|
|
1292
|
+
if (!this._bindingsByGroup[group] || this._bindingsByGroup[group] === currentGroupBindings) {
|
|
1293
|
+
this._bindingsByGroup[group] = { ...currentGroupBindings };
|
|
1294
|
+
}
|
|
1295
|
+
this._bindingsByGroup[group][name] = binding;
|
|
1296
|
+
this._bindGroupCacheKeysByGroup[group] = {};
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1068
1300
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
this.
|
|
1072
|
-
|
|
1073
|
-
|
|
1301
|
+
_getBindGroups(bindings, bindGroupCacheKeys) {
|
|
1302
|
+
const hasExplicitBindings = Boolean(bindings);
|
|
1303
|
+
return (0, import_core11._getDefaultBindGroupFactory)(this.device).getBindGroups(this, hasExplicitBindings ? bindings : this._bindingsByGroup, hasExplicitBindings ? bindGroupCacheKeys : this._bindGroupCacheKeysByGroup);
|
|
1304
|
+
}
|
|
1305
|
+
_getBindingsByGroupWebGPU() {
|
|
1306
|
+
return this._bindingsByGroup;
|
|
1307
|
+
}
|
|
1308
|
+
_getBindGroupCacheKeysWebGPU() {
|
|
1309
|
+
return this._bindGroupCacheKeysByGroup;
|
|
1074
1310
|
}
|
|
1075
1311
|
};
|
|
1076
1312
|
}
|
|
1077
1313
|
});
|
|
1078
1314
|
|
|
1079
1315
|
// dist/adapter/resources/webgpu-vertex-array.js
|
|
1080
|
-
var
|
|
1316
|
+
var import_core12, import_env, WebGPUVertexArray;
|
|
1081
1317
|
var init_webgpu_vertex_array = __esm({
|
|
1082
1318
|
"dist/adapter/resources/webgpu-vertex-array.js"() {
|
|
1083
1319
|
"use strict";
|
|
1084
|
-
|
|
1320
|
+
import_core12 = require("@luma.gl/core");
|
|
1085
1321
|
import_env = require("@probe.gl/env");
|
|
1086
|
-
WebGPUVertexArray = class extends
|
|
1322
|
+
WebGPUVertexArray = class extends import_core12.VertexArray {
|
|
1087
1323
|
get [Symbol.toStringTag]() {
|
|
1088
|
-
return "
|
|
1324
|
+
return "VertexArray";
|
|
1089
1325
|
}
|
|
1090
1326
|
device;
|
|
1091
1327
|
/** Vertex Array is just a helper class under WebGPU */
|
|
@@ -1112,7 +1348,7 @@ var init_webgpu_vertex_array = __esm({
|
|
|
1112
1348
|
const webgpuRenderPass = renderPass;
|
|
1113
1349
|
const webgpuIndexBuffer = this.indexBuffer;
|
|
1114
1350
|
if (webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.handle) {
|
|
1115
|
-
|
|
1351
|
+
import_core12.log.info(3, "setting index buffer", webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.handle, webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.indexType)();
|
|
1116
1352
|
webgpuRenderPass.handle.setIndexBuffer(
|
|
1117
1353
|
webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.handle,
|
|
1118
1354
|
// @ts-expect-error TODO - we must enforce type
|
|
@@ -1122,7 +1358,7 @@ var init_webgpu_vertex_array = __esm({
|
|
|
1122
1358
|
for (let location = 0; location < this.maxVertexAttributes; location++) {
|
|
1123
1359
|
const webgpuBuffer = this.attributes[location];
|
|
1124
1360
|
if (webgpuBuffer == null ? void 0 : webgpuBuffer.handle) {
|
|
1125
|
-
|
|
1361
|
+
import_core12.log.info(3, `setting vertex buffer ${location}`, webgpuBuffer == null ? void 0 : webgpuBuffer.handle)();
|
|
1126
1362
|
webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer == null ? void 0 : webgpuBuffer.handle);
|
|
1127
1363
|
}
|
|
1128
1364
|
}
|
|
@@ -1142,16 +1378,19 @@ var init_webgpu_vertex_array = __esm({
|
|
|
1142
1378
|
});
|
|
1143
1379
|
|
|
1144
1380
|
// dist/adapter/webgpu-canvas-context.js
|
|
1145
|
-
var
|
|
1381
|
+
var import_core13, WebGPUCanvasContext;
|
|
1146
1382
|
var init_webgpu_canvas_context = __esm({
|
|
1147
1383
|
"dist/adapter/webgpu-canvas-context.js"() {
|
|
1148
1384
|
"use strict";
|
|
1149
|
-
|
|
1385
|
+
import_core13 = require("@luma.gl/core");
|
|
1150
1386
|
init_webgpu_framebuffer();
|
|
1151
|
-
|
|
1387
|
+
init_cpu_hotspot_profiler();
|
|
1388
|
+
WebGPUCanvasContext = class extends import_core13.CanvasContext {
|
|
1152
1389
|
device;
|
|
1153
1390
|
handle;
|
|
1391
|
+
colorAttachment = null;
|
|
1154
1392
|
depthStencilAttachment = null;
|
|
1393
|
+
framebuffer = null;
|
|
1155
1394
|
get [Symbol.toStringTag]() {
|
|
1156
1395
|
return "WebGPUCanvasContext";
|
|
1157
1396
|
}
|
|
@@ -1164,34 +1403,29 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1164
1403
|
this.device = device;
|
|
1165
1404
|
this.handle = context;
|
|
1166
1405
|
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
|
|
1167
|
-
this.
|
|
1406
|
+
this._configureDevice();
|
|
1407
|
+
this._startObservers();
|
|
1168
1408
|
}
|
|
1169
1409
|
/** Destroy any textures produced while configured and remove the context configuration. */
|
|
1170
1410
|
destroy() {
|
|
1411
|
+
if (this.framebuffer) {
|
|
1412
|
+
this.framebuffer.destroy();
|
|
1413
|
+
this.framebuffer = null;
|
|
1414
|
+
}
|
|
1415
|
+
if (this.colorAttachment) {
|
|
1416
|
+
this.colorAttachment.destroy();
|
|
1417
|
+
this.colorAttachment = null;
|
|
1418
|
+
}
|
|
1419
|
+
if (this.depthStencilAttachment) {
|
|
1420
|
+
this.depthStencilAttachment.destroy();
|
|
1421
|
+
this.depthStencilAttachment = null;
|
|
1422
|
+
}
|
|
1171
1423
|
this.handle.unconfigure();
|
|
1172
1424
|
super.destroy();
|
|
1173
1425
|
}
|
|
1174
|
-
/** Update framebuffer with properly resized "swap chain" texture views */
|
|
1175
|
-
getCurrentFramebuffer(options = {
|
|
1176
|
-
depthStencilFormat: "depth24plus"
|
|
1177
|
-
}) {
|
|
1178
|
-
const currentColorAttachment = this.getCurrentTexture();
|
|
1179
|
-
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
|
|
1180
|
-
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
1181
|
-
this.drawingBufferWidth = currentColorAttachment.width;
|
|
1182
|
-
this.drawingBufferHeight = currentColorAttachment.height;
|
|
1183
|
-
import_core14.log.log(1, `${this}: Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`)();
|
|
1184
|
-
}
|
|
1185
|
-
if (options == null ? void 0 : options.depthStencilFormat) {
|
|
1186
|
-
this._createDepthStencilAttachment(options == null ? void 0 : options.depthStencilFormat);
|
|
1187
|
-
}
|
|
1188
|
-
return new WebGPUFramebuffer(this.device, {
|
|
1189
|
-
colorAttachments: [currentColorAttachment],
|
|
1190
|
-
depthStencilAttachment: this.depthStencilAttachment
|
|
1191
|
-
});
|
|
1192
|
-
}
|
|
1193
1426
|
// IMPLEMENTATION OF ABSTRACT METHODS
|
|
1194
|
-
|
|
1427
|
+
/** @see https://www.w3.org/TR/webgpu/#canvas-configuration */
|
|
1428
|
+
_configureDevice() {
|
|
1195
1429
|
if (this.depthStencilAttachment) {
|
|
1196
1430
|
this.depthStencilAttachment.destroy();
|
|
1197
1431
|
this.depthStencilAttachment = null;
|
|
@@ -1204,24 +1438,81 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1204
1438
|
colorSpace: this.props.colorSpace,
|
|
1205
1439
|
alphaMode: this.props.alphaMode
|
|
1206
1440
|
});
|
|
1441
|
+
this._createDepthStencilAttachment(this.device.preferredDepthFormat);
|
|
1442
|
+
}
|
|
1443
|
+
/** Update framebuffer with properly resized "swap chain" texture views */
|
|
1444
|
+
_getCurrentFramebuffer(options = {
|
|
1445
|
+
depthStencilFormat: "depth24plus"
|
|
1446
|
+
}) {
|
|
1447
|
+
var _a;
|
|
1448
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1449
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1450
|
+
if (profiler) {
|
|
1451
|
+
profiler.framebufferAcquireCount = (profiler.framebufferAcquireCount || 0) + 1;
|
|
1452
|
+
profiler.activeDefaultFramebufferAcquireDepth = (profiler.activeDefaultFramebufferAcquireDepth || 0) + 1;
|
|
1453
|
+
}
|
|
1454
|
+
try {
|
|
1455
|
+
const currentColorAttachment = this._getCurrentTexture();
|
|
1456
|
+
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
|
|
1457
|
+
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
1458
|
+
this.drawingBufferWidth = currentColorAttachment.width;
|
|
1459
|
+
this.drawingBufferHeight = currentColorAttachment.height;
|
|
1460
|
+
import_core13.log.log(1, `${this}: Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`)();
|
|
1461
|
+
}
|
|
1462
|
+
if (options == null ? void 0 : options.depthStencilFormat) {
|
|
1463
|
+
this._createDepthStencilAttachment(options == null ? void 0 : options.depthStencilFormat);
|
|
1464
|
+
}
|
|
1465
|
+
this.framebuffer ||= new WebGPUFramebuffer(this.device, {
|
|
1466
|
+
id: `${this.id}#framebuffer`,
|
|
1467
|
+
colorAttachments: [currentColorAttachment],
|
|
1468
|
+
depthStencilAttachment: null
|
|
1469
|
+
});
|
|
1470
|
+
this.framebuffer._reinitialize(currentColorAttachment.view, (options == null ? void 0 : options.depthStencilFormat) ? ((_a = this.depthStencilAttachment) == null ? void 0 : _a.view) || null : null);
|
|
1471
|
+
return this.framebuffer;
|
|
1472
|
+
} finally {
|
|
1473
|
+
if (profiler) {
|
|
1474
|
+
profiler.activeDefaultFramebufferAcquireDepth = (profiler.activeDefaultFramebufferAcquireDepth || 1) - 1;
|
|
1475
|
+
profiler.framebufferAcquireTimeMs = (profiler.framebufferAcquireTimeMs || 0) + (getTimestamp() - startTime);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1207
1478
|
}
|
|
1479
|
+
// PRIMARY METHODS
|
|
1208
1480
|
/** Wrap the current canvas context texture in a luma.gl texture */
|
|
1209
|
-
|
|
1481
|
+
_getCurrentTexture() {
|
|
1482
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1483
|
+
const currentTextureStartTime = profiler ? getTimestamp() : 0;
|
|
1210
1484
|
const handle = this.handle.getCurrentTexture();
|
|
1211
|
-
|
|
1212
|
-
|
|
1485
|
+
if (profiler) {
|
|
1486
|
+
profiler.currentTextureAcquireCount = (profiler.currentTextureAcquireCount || 0) + 1;
|
|
1487
|
+
profiler.currentTextureAcquireTimeMs = (profiler.currentTextureAcquireTimeMs || 0) + (getTimestamp() - currentTextureStartTime);
|
|
1488
|
+
}
|
|
1489
|
+
if (!this.colorAttachment) {
|
|
1490
|
+
this.colorAttachment = this.device.createTexture({
|
|
1491
|
+
id: `${this.id}#color-texture`,
|
|
1492
|
+
handle,
|
|
1493
|
+
format: this.device.preferredColorFormat,
|
|
1494
|
+
width: handle.width,
|
|
1495
|
+
height: handle.height
|
|
1496
|
+
});
|
|
1497
|
+
return this.colorAttachment;
|
|
1498
|
+
}
|
|
1499
|
+
this.colorAttachment._reinitialize(handle, {
|
|
1213
1500
|
handle,
|
|
1214
1501
|
format: this.device.preferredColorFormat,
|
|
1215
1502
|
width: handle.width,
|
|
1216
1503
|
height: handle.height
|
|
1217
1504
|
});
|
|
1505
|
+
return this.colorAttachment;
|
|
1218
1506
|
}
|
|
1219
1507
|
/** We build render targets on demand (i.e. not when size changes but when about to render) */
|
|
1220
1508
|
_createDepthStencilAttachment(depthStencilFormat) {
|
|
1221
|
-
|
|
1509
|
+
var _a;
|
|
1510
|
+
const needsNewDepthStencilAttachment = !this.depthStencilAttachment || this.depthStencilAttachment.width !== this.drawingBufferWidth || this.depthStencilAttachment.height !== this.drawingBufferHeight || this.depthStencilAttachment.format !== depthStencilFormat;
|
|
1511
|
+
if (needsNewDepthStencilAttachment) {
|
|
1512
|
+
(_a = this.depthStencilAttachment) == null ? void 0 : _a.destroy();
|
|
1222
1513
|
this.depthStencilAttachment = this.device.createTexture({
|
|
1223
1514
|
id: `${this.id}#depth-stencil-texture`,
|
|
1224
|
-
usage:
|
|
1515
|
+
usage: import_core13.Texture.RENDER_ATTACHMENT,
|
|
1225
1516
|
format: depthStencilFormat,
|
|
1226
1517
|
width: this.drawingBufferWidth,
|
|
1227
1518
|
height: this.drawingBufferHeight
|
|
@@ -1233,76 +1524,246 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1233
1524
|
}
|
|
1234
1525
|
});
|
|
1235
1526
|
|
|
1236
|
-
// dist/adapter/
|
|
1237
|
-
var
|
|
1238
|
-
var
|
|
1239
|
-
"dist/adapter/
|
|
1527
|
+
// dist/adapter/webgpu-presentation-context.js
|
|
1528
|
+
var import_core14, WebGPUPresentationContext;
|
|
1529
|
+
var init_webgpu_presentation_context = __esm({
|
|
1530
|
+
"dist/adapter/webgpu-presentation-context.js"() {
|
|
1240
1531
|
"use strict";
|
|
1241
|
-
|
|
1242
|
-
|
|
1532
|
+
import_core14 = require("@luma.gl/core");
|
|
1533
|
+
init_webgpu_framebuffer();
|
|
1534
|
+
init_cpu_hotspot_profiler();
|
|
1535
|
+
WebGPUPresentationContext = class extends import_core14.PresentationContext {
|
|
1243
1536
|
device;
|
|
1244
1537
|
handle;
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
});
|
|
1538
|
+
colorAttachment = null;
|
|
1539
|
+
depthStencilAttachment = null;
|
|
1540
|
+
framebuffer = null;
|
|
1541
|
+
get [Symbol.toStringTag]() {
|
|
1542
|
+
return "WebGPUPresentationContext";
|
|
1251
1543
|
}
|
|
1252
|
-
};
|
|
1253
|
-
}
|
|
1254
|
-
});
|
|
1255
|
-
|
|
1256
|
-
// dist/adapter/resources/webgpu-render-pass.js
|
|
1257
|
-
function convertColor(color) {
|
|
1258
|
-
return { r: color[0], g: color[1], b: color[2], a: color[3] };
|
|
1259
|
-
}
|
|
1260
|
-
var import_core16, WebGPURenderPass;
|
|
1261
|
-
var init_webgpu_render_pass = __esm({
|
|
1262
|
-
"dist/adapter/resources/webgpu-render-pass.js"() {
|
|
1263
|
-
"use strict";
|
|
1264
|
-
import_core16 = require("@luma.gl/core");
|
|
1265
|
-
WebGPURenderPass = class extends import_core16.RenderPass {
|
|
1266
|
-
device;
|
|
1267
|
-
handle;
|
|
1268
|
-
/** Active pipeline */
|
|
1269
|
-
pipeline = null;
|
|
1270
1544
|
constructor(device, props = {}) {
|
|
1271
|
-
super(
|
|
1272
|
-
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
this.
|
|
1293
|
-
this.
|
|
1294
|
-
|
|
1295
|
-
|
|
1545
|
+
super(props);
|
|
1546
|
+
const contextLabel = `${this[Symbol.toStringTag]}(${this.id})`;
|
|
1547
|
+
const context = this.canvas.getContext("webgpu");
|
|
1548
|
+
if (!context) {
|
|
1549
|
+
throw new Error(`${contextLabel}: Failed to create WebGPU presentation context`);
|
|
1550
|
+
}
|
|
1551
|
+
this.device = device;
|
|
1552
|
+
this.handle = context;
|
|
1553
|
+
this._setAutoCreatedCanvasId(`${this.device.id}-presentation-canvas`);
|
|
1554
|
+
this._configureDevice();
|
|
1555
|
+
this._startObservers();
|
|
1556
|
+
}
|
|
1557
|
+
destroy() {
|
|
1558
|
+
if (this.framebuffer) {
|
|
1559
|
+
this.framebuffer.destroy();
|
|
1560
|
+
this.framebuffer = null;
|
|
1561
|
+
}
|
|
1562
|
+
if (this.colorAttachment) {
|
|
1563
|
+
this.colorAttachment.destroy();
|
|
1564
|
+
this.colorAttachment = null;
|
|
1565
|
+
}
|
|
1566
|
+
if (this.depthStencilAttachment) {
|
|
1567
|
+
this.depthStencilAttachment.destroy();
|
|
1568
|
+
this.depthStencilAttachment = null;
|
|
1569
|
+
}
|
|
1570
|
+
this.handle.unconfigure();
|
|
1571
|
+
super.destroy();
|
|
1572
|
+
}
|
|
1573
|
+
present() {
|
|
1574
|
+
this.device.submit();
|
|
1575
|
+
}
|
|
1576
|
+
_configureDevice() {
|
|
1577
|
+
if (this.depthStencilAttachment) {
|
|
1578
|
+
this.depthStencilAttachment.destroy();
|
|
1579
|
+
this.depthStencilAttachment = null;
|
|
1580
|
+
}
|
|
1581
|
+
this.handle.configure({
|
|
1582
|
+
device: this.device.handle,
|
|
1583
|
+
format: this.device.preferredColorFormat,
|
|
1584
|
+
colorSpace: this.props.colorSpace,
|
|
1585
|
+
alphaMode: this.props.alphaMode
|
|
1296
1586
|
});
|
|
1297
|
-
this.
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1587
|
+
this._createDepthStencilAttachment(this.device.preferredDepthFormat);
|
|
1588
|
+
}
|
|
1589
|
+
_getCurrentFramebuffer(options = {
|
|
1590
|
+
depthStencilFormat: "depth24plus"
|
|
1591
|
+
}) {
|
|
1592
|
+
var _a;
|
|
1593
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1594
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1595
|
+
if (profiler) {
|
|
1596
|
+
profiler.framebufferAcquireCount = (profiler.framebufferAcquireCount || 0) + 1;
|
|
1597
|
+
}
|
|
1598
|
+
try {
|
|
1599
|
+
const currentColorAttachment = this._getCurrentTexture();
|
|
1600
|
+
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
|
|
1601
|
+
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
1602
|
+
this.drawingBufferWidth = currentColorAttachment.width;
|
|
1603
|
+
this.drawingBufferHeight = currentColorAttachment.height;
|
|
1604
|
+
import_core14.log.log(1, `${this[Symbol.toStringTag]}(${this.id}): Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`)();
|
|
1605
|
+
}
|
|
1606
|
+
if (options == null ? void 0 : options.depthStencilFormat) {
|
|
1607
|
+
this._createDepthStencilAttachment(options.depthStencilFormat);
|
|
1608
|
+
}
|
|
1609
|
+
this.framebuffer ||= new WebGPUFramebuffer(this.device, {
|
|
1610
|
+
id: `${this.id}#framebuffer`,
|
|
1611
|
+
colorAttachments: [currentColorAttachment],
|
|
1612
|
+
depthStencilAttachment: null
|
|
1613
|
+
});
|
|
1614
|
+
this.framebuffer._reinitialize(currentColorAttachment.view, (options == null ? void 0 : options.depthStencilFormat) ? ((_a = this.depthStencilAttachment) == null ? void 0 : _a.view) || null : null);
|
|
1615
|
+
return this.framebuffer;
|
|
1616
|
+
} finally {
|
|
1617
|
+
if (profiler) {
|
|
1618
|
+
profiler.framebufferAcquireTimeMs = (profiler.framebufferAcquireTimeMs || 0) + (getTimestamp() - startTime);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
_getCurrentTexture() {
|
|
1623
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1624
|
+
const currentTextureStartTime = profiler ? getTimestamp() : 0;
|
|
1625
|
+
const handle = this.handle.getCurrentTexture();
|
|
1626
|
+
if (profiler) {
|
|
1627
|
+
profiler.currentTextureAcquireCount = (profiler.currentTextureAcquireCount || 0) + 1;
|
|
1628
|
+
profiler.currentTextureAcquireTimeMs = (profiler.currentTextureAcquireTimeMs || 0) + (getTimestamp() - currentTextureStartTime);
|
|
1629
|
+
}
|
|
1630
|
+
if (!this.colorAttachment) {
|
|
1631
|
+
this.colorAttachment = this.device.createTexture({
|
|
1632
|
+
id: `${this.id}#color-texture`,
|
|
1633
|
+
handle,
|
|
1634
|
+
format: this.device.preferredColorFormat,
|
|
1635
|
+
width: handle.width,
|
|
1636
|
+
height: handle.height
|
|
1637
|
+
});
|
|
1638
|
+
return this.colorAttachment;
|
|
1639
|
+
}
|
|
1640
|
+
this.colorAttachment._reinitialize(handle, {
|
|
1641
|
+
handle,
|
|
1642
|
+
format: this.device.preferredColorFormat,
|
|
1643
|
+
width: handle.width,
|
|
1644
|
+
height: handle.height
|
|
1645
|
+
});
|
|
1646
|
+
return this.colorAttachment;
|
|
1647
|
+
}
|
|
1648
|
+
_createDepthStencilAttachment(depthStencilFormat) {
|
|
1649
|
+
var _a;
|
|
1650
|
+
const needsNewDepthStencilAttachment = !this.depthStencilAttachment || this.depthStencilAttachment.width !== this.drawingBufferWidth || this.depthStencilAttachment.height !== this.drawingBufferHeight || this.depthStencilAttachment.format !== depthStencilFormat;
|
|
1651
|
+
if (needsNewDepthStencilAttachment) {
|
|
1652
|
+
(_a = this.depthStencilAttachment) == null ? void 0 : _a.destroy();
|
|
1653
|
+
this.depthStencilAttachment = this.device.createTexture({
|
|
1654
|
+
id: `${this.id}#depth-stencil-texture`,
|
|
1655
|
+
usage: import_core14.Texture.RENDER_ATTACHMENT,
|
|
1656
|
+
format: depthStencilFormat,
|
|
1657
|
+
width: this.drawingBufferWidth,
|
|
1658
|
+
height: this.drawingBufferHeight
|
|
1659
|
+
});
|
|
1660
|
+
}
|
|
1661
|
+
return this.depthStencilAttachment;
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
}
|
|
1665
|
+
});
|
|
1666
|
+
|
|
1667
|
+
// dist/adapter/resources/webgpu-command-buffer.js
|
|
1668
|
+
var import_core15, WebGPUCommandBuffer;
|
|
1669
|
+
var init_webgpu_command_buffer = __esm({
|
|
1670
|
+
"dist/adapter/resources/webgpu-command-buffer.js"() {
|
|
1671
|
+
"use strict";
|
|
1672
|
+
import_core15 = require("@luma.gl/core");
|
|
1673
|
+
WebGPUCommandBuffer = class extends import_core15.CommandBuffer {
|
|
1674
|
+
device;
|
|
1675
|
+
handle;
|
|
1676
|
+
constructor(commandEncoder, props) {
|
|
1677
|
+
super(commandEncoder.device, props);
|
|
1678
|
+
this.device = commandEncoder.device;
|
|
1679
|
+
this.handle = this.props.handle || commandEncoder.handle.finish({
|
|
1680
|
+
label: (props == null ? void 0 : props.id) || "unnamed-command-buffer"
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
// dist/adapter/resources/webgpu-render-pass.js
|
|
1688
|
+
function convertColor(color) {
|
|
1689
|
+
return { r: color[0], g: color[1], b: color[2], a: color[3] };
|
|
1690
|
+
}
|
|
1691
|
+
var import_core16, WebGPURenderPass;
|
|
1692
|
+
var init_webgpu_render_pass = __esm({
|
|
1693
|
+
"dist/adapter/resources/webgpu-render-pass.js"() {
|
|
1694
|
+
"use strict";
|
|
1695
|
+
import_core16 = require("@luma.gl/core");
|
|
1696
|
+
init_cpu_hotspot_profiler();
|
|
1697
|
+
WebGPURenderPass = class extends import_core16.RenderPass {
|
|
1698
|
+
device;
|
|
1699
|
+
handle;
|
|
1700
|
+
framebuffer;
|
|
1701
|
+
/** Active pipeline */
|
|
1702
|
+
pipeline = null;
|
|
1703
|
+
/** Latest bindings applied to this pass */
|
|
1704
|
+
bindings = {};
|
|
1705
|
+
constructor(device, props = {}, commandEncoder = device.commandEncoder.handle) {
|
|
1706
|
+
super(device, props);
|
|
1707
|
+
this.device = device;
|
|
1708
|
+
const { props: renderPassProps } = this;
|
|
1709
|
+
this.framebuffer = renderPassProps.framebuffer || device.getCanvasContext().getCurrentFramebuffer();
|
|
1710
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1711
|
+
if (profiler) {
|
|
1712
|
+
const counterName = renderPassProps.framebuffer ? "explicitFramebufferRenderPassCount" : "defaultFramebufferRenderPassCount";
|
|
1713
|
+
profiler[counterName] = (profiler[counterName] || 0) + 1;
|
|
1714
|
+
}
|
|
1715
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1716
|
+
try {
|
|
1717
|
+
const descriptorAssemblyStartTime = profiler ? getTimestamp() : 0;
|
|
1718
|
+
const renderPassDescriptor = this.getRenderPassDescriptor(this.framebuffer);
|
|
1719
|
+
if (renderPassProps.occlusionQuerySet) {
|
|
1720
|
+
renderPassDescriptor.occlusionQuerySet = renderPassProps.occlusionQuerySet.handle;
|
|
1721
|
+
}
|
|
1722
|
+
if (renderPassProps.timestampQuerySet) {
|
|
1723
|
+
const webgpuTSQuerySet = renderPassProps.timestampQuerySet;
|
|
1724
|
+
webgpuTSQuerySet == null ? void 0 : webgpuTSQuerySet._invalidateResults();
|
|
1725
|
+
renderPassDescriptor.timestampWrites = webgpuTSQuerySet ? {
|
|
1726
|
+
querySet: webgpuTSQuerySet.handle,
|
|
1727
|
+
beginningOfPassWriteIndex: renderPassProps.beginTimestampIndex,
|
|
1728
|
+
endOfPassWriteIndex: renderPassProps.endTimestampIndex
|
|
1729
|
+
} : void 0;
|
|
1730
|
+
}
|
|
1731
|
+
if (profiler) {
|
|
1732
|
+
profiler.renderPassDescriptorAssemblyCount = (profiler.renderPassDescriptorAssemblyCount || 0) + 1;
|
|
1733
|
+
profiler.renderPassDescriptorAssemblyTimeMs = (profiler.renderPassDescriptorAssemblyTimeMs || 0) + (getTimestamp() - descriptorAssemblyStartTime);
|
|
1734
|
+
}
|
|
1735
|
+
this.device.pushErrorScope("validation");
|
|
1736
|
+
const beginRenderPassStartTime = profiler ? getTimestamp() : 0;
|
|
1737
|
+
this.handle = this.props.handle || commandEncoder.beginRenderPass(renderPassDescriptor);
|
|
1738
|
+
if (profiler) {
|
|
1739
|
+
profiler.renderPassBeginCount = (profiler.renderPassBeginCount || 0) + 1;
|
|
1740
|
+
profiler.renderPassBeginTimeMs = (profiler.renderPassBeginTimeMs || 0) + (getTimestamp() - beginRenderPassStartTime);
|
|
1741
|
+
}
|
|
1742
|
+
this.device.popErrorScope((error) => {
|
|
1743
|
+
this.device.reportError(new Error(`${this} creation failed:
|
|
1744
|
+
"${error.message}"`), this)();
|
|
1745
|
+
this.device.debug();
|
|
1746
|
+
});
|
|
1747
|
+
this.handle.label = this.props.id;
|
|
1748
|
+
import_core16.log.groupCollapsed(3, `new WebGPURenderPass(${this.id})`)();
|
|
1749
|
+
import_core16.log.probe(3, JSON.stringify(renderPassDescriptor, null, 2))();
|
|
1750
|
+
import_core16.log.groupEnd(3)();
|
|
1751
|
+
} finally {
|
|
1752
|
+
if (profiler) {
|
|
1753
|
+
profiler.renderPassSetupCount = (profiler.renderPassSetupCount || 0) + 1;
|
|
1754
|
+
profiler.renderPassSetupTimeMs = (profiler.renderPassSetupTimeMs || 0) + (getTimestamp() - startTime);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1301
1757
|
}
|
|
1302
1758
|
destroy() {
|
|
1759
|
+
this.destroyResource();
|
|
1303
1760
|
}
|
|
1304
1761
|
end() {
|
|
1762
|
+
if (this.destroyed) {
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1305
1765
|
this.handle.end();
|
|
1766
|
+
this.destroy();
|
|
1306
1767
|
}
|
|
1307
1768
|
setPipeline(pipeline) {
|
|
1308
1769
|
this.pipeline = pipeline;
|
|
@@ -1316,11 +1777,12 @@ var init_webgpu_render_pass = __esm({
|
|
|
1316
1777
|
}
|
|
1317
1778
|
/** Sets an array of bindings (uniform buffers, samplers, textures, ...) */
|
|
1318
1779
|
setBindings(bindings) {
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1780
|
+
this.bindings = bindings;
|
|
1781
|
+
const bindGroups = this.pipeline && (0, import_core16._getDefaultBindGroupFactory)(this.device).getBindGroups(this.pipeline, bindings) || {};
|
|
1782
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1783
|
+
if (bindGroup) {
|
|
1784
|
+
this.handle.setBindGroup(Number(group), bindGroup);
|
|
1785
|
+
}
|
|
1324
1786
|
}
|
|
1325
1787
|
}
|
|
1326
1788
|
setIndexBuffer(buffer, indexFormat, offset = 0, size) {
|
|
@@ -1427,44 +1889,60 @@ var init_webgpu_compute_pass = __esm({
|
|
|
1427
1889
|
device;
|
|
1428
1890
|
handle;
|
|
1429
1891
|
_webgpuPipeline = null;
|
|
1430
|
-
constructor(device, props) {
|
|
1892
|
+
constructor(device, props = {}, commandEncoder = device.commandEncoder.handle) {
|
|
1431
1893
|
super(device, props);
|
|
1432
1894
|
this.device = device;
|
|
1895
|
+
const { props: computePassProps } = this;
|
|
1433
1896
|
let timestampWrites;
|
|
1434
|
-
if (
|
|
1435
|
-
const webgpuQuerySet =
|
|
1897
|
+
if (computePassProps.timestampQuerySet) {
|
|
1898
|
+
const webgpuQuerySet = computePassProps.timestampQuerySet;
|
|
1436
1899
|
if (webgpuQuerySet) {
|
|
1900
|
+
webgpuQuerySet._invalidateResults();
|
|
1437
1901
|
timestampWrites = {
|
|
1438
1902
|
querySet: webgpuQuerySet.handle,
|
|
1439
|
-
beginningOfPassWriteIndex:
|
|
1440
|
-
endOfPassWriteIndex:
|
|
1903
|
+
beginningOfPassWriteIndex: computePassProps.beginTimestampIndex,
|
|
1904
|
+
endOfPassWriteIndex: computePassProps.endTimestampIndex
|
|
1441
1905
|
};
|
|
1442
1906
|
}
|
|
1443
1907
|
}
|
|
1444
|
-
this.handle = this.props.handle ||
|
|
1908
|
+
this.handle = this.props.handle || commandEncoder.beginComputePass({
|
|
1445
1909
|
label: this.props.id,
|
|
1446
1910
|
timestampWrites
|
|
1447
1911
|
});
|
|
1448
1912
|
}
|
|
1449
1913
|
/** @note no WebGPU destroy method, just gc */
|
|
1450
1914
|
destroy() {
|
|
1915
|
+
this.destroyResource();
|
|
1451
1916
|
}
|
|
1452
1917
|
end() {
|
|
1918
|
+
if (this.destroyed) {
|
|
1919
|
+
return;
|
|
1920
|
+
}
|
|
1453
1921
|
this.handle.end();
|
|
1922
|
+
this.destroy();
|
|
1454
1923
|
}
|
|
1455
1924
|
setPipeline(pipeline) {
|
|
1456
1925
|
const wgpuPipeline = pipeline;
|
|
1457
1926
|
this.handle.setPipeline(wgpuPipeline.handle);
|
|
1458
1927
|
this._webgpuPipeline = wgpuPipeline;
|
|
1459
|
-
this.
|
|
1928
|
+
const bindGroups = (0, import_core17._getDefaultBindGroupFactory)(this.device).getBindGroups(this._webgpuPipeline, this._webgpuPipeline._getBindingsByGroupWebGPU(), this._webgpuPipeline._getBindGroupCacheKeysWebGPU());
|
|
1929
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1930
|
+
if (bindGroup) {
|
|
1931
|
+
this.handle.setBindGroup(Number(group), bindGroup);
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1460
1934
|
}
|
|
1461
1935
|
/**
|
|
1462
1936
|
* Sets an array of bindings (uniform buffers, samplers, textures, ...)
|
|
1463
1937
|
* TODO - still some API confusion - does this method go here or on the pipeline?
|
|
1464
1938
|
*/
|
|
1465
1939
|
setBindings(bindings) {
|
|
1466
|
-
const
|
|
1467
|
-
|
|
1940
|
+
const bindGroups = this._webgpuPipeline && (0, import_core17._getDefaultBindGroupFactory)(this.device).getBindGroups(this._webgpuPipeline, bindings) || {};
|
|
1941
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1942
|
+
if (bindGroup) {
|
|
1943
|
+
this.handle.setBindGroup(Number(group), bindGroup);
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1468
1946
|
}
|
|
1469
1947
|
/**
|
|
1470
1948
|
* Dispatch work to be performed with the current ComputePipeline.
|
|
@@ -1522,6 +2000,7 @@ var init_webgpu_command_encoder = __esm({
|
|
|
1522
2000
|
this.handle.label = this.props.id;
|
|
1523
2001
|
}
|
|
1524
2002
|
destroy() {
|
|
2003
|
+
this.destroyResource();
|
|
1525
2004
|
}
|
|
1526
2005
|
finish(props) {
|
|
1527
2006
|
this.device.pushErrorScope("validation");
|
|
@@ -1533,49 +2012,105 @@ var init_webgpu_command_encoder = __esm({
|
|
|
1533
2012
|
this.device.reportError(new Error(message), this)();
|
|
1534
2013
|
this.device.debug();
|
|
1535
2014
|
});
|
|
2015
|
+
this.destroy();
|
|
1536
2016
|
return commandBuffer;
|
|
1537
2017
|
}
|
|
1538
2018
|
/**
|
|
1539
2019
|
* Allows a render pass to begin against a canvas context
|
|
1540
2020
|
* @todo need to support a "Framebuffer" equivalent (aka preconfigured RenderPassDescriptors?).
|
|
1541
2021
|
*/
|
|
1542
|
-
beginRenderPass(props) {
|
|
1543
|
-
return new WebGPURenderPass(this.device, props);
|
|
2022
|
+
beginRenderPass(props = {}) {
|
|
2023
|
+
return new WebGPURenderPass(this.device, this._applyTimeProfilingToPassProps(props), this.handle);
|
|
1544
2024
|
}
|
|
1545
|
-
beginComputePass(props) {
|
|
1546
|
-
return new WebGPUComputePass(this.device, props);
|
|
2025
|
+
beginComputePass(props = {}) {
|
|
2026
|
+
return new WebGPUComputePass(this.device, this._applyTimeProfilingToPassProps(props), this.handle);
|
|
1547
2027
|
}
|
|
1548
2028
|
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
1549
2029
|
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
1550
2030
|
copyBufferToBuffer(options) {
|
|
1551
2031
|
const webgpuSourceBuffer = options.sourceBuffer;
|
|
1552
|
-
const
|
|
1553
|
-
this.handle.copyBufferToBuffer(webgpuSourceBuffer.handle, options.sourceOffset ?? 0,
|
|
2032
|
+
const webgpuDestinationBuffer = options.destinationBuffer;
|
|
2033
|
+
this.handle.copyBufferToBuffer(webgpuSourceBuffer.handle, options.sourceOffset ?? 0, webgpuDestinationBuffer.handle, options.destinationOffset ?? 0, options.size ?? 0);
|
|
1554
2034
|
}
|
|
1555
2035
|
copyBufferToTexture(options) {
|
|
1556
|
-
var _a, _b, _c;
|
|
1557
2036
|
const webgpuSourceBuffer = options.sourceBuffer;
|
|
1558
|
-
const
|
|
2037
|
+
const webgpuDestinationTexture = options.destinationTexture;
|
|
2038
|
+
const copyOrigin = options.origin ?? [0, 0, 0];
|
|
2039
|
+
const copySize = options.size;
|
|
1559
2040
|
this.handle.copyBufferToTexture({
|
|
1560
2041
|
buffer: webgpuSourceBuffer.handle,
|
|
1561
|
-
offset: options.
|
|
2042
|
+
offset: options.byteOffset ?? 0,
|
|
1562
2043
|
bytesPerRow: options.bytesPerRow,
|
|
1563
2044
|
rowsPerImage: options.rowsPerImage
|
|
1564
2045
|
}, {
|
|
1565
|
-
texture:
|
|
2046
|
+
texture: webgpuDestinationTexture.handle,
|
|
1566
2047
|
mipLevel: options.mipLevel ?? 0,
|
|
1567
|
-
origin:
|
|
1568
|
-
|
|
2048
|
+
origin: {
|
|
2049
|
+
x: copyOrigin[0] ?? 0,
|
|
2050
|
+
y: copyOrigin[1] ?? 0,
|
|
2051
|
+
z: copyOrigin[2] ?? 0
|
|
2052
|
+
},
|
|
2053
|
+
aspect: options.aspect
|
|
1569
2054
|
}, {
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
depthOrArrayLayers: (_c = options.extent) == null ? void 0 : _c[2]
|
|
2055
|
+
width: copySize[0],
|
|
2056
|
+
height: copySize[1],
|
|
2057
|
+
depthOrArrayLayers: copySize[2]
|
|
1574
2058
|
});
|
|
1575
2059
|
}
|
|
1576
2060
|
copyTextureToBuffer(options) {
|
|
2061
|
+
const { sourceTexture, destinationBuffer, origin = [0, 0, 0], byteOffset = 0, width, height, depthOrArrayLayers, mipLevel, aspect } = options;
|
|
2062
|
+
const webgpuSourceTexture = sourceTexture;
|
|
2063
|
+
webgpuSourceTexture.copyToBuffer(this.handle, {
|
|
2064
|
+
x: origin[0] ?? 0,
|
|
2065
|
+
y: origin[1] ?? 0,
|
|
2066
|
+
z: origin[2] ?? 0,
|
|
2067
|
+
width,
|
|
2068
|
+
height,
|
|
2069
|
+
depthOrArrayLayers,
|
|
2070
|
+
mipLevel,
|
|
2071
|
+
aspect,
|
|
2072
|
+
byteOffset,
|
|
2073
|
+
bytesPerRow: options.bytesPerRow,
|
|
2074
|
+
rowsPerImage: options.rowsPerImage
|
|
2075
|
+
}, destinationBuffer);
|
|
1577
2076
|
}
|
|
1578
2077
|
copyTextureToTexture(options) {
|
|
2078
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2079
|
+
const webgpuSourceTexture = options.sourceTexture;
|
|
2080
|
+
const webgpuDestinationTexture = options.destinationTexture;
|
|
2081
|
+
const sourceRegion = webgpuSourceTexture._normalizeTextureReadOptions({
|
|
2082
|
+
x: ((_a = options.origin) == null ? void 0 : _a[0]) ?? 0,
|
|
2083
|
+
y: ((_b = options.origin) == null ? void 0 : _b[1]) ?? 0,
|
|
2084
|
+
z: ((_c = options.origin) == null ? void 0 : _c[2]) ?? 0,
|
|
2085
|
+
width: options.width,
|
|
2086
|
+
height: options.height,
|
|
2087
|
+
depthOrArrayLayers: options.depthOrArrayLayers,
|
|
2088
|
+
mipLevel: options.mipLevel ?? 0,
|
|
2089
|
+
aspect: options.aspect ?? "all"
|
|
2090
|
+
});
|
|
2091
|
+
this.handle.copyTextureToTexture({
|
|
2092
|
+
texture: webgpuSourceTexture.handle,
|
|
2093
|
+
mipLevel: sourceRegion.mipLevel,
|
|
2094
|
+
origin: {
|
|
2095
|
+
x: sourceRegion.x,
|
|
2096
|
+
y: sourceRegion.y,
|
|
2097
|
+
z: sourceRegion.z
|
|
2098
|
+
},
|
|
2099
|
+
aspect: sourceRegion.aspect
|
|
2100
|
+
}, {
|
|
2101
|
+
texture: webgpuDestinationTexture.handle,
|
|
2102
|
+
mipLevel: options.destinationMipLevel ?? 0,
|
|
2103
|
+
origin: {
|
|
2104
|
+
x: ((_d = options.destinationOrigin) == null ? void 0 : _d[0]) ?? 0,
|
|
2105
|
+
y: ((_e = options.destinationOrigin) == null ? void 0 : _e[1]) ?? 0,
|
|
2106
|
+
z: ((_f = options.destinationOrigin) == null ? void 0 : _f[2]) ?? 0
|
|
2107
|
+
},
|
|
2108
|
+
aspect: options.destinationAspect ?? sourceRegion.aspect
|
|
2109
|
+
}, {
|
|
2110
|
+
width: sourceRegion.width,
|
|
2111
|
+
height: sourceRegion.height,
|
|
2112
|
+
depthOrArrayLayers: sourceRegion.depthOrArrayLayers
|
|
2113
|
+
});
|
|
1579
2114
|
}
|
|
1580
2115
|
pushDebugGroup(groupLabel) {
|
|
1581
2116
|
this.handle.pushDebugGroup(groupLabel);
|
|
@@ -1591,6 +2126,21 @@ var init_webgpu_command_encoder = __esm({
|
|
|
1591
2126
|
const webgpuBuffer = destination;
|
|
1592
2127
|
this.handle.resolveQuerySet(webgpuQuerySet.handle, (options == null ? void 0 : options.firstQuery) || 0, (options == null ? void 0 : options.queryCount) || querySet.props.count - ((options == null ? void 0 : options.firstQuery) || 0), webgpuBuffer.handle, (options == null ? void 0 : options.destinationOffset) || 0);
|
|
1593
2128
|
}
|
|
2129
|
+
writeTimestamp(querySet, queryIndex) {
|
|
2130
|
+
querySet._invalidateResults();
|
|
2131
|
+
const writeTimestamp = this.handle.writeTimestamp;
|
|
2132
|
+
if (writeTimestamp) {
|
|
2133
|
+
writeTimestamp.call(this.handle, querySet.handle, queryIndex);
|
|
2134
|
+
return;
|
|
2135
|
+
}
|
|
2136
|
+
const computePass = this.handle.beginComputePass({
|
|
2137
|
+
timestampWrites: {
|
|
2138
|
+
querySet: querySet.handle,
|
|
2139
|
+
beginningOfPassWriteIndex: queryIndex
|
|
2140
|
+
}
|
|
2141
|
+
});
|
|
2142
|
+
computePass.end();
|
|
2143
|
+
}
|
|
1594
2144
|
};
|
|
1595
2145
|
}
|
|
1596
2146
|
});
|
|
@@ -1601,9 +2151,15 @@ var init_webgpu_query_set = __esm({
|
|
|
1601
2151
|
"dist/adapter/resources/webgpu-query-set.js"() {
|
|
1602
2152
|
"use strict";
|
|
1603
2153
|
import_core19 = require("@luma.gl/core");
|
|
2154
|
+
init_cpu_hotspot_profiler();
|
|
1604
2155
|
WebGPUQuerySet = class extends import_core19.QuerySet {
|
|
1605
2156
|
device;
|
|
1606
2157
|
handle;
|
|
2158
|
+
_resolveBuffer = null;
|
|
2159
|
+
_readBuffer = null;
|
|
2160
|
+
_cachedResults = null;
|
|
2161
|
+
_readResultsPromise = null;
|
|
2162
|
+
_resultsPendingResolution = false;
|
|
1607
2163
|
constructor(device, props) {
|
|
1608
2164
|
super(device, props);
|
|
1609
2165
|
this.device = device;
|
|
@@ -1615,8 +2171,133 @@ var init_webgpu_query_set = __esm({
|
|
|
1615
2171
|
}
|
|
1616
2172
|
destroy() {
|
|
1617
2173
|
var _a;
|
|
1618
|
-
(
|
|
1619
|
-
|
|
2174
|
+
if (!this.destroyed) {
|
|
2175
|
+
(_a = this.handle) == null ? void 0 : _a.destroy();
|
|
2176
|
+
this.destroyResource();
|
|
2177
|
+
this.handle = null;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
isResultAvailable(queryIndex) {
|
|
2181
|
+
if (!this._cachedResults) {
|
|
2182
|
+
return false;
|
|
2183
|
+
}
|
|
2184
|
+
return queryIndex === void 0 ? true : queryIndex >= 0 && queryIndex < this._cachedResults.length;
|
|
2185
|
+
}
|
|
2186
|
+
async readResults(options) {
|
|
2187
|
+
const firstQuery = (options == null ? void 0 : options.firstQuery) || 0;
|
|
2188
|
+
const queryCount = (options == null ? void 0 : options.queryCount) || this.props.count - firstQuery;
|
|
2189
|
+
if (firstQuery < 0 || queryCount < 0 || firstQuery + queryCount > this.props.count) {
|
|
2190
|
+
throw new Error("Query read range is out of bounds");
|
|
2191
|
+
}
|
|
2192
|
+
let needsFreshResults = true;
|
|
2193
|
+
while (needsFreshResults) {
|
|
2194
|
+
if (!this._readResultsPromise) {
|
|
2195
|
+
this._readResultsPromise = this._readAllResults();
|
|
2196
|
+
}
|
|
2197
|
+
const readResultsPromise = this._readResultsPromise;
|
|
2198
|
+
const results = await readResultsPromise;
|
|
2199
|
+
needsFreshResults = this._resultsPendingResolution;
|
|
2200
|
+
if (!needsFreshResults) {
|
|
2201
|
+
return results.slice(firstQuery, firstQuery + queryCount);
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
throw new Error("Query read unexpectedly failed to resolve");
|
|
2205
|
+
}
|
|
2206
|
+
async readTimestampDuration(beginIndex, endIndex) {
|
|
2207
|
+
if (this.props.type !== "timestamp") {
|
|
2208
|
+
throw new Error("Timestamp durations require a timestamp QuerySet");
|
|
2209
|
+
}
|
|
2210
|
+
if (beginIndex < 0 || endIndex <= beginIndex || endIndex >= this.props.count) {
|
|
2211
|
+
throw new Error("Timestamp duration range is out of bounds");
|
|
2212
|
+
}
|
|
2213
|
+
const results = await this.readResults({
|
|
2214
|
+
firstQuery: beginIndex,
|
|
2215
|
+
queryCount: endIndex - beginIndex + 1
|
|
2216
|
+
});
|
|
2217
|
+
return Number(results[results.length - 1] - results[0]) / 1e6;
|
|
2218
|
+
}
|
|
2219
|
+
/** Marks any cached query results as stale after new writes have been encoded. */
|
|
2220
|
+
_invalidateResults() {
|
|
2221
|
+
this._cachedResults = null;
|
|
2222
|
+
this._resultsPendingResolution = true;
|
|
2223
|
+
}
|
|
2224
|
+
async _readAllResults() {
|
|
2225
|
+
this._ensureBuffers();
|
|
2226
|
+
try {
|
|
2227
|
+
if (this._resultsPendingResolution) {
|
|
2228
|
+
const commandEncoder = this.device.createCommandEncoder({
|
|
2229
|
+
id: `${this.id}-read-results`
|
|
2230
|
+
});
|
|
2231
|
+
commandEncoder.resolveQuerySet(this, this._resolveBuffer);
|
|
2232
|
+
commandEncoder.copyBufferToBuffer({
|
|
2233
|
+
sourceBuffer: this._resolveBuffer,
|
|
2234
|
+
destinationBuffer: this._readBuffer,
|
|
2235
|
+
size: this._resolveBuffer.byteLength
|
|
2236
|
+
});
|
|
2237
|
+
const commandBuffer = commandEncoder.finish({
|
|
2238
|
+
id: `${this.id}-read-results-command-buffer`
|
|
2239
|
+
});
|
|
2240
|
+
const previousSubmitReason = getCpuHotspotSubmitReason(this.device) || void 0;
|
|
2241
|
+
setCpuHotspotSubmitReason(this.device, "query-readback");
|
|
2242
|
+
try {
|
|
2243
|
+
this.device.submit(commandBuffer);
|
|
2244
|
+
} finally {
|
|
2245
|
+
setCpuHotspotSubmitReason(this.device, previousSubmitReason);
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
const data = await this._readBuffer.readAsync(0, this._readBuffer.byteLength);
|
|
2249
|
+
const resultView = new BigUint64Array(data.buffer, data.byteOffset, this.props.count);
|
|
2250
|
+
this._cachedResults = Array.from(resultView, (value) => value);
|
|
2251
|
+
this._resultsPendingResolution = false;
|
|
2252
|
+
return this._cachedResults;
|
|
2253
|
+
} finally {
|
|
2254
|
+
this._readResultsPromise = null;
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
_ensureBuffers() {
|
|
2258
|
+
if (this._resolveBuffer && this._readBuffer) {
|
|
2259
|
+
return;
|
|
2260
|
+
}
|
|
2261
|
+
const byteLength = this.props.count * 8;
|
|
2262
|
+
this._resolveBuffer = this.device.createBuffer({
|
|
2263
|
+
id: `${this.id}-resolve-buffer`,
|
|
2264
|
+
usage: import_core19.Buffer.QUERY_RESOLVE | import_core19.Buffer.COPY_SRC,
|
|
2265
|
+
byteLength
|
|
2266
|
+
});
|
|
2267
|
+
this.attachResource(this._resolveBuffer);
|
|
2268
|
+
this._readBuffer = this.device.createBuffer({
|
|
2269
|
+
id: `${this.id}-read-buffer`,
|
|
2270
|
+
usage: import_core19.Buffer.COPY_DST | import_core19.Buffer.MAP_READ,
|
|
2271
|
+
byteLength
|
|
2272
|
+
});
|
|
2273
|
+
this.attachResource(this._readBuffer);
|
|
2274
|
+
}
|
|
2275
|
+
_encodeResolveToReadBuffer(commandEncoder, options) {
|
|
2276
|
+
if (!this._resultsPendingResolution) {
|
|
2277
|
+
return false;
|
|
2278
|
+
}
|
|
2279
|
+
if (this._readResultsPromise) {
|
|
2280
|
+
return false;
|
|
2281
|
+
}
|
|
2282
|
+
this._ensureBuffers();
|
|
2283
|
+
const firstQuery = (options == null ? void 0 : options.firstQuery) || 0;
|
|
2284
|
+
const queryCount = (options == null ? void 0 : options.queryCount) || this.props.count - firstQuery;
|
|
2285
|
+
const byteLength = queryCount * BigUint64Array.BYTES_PER_ELEMENT;
|
|
2286
|
+
const byteOffset = firstQuery * BigUint64Array.BYTES_PER_ELEMENT;
|
|
2287
|
+
commandEncoder.resolveQuerySet(this, this._resolveBuffer, {
|
|
2288
|
+
firstQuery,
|
|
2289
|
+
queryCount,
|
|
2290
|
+
destinationOffset: byteOffset
|
|
2291
|
+
});
|
|
2292
|
+
commandEncoder.copyBufferToBuffer({
|
|
2293
|
+
sourceBuffer: this._resolveBuffer,
|
|
2294
|
+
sourceOffset: byteOffset,
|
|
2295
|
+
destinationBuffer: this._readBuffer,
|
|
2296
|
+
destinationOffset: byteOffset,
|
|
2297
|
+
size: byteLength
|
|
2298
|
+
});
|
|
2299
|
+
this._resultsPendingResolution = false;
|
|
2300
|
+
return true;
|
|
1620
2301
|
}
|
|
1621
2302
|
};
|
|
1622
2303
|
}
|
|
@@ -1634,27 +2315,22 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1634
2315
|
constructor(device, props) {
|
|
1635
2316
|
super(device, props);
|
|
1636
2317
|
this.device = device;
|
|
1637
|
-
const
|
|
2318
|
+
const bindGroupEntriesByGroup = this.mapShaderLayoutToBindGroupEntriesByGroup();
|
|
1638
2319
|
this.handle = this.device.handle.createPipelineLayout({
|
|
1639
2320
|
label: (props == null ? void 0 : props.id) ?? "unnamed-pipeline-layout",
|
|
1640
|
-
bindGroupLayouts:
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
this.device.handle.createBindGroupLayout({
|
|
1645
|
-
label: "bind-group-layout",
|
|
1646
|
-
entries: bindGroupEntries
|
|
1647
|
-
})
|
|
1648
|
-
]
|
|
2321
|
+
bindGroupLayouts: bindGroupEntriesByGroup.map((entries, group) => this.device.handle.createBindGroupLayout({
|
|
2322
|
+
label: `bind-group-layout-${group}`,
|
|
2323
|
+
entries
|
|
2324
|
+
}))
|
|
1649
2325
|
});
|
|
1650
2326
|
}
|
|
1651
2327
|
destroy() {
|
|
1652
2328
|
this.handle = null;
|
|
1653
2329
|
}
|
|
1654
|
-
|
|
1655
|
-
const
|
|
1656
|
-
|
|
1657
|
-
|
|
2330
|
+
mapShaderLayoutToBindGroupEntriesByGroup() {
|
|
2331
|
+
const maxGroup = this.props.shaderLayout.bindings.reduce((highestGroup, binding) => Math.max(highestGroup, binding.group), -1);
|
|
2332
|
+
const bindGroupEntriesByGroup = Array.from({ length: maxGroup + 1 }, () => []);
|
|
2333
|
+
for (const binding of this.props.shaderLayout.bindings) {
|
|
1658
2334
|
const bindingTypeInfo = {};
|
|
1659
2335
|
switch (binding.type) {
|
|
1660
2336
|
case "uniform": {
|
|
@@ -1710,13 +2386,13 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1710
2386
|
}
|
|
1711
2387
|
}
|
|
1712
2388
|
const VISIBILITY_ALL = GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE;
|
|
1713
|
-
|
|
2389
|
+
bindGroupEntriesByGroup[binding.group].push({
|
|
1714
2390
|
binding: binding.location,
|
|
1715
2391
|
visibility: binding.visibility || VISIBILITY_ALL,
|
|
1716
2392
|
...bindingTypeInfo
|
|
1717
2393
|
});
|
|
1718
2394
|
}
|
|
1719
|
-
return
|
|
2395
|
+
return bindGroupEntriesByGroup;
|
|
1720
2396
|
}
|
|
1721
2397
|
};
|
|
1722
2398
|
isStorageTextureBindingLayout = (maybe) => {
|
|
@@ -1725,16 +2401,796 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1725
2401
|
}
|
|
1726
2402
|
});
|
|
1727
2403
|
|
|
2404
|
+
// dist/adapter/resources/webgpu-fence.js
|
|
2405
|
+
var import_core21, WebGPUFence;
|
|
2406
|
+
var init_webgpu_fence = __esm({
|
|
2407
|
+
"dist/adapter/resources/webgpu-fence.js"() {
|
|
2408
|
+
"use strict";
|
|
2409
|
+
import_core21 = require("@luma.gl/core");
|
|
2410
|
+
WebGPUFence = class extends import_core21.Fence {
|
|
2411
|
+
device;
|
|
2412
|
+
handle = null;
|
|
2413
|
+
signaled;
|
|
2414
|
+
_signaled = false;
|
|
2415
|
+
constructor(device, props = {}) {
|
|
2416
|
+
super(device, {});
|
|
2417
|
+
this.device = device;
|
|
2418
|
+
this.signaled = device.handle.queue.onSubmittedWorkDone().then(() => {
|
|
2419
|
+
this._signaled = true;
|
|
2420
|
+
}).catch((error) => {
|
|
2421
|
+
if (this.device.shouldIgnoreDroppedInstanceError(error)) {
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
throw error;
|
|
2425
|
+
});
|
|
2426
|
+
}
|
|
2427
|
+
isSignaled() {
|
|
2428
|
+
return this._signaled;
|
|
2429
|
+
}
|
|
2430
|
+
destroy() {
|
|
2431
|
+
}
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2434
|
+
});
|
|
2435
|
+
|
|
2436
|
+
// dist/wgsl/get-shader-layout-wgsl.js
|
|
2437
|
+
function getShaderLayoutFromWGSL(source) {
|
|
2438
|
+
var _a;
|
|
2439
|
+
const shaderLayout = { attributes: [], bindings: [] };
|
|
2440
|
+
let parsedWGSL;
|
|
2441
|
+
try {
|
|
2442
|
+
parsedWGSL = parseWGSL(source);
|
|
2443
|
+
} catch (error) {
|
|
2444
|
+
import_core22.log.error(error.message)();
|
|
2445
|
+
return shaderLayout;
|
|
2446
|
+
}
|
|
2447
|
+
for (const uniform of parsedWGSL.uniforms) {
|
|
2448
|
+
const members = [];
|
|
2449
|
+
for (const attribute of ((_a = uniform.type) == null ? void 0 : _a.members) || []) {
|
|
2450
|
+
members.push({
|
|
2451
|
+
name: attribute.name,
|
|
2452
|
+
type: getType(attribute.type)
|
|
2453
|
+
});
|
|
2454
|
+
}
|
|
2455
|
+
shaderLayout.bindings.push({
|
|
2456
|
+
type: "uniform",
|
|
2457
|
+
name: uniform.name,
|
|
2458
|
+
group: uniform.group,
|
|
2459
|
+
location: uniform.binding,
|
|
2460
|
+
// @ts-expect-error TODO - unused for now but needs fixing
|
|
2461
|
+
members
|
|
2462
|
+
});
|
|
2463
|
+
}
|
|
2464
|
+
for (const storageBuffer of parsedWGSL.storage) {
|
|
2465
|
+
shaderLayout.bindings.push({
|
|
2466
|
+
type: storageBuffer.access === "read" ? "read-only-storage" : "storage",
|
|
2467
|
+
name: storageBuffer.name,
|
|
2468
|
+
group: storageBuffer.group,
|
|
2469
|
+
location: storageBuffer.binding
|
|
2470
|
+
});
|
|
2471
|
+
}
|
|
2472
|
+
for (const texture of parsedWGSL.textures) {
|
|
2473
|
+
const bindingDeclaration = {
|
|
2474
|
+
type: "texture",
|
|
2475
|
+
name: texture.name,
|
|
2476
|
+
group: texture.group,
|
|
2477
|
+
location: texture.binding,
|
|
2478
|
+
...getTextureBindingFromReflect(texture)
|
|
2479
|
+
};
|
|
2480
|
+
shaderLayout.bindings.push(bindingDeclaration);
|
|
2481
|
+
}
|
|
2482
|
+
for (const sampler of parsedWGSL.samplers) {
|
|
2483
|
+
shaderLayout.bindings.push({
|
|
2484
|
+
type: "sampler",
|
|
2485
|
+
name: sampler.name,
|
|
2486
|
+
group: sampler.group,
|
|
2487
|
+
location: sampler.binding
|
|
2488
|
+
});
|
|
2489
|
+
}
|
|
2490
|
+
const vertex = parsedWGSL.entry.vertex[0];
|
|
2491
|
+
const attributeCount = (vertex == null ? void 0 : vertex.inputs.length) || 0;
|
|
2492
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
2493
|
+
const wgslAttribute = vertex.inputs[i];
|
|
2494
|
+
if (wgslAttribute.locationType === "location") {
|
|
2495
|
+
const type = getType(wgslAttribute.type);
|
|
2496
|
+
shaderLayout.attributes.push({
|
|
2497
|
+
name: wgslAttribute.name,
|
|
2498
|
+
location: Number(wgslAttribute.location),
|
|
2499
|
+
type
|
|
2500
|
+
});
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
return shaderLayout;
|
|
2504
|
+
}
|
|
2505
|
+
function getType(type) {
|
|
2506
|
+
return (type == null ? void 0 : type.format) ? `${type.name}<${type.format.name}>` : type.name;
|
|
2507
|
+
}
|
|
2508
|
+
function parseWGSL(source) {
|
|
2509
|
+
try {
|
|
2510
|
+
return new import_wgsl_reflect.WgslReflect(source);
|
|
2511
|
+
} catch (error) {
|
|
2512
|
+
if (error instanceof Error) {
|
|
2513
|
+
throw error;
|
|
2514
|
+
}
|
|
2515
|
+
let message = "WGSL parse error";
|
|
2516
|
+
if (typeof error === "object" && (error == null ? void 0 : error.message)) {
|
|
2517
|
+
message += `: ${error.message} `;
|
|
2518
|
+
}
|
|
2519
|
+
if (typeof error === "object" && (error == null ? void 0 : error.token)) {
|
|
2520
|
+
message += error.token.line || "";
|
|
2521
|
+
}
|
|
2522
|
+
throw new Error(message, { cause: error });
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
function getTextureBindingFromReflect(v, opts) {
|
|
2526
|
+
var _a;
|
|
2527
|
+
if (v.resourceType !== import_wgsl_reflect.ResourceType.Texture) {
|
|
2528
|
+
throw new Error("Not a texture binding");
|
|
2529
|
+
}
|
|
2530
|
+
const typeName = v.type.name;
|
|
2531
|
+
const component = (_a = v.type.format) == null ? void 0 : _a.name;
|
|
2532
|
+
const viewDimension = typeName.includes("cube_array") ? "cube-array" : typeName.includes("cube") ? "cube" : typeName.includes("2d_array") ? "2d-array" : typeName.includes("3d") ? "3d" : typeName.includes("1d") ? "1d" : "2d";
|
|
2533
|
+
const multisampled = typeName === "texture_multisampled_2d";
|
|
2534
|
+
let sampleType;
|
|
2535
|
+
if (typeName.startsWith("texture_depth")) {
|
|
2536
|
+
sampleType = "depth";
|
|
2537
|
+
} else if (component === "i32") {
|
|
2538
|
+
sampleType = "sint";
|
|
2539
|
+
} else if (component === "u32") {
|
|
2540
|
+
sampleType = "uint";
|
|
2541
|
+
} else {
|
|
2542
|
+
sampleType = "float";
|
|
2543
|
+
}
|
|
2544
|
+
return { viewDimension, sampleType, multisampled };
|
|
2545
|
+
}
|
|
2546
|
+
var import_core22, import_wgsl_reflect;
|
|
2547
|
+
var init_get_shader_layout_wgsl = __esm({
|
|
2548
|
+
"dist/wgsl/get-shader-layout-wgsl.js"() {
|
|
2549
|
+
"use strict";
|
|
2550
|
+
import_core22 = require("@luma.gl/core");
|
|
2551
|
+
import_wgsl_reflect = require("wgsl_reflect");
|
|
2552
|
+
}
|
|
2553
|
+
});
|
|
2554
|
+
|
|
2555
|
+
// dist/adapter/helpers/generate-mipmaps-webgpu.js
|
|
2556
|
+
function generateMipmapsWebGPU(device, texture) {
|
|
2557
|
+
if (texture.mipLevels <= 1) {
|
|
2558
|
+
return;
|
|
2559
|
+
}
|
|
2560
|
+
if (texture.dimension === "3d") {
|
|
2561
|
+
generateMipmaps3D(device, texture);
|
|
2562
|
+
return;
|
|
2563
|
+
}
|
|
2564
|
+
if (RENDER_DIMENSIONS.includes(texture.dimension)) {
|
|
2565
|
+
generateMipmapsRender(device, texture);
|
|
2566
|
+
return;
|
|
2567
|
+
}
|
|
2568
|
+
throw new Error(`Cannot generate mipmaps for texture dimension "${texture.dimension}" with WebGPU.`);
|
|
2569
|
+
}
|
|
2570
|
+
function generateMipmapsRender(device, texture) {
|
|
2571
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
2572
|
+
const colorAttachmentFormat = getColorAttachmentFormat(texture.format, "render", texture.dimension);
|
|
2573
|
+
const viewDimension = texture.dimension;
|
|
2574
|
+
const shaderSource = getRenderMipmapWGSL(viewDimension);
|
|
2575
|
+
const sampler = device.createSampler({ minFilter: "linear", magFilter: "linear" });
|
|
2576
|
+
const uniformsBuffer = device.createBuffer({
|
|
2577
|
+
byteLength: 16,
|
|
2578
|
+
usage: import_core23.Buffer.UNIFORM | import_core23.Buffer.COPY_DST
|
|
2579
|
+
});
|
|
2580
|
+
const uniformValues = new Uint32Array(1);
|
|
2581
|
+
const sourceTextureLayout = {
|
|
2582
|
+
type: "texture",
|
|
2583
|
+
name: "sourceTexture",
|
|
2584
|
+
group: 0,
|
|
2585
|
+
location: 1,
|
|
2586
|
+
viewDimension,
|
|
2587
|
+
sampleType: "float"
|
|
2588
|
+
};
|
|
2589
|
+
const uniformsLayout = {
|
|
2590
|
+
type: "uniform",
|
|
2591
|
+
name: "uniforms",
|
|
2592
|
+
group: 0,
|
|
2593
|
+
location: 2
|
|
2594
|
+
};
|
|
2595
|
+
const renderShaderLayout = {
|
|
2596
|
+
attributes: [],
|
|
2597
|
+
bindings: [RENDER_SOURCE_SAMPLER_LAYOUT, sourceTextureLayout, uniformsLayout]
|
|
2598
|
+
};
|
|
2599
|
+
const vertexShader = device.createShader({
|
|
2600
|
+
id: "mipmap-generation-render-vs",
|
|
2601
|
+
source: shaderSource,
|
|
2602
|
+
language: "wgsl",
|
|
2603
|
+
stage: "vertex"
|
|
2604
|
+
});
|
|
2605
|
+
const fragmentShader = device.createShader({
|
|
2606
|
+
id: "mipmap-generation-render-fs",
|
|
2607
|
+
source: shaderSource,
|
|
2608
|
+
language: "wgsl",
|
|
2609
|
+
stage: "fragment"
|
|
2610
|
+
});
|
|
2611
|
+
const renderPipeline = device.createRenderPipeline({
|
|
2612
|
+
id: `mipmap-generation-render:${texture.dimension}:${texture.format}`,
|
|
2613
|
+
vs: vertexShader,
|
|
2614
|
+
fs: fragmentShader,
|
|
2615
|
+
shaderLayout: renderShaderLayout,
|
|
2616
|
+
colorAttachmentFormats: [colorAttachmentFormat],
|
|
2617
|
+
topology: "triangle-list"
|
|
2618
|
+
});
|
|
2619
|
+
let sourceWidth = texture.width;
|
|
2620
|
+
let sourceHeight = texture.height;
|
|
2621
|
+
const layerCount = texture.dimension === "2d" ? 1 : texture.depth;
|
|
2622
|
+
function renderMipmapLayer(sourceView, baseMipLevel, baseArrayLayer, destinationWidth, destinationHeight) {
|
|
2623
|
+
uniformValues[0] = baseArrayLayer;
|
|
2624
|
+
uniformsBuffer.write(uniformValues);
|
|
2625
|
+
const destinationView = texture.createView({
|
|
2626
|
+
dimension: "2d",
|
|
2627
|
+
baseMipLevel,
|
|
2628
|
+
mipLevelCount: 1,
|
|
2629
|
+
baseArrayLayer,
|
|
2630
|
+
arrayLayerCount: 1
|
|
2631
|
+
});
|
|
2632
|
+
const framebuffer = device.createFramebuffer({
|
|
2633
|
+
colorAttachments: [destinationView]
|
|
2634
|
+
});
|
|
2635
|
+
const renderPass = device.beginRenderPass({
|
|
2636
|
+
id: `mipmap-generation:${texture.format}:${baseMipLevel}:${baseArrayLayer}`,
|
|
2637
|
+
framebuffer
|
|
2638
|
+
});
|
|
2639
|
+
try {
|
|
2640
|
+
renderPass.setPipeline(renderPipeline);
|
|
2641
|
+
renderPass.setBindings({
|
|
2642
|
+
sourceSampler: sampler,
|
|
2643
|
+
sourceTexture: sourceView,
|
|
2644
|
+
uniforms: uniformsBuffer
|
|
2645
|
+
});
|
|
2646
|
+
renderPass.setParameters({
|
|
2647
|
+
viewport: [0, 0, destinationWidth, destinationHeight, 0, 1],
|
|
2648
|
+
scissorRect: [0, 0, destinationWidth, destinationHeight]
|
|
2649
|
+
});
|
|
2650
|
+
renderPass.draw({ vertexCount: 3 });
|
|
2651
|
+
renderPass.end();
|
|
2652
|
+
device.submit();
|
|
2653
|
+
} finally {
|
|
2654
|
+
destinationView.destroy();
|
|
2655
|
+
framebuffer.destroy();
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
try {
|
|
2659
|
+
for (let baseMipLevel = 1; baseMipLevel < texture.mipLevels; ++baseMipLevel) {
|
|
2660
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
2661
|
+
const sourceMipLevel = baseMipLevel - 1;
|
|
2662
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2663
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2664
|
+
const sourceView = texture.createView({
|
|
2665
|
+
dimension: viewDimension,
|
|
2666
|
+
baseMipLevel: sourceMipLevel,
|
|
2667
|
+
mipLevelCount: 1,
|
|
2668
|
+
baseArrayLayer: 0,
|
|
2669
|
+
arrayLayerCount: texture.depth
|
|
2670
|
+
});
|
|
2671
|
+
try {
|
|
2672
|
+
for (let baseArrayLayer = 0; baseArrayLayer < layerCount; ++baseArrayLayer) {
|
|
2673
|
+
renderMipmapLayer(sourceView, baseMipLevel, baseArrayLayer, destinationWidth, destinationHeight);
|
|
2674
|
+
}
|
|
2675
|
+
} finally {
|
|
2676
|
+
sourceView.destroy();
|
|
2677
|
+
}
|
|
2678
|
+
sourceWidth = destinationWidth;
|
|
2679
|
+
sourceHeight = destinationHeight;
|
|
2680
|
+
}
|
|
2681
|
+
} finally {
|
|
2682
|
+
renderPipeline.destroy();
|
|
2683
|
+
vertexShader.destroy();
|
|
2684
|
+
fragmentShader.destroy();
|
|
2685
|
+
sampler.destroy();
|
|
2686
|
+
uniformsBuffer.destroy();
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
function getColorAttachmentFormat(format, path, dimension) {
|
|
2690
|
+
if (import_core23.textureFormatDecoder.isColor(format)) {
|
|
2691
|
+
return format;
|
|
2692
|
+
}
|
|
2693
|
+
throw new Error(`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Only color textures can be used for this operation. Required capabilities: color. Actual capabilities: color=false.`);
|
|
2694
|
+
}
|
|
2695
|
+
function generateMipmaps3D(device, texture) {
|
|
2696
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2697
|
+
const format = getColorAttachmentFormat(texture.format, "compute", texture.dimension);
|
|
2698
|
+
const shaderSource = get3DComputeMipmapWGSL(format);
|
|
2699
|
+
const destinationTextureLayout = {
|
|
2700
|
+
type: "storage",
|
|
2701
|
+
name: "destinationTexture",
|
|
2702
|
+
group: 0,
|
|
2703
|
+
location: 1,
|
|
2704
|
+
format,
|
|
2705
|
+
viewDimension: "3d",
|
|
2706
|
+
access: "write-only"
|
|
2707
|
+
};
|
|
2708
|
+
const computeShaderLayout = {
|
|
2709
|
+
bindings: [COMPUTE_SOURCE_TEXTURE_LAYOUT, destinationTextureLayout, COMPUTE_UNIFORMS_LAYOUT]
|
|
2710
|
+
};
|
|
2711
|
+
const computeShader = device.createShader({
|
|
2712
|
+
id: "mipmap-generation-compute",
|
|
2713
|
+
source: shaderSource,
|
|
2714
|
+
language: "wgsl",
|
|
2715
|
+
stage: "compute"
|
|
2716
|
+
});
|
|
2717
|
+
const computePipeline = device.createComputePipeline({
|
|
2718
|
+
id: `mipmap-generation-compute:${texture.format}`,
|
|
2719
|
+
shader: computeShader,
|
|
2720
|
+
shaderLayout: computeShaderLayout
|
|
2721
|
+
});
|
|
2722
|
+
const uniformsBuffer = device.createBuffer({
|
|
2723
|
+
byteLength: 32,
|
|
2724
|
+
usage: import_core23.Buffer.UNIFORM | import_core23.Buffer.COPY_DST
|
|
2725
|
+
});
|
|
2726
|
+
const uniformValues = new Uint32Array(8);
|
|
2727
|
+
let sourceWidth = texture.width;
|
|
2728
|
+
let sourceHeight = texture.height;
|
|
2729
|
+
let sourceDepth = texture.depth;
|
|
2730
|
+
try {
|
|
2731
|
+
for (let destinationMipLevel = 1; destinationMipLevel < texture.mipLevels; ++destinationMipLevel) {
|
|
2732
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2733
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2734
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2735
|
+
const destinationDepth = Math.max(1, sourceDepth >> 1);
|
|
2736
|
+
uniformValues[0] = sourceWidth;
|
|
2737
|
+
uniformValues[1] = sourceHeight;
|
|
2738
|
+
uniformValues[2] = sourceDepth;
|
|
2739
|
+
uniformValues[3] = destinationWidth;
|
|
2740
|
+
uniformValues[4] = destinationHeight;
|
|
2741
|
+
uniformValues[5] = destinationDepth;
|
|
2742
|
+
uniformValues[6] = 0;
|
|
2743
|
+
uniformsBuffer.write(uniformValues);
|
|
2744
|
+
const sourceView = texture.createView({
|
|
2745
|
+
dimension: "3d",
|
|
2746
|
+
baseMipLevel: destinationMipLevel - 1,
|
|
2747
|
+
mipLevelCount: 1,
|
|
2748
|
+
baseArrayLayer: 0,
|
|
2749
|
+
arrayLayerCount: 1
|
|
2750
|
+
});
|
|
2751
|
+
const destinationView = texture.createView({
|
|
2752
|
+
dimension: "3d",
|
|
2753
|
+
baseMipLevel: destinationMipLevel,
|
|
2754
|
+
mipLevelCount: 1,
|
|
2755
|
+
baseArrayLayer: 0,
|
|
2756
|
+
arrayLayerCount: 1
|
|
2757
|
+
});
|
|
2758
|
+
computePipeline.setBindings({
|
|
2759
|
+
sourceTexture: sourceView,
|
|
2760
|
+
destinationTexture: destinationView,
|
|
2761
|
+
uniforms: uniformsBuffer
|
|
2762
|
+
});
|
|
2763
|
+
try {
|
|
2764
|
+
const workgroupsX = Math.ceil(destinationWidth / WORKGROUP_SIZE.x);
|
|
2765
|
+
const workgroupsY = Math.ceil(destinationHeight / WORKGROUP_SIZE.y);
|
|
2766
|
+
const workgroupsZ = Math.ceil(destinationDepth / WORKGROUP_SIZE.z);
|
|
2767
|
+
const computePass = device.beginComputePass({});
|
|
2768
|
+
computePass.setPipeline(computePipeline);
|
|
2769
|
+
computePass.dispatch(workgroupsX, workgroupsY, workgroupsZ);
|
|
2770
|
+
computePass.end();
|
|
2771
|
+
device.submit();
|
|
2772
|
+
} finally {
|
|
2773
|
+
sourceView.destroy();
|
|
2774
|
+
destinationView.destroy();
|
|
2775
|
+
}
|
|
2776
|
+
sourceWidth = destinationWidth;
|
|
2777
|
+
sourceHeight = destinationHeight;
|
|
2778
|
+
sourceDepth = destinationDepth;
|
|
2779
|
+
}
|
|
2780
|
+
} finally {
|
|
2781
|
+
computePipeline.destroy();
|
|
2782
|
+
computeShader.destroy();
|
|
2783
|
+
uniformsBuffer.destroy();
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
function validateFormatCapabilities(device, texture, requiredCapabilities, path) {
|
|
2787
|
+
const { format, dimension } = texture;
|
|
2788
|
+
const capabilities = device.getTextureFormatCapabilities(format);
|
|
2789
|
+
const missingCapabilities = requiredCapabilities.filter((capability) => !capabilities[capability]);
|
|
2790
|
+
if (missingCapabilities.length > 0) {
|
|
2791
|
+
const required = requiredCapabilities.join(" + ");
|
|
2792
|
+
const actual = requiredCapabilities.map((capability) => `${capability}=${capabilities[capability]}`).join(", ");
|
|
2793
|
+
throw new Error(`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Required capabilities: ${required}. Actual capabilities: ${actual}.`);
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
function getSourceTextureType(dimension) {
|
|
2797
|
+
switch (dimension) {
|
|
2798
|
+
case "2d":
|
|
2799
|
+
return "texture_2d<f32>";
|
|
2800
|
+
case "2d-array":
|
|
2801
|
+
return "texture_2d_array<f32>";
|
|
2802
|
+
case "cube":
|
|
2803
|
+
return "texture_cube<f32>";
|
|
2804
|
+
case "cube-array":
|
|
2805
|
+
return "texture_cube_array<f32>";
|
|
2806
|
+
default:
|
|
2807
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
function getRenderMipmapWGSL(dimension) {
|
|
2811
|
+
const sourceSnippet = getRenderMipmapSampleSnippet(dimension);
|
|
2812
|
+
return `
|
|
2813
|
+
struct MipmapUniforms {
|
|
2814
|
+
sourceLayer: u32,
|
|
2815
|
+
};
|
|
2816
|
+
|
|
2817
|
+
fn _touchUniform(uniforms: MipmapUniforms) {
|
|
2818
|
+
let unusedSourceLayer = uniforms.sourceLayer;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
const faceMat = array(
|
|
2822
|
+
mat3x3f(
|
|
2823
|
+
0.0, 0.0, -2.0,
|
|
2824
|
+
0.0, -2.0, 0.0,
|
|
2825
|
+
1.0, 1.0, 1.0
|
|
2826
|
+
), // pos-x
|
|
2827
|
+
mat3x3f(
|
|
2828
|
+
0.0, 0.0, 2.0,
|
|
2829
|
+
0.0, -2.0, 0.0,
|
|
2830
|
+
-1.0, 1.0, -1.0
|
|
2831
|
+
), // neg-x
|
|
2832
|
+
mat3x3f(
|
|
2833
|
+
2.0, 0.0, 0.0,
|
|
2834
|
+
0.0, 0.0, 2.0,
|
|
2835
|
+
-1.0, 1.0, -1.0
|
|
2836
|
+
), // pos-y
|
|
2837
|
+
mat3x3f(
|
|
2838
|
+
2.0, 0.0, 0.0,
|
|
2839
|
+
0.0, 0.0, -2.0,
|
|
2840
|
+
-1.0, -1.0, 1.0
|
|
2841
|
+
), // neg-y
|
|
2842
|
+
mat3x3f(
|
|
2843
|
+
2.0, 0.0, 0.0,
|
|
2844
|
+
0.0, -2.0, 0.0,
|
|
2845
|
+
-1.0, 1.0, 1.0
|
|
2846
|
+
), // pos-z
|
|
2847
|
+
mat3x3f(
|
|
2848
|
+
-2.0, 0.0, 0.0,
|
|
2849
|
+
0.0, -2.0, 0.0,
|
|
2850
|
+
1.0, 1.0, -1.0
|
|
2851
|
+
) // neg-z
|
|
2852
|
+
);
|
|
2853
|
+
|
|
2854
|
+
struct FragmentInputs {
|
|
2855
|
+
@builtin(position) position: vec4f,
|
|
2856
|
+
@location(0) texcoord: vec2f
|
|
2857
|
+
};
|
|
2858
|
+
|
|
2859
|
+
struct VertexOutput {
|
|
2860
|
+
@builtin(position) position: vec4f,
|
|
2861
|
+
@location(0) texcoord: vec2f
|
|
2862
|
+
};
|
|
2863
|
+
|
|
2864
|
+
@group(0) @binding(0) var sourceSampler: sampler;
|
|
2865
|
+
@group(0) @binding(1) var sourceTexture: ${getSourceTextureType(dimension)};
|
|
2866
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2867
|
+
|
|
2868
|
+
@vertex
|
|
2869
|
+
fn vertexMain(
|
|
2870
|
+
@builtin(vertex_index) vertexIndex: u32
|
|
2871
|
+
) -> VertexOutput {
|
|
2872
|
+
const positions = array(
|
|
2873
|
+
vec2f(-1.0, -1.0),
|
|
2874
|
+
vec2f(-1.0, 3.0),
|
|
2875
|
+
vec2f( 3.0, -1.0)
|
|
2876
|
+
);
|
|
2877
|
+
|
|
2878
|
+
let xy = positions[vertexIndex];
|
|
2879
|
+
return VertexOutput(
|
|
2880
|
+
vec4f(xy, 0.0, 1.0),
|
|
2881
|
+
xy * vec2f(0.5, -0.5) + vec2f(0.5)
|
|
2882
|
+
);
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
@fragment
|
|
2886
|
+
fn fragmentMain(fsInput: VertexOutput) -> @location(0) vec4f {
|
|
2887
|
+
_touchUniform(uniforms);
|
|
2888
|
+
return ${sourceSnippet};
|
|
2889
|
+
}
|
|
2890
|
+
`;
|
|
2891
|
+
}
|
|
2892
|
+
function getRenderMipmapSampleSnippet(dimension) {
|
|
2893
|
+
const layer = "uniforms.sourceLayer";
|
|
2894
|
+
switch (dimension) {
|
|
2895
|
+
case "2d":
|
|
2896
|
+
return "textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, 0.0)";
|
|
2897
|
+
case "2d-array":
|
|
2898
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, i32(${layer}), 0.0)`;
|
|
2899
|
+
case "cube":
|
|
2900
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer})] * vec3f(fract(fsInput.texcoord), 1.0), 0.0)`;
|
|
2901
|
+
case "cube-array":
|
|
2902
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer} % 6u)] * vec3f(fract(fsInput.texcoord), 1.0), i32(${layer} / 6u), 0.0)`;
|
|
2903
|
+
default:
|
|
2904
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
function get3DComputeMipmapWGSL(format) {
|
|
2908
|
+
return `
|
|
2909
|
+
struct MipmapUniforms {
|
|
2910
|
+
sourceWidth: u32,
|
|
2911
|
+
sourceHeight: u32,
|
|
2912
|
+
sourceDepth: u32,
|
|
2913
|
+
destinationWidth: u32,
|
|
2914
|
+
destinationHeight: u32,
|
|
2915
|
+
destinationDepth: u32,
|
|
2916
|
+
padding: u32,
|
|
2917
|
+
};
|
|
2918
|
+
|
|
2919
|
+
@group(0) @binding(0) var sourceTexture: texture_3d<f32>;
|
|
2920
|
+
@group(0) @binding(1) var destinationTexture: texture_storage_3d<${format}, write>;
|
|
2921
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2922
|
+
|
|
2923
|
+
@compute @workgroup_size(${WORKGROUP_SIZE.x}, ${WORKGROUP_SIZE.y}, ${WORKGROUP_SIZE.z})
|
|
2924
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
2925
|
+
if (
|
|
2926
|
+
id.x >= uniforms.destinationWidth ||
|
|
2927
|
+
id.y >= uniforms.destinationHeight ||
|
|
2928
|
+
id.z >= uniforms.destinationDepth
|
|
2929
|
+
) {
|
|
2930
|
+
return;
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2933
|
+
let sourceBase = id * 2u;
|
|
2934
|
+
let sourceX0 = min(sourceBase.x, uniforms.sourceWidth - 1u);
|
|
2935
|
+
let sourceY0 = min(sourceBase.y, uniforms.sourceHeight - 1u);
|
|
2936
|
+
let sourceZ0 = min(sourceBase.z, uniforms.sourceDepth - 1u);
|
|
2937
|
+
|
|
2938
|
+
let sourceX1 = min(sourceBase.x + 1u, uniforms.sourceWidth - 1u);
|
|
2939
|
+
let sourceY1 = min(sourceBase.y + 1u, uniforms.sourceHeight - 1u);
|
|
2940
|
+
let sourceZ1 = min(sourceBase.z + 1u, uniforms.sourceDepth - 1u);
|
|
2941
|
+
|
|
2942
|
+
var sum = textureLoad(
|
|
2943
|
+
sourceTexture,
|
|
2944
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ0)),
|
|
2945
|
+
0
|
|
2946
|
+
);
|
|
2947
|
+
sum += textureLoad(
|
|
2948
|
+
sourceTexture,
|
|
2949
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ0)),
|
|
2950
|
+
0
|
|
2951
|
+
);
|
|
2952
|
+
sum += textureLoad(
|
|
2953
|
+
sourceTexture,
|
|
2954
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ0)),
|
|
2955
|
+
0
|
|
2956
|
+
);
|
|
2957
|
+
sum += textureLoad(
|
|
2958
|
+
sourceTexture,
|
|
2959
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ0)),
|
|
2960
|
+
0
|
|
2961
|
+
);
|
|
2962
|
+
sum += textureLoad(
|
|
2963
|
+
sourceTexture,
|
|
2964
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ1)),
|
|
2965
|
+
0
|
|
2966
|
+
);
|
|
2967
|
+
sum += textureLoad(
|
|
2968
|
+
sourceTexture,
|
|
2969
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ1)),
|
|
2970
|
+
0
|
|
2971
|
+
);
|
|
2972
|
+
sum += textureLoad(
|
|
2973
|
+
sourceTexture,
|
|
2974
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ1)),
|
|
2975
|
+
0
|
|
2976
|
+
);
|
|
2977
|
+
sum += textureLoad(
|
|
2978
|
+
sourceTexture,
|
|
2979
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ1)),
|
|
2980
|
+
0
|
|
2981
|
+
);
|
|
2982
|
+
|
|
2983
|
+
textureStore(
|
|
2984
|
+
destinationTexture,
|
|
2985
|
+
vec3<i32>(i32(id.x), i32(id.y), i32(id.z)),
|
|
2986
|
+
vec4<f32>(sum.xyz / 8.0, sum.w / 8.0)
|
|
2987
|
+
);
|
|
2988
|
+
}
|
|
2989
|
+
`;
|
|
2990
|
+
}
|
|
2991
|
+
var import_core23, RENDER_DIMENSIONS, WORKGROUP_SIZE, RENDER_SOURCE_SAMPLER_LAYOUT, COMPUTE_SOURCE_TEXTURE_LAYOUT, COMPUTE_UNIFORMS_LAYOUT;
|
|
2992
|
+
var init_generate_mipmaps_webgpu = __esm({
|
|
2993
|
+
"dist/adapter/helpers/generate-mipmaps-webgpu.js"() {
|
|
2994
|
+
"use strict";
|
|
2995
|
+
import_core23 = require("@luma.gl/core");
|
|
2996
|
+
RENDER_DIMENSIONS = [
|
|
2997
|
+
"2d",
|
|
2998
|
+
"2d-array",
|
|
2999
|
+
"cube",
|
|
3000
|
+
"cube-array"
|
|
3001
|
+
];
|
|
3002
|
+
WORKGROUP_SIZE = {
|
|
3003
|
+
x: 4,
|
|
3004
|
+
y: 4,
|
|
3005
|
+
z: 4
|
|
3006
|
+
};
|
|
3007
|
+
RENDER_SOURCE_SAMPLER_LAYOUT = {
|
|
3008
|
+
type: "sampler",
|
|
3009
|
+
name: "sourceSampler",
|
|
3010
|
+
group: 0,
|
|
3011
|
+
location: 0
|
|
3012
|
+
};
|
|
3013
|
+
COMPUTE_SOURCE_TEXTURE_LAYOUT = {
|
|
3014
|
+
type: "texture",
|
|
3015
|
+
name: "sourceTexture",
|
|
3016
|
+
group: 0,
|
|
3017
|
+
location: 0,
|
|
3018
|
+
viewDimension: "3d",
|
|
3019
|
+
sampleType: "float"
|
|
3020
|
+
};
|
|
3021
|
+
COMPUTE_UNIFORMS_LAYOUT = {
|
|
3022
|
+
type: "uniform",
|
|
3023
|
+
name: "uniforms",
|
|
3024
|
+
group: 0,
|
|
3025
|
+
location: 2
|
|
3026
|
+
};
|
|
3027
|
+
}
|
|
3028
|
+
});
|
|
3029
|
+
|
|
3030
|
+
// dist/adapter/helpers/get-bind-group.js
|
|
3031
|
+
function getBindGroup(device, bindGroupLayout, shaderLayout, bindings, group, label) {
|
|
3032
|
+
const entries = getBindGroupEntries(bindings, shaderLayout, group);
|
|
3033
|
+
if (entries.length === 0) {
|
|
3034
|
+
return null;
|
|
3035
|
+
}
|
|
3036
|
+
device.pushErrorScope("validation");
|
|
3037
|
+
const bindGroup = device.handle.createBindGroup({
|
|
3038
|
+
label,
|
|
3039
|
+
layout: bindGroupLayout,
|
|
3040
|
+
entries
|
|
3041
|
+
});
|
|
3042
|
+
device.popErrorScope((error) => {
|
|
3043
|
+
const summary = formatBindGroupCreationErrorSummary(shaderLayout, bindings, entries, group);
|
|
3044
|
+
import_core24.log.error(`bindGroup creation: ${summary}
|
|
3045
|
+
Raw WebGPU error: ${error.message}`, bindGroup)();
|
|
3046
|
+
});
|
|
3047
|
+
return bindGroup;
|
|
3048
|
+
}
|
|
3049
|
+
function formatBindGroupCreationErrorSummary(shaderLayout, bindings, entries, group) {
|
|
3050
|
+
const expectedBindings = getExpectedBindingsForGroup(shaderLayout, group);
|
|
3051
|
+
const expectedByLocation = new Map(expectedBindings.map((bindingSummary) => [bindingSummary.location, bindingSummary]));
|
|
3052
|
+
const providedBindings = entries.map((entry) => expectedByLocation.get(entry.binding) || getUnexpectedEntrySummary(entry)).sort(compareBindingSummaries);
|
|
3053
|
+
const missingBindings = expectedBindings.filter((bindingSummary) => !providedBindings.some((provided) => provided.location === bindingSummary.location));
|
|
3054
|
+
const unexpectedBindings = providedBindings.filter((bindingSummary) => !expectedByLocation.has(bindingSummary.location));
|
|
3055
|
+
const unmatchedLogicalBindings = Object.keys(bindings).filter((bindingName) => !resolveGroupBinding(bindingName, bindings, shaderLayout, group)).sort();
|
|
3056
|
+
const lines = [
|
|
3057
|
+
`bindGroup creation failed for group ${group}: expected ${expectedBindings.length}, provided ${providedBindings.length}`,
|
|
3058
|
+
`expected: ${formatBindingSummaryList(expectedBindings)}`,
|
|
3059
|
+
`provided: ${formatBindingSummaryList(providedBindings)}`
|
|
3060
|
+
];
|
|
3061
|
+
if (missingBindings.length > 0) {
|
|
3062
|
+
lines.push(`missing: ${formatBindingSummaryList(missingBindings)}`);
|
|
3063
|
+
}
|
|
3064
|
+
if (unexpectedBindings.length > 0) {
|
|
3065
|
+
lines.push(`unexpected entries: ${formatBindingSummaryList(unexpectedBindings)}`);
|
|
3066
|
+
}
|
|
3067
|
+
if (unmatchedLogicalBindings.length > 0) {
|
|
3068
|
+
lines.push(`unmatched logical bindings: ${unmatchedLogicalBindings.join(", ")}`);
|
|
3069
|
+
}
|
|
3070
|
+
return lines.join("\n");
|
|
3071
|
+
}
|
|
3072
|
+
function getBindGroupEntries(bindings, shaderLayout, group) {
|
|
3073
|
+
const entries = [];
|
|
3074
|
+
for (const [bindingName, value] of Object.entries(bindings)) {
|
|
3075
|
+
const { bindingLayout, isShadowedAlias } = resolveGroupBinding(bindingName, bindings, shaderLayout, group) || { bindingLayout: null, isShadowedAlias: false };
|
|
3076
|
+
if (!isShadowedAlias && bindingLayout) {
|
|
3077
|
+
const entry = bindingLayout ? getBindGroupEntry(value, bindingLayout.location, void 0, bindingName) : null;
|
|
3078
|
+
if (entry) {
|
|
3079
|
+
entries.push(entry);
|
|
3080
|
+
}
|
|
3081
|
+
if (value instanceof import_core24.Texture) {
|
|
3082
|
+
const samplerBindingLayout = (0, import_core24.getShaderLayoutBinding)(shaderLayout, `${bindingName}Sampler`, {
|
|
3083
|
+
ignoreWarnings: true
|
|
3084
|
+
});
|
|
3085
|
+
const samplerEntry = samplerBindingLayout ? samplerBindingLayout.group === group ? getBindGroupEntry(value, samplerBindingLayout.location, { sampler: true }, bindingName) : null : null;
|
|
3086
|
+
if (samplerEntry) {
|
|
3087
|
+
entries.push(samplerEntry);
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
return entries;
|
|
3093
|
+
}
|
|
3094
|
+
function getBindGroupEntry(binding, index, options, bindingName = "unknown") {
|
|
3095
|
+
if (binding instanceof import_core24.Buffer) {
|
|
3096
|
+
return {
|
|
3097
|
+
binding: index,
|
|
3098
|
+
resource: {
|
|
3099
|
+
buffer: binding.handle
|
|
3100
|
+
}
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
if (binding instanceof import_core24.Sampler) {
|
|
3104
|
+
return {
|
|
3105
|
+
binding: index,
|
|
3106
|
+
resource: binding.handle
|
|
3107
|
+
};
|
|
3108
|
+
}
|
|
3109
|
+
if (binding instanceof import_core24.TextureView) {
|
|
3110
|
+
return {
|
|
3111
|
+
binding: index,
|
|
3112
|
+
resource: binding.handle
|
|
3113
|
+
};
|
|
3114
|
+
}
|
|
3115
|
+
if (binding instanceof import_core24.Texture) {
|
|
3116
|
+
if (options == null ? void 0 : options.sampler) {
|
|
3117
|
+
return {
|
|
3118
|
+
binding: index,
|
|
3119
|
+
resource: binding.sampler.handle
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
return {
|
|
3123
|
+
binding: index,
|
|
3124
|
+
resource: binding.view.handle
|
|
3125
|
+
};
|
|
3126
|
+
}
|
|
3127
|
+
import_core24.log.warn(`invalid binding ${bindingName}`, binding);
|
|
3128
|
+
return null;
|
|
3129
|
+
}
|
|
3130
|
+
function getExpectedBindingsForGroup(shaderLayout, group) {
|
|
3131
|
+
return shaderLayout.bindings.filter((bindingLayout) => bindingLayout.group === group).map((bindingLayout) => toBindingSummary(bindingLayout)).sort(compareBindingSummaries);
|
|
3132
|
+
}
|
|
3133
|
+
function resolveGroupBinding(bindingName, bindings, shaderLayout, group) {
|
|
3134
|
+
const exactBindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName);
|
|
3135
|
+
const bindingLayout = exactBindingLayout || (0, import_core24.getShaderLayoutBinding)(shaderLayout, bindingName, { ignoreWarnings: true });
|
|
3136
|
+
const isShadowedAlias = !exactBindingLayout && bindingLayout ? bindingLayout.name in bindings : false;
|
|
3137
|
+
if (isShadowedAlias || !bindingLayout || bindingLayout.group !== group) {
|
|
3138
|
+
return null;
|
|
3139
|
+
}
|
|
3140
|
+
return { bindingLayout, isShadowedAlias };
|
|
3141
|
+
}
|
|
3142
|
+
function toBindingSummary(bindingLayout) {
|
|
3143
|
+
return {
|
|
3144
|
+
name: bindingLayout.name,
|
|
3145
|
+
location: bindingLayout.location,
|
|
3146
|
+
type: bindingLayout.type
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
function getUnexpectedEntrySummary(entry) {
|
|
3150
|
+
return {
|
|
3151
|
+
name: "?",
|
|
3152
|
+
location: entry.binding,
|
|
3153
|
+
type: "unknown"
|
|
3154
|
+
};
|
|
3155
|
+
}
|
|
3156
|
+
function compareBindingSummaries(left, right) {
|
|
3157
|
+
if (left.location !== right.location) {
|
|
3158
|
+
return left.location - right.location;
|
|
3159
|
+
}
|
|
3160
|
+
return left.name.localeCompare(right.name);
|
|
3161
|
+
}
|
|
3162
|
+
function formatBindingSummaryList(bindings) {
|
|
3163
|
+
if (bindings.length === 0) {
|
|
3164
|
+
return "none";
|
|
3165
|
+
}
|
|
3166
|
+
return bindings.map((binding) => `${binding.name}@${binding.location}`).join(", ");
|
|
3167
|
+
}
|
|
3168
|
+
var import_core24;
|
|
3169
|
+
var init_get_bind_group = __esm({
|
|
3170
|
+
"dist/adapter/helpers/get-bind-group.js"() {
|
|
3171
|
+
"use strict";
|
|
3172
|
+
import_core24 = require("@luma.gl/core");
|
|
3173
|
+
}
|
|
3174
|
+
});
|
|
3175
|
+
|
|
1728
3176
|
// dist/adapter/webgpu-device.js
|
|
1729
3177
|
var webgpu_device_exports = {};
|
|
1730
3178
|
__export(webgpu_device_exports, {
|
|
1731
3179
|
WebGPUDevice: () => WebGPUDevice
|
|
1732
3180
|
});
|
|
1733
|
-
|
|
3181
|
+
function scheduleMicrotask(callback) {
|
|
3182
|
+
if (globalThis.queueMicrotask) {
|
|
3183
|
+
globalThis.queueMicrotask(callback);
|
|
3184
|
+
return;
|
|
3185
|
+
}
|
|
3186
|
+
Promise.resolve().then(callback).catch(() => {
|
|
3187
|
+
});
|
|
3188
|
+
}
|
|
3189
|
+
var import_core25, WebGPUDevice;
|
|
1734
3190
|
var init_webgpu_device = __esm({
|
|
1735
3191
|
"dist/adapter/webgpu-device.js"() {
|
|
1736
3192
|
"use strict";
|
|
1737
|
-
|
|
3193
|
+
import_core25 = require("@luma.gl/core");
|
|
1738
3194
|
init_webgpu_buffer();
|
|
1739
3195
|
init_webgpu_texture();
|
|
1740
3196
|
init_webgpu_external_texture();
|
|
@@ -1745,10 +3201,16 @@ var init_webgpu_device = __esm({
|
|
|
1745
3201
|
init_webgpu_compute_pipeline();
|
|
1746
3202
|
init_webgpu_vertex_array();
|
|
1747
3203
|
init_webgpu_canvas_context();
|
|
3204
|
+
init_webgpu_presentation_context();
|
|
1748
3205
|
init_webgpu_command_encoder();
|
|
1749
3206
|
init_webgpu_query_set();
|
|
1750
3207
|
init_webgpu_pipeline_layout();
|
|
1751
|
-
|
|
3208
|
+
init_webgpu_fence();
|
|
3209
|
+
init_get_shader_layout_wgsl();
|
|
3210
|
+
init_generate_mipmaps_webgpu();
|
|
3211
|
+
init_get_bind_group();
|
|
3212
|
+
init_cpu_hotspot_profiler();
|
|
3213
|
+
WebGPUDevice = class extends import_core25.Device {
|
|
1752
3214
|
/** The underlying WebGPU device */
|
|
1753
3215
|
handle;
|
|
1754
3216
|
/* The underlying WebGPU adapter */
|
|
@@ -1765,6 +3227,7 @@ var init_webgpu_device = __esm({
|
|
|
1765
3227
|
lost;
|
|
1766
3228
|
canvasContext = null;
|
|
1767
3229
|
_isLost = false;
|
|
3230
|
+
_defaultSampler = null;
|
|
1768
3231
|
commandEncoder;
|
|
1769
3232
|
get [Symbol.toStringTag]() {
|
|
1770
3233
|
return "WebGPUDevice";
|
|
@@ -1786,12 +3249,11 @@ var init_webgpu_device = __esm({
|
|
|
1786
3249
|
this.reportError(new Error(errorMessage), this)();
|
|
1787
3250
|
this.debug();
|
|
1788
3251
|
});
|
|
1789
|
-
this.lost =
|
|
1790
|
-
const lostInfo = await this.handle.lost;
|
|
3252
|
+
this.lost = this.handle.lost.then((lostInfo) => {
|
|
1791
3253
|
this._isLost = true;
|
|
1792
|
-
|
|
3254
|
+
return { reason: "destroyed", message: lostInfo.message };
|
|
1793
3255
|
});
|
|
1794
|
-
const canvasContextProps =
|
|
3256
|
+
const canvasContextProps = import_core25.Device._getCanvasContextProps(props);
|
|
1795
3257
|
if (canvasContextProps) {
|
|
1796
3258
|
this.canvasContext = new WebGPUCanvasContext(this, this.adapter, canvasContextProps);
|
|
1797
3259
|
}
|
|
@@ -1802,18 +3264,22 @@ var init_webgpu_device = __esm({
|
|
|
1802
3264
|
// const {glsl = true} = props;
|
|
1803
3265
|
// this.glslang = glsl && await loadGlslangModule();
|
|
1804
3266
|
destroy() {
|
|
3267
|
+
var _a, _b;
|
|
3268
|
+
(_a = this.commandEncoder) == null ? void 0 : _a.destroy();
|
|
3269
|
+
(_b = this._defaultSampler) == null ? void 0 : _b.destroy();
|
|
3270
|
+
this._defaultSampler = null;
|
|
1805
3271
|
this.handle.destroy();
|
|
1806
3272
|
}
|
|
1807
3273
|
get isLost() {
|
|
1808
3274
|
return this._isLost;
|
|
1809
3275
|
}
|
|
3276
|
+
getShaderLayout(source) {
|
|
3277
|
+
return getShaderLayoutFromWGSL(source);
|
|
3278
|
+
}
|
|
1810
3279
|
isVertexFormatSupported(format) {
|
|
1811
3280
|
const info = this.getVertexFormatInfo(format);
|
|
1812
3281
|
return !info.webglOnly;
|
|
1813
3282
|
}
|
|
1814
|
-
getTextureByteAlignment() {
|
|
1815
|
-
return 1;
|
|
1816
|
-
}
|
|
1817
3283
|
createBuffer(props) {
|
|
1818
3284
|
const newProps = this._normalizeBufferProps(props);
|
|
1819
3285
|
return new WebGPUBuffer(this, newProps);
|
|
@@ -1830,6 +3296,12 @@ var init_webgpu_device = __esm({
|
|
|
1830
3296
|
createSampler(props) {
|
|
1831
3297
|
return new WebGPUSampler(this, props);
|
|
1832
3298
|
}
|
|
3299
|
+
getDefaultSampler() {
|
|
3300
|
+
this._defaultSampler ||= new WebGPUSampler(this, {
|
|
3301
|
+
id: `${this.id}-default-sampler`
|
|
3302
|
+
});
|
|
3303
|
+
return this._defaultSampler;
|
|
3304
|
+
}
|
|
1833
3305
|
createRenderPipeline(props) {
|
|
1834
3306
|
return new WebGPURenderPipeline(this, props);
|
|
1835
3307
|
}
|
|
@@ -1852,35 +3324,136 @@ var init_webgpu_device = __esm({
|
|
|
1852
3324
|
createQuerySet(props) {
|
|
1853
3325
|
return new WebGPUQuerySet(this, props);
|
|
1854
3326
|
}
|
|
3327
|
+
createFence() {
|
|
3328
|
+
return new WebGPUFence(this);
|
|
3329
|
+
}
|
|
1855
3330
|
createCanvasContext(props) {
|
|
1856
3331
|
return new WebGPUCanvasContext(this, this.adapter, props);
|
|
1857
3332
|
}
|
|
3333
|
+
createPresentationContext(props) {
|
|
3334
|
+
return new WebGPUPresentationContext(this, props);
|
|
3335
|
+
}
|
|
1858
3336
|
createPipelineLayout(props) {
|
|
1859
3337
|
return new WebGPUPipelineLayout(this, props);
|
|
1860
3338
|
}
|
|
3339
|
+
generateMipmapsWebGPU(texture) {
|
|
3340
|
+
generateMipmapsWebGPU(this, texture);
|
|
3341
|
+
}
|
|
3342
|
+
_createBindGroupLayoutWebGPU(pipeline, group) {
|
|
3343
|
+
return pipeline.handle.getBindGroupLayout(group);
|
|
3344
|
+
}
|
|
3345
|
+
_createBindGroupWebGPU(bindGroupLayout, shaderLayout, bindings, group, label) {
|
|
3346
|
+
if (Object.keys(bindings).length === 0) {
|
|
3347
|
+
return this.handle.createBindGroup({
|
|
3348
|
+
label,
|
|
3349
|
+
layout: bindGroupLayout,
|
|
3350
|
+
entries: []
|
|
3351
|
+
});
|
|
3352
|
+
}
|
|
3353
|
+
return getBindGroup(this, bindGroupLayout, shaderLayout, bindings, group, label);
|
|
3354
|
+
}
|
|
1861
3355
|
submit(commandBuffer) {
|
|
3356
|
+
let submittedCommandEncoder = null;
|
|
1862
3357
|
if (!commandBuffer) {
|
|
1863
|
-
commandBuffer = this.
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
this
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
this.
|
|
3358
|
+
({ submittedCommandEncoder, commandBuffer } = this._finalizeDefaultCommandEncoderForSubmit());
|
|
3359
|
+
}
|
|
3360
|
+
const profiler = getCpuHotspotProfiler(this);
|
|
3361
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
3362
|
+
const submitReason = getCpuHotspotSubmitReason(this);
|
|
3363
|
+
try {
|
|
3364
|
+
this.pushErrorScope("validation");
|
|
3365
|
+
const queueSubmitStartTime = profiler ? getTimestamp() : 0;
|
|
3366
|
+
this.handle.queue.submit([commandBuffer.handle]);
|
|
3367
|
+
if (profiler) {
|
|
3368
|
+
profiler.queueSubmitCount = (profiler.queueSubmitCount || 0) + 1;
|
|
3369
|
+
profiler.queueSubmitTimeMs = (profiler.queueSubmitTimeMs || 0) + (getTimestamp() - queueSubmitStartTime);
|
|
3370
|
+
}
|
|
3371
|
+
this.popErrorScope((error) => {
|
|
3372
|
+
this.reportError(new Error(`${this} command submission: ${error.message}`), this)();
|
|
3373
|
+
this.debug();
|
|
3374
|
+
});
|
|
3375
|
+
if (submittedCommandEncoder) {
|
|
3376
|
+
const submitResolveKickoffStartTime = profiler ? getTimestamp() : 0;
|
|
3377
|
+
scheduleMicrotask(() => {
|
|
3378
|
+
submittedCommandEncoder.resolveTimeProfilingQuerySet().then(() => {
|
|
3379
|
+
this.commandEncoder._gpuTimeMs = submittedCommandEncoder._gpuTimeMs;
|
|
3380
|
+
}).catch(() => {
|
|
3381
|
+
});
|
|
3382
|
+
});
|
|
3383
|
+
if (profiler) {
|
|
3384
|
+
profiler.submitResolveKickoffCount = (profiler.submitResolveKickoffCount || 0) + 1;
|
|
3385
|
+
profiler.submitResolveKickoffTimeMs = (profiler.submitResolveKickoffTimeMs || 0) + (getTimestamp() - submitResolveKickoffStartTime);
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
} finally {
|
|
3389
|
+
if (profiler) {
|
|
3390
|
+
profiler.submitCount = (profiler.submitCount || 0) + 1;
|
|
3391
|
+
profiler.submitTimeMs = (profiler.submitTimeMs || 0) + (getTimestamp() - startTime);
|
|
3392
|
+
const reasonCountKey = submitReason === "query-readback" ? "queryReadbackSubmitCount" : "defaultSubmitCount";
|
|
3393
|
+
const reasonTimeKey = submitReason === "query-readback" ? "queryReadbackSubmitTimeMs" : "defaultSubmitTimeMs";
|
|
3394
|
+
profiler[reasonCountKey] = (profiler[reasonCountKey] || 0) + 1;
|
|
3395
|
+
profiler[reasonTimeKey] = (profiler[reasonTimeKey] || 0) + (getTimestamp() - startTime);
|
|
3396
|
+
}
|
|
3397
|
+
const commandBufferDestroyStartTime = profiler ? getTimestamp() : 0;
|
|
3398
|
+
commandBuffer.destroy();
|
|
3399
|
+
if (profiler) {
|
|
3400
|
+
profiler.commandBufferDestroyCount = (profiler.commandBufferDestroyCount || 0) + 1;
|
|
3401
|
+
profiler.commandBufferDestroyTimeMs = (profiler.commandBufferDestroyTimeMs || 0) + (getTimestamp() - commandBufferDestroyStartTime);
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
_finalizeDefaultCommandEncoderForSubmit() {
|
|
3406
|
+
const submittedCommandEncoder = this.commandEncoder;
|
|
3407
|
+
if (submittedCommandEncoder.getTimeProfilingSlotCount() > 0 && submittedCommandEncoder.getTimeProfilingQuerySet() instanceof WebGPUQuerySet) {
|
|
3408
|
+
const querySet = submittedCommandEncoder.getTimeProfilingQuerySet();
|
|
3409
|
+
querySet._encodeResolveToReadBuffer(submittedCommandEncoder, {
|
|
3410
|
+
firstQuery: 0,
|
|
3411
|
+
queryCount: submittedCommandEncoder.getTimeProfilingSlotCount()
|
|
3412
|
+
});
|
|
3413
|
+
}
|
|
3414
|
+
const commandBuffer = submittedCommandEncoder.finish();
|
|
3415
|
+
this.commandEncoder.destroy();
|
|
3416
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
3417
|
+
id: submittedCommandEncoder.props.id,
|
|
3418
|
+
timeProfilingQuerySet: submittedCommandEncoder.getTimeProfilingQuerySet()
|
|
1872
3419
|
});
|
|
3420
|
+
return { submittedCommandEncoder, commandBuffer };
|
|
1873
3421
|
}
|
|
1874
3422
|
// WebGPU specific
|
|
1875
3423
|
pushErrorScope(scope) {
|
|
3424
|
+
if (!this.props.debug) {
|
|
3425
|
+
return;
|
|
3426
|
+
}
|
|
3427
|
+
const profiler = getCpuHotspotProfiler(this);
|
|
3428
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1876
3429
|
this.handle.pushErrorScope(scope);
|
|
3430
|
+
if (profiler) {
|
|
3431
|
+
profiler.errorScopePushCount = (profiler.errorScopePushCount || 0) + 1;
|
|
3432
|
+
profiler.errorScopeTimeMs = (profiler.errorScopeTimeMs || 0) + (getTimestamp() - startTime);
|
|
3433
|
+
}
|
|
1877
3434
|
}
|
|
1878
3435
|
popErrorScope(handler) {
|
|
3436
|
+
if (!this.props.debug) {
|
|
3437
|
+
return;
|
|
3438
|
+
}
|
|
3439
|
+
const profiler = getCpuHotspotProfiler(this);
|
|
3440
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1879
3441
|
this.handle.popErrorScope().then((error) => {
|
|
1880
3442
|
if (error) {
|
|
1881
3443
|
handler(error);
|
|
1882
3444
|
}
|
|
3445
|
+
}).catch((error) => {
|
|
3446
|
+
if (this.shouldIgnoreDroppedInstanceError(error, "popErrorScope")) {
|
|
3447
|
+
return;
|
|
3448
|
+
}
|
|
3449
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3450
|
+
this.reportError(new Error(`${this} popErrorScope failed: ${errorMessage}`), this)();
|
|
3451
|
+
this.debug();
|
|
1883
3452
|
});
|
|
3453
|
+
if (profiler) {
|
|
3454
|
+
profiler.errorScopePopCount = (profiler.errorScopePopCount || 0) + 1;
|
|
3455
|
+
profiler.errorScopeTimeMs = (profiler.errorScopeTimeMs || 0) + (getTimestamp() - startTime);
|
|
3456
|
+
}
|
|
1884
3457
|
}
|
|
1885
3458
|
// PRIVATE METHODS
|
|
1886
3459
|
_getInfo() {
|
|
@@ -1888,10 +3461,12 @@ var init_webgpu_device = __esm({
|
|
|
1888
3461
|
const vendor = this.adapterInfo.vendor || this.adapter.__brand || "unknown";
|
|
1889
3462
|
const renderer = driver || "";
|
|
1890
3463
|
const version = driverVersion || "";
|
|
1891
|
-
const
|
|
3464
|
+
const fallback = Boolean(this.adapterInfo.isFallbackAdapter ?? this.adapter.isFallbackAdapter ?? false);
|
|
3465
|
+
const softwareRenderer = /SwiftShader/i.test(`${vendor} ${renderer} ${this.adapterInfo.architecture || ""}`);
|
|
3466
|
+
const gpu = vendor === "apple" ? "apple" : softwareRenderer || fallback ? "software" : "unknown";
|
|
1892
3467
|
const gpuArchitecture = this.adapterInfo.architecture || "unknown";
|
|
1893
3468
|
const gpuBackend = this.adapterInfo.backend || "unknown";
|
|
1894
|
-
const gpuType = (this.adapterInfo.type || "").split(" ")[0].toLowerCase() || "unknown";
|
|
3469
|
+
const gpuType = (this.adapterInfo.type || "").split(" ")[0].toLowerCase() || (softwareRenderer || fallback ? "cpu" : "unknown");
|
|
1895
3470
|
return {
|
|
1896
3471
|
type: "webgpu",
|
|
1897
3472
|
vendor,
|
|
@@ -1901,10 +3476,15 @@ var init_webgpu_device = __esm({
|
|
|
1901
3476
|
gpuType,
|
|
1902
3477
|
gpuBackend,
|
|
1903
3478
|
gpuArchitecture,
|
|
3479
|
+
fallback,
|
|
1904
3480
|
shadingLanguage: "wgsl",
|
|
1905
3481
|
shadingLanguageVersion: 100
|
|
1906
3482
|
};
|
|
1907
3483
|
}
|
|
3484
|
+
shouldIgnoreDroppedInstanceError(error, operation) {
|
|
3485
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3486
|
+
return errorMessage.includes("Instance dropped") && (!operation || errorMessage.includes(operation)) && (this._isLost || this.info.gpu === "software" || this.info.gpuType === "cpu" || Boolean(this.info.fallback));
|
|
3487
|
+
}
|
|
1908
3488
|
_getFeatures() {
|
|
1909
3489
|
const features = new Set(this.handle.features);
|
|
1910
3490
|
if (features.has("depth-clamping")) {
|
|
@@ -1914,8 +3494,13 @@ var init_webgpu_device = __esm({
|
|
|
1914
3494
|
if (features.has("texture-compression-bc")) {
|
|
1915
3495
|
features.add("texture-compression-bc5-webgl");
|
|
1916
3496
|
}
|
|
3497
|
+
if (this.handle.features.has("chromium-experimental-norm16-texture-formats")) {
|
|
3498
|
+
features.add("norm16-renderable-webgl");
|
|
3499
|
+
}
|
|
3500
|
+
if (this.handle.features.has("chromium-experimental-snorm16-texture-formats")) {
|
|
3501
|
+
features.add("snorm16-renderable-webgl");
|
|
3502
|
+
}
|
|
1917
3503
|
const WEBGPU_ALWAYS_FEATURES = [
|
|
1918
|
-
"timer-query-webgl",
|
|
1919
3504
|
"compilation-status-async-webgl",
|
|
1920
3505
|
"float32-renderable-webgl",
|
|
1921
3506
|
"float16-renderable-webgl",
|
|
@@ -1926,7 +3511,7 @@ var init_webgpu_device = __esm({
|
|
|
1926
3511
|
for (const feature of WEBGPU_ALWAYS_FEATURES) {
|
|
1927
3512
|
features.add(feature);
|
|
1928
3513
|
}
|
|
1929
|
-
return new
|
|
3514
|
+
return new import_core25.DeviceFeatures(Array.from(features), this.props._disabledFeatures);
|
|
1930
3515
|
}
|
|
1931
3516
|
_getDeviceSpecificTextureFormatCapabilities(capabilities) {
|
|
1932
3517
|
const { format } = capabilities;
|
|
@@ -1944,16 +3529,18 @@ var dist_exports = {};
|
|
|
1944
3529
|
__export(dist_exports, {
|
|
1945
3530
|
WebGPUBuffer: () => WebGPUBuffer,
|
|
1946
3531
|
WebGPUDevice: () => WebGPUDevice,
|
|
3532
|
+
WebGPUFence: () => WebGPUFence,
|
|
1947
3533
|
WebGPUSampler: () => WebGPUSampler,
|
|
1948
3534
|
WebGPUShader: () => WebGPUShader,
|
|
1949
3535
|
WebGPUTexture: () => WebGPUTexture,
|
|
3536
|
+
getShaderLayoutFromWGSL: () => getShaderLayoutFromWGSL,
|
|
1950
3537
|
webgpuAdapter: () => webgpuAdapter
|
|
1951
3538
|
});
|
|
1952
3539
|
module.exports = __toCommonJS(dist_exports);
|
|
1953
3540
|
|
|
1954
3541
|
// dist/adapter/webgpu-adapter.js
|
|
1955
|
-
var
|
|
1956
|
-
var WebGPUAdapter = class extends
|
|
3542
|
+
var import_core26 = require("@luma.gl/core");
|
|
3543
|
+
var WebGPUAdapter = class extends import_core26.Adapter {
|
|
1957
3544
|
/** type of device's created by this adapter */
|
|
1958
3545
|
type = "webgpu";
|
|
1959
3546
|
isSupported() {
|
|
@@ -1973,43 +3560,41 @@ var WebGPUAdapter = class extends import_core22.Adapter {
|
|
|
1973
3560
|
if (!navigator.gpu) {
|
|
1974
3561
|
throw new Error("WebGPU not available. Recent Chrome browsers should work.");
|
|
1975
3562
|
}
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
const
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
const
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
const value = adapter.limits[limit];
|
|
1996
|
-
if (typeof value === "number") {
|
|
1997
|
-
requiredLimits[limit] = value;
|
|
1998
|
-
}
|
|
3563
|
+
const adapter = await navigator.gpu.requestAdapter({
|
|
3564
|
+
powerPreference: "high-performance"
|
|
3565
|
+
// forceSoftware: false
|
|
3566
|
+
});
|
|
3567
|
+
if (!adapter) {
|
|
3568
|
+
throw new Error("Failed to request WebGPU adapter");
|
|
3569
|
+
}
|
|
3570
|
+
const adapterInfo = adapter.info || // @ts-ignore
|
|
3571
|
+
await ((_a = adapter.requestAdapterInfo) == null ? void 0 : _a.call(adapter));
|
|
3572
|
+
const requiredFeatures = [];
|
|
3573
|
+
const requiredLimits = {};
|
|
3574
|
+
if (props._requestMaxLimits) {
|
|
3575
|
+
requiredFeatures.push(...Array.from(adapter.features));
|
|
3576
|
+
const limits = Object.keys(adapter.limits).filter((key) => !["minSubgroupSize", "maxSubgroupSize"].includes(key));
|
|
3577
|
+
for (const key of limits) {
|
|
3578
|
+
const limit = key;
|
|
3579
|
+
const value = adapter.limits[limit];
|
|
3580
|
+
if (typeof value === "number") {
|
|
3581
|
+
requiredLimits[limit] = value;
|
|
1999
3582
|
}
|
|
2000
3583
|
}
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
3584
|
+
}
|
|
3585
|
+
const gpuDevice = await adapter.requestDevice({
|
|
3586
|
+
requiredFeatures,
|
|
3587
|
+
requiredLimits
|
|
3588
|
+
});
|
|
3589
|
+
const { WebGPUDevice: WebGPUDevice2 } = await Promise.resolve().then(() => (init_webgpu_device(), webgpu_device_exports));
|
|
3590
|
+
import_core26.log.groupCollapsed(1, "WebGPUDevice created")();
|
|
3591
|
+
try {
|
|
2007
3592
|
const device = new WebGPUDevice2(props, gpuDevice, adapter, adapterInfo);
|
|
2008
|
-
|
|
2009
|
-
|
|
3593
|
+
import_core26.log.probe(1, "Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")();
|
|
3594
|
+
import_core26.log.table(1, device.info)();
|
|
2010
3595
|
return device;
|
|
2011
3596
|
} finally {
|
|
2012
|
-
|
|
3597
|
+
import_core26.log.groupEnd(1)();
|
|
2013
3598
|
}
|
|
2014
3599
|
}
|
|
2015
3600
|
async attach(handle) {
|
|
@@ -2024,4 +3609,6 @@ init_webgpu_buffer();
|
|
|
2024
3609
|
init_webgpu_texture();
|
|
2025
3610
|
init_webgpu_sampler();
|
|
2026
3611
|
init_webgpu_shader();
|
|
3612
|
+
init_webgpu_fence();
|
|
3613
|
+
init_get_shader_layout_wgsl();
|
|
2027
3614
|
//# sourceMappingURL=index.cjs.map
|