@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.
- package/dist/adapter/helpers/get-bind-group.d.ts +3 -3
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.js +3 -1
- package/dist/adapter/resources/webgpu-compute-pass.d.ts +14 -8
- package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js +18 -13
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +13 -3
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.js +25 -7
- package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-external-texture.js +2 -0
- package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-query-set.js +3 -1
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts +49 -1
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.js +69 -51
- package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.js +3 -0
- package/dist/adapter/resources/webgpu-shader.d.ts +1 -4
- package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-shader.js +7 -18
- package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture-view.js +3 -0
- package/dist/adapter/resources/webgpu-texture.d.ts +3 -4
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +8 -8
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +2 -1
- package/dist/adapter/webgpu-device.d.ts +2 -7
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +9 -19
- package/dist/dist.dev.js +130 -176
- package/dist/dist.min.js +9 -0
- package/dist/index.cjs +122 -131
- package/dist/index.cjs.map +4 -4
- package/package.json +5 -5
- package/src/.DS_Store +0 -0
- package/src/adapter/.DS_Store +0 -0
- package/src/adapter/helpers/get-bind-group.ts +4 -4
- package/src/adapter/resources/webgpu-buffer.ts +3 -1
- package/src/adapter/resources/webgpu-compute-pass.ts +19 -14
- package/src/adapter/resources/webgpu-compute-pipeline.ts +36 -9
- package/src/adapter/resources/webgpu-external-texture.ts +2 -0
- package/src/adapter/resources/webgpu-query-set.ts +3 -1
- package/src/adapter/resources/webgpu-render-pipeline.ts +63 -92
- package/src/adapter/resources/webgpu-sampler.ts +3 -0
- package/src/adapter/resources/webgpu-shader.ts +8 -23
- package/src/adapter/resources/webgpu-texture-view.ts +3 -0
- package/src/adapter/resources/webgpu-texture.ts +11 -10
- package/src/adapter/webgpu-canvas-context.ts +2 -1
- package/src/adapter/webgpu-device.ts +11 -20
- package/dist/adapter/helpers/generate-mipmaps.d.ts +0 -10
- package/dist/adapter/helpers/generate-mipmaps.d.ts.map +0 -1
- package/dist/adapter/helpers/generate-mipmaps.js +0 -103
- package/dist/adapter/resources/webgpu-query.d.ts +0 -1
- package/dist/adapter/resources/webgpu-query.d.ts.map +0 -1
- package/dist/adapter/resources/webgpu-query.js +0 -43
- package/dist/adapter/webgpu-types.d.ts +0 -1
- package/dist/adapter/webgpu-types.d.ts.map +0 -1
- package/dist/adapter/webgpu-types.js +0 -0
- package/dist/glsl/glsllang.d.ts +0 -3
- package/dist/glsl/glsllang.d.ts.map +0 -1
- package/dist/glsl/glsllang.js +0 -12
- package/dist.min.js +0 -9
- 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
|
-
|
|
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.
|
|
52
|
+
this._webgpuPipeline = wgpuPipeline;
|
|
53
|
+
this.setBindings([]);
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
/**
|
|
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
|
-
|
|
58
|
-
|
|
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
|
|
65
|
-
* @param y Y dimension of the grid of
|
|
66
|
-
* @param z Z dimension of the grid of
|
|
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
|
-
*
|
|
75
|
-
*
|
|
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,
|
|
82
|
+
dispatchIndirect(indirectBuffer: Buffer, indirectByteOffset: number = 0): void {
|
|
78
83
|
const webgpuBuffer = indirectBuffer as WebGPUBuffer;
|
|
79
|
-
this.handle.dispatchWorkgroupsIndirect(webgpuBuffer.handle,
|
|
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.
|
|
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.
|
|
29
|
-
|
|
35
|
+
entryPoint: this.props.entryPoint,
|
|
36
|
+
constants: this.props.constants
|
|
30
37
|
},
|
|
31
38
|
layout: 'auto'
|
|
32
39
|
});
|
|
33
40
|
}
|
|
34
41
|
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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 */
|
|
@@ -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
|
-
|
|
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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
-
}):
|
|
104
|
-
const 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
|
-
|
|
142
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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(
|
|
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
|
+
*/
|
|
@@ -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:
|
|
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
|
|
58
|
+
const {source} = this.props;
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -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.
|
|
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
|
|
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
|
-
|
|
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"}
|