@luma.gl/webgpu 9.0.0-beta.6 → 9.0.0-beta.8

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 (66) hide show
  1. package/dist/adapter/helpers/get-bind-group.d.ts +3 -3
  2. package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
  3. package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
  4. package/dist/adapter/resources/webgpu-buffer.js +3 -1
  5. package/dist/adapter/resources/webgpu-compute-pass.d.ts +14 -8
  6. package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
  7. package/dist/adapter/resources/webgpu-compute-pass.js +18 -13
  8. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +13 -3
  9. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
  10. package/dist/adapter/resources/webgpu-compute-pipeline.js +25 -7
  11. package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
  12. package/dist/adapter/resources/webgpu-external-texture.js +2 -0
  13. package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -1
  14. package/dist/adapter/resources/webgpu-query-set.js +3 -1
  15. package/dist/adapter/resources/webgpu-render-pipeline.d.ts +49 -1
  16. package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
  17. package/dist/adapter/resources/webgpu-render-pipeline.js +69 -51
  18. package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
  19. package/dist/adapter/resources/webgpu-sampler.js +3 -0
  20. package/dist/adapter/resources/webgpu-shader.d.ts +1 -4
  21. package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
  22. package/dist/adapter/resources/webgpu-shader.js +7 -18
  23. package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
  24. package/dist/adapter/resources/webgpu-texture-view.js +3 -0
  25. package/dist/adapter/resources/webgpu-texture.d.ts +3 -4
  26. package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
  27. package/dist/adapter/resources/webgpu-texture.js +8 -8
  28. package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
  29. package/dist/adapter/webgpu-canvas-context.js +2 -1
  30. package/dist/adapter/webgpu-device.d.ts +2 -7
  31. package/dist/adapter/webgpu-device.d.ts.map +1 -1
  32. package/dist/adapter/webgpu-device.js +9 -19
  33. package/dist/dist.dev.js +130 -176
  34. package/dist/dist.min.js +9 -0
  35. package/dist/index.cjs +122 -131
  36. package/dist/index.cjs.map +4 -4
  37. package/package.json +5 -5
  38. package/src/.DS_Store +0 -0
  39. package/src/adapter/.DS_Store +0 -0
  40. package/src/adapter/helpers/get-bind-group.ts +4 -4
  41. package/src/adapter/resources/webgpu-buffer.ts +3 -1
  42. package/src/adapter/resources/webgpu-compute-pass.ts +19 -14
  43. package/src/adapter/resources/webgpu-compute-pipeline.ts +36 -9
  44. package/src/adapter/resources/webgpu-external-texture.ts +2 -0
  45. package/src/adapter/resources/webgpu-query-set.ts +3 -1
  46. package/src/adapter/resources/webgpu-render-pipeline.ts +63 -92
  47. package/src/adapter/resources/webgpu-sampler.ts +3 -0
  48. package/src/adapter/resources/webgpu-shader.ts +8 -23
  49. package/src/adapter/resources/webgpu-texture-view.ts +3 -0
  50. package/src/adapter/resources/webgpu-texture.ts +11 -10
  51. package/src/adapter/webgpu-canvas-context.ts +2 -1
  52. package/src/adapter/webgpu-device.ts +11 -20
  53. package/dist/adapter/helpers/generate-mipmaps.d.ts +0 -10
  54. package/dist/adapter/helpers/generate-mipmaps.d.ts.map +0 -1
  55. package/dist/adapter/helpers/generate-mipmaps.js +0 -103
  56. package/dist/adapter/resources/webgpu-query.d.ts +0 -1
  57. package/dist/adapter/resources/webgpu-query.d.ts.map +0 -1
  58. package/dist/adapter/resources/webgpu-query.js +0 -43
  59. package/dist/adapter/webgpu-types.d.ts +0 -1
  60. package/dist/adapter/webgpu-types.d.ts.map +0 -1
  61. package/dist/adapter/webgpu-types.js +0 -0
  62. package/dist/glsl/glsllang.d.ts +0 -3
  63. package/dist/glsl/glsllang.d.ts.map +0 -1
  64. package/dist/glsl/glsllang.js +0 -12
  65. package/dist.min.js +0 -9
  66. package/src/adapter/helpers/generate-mipmaps.ts +0 -118
@@ -5,14 +5,14 @@
5
5
  import {ComputePass, ComputePassProps, ComputePipeline, Buffer, Binding} from '@luma.gl/core';
6
6
  import {WebGPUDevice} from '../webgpu-device';
7
7
  import {WebGPUBuffer} from './webgpu-buffer';
8
- // import {WebGPUCommandEncoder} from './webgpu-command-encoder';
9
8
  import {WebGPUComputePipeline} from './webgpu-compute-pipeline';
10
9
  import {WebGPUQuerySet} from './webgpu-query-set';
11
10
 
12
11
  export class WebGPUComputePass extends ComputePass {
13
12
  readonly device: WebGPUDevice;
14
13
  readonly handle: GPUComputePassEncoder;
15
- _bindGroupLayout: GPUBindGroupLayout | null = null;
14
+
15
+ _webgpuPipeline: WebGPUComputePipeline | null = null;
16
16
 
17
17
  constructor(device: WebGPUDevice, props: ComputePassProps) {
18
18
  super(device, props);
@@ -49,21 +49,24 @@ export class WebGPUComputePass extends ComputePass {
49
49
  setPipeline(pipeline: ComputePipeline): void {
50
50
  const wgpuPipeline = pipeline as WebGPUComputePipeline;
51
51
  this.handle.setPipeline(wgpuPipeline.handle);
52
- this._bindGroupLayout = wgpuPipeline._getBindGroupLayout();
52
+ this._webgpuPipeline = wgpuPipeline;
53
+ this.setBindings([]);
53
54
  }
54
55
 
55
- /** Sets an array of bindings (uniform buffers, samplers, textures, ...) */
56
+ /**
57
+ * Sets an array of bindings (uniform buffers, samplers, textures, ...)
58
+ * TODO - still some API confusion - does this method go here or on the pipeline?
59
+ */
56
60
  setBindings(bindings: Binding[]): void {
57
- throw new Error('fix me');
58
- // const bindGroup = getBindGroup(this.device.handle, this._bindGroupLayout, this.props.bindings);
59
- // this.handle.setBindGroup(0, bindGroup);
61
+ const bindGroup = this._webgpuPipeline._getBindGroup();
62
+ this.handle.setBindGroup(0, bindGroup);
60
63
  }
61
64
 
62
65
  /**
63
66
  * Dispatch work to be performed with the current ComputePipeline.
64
- * @param x X dimension of the grid of workgroups to dispatch.
65
- * @param y Y dimension of the grid of workgroups to dispatch.
66
- * @param z Z dimension of the grid of workgroups to dispatch.
67
+ * @param x X dimension of the grid of work groups to dispatch.
68
+ * @param y Y dimension of the grid of work groups to dispatch.
69
+ * @param z Z dimension of the grid of work groups to dispatch.
67
70
  */
68
71
  dispatch(x: number, y?: number, z?: number): void {
69
72
  this.handle.dispatchWorkgroups(x, y, z);
@@ -71,12 +74,14 @@ export class WebGPUComputePass extends ComputePass {
71
74
 
72
75
  /**
73
76
  * Dispatch work to be performed with the current ComputePipeline.
74
- * @param indirectBuffer buffer must be a tightly packed block of three 32-bit unsigned integer values (12 bytes total), given in the same order as the arguments for dispatch()
75
- * @param indirectOffset
77
+ *
78
+ * Buffer must be a tightly packed block of three 32-bit unsigned integer values (12 bytes total), given in the same order as the arguments for dispatch()
79
+ * @param indirectBuffer
80
+ * @param indirectOffset offset in buffer to the beginning of the dispatch data.
76
81
  */
77
- dispatchIndirect(indirectBuffer: Buffer, indirectOffset: number = 0): void {
82
+ dispatchIndirect(indirectBuffer: Buffer, indirectByteOffset: number = 0): void {
78
83
  const webgpuBuffer = indirectBuffer as WebGPUBuffer;
79
- this.handle.dispatchWorkgroupsIndirect(webgpuBuffer.handle, indirectOffset);
84
+ this.handle.dispatchWorkgroupsIndirect(webgpuBuffer.handle, indirectByteOffset);
80
85
  }
81
86
 
82
87
  pushDebugGroup(groupLabel: string): void {
@@ -2,8 +2,8 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {ComputePipeline, ComputePipelineProps} from '@luma.gl/core';
6
-
5
+ import {ComputePipeline, ComputePipelineProps, Binding} from '@luma.gl/core';
6
+ import {getBindGroup} from '../helpers/get-bind-group';
7
7
  import {WebGPUDevice} from '../webgpu-device';
8
8
  import {WebGPUShader} from './webgpu-shader';
9
9
 
@@ -14,27 +14,54 @@ export class WebGPUComputePipeline extends ComputePipeline {
14
14
  device: WebGPUDevice;
15
15
  handle: GPUComputePipeline;
16
16
 
17
+ /** For internal use to create BindGroups */
18
+ private _bindGroupLayout: GPUBindGroupLayout | null = null;
19
+ private _bindGroup: GPUBindGroup | null = null;
20
+ /** For internal use to create BindGroups */
21
+ private _bindings: Record<string, Binding> = {};
22
+
17
23
  constructor(device: WebGPUDevice, props: ComputePipelineProps) {
18
24
  super(device, props);
19
25
  this.device = device;
20
26
 
21
- const webgpuShader = this.props.cs as WebGPUShader;
27
+ const webgpuShader = this.props.shader as WebGPUShader;
28
+
22
29
  this.handle =
23
30
  this.props.handle ||
24
31
  this.device.handle.createComputePipeline({
25
32
  label: this.props.id,
26
33
  compute: {
27
34
  module: webgpuShader.handle,
28
- entryPoint: this.props.csEntryPoint
29
- // constants: this.props.csConstants
35
+ entryPoint: this.props.entryPoint,
36
+ constants: this.props.constants
30
37
  },
31
38
  layout: 'auto'
32
39
  });
33
40
  }
34
41
 
35
- /** For internal use in render passes */
36
- _getBindGroupLayout() {
37
- // TODO: Cache?
38
- return this.handle.getBindGroupLayout(0);
42
+ /**
43
+ * @todo Use renderpass.setBindings() ?
44
+ * @todo Do we want to expose BindGroups in the API and remove this?
45
+ */
46
+ setBindings(bindings: Record<string, Binding>): void {
47
+ Object.assign(this._bindings, bindings);
48
+ }
49
+
50
+ /** Return a bind group created by setBindings */
51
+ _getBindGroup() {
52
+ // Get hold of the bind group layout. We don't want to do this unless we know there is at least one bind group
53
+ this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
54
+
55
+ // Set up the bindings
56
+ this._bindGroup =
57
+ this._bindGroup ||
58
+ getBindGroup(
59
+ this.device.handle,
60
+ this._bindGroupLayout,
61
+ this.props.shaderLayout,
62
+ this._bindings
63
+ );
64
+
65
+ return this._bindGroup;
39
66
  }
40
67
  }
@@ -31,6 +31,8 @@ export class WebGPUExternalTexture extends ExternalTexture {
31
31
  // External textures are destroyed automatically,
32
32
  // as a microtask, instead of manually or upon garbage collection like other resources.
33
33
  // this.handle.destroy();
34
+ // @ts-expect-error readonly
35
+ this.handle = null;
34
36
  }
35
37
 
36
38
  /** Set default sampler */
@@ -30,6 +30,8 @@ export class WebGPUQuerySet extends QuerySet {
30
30
  }
31
31
 
32
32
  override destroy(): void {
33
- this.handle.destroy();
33
+ this.handle?.destroy();
34
+ // @ts-expect-error readonly
35
+ this.handle = null;
34
36
  }
35
37
  }
@@ -25,12 +25,8 @@ export class WebGPURenderPipeline extends RenderPipeline {
25
25
  vs: WebGPUShader;
26
26
  fs: WebGPUShader | null = null;
27
27
 
28
- // private _bufferSlots: Record<string, number>;
29
- // private _buffers: Buffer[];
30
- // private _firstIndex: number;
31
- // private _lastIndex: number;
32
-
33
28
  /** For internal use to create BindGroups */
29
+ private _bindings: Record<string, Binding>;
34
30
  private _bindGroupLayout: GPUBindGroupLayout | null = null;
35
31
  private _bindGroup: GPUBindGroup | null = null;
36
32
 
@@ -50,46 +46,23 @@ export class WebGPURenderPipeline extends RenderPipeline {
50
46
  this.vs = cast<WebGPUShader>(props.vs);
51
47
  this.fs = cast<WebGPUShader>(props.fs);
52
48
 
53
- // this._bufferSlots = getBufferSlots(this.props.shaderLayout, this.props.bufferLayout);
54
- // this._buffers = new Array<Buffer>(Object.keys(this._bufferSlots).length).fill(null);
49
+ this._bindings = {...this.props.bindings};
55
50
  }
56
51
 
57
52
  override destroy(): void {
58
53
  // WebGPURenderPipeline has no destroy method.
54
+ this.handle = null;
59
55
  }
60
56
 
61
- // setIndexBuffer(indexBuffer: Buffer): void {
62
- // this._indexBuffer = cast<WebGPUBuffer>(indexBuffer);
63
- // }
64
-
65
- // setAttributes(attributes: Record<string, Buffer>): void {
66
- // for (const [name, buffer] of Object.entries(attributes)) {
67
- // const bufferIndex = this._bufferSlots[name];
68
- // if (bufferIndex >= 0) {
69
- // this._buffers[bufferIndex] = buffer;
70
- // } else {
71
- // throw new Error(
72
- // `Setting attribute '${name}' not listed in shader layout for program ${this.id}`
73
- // );
74
- // }
75
- // }
76
- // // for (let i = 0; i < this._bufferSlots.length; ++i) {
77
- // // const bufferName = this._bufferSlots[i];
78
- // // if (attributes[bufferName]) {
79
- // // this.handle
80
- // // }
81
- // // }
82
- // }
83
-
57
+ /**
58
+ * @todo Use renderpass.setBindings() ?
59
+ * @todo Do we want to expose BindGroups in the API and remove this?
60
+ */
84
61
  setBindings(bindings: Record<string, Binding>): void {
85
- // if (isObjectEmpty(bindings)) {
86
- // return;
87
- // }
88
-
89
- // Do we want to save things on CPU side?
90
- Object.assign(this.props.bindings, bindings);
62
+ Object.assign(this._bindings, bindings);
91
63
  }
92
64
 
65
+ /** @todo - should this be moved to renderpass? */
93
66
  draw(options: {
94
67
  renderPass: RenderPass;
95
68
  vertexArray: VertexArray;
@@ -100,9 +73,8 @@ export class WebGPURenderPipeline extends RenderPipeline {
100
73
  firstIndex?: number;
101
74
  firstInstance?: number;
102
75
  baseVertex?: number;
103
- }): void {
104
- const webgpuRenderPass: WebGPURenderPass =
105
- cast<WebGPURenderPass>(options.renderPass) || this.device.getDefaultRenderPass();
76
+ }): boolean {
77
+ const webgpuRenderPass = options.renderPass as WebGPURenderPass;
106
78
 
107
79
  // Set pipeline
108
80
  webgpuRenderPass.handle.setPipeline(this.handle);
@@ -136,25 +108,28 @@ export class WebGPURenderPipeline extends RenderPipeline {
136
108
 
137
109
  // Note: Rebinds constant attributes before each draw call
138
110
  options.vertexArray.unbindAfterRender(options.renderPass);
139
- }
140
111
 
141
- // _getBuffers() {
142
- // return this._buffers;
143
- // }
112
+ return true;
113
+ }
144
114
 
145
115
  /** Return a bind group created by setBindings */
146
116
  _getBindGroup() {
117
+ if (this.props.shaderLayout.bindings.length === 0) {
118
+ return null;
119
+ }
120
+
147
121
  // Get hold of the bind group layout. We don't want to do this unless we know there is at least one bind group
148
122
  this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
149
123
 
150
124
  // Set up the bindings
125
+ // TODO what if bindings change? We need to rebuild the bind group!
151
126
  this._bindGroup =
152
127
  this._bindGroup ||
153
128
  getBindGroup(
154
129
  this.device.handle,
155
130
  this._bindGroupLayout,
156
131
  this.props.shaderLayout,
157
- this.props.bindings
132
+ this._bindings
158
133
  );
159
134
 
160
135
  return this._bindGroup;
@@ -167,24 +142,21 @@ export class WebGPURenderPipeline extends RenderPipeline {
167
142
  // Set up the vertex stage
168
143
  const vertex: GPUVertexState = {
169
144
  module: cast<WebGPUShader>(this.props.vs).handle,
170
- entryPoint: this.props.vsEntryPoint || 'main',
145
+ entryPoint: this.props.vertexEntryPoint || 'main',
171
146
  buffers: getVertexBufferLayout(this.props.shaderLayout, this.props.bufferLayout)
172
147
  };
173
148
 
174
149
  // Set up the fragment stage
175
- let fragment: GPUFragmentState | undefined;
176
- if (this.props.fs) {
177
- fragment = {
178
- module: cast<WebGPUShader>(this.props.fs).handle,
179
- entryPoint: this.props.fsEntryPoint || 'main',
180
- targets: [
181
- {
182
- // TODO exclamation mark hack!
183
- format: getWebGPUTextureFormat(this.device?.canvasContext?.format)
184
- }
185
- ]
186
- };
187
- }
150
+ const fragment: GPUFragmentState = {
151
+ module: cast<WebGPUShader>(this.props.fs).handle,
152
+ entryPoint: this.props.fragmentEntryPoint || 'main',
153
+ targets: [
154
+ {
155
+ // TODO exclamation mark hack!
156
+ format: getWebGPUTextureFormat(this.device?.canvasContext?.format)
157
+ }
158
+ ]
159
+ };
188
160
 
189
161
  // WebGPU has more restrictive topology support than WebGL
190
162
  switch (this.props.topology) {
@@ -209,47 +181,46 @@ export class WebGPURenderPipeline extends RenderPipeline {
209
181
 
210
182
  return descriptor;
211
183
  }
184
+ }
185
+ /**
186
+ _setAttributeBuffers(webgpuRenderPass: WebGPURenderPass) {
187
+ if (this._indexBuffer) {
188
+ webgpuRenderPass.handle.setIndexBuffer(this._indexBuffer.handle, this._indexBuffer.props.indexType);
189
+ }
212
190
 
213
- /**
214
- _setAttributeBuffers(webgpuRenderPass: WebGPURenderPass) {
215
- if (this._indexBuffer) {
216
- webgpuRenderPass.handle.setIndexBuffer(this._indexBuffer.handle, this._indexBuffer.props.indexType);
191
+ const buffers = this._getBuffers();
192
+ for (let i = 0; i < buffers.length; ++i) {
193
+ const buffer = cast<WebGPUBuffer>(buffers[i]);
194
+ if (!buffer) {
195
+ const attribute = this.props.shaderLayout.attributes.find(
196
+ (attribute) => attribute.location === i
197
+ );
198
+ throw new Error(
199
+ `No buffer provided for attribute '${attribute?.name || ''}' in Model '${this.props.id}'`
200
+ );
217
201
  }
202
+ webgpuRenderPass.handle.setVertexBuffer(i, buffer.handle);
203
+ }
218
204
 
219
- const buffers = this._getBuffers();
220
- for (let i = 0; i < buffers.length; ++i) {
221
- const buffer = cast<WebGPUBuffer>(buffers[i]);
222
- if (!buffer) {
223
- const attribute = this.props.shaderLayout.attributes.find(
224
- (attribute) => attribute.location === i
225
- );
226
- throw new Error(
227
- `No buffer provided for attribute '${attribute?.name || ''}' in Model '${this.props.id}'`
228
- );
229
- }
230
- webgpuRenderPass.handle.setVertexBuffer(i, buffer.handle);
205
+ // TODO - HANDLE buffer maps
206
+ /*
207
+ for (const [bufferName, attributeMapping] of Object.entries(this.props.bufferLayout)) {
208
+ const buffer = cast<WebGPUBuffer>(this.props.attributes[bufferName]);
209
+ if (!buffer) {
210
+ log.warn(`Missing buffer for buffer map ${bufferName}`)();
211
+ continue;
231
212
  }
232
213
 
233
- // TODO - HANDLE buffer maps
234
- /*
235
- for (const [bufferName, attributeMapping] of Object.entries(this.props.bufferLayout)) {
236
- const buffer = cast<WebGPUBuffer>(this.props.attributes[bufferName]);
237
- if (!buffer) {
238
- log.warn(`Missing buffer for buffer map ${bufferName}`)();
239
- continue;
240
- }
241
-
242
- if ('location' in attributeMapping) {
214
+ if ('location' in attributeMapping) {
215
+ // @ts-expect-error TODO model must not depend on webgpu
216
+ renderPass.handle.setVertexBuffer(layout.location, buffer.handle);
217
+ } else {
218
+ for (const [bufferName, mapping] of Object.entries(attributeMapping)) {
243
219
  // @ts-expect-error TODO model must not depend on webgpu
244
- renderPass.handle.setVertexBuffer(layout.location, buffer.handle);
245
- } else {
246
- for (const [bufferName, mapping] of Object.entries(attributeMapping)) {
247
- // @ts-expect-error TODO model must not depend on webgpu
248
- renderPass.handle.setVertexBuffer(field.location, buffer.handle);
249
- }
220
+ renderPass.handle.setVertexBuffer(field.location, buffer.handle);
250
221
  }
251
222
  }
252
- *
253
223
  }
254
- */
224
+ *
255
225
  }
226
+ */
@@ -27,6 +27,9 @@ export class WebGPUSampler extends Sampler {
27
27
  }
28
28
 
29
29
  override destroy(): void {
30
+ // GPUSampler does not have a destroy method
30
31
  // this.handle.destroy();
32
+ // @ts-expect-error readonly
33
+ this.handle = null;
31
34
  }
32
35
  }
@@ -6,10 +6,6 @@ import type {ShaderProps, CompilerMessage} from '@luma.gl/core';
6
6
  import {Shader, log} from '@luma.gl/core';
7
7
  import type {WebGPUDevice} from '../webgpu-device';
8
8
 
9
- export type WebGPUShaderProps = ShaderProps & {
10
- handle?: GPUShaderModule;
11
- };
12
-
13
9
  /**
14
10
  * Immutable shader
15
11
  */
@@ -17,7 +13,7 @@ export class WebGPUShader extends Shader {
17
13
  readonly device: WebGPUDevice;
18
14
  readonly handle: GPUShaderModule;
19
15
 
20
- constructor(device: WebGPUDevice, props: WebGPUShaderProps) {
16
+ constructor(device: WebGPUDevice, props: ShaderProps) {
21
17
  super(device, props);
22
18
  this.device = device;
23
19
 
@@ -46,6 +42,8 @@ export class WebGPUShader extends Shader {
46
42
  override destroy(): void {
47
43
  // Note: WebGPU does not offer a method to destroy shaders
48
44
  // this.handle.destroy();
45
+ // @ts-expect-error readonly
46
+ this.handle = null;
49
47
  }
50
48
 
51
49
  /** Returns compilation info for this shader */
@@ -57,26 +55,13 @@ export class WebGPUShader extends Shader {
57
55
  // PRIVATE METHODS
58
56
 
59
57
  protected createHandle(): GPUShaderModule {
60
- const {source, stage} = this.props;
58
+ const {source} = this.props;
61
59
 
62
- let language = this.props.language;
63
- // Compile from src
64
- if (language === 'auto') {
65
- // wgsl uses C++ "auto" style arrow notation
66
- language = source.includes('->') ? 'wgsl' : 'glsl';
60
+ const isGLSL = source.includes('#version');
61
+ if (this.props.language === 'glsl' || isGLSL) {
62
+ throw new Error('GLSL shaders are not supported in WebGPU');
67
63
  }
68
64
 
69
- switch (language) {
70
- case 'wgsl':
71
- return this.device.handle.createShaderModule({code: source});
72
- case 'glsl':
73
- return this.device.handle.createShaderModule({
74
- code: source,
75
- // @ts-expect-error
76
- transform: glsl => this.device.glslang.compileGLSL(glsl, stage)
77
- });
78
- default:
79
- throw new Error(language);
80
- }
65
+ return this.device.handle.createShaderModule({code: source});
81
66
  }
82
67
  }
@@ -38,6 +38,9 @@ export class WebGPUTextureView extends TextureView {
38
38
  }
39
39
 
40
40
  override destroy(): void {
41
+ // GPUTextureView does not have a destroy method
41
42
  // this.handle.destroy();
43
+ // @ts-expect-error readonly
44
+ this.handle = null;
42
45
  }
43
46
  }
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {Texture, TextureProps, Sampler, SamplerProps} from '@luma.gl/core';
5
+ import {Texture, TextureProps, TextureViewProps, Sampler, SamplerProps} from '@luma.gl/core';
6
6
  import {getWebGPUTextureFormat} from '../helpers/convert-texture-format';
7
7
  import type {WebGPUDevice} from '../webgpu-device';
8
8
  import {WebGPUSampler} from './webgpu-sampler';
@@ -51,6 +51,16 @@ export class WebGPUTexture extends Texture {
51
51
  this.initialize(props);
52
52
  }
53
53
 
54
+ override destroy(): void {
55
+ this.handle?.destroy();
56
+ // @ts-expect-error readonly
57
+ this.handle = null;
58
+ }
59
+
60
+ createView(props: TextureViewProps): WebGPUTextureView {
61
+ return new WebGPUTextureView(this.device, {...props, texture: this});
62
+ }
63
+
54
64
  protected initialize(props: TextureProps): void {
55
65
  // @ts-expect-error
56
66
  this.handle = this.props.handle || this.createHandle();
@@ -113,10 +123,6 @@ export class WebGPUTexture extends Texture {
113
123
  });
114
124
  }
115
125
 
116
- override destroy(): void {
117
- this.handle.destroy();
118
- }
119
-
120
126
  /**
121
127
  * Set default sampler
122
128
  * Accept a sampler instance or set of props;
@@ -188,11 +194,6 @@ export class WebGPUTexture extends Texture {
188
194
 
189
195
  // WebGPU specific
190
196
 
191
- /** TODO - intention is to expose TextureViews in the public API */
192
- createView(): GPUTextureView {
193
- return this.handle.createView({label: this.id});
194
- }
195
-
196
197
  /*
197
198
  async readPixels() {
198
199
  const readbackBuffer = device.createBuffer({
@@ -112,7 +112,8 @@ export class WebGPUCanvasContext extends CanvasContext {
112
112
  getCurrentTexture(): WebGPUTexture {
113
113
  return this.device._createTexture({
114
114
  id: `${this.id}#color-texture`,
115
- handle: this.gpuCanvasContext.getCurrentTexture()
115
+ handle: this.gpuCanvasContext.getCurrentTexture(),
116
+ format: this.format
116
117
  });
117
118
  }
118
119
 
@@ -51,6 +51,9 @@ import {WebGPUQuerySet} from './resources/webgpu-query-set';
51
51
  export class WebGPUDevice extends Device {
52
52
  static type: string = 'webgpu';
53
53
 
54
+ /** type of this device */
55
+ readonly type = 'webgpu';
56
+
54
57
  /** The underlying WebGPU device */
55
58
  readonly handle: GPUDevice;
56
59
  /* The underlying WebGPU adapter */
@@ -95,7 +98,7 @@ export class WebGPUDevice extends Device {
95
98
  const requiredFeatures: GPUFeatureName[] = [];
96
99
  const requiredLimits: Record<string, number> = {};
97
100
 
98
- if (props.requestMaximalLimits) {
101
+ if (props.requestMaxLimits) {
99
102
  requiredFeatures.push(...(Array.from(adapter.features) as GPUFeatureName[]));
100
103
  for (const key in adapter.limits) {
101
104
  requiredLimits[key] = adapter.limits[key];
@@ -175,7 +178,11 @@ export class WebGPUDevice extends Device {
175
178
 
176
179
  /** @todo implement proper check? */
177
180
  isTextureFormatFilterable(format: TextureFormat): boolean {
178
- return this.isTextureFormatSupported(format);
181
+ return (
182
+ this.isTextureFormatSupported(format) &&
183
+ !format.startsWith('depth') &&
184
+ !format.startsWith('stencil')
185
+ );
179
186
  }
180
187
 
181
188
  /** @todo implement proper check? */
@@ -213,7 +220,7 @@ export class WebGPUDevice extends Device {
213
220
  }
214
221
 
215
222
  createFramebuffer(props: FramebufferProps): WebGPUFramebuffer {
216
- throw new Error('Not implemented');
223
+ return new WebGPUFramebuffer(this, props);
217
224
  }
218
225
 
219
226
  createComputePipeline(props: ComputePipelineProps): WebGPUComputePipeline {
@@ -256,22 +263,6 @@ export class WebGPUDevice extends Device {
256
263
  return new WebGPUCanvasContext(this, this.adapter, props);
257
264
  }
258
265
 
259
- /**
260
- * Gets default renderpass encoder.
261
- * Creates a new encoder against default canvasContext if not already created
262
- * @note Called internally by Model.
263
- * @deprecated Create explicit pass with device.beginRenderPass
264
- */
265
- getDefaultRenderPass(): WebGPURenderPass {
266
- // this.renderPass =
267
- // this.renderPass ||
268
- // this.beginRenderPass({
269
- // framebuffer: this.canvasContext?.getCurrentFramebuffer()
270
- // });
271
- // return this.renderPass;
272
- throw new Error('a');
273
- }
274
-
275
266
  submit(): void {
276
267
  // this.renderPass?.end();
277
268
  const commandBuffer = this.commandEncoder?.finish();
@@ -341,7 +332,7 @@ export class WebGPUDevice extends Device {
341
332
  features.add(feature);
342
333
  }
343
334
 
344
- return new DeviceFeatures(Array.from(features));
335
+ return new DeviceFeatures(Array.from(features), this.props.disabledFeatures);
345
336
  }
346
337
 
347
338
  copyExternalImageToTexture(options: {
@@ -1,10 +0,0 @@
1
- /// <reference types="dist" />
2
- /** WebGPU does not have built-in mipmap creation */
3
- export declare class WebGPUMipmapGenerator {
4
- device: GPUDevice;
5
- mipmapSampler: GPUSampler;
6
- mipmapPipeline: GPURenderPipeline;
7
- constructor(device: GPUDevice, glslang: any);
8
- generateMipmappedTexture(imageBitmap: ImageBitmap): GPUTexture;
9
- }
10
- //# sourceMappingURL=generate-mipmaps.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-mipmaps.d.ts","sourceRoot":"","sources":["../../../src/adapter/helpers/generate-mipmaps.ts"],"names":[],"mappings":";AA0BA,oDAAoD;AACpD,qBAAa,qBAAqB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,iBAAiB,CAAC;gBAEtB,MAAM,EAAE,SAAS,EAAE,OAAO,KAAA;IA2BtC,wBAAwB,CAAC,WAAW,EAAE,WAAW;CA0DlD"}