@luma.gl/webgpu 9.1.0-alpha.1 → 9.1.0-alpha.9

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.
Files changed (53) hide show
  1. package/dist/adapter/helpers/convert-texture-format.d.ts +0 -1
  2. package/dist/adapter/helpers/convert-texture-format.d.ts.map +1 -1
  3. package/dist/adapter/helpers/get-bind-group.d.ts +0 -1
  4. package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
  5. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts +0 -1
  6. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
  7. package/dist/adapter/helpers/webgpu-parameters.d.ts +0 -1
  8. package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
  9. package/dist/adapter/resources/webgpu-buffer.d.ts +0 -1
  10. package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
  11. package/dist/adapter/resources/webgpu-command-encoder.d.ts +0 -1
  12. package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
  13. package/dist/adapter/resources/webgpu-compute-pass.d.ts +0 -1
  14. package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
  15. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +0 -1
  16. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
  17. package/dist/adapter/resources/webgpu-external-texture.d.ts +0 -1
  18. package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
  19. package/dist/adapter/resources/webgpu-query-set.d.ts +0 -1
  20. package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -1
  21. package/dist/adapter/resources/webgpu-render-pass.d.ts +0 -1
  22. package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
  23. package/dist/adapter/resources/webgpu-render-pipeline.d.ts +0 -1
  24. package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
  25. package/dist/adapter/resources/webgpu-sampler.d.ts +0 -1
  26. package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
  27. package/dist/adapter/resources/webgpu-shader.d.ts +0 -1
  28. package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
  29. package/dist/adapter/resources/webgpu-texture-view.d.ts +0 -1
  30. package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
  31. package/dist/adapter/resources/webgpu-texture.d.ts +2 -3
  32. package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
  33. package/dist/adapter/resources/webgpu-texture.js +27 -3
  34. package/dist/adapter/webgpu-adapter.d.ts +13 -0
  35. package/dist/adapter/webgpu-adapter.d.ts.map +1 -0
  36. package/dist/adapter/webgpu-adapter.js +68 -0
  37. package/dist/adapter/webgpu-canvas-context.d.ts +0 -1
  38. package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
  39. package/dist/adapter/webgpu-device.d.ts +1 -6
  40. package/dist/adapter/webgpu-device.d.ts.map +1 -1
  41. package/dist/adapter/webgpu-device.js +2 -52
  42. package/dist/dist.dev.js +101 -83
  43. package/dist/dist.min.js +1 -1
  44. package/dist/index.cjs +93 -60
  45. package/dist/index.cjs.map +4 -4
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +2 -2
  49. package/package.json +2 -2
  50. package/src/adapter/resources/webgpu-texture.ts +36 -22
  51. package/src/adapter/webgpu-adapter.ts +93 -0
  52. package/src/adapter/webgpu-device.ts +3 -72
  53. package/src/index.ts +3 -1
@@ -14,7 +14,8 @@ import type {
14
14
  Texture3DData,
15
15
  TextureCubeData,
16
16
  TextureArrayData,
17
- TextureCubeArrayData
17
+ TextureCubeArrayData,
18
+ ExternalImage
18
19
  } from '@luma.gl/core';
19
20
  import {Texture} from '@luma.gl/core';
20
21
 
@@ -82,7 +83,11 @@ export class WebGPUTexture extends Texture {
82
83
  this.handle.label ||= this.id;
83
84
 
84
85
  if (this.props.data) {
85
- this.setData({data: this.props.data});
86
+ if (Texture.isExternalImage(this.props.data)) {
87
+ this.setImage({source: this.props.data});
88
+ } else {
89
+ this.setData({data: this.props.data});
90
+ }
86
91
  }
87
92
 
88
93
  this.width = this.handle.width;
@@ -177,13 +182,36 @@ export class WebGPUTexture extends Texture {
177
182
  throw new Error('not implemented');
178
183
  }
179
184
 
180
- setData(options: {data: any}) {
181
- return this.setImage({source: options.data});
185
+ setData(options: {data: any}): {width: number; height: number} {
186
+ let source = options.data;
187
+
188
+ if (ArrayBuffer.isView(options.data)) {
189
+ const clampedArray = new Uint8ClampedArray(options.data.buffer);
190
+ // TODO - pass through src data color space as ImageData Options?
191
+ source = new ImageData(clampedArray, this.width, this.height);
192
+ }
193
+
194
+ return this.setImage({source});
182
195
  }
183
196
 
197
+ // setDataFromTypedArray(data): this {
198
+ // const textureDataBuffer = this.device.handle.createBuffer({
199
+ // size: data.byteLength,
200
+ // usage: Buffer.COPY_DST | Buffer.COPY_SRC,
201
+ // mappedAtCreation: true
202
+ // });
203
+ // new Uint8Array(textureDataBuffer.getMappedRange()).set(data);
204
+ // textureDataBuffer.unmap();
205
+
206
+ // this.setBuffer(textureDataBuffer);
207
+
208
+ // textureDataBuffer.destroy();
209
+ // return this;
210
+ // }
211
+
184
212
  /** Set image */
185
213
  setImage(options: {
186
- source: ImageBitmap | HTMLCanvasElement | OffscreenCanvas;
214
+ source: ExternalImage;
187
215
  width?: number;
188
216
  height?: number;
189
217
  depth?: number;
@@ -197,10 +225,11 @@ export class WebGPUTexture extends Texture {
197
225
  colorSpace?: 'srgb';
198
226
  premultipliedAlpha?: boolean;
199
227
  }): {width: number; height: number} {
228
+ const size = Texture.getExternalImageSize(options.source);
200
229
  const {
201
230
  source,
202
- width = options.source.width,
203
- height = options.source.height,
231
+ width = size.width,
232
+ height = size.height,
204
233
  depth = 1,
205
234
  sourceX = 0,
206
235
  sourceY = 0,
@@ -283,21 +312,6 @@ export class WebGPUTexture extends Texture {
283
312
  return this;
284
313
  }
285
314
 
286
- setData(data): this {
287
- const textureDataBuffer = this.device.handle.createBuffer({
288
- size: data.byteLength,
289
- usage: Buffer.COPY_DST | Buffer.COPY_SRC,
290
- mappedAtCreation: true
291
- });
292
- new Uint8Array(textureDataBuffer.getMappedRange()).set(data);
293
- textureDataBuffer.unmap();
294
-
295
- this.setBuffer(textureDataBuffer);
296
-
297
- textureDataBuffer.destroy();
298
- return this;
299
- }
300
-
301
315
  setBuffer(textureDataBuffer, {bytesPerRow}): this {
302
316
  const commandEncoder = this.device.handle.createCommandEncoder();
303
317
  commandEncoder.copyBufferToTexture(
@@ -0,0 +1,93 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {Adapter, DeviceProps, CanvasContext, log} from '@luma.gl/core';
6
+ import {WebGPUDevice} from './webgpu-device';
7
+
8
+ // / <reference types="@webgpu/types" />
9
+
10
+ export class WebGPUAdapter extends Adapter {
11
+ /** type of device's created by this adapter */
12
+ readonly type: WebGPUDevice['type'] = 'webgpu';
13
+
14
+ constructor() {
15
+ super();
16
+ // @ts-ignore For backwards compatibility luma.registerDevices
17
+ WebGPUDevice.adapter = this;
18
+ }
19
+
20
+ /** Check if WebGPU is available */
21
+ isSupported(): boolean {
22
+ return Boolean(typeof navigator !== 'undefined' && navigator.gpu);
23
+ }
24
+
25
+ async create(props: DeviceProps): Promise<WebGPUDevice> {
26
+ if (!navigator.gpu) {
27
+ throw new Error(
28
+ 'WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu'
29
+ );
30
+ }
31
+ log.groupCollapsed(1, 'WebGPUDevice created')();
32
+ const adapter = await navigator.gpu.requestAdapter({
33
+ powerPreference: 'high-performance'
34
+ // forceSoftware: false
35
+ });
36
+
37
+ if (!adapter) {
38
+ throw new Error('Failed to request WebGPU adapter');
39
+ }
40
+
41
+ const adapterInfo = await adapter.requestAdapterInfo();
42
+ log.probe(2, 'Adapter available', adapterInfo)();
43
+
44
+ const requiredFeatures: GPUFeatureName[] = [];
45
+ const requiredLimits: Record<string, number> = {};
46
+
47
+ if (props.requestMaxLimits) {
48
+ // Require all features
49
+ requiredFeatures.push(...(Array.from(adapter.features) as GPUFeatureName[]));
50
+
51
+ // Require all limits
52
+ // Filter out chrome specific keys (avoid crash)
53
+ const limits = Object.keys(adapter.limits).filter(
54
+ key => !['minSubgroupSize', 'maxSubgroupSize'].includes(key)
55
+ );
56
+ for (const key of limits) {
57
+ const limit = key as keyof GPUSupportedLimits;
58
+ const value = adapter.limits[limit];
59
+ if (typeof value === 'number') {
60
+ requiredLimits[limit] = value;
61
+ }
62
+ }
63
+ }
64
+
65
+ const gpuDevice = await adapter.requestDevice({
66
+ requiredFeatures,
67
+ requiredLimits
68
+ });
69
+
70
+ log.probe(1, 'GPUDevice available')();
71
+
72
+ if (typeof props.canvas === 'string') {
73
+ await CanvasContext.pageLoaded;
74
+ log.probe(1, 'DOM is loaded')();
75
+ }
76
+
77
+ const device = new WebGPUDevice(props, gpuDevice, adapter, adapterInfo);
78
+
79
+ log.probe(
80
+ 1,
81
+ 'Device created. For more info, set chrome://flags/#enable-webgpu-developer-features'
82
+ )();
83
+ log.table(1, device.info)();
84
+ log.groupEnd(1)();
85
+ return device;
86
+ }
87
+
88
+ async attach(handle: GPUDevice): Promise<WebGPUDevice> {
89
+ throw new Error('WebGPUAdapter.attach() not implemented');
90
+ }
91
+ }
92
+
93
+ export const webgpuAdapter = new WebGPUAdapter();
@@ -30,7 +30,7 @@ import type {
30
30
  QuerySet,
31
31
  QuerySetProps
32
32
  } from '@luma.gl/core';
33
- import {Device, DeviceFeatures, CanvasContext, log} from '@luma.gl/core';
33
+ import {Device, DeviceFeatures} from '@luma.gl/core';
34
34
  import {WebGPUBuffer} from './resources/webgpu-buffer';
35
35
  import {WebGPUTexture} from './resources/webgpu-texture';
36
36
  import {WebGPUExternalTexture} from './resources/webgpu-external-texture';
@@ -49,8 +49,6 @@ import {WebGPUQuerySet} from './resources/webgpu-query-set';
49
49
 
50
50
  /** WebGPU Device implementation */
51
51
  export class WebGPUDevice extends Device {
52
- static type: string = 'webgpu';
53
-
54
52
  /** type of this device */
55
53
  readonly type = 'webgpu';
56
54
 
@@ -72,78 +70,11 @@ export class WebGPUDevice extends Device {
72
70
  commandEncoder: GPUCommandEncoder | null = null;
73
71
  renderPass: WebGPURenderPass | null = null;
74
72
 
75
- /** Check if WebGPU is available */
76
- static isSupported(): boolean {
77
- return Boolean(typeof navigator !== 'undefined' && navigator.gpu);
78
- }
79
-
80
- static async create(props: DeviceProps): Promise<WebGPUDevice> {
81
- if (!navigator.gpu) {
82
- throw new Error(
83
- 'WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu'
84
- );
85
- }
86
- log.groupCollapsed(1, 'WebGPUDevice created')();
87
- const adapter = await navigator.gpu.requestAdapter({
88
- powerPreference: 'high-performance'
89
- // forceSoftware: false
90
- });
91
- if (!adapter) {
92
- throw new Error('Failed to request WebGPU adapter');
93
- }
94
-
95
- const adapterInfo = await adapter.requestAdapterInfo();
96
- log.probe(2, 'Adapter available', adapterInfo)();
97
-
98
- const requiredFeatures: GPUFeatureName[] = [];
99
- const requiredLimits: Record<string, number> = {};
100
-
101
- if (props.requestMaxLimits) {
102
- // Require all features
103
- requiredFeatures.push(...(Array.from(adapter.features) as GPUFeatureName[]));
104
-
105
- // Require all limits
106
- // Filter out chrome specific keys (avoid crash)
107
- const limits = Object.keys(adapter.limits).filter(
108
- key => !['minSubgroupSize', 'maxSubgroupSize'].includes(key)
109
- );
110
- for (const key of limits) {
111
- const limit = key as keyof GPUSupportedLimits;
112
- const value = adapter.limits[limit];
113
- if (typeof value === 'number') {
114
- requiredLimits[limit] = value;
115
- }
116
- }
117
- }
118
-
119
- const gpuDevice = await adapter.requestDevice({
120
- requiredFeatures,
121
- requiredLimits
122
- });
123
-
124
- log.probe(1, 'GPUDevice available')();
125
-
126
- if (typeof props.canvas === 'string') {
127
- await CanvasContext.pageLoaded;
128
- log.probe(1, 'DOM is loaded')();
129
- }
130
-
131
- const device = new WebGPUDevice(gpuDevice, adapter, adapterInfo, props);
132
-
133
- log.probe(
134
- 1,
135
- 'Device created. For more info, set chrome://flags/#enable-webgpu-developer-features'
136
- )();
137
- log.table(1, device.info)();
138
- log.groupEnd(1)();
139
- return device;
140
- }
141
-
142
73
  constructor(
74
+ props: DeviceProps,
143
75
  device: GPUDevice,
144
76
  adapter: GPUAdapter,
145
- adapterInfo: GPUAdapterInfo,
146
- props: DeviceProps
77
+ adapterInfo: GPUAdapterInfo
147
78
  ) {
148
79
  super({...props, id: props.id || 'webgpu-device'});
149
80
  this.handle = device;
package/src/index.ts CHANGED
@@ -3,9 +3,11 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  // WEBGPU ADAPTER
6
- export {WebGPUDevice} from './adapter/webgpu-device';
6
+ export type {WebGPUAdapter} from './adapter/webgpu-adapter';
7
+ export {webgpuAdapter} from './adapter/webgpu-adapter';
7
8
 
8
9
  // WEBGPU CLASSES (typically not accessed directly)
10
+ export {WebGPUDevice} from './adapter/webgpu-device';
9
11
  export {WebGPUBuffer} from './adapter/resources/webgpu-buffer';
10
12
  export {WebGPUTexture} from './adapter/resources/webgpu-texture';
11
13
  export {WebGPUSampler} from './adapter/resources/webgpu-sampler';