@luma.gl/webgpu 9.2.5 → 9.3.0-alpha.10
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 +4 -6
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +39 -32
- 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 +56 -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 +34 -34
- 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 +173 -16
- 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 +8070 -547
- package/dist/dist.min.js +169 -6
- package/dist/index.cjs +1929 -410
- 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 +52 -46
- 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 +83 -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 +40 -42
- package/src/adapter/webgpu-canvas-context.ts +107 -40
- package/src/adapter/webgpu-device.ts +231 -21
- 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,59 +1020,74 @@ 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) => {
|
|
@@ -905,29 +1096,40 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
905
1096
|
this.device.debug();
|
|
906
1097
|
});
|
|
907
1098
|
}
|
|
1099
|
+
this.descriptor = descriptor;
|
|
908
1100
|
this.handle.label = this.props.id;
|
|
909
1101
|
this.vs = props.vs;
|
|
910
1102
|
this.fs = props.fs;
|
|
911
|
-
this.
|
|
1103
|
+
this._bindingsByGroup = props.bindGroups || (0, import_core9.normalizeBindingsByGroup)(this.shaderLayout, props.bindings);
|
|
1104
|
+
this._bindGroupCacheKeysByGroup = createBindGroupCacheKeys(this._bindingsByGroup);
|
|
912
1105
|
}
|
|
913
1106
|
destroy() {
|
|
914
1107
|
this.handle = null;
|
|
915
1108
|
}
|
|
916
1109
|
/**
|
|
917
|
-
*
|
|
918
|
-
*
|
|
1110
|
+
* Compatibility shim for code paths that still set bindings on the pipeline.
|
|
1111
|
+
* The shared-model path passes bindings per draw and does not rely on this state.
|
|
919
1112
|
*/
|
|
920
1113
|
setBindings(bindings) {
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
1114
|
+
const nextBindingsByGroup = (0, import_core9.normalizeBindingsByGroup)(this.shaderLayout, bindings);
|
|
1115
|
+
for (const [groupKey, groupBindings] of Object.entries(nextBindingsByGroup)) {
|
|
1116
|
+
const group = Number(groupKey);
|
|
1117
|
+
for (const [name, binding] of Object.entries(groupBindings || {})) {
|
|
1118
|
+
const currentGroupBindings = this._bindingsByGroup[group] || {};
|
|
1119
|
+
if (currentGroupBindings[name] !== binding) {
|
|
1120
|
+
if (!this._bindingsByGroup[group] || this._bindingsByGroup[group] === currentGroupBindings) {
|
|
1121
|
+
this._bindingsByGroup[group] = { ...currentGroupBindings };
|
|
1122
|
+
}
|
|
1123
|
+
this._bindingsByGroup[group][name] = binding;
|
|
1124
|
+
this._bindGroupCacheKeysByGroup[group] = {};
|
|
1125
|
+
}
|
|
924
1126
|
}
|
|
925
1127
|
}
|
|
926
|
-
Object.assign(this._bindings, bindings);
|
|
927
1128
|
}
|
|
928
1129
|
/** @todo - should this be moved to renderpass? */
|
|
929
1130
|
draw(options) {
|
|
930
1131
|
const webgpuRenderPass = options.renderPass;
|
|
1132
|
+
const instanceCount = options.instanceCount && options.instanceCount > 0 ? options.instanceCount : 1;
|
|
931
1133
|
this.device.pushErrorScope("validation");
|
|
932
1134
|
webgpuRenderPass.handle.setPipeline(this.handle);
|
|
933
1135
|
this.device.popErrorScope((error) => {
|
|
@@ -935,32 +1137,27 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
935
1137
|
"${error.message}"`), this)();
|
|
936
1138
|
this.device.debug();
|
|
937
1139
|
});
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
1140
|
+
const hasExplicitBindings = Boolean(options.bindGroups || options.bindings);
|
|
1141
|
+
const bindGroups = (0, import_core9._getDefaultBindGroupFactory)(this.device).getBindGroups(this, hasExplicitBindings ? options.bindGroups || options.bindings : this._bindingsByGroup, hasExplicitBindings ? options._bindGroupCacheKeys : this._bindGroupCacheKeysByGroup);
|
|
1142
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1143
|
+
if (bindGroup) {
|
|
1144
|
+
webgpuRenderPass.handle.setBindGroup(Number(group), bindGroup);
|
|
1145
|
+
}
|
|
941
1146
|
}
|
|
942
1147
|
options.vertexArray.bindBeforeRender(options.renderPass);
|
|
943
1148
|
if (options.indexCount) {
|
|
944
|
-
webgpuRenderPass.handle.drawIndexed(options.indexCount,
|
|
1149
|
+
webgpuRenderPass.handle.drawIndexed(options.indexCount, instanceCount, options.firstIndex || 0, options.baseVertex || 0, options.firstInstance || 0);
|
|
945
1150
|
} else {
|
|
946
|
-
webgpuRenderPass.handle.draw(
|
|
947
|
-
options.vertexCount || 0,
|
|
948
|
-
options.instanceCount || 1,
|
|
949
|
-
// If 0, nothing will be drawn
|
|
950
|
-
options.firstInstance
|
|
951
|
-
);
|
|
1151
|
+
webgpuRenderPass.handle.draw(options.vertexCount || 0, instanceCount, options.firstVertex || 0, options.firstInstance || 0);
|
|
952
1152
|
}
|
|
953
1153
|
options.vertexArray.unbindAfterRender(options.renderPass);
|
|
954
1154
|
return true;
|
|
955
1155
|
}
|
|
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;
|
|
1156
|
+
_getBindingsByGroupWebGPU() {
|
|
1157
|
+
return this._bindingsByGroup;
|
|
1158
|
+
}
|
|
1159
|
+
_getBindGroupCacheKeysWebGPU() {
|
|
1160
|
+
return this._bindGroupCacheKeysByGroup;
|
|
964
1161
|
}
|
|
965
1162
|
/**
|
|
966
1163
|
* Populate the complex WebGPU GPURenderPipelineDescriptor
|
|
@@ -969,7 +1166,9 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
969
1166
|
const vertex = {
|
|
970
1167
|
module: this.props.vs.handle,
|
|
971
1168
|
entryPoint: this.props.vertexEntryPoint || "main",
|
|
972
|
-
buffers: getVertexBufferLayout(this.shaderLayout, this.props.bufferLayout
|
|
1169
|
+
buffers: getVertexBufferLayout(this.shaderLayout, this.props.bufferLayout, {
|
|
1170
|
+
pipelineId: this.id
|
|
1171
|
+
})
|
|
973
1172
|
};
|
|
974
1173
|
const targets = [];
|
|
975
1174
|
if (this.props.colorAttachmentFormats) {
|
|
@@ -1009,12 +1208,12 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
1009
1208
|
});
|
|
1010
1209
|
|
|
1011
1210
|
// dist/adapter/resources/webgpu-framebuffer.js
|
|
1012
|
-
var
|
|
1211
|
+
var import_core10, WebGPUFramebuffer;
|
|
1013
1212
|
var init_webgpu_framebuffer = __esm({
|
|
1014
1213
|
"dist/adapter/resources/webgpu-framebuffer.js"() {
|
|
1015
1214
|
"use strict";
|
|
1016
|
-
|
|
1017
|
-
WebGPUFramebuffer = class extends
|
|
1215
|
+
import_core10 = require("@luma.gl/core");
|
|
1216
|
+
WebGPUFramebuffer = class extends import_core10.Framebuffer {
|
|
1018
1217
|
device;
|
|
1019
1218
|
handle = null;
|
|
1020
1219
|
colorAttachments = [];
|
|
@@ -1026,25 +1225,37 @@ var init_webgpu_framebuffer = __esm({
|
|
|
1026
1225
|
}
|
|
1027
1226
|
updateAttachments() {
|
|
1028
1227
|
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Internal-only hook for the cached CanvasContext/PresentationContext swapchain path.
|
|
1230
|
+
* Rebinds the long-lived default framebuffer wrapper to the current per-frame color view
|
|
1231
|
+
* and optional depth attachment without allocating a new luma.gl Framebuffer object.
|
|
1232
|
+
*/
|
|
1233
|
+
_reinitialize(colorAttachment, depthStencilAttachment) {
|
|
1234
|
+
this.colorAttachments[0] = colorAttachment;
|
|
1235
|
+
this.depthStencilAttachment = depthStencilAttachment;
|
|
1236
|
+
this.width = colorAttachment.texture.width;
|
|
1237
|
+
this.height = colorAttachment.texture.height;
|
|
1238
|
+
this.props.width = this.width;
|
|
1239
|
+
this.props.height = this.height;
|
|
1240
|
+
this.props.colorAttachments = [colorAttachment.texture];
|
|
1241
|
+
this.props.depthStencilAttachment = (depthStencilAttachment == null ? void 0 : depthStencilAttachment.texture) || null;
|
|
1242
|
+
}
|
|
1029
1243
|
};
|
|
1030
1244
|
}
|
|
1031
1245
|
});
|
|
1032
1246
|
|
|
1033
1247
|
// dist/adapter/resources/webgpu-compute-pipeline.js
|
|
1034
|
-
var
|
|
1248
|
+
var import_core11, EMPTY_BIND_GROUPS, WebGPUComputePipeline;
|
|
1035
1249
|
var init_webgpu_compute_pipeline = __esm({
|
|
1036
1250
|
"dist/adapter/resources/webgpu-compute-pipeline.js"() {
|
|
1037
1251
|
"use strict";
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
WebGPUComputePipeline = class extends
|
|
1252
|
+
import_core11 = require("@luma.gl/core");
|
|
1253
|
+
EMPTY_BIND_GROUPS = {};
|
|
1254
|
+
WebGPUComputePipeline = class extends import_core11.ComputePipeline {
|
|
1041
1255
|
device;
|
|
1042
1256
|
handle;
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
_bindGroup = null;
|
|
1046
|
-
/** For internal use to create BindGroups */
|
|
1047
|
-
_bindings = {};
|
|
1257
|
+
_bindingsByGroup;
|
|
1258
|
+
_bindGroupCacheKeysByGroup;
|
|
1048
1259
|
constructor(device, props) {
|
|
1049
1260
|
super(device, props);
|
|
1050
1261
|
this.device = device;
|
|
@@ -1058,34 +1269,53 @@ var init_webgpu_compute_pipeline = __esm({
|
|
|
1058
1269
|
},
|
|
1059
1270
|
layout: "auto"
|
|
1060
1271
|
});
|
|
1272
|
+
this._bindingsByGroup = EMPTY_BIND_GROUPS;
|
|
1273
|
+
this._bindGroupCacheKeysByGroup = {};
|
|
1061
1274
|
}
|
|
1062
1275
|
/**
|
|
1063
1276
|
* @todo Use renderpass.setBindings() ?
|
|
1064
1277
|
* @todo Do we want to expose BindGroups in the API and remove this?
|
|
1065
1278
|
*/
|
|
1066
1279
|
setBindings(bindings) {
|
|
1067
|
-
|
|
1280
|
+
const nextBindingsByGroup = (0, import_core11.normalizeBindingsByGroup)(this.shaderLayout, bindings);
|
|
1281
|
+
for (const [groupKey, groupBindings] of Object.entries(nextBindingsByGroup)) {
|
|
1282
|
+
const group = Number(groupKey);
|
|
1283
|
+
for (const [name, binding] of Object.entries(groupBindings || {})) {
|
|
1284
|
+
const currentGroupBindings = this._bindingsByGroup[group] || {};
|
|
1285
|
+
if (currentGroupBindings[name] !== binding) {
|
|
1286
|
+
if (!this._bindingsByGroup[group] || this._bindingsByGroup[group] === currentGroupBindings) {
|
|
1287
|
+
this._bindingsByGroup[group] = { ...currentGroupBindings };
|
|
1288
|
+
}
|
|
1289
|
+
this._bindingsByGroup[group][name] = binding;
|
|
1290
|
+
this._bindGroupCacheKeysByGroup[group] = {};
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
_getBindGroups(bindings, bindGroupCacheKeys) {
|
|
1296
|
+
const hasExplicitBindings = Boolean(bindings);
|
|
1297
|
+
return (0, import_core11._getDefaultBindGroupFactory)(this.device).getBindGroups(this, hasExplicitBindings ? bindings : this._bindingsByGroup, hasExplicitBindings ? bindGroupCacheKeys : this._bindGroupCacheKeysByGroup);
|
|
1068
1298
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
return this.
|
|
1299
|
+
_getBindingsByGroupWebGPU() {
|
|
1300
|
+
return this._bindingsByGroup;
|
|
1301
|
+
}
|
|
1302
|
+
_getBindGroupCacheKeysWebGPU() {
|
|
1303
|
+
return this._bindGroupCacheKeysByGroup;
|
|
1074
1304
|
}
|
|
1075
1305
|
};
|
|
1076
1306
|
}
|
|
1077
1307
|
});
|
|
1078
1308
|
|
|
1079
1309
|
// dist/adapter/resources/webgpu-vertex-array.js
|
|
1080
|
-
var
|
|
1310
|
+
var import_core12, import_env, WebGPUVertexArray;
|
|
1081
1311
|
var init_webgpu_vertex_array = __esm({
|
|
1082
1312
|
"dist/adapter/resources/webgpu-vertex-array.js"() {
|
|
1083
1313
|
"use strict";
|
|
1084
|
-
|
|
1314
|
+
import_core12 = require("@luma.gl/core");
|
|
1085
1315
|
import_env = require("@probe.gl/env");
|
|
1086
|
-
WebGPUVertexArray = class extends
|
|
1316
|
+
WebGPUVertexArray = class extends import_core12.VertexArray {
|
|
1087
1317
|
get [Symbol.toStringTag]() {
|
|
1088
|
-
return "
|
|
1318
|
+
return "VertexArray";
|
|
1089
1319
|
}
|
|
1090
1320
|
device;
|
|
1091
1321
|
/** Vertex Array is just a helper class under WebGPU */
|
|
@@ -1112,7 +1342,7 @@ var init_webgpu_vertex_array = __esm({
|
|
|
1112
1342
|
const webgpuRenderPass = renderPass;
|
|
1113
1343
|
const webgpuIndexBuffer = this.indexBuffer;
|
|
1114
1344
|
if (webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.handle) {
|
|
1115
|
-
|
|
1345
|
+
import_core12.log.info(3, "setting index buffer", webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.handle, webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.indexType)();
|
|
1116
1346
|
webgpuRenderPass.handle.setIndexBuffer(
|
|
1117
1347
|
webgpuIndexBuffer == null ? void 0 : webgpuIndexBuffer.handle,
|
|
1118
1348
|
// @ts-expect-error TODO - we must enforce type
|
|
@@ -1122,7 +1352,7 @@ var init_webgpu_vertex_array = __esm({
|
|
|
1122
1352
|
for (let location = 0; location < this.maxVertexAttributes; location++) {
|
|
1123
1353
|
const webgpuBuffer = this.attributes[location];
|
|
1124
1354
|
if (webgpuBuffer == null ? void 0 : webgpuBuffer.handle) {
|
|
1125
|
-
|
|
1355
|
+
import_core12.log.info(3, `setting vertex buffer ${location}`, webgpuBuffer == null ? void 0 : webgpuBuffer.handle)();
|
|
1126
1356
|
webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer == null ? void 0 : webgpuBuffer.handle);
|
|
1127
1357
|
}
|
|
1128
1358
|
}
|
|
@@ -1142,16 +1372,19 @@ var init_webgpu_vertex_array = __esm({
|
|
|
1142
1372
|
});
|
|
1143
1373
|
|
|
1144
1374
|
// dist/adapter/webgpu-canvas-context.js
|
|
1145
|
-
var
|
|
1375
|
+
var import_core13, WebGPUCanvasContext;
|
|
1146
1376
|
var init_webgpu_canvas_context = __esm({
|
|
1147
1377
|
"dist/adapter/webgpu-canvas-context.js"() {
|
|
1148
1378
|
"use strict";
|
|
1149
|
-
|
|
1379
|
+
import_core13 = require("@luma.gl/core");
|
|
1150
1380
|
init_webgpu_framebuffer();
|
|
1151
|
-
|
|
1381
|
+
init_cpu_hotspot_profiler();
|
|
1382
|
+
WebGPUCanvasContext = class extends import_core13.CanvasContext {
|
|
1152
1383
|
device;
|
|
1153
1384
|
handle;
|
|
1385
|
+
colorAttachment = null;
|
|
1154
1386
|
depthStencilAttachment = null;
|
|
1387
|
+
framebuffer = null;
|
|
1155
1388
|
get [Symbol.toStringTag]() {
|
|
1156
1389
|
return "WebGPUCanvasContext";
|
|
1157
1390
|
}
|
|
@@ -1164,34 +1397,29 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1164
1397
|
this.device = device;
|
|
1165
1398
|
this.handle = context;
|
|
1166
1399
|
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
|
|
1167
|
-
this.
|
|
1400
|
+
this._configureDevice();
|
|
1401
|
+
this._startObservers();
|
|
1168
1402
|
}
|
|
1169
1403
|
/** Destroy any textures produced while configured and remove the context configuration. */
|
|
1170
1404
|
destroy() {
|
|
1405
|
+
if (this.framebuffer) {
|
|
1406
|
+
this.framebuffer.destroy();
|
|
1407
|
+
this.framebuffer = null;
|
|
1408
|
+
}
|
|
1409
|
+
if (this.colorAttachment) {
|
|
1410
|
+
this.colorAttachment.destroy();
|
|
1411
|
+
this.colorAttachment = null;
|
|
1412
|
+
}
|
|
1413
|
+
if (this.depthStencilAttachment) {
|
|
1414
|
+
this.depthStencilAttachment.destroy();
|
|
1415
|
+
this.depthStencilAttachment = null;
|
|
1416
|
+
}
|
|
1171
1417
|
this.handle.unconfigure();
|
|
1172
1418
|
super.destroy();
|
|
1173
1419
|
}
|
|
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
1420
|
// IMPLEMENTATION OF ABSTRACT METHODS
|
|
1194
|
-
|
|
1421
|
+
/** @see https://www.w3.org/TR/webgpu/#canvas-configuration */
|
|
1422
|
+
_configureDevice() {
|
|
1195
1423
|
if (this.depthStencilAttachment) {
|
|
1196
1424
|
this.depthStencilAttachment.destroy();
|
|
1197
1425
|
this.depthStencilAttachment = null;
|
|
@@ -1204,24 +1432,81 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1204
1432
|
colorSpace: this.props.colorSpace,
|
|
1205
1433
|
alphaMode: this.props.alphaMode
|
|
1206
1434
|
});
|
|
1435
|
+
this._createDepthStencilAttachment(this.device.preferredDepthFormat);
|
|
1436
|
+
}
|
|
1437
|
+
/** Update framebuffer with properly resized "swap chain" texture views */
|
|
1438
|
+
_getCurrentFramebuffer(options = {
|
|
1439
|
+
depthStencilFormat: "depth24plus"
|
|
1440
|
+
}) {
|
|
1441
|
+
var _a;
|
|
1442
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1443
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1444
|
+
if (profiler) {
|
|
1445
|
+
profiler.framebufferAcquireCount = (profiler.framebufferAcquireCount || 0) + 1;
|
|
1446
|
+
profiler.activeDefaultFramebufferAcquireDepth = (profiler.activeDefaultFramebufferAcquireDepth || 0) + 1;
|
|
1447
|
+
}
|
|
1448
|
+
try {
|
|
1449
|
+
const currentColorAttachment = this._getCurrentTexture();
|
|
1450
|
+
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
|
|
1451
|
+
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
1452
|
+
this.drawingBufferWidth = currentColorAttachment.width;
|
|
1453
|
+
this.drawingBufferHeight = currentColorAttachment.height;
|
|
1454
|
+
import_core13.log.log(1, `${this}: Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`)();
|
|
1455
|
+
}
|
|
1456
|
+
if (options == null ? void 0 : options.depthStencilFormat) {
|
|
1457
|
+
this._createDepthStencilAttachment(options == null ? void 0 : options.depthStencilFormat);
|
|
1458
|
+
}
|
|
1459
|
+
this.framebuffer ||= new WebGPUFramebuffer(this.device, {
|
|
1460
|
+
id: `${this.id}#framebuffer`,
|
|
1461
|
+
colorAttachments: [currentColorAttachment],
|
|
1462
|
+
depthStencilAttachment: null
|
|
1463
|
+
});
|
|
1464
|
+
this.framebuffer._reinitialize(currentColorAttachment.view, (options == null ? void 0 : options.depthStencilFormat) ? ((_a = this.depthStencilAttachment) == null ? void 0 : _a.view) || null : null);
|
|
1465
|
+
return this.framebuffer;
|
|
1466
|
+
} finally {
|
|
1467
|
+
if (profiler) {
|
|
1468
|
+
profiler.activeDefaultFramebufferAcquireDepth = (profiler.activeDefaultFramebufferAcquireDepth || 1) - 1;
|
|
1469
|
+
profiler.framebufferAcquireTimeMs = (profiler.framebufferAcquireTimeMs || 0) + (getTimestamp() - startTime);
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1207
1472
|
}
|
|
1473
|
+
// PRIMARY METHODS
|
|
1208
1474
|
/** Wrap the current canvas context texture in a luma.gl texture */
|
|
1209
|
-
|
|
1475
|
+
_getCurrentTexture() {
|
|
1476
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1477
|
+
const currentTextureStartTime = profiler ? getTimestamp() : 0;
|
|
1210
1478
|
const handle = this.handle.getCurrentTexture();
|
|
1211
|
-
|
|
1212
|
-
|
|
1479
|
+
if (profiler) {
|
|
1480
|
+
profiler.currentTextureAcquireCount = (profiler.currentTextureAcquireCount || 0) + 1;
|
|
1481
|
+
profiler.currentTextureAcquireTimeMs = (profiler.currentTextureAcquireTimeMs || 0) + (getTimestamp() - currentTextureStartTime);
|
|
1482
|
+
}
|
|
1483
|
+
if (!this.colorAttachment) {
|
|
1484
|
+
this.colorAttachment = this.device.createTexture({
|
|
1485
|
+
id: `${this.id}#color-texture`,
|
|
1486
|
+
handle,
|
|
1487
|
+
format: this.device.preferredColorFormat,
|
|
1488
|
+
width: handle.width,
|
|
1489
|
+
height: handle.height
|
|
1490
|
+
});
|
|
1491
|
+
return this.colorAttachment;
|
|
1492
|
+
}
|
|
1493
|
+
this.colorAttachment._reinitialize(handle, {
|
|
1213
1494
|
handle,
|
|
1214
1495
|
format: this.device.preferredColorFormat,
|
|
1215
1496
|
width: handle.width,
|
|
1216
1497
|
height: handle.height
|
|
1217
1498
|
});
|
|
1499
|
+
return this.colorAttachment;
|
|
1218
1500
|
}
|
|
1219
1501
|
/** We build render targets on demand (i.e. not when size changes but when about to render) */
|
|
1220
1502
|
_createDepthStencilAttachment(depthStencilFormat) {
|
|
1221
|
-
|
|
1503
|
+
var _a;
|
|
1504
|
+
const needsNewDepthStencilAttachment = !this.depthStencilAttachment || this.depthStencilAttachment.width !== this.drawingBufferWidth || this.depthStencilAttachment.height !== this.drawingBufferHeight || this.depthStencilAttachment.format !== depthStencilFormat;
|
|
1505
|
+
if (needsNewDepthStencilAttachment) {
|
|
1506
|
+
(_a = this.depthStencilAttachment) == null ? void 0 : _a.destroy();
|
|
1222
1507
|
this.depthStencilAttachment = this.device.createTexture({
|
|
1223
1508
|
id: `${this.id}#depth-stencil-texture`,
|
|
1224
|
-
usage:
|
|
1509
|
+
usage: import_core13.Texture.RENDER_ATTACHMENT,
|
|
1225
1510
|
format: depthStencilFormat,
|
|
1226
1511
|
width: this.drawingBufferWidth,
|
|
1227
1512
|
height: this.drawingBufferHeight
|
|
@@ -1233,76 +1518,246 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1233
1518
|
}
|
|
1234
1519
|
});
|
|
1235
1520
|
|
|
1236
|
-
// dist/adapter/
|
|
1237
|
-
var
|
|
1238
|
-
var
|
|
1239
|
-
"dist/adapter/
|
|
1521
|
+
// dist/adapter/webgpu-presentation-context.js
|
|
1522
|
+
var import_core14, WebGPUPresentationContext;
|
|
1523
|
+
var init_webgpu_presentation_context = __esm({
|
|
1524
|
+
"dist/adapter/webgpu-presentation-context.js"() {
|
|
1240
1525
|
"use strict";
|
|
1241
|
-
|
|
1242
|
-
|
|
1526
|
+
import_core14 = require("@luma.gl/core");
|
|
1527
|
+
init_webgpu_framebuffer();
|
|
1528
|
+
init_cpu_hotspot_profiler();
|
|
1529
|
+
WebGPUPresentationContext = class extends import_core14.PresentationContext {
|
|
1243
1530
|
device;
|
|
1244
1531
|
handle;
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
});
|
|
1532
|
+
colorAttachment = null;
|
|
1533
|
+
depthStencilAttachment = null;
|
|
1534
|
+
framebuffer = null;
|
|
1535
|
+
get [Symbol.toStringTag]() {
|
|
1536
|
+
return "WebGPUPresentationContext";
|
|
1251
1537
|
}
|
|
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
1538
|
constructor(device, props = {}) {
|
|
1271
|
-
super(
|
|
1272
|
-
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
if (webgpuQuerySet) {
|
|
1277
|
-
renderPassDescriptor.occlusionQuerySet = webgpuQuerySet.handle;
|
|
1278
|
-
}
|
|
1279
|
-
if (device.features.has("timestamp-query")) {
|
|
1280
|
-
const webgpuTSQuerySet = props.timestampQuerySet;
|
|
1281
|
-
renderPassDescriptor.timestampWrites = webgpuTSQuerySet ? {
|
|
1282
|
-
querySet: webgpuTSQuerySet.handle,
|
|
1283
|
-
beginningOfPassWriteIndex: props.beginTimestampIndex,
|
|
1284
|
-
endOfPassWriteIndex: props.endTimestampIndex
|
|
1285
|
-
} : void 0;
|
|
1286
|
-
}
|
|
1287
|
-
if (!device.commandEncoder) {
|
|
1288
|
-
throw new Error("commandEncoder not available");
|
|
1539
|
+
super(props);
|
|
1540
|
+
const contextLabel = `${this[Symbol.toStringTag]}(${this.id})`;
|
|
1541
|
+
const context = this.canvas.getContext("webgpu");
|
|
1542
|
+
if (!context) {
|
|
1543
|
+
throw new Error(`${contextLabel}: Failed to create WebGPU presentation context`);
|
|
1289
1544
|
}
|
|
1290
|
-
this.device
|
|
1291
|
-
this.handle =
|
|
1292
|
-
this.device.
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1545
|
+
this.device = device;
|
|
1546
|
+
this.handle = context;
|
|
1547
|
+
this._setAutoCreatedCanvasId(`${this.device.id}-presentation-canvas`);
|
|
1548
|
+
this._configureDevice();
|
|
1549
|
+
this._startObservers();
|
|
1550
|
+
}
|
|
1551
|
+
destroy() {
|
|
1552
|
+
if (this.framebuffer) {
|
|
1553
|
+
this.framebuffer.destroy();
|
|
1554
|
+
this.framebuffer = null;
|
|
1555
|
+
}
|
|
1556
|
+
if (this.colorAttachment) {
|
|
1557
|
+
this.colorAttachment.destroy();
|
|
1558
|
+
this.colorAttachment = null;
|
|
1559
|
+
}
|
|
1560
|
+
if (this.depthStencilAttachment) {
|
|
1561
|
+
this.depthStencilAttachment.destroy();
|
|
1562
|
+
this.depthStencilAttachment = null;
|
|
1563
|
+
}
|
|
1564
|
+
this.handle.unconfigure();
|
|
1565
|
+
super.destroy();
|
|
1566
|
+
}
|
|
1567
|
+
present() {
|
|
1568
|
+
this.device.submit();
|
|
1569
|
+
}
|
|
1570
|
+
_configureDevice() {
|
|
1571
|
+
if (this.depthStencilAttachment) {
|
|
1572
|
+
this.depthStencilAttachment.destroy();
|
|
1573
|
+
this.depthStencilAttachment = null;
|
|
1574
|
+
}
|
|
1575
|
+
this.handle.configure({
|
|
1576
|
+
device: this.device.handle,
|
|
1577
|
+
format: this.device.preferredColorFormat,
|
|
1578
|
+
colorSpace: this.props.colorSpace,
|
|
1579
|
+
alphaMode: this.props.alphaMode
|
|
1296
1580
|
});
|
|
1297
|
-
this.
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1581
|
+
this._createDepthStencilAttachment(this.device.preferredDepthFormat);
|
|
1582
|
+
}
|
|
1583
|
+
_getCurrentFramebuffer(options = {
|
|
1584
|
+
depthStencilFormat: "depth24plus"
|
|
1585
|
+
}) {
|
|
1586
|
+
var _a;
|
|
1587
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1588
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1589
|
+
if (profiler) {
|
|
1590
|
+
profiler.framebufferAcquireCount = (profiler.framebufferAcquireCount || 0) + 1;
|
|
1591
|
+
}
|
|
1592
|
+
try {
|
|
1593
|
+
const currentColorAttachment = this._getCurrentTexture();
|
|
1594
|
+
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
|
|
1595
|
+
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
1596
|
+
this.drawingBufferWidth = currentColorAttachment.width;
|
|
1597
|
+
this.drawingBufferHeight = currentColorAttachment.height;
|
|
1598
|
+
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`)();
|
|
1599
|
+
}
|
|
1600
|
+
if (options == null ? void 0 : options.depthStencilFormat) {
|
|
1601
|
+
this._createDepthStencilAttachment(options.depthStencilFormat);
|
|
1602
|
+
}
|
|
1603
|
+
this.framebuffer ||= new WebGPUFramebuffer(this.device, {
|
|
1604
|
+
id: `${this.id}#framebuffer`,
|
|
1605
|
+
colorAttachments: [currentColorAttachment],
|
|
1606
|
+
depthStencilAttachment: null
|
|
1607
|
+
});
|
|
1608
|
+
this.framebuffer._reinitialize(currentColorAttachment.view, (options == null ? void 0 : options.depthStencilFormat) ? ((_a = this.depthStencilAttachment) == null ? void 0 : _a.view) || null : null);
|
|
1609
|
+
return this.framebuffer;
|
|
1610
|
+
} finally {
|
|
1611
|
+
if (profiler) {
|
|
1612
|
+
profiler.framebufferAcquireTimeMs = (profiler.framebufferAcquireTimeMs || 0) + (getTimestamp() - startTime);
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
_getCurrentTexture() {
|
|
1617
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1618
|
+
const currentTextureStartTime = profiler ? getTimestamp() : 0;
|
|
1619
|
+
const handle = this.handle.getCurrentTexture();
|
|
1620
|
+
if (profiler) {
|
|
1621
|
+
profiler.currentTextureAcquireCount = (profiler.currentTextureAcquireCount || 0) + 1;
|
|
1622
|
+
profiler.currentTextureAcquireTimeMs = (profiler.currentTextureAcquireTimeMs || 0) + (getTimestamp() - currentTextureStartTime);
|
|
1623
|
+
}
|
|
1624
|
+
if (!this.colorAttachment) {
|
|
1625
|
+
this.colorAttachment = this.device.createTexture({
|
|
1626
|
+
id: `${this.id}#color-texture`,
|
|
1627
|
+
handle,
|
|
1628
|
+
format: this.device.preferredColorFormat,
|
|
1629
|
+
width: handle.width,
|
|
1630
|
+
height: handle.height
|
|
1631
|
+
});
|
|
1632
|
+
return this.colorAttachment;
|
|
1633
|
+
}
|
|
1634
|
+
this.colorAttachment._reinitialize(handle, {
|
|
1635
|
+
handle,
|
|
1636
|
+
format: this.device.preferredColorFormat,
|
|
1637
|
+
width: handle.width,
|
|
1638
|
+
height: handle.height
|
|
1639
|
+
});
|
|
1640
|
+
return this.colorAttachment;
|
|
1641
|
+
}
|
|
1642
|
+
_createDepthStencilAttachment(depthStencilFormat) {
|
|
1643
|
+
var _a;
|
|
1644
|
+
const needsNewDepthStencilAttachment = !this.depthStencilAttachment || this.depthStencilAttachment.width !== this.drawingBufferWidth || this.depthStencilAttachment.height !== this.drawingBufferHeight || this.depthStencilAttachment.format !== depthStencilFormat;
|
|
1645
|
+
if (needsNewDepthStencilAttachment) {
|
|
1646
|
+
(_a = this.depthStencilAttachment) == null ? void 0 : _a.destroy();
|
|
1647
|
+
this.depthStencilAttachment = this.device.createTexture({
|
|
1648
|
+
id: `${this.id}#depth-stencil-texture`,
|
|
1649
|
+
usage: import_core14.Texture.RENDER_ATTACHMENT,
|
|
1650
|
+
format: depthStencilFormat,
|
|
1651
|
+
width: this.drawingBufferWidth,
|
|
1652
|
+
height: this.drawingBufferHeight
|
|
1653
|
+
});
|
|
1654
|
+
}
|
|
1655
|
+
return this.depthStencilAttachment;
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
});
|
|
1660
|
+
|
|
1661
|
+
// dist/adapter/resources/webgpu-command-buffer.js
|
|
1662
|
+
var import_core15, WebGPUCommandBuffer;
|
|
1663
|
+
var init_webgpu_command_buffer = __esm({
|
|
1664
|
+
"dist/adapter/resources/webgpu-command-buffer.js"() {
|
|
1665
|
+
"use strict";
|
|
1666
|
+
import_core15 = require("@luma.gl/core");
|
|
1667
|
+
WebGPUCommandBuffer = class extends import_core15.CommandBuffer {
|
|
1668
|
+
device;
|
|
1669
|
+
handle;
|
|
1670
|
+
constructor(commandEncoder, props) {
|
|
1671
|
+
super(commandEncoder.device, props);
|
|
1672
|
+
this.device = commandEncoder.device;
|
|
1673
|
+
this.handle = this.props.handle || commandEncoder.handle.finish({
|
|
1674
|
+
label: (props == null ? void 0 : props.id) || "unnamed-command-buffer"
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
});
|
|
1680
|
+
|
|
1681
|
+
// dist/adapter/resources/webgpu-render-pass.js
|
|
1682
|
+
function convertColor(color) {
|
|
1683
|
+
return { r: color[0], g: color[1], b: color[2], a: color[3] };
|
|
1684
|
+
}
|
|
1685
|
+
var import_core16, WebGPURenderPass;
|
|
1686
|
+
var init_webgpu_render_pass = __esm({
|
|
1687
|
+
"dist/adapter/resources/webgpu-render-pass.js"() {
|
|
1688
|
+
"use strict";
|
|
1689
|
+
import_core16 = require("@luma.gl/core");
|
|
1690
|
+
init_cpu_hotspot_profiler();
|
|
1691
|
+
WebGPURenderPass = class extends import_core16.RenderPass {
|
|
1692
|
+
device;
|
|
1693
|
+
handle;
|
|
1694
|
+
framebuffer;
|
|
1695
|
+
/** Active pipeline */
|
|
1696
|
+
pipeline = null;
|
|
1697
|
+
/** Latest bindings applied to this pass */
|
|
1698
|
+
bindings = {};
|
|
1699
|
+
constructor(device, props = {}, commandEncoder = device.commandEncoder.handle) {
|
|
1700
|
+
super(device, props);
|
|
1701
|
+
this.device = device;
|
|
1702
|
+
const { props: renderPassProps } = this;
|
|
1703
|
+
this.framebuffer = renderPassProps.framebuffer || device.getCanvasContext().getCurrentFramebuffer();
|
|
1704
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
1705
|
+
if (profiler) {
|
|
1706
|
+
const counterName = renderPassProps.framebuffer ? "explicitFramebufferRenderPassCount" : "defaultFramebufferRenderPassCount";
|
|
1707
|
+
profiler[counterName] = (profiler[counterName] || 0) + 1;
|
|
1708
|
+
}
|
|
1709
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1710
|
+
try {
|
|
1711
|
+
const descriptorAssemblyStartTime = profiler ? getTimestamp() : 0;
|
|
1712
|
+
const renderPassDescriptor = this.getRenderPassDescriptor(this.framebuffer);
|
|
1713
|
+
if (renderPassProps.occlusionQuerySet) {
|
|
1714
|
+
renderPassDescriptor.occlusionQuerySet = renderPassProps.occlusionQuerySet.handle;
|
|
1715
|
+
}
|
|
1716
|
+
if (renderPassProps.timestampQuerySet) {
|
|
1717
|
+
const webgpuTSQuerySet = renderPassProps.timestampQuerySet;
|
|
1718
|
+
webgpuTSQuerySet == null ? void 0 : webgpuTSQuerySet._invalidateResults();
|
|
1719
|
+
renderPassDescriptor.timestampWrites = webgpuTSQuerySet ? {
|
|
1720
|
+
querySet: webgpuTSQuerySet.handle,
|
|
1721
|
+
beginningOfPassWriteIndex: renderPassProps.beginTimestampIndex,
|
|
1722
|
+
endOfPassWriteIndex: renderPassProps.endTimestampIndex
|
|
1723
|
+
} : void 0;
|
|
1724
|
+
}
|
|
1725
|
+
if (profiler) {
|
|
1726
|
+
profiler.renderPassDescriptorAssemblyCount = (profiler.renderPassDescriptorAssemblyCount || 0) + 1;
|
|
1727
|
+
profiler.renderPassDescriptorAssemblyTimeMs = (profiler.renderPassDescriptorAssemblyTimeMs || 0) + (getTimestamp() - descriptorAssemblyStartTime);
|
|
1728
|
+
}
|
|
1729
|
+
this.device.pushErrorScope("validation");
|
|
1730
|
+
const beginRenderPassStartTime = profiler ? getTimestamp() : 0;
|
|
1731
|
+
this.handle = this.props.handle || commandEncoder.beginRenderPass(renderPassDescriptor);
|
|
1732
|
+
if (profiler) {
|
|
1733
|
+
profiler.renderPassBeginCount = (profiler.renderPassBeginCount || 0) + 1;
|
|
1734
|
+
profiler.renderPassBeginTimeMs = (profiler.renderPassBeginTimeMs || 0) + (getTimestamp() - beginRenderPassStartTime);
|
|
1735
|
+
}
|
|
1736
|
+
this.device.popErrorScope((error) => {
|
|
1737
|
+
this.device.reportError(new Error(`${this} creation failed:
|
|
1738
|
+
"${error.message}"`), this)();
|
|
1739
|
+
this.device.debug();
|
|
1740
|
+
});
|
|
1741
|
+
this.handle.label = this.props.id;
|
|
1742
|
+
import_core16.log.groupCollapsed(3, `new WebGPURenderPass(${this.id})`)();
|
|
1743
|
+
import_core16.log.probe(3, JSON.stringify(renderPassDescriptor, null, 2))();
|
|
1744
|
+
import_core16.log.groupEnd(3)();
|
|
1745
|
+
} finally {
|
|
1746
|
+
if (profiler) {
|
|
1747
|
+
profiler.renderPassSetupCount = (profiler.renderPassSetupCount || 0) + 1;
|
|
1748
|
+
profiler.renderPassSetupTimeMs = (profiler.renderPassSetupTimeMs || 0) + (getTimestamp() - startTime);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1301
1751
|
}
|
|
1302
1752
|
destroy() {
|
|
1753
|
+
this.destroyResource();
|
|
1303
1754
|
}
|
|
1304
1755
|
end() {
|
|
1756
|
+
if (this.destroyed) {
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1305
1759
|
this.handle.end();
|
|
1760
|
+
this.destroy();
|
|
1306
1761
|
}
|
|
1307
1762
|
setPipeline(pipeline) {
|
|
1308
1763
|
this.pipeline = pipeline;
|
|
@@ -1316,11 +1771,12 @@ var init_webgpu_render_pass = __esm({
|
|
|
1316
1771
|
}
|
|
1317
1772
|
/** Sets an array of bindings (uniform buffers, samplers, textures, ...) */
|
|
1318
1773
|
setBindings(bindings) {
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1774
|
+
this.bindings = bindings;
|
|
1775
|
+
const bindGroups = this.pipeline && (0, import_core16._getDefaultBindGroupFactory)(this.device).getBindGroups(this.pipeline, bindings) || {};
|
|
1776
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1777
|
+
if (bindGroup) {
|
|
1778
|
+
this.handle.setBindGroup(Number(group), bindGroup);
|
|
1779
|
+
}
|
|
1324
1780
|
}
|
|
1325
1781
|
}
|
|
1326
1782
|
setIndexBuffer(buffer, indexFormat, offset = 0, size) {
|
|
@@ -1427,44 +1883,60 @@ var init_webgpu_compute_pass = __esm({
|
|
|
1427
1883
|
device;
|
|
1428
1884
|
handle;
|
|
1429
1885
|
_webgpuPipeline = null;
|
|
1430
|
-
constructor(device, props) {
|
|
1886
|
+
constructor(device, props = {}, commandEncoder = device.commandEncoder.handle) {
|
|
1431
1887
|
super(device, props);
|
|
1432
1888
|
this.device = device;
|
|
1889
|
+
const { props: computePassProps } = this;
|
|
1433
1890
|
let timestampWrites;
|
|
1434
|
-
if (
|
|
1435
|
-
const webgpuQuerySet =
|
|
1891
|
+
if (computePassProps.timestampQuerySet) {
|
|
1892
|
+
const webgpuQuerySet = computePassProps.timestampQuerySet;
|
|
1436
1893
|
if (webgpuQuerySet) {
|
|
1894
|
+
webgpuQuerySet._invalidateResults();
|
|
1437
1895
|
timestampWrites = {
|
|
1438
1896
|
querySet: webgpuQuerySet.handle,
|
|
1439
|
-
beginningOfPassWriteIndex:
|
|
1440
|
-
endOfPassWriteIndex:
|
|
1897
|
+
beginningOfPassWriteIndex: computePassProps.beginTimestampIndex,
|
|
1898
|
+
endOfPassWriteIndex: computePassProps.endTimestampIndex
|
|
1441
1899
|
};
|
|
1442
1900
|
}
|
|
1443
1901
|
}
|
|
1444
|
-
this.handle = this.props.handle ||
|
|
1902
|
+
this.handle = this.props.handle || commandEncoder.beginComputePass({
|
|
1445
1903
|
label: this.props.id,
|
|
1446
1904
|
timestampWrites
|
|
1447
1905
|
});
|
|
1448
1906
|
}
|
|
1449
1907
|
/** @note no WebGPU destroy method, just gc */
|
|
1450
1908
|
destroy() {
|
|
1909
|
+
this.destroyResource();
|
|
1451
1910
|
}
|
|
1452
1911
|
end() {
|
|
1912
|
+
if (this.destroyed) {
|
|
1913
|
+
return;
|
|
1914
|
+
}
|
|
1453
1915
|
this.handle.end();
|
|
1916
|
+
this.destroy();
|
|
1454
1917
|
}
|
|
1455
1918
|
setPipeline(pipeline) {
|
|
1456
1919
|
const wgpuPipeline = pipeline;
|
|
1457
1920
|
this.handle.setPipeline(wgpuPipeline.handle);
|
|
1458
1921
|
this._webgpuPipeline = wgpuPipeline;
|
|
1459
|
-
this.
|
|
1922
|
+
const bindGroups = (0, import_core17._getDefaultBindGroupFactory)(this.device).getBindGroups(this._webgpuPipeline, this._webgpuPipeline._getBindingsByGroupWebGPU(), this._webgpuPipeline._getBindGroupCacheKeysWebGPU());
|
|
1923
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1924
|
+
if (bindGroup) {
|
|
1925
|
+
this.handle.setBindGroup(Number(group), bindGroup);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1460
1928
|
}
|
|
1461
1929
|
/**
|
|
1462
1930
|
* Sets an array of bindings (uniform buffers, samplers, textures, ...)
|
|
1463
1931
|
* TODO - still some API confusion - does this method go here or on the pipeline?
|
|
1464
1932
|
*/
|
|
1465
1933
|
setBindings(bindings) {
|
|
1466
|
-
const
|
|
1467
|
-
|
|
1934
|
+
const bindGroups = this._webgpuPipeline && (0, import_core17._getDefaultBindGroupFactory)(this.device).getBindGroups(this._webgpuPipeline, bindings) || {};
|
|
1935
|
+
for (const [group, bindGroup] of Object.entries(bindGroups)) {
|
|
1936
|
+
if (bindGroup) {
|
|
1937
|
+
this.handle.setBindGroup(Number(group), bindGroup);
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1468
1940
|
}
|
|
1469
1941
|
/**
|
|
1470
1942
|
* Dispatch work to be performed with the current ComputePipeline.
|
|
@@ -1522,6 +1994,7 @@ var init_webgpu_command_encoder = __esm({
|
|
|
1522
1994
|
this.handle.label = this.props.id;
|
|
1523
1995
|
}
|
|
1524
1996
|
destroy() {
|
|
1997
|
+
this.destroyResource();
|
|
1525
1998
|
}
|
|
1526
1999
|
finish(props) {
|
|
1527
2000
|
this.device.pushErrorScope("validation");
|
|
@@ -1533,49 +2006,105 @@ var init_webgpu_command_encoder = __esm({
|
|
|
1533
2006
|
this.device.reportError(new Error(message), this)();
|
|
1534
2007
|
this.device.debug();
|
|
1535
2008
|
});
|
|
2009
|
+
this.destroy();
|
|
1536
2010
|
return commandBuffer;
|
|
1537
2011
|
}
|
|
1538
2012
|
/**
|
|
1539
2013
|
* Allows a render pass to begin against a canvas context
|
|
1540
2014
|
* @todo need to support a "Framebuffer" equivalent (aka preconfigured RenderPassDescriptors?).
|
|
1541
2015
|
*/
|
|
1542
|
-
beginRenderPass(props) {
|
|
1543
|
-
return new WebGPURenderPass(this.device, props);
|
|
2016
|
+
beginRenderPass(props = {}) {
|
|
2017
|
+
return new WebGPURenderPass(this.device, this._applyTimeProfilingToPassProps(props), this.handle);
|
|
1544
2018
|
}
|
|
1545
|
-
beginComputePass(props) {
|
|
1546
|
-
return new WebGPUComputePass(this.device, props);
|
|
2019
|
+
beginComputePass(props = {}) {
|
|
2020
|
+
return new WebGPUComputePass(this.device, this._applyTimeProfilingToPassProps(props), this.handle);
|
|
1547
2021
|
}
|
|
1548
2022
|
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
1549
2023
|
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
1550
2024
|
copyBufferToBuffer(options) {
|
|
1551
2025
|
const webgpuSourceBuffer = options.sourceBuffer;
|
|
1552
|
-
const
|
|
1553
|
-
this.handle.copyBufferToBuffer(webgpuSourceBuffer.handle, options.sourceOffset ?? 0,
|
|
2026
|
+
const webgpuDestinationBuffer = options.destinationBuffer;
|
|
2027
|
+
this.handle.copyBufferToBuffer(webgpuSourceBuffer.handle, options.sourceOffset ?? 0, webgpuDestinationBuffer.handle, options.destinationOffset ?? 0, options.size ?? 0);
|
|
1554
2028
|
}
|
|
1555
2029
|
copyBufferToTexture(options) {
|
|
1556
|
-
var _a, _b, _c;
|
|
1557
2030
|
const webgpuSourceBuffer = options.sourceBuffer;
|
|
1558
|
-
const
|
|
2031
|
+
const webgpuDestinationTexture = options.destinationTexture;
|
|
2032
|
+
const copyOrigin = options.origin ?? [0, 0, 0];
|
|
2033
|
+
const copySize = options.size;
|
|
1559
2034
|
this.handle.copyBufferToTexture({
|
|
1560
2035
|
buffer: webgpuSourceBuffer.handle,
|
|
1561
|
-
offset: options.
|
|
2036
|
+
offset: options.byteOffset ?? 0,
|
|
1562
2037
|
bytesPerRow: options.bytesPerRow,
|
|
1563
2038
|
rowsPerImage: options.rowsPerImage
|
|
1564
2039
|
}, {
|
|
1565
|
-
texture:
|
|
2040
|
+
texture: webgpuDestinationTexture.handle,
|
|
1566
2041
|
mipLevel: options.mipLevel ?? 0,
|
|
1567
|
-
origin:
|
|
1568
|
-
|
|
2042
|
+
origin: {
|
|
2043
|
+
x: copyOrigin[0] ?? 0,
|
|
2044
|
+
y: copyOrigin[1] ?? 0,
|
|
2045
|
+
z: copyOrigin[2] ?? 0
|
|
2046
|
+
},
|
|
2047
|
+
aspect: options.aspect
|
|
1569
2048
|
}, {
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
depthOrArrayLayers: (_c = options.extent) == null ? void 0 : _c[2]
|
|
2049
|
+
width: copySize[0],
|
|
2050
|
+
height: copySize[1],
|
|
2051
|
+
depthOrArrayLayers: copySize[2]
|
|
1574
2052
|
});
|
|
1575
2053
|
}
|
|
1576
2054
|
copyTextureToBuffer(options) {
|
|
2055
|
+
const { sourceTexture, destinationBuffer, origin = [0, 0, 0], byteOffset = 0, width, height, depthOrArrayLayers, mipLevel, aspect } = options;
|
|
2056
|
+
const webgpuSourceTexture = sourceTexture;
|
|
2057
|
+
webgpuSourceTexture.copyToBuffer(this.handle, {
|
|
2058
|
+
x: origin[0] ?? 0,
|
|
2059
|
+
y: origin[1] ?? 0,
|
|
2060
|
+
z: origin[2] ?? 0,
|
|
2061
|
+
width,
|
|
2062
|
+
height,
|
|
2063
|
+
depthOrArrayLayers,
|
|
2064
|
+
mipLevel,
|
|
2065
|
+
aspect,
|
|
2066
|
+
byteOffset,
|
|
2067
|
+
bytesPerRow: options.bytesPerRow,
|
|
2068
|
+
rowsPerImage: options.rowsPerImage
|
|
2069
|
+
}, destinationBuffer);
|
|
1577
2070
|
}
|
|
1578
2071
|
copyTextureToTexture(options) {
|
|
2072
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2073
|
+
const webgpuSourceTexture = options.sourceTexture;
|
|
2074
|
+
const webgpuDestinationTexture = options.destinationTexture;
|
|
2075
|
+
const sourceRegion = webgpuSourceTexture._normalizeTextureReadOptions({
|
|
2076
|
+
x: ((_a = options.origin) == null ? void 0 : _a[0]) ?? 0,
|
|
2077
|
+
y: ((_b = options.origin) == null ? void 0 : _b[1]) ?? 0,
|
|
2078
|
+
z: ((_c = options.origin) == null ? void 0 : _c[2]) ?? 0,
|
|
2079
|
+
width: options.width,
|
|
2080
|
+
height: options.height,
|
|
2081
|
+
depthOrArrayLayers: options.depthOrArrayLayers,
|
|
2082
|
+
mipLevel: options.mipLevel ?? 0,
|
|
2083
|
+
aspect: options.aspect ?? "all"
|
|
2084
|
+
});
|
|
2085
|
+
this.handle.copyTextureToTexture({
|
|
2086
|
+
texture: webgpuSourceTexture.handle,
|
|
2087
|
+
mipLevel: sourceRegion.mipLevel,
|
|
2088
|
+
origin: {
|
|
2089
|
+
x: sourceRegion.x,
|
|
2090
|
+
y: sourceRegion.y,
|
|
2091
|
+
z: sourceRegion.z
|
|
2092
|
+
},
|
|
2093
|
+
aspect: sourceRegion.aspect
|
|
2094
|
+
}, {
|
|
2095
|
+
texture: webgpuDestinationTexture.handle,
|
|
2096
|
+
mipLevel: options.destinationMipLevel ?? 0,
|
|
2097
|
+
origin: {
|
|
2098
|
+
x: ((_d = options.destinationOrigin) == null ? void 0 : _d[0]) ?? 0,
|
|
2099
|
+
y: ((_e = options.destinationOrigin) == null ? void 0 : _e[1]) ?? 0,
|
|
2100
|
+
z: ((_f = options.destinationOrigin) == null ? void 0 : _f[2]) ?? 0
|
|
2101
|
+
},
|
|
2102
|
+
aspect: options.destinationAspect ?? sourceRegion.aspect
|
|
2103
|
+
}, {
|
|
2104
|
+
width: sourceRegion.width,
|
|
2105
|
+
height: sourceRegion.height,
|
|
2106
|
+
depthOrArrayLayers: sourceRegion.depthOrArrayLayers
|
|
2107
|
+
});
|
|
1579
2108
|
}
|
|
1580
2109
|
pushDebugGroup(groupLabel) {
|
|
1581
2110
|
this.handle.pushDebugGroup(groupLabel);
|
|
@@ -1591,6 +2120,21 @@ var init_webgpu_command_encoder = __esm({
|
|
|
1591
2120
|
const webgpuBuffer = destination;
|
|
1592
2121
|
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
2122
|
}
|
|
2123
|
+
writeTimestamp(querySet, queryIndex) {
|
|
2124
|
+
querySet._invalidateResults();
|
|
2125
|
+
const writeTimestamp = this.handle.writeTimestamp;
|
|
2126
|
+
if (writeTimestamp) {
|
|
2127
|
+
writeTimestamp.call(this.handle, querySet.handle, queryIndex);
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
const computePass = this.handle.beginComputePass({
|
|
2131
|
+
timestampWrites: {
|
|
2132
|
+
querySet: querySet.handle,
|
|
2133
|
+
beginningOfPassWriteIndex: queryIndex
|
|
2134
|
+
}
|
|
2135
|
+
});
|
|
2136
|
+
computePass.end();
|
|
2137
|
+
}
|
|
1594
2138
|
};
|
|
1595
2139
|
}
|
|
1596
2140
|
});
|
|
@@ -1601,9 +2145,15 @@ var init_webgpu_query_set = __esm({
|
|
|
1601
2145
|
"dist/adapter/resources/webgpu-query-set.js"() {
|
|
1602
2146
|
"use strict";
|
|
1603
2147
|
import_core19 = require("@luma.gl/core");
|
|
2148
|
+
init_cpu_hotspot_profiler();
|
|
1604
2149
|
WebGPUQuerySet = class extends import_core19.QuerySet {
|
|
1605
2150
|
device;
|
|
1606
2151
|
handle;
|
|
2152
|
+
_resolveBuffer = null;
|
|
2153
|
+
_readBuffer = null;
|
|
2154
|
+
_cachedResults = null;
|
|
2155
|
+
_readResultsPromise = null;
|
|
2156
|
+
_resultsPendingResolution = false;
|
|
1607
2157
|
constructor(device, props) {
|
|
1608
2158
|
super(device, props);
|
|
1609
2159
|
this.device = device;
|
|
@@ -1615,8 +2165,133 @@ var init_webgpu_query_set = __esm({
|
|
|
1615
2165
|
}
|
|
1616
2166
|
destroy() {
|
|
1617
2167
|
var _a;
|
|
1618
|
-
(
|
|
1619
|
-
|
|
2168
|
+
if (!this.destroyed) {
|
|
2169
|
+
(_a = this.handle) == null ? void 0 : _a.destroy();
|
|
2170
|
+
this.destroyResource();
|
|
2171
|
+
this.handle = null;
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
isResultAvailable(queryIndex) {
|
|
2175
|
+
if (!this._cachedResults) {
|
|
2176
|
+
return false;
|
|
2177
|
+
}
|
|
2178
|
+
return queryIndex === void 0 ? true : queryIndex >= 0 && queryIndex < this._cachedResults.length;
|
|
2179
|
+
}
|
|
2180
|
+
async readResults(options) {
|
|
2181
|
+
const firstQuery = (options == null ? void 0 : options.firstQuery) || 0;
|
|
2182
|
+
const queryCount = (options == null ? void 0 : options.queryCount) || this.props.count - firstQuery;
|
|
2183
|
+
if (firstQuery < 0 || queryCount < 0 || firstQuery + queryCount > this.props.count) {
|
|
2184
|
+
throw new Error("Query read range is out of bounds");
|
|
2185
|
+
}
|
|
2186
|
+
let needsFreshResults = true;
|
|
2187
|
+
while (needsFreshResults) {
|
|
2188
|
+
if (!this._readResultsPromise) {
|
|
2189
|
+
this._readResultsPromise = this._readAllResults();
|
|
2190
|
+
}
|
|
2191
|
+
const readResultsPromise = this._readResultsPromise;
|
|
2192
|
+
const results = await readResultsPromise;
|
|
2193
|
+
needsFreshResults = this._resultsPendingResolution;
|
|
2194
|
+
if (!needsFreshResults) {
|
|
2195
|
+
return results.slice(firstQuery, firstQuery + queryCount);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
throw new Error("Query read unexpectedly failed to resolve");
|
|
2199
|
+
}
|
|
2200
|
+
async readTimestampDuration(beginIndex, endIndex) {
|
|
2201
|
+
if (this.props.type !== "timestamp") {
|
|
2202
|
+
throw new Error("Timestamp durations require a timestamp QuerySet");
|
|
2203
|
+
}
|
|
2204
|
+
if (beginIndex < 0 || endIndex <= beginIndex || endIndex >= this.props.count) {
|
|
2205
|
+
throw new Error("Timestamp duration range is out of bounds");
|
|
2206
|
+
}
|
|
2207
|
+
const results = await this.readResults({
|
|
2208
|
+
firstQuery: beginIndex,
|
|
2209
|
+
queryCount: endIndex - beginIndex + 1
|
|
2210
|
+
});
|
|
2211
|
+
return Number(results[results.length - 1] - results[0]) / 1e6;
|
|
2212
|
+
}
|
|
2213
|
+
/** Marks any cached query results as stale after new writes have been encoded. */
|
|
2214
|
+
_invalidateResults() {
|
|
2215
|
+
this._cachedResults = null;
|
|
2216
|
+
this._resultsPendingResolution = true;
|
|
2217
|
+
}
|
|
2218
|
+
async _readAllResults() {
|
|
2219
|
+
this._ensureBuffers();
|
|
2220
|
+
try {
|
|
2221
|
+
if (this._resultsPendingResolution) {
|
|
2222
|
+
const commandEncoder = this.device.createCommandEncoder({
|
|
2223
|
+
id: `${this.id}-read-results`
|
|
2224
|
+
});
|
|
2225
|
+
commandEncoder.resolveQuerySet(this, this._resolveBuffer);
|
|
2226
|
+
commandEncoder.copyBufferToBuffer({
|
|
2227
|
+
sourceBuffer: this._resolveBuffer,
|
|
2228
|
+
destinationBuffer: this._readBuffer,
|
|
2229
|
+
size: this._resolveBuffer.byteLength
|
|
2230
|
+
});
|
|
2231
|
+
const commandBuffer = commandEncoder.finish({
|
|
2232
|
+
id: `${this.id}-read-results-command-buffer`
|
|
2233
|
+
});
|
|
2234
|
+
const previousSubmitReason = getCpuHotspotSubmitReason(this.device) || void 0;
|
|
2235
|
+
setCpuHotspotSubmitReason(this.device, "query-readback");
|
|
2236
|
+
try {
|
|
2237
|
+
this.device.submit(commandBuffer);
|
|
2238
|
+
} finally {
|
|
2239
|
+
setCpuHotspotSubmitReason(this.device, previousSubmitReason);
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
const data = await this._readBuffer.readAsync(0, this._readBuffer.byteLength);
|
|
2243
|
+
const resultView = new BigUint64Array(data.buffer, data.byteOffset, this.props.count);
|
|
2244
|
+
this._cachedResults = Array.from(resultView, (value) => value);
|
|
2245
|
+
this._resultsPendingResolution = false;
|
|
2246
|
+
return this._cachedResults;
|
|
2247
|
+
} finally {
|
|
2248
|
+
this._readResultsPromise = null;
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
_ensureBuffers() {
|
|
2252
|
+
if (this._resolveBuffer && this._readBuffer) {
|
|
2253
|
+
return;
|
|
2254
|
+
}
|
|
2255
|
+
const byteLength = this.props.count * 8;
|
|
2256
|
+
this._resolveBuffer = this.device.createBuffer({
|
|
2257
|
+
id: `${this.id}-resolve-buffer`,
|
|
2258
|
+
usage: import_core19.Buffer.QUERY_RESOLVE | import_core19.Buffer.COPY_SRC,
|
|
2259
|
+
byteLength
|
|
2260
|
+
});
|
|
2261
|
+
this.attachResource(this._resolveBuffer);
|
|
2262
|
+
this._readBuffer = this.device.createBuffer({
|
|
2263
|
+
id: `${this.id}-read-buffer`,
|
|
2264
|
+
usage: import_core19.Buffer.COPY_DST | import_core19.Buffer.MAP_READ,
|
|
2265
|
+
byteLength
|
|
2266
|
+
});
|
|
2267
|
+
this.attachResource(this._readBuffer);
|
|
2268
|
+
}
|
|
2269
|
+
_encodeResolveToReadBuffer(commandEncoder, options) {
|
|
2270
|
+
if (!this._resultsPendingResolution) {
|
|
2271
|
+
return false;
|
|
2272
|
+
}
|
|
2273
|
+
if (this._readResultsPromise) {
|
|
2274
|
+
return false;
|
|
2275
|
+
}
|
|
2276
|
+
this._ensureBuffers();
|
|
2277
|
+
const firstQuery = (options == null ? void 0 : options.firstQuery) || 0;
|
|
2278
|
+
const queryCount = (options == null ? void 0 : options.queryCount) || this.props.count - firstQuery;
|
|
2279
|
+
const byteLength = queryCount * BigUint64Array.BYTES_PER_ELEMENT;
|
|
2280
|
+
const byteOffset = firstQuery * BigUint64Array.BYTES_PER_ELEMENT;
|
|
2281
|
+
commandEncoder.resolveQuerySet(this, this._resolveBuffer, {
|
|
2282
|
+
firstQuery,
|
|
2283
|
+
queryCount,
|
|
2284
|
+
destinationOffset: byteOffset
|
|
2285
|
+
});
|
|
2286
|
+
commandEncoder.copyBufferToBuffer({
|
|
2287
|
+
sourceBuffer: this._resolveBuffer,
|
|
2288
|
+
sourceOffset: byteOffset,
|
|
2289
|
+
destinationBuffer: this._readBuffer,
|
|
2290
|
+
destinationOffset: byteOffset,
|
|
2291
|
+
size: byteLength
|
|
2292
|
+
});
|
|
2293
|
+
this._resultsPendingResolution = false;
|
|
2294
|
+
return true;
|
|
1620
2295
|
}
|
|
1621
2296
|
};
|
|
1622
2297
|
}
|
|
@@ -1634,27 +2309,22 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1634
2309
|
constructor(device, props) {
|
|
1635
2310
|
super(device, props);
|
|
1636
2311
|
this.device = device;
|
|
1637
|
-
const
|
|
2312
|
+
const bindGroupEntriesByGroup = this.mapShaderLayoutToBindGroupEntriesByGroup();
|
|
1638
2313
|
this.handle = this.device.handle.createPipelineLayout({
|
|
1639
2314
|
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
|
-
]
|
|
2315
|
+
bindGroupLayouts: bindGroupEntriesByGroup.map((entries, group) => this.device.handle.createBindGroupLayout({
|
|
2316
|
+
label: `bind-group-layout-${group}`,
|
|
2317
|
+
entries
|
|
2318
|
+
}))
|
|
1649
2319
|
});
|
|
1650
2320
|
}
|
|
1651
2321
|
destroy() {
|
|
1652
2322
|
this.handle = null;
|
|
1653
2323
|
}
|
|
1654
|
-
|
|
1655
|
-
const
|
|
1656
|
-
|
|
1657
|
-
|
|
2324
|
+
mapShaderLayoutToBindGroupEntriesByGroup() {
|
|
2325
|
+
const maxGroup = this.props.shaderLayout.bindings.reduce((highestGroup, binding) => Math.max(highestGroup, binding.group), -1);
|
|
2326
|
+
const bindGroupEntriesByGroup = Array.from({ length: maxGroup + 1 }, () => []);
|
|
2327
|
+
for (const binding of this.props.shaderLayout.bindings) {
|
|
1658
2328
|
const bindingTypeInfo = {};
|
|
1659
2329
|
switch (binding.type) {
|
|
1660
2330
|
case "uniform": {
|
|
@@ -1710,13 +2380,13 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1710
2380
|
}
|
|
1711
2381
|
}
|
|
1712
2382
|
const VISIBILITY_ALL = GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE;
|
|
1713
|
-
|
|
2383
|
+
bindGroupEntriesByGroup[binding.group].push({
|
|
1714
2384
|
binding: binding.location,
|
|
1715
2385
|
visibility: binding.visibility || VISIBILITY_ALL,
|
|
1716
2386
|
...bindingTypeInfo
|
|
1717
2387
|
});
|
|
1718
2388
|
}
|
|
1719
|
-
return
|
|
2389
|
+
return bindGroupEntriesByGroup;
|
|
1720
2390
|
}
|
|
1721
2391
|
};
|
|
1722
2392
|
isStorageTextureBindingLayout = (maybe) => {
|
|
@@ -1725,16 +2395,734 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1725
2395
|
}
|
|
1726
2396
|
});
|
|
1727
2397
|
|
|
2398
|
+
// dist/adapter/resources/webgpu-fence.js
|
|
2399
|
+
var import_core21, WebGPUFence;
|
|
2400
|
+
var init_webgpu_fence = __esm({
|
|
2401
|
+
"dist/adapter/resources/webgpu-fence.js"() {
|
|
2402
|
+
"use strict";
|
|
2403
|
+
import_core21 = require("@luma.gl/core");
|
|
2404
|
+
WebGPUFence = class extends import_core21.Fence {
|
|
2405
|
+
device;
|
|
2406
|
+
handle = null;
|
|
2407
|
+
signaled;
|
|
2408
|
+
_signaled = false;
|
|
2409
|
+
constructor(device, props = {}) {
|
|
2410
|
+
super(device, {});
|
|
2411
|
+
this.device = device;
|
|
2412
|
+
this.signaled = device.handle.queue.onSubmittedWorkDone().then(() => {
|
|
2413
|
+
this._signaled = true;
|
|
2414
|
+
}).catch((error) => {
|
|
2415
|
+
if (this.device.shouldIgnoreDroppedInstanceError(error)) {
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2418
|
+
throw error;
|
|
2419
|
+
});
|
|
2420
|
+
}
|
|
2421
|
+
isSignaled() {
|
|
2422
|
+
return this._signaled;
|
|
2423
|
+
}
|
|
2424
|
+
destroy() {
|
|
2425
|
+
}
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2428
|
+
});
|
|
2429
|
+
|
|
2430
|
+
// dist/wgsl/get-shader-layout-wgsl.js
|
|
2431
|
+
function getShaderLayoutFromWGSL(source) {
|
|
2432
|
+
var _a;
|
|
2433
|
+
const shaderLayout = { attributes: [], bindings: [] };
|
|
2434
|
+
let parsedWGSL;
|
|
2435
|
+
try {
|
|
2436
|
+
parsedWGSL = parseWGSL(source);
|
|
2437
|
+
} catch (error) {
|
|
2438
|
+
import_core22.log.error(error.message)();
|
|
2439
|
+
return shaderLayout;
|
|
2440
|
+
}
|
|
2441
|
+
for (const uniform of parsedWGSL.uniforms) {
|
|
2442
|
+
const members = [];
|
|
2443
|
+
for (const attribute of ((_a = uniform.type) == null ? void 0 : _a.members) || []) {
|
|
2444
|
+
members.push({
|
|
2445
|
+
name: attribute.name,
|
|
2446
|
+
type: getType(attribute.type)
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
shaderLayout.bindings.push({
|
|
2450
|
+
type: "uniform",
|
|
2451
|
+
name: uniform.name,
|
|
2452
|
+
group: uniform.group,
|
|
2453
|
+
location: uniform.binding,
|
|
2454
|
+
// @ts-expect-error TODO - unused for now but needs fixing
|
|
2455
|
+
members
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
for (const storageBuffer of parsedWGSL.storage) {
|
|
2459
|
+
shaderLayout.bindings.push({
|
|
2460
|
+
type: storageBuffer.access === "read" ? "read-only-storage" : "storage",
|
|
2461
|
+
name: storageBuffer.name,
|
|
2462
|
+
group: storageBuffer.group,
|
|
2463
|
+
location: storageBuffer.binding
|
|
2464
|
+
});
|
|
2465
|
+
}
|
|
2466
|
+
for (const texture of parsedWGSL.textures) {
|
|
2467
|
+
const bindingDeclaration = {
|
|
2468
|
+
type: "texture",
|
|
2469
|
+
name: texture.name,
|
|
2470
|
+
group: texture.group,
|
|
2471
|
+
location: texture.binding,
|
|
2472
|
+
...getTextureBindingFromReflect(texture)
|
|
2473
|
+
};
|
|
2474
|
+
shaderLayout.bindings.push(bindingDeclaration);
|
|
2475
|
+
}
|
|
2476
|
+
for (const sampler of parsedWGSL.samplers) {
|
|
2477
|
+
shaderLayout.bindings.push({
|
|
2478
|
+
type: "sampler",
|
|
2479
|
+
name: sampler.name,
|
|
2480
|
+
group: sampler.group,
|
|
2481
|
+
location: sampler.binding
|
|
2482
|
+
});
|
|
2483
|
+
}
|
|
2484
|
+
const vertex = parsedWGSL.entry.vertex[0];
|
|
2485
|
+
const attributeCount = (vertex == null ? void 0 : vertex.inputs.length) || 0;
|
|
2486
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
2487
|
+
const wgslAttribute = vertex.inputs[i];
|
|
2488
|
+
if (wgslAttribute.locationType === "location") {
|
|
2489
|
+
const type = getType(wgslAttribute.type);
|
|
2490
|
+
shaderLayout.attributes.push({
|
|
2491
|
+
name: wgslAttribute.name,
|
|
2492
|
+
location: Number(wgslAttribute.location),
|
|
2493
|
+
type
|
|
2494
|
+
});
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
return shaderLayout;
|
|
2498
|
+
}
|
|
2499
|
+
function getType(type) {
|
|
2500
|
+
return (type == null ? void 0 : type.format) ? `${type.name}<${type.format.name}>` : type.name;
|
|
2501
|
+
}
|
|
2502
|
+
function parseWGSL(source) {
|
|
2503
|
+
try {
|
|
2504
|
+
return new import_wgsl_reflect.WgslReflect(source);
|
|
2505
|
+
} catch (error) {
|
|
2506
|
+
if (error instanceof Error) {
|
|
2507
|
+
throw error;
|
|
2508
|
+
}
|
|
2509
|
+
let message = "WGSL parse error";
|
|
2510
|
+
if (typeof error === "object" && (error == null ? void 0 : error.message)) {
|
|
2511
|
+
message += `: ${error.message} `;
|
|
2512
|
+
}
|
|
2513
|
+
if (typeof error === "object" && (error == null ? void 0 : error.token)) {
|
|
2514
|
+
message += error.token.line || "";
|
|
2515
|
+
}
|
|
2516
|
+
throw new Error(message, { cause: error });
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
function getTextureBindingFromReflect(v, opts) {
|
|
2520
|
+
var _a;
|
|
2521
|
+
if (v.resourceType !== import_wgsl_reflect.ResourceType.Texture) {
|
|
2522
|
+
throw new Error("Not a texture binding");
|
|
2523
|
+
}
|
|
2524
|
+
const typeName = v.type.name;
|
|
2525
|
+
const component = (_a = v.type.format) == null ? void 0 : _a.name;
|
|
2526
|
+
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";
|
|
2527
|
+
const multisampled = typeName === "texture_multisampled_2d";
|
|
2528
|
+
let sampleType;
|
|
2529
|
+
if (typeName.startsWith("texture_depth")) {
|
|
2530
|
+
sampleType = "depth";
|
|
2531
|
+
} else if (component === "i32") {
|
|
2532
|
+
sampleType = "sint";
|
|
2533
|
+
} else if (component === "u32") {
|
|
2534
|
+
sampleType = "uint";
|
|
2535
|
+
} else {
|
|
2536
|
+
sampleType = "float";
|
|
2537
|
+
}
|
|
2538
|
+
return { viewDimension, sampleType, multisampled };
|
|
2539
|
+
}
|
|
2540
|
+
var import_core22, import_wgsl_reflect;
|
|
2541
|
+
var init_get_shader_layout_wgsl = __esm({
|
|
2542
|
+
"dist/wgsl/get-shader-layout-wgsl.js"() {
|
|
2543
|
+
"use strict";
|
|
2544
|
+
import_core22 = require("@luma.gl/core");
|
|
2545
|
+
import_wgsl_reflect = require("wgsl_reflect");
|
|
2546
|
+
}
|
|
2547
|
+
});
|
|
2548
|
+
|
|
2549
|
+
// dist/adapter/helpers/generate-mipmaps-webgpu.js
|
|
2550
|
+
function generateMipmapsWebGPU(device, texture) {
|
|
2551
|
+
if (texture.mipLevels <= 1) {
|
|
2552
|
+
return;
|
|
2553
|
+
}
|
|
2554
|
+
if (texture.dimension === "3d") {
|
|
2555
|
+
generateMipmaps3D(device, texture);
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
if (RENDER_DIMENSIONS.includes(texture.dimension)) {
|
|
2559
|
+
generateMipmapsRender(device, texture);
|
|
2560
|
+
return;
|
|
2561
|
+
}
|
|
2562
|
+
throw new Error(`Cannot generate mipmaps for texture dimension "${texture.dimension}" with WebGPU.`);
|
|
2563
|
+
}
|
|
2564
|
+
function generateMipmapsRender(device, texture) {
|
|
2565
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
2566
|
+
const colorAttachmentFormat = getColorAttachmentFormat(texture.format, "render", texture.dimension);
|
|
2567
|
+
const viewDimension = texture.dimension;
|
|
2568
|
+
const shaderSource = getRenderMipmapWGSL(viewDimension);
|
|
2569
|
+
const sampler = device.createSampler({ minFilter: "linear", magFilter: "linear" });
|
|
2570
|
+
const uniformsBuffer = device.createBuffer({
|
|
2571
|
+
byteLength: 16,
|
|
2572
|
+
usage: import_core23.Buffer.UNIFORM | import_core23.Buffer.COPY_DST
|
|
2573
|
+
});
|
|
2574
|
+
const uniformValues = new Uint32Array(1);
|
|
2575
|
+
const sourceTextureLayout = {
|
|
2576
|
+
type: "texture",
|
|
2577
|
+
name: "sourceTexture",
|
|
2578
|
+
group: 0,
|
|
2579
|
+
location: 1,
|
|
2580
|
+
viewDimension,
|
|
2581
|
+
sampleType: "float"
|
|
2582
|
+
};
|
|
2583
|
+
const uniformsLayout = {
|
|
2584
|
+
type: "uniform",
|
|
2585
|
+
name: "uniforms",
|
|
2586
|
+
group: 0,
|
|
2587
|
+
location: 2
|
|
2588
|
+
};
|
|
2589
|
+
const renderShaderLayout = {
|
|
2590
|
+
attributes: [],
|
|
2591
|
+
bindings: [RENDER_SOURCE_SAMPLER_LAYOUT, sourceTextureLayout, uniformsLayout]
|
|
2592
|
+
};
|
|
2593
|
+
const vertexShader = device.createShader({
|
|
2594
|
+
id: "mipmap-generation-render-vs",
|
|
2595
|
+
source: shaderSource,
|
|
2596
|
+
language: "wgsl",
|
|
2597
|
+
stage: "vertex"
|
|
2598
|
+
});
|
|
2599
|
+
const fragmentShader = device.createShader({
|
|
2600
|
+
id: "mipmap-generation-render-fs",
|
|
2601
|
+
source: shaderSource,
|
|
2602
|
+
language: "wgsl",
|
|
2603
|
+
stage: "fragment"
|
|
2604
|
+
});
|
|
2605
|
+
const renderPipeline = device.createRenderPipeline({
|
|
2606
|
+
id: `mipmap-generation-render:${texture.dimension}:${texture.format}`,
|
|
2607
|
+
vs: vertexShader,
|
|
2608
|
+
fs: fragmentShader,
|
|
2609
|
+
shaderLayout: renderShaderLayout,
|
|
2610
|
+
colorAttachmentFormats: [colorAttachmentFormat],
|
|
2611
|
+
topology: "triangle-list"
|
|
2612
|
+
});
|
|
2613
|
+
let sourceWidth = texture.width;
|
|
2614
|
+
let sourceHeight = texture.height;
|
|
2615
|
+
const layerCount = texture.dimension === "2d" ? 1 : texture.depth;
|
|
2616
|
+
function renderMipmapLayer(sourceView, baseMipLevel, baseArrayLayer, destinationWidth, destinationHeight) {
|
|
2617
|
+
uniformValues[0] = baseArrayLayer;
|
|
2618
|
+
uniformsBuffer.write(uniformValues);
|
|
2619
|
+
const destinationView = texture.createView({
|
|
2620
|
+
dimension: "2d",
|
|
2621
|
+
baseMipLevel,
|
|
2622
|
+
mipLevelCount: 1,
|
|
2623
|
+
baseArrayLayer,
|
|
2624
|
+
arrayLayerCount: 1
|
|
2625
|
+
});
|
|
2626
|
+
const framebuffer = device.createFramebuffer({
|
|
2627
|
+
colorAttachments: [destinationView]
|
|
2628
|
+
});
|
|
2629
|
+
const renderPass = device.beginRenderPass({
|
|
2630
|
+
id: `mipmap-generation:${texture.format}:${baseMipLevel}:${baseArrayLayer}`,
|
|
2631
|
+
framebuffer
|
|
2632
|
+
});
|
|
2633
|
+
try {
|
|
2634
|
+
renderPass.setPipeline(renderPipeline);
|
|
2635
|
+
renderPass.setBindings({
|
|
2636
|
+
sourceSampler: sampler,
|
|
2637
|
+
sourceTexture: sourceView,
|
|
2638
|
+
uniforms: uniformsBuffer
|
|
2639
|
+
});
|
|
2640
|
+
renderPass.setParameters({
|
|
2641
|
+
viewport: [0, 0, destinationWidth, destinationHeight, 0, 1],
|
|
2642
|
+
scissorRect: [0, 0, destinationWidth, destinationHeight]
|
|
2643
|
+
});
|
|
2644
|
+
renderPass.draw({ vertexCount: 3 });
|
|
2645
|
+
renderPass.end();
|
|
2646
|
+
device.submit();
|
|
2647
|
+
} finally {
|
|
2648
|
+
destinationView.destroy();
|
|
2649
|
+
framebuffer.destroy();
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
try {
|
|
2653
|
+
for (let baseMipLevel = 1; baseMipLevel < texture.mipLevels; ++baseMipLevel) {
|
|
2654
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
2655
|
+
const sourceMipLevel = baseMipLevel - 1;
|
|
2656
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2657
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2658
|
+
const sourceView = texture.createView({
|
|
2659
|
+
dimension: viewDimension,
|
|
2660
|
+
baseMipLevel: sourceMipLevel,
|
|
2661
|
+
mipLevelCount: 1,
|
|
2662
|
+
baseArrayLayer: 0,
|
|
2663
|
+
arrayLayerCount: texture.depth
|
|
2664
|
+
});
|
|
2665
|
+
try {
|
|
2666
|
+
for (let baseArrayLayer = 0; baseArrayLayer < layerCount; ++baseArrayLayer) {
|
|
2667
|
+
renderMipmapLayer(sourceView, baseMipLevel, baseArrayLayer, destinationWidth, destinationHeight);
|
|
2668
|
+
}
|
|
2669
|
+
} finally {
|
|
2670
|
+
sourceView.destroy();
|
|
2671
|
+
}
|
|
2672
|
+
sourceWidth = destinationWidth;
|
|
2673
|
+
sourceHeight = destinationHeight;
|
|
2674
|
+
}
|
|
2675
|
+
} finally {
|
|
2676
|
+
renderPipeline.destroy();
|
|
2677
|
+
vertexShader.destroy();
|
|
2678
|
+
fragmentShader.destroy();
|
|
2679
|
+
sampler.destroy();
|
|
2680
|
+
uniformsBuffer.destroy();
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
function getColorAttachmentFormat(format, path, dimension) {
|
|
2684
|
+
if (import_core23.textureFormatDecoder.isColor(format)) {
|
|
2685
|
+
return format;
|
|
2686
|
+
}
|
|
2687
|
+
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.`);
|
|
2688
|
+
}
|
|
2689
|
+
function generateMipmaps3D(device, texture) {
|
|
2690
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2691
|
+
const format = getColorAttachmentFormat(texture.format, "compute", texture.dimension);
|
|
2692
|
+
const shaderSource = get3DComputeMipmapWGSL(format);
|
|
2693
|
+
const destinationTextureLayout = {
|
|
2694
|
+
type: "storage",
|
|
2695
|
+
name: "destinationTexture",
|
|
2696
|
+
group: 0,
|
|
2697
|
+
location: 1,
|
|
2698
|
+
format,
|
|
2699
|
+
viewDimension: "3d",
|
|
2700
|
+
access: "write-only"
|
|
2701
|
+
};
|
|
2702
|
+
const computeShaderLayout = {
|
|
2703
|
+
bindings: [COMPUTE_SOURCE_TEXTURE_LAYOUT, destinationTextureLayout, COMPUTE_UNIFORMS_LAYOUT]
|
|
2704
|
+
};
|
|
2705
|
+
const computeShader = device.createShader({
|
|
2706
|
+
id: "mipmap-generation-compute",
|
|
2707
|
+
source: shaderSource,
|
|
2708
|
+
language: "wgsl",
|
|
2709
|
+
stage: "compute"
|
|
2710
|
+
});
|
|
2711
|
+
const computePipeline = device.createComputePipeline({
|
|
2712
|
+
id: `mipmap-generation-compute:${texture.format}`,
|
|
2713
|
+
shader: computeShader,
|
|
2714
|
+
shaderLayout: computeShaderLayout
|
|
2715
|
+
});
|
|
2716
|
+
const uniformsBuffer = device.createBuffer({
|
|
2717
|
+
byteLength: 32,
|
|
2718
|
+
usage: import_core23.Buffer.UNIFORM | import_core23.Buffer.COPY_DST
|
|
2719
|
+
});
|
|
2720
|
+
const uniformValues = new Uint32Array(8);
|
|
2721
|
+
let sourceWidth = texture.width;
|
|
2722
|
+
let sourceHeight = texture.height;
|
|
2723
|
+
let sourceDepth = texture.depth;
|
|
2724
|
+
try {
|
|
2725
|
+
for (let destinationMipLevel = 1; destinationMipLevel < texture.mipLevels; ++destinationMipLevel) {
|
|
2726
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2727
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2728
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2729
|
+
const destinationDepth = Math.max(1, sourceDepth >> 1);
|
|
2730
|
+
uniformValues[0] = sourceWidth;
|
|
2731
|
+
uniformValues[1] = sourceHeight;
|
|
2732
|
+
uniformValues[2] = sourceDepth;
|
|
2733
|
+
uniformValues[3] = destinationWidth;
|
|
2734
|
+
uniformValues[4] = destinationHeight;
|
|
2735
|
+
uniformValues[5] = destinationDepth;
|
|
2736
|
+
uniformValues[6] = 0;
|
|
2737
|
+
uniformsBuffer.write(uniformValues);
|
|
2738
|
+
const sourceView = texture.createView({
|
|
2739
|
+
dimension: "3d",
|
|
2740
|
+
baseMipLevel: destinationMipLevel - 1,
|
|
2741
|
+
mipLevelCount: 1,
|
|
2742
|
+
baseArrayLayer: 0,
|
|
2743
|
+
arrayLayerCount: 1
|
|
2744
|
+
});
|
|
2745
|
+
const destinationView = texture.createView({
|
|
2746
|
+
dimension: "3d",
|
|
2747
|
+
baseMipLevel: destinationMipLevel,
|
|
2748
|
+
mipLevelCount: 1,
|
|
2749
|
+
baseArrayLayer: 0,
|
|
2750
|
+
arrayLayerCount: 1
|
|
2751
|
+
});
|
|
2752
|
+
computePipeline.setBindings({
|
|
2753
|
+
sourceTexture: sourceView,
|
|
2754
|
+
destinationTexture: destinationView,
|
|
2755
|
+
uniforms: uniformsBuffer
|
|
2756
|
+
});
|
|
2757
|
+
try {
|
|
2758
|
+
const workgroupsX = Math.ceil(destinationWidth / WORKGROUP_SIZE.x);
|
|
2759
|
+
const workgroupsY = Math.ceil(destinationHeight / WORKGROUP_SIZE.y);
|
|
2760
|
+
const workgroupsZ = Math.ceil(destinationDepth / WORKGROUP_SIZE.z);
|
|
2761
|
+
const computePass = device.beginComputePass({});
|
|
2762
|
+
computePass.setPipeline(computePipeline);
|
|
2763
|
+
computePass.dispatch(workgroupsX, workgroupsY, workgroupsZ);
|
|
2764
|
+
computePass.end();
|
|
2765
|
+
device.submit();
|
|
2766
|
+
} finally {
|
|
2767
|
+
sourceView.destroy();
|
|
2768
|
+
destinationView.destroy();
|
|
2769
|
+
}
|
|
2770
|
+
sourceWidth = destinationWidth;
|
|
2771
|
+
sourceHeight = destinationHeight;
|
|
2772
|
+
sourceDepth = destinationDepth;
|
|
2773
|
+
}
|
|
2774
|
+
} finally {
|
|
2775
|
+
computePipeline.destroy();
|
|
2776
|
+
computeShader.destroy();
|
|
2777
|
+
uniformsBuffer.destroy();
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
function validateFormatCapabilities(device, texture, requiredCapabilities, path) {
|
|
2781
|
+
const { format, dimension } = texture;
|
|
2782
|
+
const capabilities = device.getTextureFormatCapabilities(format);
|
|
2783
|
+
const missingCapabilities = requiredCapabilities.filter((capability) => !capabilities[capability]);
|
|
2784
|
+
if (missingCapabilities.length > 0) {
|
|
2785
|
+
const required = requiredCapabilities.join(" + ");
|
|
2786
|
+
const actual = requiredCapabilities.map((capability) => `${capability}=${capabilities[capability]}`).join(", ");
|
|
2787
|
+
throw new Error(`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Required capabilities: ${required}. Actual capabilities: ${actual}.`);
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
function getSourceTextureType(dimension) {
|
|
2791
|
+
switch (dimension) {
|
|
2792
|
+
case "2d":
|
|
2793
|
+
return "texture_2d<f32>";
|
|
2794
|
+
case "2d-array":
|
|
2795
|
+
return "texture_2d_array<f32>";
|
|
2796
|
+
case "cube":
|
|
2797
|
+
return "texture_cube<f32>";
|
|
2798
|
+
case "cube-array":
|
|
2799
|
+
return "texture_cube_array<f32>";
|
|
2800
|
+
default:
|
|
2801
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
function getRenderMipmapWGSL(dimension) {
|
|
2805
|
+
const sourceSnippet = getRenderMipmapSampleSnippet(dimension);
|
|
2806
|
+
return `
|
|
2807
|
+
struct MipmapUniforms {
|
|
2808
|
+
sourceLayer: u32,
|
|
2809
|
+
};
|
|
2810
|
+
|
|
2811
|
+
fn _touchUniform(uniforms: MipmapUniforms) {
|
|
2812
|
+
let unusedSourceLayer = uniforms.sourceLayer;
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
const faceMat = array(
|
|
2816
|
+
mat3x3f(
|
|
2817
|
+
0.0, 0.0, -2.0,
|
|
2818
|
+
0.0, -2.0, 0.0,
|
|
2819
|
+
1.0, 1.0, 1.0
|
|
2820
|
+
), // pos-x
|
|
2821
|
+
mat3x3f(
|
|
2822
|
+
0.0, 0.0, 2.0,
|
|
2823
|
+
0.0, -2.0, 0.0,
|
|
2824
|
+
-1.0, 1.0, -1.0
|
|
2825
|
+
), // neg-x
|
|
2826
|
+
mat3x3f(
|
|
2827
|
+
2.0, 0.0, 0.0,
|
|
2828
|
+
0.0, 0.0, 2.0,
|
|
2829
|
+
-1.0, 1.0, -1.0
|
|
2830
|
+
), // pos-y
|
|
2831
|
+
mat3x3f(
|
|
2832
|
+
2.0, 0.0, 0.0,
|
|
2833
|
+
0.0, 0.0, -2.0,
|
|
2834
|
+
-1.0, -1.0, 1.0
|
|
2835
|
+
), // neg-y
|
|
2836
|
+
mat3x3f(
|
|
2837
|
+
2.0, 0.0, 0.0,
|
|
2838
|
+
0.0, -2.0, 0.0,
|
|
2839
|
+
-1.0, 1.0, 1.0
|
|
2840
|
+
), // pos-z
|
|
2841
|
+
mat3x3f(
|
|
2842
|
+
-2.0, 0.0, 0.0,
|
|
2843
|
+
0.0, -2.0, 0.0,
|
|
2844
|
+
1.0, 1.0, -1.0
|
|
2845
|
+
) // neg-z
|
|
2846
|
+
);
|
|
2847
|
+
|
|
2848
|
+
struct FragmentInputs {
|
|
2849
|
+
@builtin(position) position: vec4f,
|
|
2850
|
+
@location(0) texcoord: vec2f
|
|
2851
|
+
};
|
|
2852
|
+
|
|
2853
|
+
struct VertexOutput {
|
|
2854
|
+
@builtin(position) position: vec4f,
|
|
2855
|
+
@location(0) texcoord: vec2f
|
|
2856
|
+
};
|
|
2857
|
+
|
|
2858
|
+
@group(0) @binding(0) var sourceSampler: sampler;
|
|
2859
|
+
@group(0) @binding(1) var sourceTexture: ${getSourceTextureType(dimension)};
|
|
2860
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2861
|
+
|
|
2862
|
+
@vertex
|
|
2863
|
+
fn vertexMain(
|
|
2864
|
+
@builtin(vertex_index) vertexIndex: u32
|
|
2865
|
+
) -> VertexOutput {
|
|
2866
|
+
const positions = array(
|
|
2867
|
+
vec2f(-1.0, -1.0),
|
|
2868
|
+
vec2f(-1.0, 3.0),
|
|
2869
|
+
vec2f( 3.0, -1.0)
|
|
2870
|
+
);
|
|
2871
|
+
|
|
2872
|
+
let xy = positions[vertexIndex];
|
|
2873
|
+
return VertexOutput(
|
|
2874
|
+
vec4f(xy, 0.0, 1.0),
|
|
2875
|
+
xy * vec2f(0.5, -0.5) + vec2f(0.5)
|
|
2876
|
+
);
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
@fragment
|
|
2880
|
+
fn fragmentMain(fsInput: VertexOutput) -> @location(0) vec4f {
|
|
2881
|
+
_touchUniform(uniforms);
|
|
2882
|
+
return ${sourceSnippet};
|
|
2883
|
+
}
|
|
2884
|
+
`;
|
|
2885
|
+
}
|
|
2886
|
+
function getRenderMipmapSampleSnippet(dimension) {
|
|
2887
|
+
const layer = "uniforms.sourceLayer";
|
|
2888
|
+
switch (dimension) {
|
|
2889
|
+
case "2d":
|
|
2890
|
+
return "textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, 0.0)";
|
|
2891
|
+
case "2d-array":
|
|
2892
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, i32(${layer}), 0.0)`;
|
|
2893
|
+
case "cube":
|
|
2894
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer})] * vec3f(fract(fsInput.texcoord), 1.0), 0.0)`;
|
|
2895
|
+
case "cube-array":
|
|
2896
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer} % 6u)] * vec3f(fract(fsInput.texcoord), 1.0), i32(${layer} / 6u), 0.0)`;
|
|
2897
|
+
default:
|
|
2898
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
function get3DComputeMipmapWGSL(format) {
|
|
2902
|
+
return `
|
|
2903
|
+
struct MipmapUniforms {
|
|
2904
|
+
sourceWidth: u32,
|
|
2905
|
+
sourceHeight: u32,
|
|
2906
|
+
sourceDepth: u32,
|
|
2907
|
+
destinationWidth: u32,
|
|
2908
|
+
destinationHeight: u32,
|
|
2909
|
+
destinationDepth: u32,
|
|
2910
|
+
padding: u32,
|
|
2911
|
+
};
|
|
2912
|
+
|
|
2913
|
+
@group(0) @binding(0) var sourceTexture: texture_3d<f32>;
|
|
2914
|
+
@group(0) @binding(1) var destinationTexture: texture_storage_3d<${format}, write>;
|
|
2915
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2916
|
+
|
|
2917
|
+
@compute @workgroup_size(${WORKGROUP_SIZE.x}, ${WORKGROUP_SIZE.y}, ${WORKGROUP_SIZE.z})
|
|
2918
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
2919
|
+
if (
|
|
2920
|
+
id.x >= uniforms.destinationWidth ||
|
|
2921
|
+
id.y >= uniforms.destinationHeight ||
|
|
2922
|
+
id.z >= uniforms.destinationDepth
|
|
2923
|
+
) {
|
|
2924
|
+
return;
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2927
|
+
let sourceBase = id * 2u;
|
|
2928
|
+
let sourceX0 = min(sourceBase.x, uniforms.sourceWidth - 1u);
|
|
2929
|
+
let sourceY0 = min(sourceBase.y, uniforms.sourceHeight - 1u);
|
|
2930
|
+
let sourceZ0 = min(sourceBase.z, uniforms.sourceDepth - 1u);
|
|
2931
|
+
|
|
2932
|
+
let sourceX1 = min(sourceBase.x + 1u, uniforms.sourceWidth - 1u);
|
|
2933
|
+
let sourceY1 = min(sourceBase.y + 1u, uniforms.sourceHeight - 1u);
|
|
2934
|
+
let sourceZ1 = min(sourceBase.z + 1u, uniforms.sourceDepth - 1u);
|
|
2935
|
+
|
|
2936
|
+
var sum = textureLoad(
|
|
2937
|
+
sourceTexture,
|
|
2938
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ0)),
|
|
2939
|
+
0
|
|
2940
|
+
);
|
|
2941
|
+
sum += textureLoad(
|
|
2942
|
+
sourceTexture,
|
|
2943
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ0)),
|
|
2944
|
+
0
|
|
2945
|
+
);
|
|
2946
|
+
sum += textureLoad(
|
|
2947
|
+
sourceTexture,
|
|
2948
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ0)),
|
|
2949
|
+
0
|
|
2950
|
+
);
|
|
2951
|
+
sum += textureLoad(
|
|
2952
|
+
sourceTexture,
|
|
2953
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ0)),
|
|
2954
|
+
0
|
|
2955
|
+
);
|
|
2956
|
+
sum += textureLoad(
|
|
2957
|
+
sourceTexture,
|
|
2958
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ1)),
|
|
2959
|
+
0
|
|
2960
|
+
);
|
|
2961
|
+
sum += textureLoad(
|
|
2962
|
+
sourceTexture,
|
|
2963
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ1)),
|
|
2964
|
+
0
|
|
2965
|
+
);
|
|
2966
|
+
sum += textureLoad(
|
|
2967
|
+
sourceTexture,
|
|
2968
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ1)),
|
|
2969
|
+
0
|
|
2970
|
+
);
|
|
2971
|
+
sum += textureLoad(
|
|
2972
|
+
sourceTexture,
|
|
2973
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ1)),
|
|
2974
|
+
0
|
|
2975
|
+
);
|
|
2976
|
+
|
|
2977
|
+
textureStore(
|
|
2978
|
+
destinationTexture,
|
|
2979
|
+
vec3<i32>(i32(id.x), i32(id.y), i32(id.z)),
|
|
2980
|
+
vec4<f32>(sum.xyz / 8.0, sum.w / 8.0)
|
|
2981
|
+
);
|
|
2982
|
+
}
|
|
2983
|
+
`;
|
|
2984
|
+
}
|
|
2985
|
+
var import_core23, RENDER_DIMENSIONS, WORKGROUP_SIZE, RENDER_SOURCE_SAMPLER_LAYOUT, COMPUTE_SOURCE_TEXTURE_LAYOUT, COMPUTE_UNIFORMS_LAYOUT;
|
|
2986
|
+
var init_generate_mipmaps_webgpu = __esm({
|
|
2987
|
+
"dist/adapter/helpers/generate-mipmaps-webgpu.js"() {
|
|
2988
|
+
"use strict";
|
|
2989
|
+
import_core23 = require("@luma.gl/core");
|
|
2990
|
+
RENDER_DIMENSIONS = [
|
|
2991
|
+
"2d",
|
|
2992
|
+
"2d-array",
|
|
2993
|
+
"cube",
|
|
2994
|
+
"cube-array"
|
|
2995
|
+
];
|
|
2996
|
+
WORKGROUP_SIZE = {
|
|
2997
|
+
x: 4,
|
|
2998
|
+
y: 4,
|
|
2999
|
+
z: 4
|
|
3000
|
+
};
|
|
3001
|
+
RENDER_SOURCE_SAMPLER_LAYOUT = {
|
|
3002
|
+
type: "sampler",
|
|
3003
|
+
name: "sourceSampler",
|
|
3004
|
+
group: 0,
|
|
3005
|
+
location: 0
|
|
3006
|
+
};
|
|
3007
|
+
COMPUTE_SOURCE_TEXTURE_LAYOUT = {
|
|
3008
|
+
type: "texture",
|
|
3009
|
+
name: "sourceTexture",
|
|
3010
|
+
group: 0,
|
|
3011
|
+
location: 0,
|
|
3012
|
+
viewDimension: "3d",
|
|
3013
|
+
sampleType: "float"
|
|
3014
|
+
};
|
|
3015
|
+
COMPUTE_UNIFORMS_LAYOUT = {
|
|
3016
|
+
type: "uniform",
|
|
3017
|
+
name: "uniforms",
|
|
3018
|
+
group: 0,
|
|
3019
|
+
location: 2
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
});
|
|
3023
|
+
|
|
3024
|
+
// dist/adapter/helpers/get-bind-group.js
|
|
3025
|
+
function getBindGroup(device, bindGroupLayout, shaderLayout, bindings, group) {
|
|
3026
|
+
const entries = getBindGroupEntries(bindings, shaderLayout, group);
|
|
3027
|
+
if (entries.length === 0) {
|
|
3028
|
+
return null;
|
|
3029
|
+
}
|
|
3030
|
+
device.pushErrorScope("validation");
|
|
3031
|
+
const bindGroup = device.handle.createBindGroup({
|
|
3032
|
+
layout: bindGroupLayout,
|
|
3033
|
+
entries
|
|
3034
|
+
});
|
|
3035
|
+
device.popErrorScope((error) => {
|
|
3036
|
+
import_core24.log.error(`bindGroup creation: ${error.message}`, bindGroup)();
|
|
3037
|
+
});
|
|
3038
|
+
return bindGroup;
|
|
3039
|
+
}
|
|
3040
|
+
function getBindGroupEntries(bindings, shaderLayout, group) {
|
|
3041
|
+
const entries = [];
|
|
3042
|
+
for (const [bindingName, value] of Object.entries(bindings)) {
|
|
3043
|
+
const exactBindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName);
|
|
3044
|
+
const bindingLayout = exactBindingLayout || (0, import_core24.getShaderLayoutBinding)(shaderLayout, bindingName);
|
|
3045
|
+
const isShadowedAlias = !exactBindingLayout && bindingLayout ? bindingLayout.name in bindings : false;
|
|
3046
|
+
if (!isShadowedAlias && (bindingLayout == null ? void 0 : bindingLayout.group) === group) {
|
|
3047
|
+
const entry = bindingLayout ? getBindGroupEntry(value, bindingLayout.location, void 0, bindingName) : null;
|
|
3048
|
+
if (entry) {
|
|
3049
|
+
entries.push(entry);
|
|
3050
|
+
}
|
|
3051
|
+
if (value instanceof import_core24.Texture) {
|
|
3052
|
+
const samplerBindingLayout = (0, import_core24.getShaderLayoutBinding)(shaderLayout, `${bindingName}Sampler`, {
|
|
3053
|
+
ignoreWarnings: true
|
|
3054
|
+
});
|
|
3055
|
+
const samplerEntry = samplerBindingLayout ? samplerBindingLayout.group === group ? getBindGroupEntry(value, samplerBindingLayout.location, { sampler: true }, bindingName) : null : null;
|
|
3056
|
+
if (samplerEntry) {
|
|
3057
|
+
entries.push(samplerEntry);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
return entries;
|
|
3063
|
+
}
|
|
3064
|
+
function getBindGroupEntry(binding, index, options, bindingName = "unknown") {
|
|
3065
|
+
if (binding instanceof import_core24.Buffer) {
|
|
3066
|
+
return {
|
|
3067
|
+
binding: index,
|
|
3068
|
+
resource: {
|
|
3069
|
+
buffer: binding.handle
|
|
3070
|
+
}
|
|
3071
|
+
};
|
|
3072
|
+
}
|
|
3073
|
+
if (binding instanceof import_core24.Sampler) {
|
|
3074
|
+
return {
|
|
3075
|
+
binding: index,
|
|
3076
|
+
resource: binding.handle
|
|
3077
|
+
};
|
|
3078
|
+
}
|
|
3079
|
+
if (binding instanceof import_core24.TextureView) {
|
|
3080
|
+
return {
|
|
3081
|
+
binding: index,
|
|
3082
|
+
resource: binding.handle
|
|
3083
|
+
};
|
|
3084
|
+
}
|
|
3085
|
+
if (binding instanceof import_core24.Texture) {
|
|
3086
|
+
if (options == null ? void 0 : options.sampler) {
|
|
3087
|
+
return {
|
|
3088
|
+
binding: index,
|
|
3089
|
+
resource: binding.sampler.handle
|
|
3090
|
+
};
|
|
3091
|
+
}
|
|
3092
|
+
return {
|
|
3093
|
+
binding: index,
|
|
3094
|
+
resource: binding.view.handle
|
|
3095
|
+
};
|
|
3096
|
+
}
|
|
3097
|
+
import_core24.log.warn(`invalid binding ${bindingName}`, binding);
|
|
3098
|
+
return null;
|
|
3099
|
+
}
|
|
3100
|
+
var import_core24;
|
|
3101
|
+
var init_get_bind_group = __esm({
|
|
3102
|
+
"dist/adapter/helpers/get-bind-group.js"() {
|
|
3103
|
+
"use strict";
|
|
3104
|
+
import_core24 = require("@luma.gl/core");
|
|
3105
|
+
}
|
|
3106
|
+
});
|
|
3107
|
+
|
|
1728
3108
|
// dist/adapter/webgpu-device.js
|
|
1729
3109
|
var webgpu_device_exports = {};
|
|
1730
3110
|
__export(webgpu_device_exports, {
|
|
1731
3111
|
WebGPUDevice: () => WebGPUDevice
|
|
1732
3112
|
});
|
|
1733
|
-
|
|
3113
|
+
function scheduleMicrotask(callback) {
|
|
3114
|
+
if (globalThis.queueMicrotask) {
|
|
3115
|
+
globalThis.queueMicrotask(callback);
|
|
3116
|
+
return;
|
|
3117
|
+
}
|
|
3118
|
+
Promise.resolve().then(callback).catch(() => {
|
|
3119
|
+
});
|
|
3120
|
+
}
|
|
3121
|
+
var import_core25, WebGPUDevice;
|
|
1734
3122
|
var init_webgpu_device = __esm({
|
|
1735
3123
|
"dist/adapter/webgpu-device.js"() {
|
|
1736
3124
|
"use strict";
|
|
1737
|
-
|
|
3125
|
+
import_core25 = require("@luma.gl/core");
|
|
1738
3126
|
init_webgpu_buffer();
|
|
1739
3127
|
init_webgpu_texture();
|
|
1740
3128
|
init_webgpu_external_texture();
|
|
@@ -1745,10 +3133,16 @@ var init_webgpu_device = __esm({
|
|
|
1745
3133
|
init_webgpu_compute_pipeline();
|
|
1746
3134
|
init_webgpu_vertex_array();
|
|
1747
3135
|
init_webgpu_canvas_context();
|
|
3136
|
+
init_webgpu_presentation_context();
|
|
1748
3137
|
init_webgpu_command_encoder();
|
|
1749
3138
|
init_webgpu_query_set();
|
|
1750
3139
|
init_webgpu_pipeline_layout();
|
|
1751
|
-
|
|
3140
|
+
init_webgpu_fence();
|
|
3141
|
+
init_get_shader_layout_wgsl();
|
|
3142
|
+
init_generate_mipmaps_webgpu();
|
|
3143
|
+
init_get_bind_group();
|
|
3144
|
+
init_cpu_hotspot_profiler();
|
|
3145
|
+
WebGPUDevice = class extends import_core25.Device {
|
|
1752
3146
|
/** The underlying WebGPU device */
|
|
1753
3147
|
handle;
|
|
1754
3148
|
/* The underlying WebGPU adapter */
|
|
@@ -1765,6 +3159,7 @@ var init_webgpu_device = __esm({
|
|
|
1765
3159
|
lost;
|
|
1766
3160
|
canvasContext = null;
|
|
1767
3161
|
_isLost = false;
|
|
3162
|
+
_defaultSampler = null;
|
|
1768
3163
|
commandEncoder;
|
|
1769
3164
|
get [Symbol.toStringTag]() {
|
|
1770
3165
|
return "WebGPUDevice";
|
|
@@ -1791,7 +3186,7 @@ var init_webgpu_device = __esm({
|
|
|
1791
3186
|
this._isLost = true;
|
|
1792
3187
|
resolve({ reason: "destroyed", message: lostInfo.message });
|
|
1793
3188
|
});
|
|
1794
|
-
const canvasContextProps =
|
|
3189
|
+
const canvasContextProps = import_core25.Device._getCanvasContextProps(props);
|
|
1795
3190
|
if (canvasContextProps) {
|
|
1796
3191
|
this.canvasContext = new WebGPUCanvasContext(this, this.adapter, canvasContextProps);
|
|
1797
3192
|
}
|
|
@@ -1802,18 +3197,22 @@ var init_webgpu_device = __esm({
|
|
|
1802
3197
|
// const {glsl = true} = props;
|
|
1803
3198
|
// this.glslang = glsl && await loadGlslangModule();
|
|
1804
3199
|
destroy() {
|
|
3200
|
+
var _a, _b;
|
|
3201
|
+
(_a = this.commandEncoder) == null ? void 0 : _a.destroy();
|
|
3202
|
+
(_b = this._defaultSampler) == null ? void 0 : _b.destroy();
|
|
3203
|
+
this._defaultSampler = null;
|
|
1805
3204
|
this.handle.destroy();
|
|
1806
3205
|
}
|
|
1807
3206
|
get isLost() {
|
|
1808
3207
|
return this._isLost;
|
|
1809
3208
|
}
|
|
3209
|
+
getShaderLayout(source) {
|
|
3210
|
+
return getShaderLayoutFromWGSL(source);
|
|
3211
|
+
}
|
|
1810
3212
|
isVertexFormatSupported(format) {
|
|
1811
3213
|
const info = this.getVertexFormatInfo(format);
|
|
1812
3214
|
return !info.webglOnly;
|
|
1813
3215
|
}
|
|
1814
|
-
getTextureByteAlignment() {
|
|
1815
|
-
return 1;
|
|
1816
|
-
}
|
|
1817
3216
|
createBuffer(props) {
|
|
1818
3217
|
const newProps = this._normalizeBufferProps(props);
|
|
1819
3218
|
return new WebGPUBuffer(this, newProps);
|
|
@@ -1830,6 +3229,12 @@ var init_webgpu_device = __esm({
|
|
|
1830
3229
|
createSampler(props) {
|
|
1831
3230
|
return new WebGPUSampler(this, props);
|
|
1832
3231
|
}
|
|
3232
|
+
getDefaultSampler() {
|
|
3233
|
+
this._defaultSampler ||= new WebGPUSampler(this, {
|
|
3234
|
+
id: `${this.id}-default-sampler`
|
|
3235
|
+
});
|
|
3236
|
+
return this._defaultSampler;
|
|
3237
|
+
}
|
|
1833
3238
|
createRenderPipeline(props) {
|
|
1834
3239
|
return new WebGPURenderPipeline(this, props);
|
|
1835
3240
|
}
|
|
@@ -1852,35 +3257,135 @@ var init_webgpu_device = __esm({
|
|
|
1852
3257
|
createQuerySet(props) {
|
|
1853
3258
|
return new WebGPUQuerySet(this, props);
|
|
1854
3259
|
}
|
|
3260
|
+
createFence() {
|
|
3261
|
+
return new WebGPUFence(this);
|
|
3262
|
+
}
|
|
1855
3263
|
createCanvasContext(props) {
|
|
1856
3264
|
return new WebGPUCanvasContext(this, this.adapter, props);
|
|
1857
3265
|
}
|
|
3266
|
+
createPresentationContext(props) {
|
|
3267
|
+
return new WebGPUPresentationContext(this, props);
|
|
3268
|
+
}
|
|
1858
3269
|
createPipelineLayout(props) {
|
|
1859
3270
|
return new WebGPUPipelineLayout(this, props);
|
|
1860
3271
|
}
|
|
3272
|
+
generateMipmapsWebGPU(texture) {
|
|
3273
|
+
generateMipmapsWebGPU(this, texture);
|
|
3274
|
+
}
|
|
3275
|
+
_createBindGroupLayoutWebGPU(pipeline, group) {
|
|
3276
|
+
return pipeline.handle.getBindGroupLayout(group);
|
|
3277
|
+
}
|
|
3278
|
+
_createBindGroupWebGPU(bindGroupLayout, shaderLayout, bindings, group) {
|
|
3279
|
+
if (Object.keys(bindings).length === 0) {
|
|
3280
|
+
return this.handle.createBindGroup({
|
|
3281
|
+
layout: bindGroupLayout,
|
|
3282
|
+
entries: []
|
|
3283
|
+
});
|
|
3284
|
+
}
|
|
3285
|
+
return getBindGroup(this, bindGroupLayout, shaderLayout, bindings, group);
|
|
3286
|
+
}
|
|
1861
3287
|
submit(commandBuffer) {
|
|
3288
|
+
let submittedCommandEncoder = null;
|
|
1862
3289
|
if (!commandBuffer) {
|
|
1863
|
-
commandBuffer = this.
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
this
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
this.
|
|
3290
|
+
({ submittedCommandEncoder, commandBuffer } = this._finalizeDefaultCommandEncoderForSubmit());
|
|
3291
|
+
}
|
|
3292
|
+
const profiler = getCpuHotspotProfiler(this);
|
|
3293
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
3294
|
+
const submitReason = getCpuHotspotSubmitReason(this);
|
|
3295
|
+
try {
|
|
3296
|
+
this.pushErrorScope("validation");
|
|
3297
|
+
const queueSubmitStartTime = profiler ? getTimestamp() : 0;
|
|
3298
|
+
this.handle.queue.submit([commandBuffer.handle]);
|
|
3299
|
+
if (profiler) {
|
|
3300
|
+
profiler.queueSubmitCount = (profiler.queueSubmitCount || 0) + 1;
|
|
3301
|
+
profiler.queueSubmitTimeMs = (profiler.queueSubmitTimeMs || 0) + (getTimestamp() - queueSubmitStartTime);
|
|
3302
|
+
}
|
|
3303
|
+
this.popErrorScope((error) => {
|
|
3304
|
+
this.reportError(new Error(`${this} command submission: ${error.message}`), this)();
|
|
3305
|
+
this.debug();
|
|
3306
|
+
});
|
|
3307
|
+
if (submittedCommandEncoder) {
|
|
3308
|
+
const submitResolveKickoffStartTime = profiler ? getTimestamp() : 0;
|
|
3309
|
+
scheduleMicrotask(() => {
|
|
3310
|
+
submittedCommandEncoder.resolveTimeProfilingQuerySet().then(() => {
|
|
3311
|
+
this.commandEncoder._gpuTimeMs = submittedCommandEncoder._gpuTimeMs;
|
|
3312
|
+
}).catch(() => {
|
|
3313
|
+
});
|
|
3314
|
+
});
|
|
3315
|
+
if (profiler) {
|
|
3316
|
+
profiler.submitResolveKickoffCount = (profiler.submitResolveKickoffCount || 0) + 1;
|
|
3317
|
+
profiler.submitResolveKickoffTimeMs = (profiler.submitResolveKickoffTimeMs || 0) + (getTimestamp() - submitResolveKickoffStartTime);
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
} finally {
|
|
3321
|
+
if (profiler) {
|
|
3322
|
+
profiler.submitCount = (profiler.submitCount || 0) + 1;
|
|
3323
|
+
profiler.submitTimeMs = (profiler.submitTimeMs || 0) + (getTimestamp() - startTime);
|
|
3324
|
+
const reasonCountKey = submitReason === "query-readback" ? "queryReadbackSubmitCount" : "defaultSubmitCount";
|
|
3325
|
+
const reasonTimeKey = submitReason === "query-readback" ? "queryReadbackSubmitTimeMs" : "defaultSubmitTimeMs";
|
|
3326
|
+
profiler[reasonCountKey] = (profiler[reasonCountKey] || 0) + 1;
|
|
3327
|
+
profiler[reasonTimeKey] = (profiler[reasonTimeKey] || 0) + (getTimestamp() - startTime);
|
|
3328
|
+
}
|
|
3329
|
+
const commandBufferDestroyStartTime = profiler ? getTimestamp() : 0;
|
|
3330
|
+
commandBuffer.destroy();
|
|
3331
|
+
if (profiler) {
|
|
3332
|
+
profiler.commandBufferDestroyCount = (profiler.commandBufferDestroyCount || 0) + 1;
|
|
3333
|
+
profiler.commandBufferDestroyTimeMs = (profiler.commandBufferDestroyTimeMs || 0) + (getTimestamp() - commandBufferDestroyStartTime);
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3337
|
+
_finalizeDefaultCommandEncoderForSubmit() {
|
|
3338
|
+
const submittedCommandEncoder = this.commandEncoder;
|
|
3339
|
+
if (submittedCommandEncoder.getTimeProfilingSlotCount() > 0 && submittedCommandEncoder.getTimeProfilingQuerySet() instanceof WebGPUQuerySet) {
|
|
3340
|
+
const querySet = submittedCommandEncoder.getTimeProfilingQuerySet();
|
|
3341
|
+
querySet._encodeResolveToReadBuffer(submittedCommandEncoder, {
|
|
3342
|
+
firstQuery: 0,
|
|
3343
|
+
queryCount: submittedCommandEncoder.getTimeProfilingSlotCount()
|
|
3344
|
+
});
|
|
3345
|
+
}
|
|
3346
|
+
const commandBuffer = submittedCommandEncoder.finish();
|
|
3347
|
+
this.commandEncoder.destroy();
|
|
3348
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
3349
|
+
id: submittedCommandEncoder.props.id,
|
|
3350
|
+
timeProfilingQuerySet: submittedCommandEncoder.getTimeProfilingQuerySet()
|
|
1872
3351
|
});
|
|
3352
|
+
return { submittedCommandEncoder, commandBuffer };
|
|
1873
3353
|
}
|
|
1874
3354
|
// WebGPU specific
|
|
1875
3355
|
pushErrorScope(scope) {
|
|
3356
|
+
if (!this.props.debug) {
|
|
3357
|
+
return;
|
|
3358
|
+
}
|
|
3359
|
+
const profiler = getCpuHotspotProfiler(this);
|
|
3360
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1876
3361
|
this.handle.pushErrorScope(scope);
|
|
3362
|
+
if (profiler) {
|
|
3363
|
+
profiler.errorScopePushCount = (profiler.errorScopePushCount || 0) + 1;
|
|
3364
|
+
profiler.errorScopeTimeMs = (profiler.errorScopeTimeMs || 0) + (getTimestamp() - startTime);
|
|
3365
|
+
}
|
|
1877
3366
|
}
|
|
1878
3367
|
popErrorScope(handler) {
|
|
3368
|
+
if (!this.props.debug) {
|
|
3369
|
+
return;
|
|
3370
|
+
}
|
|
3371
|
+
const profiler = getCpuHotspotProfiler(this);
|
|
3372
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
1879
3373
|
this.handle.popErrorScope().then((error) => {
|
|
1880
3374
|
if (error) {
|
|
1881
3375
|
handler(error);
|
|
1882
3376
|
}
|
|
3377
|
+
}).catch((error) => {
|
|
3378
|
+
if (this.shouldIgnoreDroppedInstanceError(error, "popErrorScope")) {
|
|
3379
|
+
return;
|
|
3380
|
+
}
|
|
3381
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3382
|
+
this.reportError(new Error(`${this} popErrorScope failed: ${errorMessage}`), this)();
|
|
3383
|
+
this.debug();
|
|
1883
3384
|
});
|
|
3385
|
+
if (profiler) {
|
|
3386
|
+
profiler.errorScopePopCount = (profiler.errorScopePopCount || 0) + 1;
|
|
3387
|
+
profiler.errorScopeTimeMs = (profiler.errorScopeTimeMs || 0) + (getTimestamp() - startTime);
|
|
3388
|
+
}
|
|
1884
3389
|
}
|
|
1885
3390
|
// PRIVATE METHODS
|
|
1886
3391
|
_getInfo() {
|
|
@@ -1888,10 +3393,12 @@ var init_webgpu_device = __esm({
|
|
|
1888
3393
|
const vendor = this.adapterInfo.vendor || this.adapter.__brand || "unknown";
|
|
1889
3394
|
const renderer = driver || "";
|
|
1890
3395
|
const version = driverVersion || "";
|
|
1891
|
-
const
|
|
3396
|
+
const fallback = Boolean(this.adapterInfo.isFallbackAdapter ?? this.adapter.isFallbackAdapter ?? false);
|
|
3397
|
+
const softwareRenderer = /SwiftShader/i.test(`${vendor} ${renderer} ${this.adapterInfo.architecture || ""}`);
|
|
3398
|
+
const gpu = vendor === "apple" ? "apple" : softwareRenderer || fallback ? "software" : "unknown";
|
|
1892
3399
|
const gpuArchitecture = this.adapterInfo.architecture || "unknown";
|
|
1893
3400
|
const gpuBackend = this.adapterInfo.backend || "unknown";
|
|
1894
|
-
const gpuType = (this.adapterInfo.type || "").split(" ")[0].toLowerCase() || "unknown";
|
|
3401
|
+
const gpuType = (this.adapterInfo.type || "").split(" ")[0].toLowerCase() || (softwareRenderer || fallback ? "cpu" : "unknown");
|
|
1895
3402
|
return {
|
|
1896
3403
|
type: "webgpu",
|
|
1897
3404
|
vendor,
|
|
@@ -1901,10 +3408,15 @@ var init_webgpu_device = __esm({
|
|
|
1901
3408
|
gpuType,
|
|
1902
3409
|
gpuBackend,
|
|
1903
3410
|
gpuArchitecture,
|
|
3411
|
+
fallback,
|
|
1904
3412
|
shadingLanguage: "wgsl",
|
|
1905
3413
|
shadingLanguageVersion: 100
|
|
1906
3414
|
};
|
|
1907
3415
|
}
|
|
3416
|
+
shouldIgnoreDroppedInstanceError(error, operation) {
|
|
3417
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3418
|
+
return errorMessage.includes("Instance dropped") && (!operation || errorMessage.includes(operation)) && (this._isLost || this.info.gpu === "software" || this.info.gpuType === "cpu" || Boolean(this.info.fallback));
|
|
3419
|
+
}
|
|
1908
3420
|
_getFeatures() {
|
|
1909
3421
|
const features = new Set(this.handle.features);
|
|
1910
3422
|
if (features.has("depth-clamping")) {
|
|
@@ -1914,8 +3426,13 @@ var init_webgpu_device = __esm({
|
|
|
1914
3426
|
if (features.has("texture-compression-bc")) {
|
|
1915
3427
|
features.add("texture-compression-bc5-webgl");
|
|
1916
3428
|
}
|
|
3429
|
+
if (this.handle.features.has("chromium-experimental-norm16-texture-formats")) {
|
|
3430
|
+
features.add("norm16-renderable-webgl");
|
|
3431
|
+
}
|
|
3432
|
+
if (this.handle.features.has("chromium-experimental-snorm16-texture-formats")) {
|
|
3433
|
+
features.add("snorm16-renderable-webgl");
|
|
3434
|
+
}
|
|
1917
3435
|
const WEBGPU_ALWAYS_FEATURES = [
|
|
1918
|
-
"timer-query-webgl",
|
|
1919
3436
|
"compilation-status-async-webgl",
|
|
1920
3437
|
"float32-renderable-webgl",
|
|
1921
3438
|
"float16-renderable-webgl",
|
|
@@ -1926,7 +3443,7 @@ var init_webgpu_device = __esm({
|
|
|
1926
3443
|
for (const feature of WEBGPU_ALWAYS_FEATURES) {
|
|
1927
3444
|
features.add(feature);
|
|
1928
3445
|
}
|
|
1929
|
-
return new
|
|
3446
|
+
return new import_core25.DeviceFeatures(Array.from(features), this.props._disabledFeatures);
|
|
1930
3447
|
}
|
|
1931
3448
|
_getDeviceSpecificTextureFormatCapabilities(capabilities) {
|
|
1932
3449
|
const { format } = capabilities;
|
|
@@ -1944,16 +3461,18 @@ var dist_exports = {};
|
|
|
1944
3461
|
__export(dist_exports, {
|
|
1945
3462
|
WebGPUBuffer: () => WebGPUBuffer,
|
|
1946
3463
|
WebGPUDevice: () => WebGPUDevice,
|
|
3464
|
+
WebGPUFence: () => WebGPUFence,
|
|
1947
3465
|
WebGPUSampler: () => WebGPUSampler,
|
|
1948
3466
|
WebGPUShader: () => WebGPUShader,
|
|
1949
3467
|
WebGPUTexture: () => WebGPUTexture,
|
|
3468
|
+
getShaderLayoutFromWGSL: () => getShaderLayoutFromWGSL,
|
|
1950
3469
|
webgpuAdapter: () => webgpuAdapter
|
|
1951
3470
|
});
|
|
1952
3471
|
module.exports = __toCommonJS(dist_exports);
|
|
1953
3472
|
|
|
1954
3473
|
// dist/adapter/webgpu-adapter.js
|
|
1955
|
-
var
|
|
1956
|
-
var WebGPUAdapter = class extends
|
|
3474
|
+
var import_core26 = require("@luma.gl/core");
|
|
3475
|
+
var WebGPUAdapter = class extends import_core26.Adapter {
|
|
1957
3476
|
/** type of device's created by this adapter */
|
|
1958
3477
|
type = "webgpu";
|
|
1959
3478
|
isSupported() {
|
|
@@ -1973,43 +3492,41 @@ var WebGPUAdapter = class extends import_core22.Adapter {
|
|
|
1973
3492
|
if (!navigator.gpu) {
|
|
1974
3493
|
throw new Error("WebGPU not available. Recent Chrome browsers should work.");
|
|
1975
3494
|
}
|
|
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
|
-
}
|
|
3495
|
+
const adapter = await navigator.gpu.requestAdapter({
|
|
3496
|
+
powerPreference: "high-performance"
|
|
3497
|
+
// forceSoftware: false
|
|
3498
|
+
});
|
|
3499
|
+
if (!adapter) {
|
|
3500
|
+
throw new Error("Failed to request WebGPU adapter");
|
|
3501
|
+
}
|
|
3502
|
+
const adapterInfo = adapter.info || // @ts-ignore
|
|
3503
|
+
await ((_a = adapter.requestAdapterInfo) == null ? void 0 : _a.call(adapter));
|
|
3504
|
+
const requiredFeatures = [];
|
|
3505
|
+
const requiredLimits = {};
|
|
3506
|
+
if (props._requestMaxLimits) {
|
|
3507
|
+
requiredFeatures.push(...Array.from(adapter.features));
|
|
3508
|
+
const limits = Object.keys(adapter.limits).filter((key) => !["minSubgroupSize", "maxSubgroupSize"].includes(key));
|
|
3509
|
+
for (const key of limits) {
|
|
3510
|
+
const limit = key;
|
|
3511
|
+
const value = adapter.limits[limit];
|
|
3512
|
+
if (typeof value === "number") {
|
|
3513
|
+
requiredLimits[limit] = value;
|
|
1999
3514
|
}
|
|
2000
3515
|
}
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
3516
|
+
}
|
|
3517
|
+
const gpuDevice = await adapter.requestDevice({
|
|
3518
|
+
requiredFeatures,
|
|
3519
|
+
requiredLimits
|
|
3520
|
+
});
|
|
3521
|
+
const { WebGPUDevice: WebGPUDevice2 } = await Promise.resolve().then(() => (init_webgpu_device(), webgpu_device_exports));
|
|
3522
|
+
import_core26.log.groupCollapsed(1, "WebGPUDevice created")();
|
|
3523
|
+
try {
|
|
2007
3524
|
const device = new WebGPUDevice2(props, gpuDevice, adapter, adapterInfo);
|
|
2008
|
-
|
|
2009
|
-
|
|
3525
|
+
import_core26.log.probe(1, "Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")();
|
|
3526
|
+
import_core26.log.table(1, device.info)();
|
|
2010
3527
|
return device;
|
|
2011
3528
|
} finally {
|
|
2012
|
-
|
|
3529
|
+
import_core26.log.groupEnd(1)();
|
|
2013
3530
|
}
|
|
2014
3531
|
}
|
|
2015
3532
|
async attach(handle) {
|
|
@@ -2024,4 +3541,6 @@ init_webgpu_buffer();
|
|
|
2024
3541
|
init_webgpu_texture();
|
|
2025
3542
|
init_webgpu_sampler();
|
|
2026
3543
|
init_webgpu_shader();
|
|
3544
|
+
init_webgpu_fence();
|
|
3545
|
+
init_get_shader_layout_wgsl();
|
|
2027
3546
|
//# sourceMappingURL=index.cjs.map
|