@luma.gl/webgpu 9.2.6 → 9.3.0-alpha.4
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/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +11 -5
- package/dist/adapter/helpers/get-bind-group.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 +39 -12
- package/dist/adapter/resources/webgpu-buffer.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 +25 -0
- package/dist/adapter/resources/webgpu-fence.js.map +1 -0
- package/dist/adapter/resources/webgpu-pipeline-layout.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-pipeline-layout.js +1 -2
- package/dist/adapter/resources/webgpu-pipeline-layout.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture.d.ts +12 -3
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +143 -26
- package/dist/adapter/resources/webgpu-texture.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 +4 -3
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +22 -21
- package/dist/adapter/webgpu-canvas-context.js.map +1 -1
- package/dist/adapter/webgpu-device.d.ts +3 -1
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +14 -3
- package/dist/adapter/webgpu-device.js.map +1 -1
- package/dist/dist.dev.js +6485 -293
- package/dist/dist.min.js +10 -6
- package/dist/index.cjs +398 -114
- 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 +136 -0
- package/dist/wgsl/get-shader-layout-wgsl.js.map +1 -0
- package/package.json +6 -5
- package/src/adapter/helpers/get-bind-group.ts +18 -5
- package/src/adapter/resources/webgpu-buffer.ts +43 -12
- package/src/adapter/resources/webgpu-fence.ts +30 -0
- package/src/adapter/resources/webgpu-pipeline-layout.ts +1 -2
- package/src/adapter/resources/webgpu-texture.ts +202 -88
- package/src/adapter/webgpu-adapter.ts +40 -42
- package/src/adapter/webgpu-canvas-context.ts +25 -23
- package/src/adapter/webgpu-device.ts +19 -4
- package/src/index.ts +3 -0
- package/src/wgsl/get-shader-layout-wgsl.ts +156 -0
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({
|
|
@@ -89,18 +91,21 @@ var init_webgpu_buffer = __esm({
|
|
|
89
91
|
});
|
|
90
92
|
}
|
|
91
93
|
async mapAndWriteAsync(callback, byteOffset = 0, byteLength = this.byteLength - byteOffset) {
|
|
94
|
+
const alignedByteLength = Math.ceil(byteLength / 4) * 4;
|
|
92
95
|
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.
|
|
96
|
+
const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_WRITE | import_core.Buffer.COPY_SRC, 0, this.paddedByteLength) : null;
|
|
94
97
|
const writeBuffer = mappableBuffer || this;
|
|
95
98
|
this.device.pushErrorScope("validation");
|
|
96
99
|
try {
|
|
97
100
|
await this.device.handle.queue.onSubmittedWorkDone();
|
|
98
|
-
await writeBuffer.handle.mapAsync(GPUMapMode.WRITE, byteOffset,
|
|
99
|
-
const
|
|
101
|
+
await writeBuffer.handle.mapAsync(GPUMapMode.WRITE, byteOffset, alignedByteLength);
|
|
102
|
+
const mappedRange = writeBuffer.handle.getMappedRange(byteOffset, alignedByteLength);
|
|
103
|
+
const arrayBuffer = mappedRange.slice(0, byteLength);
|
|
100
104
|
await callback(arrayBuffer, "mapped");
|
|
105
|
+
new Uint8Array(mappedRange).set(new Uint8Array(arrayBuffer), 0);
|
|
101
106
|
writeBuffer.handle.unmap();
|
|
102
107
|
if (mappableBuffer) {
|
|
103
|
-
this._copyBuffer(mappableBuffer, byteOffset,
|
|
108
|
+
this._copyBuffer(mappableBuffer, byteOffset, alignedByteLength);
|
|
104
109
|
}
|
|
105
110
|
} finally {
|
|
106
111
|
this.device.popErrorScope((error) => {
|
|
@@ -114,24 +119,37 @@ var init_webgpu_buffer = __esm({
|
|
|
114
119
|
return this.mapAndReadAsync((arrayBuffer) => new Uint8Array(arrayBuffer.slice(0)), byteOffset, byteLength);
|
|
115
120
|
}
|
|
116
121
|
async mapAndReadAsync(callback, byteOffset = 0, byteLength = this.byteLength - byteOffset) {
|
|
122
|
+
const requestedEnd = byteOffset + byteLength;
|
|
123
|
+
if (requestedEnd > this.byteLength) {
|
|
124
|
+
throw new Error("Mapping range exceeds buffer size");
|
|
125
|
+
}
|
|
126
|
+
let mappedByteOffset = byteOffset;
|
|
127
|
+
let mappedByteLength = byteLength;
|
|
128
|
+
let sliceByteOffset = 0;
|
|
129
|
+
let lifetime = "mapped";
|
|
117
130
|
if (byteOffset % 8 !== 0 || byteLength % 4 !== 0) {
|
|
118
|
-
|
|
131
|
+
mappedByteOffset = Math.floor(byteOffset / 8) * 8;
|
|
132
|
+
const alignedEnd = Math.ceil(requestedEnd / 4) * 4;
|
|
133
|
+
mappedByteLength = alignedEnd - mappedByteOffset;
|
|
134
|
+
sliceByteOffset = byteOffset - mappedByteOffset;
|
|
135
|
+
lifetime = "copied";
|
|
119
136
|
}
|
|
120
|
-
if (
|
|
137
|
+
if (mappedByteOffset + mappedByteLength > this.paddedByteLength) {
|
|
121
138
|
throw new Error("Mapping range exceeds buffer size");
|
|
122
139
|
}
|
|
123
140
|
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.
|
|
141
|
+
const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_READ | import_core.Buffer.COPY_DST, 0, this.paddedByteLength) : null;
|
|
125
142
|
const readBuffer = mappableBuffer || this;
|
|
126
143
|
this.device.pushErrorScope("validation");
|
|
127
144
|
try {
|
|
128
145
|
await this.device.handle.queue.onSubmittedWorkDone();
|
|
129
146
|
if (mappableBuffer) {
|
|
130
|
-
mappableBuffer._copyBuffer(this);
|
|
147
|
+
mappableBuffer._copyBuffer(this, mappedByteOffset, mappedByteLength);
|
|
131
148
|
}
|
|
132
|
-
await readBuffer.handle.mapAsync(GPUMapMode.READ,
|
|
133
|
-
const arrayBuffer = readBuffer.handle.getMappedRange(
|
|
134
|
-
const
|
|
149
|
+
await readBuffer.handle.mapAsync(GPUMapMode.READ, mappedByteOffset, mappedByteLength);
|
|
150
|
+
const arrayBuffer = readBuffer.handle.getMappedRange(mappedByteOffset, mappedByteLength);
|
|
151
|
+
const mappedRange = lifetime === "mapped" ? arrayBuffer : arrayBuffer.slice(sliceByteOffset, sliceByteOffset + byteLength);
|
|
152
|
+
const result = await callback(mappedRange, lifetime);
|
|
135
153
|
readBuffer.handle.unmap();
|
|
136
154
|
return result;
|
|
137
155
|
} finally {
|
|
@@ -267,11 +285,8 @@ var init_webgpu_texture = __esm({
|
|
|
267
285
|
sampler;
|
|
268
286
|
view;
|
|
269
287
|
constructor(device, props) {
|
|
270
|
-
super(device, props);
|
|
288
|
+
super(device, props, { byteAlignment: 256 });
|
|
271
289
|
this.device = device;
|
|
272
|
-
if (this.dimension === "cube") {
|
|
273
|
-
this.depth = 6;
|
|
274
|
-
}
|
|
275
290
|
this.device.pushErrorScope("out-of-memory");
|
|
276
291
|
this.device.pushErrorScope("validation");
|
|
277
292
|
this.handle = this.props.handle || this.device.handle.createTexture({
|
|
@@ -318,6 +333,36 @@ var init_webgpu_texture = __esm({
|
|
|
318
333
|
createView(props) {
|
|
319
334
|
return new WebGPUTextureView(this.device, { ...props, texture: this });
|
|
320
335
|
}
|
|
336
|
+
copyExternalImage(options_) {
|
|
337
|
+
const options = this._normalizeCopyExternalImageOptions(options_);
|
|
338
|
+
this.device.pushErrorScope("validation");
|
|
339
|
+
this.device.handle.queue.copyExternalImageToTexture(
|
|
340
|
+
// source: GPUImageCopyExternalImage
|
|
341
|
+
{
|
|
342
|
+
source: options.image,
|
|
343
|
+
origin: [options.sourceX, options.sourceY],
|
|
344
|
+
flipY: false
|
|
345
|
+
// options.flipY
|
|
346
|
+
},
|
|
347
|
+
// destination: GPUImageCopyTextureTagged
|
|
348
|
+
{
|
|
349
|
+
texture: this.handle,
|
|
350
|
+
origin: [options.x, options.y, options.z],
|
|
351
|
+
mipLevel: options.mipLevel,
|
|
352
|
+
aspect: options.aspect,
|
|
353
|
+
colorSpace: options.colorSpace,
|
|
354
|
+
premultipliedAlpha: options.premultipliedAlpha
|
|
355
|
+
},
|
|
356
|
+
// copySize: GPUExtent3D
|
|
357
|
+
[options.width, options.height, options.depth]
|
|
358
|
+
// depth is always 1 for 2D textures
|
|
359
|
+
);
|
|
360
|
+
this.device.popErrorScope((error) => {
|
|
361
|
+
this.device.reportError(new Error(`copyExternalImage: ${error.message}`), this)();
|
|
362
|
+
this.device.debug();
|
|
363
|
+
});
|
|
364
|
+
return { width: options.width, height: options.height };
|
|
365
|
+
}
|
|
321
366
|
copyImageData(options_) {
|
|
322
367
|
const { width, height, depth } = this;
|
|
323
368
|
const options = this._normalizeCopyImageDataOptions(options_);
|
|
@@ -348,37 +393,118 @@ var init_webgpu_texture = __esm({
|
|
|
348
393
|
this.device.debug();
|
|
349
394
|
});
|
|
350
395
|
}
|
|
351
|
-
|
|
352
|
-
|
|
396
|
+
generateMipmapsWebGL() {
|
|
397
|
+
import_core4.log.warn(`${this}: generateMipmaps not supported in WebGPU`)();
|
|
398
|
+
}
|
|
399
|
+
getImageDataLayout(options) {
|
|
400
|
+
return {
|
|
401
|
+
byteLength: 0,
|
|
402
|
+
bytesPerRow: 0,
|
|
403
|
+
rowsPerImage: 0
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
readBuffer(options = {}, buffer) {
|
|
407
|
+
const { x = 0, y = 0, z = 0, width = this.width, height = this.height, depthOrArrayLayers = this.depth, mipLevel = 0, aspect = "all" } = options;
|
|
408
|
+
const layout = this.computeMemoryLayout(options);
|
|
409
|
+
const { bytesPerRow, rowsPerImage, byteLength } = layout;
|
|
410
|
+
const readBuffer = buffer || this.device.createBuffer({
|
|
411
|
+
byteLength,
|
|
412
|
+
usage: import_core4.Buffer.COPY_DST | import_core4.Buffer.MAP_READ
|
|
413
|
+
});
|
|
414
|
+
const gpuReadBuffer = readBuffer.handle;
|
|
415
|
+
const gpuDevice = this.device.handle;
|
|
353
416
|
this.device.pushErrorScope("validation");
|
|
354
|
-
|
|
355
|
-
|
|
417
|
+
const commandEncoder = gpuDevice.createCommandEncoder();
|
|
418
|
+
commandEncoder.copyTextureToBuffer(
|
|
419
|
+
// source
|
|
356
420
|
{
|
|
357
|
-
|
|
358
|
-
origin:
|
|
359
|
-
|
|
421
|
+
texture: this.handle,
|
|
422
|
+
origin: { x, y, z },
|
|
423
|
+
// origin: [options.x, options.y, 0], // options.depth],
|
|
424
|
+
mipLevel,
|
|
425
|
+
aspect
|
|
426
|
+
// colorSpace: options.colorSpace,
|
|
427
|
+
// premultipliedAlpha: options.premultipliedAlpha
|
|
360
428
|
},
|
|
361
|
-
// destination
|
|
429
|
+
// destination
|
|
362
430
|
{
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
aspect: options.aspect,
|
|
368
|
-
colorSpace: options.colorSpace,
|
|
369
|
-
premultipliedAlpha: options.premultipliedAlpha
|
|
431
|
+
buffer: gpuReadBuffer,
|
|
432
|
+
offset: 0,
|
|
433
|
+
bytesPerRow,
|
|
434
|
+
rowsPerImage
|
|
370
435
|
},
|
|
371
|
-
//
|
|
372
|
-
|
|
436
|
+
// copy size
|
|
437
|
+
{
|
|
438
|
+
width,
|
|
439
|
+
height,
|
|
440
|
+
depthOrArrayLayers
|
|
441
|
+
}
|
|
373
442
|
);
|
|
443
|
+
const commandBuffer = commandEncoder.finish();
|
|
444
|
+
this.device.handle.queue.submit([commandBuffer]);
|
|
374
445
|
this.device.popErrorScope((error) => {
|
|
375
|
-
this.device.reportError(new Error(
|
|
446
|
+
this.device.reportError(new Error(`${this} readBuffer: ${error.message}`), this)();
|
|
447
|
+
this.device.debug();
|
|
448
|
+
});
|
|
449
|
+
return readBuffer;
|
|
450
|
+
}
|
|
451
|
+
async readDataAsync(options = {}) {
|
|
452
|
+
const buffer = this.readBuffer(options);
|
|
453
|
+
const data = await buffer.readAsync();
|
|
454
|
+
buffer.destroy();
|
|
455
|
+
return data.buffer;
|
|
456
|
+
}
|
|
457
|
+
writeBuffer(buffer, options = {}) {
|
|
458
|
+
const { x = 0, y = 0, z = 0, width = this.width, height = this.height, depthOrArrayLayers = this.depth, mipLevel = 0, aspect = "all" } = options;
|
|
459
|
+
const layout = this.computeMemoryLayout(options);
|
|
460
|
+
const { bytesPerRow, rowsPerImage } = layout;
|
|
461
|
+
const gpuDevice = this.device.handle;
|
|
462
|
+
this.device.pushErrorScope("validation");
|
|
463
|
+
const commandEncoder = gpuDevice.createCommandEncoder();
|
|
464
|
+
commandEncoder.copyBufferToTexture({
|
|
465
|
+
buffer: buffer.handle,
|
|
466
|
+
offset: 0,
|
|
467
|
+
bytesPerRow,
|
|
468
|
+
rowsPerImage
|
|
469
|
+
}, {
|
|
470
|
+
texture: this.handle,
|
|
471
|
+
origin: { x, y, z },
|
|
472
|
+
mipLevel,
|
|
473
|
+
aspect
|
|
474
|
+
}, { width, height, depthOrArrayLayers });
|
|
475
|
+
const commandBuffer = commandEncoder.finish();
|
|
476
|
+
this.device.handle.queue.submit([commandBuffer]);
|
|
477
|
+
this.device.popErrorScope((error) => {
|
|
478
|
+
this.device.reportError(new Error(`${this} writeBuffer: ${error.message}`), this)();
|
|
376
479
|
this.device.debug();
|
|
377
480
|
});
|
|
378
|
-
return { width: options.width, height: options.height };
|
|
379
481
|
}
|
|
380
|
-
|
|
381
|
-
|
|
482
|
+
writeData(data, options = {}) {
|
|
483
|
+
const device = this.device;
|
|
484
|
+
const { x = 0, y = 0, z = 0, width = this.width, height = this.height, depthOrArrayLayers = this.depth, mipLevel = 0, aspect = "all" } = options;
|
|
485
|
+
const layout = import_core4.textureFormatDecoder.computeMemoryLayout({
|
|
486
|
+
format: this.format,
|
|
487
|
+
width: this.width,
|
|
488
|
+
height: this.height,
|
|
489
|
+
depth: this.depth,
|
|
490
|
+
byteAlignment: this.byteAlignment
|
|
491
|
+
});
|
|
492
|
+
const { bytesPerRow, rowsPerImage } = layout;
|
|
493
|
+
this.device.pushErrorScope("validation");
|
|
494
|
+
device.handle.queue.writeTexture({
|
|
495
|
+
texture: this.handle,
|
|
496
|
+
mipLevel,
|
|
497
|
+
aspect,
|
|
498
|
+
origin: { x, y, z }
|
|
499
|
+
}, data, {
|
|
500
|
+
offset: 0,
|
|
501
|
+
bytesPerRow,
|
|
502
|
+
rowsPerImage
|
|
503
|
+
}, { width, height, depthOrArrayLayers });
|
|
504
|
+
this.device.popErrorScope((error) => {
|
|
505
|
+
this.device.reportError(new Error(`${this} writeData: ${error.message}`), this)();
|
|
506
|
+
this.device.debug();
|
|
507
|
+
});
|
|
382
508
|
}
|
|
383
509
|
};
|
|
384
510
|
}
|
|
@@ -716,7 +842,7 @@ function getBindGroupEntries(bindings, shaderLayout) {
|
|
|
716
842
|
for (const [bindingName, value] of Object.entries(bindings)) {
|
|
717
843
|
let bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
|
|
718
844
|
if (bindingLayout) {
|
|
719
|
-
const entry = getBindGroupEntry(value, bindingLayout.location);
|
|
845
|
+
const entry = getBindGroupEntry(value, bindingLayout.location, void 0, bindingName);
|
|
720
846
|
if (entry) {
|
|
721
847
|
entries.push(entry);
|
|
722
848
|
}
|
|
@@ -726,7 +852,7 @@ function getBindGroupEntries(bindings, shaderLayout) {
|
|
|
726
852
|
ignoreWarnings: true
|
|
727
853
|
});
|
|
728
854
|
if (bindingLayout) {
|
|
729
|
-
const entry = getBindGroupEntry(value, bindingLayout.location, { sampler: true });
|
|
855
|
+
const entry = getBindGroupEntry(value, bindingLayout.location, { sampler: true }, bindingName);
|
|
730
856
|
if (entry) {
|
|
731
857
|
entries.push(entry);
|
|
732
858
|
}
|
|
@@ -735,7 +861,7 @@ function getBindGroupEntries(bindings, shaderLayout) {
|
|
|
735
861
|
}
|
|
736
862
|
return entries;
|
|
737
863
|
}
|
|
738
|
-
function getBindGroupEntry(binding, index, options) {
|
|
864
|
+
function getBindGroupEntry(binding, index, options, bindingName = "unknown") {
|
|
739
865
|
if (binding instanceof import_core8.Buffer) {
|
|
740
866
|
return {
|
|
741
867
|
binding: index,
|
|
@@ -750,6 +876,12 @@ function getBindGroupEntry(binding, index, options) {
|
|
|
750
876
|
resource: binding.handle
|
|
751
877
|
};
|
|
752
878
|
}
|
|
879
|
+
if (binding instanceof import_core8.TextureView) {
|
|
880
|
+
return {
|
|
881
|
+
binding: index,
|
|
882
|
+
resource: binding.handle
|
|
883
|
+
};
|
|
884
|
+
}
|
|
753
885
|
if (binding instanceof import_core8.Texture) {
|
|
754
886
|
if (options == null ? void 0 : options.sampler) {
|
|
755
887
|
return {
|
|
@@ -762,7 +894,7 @@ function getBindGroupEntry(binding, index, options) {
|
|
|
762
894
|
resource: binding.view.handle
|
|
763
895
|
};
|
|
764
896
|
}
|
|
765
|
-
import_core8.log.warn(`invalid binding ${
|
|
897
|
+
import_core8.log.warn(`invalid binding ${bindingName}`, binding);
|
|
766
898
|
return null;
|
|
767
899
|
}
|
|
768
900
|
var import_core8;
|
|
@@ -844,17 +976,17 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
|
|
|
844
976
|
});
|
|
845
977
|
return vertexBufferLayouts;
|
|
846
978
|
}
|
|
847
|
-
function findAttributeLayout(shaderLayout,
|
|
848
|
-
const attribute = shaderLayout.attributes.find((attribute_) => attribute_.name ===
|
|
979
|
+
function findAttributeLayout(shaderLayout, name, attributeNames) {
|
|
980
|
+
const attribute = shaderLayout.attributes.find((attribute_) => attribute_.name === name);
|
|
849
981
|
if (!attribute) {
|
|
850
|
-
import_core9.log.warn(`Supplied attribute not present in shader layout: ${
|
|
982
|
+
import_core9.log.warn(`Supplied attribute not present in shader layout: ${name}`)();
|
|
851
983
|
return null;
|
|
852
984
|
}
|
|
853
985
|
if (attributeNames) {
|
|
854
|
-
if (attributeNames.has(
|
|
855
|
-
throw new Error(`Found multiple entries for attribute: ${
|
|
986
|
+
if (attributeNames.has(name)) {
|
|
987
|
+
throw new Error(`Found multiple entries for attribute: ${name}`);
|
|
856
988
|
}
|
|
857
|
-
attributeNames.add(
|
|
989
|
+
attributeNames.add(name);
|
|
858
990
|
}
|
|
859
991
|
return attribute;
|
|
860
992
|
}
|
|
@@ -918,8 +1050,8 @@ var init_webgpu_render_pipeline = __esm({
|
|
|
918
1050
|
* @todo Do we want to expose BindGroups in the API and remove this?
|
|
919
1051
|
*/
|
|
920
1052
|
setBindings(bindings) {
|
|
921
|
-
for (const [
|
|
922
|
-
if (this._bindings[
|
|
1053
|
+
for (const [name, binding] of Object.entries(bindings)) {
|
|
1054
|
+
if (this._bindings[name] !== binding) {
|
|
923
1055
|
this._bindGroup = null;
|
|
924
1056
|
}
|
|
925
1057
|
}
|
|
@@ -1164,18 +1296,34 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1164
1296
|
this.device = device;
|
|
1165
1297
|
this.handle = context;
|
|
1166
1298
|
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
|
|
1167
|
-
this.
|
|
1299
|
+
this._configureDevice();
|
|
1168
1300
|
}
|
|
1169
1301
|
/** Destroy any textures produced while configured and remove the context configuration. */
|
|
1170
1302
|
destroy() {
|
|
1171
1303
|
this.handle.unconfigure();
|
|
1172
1304
|
super.destroy();
|
|
1173
1305
|
}
|
|
1306
|
+
// IMPLEMENTATION OF ABSTRACT METHODS
|
|
1307
|
+
/** @see https://www.w3.org/TR/webgpu/#canvas-configuration */
|
|
1308
|
+
_configureDevice() {
|
|
1309
|
+
if (this.depthStencilAttachment) {
|
|
1310
|
+
this.depthStencilAttachment.destroy();
|
|
1311
|
+
this.depthStencilAttachment = null;
|
|
1312
|
+
}
|
|
1313
|
+
this.handle.configure({
|
|
1314
|
+
device: this.device.handle,
|
|
1315
|
+
format: this.device.preferredColorFormat,
|
|
1316
|
+
// Can be used to define e.g. -srgb views
|
|
1317
|
+
// viewFormats: [...]
|
|
1318
|
+
colorSpace: this.props.colorSpace,
|
|
1319
|
+
alphaMode: this.props.alphaMode
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1174
1322
|
/** Update framebuffer with properly resized "swap chain" texture views */
|
|
1175
|
-
|
|
1323
|
+
_getCurrentFramebuffer(options = {
|
|
1176
1324
|
depthStencilFormat: "depth24plus"
|
|
1177
1325
|
}) {
|
|
1178
|
-
const currentColorAttachment = this.
|
|
1326
|
+
const currentColorAttachment = this._getCurrentTexture();
|
|
1179
1327
|
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
|
|
1180
1328
|
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
1181
1329
|
this.drawingBufferWidth = currentColorAttachment.width;
|
|
@@ -1190,23 +1338,9 @@ var init_webgpu_canvas_context = __esm({
|
|
|
1190
1338
|
depthStencilAttachment: this.depthStencilAttachment
|
|
1191
1339
|
});
|
|
1192
1340
|
}
|
|
1193
|
-
//
|
|
1194
|
-
_updateDevice() {
|
|
1195
|
-
if (this.depthStencilAttachment) {
|
|
1196
|
-
this.depthStencilAttachment.destroy();
|
|
1197
|
-
this.depthStencilAttachment = null;
|
|
1198
|
-
}
|
|
1199
|
-
this.handle.configure({
|
|
1200
|
-
device: this.device.handle,
|
|
1201
|
-
format: this.device.preferredColorFormat,
|
|
1202
|
-
// Can be used to define e.g. -srgb views
|
|
1203
|
-
// viewFormats: [...]
|
|
1204
|
-
colorSpace: this.props.colorSpace,
|
|
1205
|
-
alphaMode: this.props.alphaMode
|
|
1206
|
-
});
|
|
1207
|
-
}
|
|
1341
|
+
// PRIMARY METHODS
|
|
1208
1342
|
/** Wrap the current canvas context texture in a luma.gl texture */
|
|
1209
|
-
|
|
1343
|
+
_getCurrentTexture() {
|
|
1210
1344
|
const handle = this.handle.getCurrentTexture();
|
|
1211
1345
|
return this.device.createTexture({
|
|
1212
1346
|
id: `${this.id}#color-texture`,
|
|
@@ -1653,8 +1787,7 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1653
1787
|
}
|
|
1654
1788
|
mapShaderLayoutToBindGroupEntries() {
|
|
1655
1789
|
const bindGroupEntries = [];
|
|
1656
|
-
for (
|
|
1657
|
-
const binding = this.props.shaderLayout.bindings[i];
|
|
1790
|
+
for (const binding of this.props.shaderLayout.bindings) {
|
|
1658
1791
|
const bindingTypeInfo = {};
|
|
1659
1792
|
switch (binding.type) {
|
|
1660
1793
|
case "uniform": {
|
|
@@ -1725,16 +1858,154 @@ var init_webgpu_pipeline_layout = __esm({
|
|
|
1725
1858
|
}
|
|
1726
1859
|
});
|
|
1727
1860
|
|
|
1861
|
+
// dist/adapter/resources/webgpu-fence.js
|
|
1862
|
+
var import_core21, WebGPUFence;
|
|
1863
|
+
var init_webgpu_fence = __esm({
|
|
1864
|
+
"dist/adapter/resources/webgpu-fence.js"() {
|
|
1865
|
+
"use strict";
|
|
1866
|
+
import_core21 = require("@luma.gl/core");
|
|
1867
|
+
WebGPUFence = class extends import_core21.Fence {
|
|
1868
|
+
device;
|
|
1869
|
+
handle = null;
|
|
1870
|
+
signaled;
|
|
1871
|
+
_signaled = false;
|
|
1872
|
+
constructor(device, props = {}) {
|
|
1873
|
+
super(device, {});
|
|
1874
|
+
this.device = device;
|
|
1875
|
+
this.signaled = device.handle.queue.onSubmittedWorkDone().then(() => {
|
|
1876
|
+
this._signaled = true;
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
isSignaled() {
|
|
1880
|
+
return this._signaled;
|
|
1881
|
+
}
|
|
1882
|
+
destroy() {
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
}
|
|
1886
|
+
});
|
|
1887
|
+
|
|
1888
|
+
// dist/wgsl/get-shader-layout-wgsl.js
|
|
1889
|
+
function getShaderLayoutFromWGSL(source) {
|
|
1890
|
+
var _a;
|
|
1891
|
+
const shaderLayout = { attributes: [], bindings: [] };
|
|
1892
|
+
let parsedWGSL;
|
|
1893
|
+
try {
|
|
1894
|
+
parsedWGSL = parseWGSL(source);
|
|
1895
|
+
} catch (error) {
|
|
1896
|
+
import_core22.log.error(error.message)();
|
|
1897
|
+
return shaderLayout;
|
|
1898
|
+
}
|
|
1899
|
+
for (const uniform of parsedWGSL.uniforms) {
|
|
1900
|
+
const members = [];
|
|
1901
|
+
for (const attribute of ((_a = uniform.type) == null ? void 0 : _a.members) || []) {
|
|
1902
|
+
members.push({
|
|
1903
|
+
name: attribute.name,
|
|
1904
|
+
type: getType(attribute.type)
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
shaderLayout.bindings.push({
|
|
1908
|
+
type: "uniform",
|
|
1909
|
+
name: uniform.name,
|
|
1910
|
+
group: uniform.group,
|
|
1911
|
+
location: uniform.binding,
|
|
1912
|
+
// @ts-expect-error TODO - unused for now but needs fixing
|
|
1913
|
+
members
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1916
|
+
for (const texture of parsedWGSL.textures) {
|
|
1917
|
+
const bindingDeclaration = {
|
|
1918
|
+
type: "texture",
|
|
1919
|
+
name: texture.name,
|
|
1920
|
+
group: texture.group,
|
|
1921
|
+
location: texture.binding,
|
|
1922
|
+
...getTextureBindingFromReflect(texture)
|
|
1923
|
+
};
|
|
1924
|
+
shaderLayout.bindings.push(bindingDeclaration);
|
|
1925
|
+
}
|
|
1926
|
+
for (const sampler of parsedWGSL.samplers) {
|
|
1927
|
+
shaderLayout.bindings.push({
|
|
1928
|
+
type: "sampler",
|
|
1929
|
+
name: sampler.name,
|
|
1930
|
+
group: sampler.group,
|
|
1931
|
+
location: sampler.binding
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
const vertex = parsedWGSL.entry.vertex[0];
|
|
1935
|
+
const attributeCount = (vertex == null ? void 0 : vertex.inputs.length) || 0;
|
|
1936
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
1937
|
+
const wgslAttribute = vertex.inputs[i];
|
|
1938
|
+
if (wgslAttribute.locationType === "location") {
|
|
1939
|
+
const type = getType(wgslAttribute.type);
|
|
1940
|
+
shaderLayout.attributes.push({
|
|
1941
|
+
name: wgslAttribute.name,
|
|
1942
|
+
location: Number(wgslAttribute.location),
|
|
1943
|
+
type
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
return shaderLayout;
|
|
1948
|
+
}
|
|
1949
|
+
function getType(type) {
|
|
1950
|
+
return (type == null ? void 0 : type.format) ? `${type.name}<${type.format.name}>` : type.name;
|
|
1951
|
+
}
|
|
1952
|
+
function parseWGSL(source) {
|
|
1953
|
+
try {
|
|
1954
|
+
return new import_wgsl_reflect.WgslReflect(source);
|
|
1955
|
+
} catch (error) {
|
|
1956
|
+
if (error instanceof Error) {
|
|
1957
|
+
throw error;
|
|
1958
|
+
}
|
|
1959
|
+
let message = "WGSL parse error";
|
|
1960
|
+
if (typeof error === "object" && (error == null ? void 0 : error.message)) {
|
|
1961
|
+
message += `: ${error.message} `;
|
|
1962
|
+
}
|
|
1963
|
+
if (typeof error === "object" && (error == null ? void 0 : error.token)) {
|
|
1964
|
+
message += error.token.line || "";
|
|
1965
|
+
}
|
|
1966
|
+
throw new Error(message, { cause: error });
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
function getTextureBindingFromReflect(v, opts) {
|
|
1970
|
+
var _a;
|
|
1971
|
+
if (v.resourceType !== import_wgsl_reflect.ResourceType.Texture) {
|
|
1972
|
+
throw new Error("Not a texture binding");
|
|
1973
|
+
}
|
|
1974
|
+
const typeName = v.type.name;
|
|
1975
|
+
const component = (_a = v.type.format) == null ? void 0 : _a.name;
|
|
1976
|
+
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";
|
|
1977
|
+
const multisampled = typeName === "texture_multisampled_2d";
|
|
1978
|
+
let sampleType;
|
|
1979
|
+
if (typeName.startsWith("texture_depth")) {
|
|
1980
|
+
sampleType = "depth";
|
|
1981
|
+
} else if (component === "i32") {
|
|
1982
|
+
sampleType = "sint";
|
|
1983
|
+
} else if (component === "u32") {
|
|
1984
|
+
sampleType = "uint";
|
|
1985
|
+
} else {
|
|
1986
|
+
sampleType = "float";
|
|
1987
|
+
}
|
|
1988
|
+
return { viewDimension, sampleType, multisampled };
|
|
1989
|
+
}
|
|
1990
|
+
var import_core22, import_wgsl_reflect;
|
|
1991
|
+
var init_get_shader_layout_wgsl = __esm({
|
|
1992
|
+
"dist/wgsl/get-shader-layout-wgsl.js"() {
|
|
1993
|
+
"use strict";
|
|
1994
|
+
import_core22 = require("@luma.gl/core");
|
|
1995
|
+
import_wgsl_reflect = require("wgsl_reflect");
|
|
1996
|
+
}
|
|
1997
|
+
});
|
|
1998
|
+
|
|
1728
1999
|
// dist/adapter/webgpu-device.js
|
|
1729
2000
|
var webgpu_device_exports = {};
|
|
1730
2001
|
__export(webgpu_device_exports, {
|
|
1731
2002
|
WebGPUDevice: () => WebGPUDevice
|
|
1732
2003
|
});
|
|
1733
|
-
var
|
|
2004
|
+
var import_core23, WebGPUDevice;
|
|
1734
2005
|
var init_webgpu_device = __esm({
|
|
1735
2006
|
"dist/adapter/webgpu-device.js"() {
|
|
1736
2007
|
"use strict";
|
|
1737
|
-
|
|
2008
|
+
import_core23 = require("@luma.gl/core");
|
|
1738
2009
|
init_webgpu_buffer();
|
|
1739
2010
|
init_webgpu_texture();
|
|
1740
2011
|
init_webgpu_external_texture();
|
|
@@ -1748,7 +2019,9 @@ var init_webgpu_device = __esm({
|
|
|
1748
2019
|
init_webgpu_command_encoder();
|
|
1749
2020
|
init_webgpu_query_set();
|
|
1750
2021
|
init_webgpu_pipeline_layout();
|
|
1751
|
-
|
|
2022
|
+
init_webgpu_fence();
|
|
2023
|
+
init_get_shader_layout_wgsl();
|
|
2024
|
+
WebGPUDevice = class extends import_core23.Device {
|
|
1752
2025
|
/** The underlying WebGPU device */
|
|
1753
2026
|
handle;
|
|
1754
2027
|
/* The underlying WebGPU adapter */
|
|
@@ -1791,7 +2064,7 @@ var init_webgpu_device = __esm({
|
|
|
1791
2064
|
this._isLost = true;
|
|
1792
2065
|
resolve({ reason: "destroyed", message: lostInfo.message });
|
|
1793
2066
|
});
|
|
1794
|
-
const canvasContextProps =
|
|
2067
|
+
const canvasContextProps = import_core23.Device._getCanvasContextProps(props);
|
|
1795
2068
|
if (canvasContextProps) {
|
|
1796
2069
|
this.canvasContext = new WebGPUCanvasContext(this, this.adapter, canvasContextProps);
|
|
1797
2070
|
}
|
|
@@ -1807,13 +2080,13 @@ var init_webgpu_device = __esm({
|
|
|
1807
2080
|
get isLost() {
|
|
1808
2081
|
return this._isLost;
|
|
1809
2082
|
}
|
|
2083
|
+
getShaderLayout(source) {
|
|
2084
|
+
return getShaderLayoutFromWGSL(source);
|
|
2085
|
+
}
|
|
1810
2086
|
isVertexFormatSupported(format) {
|
|
1811
2087
|
const info = this.getVertexFormatInfo(format);
|
|
1812
2088
|
return !info.webglOnly;
|
|
1813
2089
|
}
|
|
1814
|
-
getTextureByteAlignment() {
|
|
1815
|
-
return 1;
|
|
1816
|
-
}
|
|
1817
2090
|
createBuffer(props) {
|
|
1818
2091
|
const newProps = this._normalizeBufferProps(props);
|
|
1819
2092
|
return new WebGPUBuffer(this, newProps);
|
|
@@ -1852,6 +2125,9 @@ var init_webgpu_device = __esm({
|
|
|
1852
2125
|
createQuerySet(props) {
|
|
1853
2126
|
return new WebGPUQuerySet(this, props);
|
|
1854
2127
|
}
|
|
2128
|
+
createFence() {
|
|
2129
|
+
return new WebGPUFence(this);
|
|
2130
|
+
}
|
|
1855
2131
|
createCanvasContext(props) {
|
|
1856
2132
|
return new WebGPUCanvasContext(this, this.adapter, props);
|
|
1857
2133
|
}
|
|
@@ -1914,6 +2190,12 @@ var init_webgpu_device = __esm({
|
|
|
1914
2190
|
if (features.has("texture-compression-bc")) {
|
|
1915
2191
|
features.add("texture-compression-bc5-webgl");
|
|
1916
2192
|
}
|
|
2193
|
+
if (this.handle.features.has("chromium-experimental-norm16-texture-formats")) {
|
|
2194
|
+
features.add("norm16-renderable-webgl");
|
|
2195
|
+
}
|
|
2196
|
+
if (this.handle.features.has("chromium-experimental-snorm16-texture-formats")) {
|
|
2197
|
+
features.add("snorm16-renderable-webgl");
|
|
2198
|
+
}
|
|
1917
2199
|
const WEBGPU_ALWAYS_FEATURES = [
|
|
1918
2200
|
"timer-query-webgl",
|
|
1919
2201
|
"compilation-status-async-webgl",
|
|
@@ -1926,7 +2208,7 @@ var init_webgpu_device = __esm({
|
|
|
1926
2208
|
for (const feature of WEBGPU_ALWAYS_FEATURES) {
|
|
1927
2209
|
features.add(feature);
|
|
1928
2210
|
}
|
|
1929
|
-
return new
|
|
2211
|
+
return new import_core23.DeviceFeatures(Array.from(features), this.props._disabledFeatures);
|
|
1930
2212
|
}
|
|
1931
2213
|
_getDeviceSpecificTextureFormatCapabilities(capabilities) {
|
|
1932
2214
|
const { format } = capabilities;
|
|
@@ -1944,16 +2226,18 @@ var dist_exports = {};
|
|
|
1944
2226
|
__export(dist_exports, {
|
|
1945
2227
|
WebGPUBuffer: () => WebGPUBuffer,
|
|
1946
2228
|
WebGPUDevice: () => WebGPUDevice,
|
|
2229
|
+
WebGPUFence: () => WebGPUFence,
|
|
1947
2230
|
WebGPUSampler: () => WebGPUSampler,
|
|
1948
2231
|
WebGPUShader: () => WebGPUShader,
|
|
1949
2232
|
WebGPUTexture: () => WebGPUTexture,
|
|
2233
|
+
getShaderLayoutFromWGSL: () => getShaderLayoutFromWGSL,
|
|
1950
2234
|
webgpuAdapter: () => webgpuAdapter
|
|
1951
2235
|
});
|
|
1952
2236
|
module.exports = __toCommonJS(dist_exports);
|
|
1953
2237
|
|
|
1954
2238
|
// dist/adapter/webgpu-adapter.js
|
|
1955
|
-
var
|
|
1956
|
-
var WebGPUAdapter = class extends
|
|
2239
|
+
var import_core24 = require("@luma.gl/core");
|
|
2240
|
+
var WebGPUAdapter = class extends import_core24.Adapter {
|
|
1957
2241
|
/** type of device's created by this adapter */
|
|
1958
2242
|
type = "webgpu";
|
|
1959
2243
|
isSupported() {
|
|
@@ -1973,43 +2257,41 @@ var WebGPUAdapter = class extends import_core22.Adapter {
|
|
|
1973
2257
|
if (!navigator.gpu) {
|
|
1974
2258
|
throw new Error("WebGPU not available. Recent Chrome browsers should work.");
|
|
1975
2259
|
}
|
|
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
|
-
}
|
|
2260
|
+
const adapter = await navigator.gpu.requestAdapter({
|
|
2261
|
+
powerPreference: "high-performance"
|
|
2262
|
+
// forceSoftware: false
|
|
2263
|
+
});
|
|
2264
|
+
if (!adapter) {
|
|
2265
|
+
throw new Error("Failed to request WebGPU adapter");
|
|
2266
|
+
}
|
|
2267
|
+
const adapterInfo = adapter.info || // @ts-ignore
|
|
2268
|
+
await ((_a = adapter.requestAdapterInfo) == null ? void 0 : _a.call(adapter));
|
|
2269
|
+
const requiredFeatures = [];
|
|
2270
|
+
const requiredLimits = {};
|
|
2271
|
+
if (props._requestMaxLimits) {
|
|
2272
|
+
requiredFeatures.push(...Array.from(adapter.features));
|
|
2273
|
+
const limits = Object.keys(adapter.limits).filter((key) => !["minSubgroupSize", "maxSubgroupSize"].includes(key));
|
|
2274
|
+
for (const key of limits) {
|
|
2275
|
+
const limit = key;
|
|
2276
|
+
const value = adapter.limits[limit];
|
|
2277
|
+
if (typeof value === "number") {
|
|
2278
|
+
requiredLimits[limit] = value;
|
|
1999
2279
|
}
|
|
2000
2280
|
}
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2281
|
+
}
|
|
2282
|
+
const gpuDevice = await adapter.requestDevice({
|
|
2283
|
+
requiredFeatures,
|
|
2284
|
+
requiredLimits
|
|
2285
|
+
});
|
|
2286
|
+
const { WebGPUDevice: WebGPUDevice2 } = await Promise.resolve().then(() => (init_webgpu_device(), webgpu_device_exports));
|
|
2287
|
+
import_core24.log.groupCollapsed(1, "WebGPUDevice created")();
|
|
2288
|
+
try {
|
|
2007
2289
|
const device = new WebGPUDevice2(props, gpuDevice, adapter, adapterInfo);
|
|
2008
|
-
|
|
2009
|
-
|
|
2290
|
+
import_core24.log.probe(1, "Device created. For more info, set chrome://flags/#enable-webgpu-developer-features")();
|
|
2291
|
+
import_core24.log.table(1, device.info)();
|
|
2010
2292
|
return device;
|
|
2011
2293
|
} finally {
|
|
2012
|
-
|
|
2294
|
+
import_core24.log.groupEnd(1)();
|
|
2013
2295
|
}
|
|
2014
2296
|
}
|
|
2015
2297
|
async attach(handle) {
|
|
@@ -2024,4 +2306,6 @@ init_webgpu_buffer();
|
|
|
2024
2306
|
init_webgpu_texture();
|
|
2025
2307
|
init_webgpu_sampler();
|
|
2026
2308
|
init_webgpu_shader();
|
|
2309
|
+
init_webgpu_fence();
|
|
2310
|
+
init_get_shader_layout_wgsl();
|
|
2027
2311
|
//# sourceMappingURL=index.cjs.map
|