@luma.gl/webgpu 9.1.0-beta.8 → 9.2.0-alpha.1
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/accessor-to-format.js +1 -0
- package/dist/adapter/helpers/accessor-to-format.js.map +1 -1
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +26 -10
- package/dist/adapter/helpers/get-bind-group.js.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +4 -4
- package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.js +66 -68
- package/dist/adapter/helpers/webgpu-parameters.js.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.js +12 -0
- package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-command-buffer.d.ts +10 -0
- package/dist/adapter/resources/webgpu-command-buffer.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-command-buffer.js +18 -0
- package/dist/adapter/resources/webgpu-command-buffer.js.map +1 -0
- package/dist/adapter/resources/webgpu-command-encoder.d.ts +12 -5
- package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.js +21 -5
- package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.js +2 -1
- package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.js +1 -1
- package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture-view.js +16 -10
- package/dist/adapter/resources/webgpu-texture-view.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture.d.ts +4 -37
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +98 -124
- package/dist/adapter/resources/webgpu-texture.js.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.d.ts +2 -2
- package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js +2 -2
- package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -1
- package/dist/adapter/webgpu-adapter.d.ts +2 -3
- package/dist/adapter/webgpu-adapter.d.ts.map +1 -1
- package/dist/adapter/webgpu-adapter.js +19 -10
- package/dist/adapter/webgpu-adapter.js.map +1 -1
- package/dist/adapter/webgpu-canvas-context.d.ts +1 -7
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +13 -18
- package/dist/adapter/webgpu-canvas-context.js.map +1 -1
- package/dist/adapter/webgpu-device.d.ts +8 -25
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +31 -61
- package/dist/adapter/webgpu-device.js.map +1 -1
- package/dist/dist.dev.js +1657 -1389
- package/dist/dist.min.js +4 -4
- package/dist/index.cjs +1510 -1270
- package/dist/index.cjs.map +4 -4
- package/package.json +3 -3
- package/src/adapter/helpers/get-bind-group.ts +28 -11
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +4 -4
- package/src/adapter/helpers/webgpu-parameters.ts +88 -97
- package/src/adapter/resources/webgpu-buffer.ts +12 -0
- package/src/adapter/resources/webgpu-command-buffer.ts +24 -0
- package/src/adapter/resources/webgpu-command-encoder.ts +27 -4
- package/src/adapter/resources/webgpu-compute-pass.ts +1 -1
- package/src/adapter/resources/webgpu-render-pass.ts +2 -1
- package/src/adapter/resources/webgpu-sampler.ts +1 -1
- package/src/adapter/resources/webgpu-texture-view.ts +15 -8
- package/src/adapter/resources/webgpu-texture.ts +106 -184
- package/src/adapter/resources/webgpu-vertex-array.ts +2 -2
- package/src/adapter/webgpu-adapter.ts +27 -14
- package/src/adapter/webgpu-canvas-context.ts +16 -20
- package/src/adapter/webgpu-device.ts +38 -99
package/dist/dist.dev.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
else if (typeof define === 'function' && define.amd) define([], factory);
|
|
5
5
|
else if (typeof exports === 'object') exports['luma'] = factory();
|
|
6
6
|
else root['luma'] = factory();})(globalThis, function () {
|
|
7
|
+
"use strict";
|
|
7
8
|
var __exports__ = (() => {
|
|
8
9
|
var __create = Object.create;
|
|
9
10
|
var __defProp = Object.defineProperty;
|
|
@@ -11,12 +12,15 @@ var __exports__ = (() => {
|
|
|
11
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
13
|
var __getProtoOf = Object.getPrototypeOf;
|
|
13
14
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
|
+
var __esm = (fn, res) => function __init() {
|
|
16
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
17
|
+
};
|
|
14
18
|
var __commonJS = (cb, mod) => function __require() {
|
|
15
19
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
16
20
|
};
|
|
17
21
|
var __export = (target, all) => {
|
|
18
|
-
for (var
|
|
19
|
-
__defProp(target,
|
|
22
|
+
for (var name2 in all)
|
|
23
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
20
24
|
};
|
|
21
25
|
var __copyProps = (to, from, except, desc) => {
|
|
22
26
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -44,99 +48,96 @@ var __exports__ = (() => {
|
|
|
44
48
|
}
|
|
45
49
|
});
|
|
46
50
|
|
|
47
|
-
// bundle.ts
|
|
48
|
-
var bundle_exports = {};
|
|
49
|
-
__export(bundle_exports, {
|
|
50
|
-
WebGPUBuffer: () => WebGPUBuffer,
|
|
51
|
-
WebGPUDevice: () => WebGPUDevice,
|
|
52
|
-
WebGPUSampler: () => WebGPUSampler,
|
|
53
|
-
WebGPUShader: () => WebGPUShader,
|
|
54
|
-
WebGPUTexture: () => WebGPUTexture,
|
|
55
|
-
webgpuAdapter: () => webgpuAdapter
|
|
56
|
-
});
|
|
57
|
-
__reExport(bundle_exports, __toESM(require_core(), 1));
|
|
58
|
-
|
|
59
|
-
// src/adapter/webgpu-adapter.ts
|
|
60
|
-
var import_core18 = __toESM(require_core(), 1);
|
|
61
|
-
|
|
62
|
-
// src/adapter/webgpu-device.ts
|
|
63
|
-
var import_core17 = __toESM(require_core(), 1);
|
|
64
|
-
|
|
65
51
|
// src/adapter/resources/webgpu-buffer.ts
|
|
66
|
-
var import_core = __toESM(require_core(), 1);
|
|
67
52
|
function getByteLength(props) {
|
|
68
53
|
return props.byteLength || props.data?.byteLength || 0;
|
|
69
54
|
}
|
|
70
|
-
var
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
55
|
+
var import_core, WebGPUBuffer;
|
|
56
|
+
var init_webgpu_buffer = __esm({
|
|
57
|
+
"src/adapter/resources/webgpu-buffer.ts"() {
|
|
58
|
+
"use strict";
|
|
59
|
+
import_core = __toESM(require_core(), 1);
|
|
60
|
+
WebGPUBuffer = class extends import_core.Buffer {
|
|
61
|
+
device;
|
|
62
|
+
handle;
|
|
63
|
+
byteLength;
|
|
64
|
+
constructor(device, props) {
|
|
65
|
+
super(device, props);
|
|
66
|
+
this.device = device;
|
|
67
|
+
this.byteLength = getByteLength(props);
|
|
68
|
+
const mapBuffer = Boolean(props.data);
|
|
69
|
+
const size = Math.ceil(this.byteLength / 4) * 4;
|
|
70
|
+
this.device.handle.pushErrorScope("out-of-memory");
|
|
71
|
+
this.device.handle.pushErrorScope("validation");
|
|
72
|
+
this.handle = this.props.handle || this.device.handle.createBuffer({
|
|
73
|
+
size,
|
|
74
|
+
// usage defaults to vertex
|
|
75
|
+
usage: this.props.usage || GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
|
76
|
+
mappedAtCreation: this.props.mappedAtCreation || mapBuffer,
|
|
77
|
+
label: this.props.id
|
|
78
|
+
});
|
|
79
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
80
|
+
if (error) {
|
|
81
|
+
this.device.reportError(new Error(`Buffer validation failed: ${error.message}`), this);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
85
|
+
if (error) {
|
|
86
|
+
this.device.reportError(new Error(`Buffer out of memory: ${error.message}`), this);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (props.data) {
|
|
90
|
+
this._writeMapped(props.data);
|
|
91
|
+
}
|
|
92
|
+
if (mapBuffer && !props.mappedAtCreation) {
|
|
93
|
+
this.handle.unmap();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
destroy() {
|
|
97
|
+
this.handle?.destroy();
|
|
98
|
+
this.handle = null;
|
|
99
|
+
}
|
|
100
|
+
// WebGPU provides multiple ways to write a buffer...
|
|
101
|
+
write(data, byteOffset = 0) {
|
|
102
|
+
this.device.handle.queue.writeBuffer(
|
|
103
|
+
this.handle,
|
|
104
|
+
byteOffset,
|
|
105
|
+
data.buffer,
|
|
106
|
+
data.byteOffset,
|
|
107
|
+
data.byteLength
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
async readAsync(byteOffset = 0, byteLength = this.byteLength) {
|
|
111
|
+
const tempBuffer = new WebGPUBuffer(this.device, {
|
|
112
|
+
usage: import_core.Buffer.MAP_READ | import_core.Buffer.COPY_DST,
|
|
113
|
+
byteLength
|
|
114
|
+
});
|
|
115
|
+
const commandEncoder = this.device.handle.createCommandEncoder();
|
|
116
|
+
commandEncoder.copyBufferToBuffer(this.handle, byteOffset, tempBuffer.handle, 0, byteLength);
|
|
117
|
+
this.device.handle.queue.submit([commandEncoder.finish()]);
|
|
118
|
+
await tempBuffer.handle.mapAsync(GPUMapMode.READ, byteOffset, byteLength);
|
|
119
|
+
const arrayBuffer = tempBuffer.handle.getMappedRange().slice(0);
|
|
120
|
+
tempBuffer.handle.unmap();
|
|
121
|
+
tempBuffer.destroy();
|
|
122
|
+
return new Uint8Array(arrayBuffer);
|
|
123
|
+
}
|
|
124
|
+
_writeMapped(typedArray) {
|
|
125
|
+
const arrayBuffer = this.handle.getMappedRange();
|
|
126
|
+
new typedArray.constructor(arrayBuffer).set(typedArray);
|
|
127
|
+
}
|
|
128
|
+
// WEBGPU API
|
|
129
|
+
mapAsync(mode, offset = 0, size) {
|
|
130
|
+
return this.handle.mapAsync(mode, offset, size);
|
|
131
|
+
}
|
|
132
|
+
getMappedRange(offset = 0, size) {
|
|
133
|
+
return this.handle.getMappedRange(offset, size);
|
|
134
|
+
}
|
|
135
|
+
unmap() {
|
|
136
|
+
this.handle.unmap();
|
|
137
|
+
}
|
|
138
|
+
};
|
|
135
139
|
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
// src/adapter/resources/webgpu-texture.ts
|
|
139
|
-
var import_core4 = __toESM(require_core(), 1);
|
|
140
|
+
});
|
|
140
141
|
|
|
141
142
|
// src/adapter/helpers/convert-texture-format.ts
|
|
142
143
|
function getWebGPUTextureFormat(format) {
|
|
@@ -145,343 +146,365 @@ var __exports__ = (() => {
|
|
|
145
146
|
}
|
|
146
147
|
return format;
|
|
147
148
|
}
|
|
149
|
+
var init_convert_texture_format = __esm({
|
|
150
|
+
"src/adapter/helpers/convert-texture-format.ts"() {
|
|
151
|
+
"use strict";
|
|
152
|
+
}
|
|
153
|
+
});
|
|
148
154
|
|
|
149
155
|
// src/adapter/resources/webgpu-sampler.ts
|
|
150
|
-
var import_core2
|
|
151
|
-
var
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
var import_core2, WebGPUSampler;
|
|
157
|
+
var init_webgpu_sampler = __esm({
|
|
158
|
+
"src/adapter/resources/webgpu-sampler.ts"() {
|
|
159
|
+
"use strict";
|
|
160
|
+
import_core2 = __toESM(require_core(), 1);
|
|
161
|
+
WebGPUSampler = class extends import_core2.Sampler {
|
|
162
|
+
device;
|
|
163
|
+
handle;
|
|
164
|
+
constructor(device, props) {
|
|
165
|
+
super(device, props);
|
|
166
|
+
this.device = device;
|
|
167
|
+
const samplerDescriptor = {
|
|
168
|
+
...this.props,
|
|
169
|
+
mipmapFilter: void 0
|
|
170
|
+
};
|
|
171
|
+
if (props.type !== "comparison-sampler") {
|
|
172
|
+
delete samplerDescriptor.compare;
|
|
173
|
+
}
|
|
174
|
+
if (props.mipmapFilter && props.mipmapFilter !== "none") {
|
|
175
|
+
samplerDescriptor.mipmapFilter = props.mipmapFilter;
|
|
176
|
+
}
|
|
177
|
+
this.handle = props.handle || this.device.handle.createSampler(samplerDescriptor);
|
|
178
|
+
this.handle.label = this.props.id;
|
|
179
|
+
}
|
|
180
|
+
destroy() {
|
|
181
|
+
this.handle = null;
|
|
182
|
+
}
|
|
160
183
|
};
|
|
161
|
-
if (props.type !== "comparison-sampler") {
|
|
162
|
-
delete samplerDescriptor.compare;
|
|
163
|
-
}
|
|
164
|
-
if (props.mipmapFilter && props.mipmapFilter !== "none") {
|
|
165
|
-
samplerDescriptor.mipmapFilter = props.mipmapFilter;
|
|
166
|
-
}
|
|
167
|
-
this.handle = this.handle || this.device.handle.createSampler(samplerDescriptor);
|
|
168
|
-
this.handle.label = this.props.id;
|
|
169
184
|
}
|
|
170
|
-
|
|
171
|
-
this.handle = null;
|
|
172
|
-
}
|
|
173
|
-
};
|
|
185
|
+
});
|
|
174
186
|
|
|
175
187
|
// src/adapter/resources/webgpu-texture-view.ts
|
|
176
|
-
var import_core3
|
|
177
|
-
var
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
188
|
+
var import_core3, WebGPUTextureView;
|
|
189
|
+
var init_webgpu_texture_view = __esm({
|
|
190
|
+
"src/adapter/resources/webgpu-texture-view.ts"() {
|
|
191
|
+
"use strict";
|
|
192
|
+
import_core3 = __toESM(require_core(), 1);
|
|
193
|
+
WebGPUTextureView = class extends import_core3.TextureView {
|
|
194
|
+
device;
|
|
195
|
+
handle;
|
|
196
|
+
texture;
|
|
197
|
+
constructor(device, props) {
|
|
198
|
+
super(device, props);
|
|
199
|
+
this.device = device;
|
|
200
|
+
this.texture = props.texture;
|
|
201
|
+
this.device.pushErrorScope("validation");
|
|
202
|
+
this.handle = // props.handle ||
|
|
203
|
+
this.texture.handle.createView({
|
|
204
|
+
format: this.props.format || this.texture.format,
|
|
205
|
+
dimension: this.props.dimension || this.texture.dimension,
|
|
206
|
+
aspect: this.props.aspect,
|
|
207
|
+
baseMipLevel: this.props.baseMipLevel,
|
|
208
|
+
mipLevelCount: this.props.mipLevelCount,
|
|
209
|
+
baseArrayLayer: this.props.baseArrayLayer,
|
|
210
|
+
arrayLayerCount: this.props.arrayLayerCount
|
|
211
|
+
});
|
|
212
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
213
|
+
if (error) {
|
|
214
|
+
this.device.reportError(new Error(`TextureView validation failed: ${error.message}`), this);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
this.handle.label = this.props.id;
|
|
218
|
+
}
|
|
219
|
+
destroy() {
|
|
220
|
+
this.handle = null;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
201
223
|
}
|
|
202
|
-
};
|
|
224
|
+
});
|
|
203
225
|
|
|
204
226
|
// src/adapter/resources/webgpu-texture.ts
|
|
205
|
-
var
|
|
206
|
-
|
|
207
|
-
"
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
this.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
this.width = this.handle.width;
|
|
245
|
-
this.height = this.handle.height;
|
|
246
|
-
this.sampler = props.sampler instanceof WebGPUSampler ? props.sampler : new WebGPUSampler(this.device, props.sampler || {});
|
|
247
|
-
this.view = new WebGPUTextureView(this.device, { ...this.props, texture: this });
|
|
248
|
-
}
|
|
249
|
-
createHandle() {
|
|
250
|
-
const width = this.props.width || this.props.data?.width || 1;
|
|
251
|
-
const height = this.props.height || this.props.data?.height || 1;
|
|
252
|
-
return this.device.handle.createTexture({
|
|
253
|
-
label: this.id,
|
|
254
|
-
size: {
|
|
255
|
-
width,
|
|
256
|
-
height,
|
|
257
|
-
depthOrArrayLayers: this.depth
|
|
258
|
-
},
|
|
259
|
-
usage: this.props.usage || import_core4.Texture.TEXTURE | import_core4.Texture.COPY_DST,
|
|
260
|
-
dimension: BASE_DIMENSIONS[this.dimension],
|
|
261
|
-
format: getWebGPUTextureFormat(this.format),
|
|
262
|
-
mipLevelCount: this.mipLevels,
|
|
263
|
-
sampleCount: this.props.samples
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
/** @deprecated - intention is to use the createView public API */
|
|
267
|
-
createGPUTextureView() {
|
|
268
|
-
return this.handle.createView({ label: this.id });
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Set default sampler
|
|
272
|
-
* Accept a sampler instance or set of props;
|
|
273
|
-
*/
|
|
274
|
-
setSampler(sampler) {
|
|
275
|
-
this.sampler = sampler instanceof WebGPUSampler ? sampler : new WebGPUSampler(this.device, sampler);
|
|
276
|
-
return this;
|
|
277
|
-
}
|
|
278
|
-
setTexture1DData(data) {
|
|
279
|
-
throw new Error("not implemented");
|
|
280
|
-
}
|
|
281
|
-
setTexture2DData(lodData, depth, target) {
|
|
282
|
-
throw new Error("not implemented");
|
|
283
|
-
}
|
|
284
|
-
setTexture3DData(lodData, depth, target) {
|
|
285
|
-
throw new Error("not implemented");
|
|
286
|
-
}
|
|
287
|
-
setTextureCubeData(data, depth) {
|
|
288
|
-
throw new Error("not implemented");
|
|
289
|
-
}
|
|
290
|
-
setTextureArrayData(data) {
|
|
291
|
-
throw new Error("not implemented");
|
|
292
|
-
}
|
|
293
|
-
setTextureCubeArrayData(data) {
|
|
294
|
-
throw new Error("not implemented");
|
|
295
|
-
}
|
|
296
|
-
setData(options) {
|
|
297
|
-
if (ArrayBuffer.isView(options.data)) {
|
|
298
|
-
const clampedArray = new Uint8ClampedArray(options.data.buffer);
|
|
299
|
-
const image = new ImageData(clampedArray, this.width, this.height);
|
|
300
|
-
return this.copyExternalImage({ image });
|
|
301
|
-
}
|
|
302
|
-
throw new Error("Texture.setData: Use CommandEncoder to upload data to texture in WebGPU");
|
|
303
|
-
}
|
|
304
|
-
copyExternalImage(options) {
|
|
305
|
-
const size = import_core4.Texture.getExternalImageSize(options.image);
|
|
306
|
-
const opts = { ...import_core4.Texture.defaultCopyExternalImageOptions, ...size, ...options };
|
|
307
|
-
const {
|
|
308
|
-
image,
|
|
309
|
-
sourceX,
|
|
310
|
-
sourceY,
|
|
311
|
-
width,
|
|
312
|
-
height,
|
|
313
|
-
depth,
|
|
314
|
-
mipLevel,
|
|
315
|
-
x,
|
|
316
|
-
y,
|
|
317
|
-
z,
|
|
318
|
-
aspect,
|
|
319
|
-
colorSpace,
|
|
320
|
-
premultipliedAlpha,
|
|
321
|
-
flipY
|
|
322
|
-
} = opts;
|
|
323
|
-
this.device.handle.queue.copyExternalImageToTexture(
|
|
324
|
-
// source: GPUImageCopyExternalImage
|
|
325
|
-
{
|
|
326
|
-
source: image,
|
|
327
|
-
origin: [sourceX, sourceY],
|
|
328
|
-
flipY
|
|
329
|
-
},
|
|
330
|
-
// destination: GPUImageCopyTextureTagged
|
|
331
|
-
{
|
|
332
|
-
texture: this.handle,
|
|
333
|
-
origin: [x, y, z],
|
|
334
|
-
mipLevel,
|
|
335
|
-
aspect,
|
|
336
|
-
colorSpace,
|
|
337
|
-
premultipliedAlpha
|
|
338
|
-
},
|
|
339
|
-
// copySize: GPUExtent3D
|
|
340
|
-
[width, height, depth]
|
|
341
|
-
);
|
|
342
|
-
return { width, height };
|
|
343
|
-
}
|
|
344
|
-
// WebGPU specific
|
|
345
|
-
/*
|
|
346
|
-
async readPixels() {
|
|
347
|
-
const readbackBuffer = device.createBuffer({
|
|
348
|
-
usage: Buffer.COPY_DST | Buffer.MAP_READ,
|
|
349
|
-
size: 4 * textureWidth * textureHeight,
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
// Copy data from the texture to the buffer.
|
|
353
|
-
const encoder = device.createCommandEncoder();
|
|
354
|
-
encoder.copyTextureToBuffer(
|
|
355
|
-
{ texture },
|
|
356
|
-
{ buffer, rowPitch: textureWidth * 4 },
|
|
357
|
-
[textureWidth, textureHeight],
|
|
358
|
-
);
|
|
359
|
-
device.submit([encoder.finish()]);
|
|
360
|
-
|
|
361
|
-
// Get the data on the CPU.
|
|
362
|
-
await buffer.mapAsync(GPUMapMode.READ);
|
|
363
|
-
saveScreenshot(buffer.getMappedRange());
|
|
364
|
-
buffer.unmap();
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
setImageData(imageData, usage): this {
|
|
368
|
-
let data = null;
|
|
369
|
-
|
|
370
|
-
const bytesPerRow = Math.ceil((img.width * 4) / 256) * 256;
|
|
371
|
-
if (bytesPerRow == img.width * 4) {
|
|
372
|
-
data = imageData.data;
|
|
373
|
-
} else {
|
|
374
|
-
data = new Uint8Array(bytesPerRow * img.height);
|
|
375
|
-
let imagePixelIndex = 0;
|
|
376
|
-
for (let y = 0; y < img.height; ++y) {
|
|
377
|
-
for (let x = 0; x < img.width; ++x) {
|
|
378
|
-
const i = x * 4 + y * bytesPerRow;
|
|
379
|
-
data[i] = imageData.data[imagePixelIndex];
|
|
380
|
-
data[i + 1] = imageData.data[imagePixelIndex + 1];
|
|
381
|
-
data[i + 2] = imageData.data[imagePixelIndex + 2];
|
|
382
|
-
data[i + 3] = imageData.data[imagePixelIndex + 3];
|
|
383
|
-
imagePixelIndex += 4;
|
|
227
|
+
var import_core4, WebGPUTexture;
|
|
228
|
+
var init_webgpu_texture = __esm({
|
|
229
|
+
"src/adapter/resources/webgpu-texture.ts"() {
|
|
230
|
+
"use strict";
|
|
231
|
+
import_core4 = __toESM(require_core(), 1);
|
|
232
|
+
init_convert_texture_format();
|
|
233
|
+
init_webgpu_sampler();
|
|
234
|
+
init_webgpu_texture_view();
|
|
235
|
+
WebGPUTexture = class extends import_core4.Texture {
|
|
236
|
+
device;
|
|
237
|
+
handle;
|
|
238
|
+
sampler;
|
|
239
|
+
view;
|
|
240
|
+
constructor(device, props) {
|
|
241
|
+
super(device, props);
|
|
242
|
+
this.device = device;
|
|
243
|
+
if (this.dimension === "cube") {
|
|
244
|
+
this.depth = 6;
|
|
245
|
+
}
|
|
246
|
+
this.device.handle.pushErrorScope("out-of-memory");
|
|
247
|
+
this.device.handle.pushErrorScope("validation");
|
|
248
|
+
this.handle = this.props.handle || this.device.handle.createTexture({
|
|
249
|
+
label: this.id,
|
|
250
|
+
size: {
|
|
251
|
+
width: this.width,
|
|
252
|
+
height: this.height,
|
|
253
|
+
depthOrArrayLayers: this.depth
|
|
254
|
+
},
|
|
255
|
+
usage: this.props.usage || import_core4.Texture.TEXTURE | import_core4.Texture.COPY_DST,
|
|
256
|
+
dimension: this.baseDimension,
|
|
257
|
+
format: getWebGPUTextureFormat(this.format),
|
|
258
|
+
mipLevelCount: this.mipLevels,
|
|
259
|
+
sampleCount: this.props.samples
|
|
260
|
+
});
|
|
261
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
262
|
+
if (error) {
|
|
263
|
+
this.device.reportError(new Error(`Texture validation failed: ${error.message}`), this);
|
|
384
264
|
}
|
|
265
|
+
});
|
|
266
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
267
|
+
if (error) {
|
|
268
|
+
this.device.reportError(new Error(`Texture out of memory: ${error.message}`), this);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
if (this.props.handle) {
|
|
272
|
+
this.handle.label ||= this.id;
|
|
273
|
+
this.width = this.handle.width;
|
|
274
|
+
this.height = this.handle.height;
|
|
385
275
|
}
|
|
276
|
+
this.sampler = props.sampler instanceof WebGPUSampler ? props.sampler : new WebGPUSampler(this.device, props.sampler || {});
|
|
277
|
+
this.view = new WebGPUTextureView(this.device, {
|
|
278
|
+
...this.props,
|
|
279
|
+
texture: this,
|
|
280
|
+
mipLevelCount: this.mipLevels,
|
|
281
|
+
arrayLayerCount: this.depth
|
|
282
|
+
});
|
|
283
|
+
this._initializeData(props.data);
|
|
386
284
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
285
|
+
destroy() {
|
|
286
|
+
this.handle?.destroy();
|
|
287
|
+
this.handle = null;
|
|
288
|
+
}
|
|
289
|
+
createView(props) {
|
|
290
|
+
return new WebGPUTextureView(this.device, { ...props, texture: this });
|
|
291
|
+
}
|
|
292
|
+
copyImageData(options_) {
|
|
293
|
+
const { width, height, depth } = this;
|
|
294
|
+
const options = this._normalizeCopyImageDataOptions(options_);
|
|
295
|
+
this.device.handle.pushErrorScope("validation");
|
|
296
|
+
this.device.handle.queue.writeTexture(
|
|
297
|
+
// destination: GPUImageCopyTexture
|
|
298
|
+
{
|
|
299
|
+
// texture subresource
|
|
300
|
+
texture: this.handle,
|
|
301
|
+
mipLevel: options.mipLevel,
|
|
302
|
+
aspect: options.aspect,
|
|
303
|
+
// origin to write to
|
|
304
|
+
origin: [options.x, options.y, options.z]
|
|
305
|
+
},
|
|
306
|
+
// data
|
|
307
|
+
options.data,
|
|
308
|
+
// dataLayout: GPUImageDataLayout
|
|
309
|
+
{
|
|
310
|
+
offset: options.byteOffset,
|
|
311
|
+
bytesPerRow: options.bytesPerRow,
|
|
312
|
+
rowsPerImage: options.rowsPerImage
|
|
313
|
+
},
|
|
314
|
+
// size: GPUExtent3D - extents of the content to write
|
|
315
|
+
[width, height, depth]
|
|
316
|
+
);
|
|
317
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
318
|
+
if (error) {
|
|
319
|
+
this.device.reportError(new Error(`copyImageData validation failed: ${error.message}`));
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
copyExternalImage(options_) {
|
|
324
|
+
const options = this._normalizeCopyExternalImageOptions(options_);
|
|
325
|
+
this.device.handle.pushErrorScope("validation");
|
|
326
|
+
this.device.handle.queue.copyExternalImageToTexture(
|
|
327
|
+
// source: GPUImageCopyExternalImage
|
|
328
|
+
{
|
|
329
|
+
source: options.image,
|
|
330
|
+
origin: [options.sourceX, options.sourceY],
|
|
331
|
+
flipY: options.flipY
|
|
332
|
+
},
|
|
333
|
+
// destination: GPUImageCopyTextureTagged
|
|
334
|
+
{
|
|
335
|
+
texture: this.handle,
|
|
336
|
+
origin: [options.x, options.y, options.depth],
|
|
337
|
+
mipLevel: options.mipLevel,
|
|
338
|
+
aspect: options.aspect,
|
|
339
|
+
colorSpace: options.colorSpace,
|
|
340
|
+
premultipliedAlpha: options.premultipliedAlpha
|
|
341
|
+
},
|
|
342
|
+
// copySize: GPUExtent3D
|
|
343
|
+
[options.width, options.height, 1]
|
|
344
|
+
);
|
|
345
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
346
|
+
if (error) {
|
|
347
|
+
this.device.reportError(new Error(`copyExternalImage validation failed: ${error.message}`));
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
return { width: options.width, height: options.height };
|
|
351
|
+
}
|
|
352
|
+
generateMipmapsWebGL() {
|
|
353
|
+
import_core4.log.warn(`${this}: generateMipmaps not supported in WebGPU`)();
|
|
354
|
+
}
|
|
355
|
+
// WebGPU specific
|
|
356
|
+
/*
|
|
357
|
+
async readPixels() {
|
|
358
|
+
const readbackBuffer = device.createBuffer({
|
|
359
|
+
usage: Buffer.COPY_DST | Buffer.MAP_READ,
|
|
360
|
+
size: 4 * textureWidth * textureHeight,
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// Copy data from the texture to the buffer.
|
|
364
|
+
const encoder = device.createCommandEncoder();
|
|
365
|
+
encoder.copyTextureToBuffer(
|
|
366
|
+
{ texture },
|
|
367
|
+
{ buffer, rowPitch: textureWidth * 4 },
|
|
368
|
+
[textureWidth, textureHeight],
|
|
369
|
+
);
|
|
370
|
+
device.submit([encoder.finish()]);
|
|
371
|
+
|
|
372
|
+
// Get the data on the CPU.
|
|
373
|
+
await buffer.mapAsync(GPUMapMode.READ);
|
|
374
|
+
saveScreenshot(buffer.getMappedRange());
|
|
375
|
+
buffer.unmap();
|
|
404
376
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
377
|
+
|
|
378
|
+
setImageData(imageData, usage): this {
|
|
379
|
+
let data = null;
|
|
380
|
+
|
|
381
|
+
const bytesPerRow = Math.ceil((img.width * 4) / 256) * 256;
|
|
382
|
+
if (bytesPerRow == img.width * 4) {
|
|
383
|
+
data = imageData.data;
|
|
384
|
+
} else {
|
|
385
|
+
data = new Uint8Array(bytesPerRow * img.height);
|
|
386
|
+
let imagePixelIndex = 0;
|
|
387
|
+
for (let y = 0; y < img.height; ++y) {
|
|
388
|
+
for (let x = 0; x < img.width; ++x) {
|
|
389
|
+
const i = x * 4 + y * bytesPerRow;
|
|
390
|
+
data[i] = imageData.data[imagePixelIndex];
|
|
391
|
+
data[i + 1] = imageData.data[imagePixelIndex + 1];
|
|
392
|
+
data[i + 2] = imageData.data[imagePixelIndex + 2];
|
|
393
|
+
data[i + 3] = imageData.data[imagePixelIndex + 3];
|
|
394
|
+
imagePixelIndex += 4;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return this;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
setBuffer(textureDataBuffer, {bytesPerRow}): this {
|
|
402
|
+
const commandEncoder = this.device.handle.createCommandEncoder();
|
|
403
|
+
commandEncoder.copyBufferToTexture(
|
|
404
|
+
{
|
|
405
|
+
buffer: textureDataBuffer,
|
|
406
|
+
bytesPerRow
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
texture: this.handle
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
width,
|
|
413
|
+
height,
|
|
414
|
+
depth
|
|
415
|
+
}
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
this.device.handle.defaultQueue.submit([commandEncoder.finish()]);
|
|
419
|
+
return this;
|
|
420
|
+
}
|
|
421
|
+
*/
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
});
|
|
412
425
|
|
|
413
426
|
// src/adapter/resources/webgpu-external-texture.ts
|
|
414
|
-
var import_core5
|
|
415
|
-
var
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
427
|
+
var import_core5, WebGPUExternalTexture;
|
|
428
|
+
var init_webgpu_external_texture = __esm({
|
|
429
|
+
"src/adapter/resources/webgpu-external-texture.ts"() {
|
|
430
|
+
"use strict";
|
|
431
|
+
import_core5 = __toESM(require_core(), 1);
|
|
432
|
+
init_webgpu_sampler();
|
|
433
|
+
WebGPUExternalTexture = class extends import_core5.ExternalTexture {
|
|
434
|
+
device;
|
|
435
|
+
handle;
|
|
436
|
+
sampler;
|
|
437
|
+
constructor(device, props) {
|
|
438
|
+
super(device, props);
|
|
439
|
+
this.device = device;
|
|
440
|
+
this.handle = this.props.handle || this.device.handle.importExternalTexture({
|
|
441
|
+
source: props.source,
|
|
442
|
+
colorSpace: props.colorSpace
|
|
443
|
+
});
|
|
444
|
+
this.sampler = null;
|
|
445
|
+
}
|
|
446
|
+
destroy() {
|
|
447
|
+
this.handle = null;
|
|
448
|
+
}
|
|
449
|
+
/** Set default sampler */
|
|
450
|
+
setSampler(sampler) {
|
|
451
|
+
this.sampler = sampler instanceof WebGPUSampler ? sampler : new WebGPUSampler(this.device, sampler);
|
|
452
|
+
return this;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
435
455
|
}
|
|
436
|
-
};
|
|
456
|
+
});
|
|
437
457
|
|
|
438
458
|
// src/adapter/resources/webgpu-shader.ts
|
|
439
|
-
var import_core6
|
|
440
|
-
var
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
459
|
+
var import_core6, WebGPUShader;
|
|
460
|
+
var init_webgpu_shader = __esm({
|
|
461
|
+
"src/adapter/resources/webgpu-shader.ts"() {
|
|
462
|
+
"use strict";
|
|
463
|
+
import_core6 = __toESM(require_core(), 1);
|
|
464
|
+
WebGPUShader = class extends import_core6.Shader {
|
|
465
|
+
device;
|
|
466
|
+
handle;
|
|
467
|
+
constructor(device, props) {
|
|
468
|
+
super(device, props);
|
|
469
|
+
this.device = device;
|
|
470
|
+
const isGLSL = props.source.includes("#version");
|
|
471
|
+
if (this.props.language === "glsl" || isGLSL) {
|
|
472
|
+
throw new Error("GLSL shaders are not supported in WebGPU");
|
|
473
|
+
}
|
|
474
|
+
this.device.handle.pushErrorScope("validation");
|
|
475
|
+
this.handle = this.props.handle || this.device.handle.createShaderModule({ code: props.source });
|
|
476
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
477
|
+
if (error) {
|
|
478
|
+
import_core6.log.error(`${this} creation failed:
|
|
455
479
|
"${error.message}"`, this, this.props.source)();
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
this.handle.label = this.props.id;
|
|
483
|
+
this._checkCompilationError();
|
|
456
484
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const compilationInfo = await this.handle.getCompilationInfo();
|
|
479
|
-
return compilationInfo.messages;
|
|
485
|
+
get asyncCompilationStatus() {
|
|
486
|
+
return this.getCompilationInfo().then(() => this.compilationStatus);
|
|
487
|
+
}
|
|
488
|
+
async _checkCompilationError() {
|
|
489
|
+
const shaderLog = await this.getCompilationInfo();
|
|
490
|
+
const hasErrors = Boolean(shaderLog.find((msg) => msg.type === "error"));
|
|
491
|
+
this.compilationStatus = hasErrors ? "error" : "success";
|
|
492
|
+
this.debugShader();
|
|
493
|
+
if (this.compilationStatus === "error") {
|
|
494
|
+
import_core6.log.error(`Shader compilation error`, shaderLog)();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
destroy() {
|
|
498
|
+
this.handle = null;
|
|
499
|
+
}
|
|
500
|
+
/** Returns compilation info for this shader */
|
|
501
|
+
async getCompilationInfo() {
|
|
502
|
+
const compilationInfo = await this.handle.getCompilationInfo();
|
|
503
|
+
return compilationInfo.messages;
|
|
504
|
+
}
|
|
505
|
+
};
|
|
480
506
|
}
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
// src/adapter/resources/webgpu-render-pipeline.ts
|
|
484
|
-
var import_core9 = __toESM(require_core(), 1);
|
|
507
|
+
});
|
|
485
508
|
|
|
486
509
|
// src/adapter/helpers/webgpu-parameters.ts
|
|
487
510
|
function addDepthStencil(descriptor) {
|
|
@@ -504,157 +527,6 @@ var __exports__ = (() => {
|
|
|
504
527
|
const depthStencil = addDepthStencil(descriptor);
|
|
505
528
|
return depthStencil.stencilBack;
|
|
506
529
|
}
|
|
507
|
-
var PARAMETER_TABLE = {
|
|
508
|
-
// RASTERIZATION PARAMETERS
|
|
509
|
-
cullMode: (parameter, value, descriptor) => {
|
|
510
|
-
descriptor.primitive = descriptor.primitive || {};
|
|
511
|
-
descriptor.primitive.cullMode = value;
|
|
512
|
-
},
|
|
513
|
-
frontFace: (parameter, value, descriptor) => {
|
|
514
|
-
descriptor.primitive = descriptor.primitive || {};
|
|
515
|
-
descriptor.primitive.frontFace = value;
|
|
516
|
-
},
|
|
517
|
-
// DEPTH
|
|
518
|
-
depthWriteEnabled: (parameter, value, descriptor) => {
|
|
519
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
520
|
-
depthStencil.depthWriteEnabled = value;
|
|
521
|
-
},
|
|
522
|
-
depthCompare: (parameter, value, descriptor) => {
|
|
523
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
524
|
-
depthStencil.depthCompare = value;
|
|
525
|
-
},
|
|
526
|
-
depthFormat: (parameter, value, descriptor) => {
|
|
527
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
528
|
-
depthStencil.format = value;
|
|
529
|
-
},
|
|
530
|
-
depthBias: (parameter, value, descriptor) => {
|
|
531
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
532
|
-
depthStencil.depthBias = value;
|
|
533
|
-
},
|
|
534
|
-
depthBiasSlopeScale: (parameter, value, descriptor) => {
|
|
535
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
536
|
-
depthStencil.depthBiasSlopeScale = value;
|
|
537
|
-
},
|
|
538
|
-
depthBiasClamp: (parameter, value, descriptor) => {
|
|
539
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
540
|
-
depthStencil.depthBiasClamp = value;
|
|
541
|
-
},
|
|
542
|
-
// STENCIL
|
|
543
|
-
stencilReadMask: (parameter, value, descriptor) => {
|
|
544
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
545
|
-
depthStencil.stencilReadMask = value;
|
|
546
|
-
},
|
|
547
|
-
stencilWriteMask: (parameter, value, descriptor) => {
|
|
548
|
-
const depthStencil = addDepthStencil(descriptor);
|
|
549
|
-
depthStencil.stencilWriteMask = value;
|
|
550
|
-
},
|
|
551
|
-
stencilCompare: (parameter, value, descriptor) => {
|
|
552
|
-
const stencilFront = addDepthStencilFront(descriptor);
|
|
553
|
-
const stencilBack = addDepthStencilBack(descriptor);
|
|
554
|
-
stencilFront.compare = value;
|
|
555
|
-
stencilBack.compare = value;
|
|
556
|
-
},
|
|
557
|
-
stencilPassOperation: (parameter, value, descriptor) => {
|
|
558
|
-
const stencilFront = addDepthStencilFront(descriptor);
|
|
559
|
-
const stencilBack = addDepthStencilBack(descriptor);
|
|
560
|
-
stencilFront.passOp = value;
|
|
561
|
-
stencilBack.passOp = value;
|
|
562
|
-
},
|
|
563
|
-
stencilFailOperation: (parameter, value, descriptor) => {
|
|
564
|
-
const stencilFront = addDepthStencilFront(descriptor);
|
|
565
|
-
const stencilBack = addDepthStencilBack(descriptor);
|
|
566
|
-
stencilFront.failOp = value;
|
|
567
|
-
stencilBack.failOp = value;
|
|
568
|
-
},
|
|
569
|
-
stencilDepthFailOperation: (parameter, value, descriptor) => {
|
|
570
|
-
const stencilFront = addDepthStencilFront(descriptor);
|
|
571
|
-
const stencilBack = addDepthStencilBack(descriptor);
|
|
572
|
-
stencilFront.depthFailOp = value;
|
|
573
|
-
stencilBack.depthFailOp = value;
|
|
574
|
-
},
|
|
575
|
-
// MULTISAMPLE
|
|
576
|
-
sampleCount: (parameter, value, descriptor) => {
|
|
577
|
-
descriptor.multisample = descriptor.multisample || {};
|
|
578
|
-
descriptor.multisample.count = value;
|
|
579
|
-
},
|
|
580
|
-
sampleMask: (parameter, value, descriptor) => {
|
|
581
|
-
descriptor.multisample = descriptor.multisample || {};
|
|
582
|
-
descriptor.multisample.mask = value;
|
|
583
|
-
},
|
|
584
|
-
sampleAlphaToCoverageEnabled: (parameter, value, descriptor) => {
|
|
585
|
-
descriptor.multisample = descriptor.multisample || {};
|
|
586
|
-
descriptor.multisample.alphaToCoverageEnabled = value;
|
|
587
|
-
},
|
|
588
|
-
// COLOR
|
|
589
|
-
colorMask: (parameter, value, descriptor) => {
|
|
590
|
-
const targets = addColorState(descriptor);
|
|
591
|
-
targets[0].writeMask = value;
|
|
592
|
-
},
|
|
593
|
-
blendColorOperation: (parameter, value, descriptor) => {
|
|
594
|
-
addColorState(descriptor);
|
|
595
|
-
}
|
|
596
|
-
/*
|
|
597
|
-
blendColorSrcTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
|
|
598
|
-
addColorState(descriptor);
|
|
599
|
-
targets[0].blend = targets[0].blend || {};
|
|
600
|
-
targets[0].blend.color = targets[0].blend.color || {};
|
|
601
|
-
targets[0].blend.color.srcTarget = value;
|
|
602
|
-
},
|
|
603
|
-
|
|
604
|
-
blendColorDstTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
|
|
605
|
-
addColorState(descriptor);
|
|
606
|
-
targets[0].blend = targets[0].blend || {};
|
|
607
|
-
targets[0].blend.color = targets[0].blend.color || {};
|
|
608
|
-
targets[0].blend.color.dstTarget = value;
|
|
609
|
-
},
|
|
610
|
-
|
|
611
|
-
blendAlphaOperation: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
|
|
612
|
-
addColorState(descriptor);
|
|
613
|
-
targets[0].blend = targets[0].blend || {};
|
|
614
|
-
targets[0].blend.alpha = targets[0].blend.alpha || {};
|
|
615
|
-
targets[0].blend.alpha.operation = value;
|
|
616
|
-
},
|
|
617
|
-
|
|
618
|
-
blendAlphaSrcTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
|
|
619
|
-
addColorState(descriptor);
|
|
620
|
-
targets[0].blend = targets[0].blend || {};
|
|
621
|
-
targets[0].blend.alpha = targets[0].blend.alpha || {};
|
|
622
|
-
targets[0].blend.alpha.srcTarget = value;
|
|
623
|
-
},
|
|
624
|
-
|
|
625
|
-
blendAlphaDstTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
|
|
626
|
-
addColorState(descriptor);
|
|
627
|
-
targets[0].blend = targets[0].blend || {};
|
|
628
|
-
targets[0].blend.alpha = targets[0].blend.alpha || {};
|
|
629
|
-
targets[0].blend.alpha.dstTarget = value;
|
|
630
|
-
},
|
|
631
|
-
*/
|
|
632
|
-
};
|
|
633
|
-
var DEFAULT_PIPELINE_DESCRIPTOR = {
|
|
634
|
-
// depthStencil: {
|
|
635
|
-
// stencilFront: {},
|
|
636
|
-
// stencilBack: {},
|
|
637
|
-
// // depthWriteEnabled: true,
|
|
638
|
-
// // depthCompare: 'less',
|
|
639
|
-
// // format: 'depth24plus-stencil8',
|
|
640
|
-
// },
|
|
641
|
-
primitive: {
|
|
642
|
-
cullMode: "back",
|
|
643
|
-
topology: "triangle-list"
|
|
644
|
-
},
|
|
645
|
-
vertex: {
|
|
646
|
-
module: void 0,
|
|
647
|
-
entryPoint: "main"
|
|
648
|
-
},
|
|
649
|
-
fragment: {
|
|
650
|
-
module: void 0,
|
|
651
|
-
entryPoint: "main",
|
|
652
|
-
targets: [
|
|
653
|
-
// { format: props.color0Format || 'bgra8unorm' }
|
|
654
|
-
]
|
|
655
|
-
},
|
|
656
|
-
layout: "auto"
|
|
657
|
-
};
|
|
658
530
|
function applyParametersToRenderPipelineDescriptor(pipelineDescriptor, parameters = {}) {
|
|
659
531
|
Object.assign(pipelineDescriptor, { ...DEFAULT_PIPELINE_DESCRIPTOR, ...pipelineDescriptor });
|
|
660
532
|
setParameters(pipelineDescriptor, parameters);
|
|
@@ -668,7 +540,7 @@ var __exports__ = (() => {
|
|
|
668
540
|
setterFunction(key, value, pipelineDescriptor);
|
|
669
541
|
}
|
|
670
542
|
}
|
|
671
|
-
function addColorState(descriptor) {
|
|
543
|
+
function addColorState(descriptor, attachment) {
|
|
672
544
|
descriptor.fragment.targets = descriptor.fragment?.targets || [];
|
|
673
545
|
if (!Array.isArray(descriptor.fragment?.targets)) {
|
|
674
546
|
throw new Error("colorstate");
|
|
@@ -676,17 +548,182 @@ var __exports__ = (() => {
|
|
|
676
548
|
if (descriptor.fragment?.targets?.length === 0) {
|
|
677
549
|
descriptor.fragment.targets?.push({});
|
|
678
550
|
}
|
|
679
|
-
return descriptor.fragment?.targets;
|
|
551
|
+
return descriptor.fragment?.targets[0];
|
|
680
552
|
}
|
|
553
|
+
function addBlendState(descriptor, attachment) {
|
|
554
|
+
const target = addColorState(descriptor, attachment);
|
|
555
|
+
target.blend = target.blend || { color: {}, alpha: {} };
|
|
556
|
+
return target.blend;
|
|
557
|
+
}
|
|
558
|
+
var PARAMETER_TABLE, DEFAULT_PIPELINE_DESCRIPTOR;
|
|
559
|
+
var init_webgpu_parameters = __esm({
|
|
560
|
+
"src/adapter/helpers/webgpu-parameters.ts"() {
|
|
561
|
+
"use strict";
|
|
562
|
+
PARAMETER_TABLE = {
|
|
563
|
+
// RASTERIZATION PARAMETERS
|
|
564
|
+
cullMode: (_, value, descriptor) => {
|
|
565
|
+
descriptor.primitive = descriptor.primitive || {};
|
|
566
|
+
descriptor.primitive.cullMode = value;
|
|
567
|
+
},
|
|
568
|
+
frontFace: (_, value, descriptor) => {
|
|
569
|
+
descriptor.primitive = descriptor.primitive || {};
|
|
570
|
+
descriptor.primitive.frontFace = value;
|
|
571
|
+
},
|
|
572
|
+
// DEPTH
|
|
573
|
+
depthWriteEnabled: (_, value, descriptor) => {
|
|
574
|
+
if (value) {
|
|
575
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
576
|
+
depthStencil.depthWriteEnabled = value;
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
depthCompare: (_, value, descriptor) => {
|
|
580
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
581
|
+
depthStencil.depthCompare = value;
|
|
582
|
+
},
|
|
583
|
+
depthFormat: (_, value, descriptor) => {
|
|
584
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
585
|
+
depthStencil.format = value;
|
|
586
|
+
},
|
|
587
|
+
depthBias: (_, value, descriptor) => {
|
|
588
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
589
|
+
depthStencil.depthBias = value;
|
|
590
|
+
},
|
|
591
|
+
depthBiasSlopeScale: (_, value, descriptor) => {
|
|
592
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
593
|
+
depthStencil.depthBiasSlopeScale = value;
|
|
594
|
+
},
|
|
595
|
+
depthBiasClamp: (_, value, descriptor) => {
|
|
596
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
597
|
+
depthStencil.depthBiasClamp = value;
|
|
598
|
+
},
|
|
599
|
+
// STENCIL
|
|
600
|
+
stencilReadMask: (_, value, descriptor) => {
|
|
601
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
602
|
+
depthStencil.stencilReadMask = value;
|
|
603
|
+
},
|
|
604
|
+
stencilWriteMask: (_, value, descriptor) => {
|
|
605
|
+
const depthStencil = addDepthStencil(descriptor);
|
|
606
|
+
depthStencil.stencilWriteMask = value;
|
|
607
|
+
},
|
|
608
|
+
stencilCompare: (_, value, descriptor) => {
|
|
609
|
+
const stencilFront = addDepthStencilFront(descriptor);
|
|
610
|
+
const stencilBack = addDepthStencilBack(descriptor);
|
|
611
|
+
stencilFront.compare = value;
|
|
612
|
+
stencilBack.compare = value;
|
|
613
|
+
},
|
|
614
|
+
stencilPassOperation: (_, value, descriptor) => {
|
|
615
|
+
const stencilFront = addDepthStencilFront(descriptor);
|
|
616
|
+
const stencilBack = addDepthStencilBack(descriptor);
|
|
617
|
+
stencilFront.passOp = value;
|
|
618
|
+
stencilBack.passOp = value;
|
|
619
|
+
},
|
|
620
|
+
stencilFailOperation: (_, value, descriptor) => {
|
|
621
|
+
const stencilFront = addDepthStencilFront(descriptor);
|
|
622
|
+
const stencilBack = addDepthStencilBack(descriptor);
|
|
623
|
+
stencilFront.failOp = value;
|
|
624
|
+
stencilBack.failOp = value;
|
|
625
|
+
},
|
|
626
|
+
stencilDepthFailOperation: (_, value, descriptor) => {
|
|
627
|
+
const stencilFront = addDepthStencilFront(descriptor);
|
|
628
|
+
const stencilBack = addDepthStencilBack(descriptor);
|
|
629
|
+
stencilFront.depthFailOp = value;
|
|
630
|
+
stencilBack.depthFailOp = value;
|
|
631
|
+
},
|
|
632
|
+
// MULTISAMPLE
|
|
633
|
+
sampleCount: (_, value, descriptor) => {
|
|
634
|
+
descriptor.multisample = descriptor.multisample || {};
|
|
635
|
+
descriptor.multisample.count = value;
|
|
636
|
+
},
|
|
637
|
+
sampleMask: (_, value, descriptor) => {
|
|
638
|
+
descriptor.multisample = descriptor.multisample || {};
|
|
639
|
+
descriptor.multisample.mask = value;
|
|
640
|
+
},
|
|
641
|
+
sampleAlphaToCoverageEnabled: (_, value, descriptor) => {
|
|
642
|
+
descriptor.multisample = descriptor.multisample || {};
|
|
643
|
+
descriptor.multisample.alphaToCoverageEnabled = value;
|
|
644
|
+
},
|
|
645
|
+
// COLOR
|
|
646
|
+
colorMask: (_, value, descriptor) => {
|
|
647
|
+
const target = addColorState(descriptor, 0);
|
|
648
|
+
target.writeMask = value;
|
|
649
|
+
},
|
|
650
|
+
blend: (_, value, descriptor) => {
|
|
651
|
+
if (value) {
|
|
652
|
+
addBlendState(descriptor, 0);
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
blendColorOperation: (_, value, descriptor) => {
|
|
656
|
+
const blend = addBlendState(descriptor, 0);
|
|
657
|
+
blend.color = blend.color || {};
|
|
658
|
+
blend.color.operation = value;
|
|
659
|
+
},
|
|
660
|
+
blendColorSrcFactor: (_, value, descriptor) => {
|
|
661
|
+
const blend = addBlendState(descriptor, 0);
|
|
662
|
+
blend.color = blend.color || {};
|
|
663
|
+
blend.color.srcFactor = value;
|
|
664
|
+
},
|
|
665
|
+
blendColorDstFactor: (_, value, descriptor) => {
|
|
666
|
+
const blend = addBlendState(descriptor, 0);
|
|
667
|
+
blend.color.dstFactor = value;
|
|
668
|
+
},
|
|
669
|
+
blendAlphaOperation: (_, value, descriptor) => {
|
|
670
|
+
const blend = addBlendState(descriptor, 0);
|
|
671
|
+
blend.alpha = blend.alpha || {};
|
|
672
|
+
blend.alpha.operation = value;
|
|
673
|
+
},
|
|
674
|
+
blendAlphaSrcFactor: (_, value, descriptor) => {
|
|
675
|
+
const blend = addBlendState(descriptor, 0);
|
|
676
|
+
blend.alpha = blend.alpha || {};
|
|
677
|
+
blend.alpha.srcFactor = value;
|
|
678
|
+
},
|
|
679
|
+
blendAlphaDstFactor: (_, value, descriptor) => {
|
|
680
|
+
const blend = addBlendState(descriptor, 0);
|
|
681
|
+
blend.alpha = blend.alpha || {};
|
|
682
|
+
blend.alpha.dstFactor = value;
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
DEFAULT_PIPELINE_DESCRIPTOR = {
|
|
686
|
+
// depthStencil: {
|
|
687
|
+
// stencilFront: {},
|
|
688
|
+
// stencilBack: {},
|
|
689
|
+
// // depthWriteEnabled: true,
|
|
690
|
+
// // depthCompare: 'less',
|
|
691
|
+
// // format: 'depth24plus-stencil8',
|
|
692
|
+
// },
|
|
693
|
+
primitive: {
|
|
694
|
+
cullMode: "back",
|
|
695
|
+
topology: "triangle-list"
|
|
696
|
+
},
|
|
697
|
+
vertex: {
|
|
698
|
+
module: void 0,
|
|
699
|
+
entryPoint: "main"
|
|
700
|
+
},
|
|
701
|
+
fragment: {
|
|
702
|
+
module: void 0,
|
|
703
|
+
entryPoint: "main",
|
|
704
|
+
targets: [
|
|
705
|
+
// { format: props.color0Format || 'bgra8unorm' }
|
|
706
|
+
]
|
|
707
|
+
},
|
|
708
|
+
layout: "auto"
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
});
|
|
681
712
|
|
|
682
713
|
// src/adapter/helpers/get-bind-group.ts
|
|
683
|
-
var import_core7 = __toESM(require_core(), 1);
|
|
684
714
|
function getBindGroup(device, bindGroupLayout, shaderLayout, bindings) {
|
|
685
715
|
const entries = getBindGroupEntries(bindings, shaderLayout);
|
|
686
|
-
|
|
716
|
+
device.pushErrorScope("validation");
|
|
717
|
+
const bindGroup = device.createBindGroup({
|
|
687
718
|
layout: bindGroupLayout,
|
|
688
719
|
entries
|
|
689
720
|
});
|
|
721
|
+
device.popErrorScope().then((error) => {
|
|
722
|
+
if (error) {
|
|
723
|
+
import_core7.log.error(`createBindGroup validation failed: ${error.message}`)();
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
return bindGroup;
|
|
690
727
|
}
|
|
691
728
|
function getShaderLayoutBinding(shaderLayout, bindingName, options) {
|
|
692
729
|
const bindingLayout = shaderLayout.bindings.find(
|
|
@@ -702,13 +739,21 @@ var __exports__ = (() => {
|
|
|
702
739
|
for (const [bindingName, value] of Object.entries(bindings)) {
|
|
703
740
|
let bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
|
|
704
741
|
if (bindingLayout) {
|
|
705
|
-
|
|
742
|
+
const entry = getBindGroupEntry(value, bindingLayout.location);
|
|
743
|
+
if (entry) {
|
|
744
|
+
entries.push(entry);
|
|
745
|
+
}
|
|
706
746
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
747
|
+
if (value instanceof import_core7.Texture) {
|
|
748
|
+
bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`, {
|
|
749
|
+
ignoreWarnings: true
|
|
750
|
+
});
|
|
751
|
+
if (bindingLayout) {
|
|
752
|
+
const entry = getBindGroupEntry(value, bindingLayout.location, { sampler: true });
|
|
753
|
+
if (entry) {
|
|
754
|
+
entries.push(entry);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
712
757
|
}
|
|
713
758
|
}
|
|
714
759
|
return entries;
|
|
@@ -727,7 +772,8 @@ var __exports__ = (() => {
|
|
|
727
772
|
binding: index,
|
|
728
773
|
resource: binding.handle
|
|
729
774
|
};
|
|
730
|
-
}
|
|
775
|
+
}
|
|
776
|
+
if (binding instanceof import_core7.Texture) {
|
|
731
777
|
if (options?.sampler) {
|
|
732
778
|
return {
|
|
733
779
|
binding: index,
|
|
@@ -736,14 +782,21 @@ var __exports__ = (() => {
|
|
|
736
782
|
}
|
|
737
783
|
return {
|
|
738
784
|
binding: index,
|
|
739
|
-
resource: binding.handle
|
|
785
|
+
resource: binding.view.handle
|
|
740
786
|
};
|
|
741
787
|
}
|
|
742
|
-
|
|
788
|
+
import_core7.log.warn(`invalid binding ${name}`, binding);
|
|
789
|
+
return null;
|
|
743
790
|
}
|
|
791
|
+
var import_core7;
|
|
792
|
+
var init_get_bind_group = __esm({
|
|
793
|
+
"src/adapter/helpers/get-bind-group.ts"() {
|
|
794
|
+
"use strict";
|
|
795
|
+
import_core7 = __toESM(require_core(), 1);
|
|
796
|
+
}
|
|
797
|
+
});
|
|
744
798
|
|
|
745
799
|
// src/adapter/helpers/get-vertex-buffer-layout.ts
|
|
746
|
-
var import_core8 = __toESM(require_core(), 1);
|
|
747
800
|
function getWebGPUVertexFormat(format) {
|
|
748
801
|
if (format.endsWith("-webgl")) {
|
|
749
802
|
throw new Error(`WebGPU does not support vertex format ${format}`);
|
|
@@ -769,14 +822,14 @@ var __exports__ = (() => {
|
|
|
769
822
|
offset: attributeMapping.byteOffset,
|
|
770
823
|
shaderLocation: location
|
|
771
824
|
});
|
|
772
|
-
byteStride += (0, import_core8.
|
|
825
|
+
byteStride += (0, import_core8.getVertexFormatInfo)(format).byteLength;
|
|
773
826
|
}
|
|
774
827
|
} else {
|
|
775
828
|
const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);
|
|
776
829
|
if (!attributeLayout) {
|
|
777
830
|
continue;
|
|
778
831
|
}
|
|
779
|
-
byteStride = (0, import_core8.
|
|
832
|
+
byteStride = (0, import_core8.getVertexFormatInfo)(format).byteLength;
|
|
780
833
|
stepMode = attributeLayout.stepMode || (attributeLayout.name.startsWith("instance") ? "instance" : "vertex");
|
|
781
834
|
vertexAttributes.push({
|
|
782
835
|
format: getWebGPUVertexFormat(format),
|
|
@@ -794,7 +847,7 @@ var __exports__ = (() => {
|
|
|
794
847
|
for (const attribute of shaderLayout.attributes) {
|
|
795
848
|
if (!usedAttributes.has(attribute.name)) {
|
|
796
849
|
vertexBufferLayouts.push({
|
|
797
|
-
arrayStride: (0, import_core8.
|
|
850
|
+
arrayStride: (0, import_core8.getVertexFormatInfo)("float32x3").byteLength,
|
|
798
851
|
stepMode: attribute.stepMode || (attribute.name.startsWith("instance") ? "instance" : "vertex"),
|
|
799
852
|
attributes: [
|
|
800
853
|
{
|
|
@@ -808,459 +861,250 @@ var __exports__ = (() => {
|
|
|
808
861
|
}
|
|
809
862
|
return vertexBufferLayouts;
|
|
810
863
|
}
|
|
811
|
-
function findAttributeLayout(shaderLayout,
|
|
812
|
-
const attribute = shaderLayout.attributes.find((attribute_) => attribute_.name ===
|
|
864
|
+
function findAttributeLayout(shaderLayout, name2, attributeNames) {
|
|
865
|
+
const attribute = shaderLayout.attributes.find((attribute_) => attribute_.name === name2);
|
|
813
866
|
if (!attribute) {
|
|
814
|
-
import_core8.log.warn(`Supplied attribute not present in shader layout: ${
|
|
867
|
+
import_core8.log.warn(`Supplied attribute not present in shader layout: ${name2}`)();
|
|
815
868
|
return null;
|
|
816
869
|
}
|
|
817
|
-
if (attributeNames.has(
|
|
818
|
-
throw new Error(`Found multiple entries for attribute: ${
|
|
870
|
+
if (attributeNames.has(name2)) {
|
|
871
|
+
throw new Error(`Found multiple entries for attribute: ${name2}`);
|
|
819
872
|
}
|
|
820
|
-
attributeNames.add(
|
|
873
|
+
attributeNames.add(name2);
|
|
821
874
|
return attribute;
|
|
822
875
|
}
|
|
876
|
+
var import_core8;
|
|
877
|
+
var init_get_vertex_buffer_layout = __esm({
|
|
878
|
+
"src/adapter/helpers/get-vertex-buffer-layout.ts"() {
|
|
879
|
+
"use strict";
|
|
880
|
+
import_core8 = __toESM(require_core(), 1);
|
|
881
|
+
}
|
|
882
|
+
});
|
|
823
883
|
|
|
824
884
|
// src/adapter/resources/webgpu-render-pipeline.ts
|
|
825
|
-
var
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
885
|
+
var import_core9, WebGPURenderPipeline;
|
|
886
|
+
var init_webgpu_render_pipeline = __esm({
|
|
887
|
+
"src/adapter/resources/webgpu-render-pipeline.ts"() {
|
|
888
|
+
"use strict";
|
|
889
|
+
import_core9 = __toESM(require_core(), 1);
|
|
890
|
+
init_webgpu_parameters();
|
|
891
|
+
init_convert_texture_format();
|
|
892
|
+
init_get_bind_group();
|
|
893
|
+
init_get_vertex_buffer_layout();
|
|
894
|
+
WebGPURenderPipeline = class extends import_core9.RenderPipeline {
|
|
895
|
+
device;
|
|
896
|
+
handle;
|
|
897
|
+
vs;
|
|
898
|
+
fs = null;
|
|
899
|
+
/** For internal use to create BindGroups */
|
|
900
|
+
_bindings;
|
|
901
|
+
_bindGroupLayout = null;
|
|
902
|
+
_bindGroup = null;
|
|
903
|
+
get [Symbol.toStringTag]() {
|
|
904
|
+
return "WebGPURenderPipeline";
|
|
905
|
+
}
|
|
906
|
+
constructor(device, props) {
|
|
907
|
+
super(device, props);
|
|
908
|
+
this.device = device;
|
|
909
|
+
this.handle = this.props.handle;
|
|
910
|
+
if (!this.handle) {
|
|
911
|
+
const descriptor = this._getRenderPipelineDescriptor();
|
|
912
|
+
import_core9.log.groupCollapsed(1, `new WebGPURenderPipeline(${this.id})`)();
|
|
913
|
+
import_core9.log.probe(1, JSON.stringify(descriptor, null, 2))();
|
|
914
|
+
import_core9.log.groupEnd(1)();
|
|
915
|
+
this.device.handle.pushErrorScope("validation");
|
|
916
|
+
this.handle = this.device.handle.createRenderPipeline(descriptor);
|
|
917
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
918
|
+
if (error) {
|
|
919
|
+
import_core9.log.error(`${this} creation failed:
|
|
851
920
|
"${error.message}"`, this, this.props.vs?.source)();
|
|
921
|
+
}
|
|
922
|
+
});
|
|
852
923
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
this.fs = props.fs;
|
|
858
|
-
this._bindings = { ...this.props.bindings };
|
|
859
|
-
}
|
|
860
|
-
destroy() {
|
|
861
|
-
this.handle = null;
|
|
862
|
-
}
|
|
863
|
-
/**
|
|
864
|
-
* @todo Use renderpass.setBindings() ?
|
|
865
|
-
* @todo Do we want to expose BindGroups in the API and remove this?
|
|
866
|
-
*/
|
|
867
|
-
setBindings(bindings) {
|
|
868
|
-
for (const [name, binding] of Object.entries(bindings)) {
|
|
869
|
-
if (this._bindings[name] !== binding) {
|
|
870
|
-
this._bindGroup = null;
|
|
924
|
+
this.handle.label = this.props.id;
|
|
925
|
+
this.vs = props.vs;
|
|
926
|
+
this.fs = props.fs;
|
|
927
|
+
this._bindings = { ...this.props.bindings };
|
|
871
928
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
929
|
+
destroy() {
|
|
930
|
+
this.handle = null;
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* @todo Use renderpass.setBindings() ?
|
|
934
|
+
* @todo Do we want to expose BindGroups in the API and remove this?
|
|
935
|
+
*/
|
|
936
|
+
setBindings(bindings) {
|
|
937
|
+
for (const [name2, binding] of Object.entries(bindings)) {
|
|
938
|
+
if (this._bindings[name2] !== binding) {
|
|
939
|
+
this._bindGroup = null;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
Object.assign(this._bindings, bindings);
|
|
943
|
+
}
|
|
944
|
+
/** @todo - should this be moved to renderpass? */
|
|
945
|
+
draw(options) {
|
|
946
|
+
const webgpuRenderPass = options.renderPass;
|
|
947
|
+
this.device.handle.pushErrorScope("validation");
|
|
948
|
+
webgpuRenderPass.handle.setPipeline(this.handle);
|
|
949
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
950
|
+
if (error) {
|
|
951
|
+
import_core9.log.error(`${this} setPipeline failed:
|
|
883
952
|
"${error.message}"`, this)();
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
const bindGroup = this._getBindGroup();
|
|
956
|
+
if (bindGroup) {
|
|
957
|
+
webgpuRenderPass.handle.setBindGroup(0, bindGroup);
|
|
958
|
+
}
|
|
959
|
+
options.vertexArray.bindBeforeRender(options.renderPass);
|
|
960
|
+
if (options.indexCount) {
|
|
961
|
+
webgpuRenderPass.handle.drawIndexed(
|
|
962
|
+
options.indexCount,
|
|
963
|
+
options.instanceCount,
|
|
964
|
+
options.firstIndex,
|
|
965
|
+
options.baseVertex,
|
|
966
|
+
options.firstInstance
|
|
967
|
+
);
|
|
968
|
+
} else {
|
|
969
|
+
webgpuRenderPass.handle.draw(
|
|
970
|
+
options.vertexCount || 0,
|
|
971
|
+
options.instanceCount || 1,
|
|
972
|
+
// If 0, nothing will be drawn
|
|
973
|
+
options.firstInstance
|
|
974
|
+
);
|
|
975
|
+
}
|
|
976
|
+
options.vertexArray.unbindAfterRender(options.renderPass);
|
|
977
|
+
return true;
|
|
884
978
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
979
|
+
/** Return a bind group created by setBindings */
|
|
980
|
+
_getBindGroup() {
|
|
981
|
+
if (this.shaderLayout.bindings.length === 0) {
|
|
982
|
+
return null;
|
|
983
|
+
}
|
|
984
|
+
this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
|
|
985
|
+
this._bindGroup = this._bindGroup || getBindGroup(this.device.handle, this._bindGroupLayout, this.shaderLayout, this._bindings);
|
|
986
|
+
return this._bindGroup;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Populate the complex WebGPU GPURenderPipelineDescriptor
|
|
990
|
+
*/
|
|
991
|
+
_getRenderPipelineDescriptor() {
|
|
992
|
+
const vertex = {
|
|
993
|
+
module: this.props.vs.handle,
|
|
994
|
+
entryPoint: this.props.vertexEntryPoint || "main",
|
|
995
|
+
buffers: getVertexBufferLayout(this.shaderLayout, this.props.bufferLayout)
|
|
996
|
+
};
|
|
997
|
+
const targets = [];
|
|
998
|
+
if (this.props.colorAttachmentFormats) {
|
|
999
|
+
for (const format of this.props.colorAttachmentFormats) {
|
|
1000
|
+
targets.push(format ? { format: getWebGPUTextureFormat(format) } : null);
|
|
1001
|
+
}
|
|
1002
|
+
} else {
|
|
1003
|
+
targets.push({ format: getWebGPUTextureFormat(this.device.preferredColorFormat) });
|
|
1004
|
+
}
|
|
1005
|
+
const fragment = {
|
|
1006
|
+
module: this.props.fs.handle,
|
|
1007
|
+
entryPoint: this.props.fragmentEntryPoint || "main",
|
|
1008
|
+
targets
|
|
1009
|
+
};
|
|
1010
|
+
const descriptor = {
|
|
1011
|
+
vertex,
|
|
1012
|
+
fragment,
|
|
1013
|
+
primitive: {
|
|
1014
|
+
topology: this.props.topology
|
|
1015
|
+
},
|
|
1016
|
+
layout: "auto"
|
|
1017
|
+
};
|
|
1018
|
+
const depthFormat = this.props.depthStencilAttachmentFormat || this.device.preferredDepthFormat;
|
|
1019
|
+
if (this.props.parameters.depthWriteEnabled) {
|
|
1020
|
+
descriptor.depthStencil = {
|
|
1021
|
+
format: getWebGPUTextureFormat(depthFormat)
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
applyParametersToRenderPipelineDescriptor(descriptor, this.props.parameters);
|
|
1025
|
+
return descriptor;
|
|
932
1026
|
}
|
|
933
|
-
} else {
|
|
934
|
-
targets.push({ format: getWebGPUTextureFormat(this.device.preferredColorFormat) });
|
|
935
|
-
}
|
|
936
|
-
const fragment = {
|
|
937
|
-
module: this.props.fs.handle,
|
|
938
|
-
entryPoint: this.props.fragmentEntryPoint || "main",
|
|
939
|
-
targets
|
|
940
|
-
};
|
|
941
|
-
const descriptor = {
|
|
942
|
-
vertex,
|
|
943
|
-
fragment,
|
|
944
|
-
primitive: {
|
|
945
|
-
topology: this.props.topology
|
|
946
|
-
},
|
|
947
|
-
layout: "auto"
|
|
948
1027
|
};
|
|
949
|
-
const depthFormat = this.props.depthStencilAttachmentFormat || this.device.preferredDepthFormat;
|
|
950
|
-
if (this.props.parameters.depthWriteEnabled) {
|
|
951
|
-
descriptor.depthStencil = {
|
|
952
|
-
format: getWebGPUTextureFormat(depthFormat)
|
|
953
|
-
};
|
|
954
|
-
}
|
|
955
|
-
applyParametersToRenderPipelineDescriptor(descriptor, this.props.parameters);
|
|
956
|
-
return descriptor;
|
|
957
1028
|
}
|
|
958
|
-
};
|
|
1029
|
+
});
|
|
959
1030
|
|
|
960
1031
|
// src/adapter/resources/webgpu-framebuffer.ts
|
|
961
|
-
var import_core10
|
|
962
|
-
var
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1032
|
+
var import_core10, WebGPUFramebuffer;
|
|
1033
|
+
var init_webgpu_framebuffer = __esm({
|
|
1034
|
+
"src/adapter/resources/webgpu-framebuffer.ts"() {
|
|
1035
|
+
"use strict";
|
|
1036
|
+
import_core10 = __toESM(require_core(), 1);
|
|
1037
|
+
WebGPUFramebuffer = class extends import_core10.Framebuffer {
|
|
1038
|
+
device;
|
|
1039
|
+
colorAttachments = [];
|
|
1040
|
+
depthStencilAttachment = null;
|
|
1041
|
+
constructor(device, props) {
|
|
1042
|
+
super(device, props);
|
|
1043
|
+
this.device = device;
|
|
1044
|
+
this.autoCreateAttachmentTextures();
|
|
1045
|
+
}
|
|
1046
|
+
updateAttachments() {
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
972
1049
|
}
|
|
973
|
-
};
|
|
1050
|
+
});
|
|
974
1051
|
|
|
975
1052
|
// src/adapter/resources/webgpu-compute-pipeline.ts
|
|
976
|
-
var import_core11
|
|
977
|
-
var
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
setBindings(bindings) {
|
|
1004
|
-
Object.assign(this._bindings, bindings);
|
|
1005
|
-
}
|
|
1006
|
-
/** Return a bind group created by setBindings */
|
|
1007
|
-
_getBindGroup() {
|
|
1008
|
-
this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
|
|
1009
|
-
this._bindGroup = this._bindGroup || getBindGroup(this.device.handle, this._bindGroupLayout, this.shaderLayout, this._bindings);
|
|
1010
|
-
return this._bindGroup;
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1013
|
-
|
|
1014
|
-
// src/adapter/resources/webgpu-render-pass.ts
|
|
1015
|
-
var import_core12 = __toESM(require_core(), 1);
|
|
1016
|
-
var WebGPURenderPass = class extends import_core12.RenderPass {
|
|
1017
|
-
device;
|
|
1018
|
-
handle;
|
|
1019
|
-
/** Active pipeline */
|
|
1020
|
-
pipeline = null;
|
|
1021
|
-
constructor(device, props = {}) {
|
|
1022
|
-
super(device, props);
|
|
1023
|
-
this.device = device;
|
|
1024
|
-
const framebuffer = props.framebuffer || device.getCanvasContext().getCurrentFramebuffer();
|
|
1025
|
-
const renderPassDescriptor = this.getRenderPassDescriptor(framebuffer);
|
|
1026
|
-
const webgpuQuerySet = props.timestampQuerySet;
|
|
1027
|
-
if (webgpuQuerySet) {
|
|
1028
|
-
renderPassDescriptor.occlusionQuerySet = webgpuQuerySet.handle;
|
|
1029
|
-
}
|
|
1030
|
-
if (device.features.has("timestamp-query")) {
|
|
1031
|
-
const webgpuTSQuerySet = props.timestampQuerySet;
|
|
1032
|
-
renderPassDescriptor.timestampWrites = webgpuTSQuerySet ? {
|
|
1033
|
-
querySet: webgpuTSQuerySet.handle,
|
|
1034
|
-
beginningOfPassWriteIndex: props.beginTimestampIndex,
|
|
1035
|
-
endOfPassWriteIndex: props.endTimestampIndex
|
|
1036
|
-
} : void 0;
|
|
1037
|
-
}
|
|
1038
|
-
if (!device.commandEncoder) {
|
|
1039
|
-
throw new Error("commandEncoder not available");
|
|
1040
|
-
}
|
|
1041
|
-
this.device.handle.pushErrorScope("validation");
|
|
1042
|
-
this.handle = this.props.handle || device.commandEncoder.beginRenderPass(renderPassDescriptor);
|
|
1043
|
-
this.device.handle.popErrorScope().then((error) => {
|
|
1044
|
-
if (error) {
|
|
1045
|
-
import_core12.log.error(`${this} creation failed:
|
|
1046
|
-
"${error.message}"`, this)();
|
|
1047
|
-
}
|
|
1048
|
-
});
|
|
1049
|
-
this.handle.label = this.props.id;
|
|
1050
|
-
import_core12.log.groupCollapsed(3, `new WebGPURenderPass(${this.id})`)();
|
|
1051
|
-
import_core12.log.probe(3, JSON.stringify(renderPassDescriptor, null, 2))();
|
|
1052
|
-
import_core12.log.groupEnd(3)();
|
|
1053
|
-
}
|
|
1054
|
-
destroy() {
|
|
1055
|
-
}
|
|
1056
|
-
end() {
|
|
1057
|
-
this.handle.end();
|
|
1058
|
-
}
|
|
1059
|
-
setPipeline(pipeline) {
|
|
1060
|
-
this.pipeline = pipeline;
|
|
1061
|
-
this.handle.setPipeline(this.pipeline.handle);
|
|
1062
|
-
}
|
|
1063
|
-
/** Sets an array of bindings (uniform buffers, samplers, textures, ...) */
|
|
1064
|
-
setBindings(bindings) {
|
|
1065
|
-
this.pipeline?.setBindings(bindings);
|
|
1066
|
-
const bindGroup = this.pipeline?._getBindGroup();
|
|
1067
|
-
if (bindGroup) {
|
|
1068
|
-
this.handle.setBindGroup(0, bindGroup);
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
setIndexBuffer(buffer, indexFormat, offset = 0, size) {
|
|
1072
|
-
this.handle.setIndexBuffer(buffer.handle, indexFormat, offset, size);
|
|
1073
|
-
}
|
|
1074
|
-
setVertexBuffer(slot, buffer, offset = 0) {
|
|
1075
|
-
this.handle.setVertexBuffer(slot, buffer.handle, offset);
|
|
1076
|
-
}
|
|
1077
|
-
draw(options) {
|
|
1078
|
-
if (options.indexCount) {
|
|
1079
|
-
this.handle.drawIndexed(
|
|
1080
|
-
options.indexCount,
|
|
1081
|
-
options.instanceCount,
|
|
1082
|
-
options.firstIndex,
|
|
1083
|
-
options.baseVertex,
|
|
1084
|
-
options.firstInstance
|
|
1085
|
-
);
|
|
1086
|
-
} else {
|
|
1087
|
-
this.handle.draw(
|
|
1088
|
-
options.vertexCount || 0,
|
|
1089
|
-
options.instanceCount || 1,
|
|
1090
|
-
options.firstIndex,
|
|
1091
|
-
options.firstInstance
|
|
1092
|
-
);
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
drawIndirect() {
|
|
1096
|
-
}
|
|
1097
|
-
setParameters(parameters) {
|
|
1098
|
-
const { blendConstant, stencilReference, scissorRect, viewport } = parameters;
|
|
1099
|
-
if (blendConstant) {
|
|
1100
|
-
this.handle.setBlendConstant(blendConstant);
|
|
1101
|
-
}
|
|
1102
|
-
if (stencilReference) {
|
|
1103
|
-
this.handle.setStencilReference(stencilReference);
|
|
1104
|
-
}
|
|
1105
|
-
if (scissorRect) {
|
|
1106
|
-
this.handle.setScissorRect(scissorRect[0], scissorRect[1], scissorRect[2], scissorRect[3]);
|
|
1107
|
-
}
|
|
1108
|
-
if (viewport) {
|
|
1109
|
-
this.handle.setViewport(
|
|
1110
|
-
viewport[0],
|
|
1111
|
-
viewport[1],
|
|
1112
|
-
viewport[2],
|
|
1113
|
-
viewport[3],
|
|
1114
|
-
viewport[4],
|
|
1115
|
-
viewport[5]
|
|
1116
|
-
);
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
pushDebugGroup(groupLabel) {
|
|
1120
|
-
this.handle.pushDebugGroup(groupLabel);
|
|
1121
|
-
}
|
|
1122
|
-
popDebugGroup() {
|
|
1123
|
-
this.handle.popDebugGroup();
|
|
1124
|
-
}
|
|
1125
|
-
insertDebugMarker(markerLabel) {
|
|
1126
|
-
this.handle.insertDebugMarker(markerLabel);
|
|
1127
|
-
}
|
|
1128
|
-
beginOcclusionQuery(queryIndex) {
|
|
1129
|
-
this.handle.beginOcclusionQuery(queryIndex);
|
|
1130
|
-
}
|
|
1131
|
-
endOcclusionQuery() {
|
|
1132
|
-
this.handle.endOcclusionQuery();
|
|
1133
|
-
}
|
|
1134
|
-
// executeBundles(bundles: Iterable<GPURenderBundle>): void;
|
|
1135
|
-
// INTERNAL
|
|
1136
|
-
/**
|
|
1137
|
-
* Partial render pass descriptor. Used by WebGPURenderPass.
|
|
1138
|
-
* @returns attachments fields of a renderpass descriptor.
|
|
1139
|
-
*/
|
|
1140
|
-
getRenderPassDescriptor(framebuffer) {
|
|
1141
|
-
const renderPassDescriptor = {
|
|
1142
|
-
colorAttachments: []
|
|
1143
|
-
};
|
|
1144
|
-
renderPassDescriptor.colorAttachments = framebuffer.colorAttachments.map(
|
|
1145
|
-
(colorAttachment, index) => ({
|
|
1146
|
-
// clear values
|
|
1147
|
-
loadOp: this.props.clearColor !== false ? "clear" : "load",
|
|
1148
|
-
colorClearValue: this.props.clearColors?.[index] || this.props.clearColor || import_core12.RenderPass.defaultClearColor,
|
|
1149
|
-
storeOp: this.props.discard ? "discard" : "store",
|
|
1150
|
-
// ...colorAttachment,
|
|
1151
|
-
view: colorAttachment.handle
|
|
1152
|
-
})
|
|
1153
|
-
);
|
|
1154
|
-
if (framebuffer.depthStencilAttachment) {
|
|
1155
|
-
renderPassDescriptor.depthStencilAttachment = {
|
|
1156
|
-
view: framebuffer.depthStencilAttachment.handle
|
|
1157
|
-
};
|
|
1158
|
-
const { depthStencilAttachment } = renderPassDescriptor;
|
|
1159
|
-
if (this.props.depthReadOnly) {
|
|
1160
|
-
depthStencilAttachment.depthReadOnly = true;
|
|
1161
|
-
}
|
|
1162
|
-
if (this.props.clearDepth !== false) {
|
|
1163
|
-
depthStencilAttachment.depthClearValue = this.props.clearDepth;
|
|
1164
|
-
}
|
|
1165
|
-
const hasDepthAspect = true;
|
|
1166
|
-
if (hasDepthAspect) {
|
|
1167
|
-
depthStencilAttachment.depthLoadOp = this.props.clearDepth !== false ? "clear" : "load";
|
|
1168
|
-
depthStencilAttachment.depthStoreOp = "store";
|
|
1053
|
+
var import_core11, WebGPUComputePipeline;
|
|
1054
|
+
var init_webgpu_compute_pipeline = __esm({
|
|
1055
|
+
"src/adapter/resources/webgpu-compute-pipeline.ts"() {
|
|
1056
|
+
"use strict";
|
|
1057
|
+
import_core11 = __toESM(require_core(), 1);
|
|
1058
|
+
init_get_bind_group();
|
|
1059
|
+
WebGPUComputePipeline = class extends import_core11.ComputePipeline {
|
|
1060
|
+
device;
|
|
1061
|
+
handle;
|
|
1062
|
+
/** For internal use to create BindGroups */
|
|
1063
|
+
_bindGroupLayout = null;
|
|
1064
|
+
_bindGroup = null;
|
|
1065
|
+
/** For internal use to create BindGroups */
|
|
1066
|
+
_bindings = {};
|
|
1067
|
+
constructor(device, props) {
|
|
1068
|
+
super(device, props);
|
|
1069
|
+
this.device = device;
|
|
1070
|
+
const webgpuShader = this.props.shader;
|
|
1071
|
+
this.handle = this.props.handle || this.device.handle.createComputePipeline({
|
|
1072
|
+
label: this.props.id,
|
|
1073
|
+
compute: {
|
|
1074
|
+
module: webgpuShader.handle,
|
|
1075
|
+
entryPoint: this.props.entryPoint,
|
|
1076
|
+
constants: this.props.constants
|
|
1077
|
+
},
|
|
1078
|
+
layout: "auto"
|
|
1079
|
+
});
|
|
1169
1080
|
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1081
|
+
/**
|
|
1082
|
+
* @todo Use renderpass.setBindings() ?
|
|
1083
|
+
* @todo Do we want to expose BindGroups in the API and remove this?
|
|
1084
|
+
*/
|
|
1085
|
+
setBindings(bindings) {
|
|
1086
|
+
Object.assign(this._bindings, bindings);
|
|
1174
1087
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
// src/adapter/resources/webgpu-compute-pass.ts
|
|
1181
|
-
var import_core13 = __toESM(require_core(), 1);
|
|
1182
|
-
var WebGPUComputePass = class extends import_core13.ComputePass {
|
|
1183
|
-
device;
|
|
1184
|
-
handle;
|
|
1185
|
-
_webgpuPipeline = null;
|
|
1186
|
-
constructor(device, props) {
|
|
1187
|
-
super(device, props);
|
|
1188
|
-
this.device = device;
|
|
1189
|
-
let timestampWrites;
|
|
1190
|
-
if (device.features.has("timestamp-query")) {
|
|
1191
|
-
const webgpuQuerySet = props.timestampQuerySet;
|
|
1192
|
-
if (webgpuQuerySet) {
|
|
1193
|
-
timestampWrites = {
|
|
1194
|
-
querySet: webgpuQuerySet.handle,
|
|
1195
|
-
beginningOfPassWriteIndex: props.beginTimestampIndex,
|
|
1196
|
-
endOfPassWriteIndex: props.endTimestampIndex
|
|
1197
|
-
};
|
|
1088
|
+
/** Return a bind group created by setBindings */
|
|
1089
|
+
_getBindGroup() {
|
|
1090
|
+
this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
|
|
1091
|
+
this._bindGroup = this._bindGroup || getBindGroup(this.device.handle, this._bindGroupLayout, this.shaderLayout, this._bindings);
|
|
1092
|
+
return this._bindGroup;
|
|
1198
1093
|
}
|
|
1199
|
-
}
|
|
1200
|
-
this.handle = this.props.handle || device.commandEncoder?.beginComputePass({
|
|
1201
|
-
label: this.props.id,
|
|
1202
|
-
timestampWrites
|
|
1203
|
-
});
|
|
1204
|
-
}
|
|
1205
|
-
/** @note no WebGPU destroy method, just gc */
|
|
1206
|
-
destroy() {
|
|
1207
|
-
}
|
|
1208
|
-
end() {
|
|
1209
|
-
this.handle.end();
|
|
1210
|
-
}
|
|
1211
|
-
setPipeline(pipeline) {
|
|
1212
|
-
const wgpuPipeline = pipeline;
|
|
1213
|
-
this.handle.setPipeline(wgpuPipeline.handle);
|
|
1214
|
-
this._webgpuPipeline = wgpuPipeline;
|
|
1215
|
-
this.setBindings([]);
|
|
1216
|
-
}
|
|
1217
|
-
/**
|
|
1218
|
-
* Sets an array of bindings (uniform buffers, samplers, textures, ...)
|
|
1219
|
-
* TODO - still some API confusion - does this method go here or on the pipeline?
|
|
1220
|
-
*/
|
|
1221
|
-
setBindings(bindings) {
|
|
1222
|
-
const bindGroup = this._webgpuPipeline._getBindGroup();
|
|
1223
|
-
this.handle.setBindGroup(0, bindGroup);
|
|
1224
|
-
}
|
|
1225
|
-
/**
|
|
1226
|
-
* Dispatch work to be performed with the current ComputePipeline.
|
|
1227
|
-
* @param x X dimension of the grid of work groups to dispatch.
|
|
1228
|
-
* @param y Y dimension of the grid of work groups to dispatch.
|
|
1229
|
-
* @param z Z dimension of the grid of work groups to dispatch.
|
|
1230
|
-
*/
|
|
1231
|
-
dispatch(x, y, z) {
|
|
1232
|
-
this.handle.dispatchWorkgroups(x, y, z);
|
|
1233
|
-
}
|
|
1234
|
-
/**
|
|
1235
|
-
* Dispatch work to be performed with the current ComputePipeline.
|
|
1236
|
-
*
|
|
1237
|
-
* 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()
|
|
1238
|
-
* @param indirectBuffer
|
|
1239
|
-
* @param indirectOffset offset in buffer to the beginning of the dispatch data.
|
|
1240
|
-
*/
|
|
1241
|
-
dispatchIndirect(indirectBuffer, indirectByteOffset = 0) {
|
|
1242
|
-
const webgpuBuffer = indirectBuffer;
|
|
1243
|
-
this.handle.dispatchWorkgroupsIndirect(webgpuBuffer.handle, indirectByteOffset);
|
|
1244
|
-
}
|
|
1245
|
-
pushDebugGroup(groupLabel) {
|
|
1246
|
-
this.handle.pushDebugGroup(groupLabel);
|
|
1247
|
-
}
|
|
1248
|
-
popDebugGroup() {
|
|
1249
|
-
this.handle.popDebugGroup();
|
|
1250
|
-
}
|
|
1251
|
-
insertDebugMarker(markerLabel) {
|
|
1252
|
-
this.handle.insertDebugMarker(markerLabel);
|
|
1094
|
+
};
|
|
1253
1095
|
}
|
|
1254
|
-
};
|
|
1255
|
-
|
|
1256
|
-
// src/adapter/resources/webgpu-vertex-array.ts
|
|
1257
|
-
var import_core14 = __toESM(require_core(), 1);
|
|
1096
|
+
});
|
|
1258
1097
|
|
|
1259
1098
|
// ../../node_modules/@probe.gl/env/dist/lib/globals.js
|
|
1260
|
-
var document_
|
|
1261
|
-
var
|
|
1262
|
-
|
|
1263
|
-
|
|
1099
|
+
var document_, process_, console_, navigator_;
|
|
1100
|
+
var init_globals = __esm({
|
|
1101
|
+
"../../node_modules/@probe.gl/env/dist/lib/globals.js"() {
|
|
1102
|
+
document_ = globalThis.document || {};
|
|
1103
|
+
process_ = globalThis.process || {};
|
|
1104
|
+
console_ = globalThis.console;
|
|
1105
|
+
navigator_ = globalThis.navigator || {};
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1264
1108
|
|
|
1265
1109
|
// ../../node_modules/@probe.gl/env/dist/lib/is-electron.js
|
|
1266
1110
|
function isElectron(mockUserAgent) {
|
|
@@ -1274,6 +1118,10 @@ var __exports__ = (() => {
|
|
|
1274
1118
|
const userAgent = mockUserAgent || realUserAgent;
|
|
1275
1119
|
return Boolean(userAgent && userAgent.indexOf("Electron") >= 0);
|
|
1276
1120
|
}
|
|
1121
|
+
var init_is_electron = __esm({
|
|
1122
|
+
"../../node_modules/@probe.gl/env/dist/lib/is-electron.js"() {
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1277
1125
|
|
|
1278
1126
|
// ../../node_modules/@probe.gl/env/dist/lib/is-browser.js
|
|
1279
1127
|
function isBrowser() {
|
|
@@ -1283,6 +1131,11 @@ var __exports__ = (() => {
|
|
|
1283
1131
|
);
|
|
1284
1132
|
return !isNode || isElectron();
|
|
1285
1133
|
}
|
|
1134
|
+
var init_is_browser = __esm({
|
|
1135
|
+
"../../node_modules/@probe.gl/env/dist/lib/is-browser.js"() {
|
|
1136
|
+
init_is_electron();
|
|
1137
|
+
}
|
|
1138
|
+
});
|
|
1286
1139
|
|
|
1287
1140
|
// ../../node_modules/@probe.gl/env/dist/lib/get-browser.js
|
|
1288
1141
|
function getBrowser(mockUserAgent) {
|
|
@@ -1307,417 +1160,823 @@ var __exports__ = (() => {
|
|
|
1307
1160
|
}
|
|
1308
1161
|
return "Unknown";
|
|
1309
1162
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
}
|
|
1316
|
-
device;
|
|
1317
|
-
/** Vertex Array is a helper class under WebGPU */
|
|
1318
|
-
handle;
|
|
1319
|
-
// Create a VertexArray
|
|
1320
|
-
constructor(device, props) {
|
|
1321
|
-
super(device, props);
|
|
1322
|
-
this.device = device;
|
|
1323
|
-
}
|
|
1324
|
-
destroy() {
|
|
1163
|
+
var init_get_browser = __esm({
|
|
1164
|
+
"../../node_modules/@probe.gl/env/dist/lib/get-browser.js"() {
|
|
1165
|
+
init_is_browser();
|
|
1166
|
+
init_is_electron();
|
|
1167
|
+
init_globals();
|
|
1325
1168
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
}
|
|
1333
|
-
/** Set a bufferSlot in vertex attributes array to a buffer, enables the bufferSlot, sets divisor */
|
|
1334
|
-
setBuffer(bufferSlot, buffer) {
|
|
1335
|
-
this.attributes[bufferSlot] = buffer;
|
|
1169
|
+
});
|
|
1170
|
+
|
|
1171
|
+
// ../../node_modules/@probe.gl/env/dist/index.js
|
|
1172
|
+
var init_dist = __esm({
|
|
1173
|
+
"../../node_modules/@probe.gl/env/dist/index.js"() {
|
|
1174
|
+
init_get_browser();
|
|
1336
1175
|
}
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
// @ts-expect-error TODO - we must enforce type
|
|
1350
|
-
webgpuIndexBuffer?.indexType
|
|
1351
|
-
);
|
|
1352
|
-
}
|
|
1353
|
-
for (let location = 0; location < this.maxVertexAttributes; location++) {
|
|
1354
|
-
const webgpuBuffer = this.attributes[location];
|
|
1355
|
-
if (webgpuBuffer?.handle) {
|
|
1356
|
-
import_core14.log.info(3, `setting vertex buffer ${location}`, webgpuBuffer?.handle)();
|
|
1357
|
-
webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1178
|
+
// src/adapter/resources/webgpu-vertex-array.ts
|
|
1179
|
+
var import_core12, WebGPUVertexArray;
|
|
1180
|
+
var init_webgpu_vertex_array = __esm({
|
|
1181
|
+
"src/adapter/resources/webgpu-vertex-array.ts"() {
|
|
1182
|
+
"use strict";
|
|
1183
|
+
import_core12 = __toESM(require_core(), 1);
|
|
1184
|
+
init_dist();
|
|
1185
|
+
WebGPUVertexArray = class extends import_core12.VertexArray {
|
|
1186
|
+
get [Symbol.toStringTag]() {
|
|
1187
|
+
return "WebGPUVertexArray";
|
|
1358
1188
|
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1189
|
+
device;
|
|
1190
|
+
/** Vertex Array is just a helper class under WebGPU */
|
|
1191
|
+
handle = null;
|
|
1192
|
+
// Create a VertexArray
|
|
1193
|
+
constructor(device, props) {
|
|
1194
|
+
super(device, props);
|
|
1195
|
+
this.device = device;
|
|
1196
|
+
}
|
|
1197
|
+
destroy() {
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Set an elements buffer, for indexed rendering.
|
|
1201
|
+
* Must be a Buffer bound to buffer with usage bit Buffer.INDEX set.
|
|
1202
|
+
*/
|
|
1203
|
+
setIndexBuffer(buffer) {
|
|
1204
|
+
this.indexBuffer = buffer;
|
|
1205
|
+
}
|
|
1206
|
+
/** Set a bufferSlot in vertex attributes array to a buffer, enables the bufferSlot, sets divisor */
|
|
1207
|
+
setBuffer(bufferSlot, buffer) {
|
|
1208
|
+
this.attributes[bufferSlot] = buffer;
|
|
1209
|
+
}
|
|
1210
|
+
bindBeforeRender(renderPass, firstIndex, indexCount) {
|
|
1211
|
+
const webgpuRenderPass = renderPass;
|
|
1212
|
+
const webgpuIndexBuffer = this.indexBuffer;
|
|
1213
|
+
if (webgpuIndexBuffer?.handle) {
|
|
1214
|
+
import_core12.log.info(
|
|
1215
|
+
3,
|
|
1216
|
+
"setting index buffer",
|
|
1217
|
+
webgpuIndexBuffer?.handle,
|
|
1218
|
+
webgpuIndexBuffer?.indexType
|
|
1219
|
+
)();
|
|
1220
|
+
webgpuRenderPass.handle.setIndexBuffer(
|
|
1221
|
+
webgpuIndexBuffer?.handle,
|
|
1222
|
+
// @ts-expect-error TODO - we must enforce type
|
|
1223
|
+
webgpuIndexBuffer?.indexType
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
for (let location = 0; location < this.maxVertexAttributes; location++) {
|
|
1227
|
+
const webgpuBuffer = this.attributes[location];
|
|
1228
|
+
if (webgpuBuffer?.handle) {
|
|
1229
|
+
import_core12.log.info(3, `setting vertex buffer ${location}`, webgpuBuffer?.handle)();
|
|
1230
|
+
webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
unbindAfterRender(renderPass) {
|
|
1235
|
+
}
|
|
1236
|
+
// DEPRECATED METHODS
|
|
1237
|
+
/**
|
|
1238
|
+
* @deprecated is this even an issue for WebGPU?
|
|
1239
|
+
* Attribute 0 can not be disable on most desktop OpenGL based browsers
|
|
1240
|
+
*/
|
|
1241
|
+
static isConstantAttributeZeroSupported(device) {
|
|
1242
|
+
return getBrowser() === "Chrome";
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1370
1245
|
}
|
|
1371
|
-
};
|
|
1246
|
+
});
|
|
1372
1247
|
|
|
1373
1248
|
// src/adapter/webgpu-canvas-context.ts
|
|
1374
|
-
var
|
|
1375
|
-
var
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1249
|
+
var import_core13, WebGPUCanvasContext;
|
|
1250
|
+
var init_webgpu_canvas_context = __esm({
|
|
1251
|
+
"src/adapter/webgpu-canvas-context.ts"() {
|
|
1252
|
+
"use strict";
|
|
1253
|
+
import_core13 = __toESM(require_core(), 1);
|
|
1254
|
+
init_webgpu_framebuffer();
|
|
1255
|
+
WebGPUCanvasContext = class extends import_core13.CanvasContext {
|
|
1256
|
+
device;
|
|
1257
|
+
handle;
|
|
1258
|
+
depthStencilAttachment = null;
|
|
1259
|
+
get [Symbol.toStringTag]() {
|
|
1260
|
+
return "WebGPUCanvasContext";
|
|
1261
|
+
}
|
|
1262
|
+
constructor(device, adapter, props) {
|
|
1263
|
+
super(props);
|
|
1264
|
+
const context = this.canvas.getContext("webgpu");
|
|
1265
|
+
if (!context) {
|
|
1266
|
+
throw new Error(`${this}: Failed to create WebGPU canvas context`);
|
|
1267
|
+
}
|
|
1268
|
+
this.device = device;
|
|
1269
|
+
this.handle = context;
|
|
1270
|
+
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
|
|
1271
|
+
this._updateDevice();
|
|
1272
|
+
}
|
|
1273
|
+
/** Destroy any textures produced while configured and remove the context configuration. */
|
|
1274
|
+
destroy() {
|
|
1275
|
+
this.handle.unconfigure();
|
|
1276
|
+
}
|
|
1277
|
+
/** Update framebuffer with properly resized "swap chain" texture views */
|
|
1278
|
+
getCurrentFramebuffer(options = {
|
|
1279
|
+
depthStencilFormat: "depth24plus"
|
|
1280
|
+
}) {
|
|
1281
|
+
const currentColorAttachment = this.getCurrentTexture();
|
|
1282
|
+
if (currentColorAttachment.width !== this.drawingBufferWidth || currentColorAttachment.height !== this.drawingBufferHeight) {
|
|
1283
|
+
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
1284
|
+
this.drawingBufferWidth = currentColorAttachment.width;
|
|
1285
|
+
this.drawingBufferHeight = currentColorAttachment.height;
|
|
1286
|
+
import_core13.log.log(
|
|
1287
|
+
1,
|
|
1288
|
+
`${this}: Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`
|
|
1289
|
+
)();
|
|
1290
|
+
}
|
|
1291
|
+
if (options?.depthStencilFormat) {
|
|
1292
|
+
this._createDepthStencilAttachment(options?.depthStencilFormat);
|
|
1293
|
+
}
|
|
1294
|
+
return new WebGPUFramebuffer(this.device, {
|
|
1295
|
+
colorAttachments: [currentColorAttachment],
|
|
1296
|
+
depthStencilAttachment: this.depthStencilAttachment
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
// IMPLEMENTATION OF ABSTRACT METHODS
|
|
1300
|
+
_updateDevice() {
|
|
1301
|
+
if (this.depthStencilAttachment) {
|
|
1302
|
+
this.depthStencilAttachment.destroy();
|
|
1303
|
+
this.depthStencilAttachment = null;
|
|
1304
|
+
}
|
|
1305
|
+
this.handle.configure({
|
|
1306
|
+
device: this.device.handle,
|
|
1307
|
+
format: this.device.preferredColorFormat,
|
|
1308
|
+
// Can be used to define e.g. -srgb views
|
|
1309
|
+
// viewFormats: [...]
|
|
1310
|
+
colorSpace: this.props.colorSpace,
|
|
1311
|
+
alphaMode: this.props.alphaMode
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
/** Wrap the current canvas context texture in a luma.gl texture */
|
|
1315
|
+
getCurrentTexture() {
|
|
1316
|
+
const handle = this.handle.getCurrentTexture();
|
|
1317
|
+
return this.device.createTexture({
|
|
1318
|
+
id: `${this.id}#color-texture`,
|
|
1319
|
+
handle,
|
|
1320
|
+
format: this.device.preferredColorFormat,
|
|
1321
|
+
width: handle.width,
|
|
1322
|
+
height: handle.height
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
/** We build render targets on demand (i.e. not when size changes but when about to render) */
|
|
1326
|
+
_createDepthStencilAttachment(depthStencilFormat) {
|
|
1327
|
+
if (!this.depthStencilAttachment) {
|
|
1328
|
+
this.depthStencilAttachment = this.device.createTexture({
|
|
1329
|
+
id: `${this.id}#depth-stencil-texture`,
|
|
1330
|
+
usage: import_core13.Texture.RENDER_ATTACHMENT,
|
|
1331
|
+
format: depthStencilFormat,
|
|
1332
|
+
width: this.drawingBufferWidth,
|
|
1333
|
+
height: this.drawingBufferHeight
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
return this.depthStencilAttachment;
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1413
1339
|
}
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1340
|
+
});
|
|
1341
|
+
|
|
1342
|
+
// src/adapter/resources/webgpu-command-buffer.ts
|
|
1343
|
+
var import_core14, WebGPUCommandBuffer;
|
|
1344
|
+
var init_webgpu_command_buffer = __esm({
|
|
1345
|
+
"src/adapter/resources/webgpu-command-buffer.ts"() {
|
|
1346
|
+
"use strict";
|
|
1347
|
+
import_core14 = __toESM(require_core(), 1);
|
|
1348
|
+
WebGPUCommandBuffer = class extends import_core14.CommandBuffer {
|
|
1349
|
+
device;
|
|
1350
|
+
handle;
|
|
1351
|
+
constructor(commandEncoder, props) {
|
|
1352
|
+
super(commandEncoder.device, {});
|
|
1353
|
+
this.device = commandEncoder.device;
|
|
1354
|
+
this.handle = this.props.handle || commandEncoder.handle.finish({
|
|
1355
|
+
label: props?.id || "unnamed-command-buffer"
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
};
|
|
1428
1359
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1362
|
+
// src/adapter/resources/webgpu-render-pass.ts
|
|
1363
|
+
var import_core15, WebGPURenderPass;
|
|
1364
|
+
var init_webgpu_render_pass = __esm({
|
|
1365
|
+
"src/adapter/resources/webgpu-render-pass.ts"() {
|
|
1366
|
+
"use strict";
|
|
1367
|
+
import_core15 = __toESM(require_core(), 1);
|
|
1368
|
+
WebGPURenderPass = class extends import_core15.RenderPass {
|
|
1369
|
+
device;
|
|
1370
|
+
handle;
|
|
1371
|
+
/** Active pipeline */
|
|
1372
|
+
pipeline = null;
|
|
1373
|
+
constructor(device, props = {}) {
|
|
1374
|
+
super(device, props);
|
|
1375
|
+
this.device = device;
|
|
1376
|
+
const framebuffer = props.framebuffer || device.getCanvasContext().getCurrentFramebuffer();
|
|
1377
|
+
const renderPassDescriptor = this.getRenderPassDescriptor(framebuffer);
|
|
1378
|
+
const webgpuQuerySet = props.timestampQuerySet;
|
|
1379
|
+
if (webgpuQuerySet) {
|
|
1380
|
+
renderPassDescriptor.occlusionQuerySet = webgpuQuerySet.handle;
|
|
1381
|
+
}
|
|
1382
|
+
if (device.features.has("timestamp-query")) {
|
|
1383
|
+
const webgpuTSQuerySet = props.timestampQuerySet;
|
|
1384
|
+
renderPassDescriptor.timestampWrites = webgpuTSQuerySet ? {
|
|
1385
|
+
querySet: webgpuTSQuerySet.handle,
|
|
1386
|
+
beginningOfPassWriteIndex: props.beginTimestampIndex,
|
|
1387
|
+
endOfPassWriteIndex: props.endTimestampIndex
|
|
1388
|
+
} : void 0;
|
|
1389
|
+
}
|
|
1390
|
+
if (!device.commandEncoder) {
|
|
1391
|
+
throw new Error("commandEncoder not available");
|
|
1392
|
+
}
|
|
1393
|
+
this.device.handle.pushErrorScope("validation");
|
|
1394
|
+
this.handle = this.props.handle || device.commandEncoder.handle.beginRenderPass(renderPassDescriptor);
|
|
1395
|
+
this.device.handle.popErrorScope().then((error) => {
|
|
1396
|
+
if (error) {
|
|
1397
|
+
import_core15.log.error(`${this} creation failed:
|
|
1398
|
+
"${error.message}"`, this)();
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
this.handle.label = this.props.id;
|
|
1402
|
+
import_core15.log.groupCollapsed(3, `new WebGPURenderPass(${this.id})`)();
|
|
1403
|
+
import_core15.log.probe(3, JSON.stringify(renderPassDescriptor, null, 2))();
|
|
1404
|
+
import_core15.log.groupEnd(3)();
|
|
1405
|
+
}
|
|
1406
|
+
destroy() {
|
|
1407
|
+
}
|
|
1408
|
+
end() {
|
|
1409
|
+
this.handle.end();
|
|
1410
|
+
}
|
|
1411
|
+
setPipeline(pipeline) {
|
|
1412
|
+
this.pipeline = pipeline;
|
|
1413
|
+
this.handle.setPipeline(this.pipeline.handle);
|
|
1414
|
+
}
|
|
1415
|
+
/** Sets an array of bindings (uniform buffers, samplers, textures, ...) */
|
|
1416
|
+
setBindings(bindings) {
|
|
1417
|
+
this.pipeline?.setBindings(bindings);
|
|
1418
|
+
const bindGroup = this.pipeline?._getBindGroup();
|
|
1419
|
+
if (bindGroup) {
|
|
1420
|
+
this.handle.setBindGroup(0, bindGroup);
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
setIndexBuffer(buffer, indexFormat, offset = 0, size) {
|
|
1424
|
+
this.handle.setIndexBuffer(buffer.handle, indexFormat, offset, size);
|
|
1425
|
+
}
|
|
1426
|
+
setVertexBuffer(slot, buffer, offset = 0) {
|
|
1427
|
+
this.handle.setVertexBuffer(slot, buffer.handle, offset);
|
|
1428
|
+
}
|
|
1429
|
+
draw(options) {
|
|
1430
|
+
if (options.indexCount) {
|
|
1431
|
+
this.handle.drawIndexed(
|
|
1432
|
+
options.indexCount,
|
|
1433
|
+
options.instanceCount,
|
|
1434
|
+
options.firstIndex,
|
|
1435
|
+
options.baseVertex,
|
|
1436
|
+
options.firstInstance
|
|
1437
|
+
);
|
|
1438
|
+
} else {
|
|
1439
|
+
this.handle.draw(
|
|
1440
|
+
options.vertexCount || 0,
|
|
1441
|
+
options.instanceCount || 1,
|
|
1442
|
+
options.firstIndex,
|
|
1443
|
+
options.firstInstance
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
drawIndirect() {
|
|
1448
|
+
}
|
|
1449
|
+
setParameters(parameters) {
|
|
1450
|
+
const { blendConstant, stencilReference, scissorRect, viewport } = parameters;
|
|
1451
|
+
if (blendConstant) {
|
|
1452
|
+
this.handle.setBlendConstant(blendConstant);
|
|
1453
|
+
}
|
|
1454
|
+
if (stencilReference) {
|
|
1455
|
+
this.handle.setStencilReference(stencilReference);
|
|
1456
|
+
}
|
|
1457
|
+
if (scissorRect) {
|
|
1458
|
+
this.handle.setScissorRect(scissorRect[0], scissorRect[1], scissorRect[2], scissorRect[3]);
|
|
1459
|
+
}
|
|
1460
|
+
if (viewport) {
|
|
1461
|
+
this.handle.setViewport(
|
|
1462
|
+
viewport[0],
|
|
1463
|
+
viewport[1],
|
|
1464
|
+
viewport[2],
|
|
1465
|
+
viewport[3],
|
|
1466
|
+
viewport[4],
|
|
1467
|
+
viewport[5]
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
pushDebugGroup(groupLabel) {
|
|
1472
|
+
this.handle.pushDebugGroup(groupLabel);
|
|
1473
|
+
}
|
|
1474
|
+
popDebugGroup() {
|
|
1475
|
+
this.handle.popDebugGroup();
|
|
1476
|
+
}
|
|
1477
|
+
insertDebugMarker(markerLabel) {
|
|
1478
|
+
this.handle.insertDebugMarker(markerLabel);
|
|
1479
|
+
}
|
|
1480
|
+
beginOcclusionQuery(queryIndex) {
|
|
1481
|
+
this.handle.beginOcclusionQuery(queryIndex);
|
|
1482
|
+
}
|
|
1483
|
+
endOcclusionQuery() {
|
|
1484
|
+
this.handle.endOcclusionQuery();
|
|
1485
|
+
}
|
|
1486
|
+
// executeBundles(bundles: Iterable<GPURenderBundle>): void;
|
|
1487
|
+
// INTERNAL
|
|
1488
|
+
/**
|
|
1489
|
+
* Partial render pass descriptor. Used by WebGPURenderPass.
|
|
1490
|
+
* @returns attachments fields of a renderpass descriptor.
|
|
1491
|
+
*/
|
|
1492
|
+
getRenderPassDescriptor(framebuffer) {
|
|
1493
|
+
const renderPassDescriptor = {
|
|
1494
|
+
colorAttachments: []
|
|
1495
|
+
};
|
|
1496
|
+
renderPassDescriptor.colorAttachments = framebuffer.colorAttachments.map(
|
|
1497
|
+
(colorAttachment, index) => ({
|
|
1498
|
+
// clear values
|
|
1499
|
+
loadOp: this.props.clearColor !== false ? "clear" : "load",
|
|
1500
|
+
colorClearValue: this.props.clearColors?.[index] || this.props.clearColor || import_core15.RenderPass.defaultClearColor,
|
|
1501
|
+
storeOp: this.props.discard ? "discard" : "store",
|
|
1502
|
+
// ...colorAttachment,
|
|
1503
|
+
view: colorAttachment.handle
|
|
1504
|
+
})
|
|
1505
|
+
);
|
|
1506
|
+
if (framebuffer.depthStencilAttachment) {
|
|
1507
|
+
renderPassDescriptor.depthStencilAttachment = {
|
|
1508
|
+
view: framebuffer.depthStencilAttachment.handle
|
|
1509
|
+
};
|
|
1510
|
+
const { depthStencilAttachment } = renderPassDescriptor;
|
|
1511
|
+
if (this.props.depthReadOnly) {
|
|
1512
|
+
depthStencilAttachment.depthReadOnly = true;
|
|
1513
|
+
}
|
|
1514
|
+
if (this.props.clearDepth !== false) {
|
|
1515
|
+
depthStencilAttachment.depthClearValue = this.props.clearDepth;
|
|
1516
|
+
}
|
|
1517
|
+
const hasDepthAspect = true;
|
|
1518
|
+
if (hasDepthAspect) {
|
|
1519
|
+
depthStencilAttachment.depthLoadOp = this.props.clearDepth !== false ? "clear" : "load";
|
|
1520
|
+
depthStencilAttachment.depthStoreOp = "store";
|
|
1521
|
+
}
|
|
1522
|
+
const hasStencilAspect = false;
|
|
1523
|
+
if (hasStencilAspect) {
|
|
1524
|
+
depthStencilAttachment.stencilLoadOp = this.props.clearStencil !== false ? "clear" : "load";
|
|
1525
|
+
depthStencilAttachment.stencilStoreOp = "store";
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
return renderPassDescriptor;
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1440
1531
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1532
|
+
});
|
|
1533
|
+
|
|
1534
|
+
// src/adapter/resources/webgpu-compute-pass.ts
|
|
1535
|
+
var import_core16, WebGPUComputePass;
|
|
1536
|
+
var init_webgpu_compute_pass = __esm({
|
|
1537
|
+
"src/adapter/resources/webgpu-compute-pass.ts"() {
|
|
1538
|
+
"use strict";
|
|
1539
|
+
import_core16 = __toESM(require_core(), 1);
|
|
1540
|
+
WebGPUComputePass = class extends import_core16.ComputePass {
|
|
1541
|
+
device;
|
|
1542
|
+
handle;
|
|
1543
|
+
_webgpuPipeline = null;
|
|
1544
|
+
constructor(device, props) {
|
|
1545
|
+
super(device, props);
|
|
1546
|
+
this.device = device;
|
|
1547
|
+
let timestampWrites;
|
|
1548
|
+
if (device.features.has("timestamp-query")) {
|
|
1549
|
+
const webgpuQuerySet = props.timestampQuerySet;
|
|
1550
|
+
if (webgpuQuerySet) {
|
|
1551
|
+
timestampWrites = {
|
|
1552
|
+
querySet: webgpuQuerySet.handle,
|
|
1553
|
+
beginningOfPassWriteIndex: props.beginTimestampIndex,
|
|
1554
|
+
endOfPassWriteIndex: props.endTimestampIndex
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
this.handle = this.props.handle || device.commandEncoder.handle.beginComputePass({
|
|
1559
|
+
label: this.props.id,
|
|
1560
|
+
timestampWrites
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
/** @note no WebGPU destroy method, just gc */
|
|
1564
|
+
destroy() {
|
|
1565
|
+
}
|
|
1566
|
+
end() {
|
|
1567
|
+
this.handle.end();
|
|
1568
|
+
}
|
|
1569
|
+
setPipeline(pipeline) {
|
|
1570
|
+
const wgpuPipeline = pipeline;
|
|
1571
|
+
this.handle.setPipeline(wgpuPipeline.handle);
|
|
1572
|
+
this._webgpuPipeline = wgpuPipeline;
|
|
1573
|
+
this.setBindings([]);
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Sets an array of bindings (uniform buffers, samplers, textures, ...)
|
|
1577
|
+
* TODO - still some API confusion - does this method go here or on the pipeline?
|
|
1578
|
+
*/
|
|
1579
|
+
setBindings(bindings) {
|
|
1580
|
+
const bindGroup = this._webgpuPipeline._getBindGroup();
|
|
1581
|
+
this.handle.setBindGroup(0, bindGroup);
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Dispatch work to be performed with the current ComputePipeline.
|
|
1585
|
+
* @param x X dimension of the grid of work groups to dispatch.
|
|
1586
|
+
* @param y Y dimension of the grid of work groups to dispatch.
|
|
1587
|
+
* @param z Z dimension of the grid of work groups to dispatch.
|
|
1588
|
+
*/
|
|
1589
|
+
dispatch(x, y, z) {
|
|
1590
|
+
this.handle.dispatchWorkgroups(x, y, z);
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Dispatch work to be performed with the current ComputePipeline.
|
|
1594
|
+
*
|
|
1595
|
+
* 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()
|
|
1596
|
+
* @param indirectBuffer
|
|
1597
|
+
* @param indirectOffset offset in buffer to the beginning of the dispatch data.
|
|
1598
|
+
*/
|
|
1599
|
+
dispatchIndirect(indirectBuffer, indirectByteOffset = 0) {
|
|
1600
|
+
const webgpuBuffer = indirectBuffer;
|
|
1601
|
+
this.handle.dispatchWorkgroupsIndirect(webgpuBuffer.handle, indirectByteOffset);
|
|
1602
|
+
}
|
|
1603
|
+
pushDebugGroup(groupLabel) {
|
|
1604
|
+
this.handle.pushDebugGroup(groupLabel);
|
|
1605
|
+
}
|
|
1606
|
+
popDebugGroup() {
|
|
1607
|
+
this.handle.popDebugGroup();
|
|
1608
|
+
}
|
|
1609
|
+
insertDebugMarker(markerLabel) {
|
|
1610
|
+
this.handle.insertDebugMarker(markerLabel);
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1448
1613
|
}
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1614
|
+
});
|
|
1615
|
+
|
|
1616
|
+
// src/adapter/resources/webgpu-command-encoder.ts
|
|
1617
|
+
var import_core17, WebGPUCommandEncoder;
|
|
1618
|
+
var init_webgpu_command_encoder = __esm({
|
|
1619
|
+
"src/adapter/resources/webgpu-command-encoder.ts"() {
|
|
1620
|
+
"use strict";
|
|
1621
|
+
import_core17 = __toESM(require_core(), 1);
|
|
1622
|
+
init_webgpu_command_buffer();
|
|
1623
|
+
init_webgpu_render_pass();
|
|
1624
|
+
init_webgpu_compute_pass();
|
|
1625
|
+
WebGPUCommandEncoder = class extends import_core17.CommandEncoder {
|
|
1626
|
+
device;
|
|
1627
|
+
handle;
|
|
1628
|
+
constructor(device, props = {}) {
|
|
1629
|
+
super(device, props);
|
|
1630
|
+
this.device = device;
|
|
1631
|
+
this.handle = props.handle || this.device.handle.createCommandEncoder({
|
|
1632
|
+
label: this.props.id
|
|
1633
|
+
// TODO was this removed in standard?
|
|
1634
|
+
// measureExecutionTime: this.props.measureExecutionTime
|
|
1635
|
+
});
|
|
1636
|
+
this.handle.label = this.props.id;
|
|
1637
|
+
}
|
|
1638
|
+
destroy() {
|
|
1639
|
+
}
|
|
1640
|
+
finish(props) {
|
|
1641
|
+
return new WebGPUCommandBuffer(this, {
|
|
1642
|
+
id: props?.id || "unnamed-command-buffer"
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Allows a render pass to begin against a canvas context
|
|
1647
|
+
* @todo need to support a "Framebuffer" equivalent (aka preconfigured RenderPassDescriptors?).
|
|
1648
|
+
*/
|
|
1649
|
+
beginRenderPass(props) {
|
|
1650
|
+
return new WebGPURenderPass(this.device, props);
|
|
1651
|
+
}
|
|
1652
|
+
beginComputePass(props) {
|
|
1653
|
+
return new WebGPUComputePass(this.device, props);
|
|
1654
|
+
}
|
|
1655
|
+
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
1656
|
+
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
1657
|
+
copyBufferToBuffer(options) {
|
|
1658
|
+
const webgpuSourceBuffer = options.sourceBuffer;
|
|
1659
|
+
const WebGPUDestinationBuffer = options.destinationBuffer;
|
|
1660
|
+
this.handle.copyBufferToBuffer(
|
|
1661
|
+
webgpuSourceBuffer.handle,
|
|
1662
|
+
options.sourceOffset ?? 0,
|
|
1663
|
+
WebGPUDestinationBuffer.handle,
|
|
1664
|
+
options.destinationOffset ?? 0,
|
|
1665
|
+
options.size ?? 0
|
|
1666
|
+
);
|
|
1667
|
+
}
|
|
1668
|
+
copyBufferToTexture(options) {
|
|
1669
|
+
const webgpuSourceBuffer = options.sourceBuffer;
|
|
1670
|
+
const WebGPUDestinationTexture = options.destinationTexture;
|
|
1671
|
+
this.handle.copyBufferToTexture(
|
|
1672
|
+
{
|
|
1673
|
+
buffer: webgpuSourceBuffer.handle,
|
|
1674
|
+
offset: options.offset ?? 0,
|
|
1675
|
+
bytesPerRow: options.bytesPerRow,
|
|
1676
|
+
rowsPerImage: options.rowsPerImage
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
texture: WebGPUDestinationTexture.handle,
|
|
1680
|
+
mipLevel: options.mipLevel ?? 0,
|
|
1681
|
+
origin: options.origin ?? {}
|
|
1682
|
+
// aspect: options.aspect
|
|
1683
|
+
},
|
|
1684
|
+
{
|
|
1685
|
+
// @ts-ignore
|
|
1686
|
+
width: options.extent?.[0],
|
|
1687
|
+
height: options.extent?.[1],
|
|
1688
|
+
depthOrArrayLayers: options.extent?.[2]
|
|
1689
|
+
}
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
copyTextureToBuffer(options) {
|
|
1693
|
+
}
|
|
1694
|
+
copyTextureToTexture(options) {
|
|
1695
|
+
}
|
|
1696
|
+
pushDebugGroup(groupLabel) {
|
|
1697
|
+
this.handle.pushDebugGroup(groupLabel);
|
|
1698
|
+
}
|
|
1699
|
+
popDebugGroup() {
|
|
1700
|
+
this.handle.popDebugGroup();
|
|
1701
|
+
}
|
|
1702
|
+
insertDebugMarker(markerLabel) {
|
|
1703
|
+
this.handle.insertDebugMarker(markerLabel);
|
|
1704
|
+
}
|
|
1705
|
+
resolveQuerySet(querySet, destination, options) {
|
|
1706
|
+
const webgpuQuerySet = querySet;
|
|
1707
|
+
const webgpuBuffer = destination;
|
|
1708
|
+
this.handle.resolveQuerySet(
|
|
1709
|
+
webgpuQuerySet.handle,
|
|
1710
|
+
options?.firstQuery || 0,
|
|
1711
|
+
options?.queryCount || querySet.props.count - (options?.firstQuery || 0),
|
|
1712
|
+
webgpuBuffer.handle,
|
|
1713
|
+
options?.destinationOffset || 0
|
|
1714
|
+
);
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1461
1717
|
}
|
|
1462
|
-
};
|
|
1718
|
+
});
|
|
1463
1719
|
|
|
1464
1720
|
// src/adapter/resources/webgpu-query-set.ts
|
|
1465
|
-
var
|
|
1466
|
-
var
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1721
|
+
var import_core18, WebGPUQuerySet;
|
|
1722
|
+
var init_webgpu_query_set = __esm({
|
|
1723
|
+
"src/adapter/resources/webgpu-query-set.ts"() {
|
|
1724
|
+
"use strict";
|
|
1725
|
+
import_core18 = __toESM(require_core(), 1);
|
|
1726
|
+
WebGPUQuerySet = class extends import_core18.QuerySet {
|
|
1727
|
+
device;
|
|
1728
|
+
handle;
|
|
1729
|
+
constructor(device, props) {
|
|
1730
|
+
super(device, props);
|
|
1731
|
+
this.device = device;
|
|
1732
|
+
this.handle = this.props.handle || this.device.handle.createQuerySet({
|
|
1733
|
+
type: this.props.type,
|
|
1734
|
+
count: this.props.count
|
|
1735
|
+
});
|
|
1736
|
+
this.handle.label = this.props.id;
|
|
1737
|
+
}
|
|
1738
|
+
destroy() {
|
|
1739
|
+
this.handle?.destroy();
|
|
1740
|
+
this.handle = null;
|
|
1741
|
+
}
|
|
1742
|
+
};
|
|
1481
1743
|
}
|
|
1482
|
-
};
|
|
1744
|
+
});
|
|
1483
1745
|
|
|
1484
1746
|
// src/adapter/webgpu-device.ts
|
|
1485
|
-
var
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
createExternalTexture(props) {
|
|
1549
|
-
return new WebGPUExternalTexture(this, props);
|
|
1550
|
-
}
|
|
1551
|
-
createShader(props) {
|
|
1552
|
-
return new WebGPUShader(this, props);
|
|
1553
|
-
}
|
|
1554
|
-
createSampler(props) {
|
|
1555
|
-
return new WebGPUSampler(this, props);
|
|
1556
|
-
}
|
|
1557
|
-
createRenderPipeline(props) {
|
|
1558
|
-
return new WebGPURenderPipeline(this, props);
|
|
1559
|
-
}
|
|
1560
|
-
createFramebuffer(props) {
|
|
1561
|
-
return new WebGPUFramebuffer(this, props);
|
|
1562
|
-
}
|
|
1563
|
-
createComputePipeline(props) {
|
|
1564
|
-
return new WebGPUComputePipeline(this, props);
|
|
1565
|
-
}
|
|
1566
|
-
createVertexArray(props) {
|
|
1567
|
-
return new WebGPUVertexArray(this, props);
|
|
1568
|
-
}
|
|
1569
|
-
// WebGPU specifics
|
|
1570
|
-
/**
|
|
1571
|
-
* Allows a render pass to begin against a canvas context
|
|
1572
|
-
* @todo need to support a "Framebuffer" equivalent (aka preconfigured RenderPassDescriptors?).
|
|
1573
|
-
*/
|
|
1574
|
-
beginRenderPass(props) {
|
|
1575
|
-
this.commandEncoder = this.commandEncoder || this.handle.createCommandEncoder();
|
|
1576
|
-
return new WebGPURenderPass(this, props);
|
|
1577
|
-
}
|
|
1578
|
-
beginComputePass(props) {
|
|
1579
|
-
this.commandEncoder = this.commandEncoder || this.handle.createCommandEncoder();
|
|
1580
|
-
return new WebGPUComputePass(this, props);
|
|
1581
|
-
}
|
|
1582
|
-
// createCommandEncoder(props: CommandEncoderProps): WebGPUCommandEncoder {
|
|
1583
|
-
// return new WebGPUCommandEncoder(this, props);
|
|
1584
|
-
// }
|
|
1585
|
-
createTransformFeedback(props) {
|
|
1586
|
-
throw new Error("Transform feedback not supported in WebGPU");
|
|
1587
|
-
}
|
|
1588
|
-
createQuerySet(props) {
|
|
1589
|
-
return new WebGPUQuerySet(this, props);
|
|
1590
|
-
}
|
|
1591
|
-
createCanvasContext(props) {
|
|
1592
|
-
return new WebGPUCanvasContext(this, this.adapter, props);
|
|
1593
|
-
}
|
|
1594
|
-
submit() {
|
|
1595
|
-
const commandBuffer = this.commandEncoder?.finish();
|
|
1596
|
-
if (commandBuffer) {
|
|
1597
|
-
this.handle.pushErrorScope("validation");
|
|
1598
|
-
this.handle.queue.submit([commandBuffer]);
|
|
1599
|
-
this.handle.popErrorScope().then((error) => {
|
|
1600
|
-
if (error) {
|
|
1601
|
-
this.reportError(new Error(`WebGPU command submission failed: ${error.message}`));
|
|
1747
|
+
var webgpu_device_exports = {};
|
|
1748
|
+
__export(webgpu_device_exports, {
|
|
1749
|
+
WebGPUDevice: () => WebGPUDevice
|
|
1750
|
+
});
|
|
1751
|
+
var import_core19, WebGPUDevice;
|
|
1752
|
+
var init_webgpu_device = __esm({
|
|
1753
|
+
"src/adapter/webgpu-device.ts"() {
|
|
1754
|
+
"use strict";
|
|
1755
|
+
import_core19 = __toESM(require_core(), 1);
|
|
1756
|
+
init_webgpu_buffer();
|
|
1757
|
+
init_webgpu_texture();
|
|
1758
|
+
init_webgpu_external_texture();
|
|
1759
|
+
init_webgpu_sampler();
|
|
1760
|
+
init_webgpu_shader();
|
|
1761
|
+
init_webgpu_render_pipeline();
|
|
1762
|
+
init_webgpu_framebuffer();
|
|
1763
|
+
init_webgpu_compute_pipeline();
|
|
1764
|
+
init_webgpu_vertex_array();
|
|
1765
|
+
init_webgpu_canvas_context();
|
|
1766
|
+
init_webgpu_command_encoder();
|
|
1767
|
+
init_webgpu_query_set();
|
|
1768
|
+
WebGPUDevice = class extends import_core19.Device {
|
|
1769
|
+
/** The underlying WebGPU device */
|
|
1770
|
+
handle;
|
|
1771
|
+
/** type of this device */
|
|
1772
|
+
type = "webgpu";
|
|
1773
|
+
preferredColorFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
1774
|
+
preferredDepthFormat = "depth24plus";
|
|
1775
|
+
features;
|
|
1776
|
+
info;
|
|
1777
|
+
limits;
|
|
1778
|
+
lost;
|
|
1779
|
+
canvasContext = null;
|
|
1780
|
+
_isLost = false;
|
|
1781
|
+
commandEncoder;
|
|
1782
|
+
/* The underlying WebGPU adapter */
|
|
1783
|
+
adapter;
|
|
1784
|
+
/* The underlying WebGPU adapter's info */
|
|
1785
|
+
adapterInfo;
|
|
1786
|
+
constructor(props, device, adapter, adapterInfo) {
|
|
1787
|
+
super({ ...props, id: props.id || "webgpu-device" });
|
|
1788
|
+
this.handle = device;
|
|
1789
|
+
this.adapter = adapter;
|
|
1790
|
+
this.adapterInfo = adapterInfo;
|
|
1791
|
+
this.info = this._getInfo();
|
|
1792
|
+
this.features = this._getFeatures();
|
|
1793
|
+
this.limits = this.handle.limits;
|
|
1794
|
+
device.addEventListener("uncapturederror", (event) => {
|
|
1795
|
+
event.preventDefault();
|
|
1796
|
+
const errorMessage = event instanceof GPUUncapturedErrorEvent ? event.error.message : "Unknown WebGPU error";
|
|
1797
|
+
this.reportError(new Error(errorMessage));
|
|
1798
|
+
if (this.props.debug) {
|
|
1799
|
+
debugger;
|
|
1800
|
+
}
|
|
1801
|
+
});
|
|
1802
|
+
this.lost = new Promise(async (resolve) => {
|
|
1803
|
+
const lostInfo = await this.handle.lost;
|
|
1804
|
+
this._isLost = true;
|
|
1805
|
+
resolve({ reason: "destroyed", message: lostInfo.message });
|
|
1806
|
+
});
|
|
1807
|
+
if (props.createCanvasContext) {
|
|
1808
|
+
const canvasContextProps = props.createCanvasContext === true ? {} : props.createCanvasContext;
|
|
1809
|
+
this.canvasContext = new WebGPUCanvasContext(this, this.adapter, canvasContextProps);
|
|
1602
1810
|
}
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1811
|
+
this.commandEncoder = this.createCommandEncoder({});
|
|
1812
|
+
}
|
|
1813
|
+
// TODO
|
|
1814
|
+
// Load the glslang module now so that it is available synchronously when compiling shaders
|
|
1815
|
+
// const {glsl = true} = props;
|
|
1816
|
+
// this.glslang = glsl && await loadGlslangModule();
|
|
1817
|
+
destroy() {
|
|
1818
|
+
this.handle.destroy();
|
|
1819
|
+
}
|
|
1820
|
+
get isLost() {
|
|
1821
|
+
return this._isLost;
|
|
1822
|
+
}
|
|
1823
|
+
createBuffer(props) {
|
|
1824
|
+
const newProps = this._normalizeBufferProps(props);
|
|
1825
|
+
return new WebGPUBuffer(this, newProps);
|
|
1826
|
+
}
|
|
1827
|
+
createTexture(props) {
|
|
1828
|
+
return new WebGPUTexture(this, props);
|
|
1829
|
+
}
|
|
1830
|
+
createExternalTexture(props) {
|
|
1831
|
+
return new WebGPUExternalTexture(this, props);
|
|
1832
|
+
}
|
|
1833
|
+
createShader(props) {
|
|
1834
|
+
return new WebGPUShader(this, props);
|
|
1835
|
+
}
|
|
1836
|
+
createSampler(props) {
|
|
1837
|
+
return new WebGPUSampler(this, props);
|
|
1838
|
+
}
|
|
1839
|
+
createRenderPipeline(props) {
|
|
1840
|
+
return new WebGPURenderPipeline(this, props);
|
|
1841
|
+
}
|
|
1842
|
+
createFramebuffer(props) {
|
|
1843
|
+
return new WebGPUFramebuffer(this, props);
|
|
1844
|
+
}
|
|
1845
|
+
createComputePipeline(props) {
|
|
1846
|
+
return new WebGPUComputePipeline(this, props);
|
|
1847
|
+
}
|
|
1848
|
+
createVertexArray(props) {
|
|
1849
|
+
return new WebGPUVertexArray(this, props);
|
|
1850
|
+
}
|
|
1851
|
+
createCommandEncoder(props) {
|
|
1852
|
+
return new WebGPUCommandEncoder(this, props);
|
|
1853
|
+
}
|
|
1854
|
+
// WebGPU specifics
|
|
1855
|
+
createTransformFeedback(props) {
|
|
1856
|
+
throw new Error("Transform feedback not supported in WebGPU");
|
|
1857
|
+
}
|
|
1858
|
+
createQuerySet(props) {
|
|
1859
|
+
return new WebGPUQuerySet(this, props);
|
|
1860
|
+
}
|
|
1861
|
+
createCanvasContext(props) {
|
|
1862
|
+
return new WebGPUCanvasContext(this, this.adapter, props);
|
|
1863
|
+
}
|
|
1864
|
+
submit(commandBuffer) {
|
|
1865
|
+
if (!commandBuffer) {
|
|
1866
|
+
commandBuffer = this.commandEncoder.finish();
|
|
1867
|
+
this.commandEncoder.destroy();
|
|
1868
|
+
this.commandEncoder = this.createCommandEncoder({ id: `${this.id}-default-encoder` });
|
|
1869
|
+
}
|
|
1870
|
+
this.handle.pushErrorScope("validation");
|
|
1871
|
+
this.handle.queue.submit([commandBuffer.handle]);
|
|
1872
|
+
this.handle.popErrorScope().then((error) => {
|
|
1873
|
+
if (error) {
|
|
1874
|
+
this.reportError(new Error(`WebGPU command submission failed: ${error.message}`));
|
|
1875
|
+
}
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
// WebGPU specific
|
|
1879
|
+
pushErrorScope(scope) {
|
|
1880
|
+
this.handle.pushErrorScope(scope);
|
|
1881
|
+
}
|
|
1882
|
+
popErrorScope(handler) {
|
|
1883
|
+
this.handle.popErrorScope().then((error) => {
|
|
1884
|
+
if (error) {
|
|
1885
|
+
handler(error.message);
|
|
1886
|
+
}
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
// PRIVATE METHODS
|
|
1890
|
+
_getInfo() {
|
|
1891
|
+
const [driver, driverVersion] = (this.adapterInfo.driver || "").split(" Version ");
|
|
1892
|
+
const vendor = this.adapterInfo.vendor || this.adapter.__brand || "unknown";
|
|
1893
|
+
const renderer = driver || "";
|
|
1894
|
+
const version = driverVersion || "";
|
|
1895
|
+
const gpu = vendor === "apple" ? "apple" : "unknown";
|
|
1896
|
+
const gpuArchitecture = this.adapterInfo.architecture || "unknown";
|
|
1897
|
+
const gpuBackend = this.adapterInfo.backend || "unknown";
|
|
1898
|
+
const gpuType = (this.adapterInfo.type || "").split(" ")[0].toLowerCase() || "unknown";
|
|
1899
|
+
return {
|
|
1900
|
+
type: "webgpu",
|
|
1901
|
+
vendor,
|
|
1902
|
+
renderer,
|
|
1903
|
+
version,
|
|
1904
|
+
gpu,
|
|
1905
|
+
gpuType,
|
|
1906
|
+
gpuBackend,
|
|
1907
|
+
gpuArchitecture,
|
|
1908
|
+
shadingLanguage: "wgsl",
|
|
1909
|
+
shadingLanguageVersion: 100
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
_getFeatures() {
|
|
1913
|
+
const features = new Set(this.handle.features);
|
|
1914
|
+
if (features.has("depth-clamping")) {
|
|
1915
|
+
features.delete("depth-clamping");
|
|
1916
|
+
features.add("depth-clip-control");
|
|
1917
|
+
}
|
|
1918
|
+
if (features.has("texture-compression-bc")) {
|
|
1919
|
+
features.add("texture-compression-bc5-webgl");
|
|
1920
|
+
}
|
|
1921
|
+
const WEBGPU_ALWAYS_FEATURES = [
|
|
1922
|
+
"timer-query-webgl",
|
|
1923
|
+
"compilation-status-async-webgl",
|
|
1924
|
+
"float32-renderable-webgl",
|
|
1925
|
+
"float16-renderable-webgl",
|
|
1926
|
+
"norm16-renderable-webgl",
|
|
1927
|
+
"texture-filterable-anisotropic-webgl",
|
|
1928
|
+
"shader-noperspective-interpolation-webgl"
|
|
1929
|
+
];
|
|
1930
|
+
for (const feature of WEBGPU_ALWAYS_FEATURES) {
|
|
1931
|
+
features.add(feature);
|
|
1932
|
+
}
|
|
1933
|
+
return new import_core19.DeviceFeatures(Array.from(features), this.props._disabledFeatures);
|
|
1934
|
+
}
|
|
1935
|
+
_getDeviceSpecificTextureFormatCapabilities(capabilities) {
|
|
1936
|
+
const { format } = capabilities;
|
|
1937
|
+
if (format.includes("webgl")) {
|
|
1938
|
+
return { format, create: false, render: false, filter: false, blend: false, store: false };
|
|
1939
|
+
}
|
|
1940
|
+
return capabilities;
|
|
1941
|
+
}
|
|
1628
1942
|
};
|
|
1629
1943
|
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
"float16-renderable-webgl",
|
|
1644
|
-
"norm16-renderable-webgl",
|
|
1645
|
-
"texture-filterable-anisotropic-webgl",
|
|
1646
|
-
"shader-noperspective-interpolation-webgl"
|
|
1647
|
-
];
|
|
1648
|
-
for (const feature of WEBGPU_ALWAYS_FEATURES) {
|
|
1649
|
-
features.add(feature);
|
|
1650
|
-
}
|
|
1651
|
-
return new import_core17.DeviceFeatures(Array.from(features), this.props._disabledFeatures);
|
|
1652
|
-
}
|
|
1653
|
-
_getDeviceSpecificTextureFormatCapabilities(capabilities) {
|
|
1654
|
-
const { format } = capabilities;
|
|
1655
|
-
if (format.includes("webgl")) {
|
|
1656
|
-
return { format, create: false, render: false, filter: false, blend: false, store: false };
|
|
1657
|
-
}
|
|
1658
|
-
return capabilities;
|
|
1659
|
-
}
|
|
1660
|
-
// DEPRECATED METHODS
|
|
1661
|
-
// @deprecated
|
|
1662
|
-
copyExternalImageToTexture(options) {
|
|
1663
|
-
const {
|
|
1664
|
-
source,
|
|
1665
|
-
sourceX = 0,
|
|
1666
|
-
sourceY = 0,
|
|
1667
|
-
texture,
|
|
1668
|
-
mipLevel = 0,
|
|
1669
|
-
aspect = "all",
|
|
1670
|
-
colorSpace = "display-p3",
|
|
1671
|
-
premultipliedAlpha = false,
|
|
1672
|
-
// destinationX,
|
|
1673
|
-
// destinationY,
|
|
1674
|
-
// desitnationZ,
|
|
1675
|
-
width = texture.width,
|
|
1676
|
-
height = texture.height,
|
|
1677
|
-
depth = 1
|
|
1678
|
-
} = options;
|
|
1679
|
-
const webGpuTexture = texture;
|
|
1680
|
-
this.handle?.queue.copyExternalImageToTexture(
|
|
1681
|
-
// source: GPUImageCopyExternalImage
|
|
1682
|
-
{
|
|
1683
|
-
source,
|
|
1684
|
-
origin: [sourceX, sourceY]
|
|
1685
|
-
},
|
|
1686
|
-
// destination: GPUImageCopyTextureTagged
|
|
1687
|
-
{
|
|
1688
|
-
texture: webGpuTexture.handle,
|
|
1689
|
-
origin: [0, 0, 0],
|
|
1690
|
-
// [x, y, z],
|
|
1691
|
-
mipLevel,
|
|
1692
|
-
aspect,
|
|
1693
|
-
colorSpace,
|
|
1694
|
-
premultipliedAlpha
|
|
1695
|
-
},
|
|
1696
|
-
// copySize: GPUExtent3D
|
|
1697
|
-
[width, height, depth]
|
|
1698
|
-
);
|
|
1699
|
-
}
|
|
1700
|
-
};
|
|
1944
|
+
});
|
|
1945
|
+
|
|
1946
|
+
// bundle.ts
|
|
1947
|
+
var bundle_exports = {};
|
|
1948
|
+
__export(bundle_exports, {
|
|
1949
|
+
WebGPUBuffer: () => WebGPUBuffer,
|
|
1950
|
+
WebGPUDevice: () => WebGPUDevice,
|
|
1951
|
+
WebGPUSampler: () => WebGPUSampler,
|
|
1952
|
+
WebGPUShader: () => WebGPUShader,
|
|
1953
|
+
WebGPUTexture: () => WebGPUTexture,
|
|
1954
|
+
webgpuAdapter: () => webgpuAdapter
|
|
1955
|
+
});
|
|
1956
|
+
__reExport(bundle_exports, __toESM(require_core(), 1));
|
|
1701
1957
|
|
|
1702
1958
|
// src/adapter/webgpu-adapter.ts
|
|
1703
|
-
var
|
|
1959
|
+
var import_core20 = __toESM(require_core(), 1);
|
|
1960
|
+
var WebGPUAdapter = class extends import_core20.Adapter {
|
|
1704
1961
|
/** type of device's created by this adapter */
|
|
1705
1962
|
type = "webgpu";
|
|
1706
|
-
constructor() {
|
|
1707
|
-
super();
|
|
1708
|
-
WebGPUDevice.adapter = this;
|
|
1709
|
-
}
|
|
1710
|
-
/** Check if WebGPU is available */
|
|
1711
1963
|
isSupported() {
|
|
1712
1964
|
return Boolean(typeof navigator !== "undefined" && navigator.gpu);
|
|
1713
1965
|
}
|
|
1966
|
+
isDeviceHandle(handle) {
|
|
1967
|
+
if (typeof GPUDevice !== "undefined" && handle instanceof GPUDevice) {
|
|
1968
|
+
return true;
|
|
1969
|
+
}
|
|
1970
|
+
if (handle?.queue) {
|
|
1971
|
+
return true;
|
|
1972
|
+
}
|
|
1973
|
+
return false;
|
|
1974
|
+
}
|
|
1714
1975
|
async create(props) {
|
|
1715
1976
|
if (!navigator.gpu) {
|
|
1716
|
-
throw new Error(
|
|
1717
|
-
"WebGPU not available. Open in Chrome Canary and turn on chrome://flags/#enable-unsafe-webgpu"
|
|
1718
|
-
);
|
|
1977
|
+
throw new Error("WebGPU not available. Recent Chrome browsers should work.");
|
|
1719
1978
|
}
|
|
1720
|
-
|
|
1979
|
+
import_core20.log.groupCollapsed(1, "WebGPUDevice created")();
|
|
1721
1980
|
const adapter = await navigator.gpu.requestAdapter({
|
|
1722
1981
|
powerPreference: "high-performance"
|
|
1723
1982
|
// forceSoftware: false
|
|
@@ -1725,8 +1984,9 @@ var __exports__ = (() => {
|
|
|
1725
1984
|
if (!adapter) {
|
|
1726
1985
|
throw new Error("Failed to request WebGPU adapter");
|
|
1727
1986
|
}
|
|
1728
|
-
const adapterInfo =
|
|
1729
|
-
|
|
1987
|
+
const adapterInfo = adapter.info || // @ts-ignore
|
|
1988
|
+
await adapter.requestAdapterInfo?.();
|
|
1989
|
+
import_core20.log.probe(2, "Adapter available", adapterInfo)();
|
|
1730
1990
|
const requiredFeatures = [];
|
|
1731
1991
|
const requiredLimits = {};
|
|
1732
1992
|
if (props._requestMaxLimits) {
|
|
@@ -1746,14 +2006,15 @@ var __exports__ = (() => {
|
|
|
1746
2006
|
requiredFeatures,
|
|
1747
2007
|
requiredLimits
|
|
1748
2008
|
});
|
|
1749
|
-
|
|
1750
|
-
const
|
|
1751
|
-
|
|
2009
|
+
import_core20.log.probe(1, "GPUDevice available")();
|
|
2010
|
+
const { WebGPUDevice: WebGPUDevice2 } = await Promise.resolve().then(() => (init_webgpu_device(), webgpu_device_exports));
|
|
2011
|
+
const device = new WebGPUDevice2(props, gpuDevice, adapter, adapterInfo);
|
|
2012
|
+
import_core20.log.probe(
|
|
1752
2013
|
1,
|
|
1753
2014
|
"Device created. For more info, set chrome://flags/#enable-webgpu-developer-features"
|
|
1754
2015
|
)();
|
|
1755
|
-
|
|
1756
|
-
|
|
2016
|
+
import_core20.log.table(1, device.info)();
|
|
2017
|
+
import_core20.log.groupEnd(1)();
|
|
1757
2018
|
return device;
|
|
1758
2019
|
}
|
|
1759
2020
|
async attach(handle) {
|
|
@@ -1761,6 +2022,13 @@ var __exports__ = (() => {
|
|
|
1761
2022
|
}
|
|
1762
2023
|
};
|
|
1763
2024
|
var webgpuAdapter = new WebGPUAdapter();
|
|
2025
|
+
|
|
2026
|
+
// src/index.ts
|
|
2027
|
+
init_webgpu_device();
|
|
2028
|
+
init_webgpu_buffer();
|
|
2029
|
+
init_webgpu_texture();
|
|
2030
|
+
init_webgpu_sampler();
|
|
2031
|
+
init_webgpu_shader();
|
|
1764
2032
|
return __toCommonJS(bundle_exports);
|
|
1765
2033
|
})();
|
|
1766
2034
|
return __exports__;
|