@luma.gl/webgpu 9.0.0-beta.1 → 9.0.0-beta.10
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 +102 -1
- package/dist/adapter/helpers/convert-texture-format.d.ts.map +1 -1
- package/dist/adapter/helpers/convert-texture-format.js +8 -5
- package/dist/adapter/helpers/get-bind-group.d.ts +3 -3
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +57 -41
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +117 -80
- package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.js +185 -125
- package/dist/adapter/resources/webgpu-buffer.d.ts +1 -1
- package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.js +119 -62
- package/dist/adapter/resources/webgpu-command-encoder.d.ts +7 -1
- package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.js +81 -49
- package/dist/adapter/resources/webgpu-compute-pass.d.ts +15 -9
- package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js +76 -41
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +14 -4
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.js +46 -19
- package/dist/adapter/resources/webgpu-external-texture.d.ts +2 -2
- package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-external-texture.js +35 -18
- package/dist/adapter/resources/webgpu-framebuffer.d.ts +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.js +14 -7
- package/dist/adapter/resources/webgpu-query-set.d.ts +17 -0
- package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-query-set.js +27 -0
- package/dist/adapter/resources/webgpu-render-pass.d.ts +4 -2
- package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.js +133 -105
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts +52 -5
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.js +151 -78
- package/dist/adapter/resources/webgpu-sampler.d.ts +1 -1
- package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.js +21 -15
- package/dist/adapter/resources/webgpu-shader.d.ts +2 -5
- package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-shader.js +45 -44
- package/dist/adapter/resources/webgpu-texture-view.d.ts +20 -0
- package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-texture-view.js +35 -0
- package/dist/adapter/resources/webgpu-texture.d.ts +8 -8
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +130 -107
- package/dist/adapter/resources/webgpu-vertex-array.d.ts +9 -8
- package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js +60 -39
- package/dist/adapter/webgpu-canvas-context.d.ts +3 -3
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +101 -67
- package/dist/adapter/webgpu-device.d.ts +26 -28
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +254 -220
- package/dist/dist.dev.js +804 -2270
- package/dist/dist.min.js +9 -0
- package/dist/index.cjs +366 -485
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist.min.js +1 -22
- package/package.json +9 -7
- package/src/adapter/helpers/accessor-to-format.ts +5 -1
- package/src/adapter/helpers/convert-texture-format.ts +4 -1
- package/src/adapter/helpers/get-bind-group.ts +12 -6
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +13 -5
- package/src/adapter/helpers/webgpu-parameters.ts +79 -15
- package/src/adapter/resources/webgpu-buffer.ts +24 -11
- package/src/adapter/resources/webgpu-command-encoder.ts +24 -9
- package/src/adapter/resources/webgpu-compute-pass.ts +45 -22
- package/src/adapter/resources/webgpu-compute-pipeline.ts +48 -16
- package/src/adapter/resources/webgpu-external-texture.ts +14 -6
- package/src/adapter/resources/webgpu-framebuffer.ts +4 -0
- package/src/adapter/resources/webgpu-query-set.ts +37 -0
- package/src/adapter/resources/webgpu-render-pass.ts +37 -14
- package/src/adapter/resources/webgpu-render-pipeline.ts +80 -119
- package/src/adapter/resources/webgpu-sampler.ts +4 -1
- package/src/adapter/resources/webgpu-shader.ts +14 -25
- package/src/adapter/resources/webgpu-texture-view.ts +46 -0
- package/src/adapter/resources/webgpu-texture.ts +33 -28
- package/src/adapter/resources/webgpu-vertex-array.ts +28 -20
- package/src/adapter/webgpu-canvas-context.ts +10 -4
- package/src/adapter/webgpu-device.ts +109 -106
- package/src/index.ts +2 -1
- package/dist/adapter/helpers/accessor-to-format.js.map +0 -1
- package/dist/adapter/helpers/convert-texture-format.js.map +0 -1
- package/dist/adapter/helpers/generate-mipmaps.d.ts +0 -10
- package/dist/adapter/helpers/generate-mipmaps.d.ts.map +0 -1
- package/dist/adapter/helpers/generate-mipmaps.js +0 -100
- package/dist/adapter/helpers/generate-mipmaps.js.map +0 -1
- package/dist/adapter/helpers/get-bind-group.js.map +0 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +0 -1
- package/dist/adapter/helpers/webgpu-parameters.js.map +0 -1
- package/dist/adapter/resources/webgpu-buffer.js.map +0 -1
- package/dist/adapter/resources/webgpu-command-encoder.js.map +0 -1
- package/dist/adapter/resources/webgpu-compute-pass.js.map +0 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.js.map +0 -1
- package/dist/adapter/resources/webgpu-external-texture.js.map +0 -1
- package/dist/adapter/resources/webgpu-framebuffer.js.map +0 -1
- package/dist/adapter/resources/webgpu-query.d.ts +0 -1
- package/dist/adapter/resources/webgpu-query.d.ts.map +0 -1
- package/dist/adapter/resources/webgpu-query.js +0 -2
- package/dist/adapter/resources/webgpu-query.js.map +0 -1
- package/dist/adapter/resources/webgpu-render-pass.js.map +0 -1
- package/dist/adapter/resources/webgpu-render-pipeline.js.map +0 -1
- package/dist/adapter/resources/webgpu-sampler.js.map +0 -1
- package/dist/adapter/resources/webgpu-shader.js.map +0 -1
- package/dist/adapter/resources/webgpu-texture.js.map +0 -1
- package/dist/adapter/resources/webgpu-vertex-array.js.map +0 -1
- package/dist/adapter/webgpu-canvas-context.js.map +0 -1
- package/dist/adapter/webgpu-device.js.map +0 -1
- package/dist/adapter/webgpu-types.d.ts +0 -1
- package/dist/adapter/webgpu-types.d.ts.map +0 -1
- package/dist/adapter/webgpu-types.js +0 -2
- package/dist/adapter/webgpu-types.js.map +0 -1
- package/dist/glsl/glsllang.d.ts +0 -3
- package/dist/glsl/glsllang.d.ts.map +0 -1
- package/dist/glsl/glsllang.js +0 -9
- package/dist/glsl/glsllang.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/src/adapter/helpers/generate-mipmaps.ts +0 -107
- package/src/adapter/resources/webgpu-query.ts +0 -43
- package/src/adapter/webgpu-types.ts +0 -0
- package/src/glsl/glsllang.ts +0 -14
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
// luma.gl
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
2
3
|
// Copyright (c) vis.gl contributors
|
|
3
4
|
|
|
4
|
-
import type {Device, Buffer, VertexArrayProps, RenderPass
|
|
5
|
+
import type {Device, Buffer, VertexArrayProps, RenderPass} from '@luma.gl/core';
|
|
5
6
|
import {VertexArray, log} from '@luma.gl/core';
|
|
6
7
|
import {getBrowser} from '@probe.gl/env';
|
|
7
8
|
|
|
@@ -20,11 +21,6 @@ export class WebGPUVertexArray extends VertexArray {
|
|
|
20
21
|
/** Vertex Array is a helper class under WebGPU */
|
|
21
22
|
readonly handle: never;
|
|
22
23
|
|
|
23
|
-
/** * Attribute 0 can not be disable on most desktop OpenGL based browsers */
|
|
24
|
-
static isConstantAttributeZeroSupported(device: Device): boolean {
|
|
25
|
-
return device.info.type === 'webgl2' || getBrowser() === 'Chrome';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
24
|
// Create a VertexArray
|
|
29
25
|
constructor(device: WebGPUDevice, props?: VertexArrayProps) {
|
|
30
26
|
super(device, props);
|
|
@@ -35,40 +31,42 @@ export class WebGPUVertexArray extends VertexArray {
|
|
|
35
31
|
|
|
36
32
|
/**
|
|
37
33
|
* Set an elements buffer, for indexed rendering.
|
|
38
|
-
* Must be a Buffer bound to buffer with usage bit Buffer.INDEX set.
|
|
34
|
+
* Must be a Buffer bound to buffer with usage bit Buffer.INDEX set.
|
|
39
35
|
*/
|
|
40
36
|
setIndexBuffer(buffer: Buffer | null): void {
|
|
41
37
|
// assert(!elementBuffer || elementBuffer.glTarget === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
|
|
42
38
|
this.indexBuffer = buffer;
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
/** Set a
|
|
46
|
-
setBuffer(
|
|
41
|
+
/** Set a bufferSlot in vertex attributes array to a buffer, enables the bufferSlot, sets divisor */
|
|
42
|
+
setBuffer(bufferSlot: number, buffer: Buffer): void {
|
|
47
43
|
// Sanity check target
|
|
48
44
|
// if (buffer.glUsage === GL.ELEMENT_ARRAY_BUFFER) {
|
|
49
45
|
// throw new Error('Use setIndexBuffer');
|
|
50
46
|
// }
|
|
51
47
|
|
|
52
|
-
this.attributes[
|
|
48
|
+
this.attributes[bufferSlot] = buffer;
|
|
53
49
|
}
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
override bindBeforeRender(renderPass: RenderPass, firstIndex?: number, indexCount?: number): void {
|
|
51
|
+
override bindBeforeRender(
|
|
52
|
+
renderPass: RenderPass,
|
|
53
|
+
firstIndex?: number,
|
|
54
|
+
indexCount?: number
|
|
55
|
+
): void {
|
|
61
56
|
const webgpuRenderPass = renderPass as WebGPURenderPass;
|
|
62
57
|
const webgpuIndexBuffer = this.indexBuffer as WebGPUBuffer;
|
|
63
58
|
if (webgpuIndexBuffer?.handle) {
|
|
64
59
|
// Note we can't unset an index buffer
|
|
65
60
|
log.warn('setting index buffer', webgpuIndexBuffer?.handle, webgpuIndexBuffer?.indexType)();
|
|
66
|
-
webgpuRenderPass.handle.setIndexBuffer(
|
|
61
|
+
webgpuRenderPass.handle.setIndexBuffer(
|
|
62
|
+
webgpuIndexBuffer?.handle,
|
|
63
|
+
webgpuIndexBuffer?.indexType
|
|
64
|
+
);
|
|
67
65
|
}
|
|
68
66
|
for (let location = 0; location < this.maxVertexAttributes; location++) {
|
|
69
67
|
const webgpuBuffer = this.attributes[location] as WebGPUBuffer;
|
|
70
68
|
if (webgpuBuffer?.handle) {
|
|
71
|
-
log.warn(
|
|
69
|
+
log.warn(`setting vertex buffer ${location}`, webgpuBuffer?.handle)();
|
|
72
70
|
webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);
|
|
73
71
|
}
|
|
74
72
|
}
|
|
@@ -76,8 +74,18 @@ export class WebGPUVertexArray extends VertexArray {
|
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
override unbindAfterRender(renderPass: RenderPass): void {
|
|
79
|
-
// On WebGPU we don't need to unbind.
|
|
77
|
+
// On WebGPU we don't need to unbind.
|
|
80
78
|
// In fact we can't easily do it. setIndexBuffer/setVertexBuffer don't accept null.
|
|
81
79
|
// Unbinding presumably happens automatically when the render pass is ended.
|
|
82
80
|
}
|
|
81
|
+
|
|
82
|
+
// DEPRECATED METHODS
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @deprecated is this even an issue for WebGPU?
|
|
86
|
+
* Attribute 0 can not be disable on most desktop OpenGL based browsers
|
|
87
|
+
*/
|
|
88
|
+
static isConstantAttributeZeroSupported(device: Device): boolean {
|
|
89
|
+
return getBrowser() === 'Chrome';
|
|
90
|
+
}
|
|
83
91
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
// / <reference types="@webgpu/types" />
|
|
6
|
+
|
|
2
7
|
import type {Texture, TextureFormat, CanvasContextProps} from '@luma.gl/core';
|
|
3
8
|
import {CanvasContext, log} from '@luma.gl/core';
|
|
4
9
|
import {getWebGPUTextureFormat} from './helpers/convert-texture-format';
|
|
@@ -6,7 +11,7 @@ import {WebGPUDevice} from './webgpu-device';
|
|
|
6
11
|
import {WebGPUFramebuffer} from './resources/webgpu-framebuffer';
|
|
7
12
|
import {WebGPUTexture} from './resources/webgpu-texture';
|
|
8
13
|
|
|
9
|
-
/**
|
|
14
|
+
/**
|
|
10
15
|
* Holds a WebGPU Canvas Context
|
|
11
16
|
* The primary job of the CanvasContext is to generate textures for rendering into the current canvas
|
|
12
17
|
* It also manages canvas sizing calculations and resizing.
|
|
@@ -15,7 +20,7 @@ export class WebGPUCanvasContext extends CanvasContext {
|
|
|
15
20
|
readonly device: WebGPUDevice;
|
|
16
21
|
readonly gpuCanvasContext: GPUCanvasContext;
|
|
17
22
|
/** Format of returned textures: "bgra8unorm", "rgba8unorm", "rgba16float". */
|
|
18
|
-
readonly format: TextureFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
23
|
+
readonly format: TextureFormat = navigator.gpu.getPreferredCanvasFormat() as TextureFormat;
|
|
19
24
|
/** Default stencil format for depth textures */
|
|
20
25
|
depthStencilFormat: TextureFormat = 'depth24plus';
|
|
21
26
|
|
|
@@ -55,7 +60,7 @@ export class WebGPUCanvasContext extends CanvasContext {
|
|
|
55
60
|
// height: this.height
|
|
56
61
|
// });
|
|
57
62
|
|
|
58
|
-
// Wrap the current canvas context texture in a luma.gl texture
|
|
63
|
+
// Wrap the current canvas context texture in a luma.gl texture
|
|
59
64
|
const currentColorAttachment = this.getCurrentTexture();
|
|
60
65
|
this.width = currentColorAttachment.width;
|
|
61
66
|
this.height = currentColorAttachment.height;
|
|
@@ -107,7 +112,8 @@ export class WebGPUCanvasContext extends CanvasContext {
|
|
|
107
112
|
getCurrentTexture(): WebGPUTexture {
|
|
108
113
|
return this.device._createTexture({
|
|
109
114
|
id: `${this.id}#color-texture`,
|
|
110
|
-
handle: this.gpuCanvasContext.getCurrentTexture()
|
|
115
|
+
handle: this.gpuCanvasContext.getCurrentTexture(),
|
|
116
|
+
format: this.format
|
|
111
117
|
});
|
|
112
118
|
}
|
|
113
119
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
// prettier-ignore
|
|
2
6
|
// / <reference types="@webgpu/types" />
|
|
3
7
|
|
|
@@ -22,9 +26,11 @@ import type {
|
|
|
22
26
|
// CommandEncoderProps,
|
|
23
27
|
VertexArrayProps,
|
|
24
28
|
TransformFeedback,
|
|
25
|
-
TransformFeedbackProps
|
|
29
|
+
TransformFeedbackProps,
|
|
30
|
+
QuerySet,
|
|
31
|
+
QuerySetProps
|
|
26
32
|
} from '@luma.gl/core';
|
|
27
|
-
import {Device, CanvasContext, log, uid} from '@luma.gl/core';
|
|
33
|
+
import {Device, DeviceFeatures, CanvasContext, log, uid} from '@luma.gl/core';
|
|
28
34
|
import {WebGPUBuffer} from './resources/webgpu-buffer';
|
|
29
35
|
import {WebGPUTexture} from './resources/webgpu-texture';
|
|
30
36
|
import {WebGPUExternalTexture} from './resources/webgpu-external-texture';
|
|
@@ -39,23 +45,33 @@ import {WebGPUComputePass} from './resources/webgpu-compute-pass';
|
|
|
39
45
|
import {WebGPUVertexArray} from './resources/webgpu-vertex-array';
|
|
40
46
|
|
|
41
47
|
import {WebGPUCanvasContext} from './webgpu-canvas-context';
|
|
42
|
-
|
|
48
|
+
import {WebGPUQuerySet} from './resources/webgpu-query-set';
|
|
43
49
|
|
|
44
50
|
/** WebGPU Device implementation */
|
|
45
51
|
export class WebGPUDevice extends Device {
|
|
52
|
+
static type: string = 'webgpu';
|
|
53
|
+
|
|
54
|
+
/** type of this device */
|
|
55
|
+
readonly type = 'webgpu';
|
|
56
|
+
|
|
57
|
+
/** The underlying WebGPU device */
|
|
46
58
|
readonly handle: GPUDevice;
|
|
59
|
+
/* The underlying WebGPU adapter */
|
|
47
60
|
readonly adapter: GPUAdapter;
|
|
61
|
+
/* The underlying WebGPU adapter's info */
|
|
62
|
+
readonly adapterInfo: GPUAdapterInfo;
|
|
63
|
+
|
|
64
|
+
readonly features: DeviceFeatures;
|
|
65
|
+
readonly info: DeviceInfo;
|
|
66
|
+
readonly limits: DeviceLimits;
|
|
67
|
+
|
|
48
68
|
readonly lost: Promise<{reason: 'destroyed'; message: string}>;
|
|
49
69
|
canvasContext: WebGPUCanvasContext | null = null;
|
|
50
70
|
|
|
71
|
+
private _isLost: boolean = false;
|
|
51
72
|
commandEncoder: GPUCommandEncoder | null = null;
|
|
52
73
|
renderPass: WebGPURenderPass | null = null;
|
|
53
74
|
|
|
54
|
-
private _info: DeviceInfo;
|
|
55
|
-
private _isLost: boolean = false;
|
|
56
|
-
|
|
57
|
-
static type: string = 'webgpu';
|
|
58
|
-
|
|
59
75
|
/** Check if WebGPU is available */
|
|
60
76
|
static isSupported(): boolean {
|
|
61
77
|
return Boolean(typeof navigator !== 'undefined' && navigator.gpu);
|
|
@@ -79,11 +95,23 @@ export class WebGPUDevice extends Device {
|
|
|
79
95
|
const adapterInfo = await adapter.requestAdapterInfo();
|
|
80
96
|
log.probe(2, 'Adapter available', adapterInfo)();
|
|
81
97
|
|
|
98
|
+
const requiredFeatures: GPUFeatureName[] = [];
|
|
99
|
+
const requiredLimits: Record<string, number> = {};
|
|
100
|
+
|
|
101
|
+
if (props.requestMaxLimits) {
|
|
102
|
+
requiredFeatures.push(...(Array.from(adapter.features) as GPUFeatureName[]));
|
|
103
|
+
for (const key in adapter.limits) {
|
|
104
|
+
requiredLimits[key] = adapter.limits[key];
|
|
105
|
+
}
|
|
106
|
+
delete requiredLimits.minSubgroupSize;
|
|
107
|
+
delete requiredLimits.maxSubgroupSize;
|
|
108
|
+
}
|
|
109
|
+
|
|
82
110
|
const gpuDevice = await adapter.requestDevice({
|
|
83
|
-
requiredFeatures
|
|
84
|
-
|
|
85
|
-
// requiredLimits: adapter.limits
|
|
111
|
+
requiredFeatures,
|
|
112
|
+
requiredLimits
|
|
86
113
|
});
|
|
114
|
+
|
|
87
115
|
log.probe(1, 'GPUDevice available')();
|
|
88
116
|
|
|
89
117
|
if (typeof props.canvas === 'string') {
|
|
@@ -93,41 +121,29 @@ export class WebGPUDevice extends Device {
|
|
|
93
121
|
|
|
94
122
|
const device = new WebGPUDevice(gpuDevice, adapter, adapterInfo, props);
|
|
95
123
|
|
|
96
|
-
log.probe(
|
|
124
|
+
log.probe(
|
|
125
|
+
1,
|
|
126
|
+
'Device created. For more info, set chrome://flags/#enable-webgpu-developer-features'
|
|
127
|
+
)();
|
|
97
128
|
log.table(1, device.info)();
|
|
98
129
|
log.groupEnd(1)();
|
|
99
130
|
return device;
|
|
100
131
|
}
|
|
101
132
|
|
|
102
|
-
constructor(
|
|
133
|
+
constructor(
|
|
134
|
+
device: GPUDevice,
|
|
135
|
+
adapter: GPUAdapter,
|
|
136
|
+
adapterInfo: GPUAdapterInfo,
|
|
137
|
+
props: DeviceProps
|
|
138
|
+
) {
|
|
103
139
|
super({...props, id: props.id || uid('webgpu-device')});
|
|
104
140
|
this.handle = device;
|
|
105
141
|
this.adapter = adapter;
|
|
142
|
+
this.adapterInfo = adapterInfo;
|
|
106
143
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const vendor = adapterInfo.vendor || this.adapter.__brand || 'unknown';
|
|
111
|
-
const renderer = driver || '';
|
|
112
|
-
const version = driverVersion || '';
|
|
113
|
-
|
|
114
|
-
const gpu = vendor === 'apple' ? 'apple' : 'unknown'; // 'nvidia' | 'amd' | 'intel' | 'apple' | 'unknown',
|
|
115
|
-
const gpuArchitecture = adapterInfo.architecture || 'unknown';
|
|
116
|
-
const gpuBackend = (adapterInfo as any).backend || 'unknown';
|
|
117
|
-
const gpuType = ((adapterInfo as any).type || '').split(' ')[0].toLowerCase() || 'unknown'
|
|
118
|
-
|
|
119
|
-
this._info = {
|
|
120
|
-
type: 'webgpu',
|
|
121
|
-
vendor,
|
|
122
|
-
renderer,
|
|
123
|
-
version,
|
|
124
|
-
gpu,
|
|
125
|
-
gpuType,
|
|
126
|
-
gpuBackend,
|
|
127
|
-
gpuArchitecture,
|
|
128
|
-
shadingLanguage: 'wgsl',
|
|
129
|
-
shadingLanguageVersion: 100
|
|
130
|
-
};
|
|
144
|
+
this.info = this._getInfo();
|
|
145
|
+
this.features = this._getFeatures();
|
|
146
|
+
this.limits = this.handle.limits;
|
|
131
147
|
|
|
132
148
|
// "Context" loss handling
|
|
133
149
|
this.lost = new Promise<{reason: 'destroyed'; message: string}>(async resolve => {
|
|
@@ -145,8 +161,6 @@ export class WebGPUDevice extends Device {
|
|
|
145
161
|
container: props.container
|
|
146
162
|
});
|
|
147
163
|
// }
|
|
148
|
-
|
|
149
|
-
this.features = this._getFeatures();
|
|
150
164
|
}
|
|
151
165
|
|
|
152
166
|
// TODO
|
|
@@ -158,23 +172,17 @@ export class WebGPUDevice extends Device {
|
|
|
158
172
|
this.handle.destroy();
|
|
159
173
|
}
|
|
160
174
|
|
|
161
|
-
get info(): DeviceInfo {
|
|
162
|
-
return this._info;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
features: Set<DeviceFeature>;
|
|
166
|
-
|
|
167
|
-
get limits(): DeviceLimits {
|
|
168
|
-
return this.handle.limits;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
175
|
isTextureFormatSupported(format: TextureFormat): boolean {
|
|
172
176
|
return !format.includes('webgl');
|
|
173
177
|
}
|
|
174
178
|
|
|
175
179
|
/** @todo implement proper check? */
|
|
176
180
|
isTextureFormatFilterable(format: TextureFormat): boolean {
|
|
177
|
-
return
|
|
181
|
+
return (
|
|
182
|
+
this.isTextureFormatSupported(format) &&
|
|
183
|
+
!format.startsWith('depth') &&
|
|
184
|
+
!format.startsWith('stencil')
|
|
185
|
+
);
|
|
178
186
|
}
|
|
179
187
|
|
|
180
188
|
/** @todo implement proper check? */
|
|
@@ -212,7 +220,7 @@ export class WebGPUDevice extends Device {
|
|
|
212
220
|
}
|
|
213
221
|
|
|
214
222
|
createFramebuffer(props: FramebufferProps): WebGPUFramebuffer {
|
|
215
|
-
|
|
223
|
+
return new WebGPUFramebuffer(this, props);
|
|
216
224
|
}
|
|
217
225
|
|
|
218
226
|
createComputePipeline(props: ComputePipelineProps): WebGPUComputePipeline {
|
|
@@ -247,24 +255,12 @@ export class WebGPUDevice extends Device {
|
|
|
247
255
|
throw new Error('Transform feedback not supported in WebGPU');
|
|
248
256
|
}
|
|
249
257
|
|
|
250
|
-
|
|
251
|
-
return new
|
|
258
|
+
override createQuerySet(props: QuerySetProps): QuerySet {
|
|
259
|
+
return new WebGPUQuerySet(this, props);
|
|
252
260
|
}
|
|
253
261
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
* Creates a new encoder against default canvasContext if not already created
|
|
257
|
-
* @note Called internally by Model.
|
|
258
|
-
* @deprecated Create explicit pass with device.beginRenderPass
|
|
259
|
-
*/
|
|
260
|
-
getDefaultRenderPass(): WebGPURenderPass {
|
|
261
|
-
// this.renderPass =
|
|
262
|
-
// this.renderPass ||
|
|
263
|
-
// this.beginRenderPass({
|
|
264
|
-
// framebuffer: this.canvasContext?.getCurrentFramebuffer()
|
|
265
|
-
// });
|
|
266
|
-
// return this.renderPass;
|
|
267
|
-
throw new Error('a');
|
|
262
|
+
createCanvasContext(props: CanvasContextProps): WebGPUCanvasContext {
|
|
263
|
+
return new WebGPUCanvasContext(this, this.adapter, props);
|
|
268
264
|
}
|
|
269
265
|
|
|
270
266
|
submit(): void {
|
|
@@ -277,10 +273,38 @@ export class WebGPUDevice extends Device {
|
|
|
277
273
|
// this.renderPass = null;
|
|
278
274
|
}
|
|
279
275
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
276
|
+
// PRIVATE METHODS
|
|
277
|
+
|
|
278
|
+
protected _getInfo(): DeviceInfo {
|
|
279
|
+
const [driver, driverVersion] = ((this.adapterInfo as any).driver || '').split(' Version ');
|
|
280
|
+
|
|
281
|
+
// See https://developer.chrome.com/blog/new-in-webgpu-120#adapter_information_updates
|
|
282
|
+
const vendor = this.adapterInfo.vendor || this.adapter.__brand || 'unknown';
|
|
283
|
+
const renderer = driver || '';
|
|
284
|
+
const version = driverVersion || '';
|
|
285
|
+
|
|
286
|
+
const gpu = vendor === 'apple' ? 'apple' : 'unknown'; // 'nvidia' | 'amd' | 'intel' | 'apple' | 'unknown',
|
|
287
|
+
const gpuArchitecture = this.adapterInfo.architecture || 'unknown';
|
|
288
|
+
const gpuBackend = (this.adapterInfo as any).backend || 'unknown';
|
|
289
|
+
const gpuType = ((this.adapterInfo as any).type || '').split(' ')[0].toLowerCase() || 'unknown';
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
type: 'webgpu',
|
|
293
|
+
vendor,
|
|
294
|
+
renderer,
|
|
295
|
+
version,
|
|
296
|
+
gpu,
|
|
297
|
+
gpuType,
|
|
298
|
+
gpuBackend,
|
|
299
|
+
gpuArchitecture,
|
|
300
|
+
shadingLanguage: 'wgsl',
|
|
301
|
+
shadingLanguageVersion: 100
|
|
302
|
+
};
|
|
303
|
+
}
|
|
283
304
|
|
|
305
|
+
protected _getFeatures(): DeviceFeatures {
|
|
306
|
+
// Initialize with actual WebGPU Features (note that unknown features may not be in DeviceFeature type)
|
|
307
|
+
const features = new Set<DeviceFeature>(this.handle.features as Set<DeviceFeature>);
|
|
284
308
|
// Fixups for pre-standard names: https://github.com/webgpu-native/webgpu-headers/issues/133
|
|
285
309
|
// @ts-expect-error Chrome Canary v99
|
|
286
310
|
if (features.has('depth-clamping')) {
|
|
@@ -289,47 +313,26 @@ export class WebGPUDevice extends Device {
|
|
|
289
313
|
features.add('depth-clip-control');
|
|
290
314
|
}
|
|
291
315
|
|
|
292
|
-
//
|
|
316
|
+
// Some subsets of WebGPU extensions correspond to WebGL extensions
|
|
293
317
|
if (features.has('texture-compression-bc')) {
|
|
294
318
|
features.add('texture-compression-bc5-webgl');
|
|
295
319
|
}
|
|
296
320
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
features.add('texture-formats-srgb-webgl1');
|
|
311
|
-
|
|
312
|
-
// TEXTURES
|
|
313
|
-
features.add('texture-formats-depth-webgl1');
|
|
314
|
-
features.add('texture-formats-float32-webgl1');
|
|
315
|
-
features.add('texture-formats-float16-webgl1');
|
|
316
|
-
|
|
317
|
-
features.add('texture-filter-linear-float32-webgl');
|
|
318
|
-
features.add('texture-filter-linear-float16-webgl');
|
|
319
|
-
features.add('texture-filter-anisotropic-webgl');
|
|
320
|
-
|
|
321
|
-
// FRAMEBUFFERS, TEXTURES AND RENDERBUFFERS
|
|
322
|
-
features.add('texture-renderable-rgba32float-webgl');
|
|
323
|
-
features.add('texture-renderable-float32-webgl');
|
|
324
|
-
features.add('texture-renderable-float16-webgl');
|
|
325
|
-
|
|
326
|
-
// GLSL extensions
|
|
327
|
-
features.add('glsl-frag-data');
|
|
328
|
-
features.add('glsl-frag-depth');
|
|
329
|
-
features.add('glsl-derivatives');
|
|
330
|
-
features.add('glsl-texture-lod');
|
|
321
|
+
const WEBGPU_ALWAYS_FEATURES: DeviceFeature[] = [
|
|
322
|
+
'timer-query-webgl',
|
|
323
|
+
'compilation-status-async-webgl',
|
|
324
|
+
'float32-renderable-webgl',
|
|
325
|
+
'float16-renderable-webgl',
|
|
326
|
+
'norm16-renderable-webgl',
|
|
327
|
+
'texture-filterable-anisotropic-webgl',
|
|
328
|
+
'shader-noperspective-interpolation-webgl'
|
|
329
|
+
];
|
|
330
|
+
|
|
331
|
+
for (const feature of WEBGPU_ALWAYS_FEATURES) {
|
|
332
|
+
features.add(feature);
|
|
333
|
+
}
|
|
331
334
|
|
|
332
|
-
return features;
|
|
335
|
+
return new DeviceFeatures(Array.from(features), this.props.disabledFeatures);
|
|
333
336
|
}
|
|
334
337
|
|
|
335
338
|
copyExternalImageToTexture(options: {
|
package/src/index.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"accessor-to-format.js","names":[],"sources":["../../../src/adapter/helpers/accessor-to-format.ts"],"sourcesContent":["/*\nimport {assert} from '@luma.gl/core';\n\ntype Accessor = Record<string, any>;\n\nconst FORMAT_TO_ACCESSOR: Record<GPUVertexFormat, Accessor> = {\n uchar2: {type: 'uchar', size: 2},\n uchar4: {type: 'uchar', size: 4},\n char2: {type: 'char', size: 2},\n char4: {type: 'char', size: 4},\n uchar2norm: {type: 'uchar', size: 2, normalized: true},\n uchar4norm: {type: 'uchar', size: 4, normalized: true},\n char2norm: {type: 'char', size: 2, normalized: true},\n char4norm: {type: 'char', size: 4, normalized: true},\n ushort2: {type: 'ushort', size: 2},\n ushort4: {type: 'ushort', size: 4},\n short2: {type: 'short', size: 2},\n short4: {type: 'short', size: 4},\n ushort2norm: {type: 'ushort', size: 2, normalized: true},\n ushort4norm: {type: 'ushort', size: 4, normalized: true},\n short2norm: {type: 'short', size: 1, normalized: true},\n short4norm: {type: 'short', size: 1, normalized: true},\n half2: {type: 'half', size: 2},\n half4: {type: 'half', size: 4},\n float: {type: 'float', size: 1},\n float2: {type: 'float', size: 2},\n float3: {type: 'float', size: 3},\n float4: {type: 'float', size: 4},\n uint: {type: 'uint', size: 1, integer: true},\n uint2: {type: 'uint', size: 2, integer: true},\n uint3: {type: 'uint', size: 3, integer: true},\n uint4: {type: 'uint', size: 4, integer: true},\n int: {type: 'int', size: 1, integer: true},\n int2: {type: 'int', size: 2, integer: true},\n int3: {type: 'int', size: 3, integer: true},\n int4: {type: 'int', size: 4, integer: true}\n};\n\n/**\n * Convert from WebGPU attribute format strings to accessor {type, size, normalized, integer}\n * @param {*} format\n *\nexport function mapWebGPUFormatToAccessor(format) {\n const accessorDefinition = FORMAT_TO_ACCESSOR[format];\n assert(accessorDefinition, 'invalid attribute format');\n return Object.freeze(accessorDefinition);\n}\n\n/**\n * Convert from accessor {type, size, normalized, integer} to WebGPU attribute format strings\n * @param {*} format\n *\nexport function mapAccessorToWebGPUFormat(accessor) {\n const {type = GL.FLOAT, size = 1, normalized = false, integer = false} = accessor;\n assert(size >=1 && size <=4);\n // `norm` suffix (uchar4norm)\n const norm = normalized ? 'norm' : '';\n // size 1 is ommitted in format names (float vs float2)\n const count = size === 1 ? '' : size;\n switch (type) {\n case GL.UNSIGNED_BYTE:\n switch (size) {\n case 2:\n case 4:\n return `uchar${count}${norm}`;\n }\n case GL.BYTE:\n switch (size) {\n case 2:\n case 4:\n return `char${count}${norm}`;\n }\n case GL.UNSIGNED_SHORT:\n switch (size) {\n case 2:\n case 4:\n return `ushort${count}${norm}`;\n }\n case GL.SHORT:\n switch (size) {\n case 2:\n case 4:\n return `short${count}${norm}`;\n }\n case GL.HALF_FLOAT:\n switch (size) {\n case 2:\n case 4:\n return `half${count}`;\n }\n case GL.FLOAT:\n return `float${count}`;\n case GL.UNSIGNED_INT:\n return `uint${count}`;\n case GL.INT:\n return `int${count}`;\n }\n throw new Error('illegal accessor');\n}\n*/"],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convert-texture-format.js","names":["getWebGPUTextureFormat","format","includes","Error"],"sources":["../../../src/adapter/helpers/convert-texture-format.ts"],"sourcesContent":["// luma.gl, MIT license\nimport {TextureFormat} from '@luma.gl/core';\n\n/** Ensure a texture format is WebGPU compatible */\nexport function getWebGPUTextureFormat(format: TextureFormat): GPUTextureFormat {\n if (format.includes('webgl')) {\n throw new Error('webgl-only format');\n }\n return format as GPUTextureFormat;\n}\n"],"mappings":"AAIA,OAAO,SAASA,sBAAsBA,CAACC,MAAqB,EAAoB;EAC9E,IAAIA,MAAM,CAACC,QAAQ,CAAC,OAAO,CAAC,EAAE;IAC5B,MAAM,IAAIC,KAAK,CAAC,mBAAmB,CAAC;EACtC;EACA,OAAOF,MAAM;AACf"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types="dist" />
|
|
2
|
-
/** WebGPU does not have built-in mipmap creation */
|
|
3
|
-
export declare class WebGPUMipmapGenerator {
|
|
4
|
-
device: GPUDevice;
|
|
5
|
-
mipmapSampler: GPUSampler;
|
|
6
|
-
mipmapPipeline: GPURenderPipeline;
|
|
7
|
-
constructor(device: GPUDevice, glslang: any);
|
|
8
|
-
generateMipmappedTexture(imageBitmap: ImageBitmap): GPUTexture;
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=generate-mipmaps.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-mipmaps.d.ts","sourceRoot":"","sources":["../../../src/adapter/helpers/generate-mipmaps.ts"],"names":[],"mappings":";AAuBA,oDAAoD;AACpD,qBAAa,qBAAqB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,iBAAiB,CAAC;gBAEtB,MAAM,EAAE,SAAS,EAAE,OAAO,KAAA;IAyBtC,wBAAwB,CAAC,WAAW,EAAE,WAAW;CAoDlD"}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
const VS_GEN_MIPMAP = `\#version 450
|
|
2
|
-
const vec2 pos[4] = vec2[4](vec2(-1.0f, 1.0f), vec2(1.0f, 1.0f), vec2(-1.0f, -1.0f), vec2(1.0f, -1.0f));
|
|
3
|
-
layout(location = 0) out vec2 vTex;
|
|
4
|
-
void main() {
|
|
5
|
-
gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
|
|
6
|
-
vTex = gl_Position / 2.0f + vec2(0.5f);
|
|
7
|
-
}`;
|
|
8
|
-
const FS_GEN_MIPMAP = `#version 450
|
|
9
|
-
layout(set = 0, binding = 0) uniform sampler imgSampler;
|
|
10
|
-
layout(set = 0, binding = 1) uniform texture2D img;
|
|
11
|
-
layout(location = 0) in vec2 vTex;
|
|
12
|
-
layout(location = 0) out vec4 outColor;
|
|
13
|
-
void main() {
|
|
14
|
-
outColor = texture(sampler2D(img, imgSampler), vTex);
|
|
15
|
-
}`;
|
|
16
|
-
export class WebGPUMipmapGenerator {
|
|
17
|
-
constructor(device, glslang) {
|
|
18
|
-
this.device = void 0;
|
|
19
|
-
this.mipmapSampler = void 0;
|
|
20
|
-
this.mipmapPipeline = void 0;
|
|
21
|
-
this.device = device;
|
|
22
|
-
this.mipmapSampler = device.createSampler({
|
|
23
|
-
minFilter: 'linear'
|
|
24
|
-
});
|
|
25
|
-
this.mipmapPipeline = device.createRenderPipeline({
|
|
26
|
-
vertexStage: {
|
|
27
|
-
module: device.createShaderModule({
|
|
28
|
-
code: glslang.compileGLSL(VS_GEN_MIPMAP, 'vertex')
|
|
29
|
-
}),
|
|
30
|
-
entryPoint: 'main'
|
|
31
|
-
},
|
|
32
|
-
fragmentStage: {
|
|
33
|
-
module: device.createShaderModule({
|
|
34
|
-
code: glslang.compileGLSL(FS_GEN_MIPMAP, 'fragment')
|
|
35
|
-
}),
|
|
36
|
-
entryPoint: 'main'
|
|
37
|
-
},
|
|
38
|
-
primitiveTopology: 'triangle-strip',
|
|
39
|
-
colorStates: [{
|
|
40
|
-
format: 'rgba8unorm'
|
|
41
|
-
}]
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
generateMipmappedTexture(imageBitmap) {
|
|
45
|
-
const textureSize = {
|
|
46
|
-
width: imageBitmap.width,
|
|
47
|
-
height: imageBitmap.height,
|
|
48
|
-
depth: 1
|
|
49
|
-
};
|
|
50
|
-
const mipLevelCount = Math.floor(Math.log2(Math.max(imageBitmap.width, imageBitmap.height))) + 1;
|
|
51
|
-
const texture = this.device.createTexture({
|
|
52
|
-
size: textureSize,
|
|
53
|
-
format: 'rgba8unorm',
|
|
54
|
-
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED | GPUTextureUsage.OUTPUT_ATTACHMENT,
|
|
55
|
-
mipLevelCount
|
|
56
|
-
});
|
|
57
|
-
this.device.queue.copyImageBitmapToTexture({
|
|
58
|
-
imageBitmap
|
|
59
|
-
}, {
|
|
60
|
-
texture
|
|
61
|
-
}, textureSize);
|
|
62
|
-
const commandEncoder = this.device.createCommandEncoder({});
|
|
63
|
-
for (let i = 1; i < mipLevelCount; ++i) {
|
|
64
|
-
const passEncoder = commandEncoder.beginRenderPass({
|
|
65
|
-
colorAttachments: [{
|
|
66
|
-
attachment: texture.createView({
|
|
67
|
-
baseMipLevel: i,
|
|
68
|
-
mipLevelCount: 1
|
|
69
|
-
}),
|
|
70
|
-
loadValue: {
|
|
71
|
-
r: 1.0,
|
|
72
|
-
g: 0.0,
|
|
73
|
-
b: 0.0,
|
|
74
|
-
a: 0.0
|
|
75
|
-
}
|
|
76
|
-
}]
|
|
77
|
-
});
|
|
78
|
-
const bindGroup = this.device.createBindGroup({
|
|
79
|
-
layout: this.mipmapPipeline.getBindGroupLayout(0),
|
|
80
|
-
bindings: [{
|
|
81
|
-
binding: 0,
|
|
82
|
-
resource: this.mipmapSampler
|
|
83
|
-
}, {
|
|
84
|
-
binding: 1,
|
|
85
|
-
resource: texture.createView({
|
|
86
|
-
baseMipLevel: i - 1,
|
|
87
|
-
mipLevelCount: 1
|
|
88
|
-
})
|
|
89
|
-
}]
|
|
90
|
-
});
|
|
91
|
-
passEncoder.setPipeline(this.mipmapPipeline);
|
|
92
|
-
passEncoder.setBindGroup(0, bindGroup);
|
|
93
|
-
passEncoder.draw(4);
|
|
94
|
-
passEncoder.endPass();
|
|
95
|
-
}
|
|
96
|
-
this.device.queue.submit([commandEncoder.finish()]);
|
|
97
|
-
return texture;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=generate-mipmaps.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-mipmaps.js","names":["VS_GEN_MIPMAP","FS_GEN_MIPMAP","WebGPUMipmapGenerator","constructor","device","glslang","mipmapSampler","mipmapPipeline","createSampler","minFilter","createRenderPipeline","vertexStage","module","createShaderModule","code","compileGLSL","entryPoint","fragmentStage","primitiveTopology","colorStates","format","generateMipmappedTexture","imageBitmap","textureSize","width","height","depth","mipLevelCount","Math","floor","log2","max","texture","createTexture","size","usage","GPUTextureUsage","COPY_DST","SAMPLED","OUTPUT_ATTACHMENT","queue","copyImageBitmapToTexture","commandEncoder","createCommandEncoder","i","passEncoder","beginRenderPass","colorAttachments","attachment","createView","baseMipLevel","loadValue","r","g","b","a","bindGroup","createBindGroup","layout","getBindGroupLayout","bindings","binding","resource","setPipeline","setBindGroup","draw","endPass","submit","finish"],"sources":["../../../src/adapter/helpers/generate-mipmaps.ts"],"sourcesContent":["// luma.gl, MIT license\n// Forked from Kangz/mipmapper.js under MIT license Copyright 2020 Brandon Jones\n// https://gist.github.com/Kangz/782d5f1ae502daf53910a13f55db2f83\n\n// @ts-nocheck this is written against outdated WebGPU API, needs an update pass\n\nconst VS_GEN_MIPMAP = `\\#version 450\nconst vec2 pos[4] = vec2[4](vec2(-1.0f, 1.0f), vec2(1.0f, 1.0f), vec2(-1.0f, -1.0f), vec2(1.0f, -1.0f));\nlayout(location = 0) out vec2 vTex;\nvoid main() {\n gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);\n vTex = gl_Position / 2.0f + vec2(0.5f);\n}`;\n\nconst FS_GEN_MIPMAP = `#version 450\nlayout(set = 0, binding = 0) uniform sampler imgSampler;\nlayout(set = 0, binding = 1) uniform texture2D img;\nlayout(location = 0) in vec2 vTex;\nlayout(location = 0) out vec4 outColor;\nvoid main() {\n outColor = texture(sampler2D(img, imgSampler), vTex);\n}`;\n\n/** WebGPU does not have built-in mipmap creation */\nexport class WebGPUMipmapGenerator {\n device: GPUDevice;\n mipmapSampler: GPUSampler;\n mipmapPipeline: GPURenderPipeline;\n\n constructor(device: GPUDevice, glslang) {\n this.device = device;\n\n this.mipmapSampler = device.createSampler({ minFilter: 'linear' });\n\n this.mipmapPipeline = device.createRenderPipeline({\n vertexStage: {\n module: device.createShaderModule({\n code: glslang.compileGLSL(VS_GEN_MIPMAP, 'vertex')\n }),\n entryPoint: 'main'\n },\n fragmentStage: {\n module: device.createShaderModule({\n code: glslang.compileGLSL(FS_GEN_MIPMAP, 'fragment')\n }),\n entryPoint: 'main'\n },\n primitiveTopology: 'triangle-strip',\n colorStates: [{\n format: 'rgba8unorm',\n }]\n });\n }\n\n generateMipmappedTexture(imageBitmap: ImageBitmap) {\n const textureSize = {\n width: imageBitmap.width,\n height: imageBitmap.height,\n depth: 1,\n }\n const mipLevelCount = Math.floor(Math.log2(Math.max(imageBitmap.width, imageBitmap.height))) + 1;\n\n // Populate the top level of the srcTexture with the imageBitmap.\n const texture = this.device.createTexture({\n size: textureSize,\n format: 'rgba8unorm',\n usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED | GPUTextureUsage.OUTPUT_ATTACHMENT,\n mipLevelCount\n });\n this.device.queue.copyImageBitmapToTexture({ imageBitmap }, { texture }, textureSize);\n\n const commandEncoder = this.device.createCommandEncoder({});\n for (let i = 1; i < mipLevelCount; ++i) {\n const passEncoder = commandEncoder.beginRenderPass({\n colorAttachments: [{\n attachment: texture.createView({\n baseMipLevel: i,\n mipLevelCount: 1\n }),\n loadValue: { r: 1.0, g: 0.0, b: 0.0, a: 0.0 },\n }],\n });\n\n const bindGroup = this.device.createBindGroup({\n layout: this.mipmapPipeline.getBindGroupLayout(0),\n bindings: [{\n binding: 0,\n resource: this.mipmapSampler,\n }, {\n binding: 1,\n resource: texture.createView({\n baseMipLevel: i - 1,\n mipLevelCount: 1\n }),\n }],\n });\n\n passEncoder.setPipeline(this.mipmapPipeline);\n passEncoder.setBindGroup(0, bindGroup);\n passEncoder.draw(4);\n passEncoder.endPass();\n }\n\n this.device.queue.submit([commandEncoder.finish()]);\n return texture;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"get-bind-group.js","names":["Buffer","Sampler","Texture","log","cast","makeBindGroupLayout","device","layout","bindings","Error","getBindGroup","bindGroupLayout","shaderLayout","entries","getBindGroupEntries","createBindGroup","getShaderLayoutBinding","bindingName","bindingLayout","find","binding","name","warn","value","Object","push","getBindGroupEntry","location","index","resource","buffer","handle","createView","label"],"sources":["../../../src/adapter/helpers/get-bind-group.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BindingDeclaration, Binding} from '@luma.gl/core';\nimport {Buffer, Sampler, Texture, log, cast} from '@luma.gl/core';\nimport type {WebGPUBuffer} from '../resources/webgpu-buffer';\nimport type {WebGPUSampler} from '../resources/webgpu-sampler';\nimport type {WebGPUTexture} from '../resources/webgpu-texture';\n\n/**\n * Create a WebGPU \"bind group layout\" from an array of luma.gl bindings\n * @note bind groups can be automatically generated by WebGPU.\n */\nexport function makeBindGroupLayout(\n device: GPUDevice,\n layout: GPUBindGroupLayout,\n bindings: Binding[]\n): GPUBindGroupLayout {\n throw new Error('not implemented');\n // return device.createBindGroupLayout({\n // layout,\n // entries: getBindGroupEntries(bindings)\n // })\n}\n\n/**\n * Create a WebGPU \"bind group\" from an array of luma.gl bindings\n */\nexport function getBindGroup(\n device: GPUDevice,\n bindGroupLayout: GPUBindGroupLayout,\n shaderLayout: ShaderLayout,\n bindings: Record<string, Binding>\n): GPUBindGroup {\n const entries = getBindGroupEntries(bindings, shaderLayout);\n return device.createBindGroup({\n layout: bindGroupLayout,\n entries\n });\n}\n\nexport function getShaderLayoutBinding(\n shaderLayout: ShaderLayout,\n bindingName: string\n): BindingDeclaration {\n const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName);\n if (!bindingLayout) {\n log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();\n }\n return bindingLayout;\n}\n\n/**\n * @param bindings\n * @returns\n */\nfunction getBindGroupEntries(\n bindings: Record<string, Binding>,\n shaderLayout: ShaderLayout\n): GPUBindGroupEntry[] {\n const entries: GPUBindGroupEntry[] = [];\n\n for (const [bindingName, value] of Object.entries(bindings)) {\n const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);\n if (bindingLayout) {\n entries.push(getBindGroupEntry(value, bindingLayout.location));\n }\n }\n\n return entries;\n}\n\nfunction getBindGroupEntry(binding: Binding, index: number): GPUBindGroupEntry {\n if (binding instanceof Buffer) {\n return {\n binding: index,\n resource: {\n buffer: cast<WebGPUBuffer>(binding).handle\n }\n };\n }\n if (binding instanceof Sampler) {\n return {\n binding: index,\n resource: cast<WebGPUSampler>(binding).handle\n };\n } else if (binding instanceof Texture) {\n return {\n binding: index,\n resource: cast<WebGPUTexture>(binding).handle.createView({label: 'bind-group-auto-created'})\n };\n }\n throw new Error('invalid binding');\n}\n"],"mappings":"AAEA,SAAQA,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,QAAO,eAAe;AASjE,OAAO,SAASC,mBAAmBA,CACjCC,MAAiB,EACjBC,MAA0B,EAC1BC,QAAmB,EACC;EACpB,MAAM,IAAIC,KAAK,CAAC,iBAAiB,CAAC;AAKpC;AAKA,OAAO,SAASC,YAAYA,CAC1BJ,MAAiB,EACjBK,eAAmC,EACnCC,YAA0B,EAC1BJ,QAAiC,EACnB;EACd,MAAMK,OAAO,GAAGC,mBAAmB,CAACN,QAAQ,EAAEI,YAAY,CAAC;EAC3D,OAAON,MAAM,CAACS,eAAe,CAAC;IAC5BR,MAAM,EAAEI,eAAe;IACvBE;EACF,CAAC,CAAC;AACJ;AAEA,OAAO,SAASG,sBAAsBA,CACpCJ,YAA0B,EAC1BK,WAAmB,EACC;EACpB,MAAMC,aAAa,GAAGN,YAAY,CAACJ,QAAQ,CAACW,IAAI,CAACC,OAAO,IAAIA,OAAO,CAACC,IAAI,KAAKJ,WAAW,CAAC;EACzF,IAAI,CAACC,aAAa,EAAE;IAClBf,GAAG,CAACmB,IAAI,CAAE,WAAUL,WAAY,uCAAsC,CAAC,CAAC,CAAC;EAC3E;EACA,OAAOC,aAAa;AACtB;AAMA,SAASJ,mBAAmBA,CAC1BN,QAAiC,EACjCI,YAA0B,EACL;EACrB,MAAMC,OAA4B,GAAG,EAAE;EAEvC,KAAK,MAAM,CAACI,WAAW,EAAEM,KAAK,CAAC,IAAIC,MAAM,CAACX,OAAO,CAACL,QAAQ,CAAC,EAAE;IAC3D,MAAMU,aAAa,GAAGF,sBAAsB,CAACJ,YAAY,EAAEK,WAAW,CAAC;IACvE,IAAIC,aAAa,EAAE;MACjBL,OAAO,CAACY,IAAI,CAACC,iBAAiB,CAACH,KAAK,EAAEL,aAAa,CAACS,QAAQ,CAAC,CAAC;IAChE;EACF;EAEA,OAAOd,OAAO;AAChB;AAEA,SAASa,iBAAiBA,CAACN,OAAgB,EAAEQ,KAAa,EAAqB;EAC7E,IAAIR,OAAO,YAAYpB,MAAM,EAAE;IAC7B,OAAO;MACLoB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAE;QACRC,MAAM,EAAE1B,IAAI,CAAegB,OAAO,CAAC,CAACW;MACtC;IACF,CAAC;EACH;EACA,IAAIX,OAAO,YAAYnB,OAAO,EAAE;IAC9B,OAAO;MACLmB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAEzB,IAAI,CAAgBgB,OAAO,CAAC,CAACW;IACzC,CAAC;EACH,CAAC,MAAM,IAAIX,OAAO,YAAYlB,OAAO,EAAE;IACrC,OAAO;MACLkB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAEzB,IAAI,CAAgBgB,OAAO,CAAC,CAACW,MAAM,CAACC,UAAU,CAAC;QAACC,KAAK,EAAE;MAAyB,CAAC;IAC7F,CAAC;EACH;EACA,MAAM,IAAIxB,KAAK,CAAC,iBAAiB,CAAC;AACpC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"get-vertex-buffer-layout.js","names":["log","decodeVertexFormat","getWebGPUVertexFormat","format","endsWith","Error","getVertexBufferLayout","shaderLayout","bufferLayout","vertexBufferLayouts","usedAttributes","Set","mapping","vertexAttributes","stepMode","byteStride","attributes","attributeMapping","attributeName","attribute","attributeLayout","findAttributeLayout","push","offset","byteOffset","shaderLocation","location","byteLength","name","arrayStride","has","getBufferSlots","bufferSlot","bufferSlots","interleaved","add","attributeNames","find","warn"],"sources":["../../../src/adapter/helpers/get-vertex-buffer-layout.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';\nimport {log, decodeVertexFormat} from '@luma.gl/core';\n// import {getAttributeInfosFromLayouts} from '@luma.gl/core';\n\n/** Throw error on any WebGL-only vertex formats */\nfunction getWebGPUVertexFormat(format: VertexFormat): GPUVertexFormat {\n if (format.endsWith('-webgl')) {\n throw new Error(`WebGPU does not support vertex format ${format}`);\n }\n return format as GPUVertexFormat;\n}\n\n/**\n * Build a WebGPU vertex buffer layout intended for use in a GPURenderPassDescriptor.\n * Converts luma.gl attribute definitions to a WebGPU GPUVertexBufferLayout[] array\n * @param layout\n * @param bufferLayout The buffer map is optional\n * @returns WebGPU layout intended for a GPURenderPassDescriptor.\n */\nexport function getVertexBufferLayout(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): GPUVertexBufferLayout[] {\n const vertexBufferLayouts: GPUVertexBufferLayout[] = [];\n const usedAttributes = new Set<string>();\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // Build vertex attributes for one buffer\n const vertexAttributes: GPUVertexAttribute[] = [];\n\n // TODO verify that all stepModes for one buffer are the same\n let stepMode: 'vertex' | 'instance' = 'vertex';\n let byteStride = 0;\n // interleaved mapping {..., attributes: [{...}, ...]}\n if (mapping.attributes) {\n // const arrayStride = mapping.byteStride; TODO\n for (const attributeMapping of mapping.attributes) {\n const attributeName = attributeMapping.attribute;\n const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);\n\n stepMode = attributeLayout.stepMode || 'vertex';\n vertexAttributes.push({\n format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),\n offset: attributeMapping.byteOffset,\n shaderLocation: attributeLayout.location\n });\n\n byteStride += decodeVertexFormat(mapping.format).byteLength;\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);\n if (!attributeLayout) {\n continue; // eslint-disable-line no-continue\n }\n byteStride = decodeVertexFormat(mapping.format).byteLength;\n\n stepMode = attributeLayout.stepMode || 'vertex';\n vertexAttributes.push({\n format: getWebGPUVertexFormat(mapping.format),\n // We only support 0 offset for non-interleaved buffer layouts\n offset: 0,\n shaderLocation: attributeLayout.location\n });\n }\n\n // Store all the attribute bindings for one buffer\n vertexBufferLayouts.push({\n arrayStride: mapping.byteStride || byteStride,\n stepMode: stepMode || 'vertex',\n attributes: vertexAttributes\n });\n }\n\n // Add any non-mapped attributes - TODO - avoid hardcoded types\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n vertexBufferLayouts.push({\n arrayStride: decodeVertexFormat('float32x3').byteLength,\n stepMode: attribute.stepMode || 'vertex',\n attributes: [\n {\n format: getWebGPUVertexFormat('float32x3'),\n offset: 0,\n shaderLocation: attribute.location\n }\n ]\n });\n }\n }\n\n return vertexBufferLayouts;\n}\n\nexport function getBufferSlots(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): Record<string, number> {\n const usedAttributes = new Set<string>();\n let bufferSlot = 0;\n const bufferSlots: Record<string, number> = {};\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // interleaved mapping {..., attributes: [{...}, ...]}\n if ('attributes' in mapping) {\n for (const interleaved of mapping.attributes) {\n usedAttributes.add(interleaved.attribute);\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n usedAttributes.add(mapping.name);\n }\n bufferSlots[mapping.name] = bufferSlot++;\n }\n\n // Add any non-mapped attributes\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n bufferSlots[attribute.name] = bufferSlot++;\n }\n }\n\n return bufferSlots;\n}\n\n/**\n * Looks up an attribute in the ShaderLayout.\n * @throws if name is not in ShaderLayout\n * @throws if name has already been referenced\n */\nfunction findAttributeLayout(\n shaderLayout: ShaderLayout,\n name: string,\n attributeNames: Set<string>\n): AttributeDeclaration {\n const attribute = shaderLayout.attributes.find(attribute => attribute.name === name);\n if (!attribute) {\n log.warn(`Unknown attribute ${name}`)();\n return null;\n }\n if (attributeNames.has(name)) {\n throw new Error(`Duplicate attribute ${name}`);\n }\n attributeNames.add(name);\n return attribute;\n}\n"],"mappings":"AAEA,SAAQA,GAAG,EAAEC,kBAAkB,QAAO,eAAe;AAIrD,SAASC,qBAAqBA,CAACC,MAAoB,EAAmB;EACpE,IAAIA,MAAM,CAACC,QAAQ,CAAC,QAAQ,CAAC,EAAE;IAC7B,MAAM,IAAIC,KAAK,CAAE,yCAAwCF,MAAO,EAAC,CAAC;EACpE;EACA,OAAOA,MAAM;AACf;AASA,OAAO,SAASG,qBAAqBA,CACnCC,YAA0B,EAC1BC,YAA4B,EACH;EACzB,MAAMC,mBAA4C,GAAG,EAAE;EACvD,MAAMC,cAAc,GAAG,IAAIC,GAAG,CAAS,CAAC;EAGxC,KAAK,MAAMC,OAAO,IAAIJ,YAAY,EAAE;IAElC,MAAMK,gBAAsC,GAAG,EAAE;IAGjD,IAAIC,QAA+B,GAAG,QAAQ;IAC9C,IAAIC,UAAU,GAAG,CAAC;IAElB,IAAIH,OAAO,CAACI,UAAU,EAAE;MAEtB,KAAK,MAAMC,gBAAgB,IAAIL,OAAO,CAACI,UAAU,EAAE;QACjD,MAAME,aAAa,GAAGD,gBAAgB,CAACE,SAAS;QAChD,MAAMC,eAAe,GAAGC,mBAAmB,CAACd,YAAY,EAAEW,aAAa,EAAER,cAAc,CAAC;QAExFI,QAAQ,GAAGM,eAAe,CAACN,QAAQ,IAAI,QAAQ;QAC/CD,gBAAgB,CAACS,IAAI,CAAC;UACpBnB,MAAM,EAAED,qBAAqB,CAACe,gBAAgB,CAACd,MAAM,IAAIS,OAAO,CAACT,MAAM,CAAC;UACxEoB,MAAM,EAAEN,gBAAgB,CAACO,UAAU;UACnCC,cAAc,EAAEL,eAAe,CAACM;QAClC,CAAC,CAAC;QAEFX,UAAU,IAAId,kBAAkB,CAACW,OAAO,CAACT,MAAM,CAAC,CAACwB,UAAU;MAC7D;IAEF,CAAC,MAAM;MACL,MAAMP,eAAe,GAAGC,mBAAmB,CAACd,YAAY,EAAEK,OAAO,CAACgB,IAAI,EAAElB,cAAc,CAAC;MACvF,IAAI,CAACU,eAAe,EAAE;QACpB;MACF;MACAL,UAAU,GAAGd,kBAAkB,CAACW,OAAO,CAACT,MAAM,CAAC,CAACwB,UAAU;MAE1Db,QAAQ,GAAGM,eAAe,CAACN,QAAQ,IAAI,QAAQ;MAC/CD,gBAAgB,CAACS,IAAI,CAAC;QACpBnB,MAAM,EAAED,qBAAqB,CAACU,OAAO,CAACT,MAAM,CAAC;QAE7CoB,MAAM,EAAE,CAAC;QACTE,cAAc,EAAEL,eAAe,CAACM;MAClC,CAAC,CAAC;IACJ;IAGAjB,mBAAmB,CAACa,IAAI,CAAC;MACvBO,WAAW,EAAEjB,OAAO,CAACG,UAAU,IAAIA,UAAU;MAC7CD,QAAQ,EAAEA,QAAQ,IAAI,QAAQ;MAC9BE,UAAU,EAAEH;IACd,CAAC,CAAC;EACJ;EAGA,KAAK,MAAMM,SAAS,IAAIZ,YAAY,CAACS,UAAU,EAAE;IAC/C,IAAI,CAACN,cAAc,CAACoB,GAAG,CAACX,SAAS,CAACS,IAAI,CAAC,EAAE;MACvCnB,mBAAmB,CAACa,IAAI,CAAC;QACvBO,WAAW,EAAE5B,kBAAkB,CAAC,WAAW,CAAC,CAAC0B,UAAU;QACvDb,QAAQ,EAAEK,SAAS,CAACL,QAAQ,IAAI,QAAQ;QACxCE,UAAU,EAAE,CACV;UACEb,MAAM,EAAED,qBAAqB,CAAC,WAAW,CAAC;UAC1CqB,MAAM,EAAE,CAAC;UACTE,cAAc,EAAEN,SAAS,CAACO;QAC5B,CAAC;MAEL,CAAC,CAAC;IACJ;EACF;EAEA,OAAOjB,mBAAmB;AAC5B;AAEA,OAAO,SAASsB,cAAcA,CAC5BxB,YAA0B,EAC1BC,YAA4B,EACJ;EACxB,MAAME,cAAc,GAAG,IAAIC,GAAG,CAAS,CAAC;EACxC,IAAIqB,UAAU,GAAG,CAAC;EAClB,MAAMC,WAAmC,GAAG,CAAC,CAAC;EAG9C,KAAK,MAAMrB,OAAO,IAAIJ,YAAY,EAAE;IAElC,IAAI,YAAY,IAAII,OAAO,EAAE;MAC3B,KAAK,MAAMsB,WAAW,IAAItB,OAAO,CAACI,UAAU,EAAE;QAC5CN,cAAc,CAACyB,GAAG,CAACD,WAAW,CAACf,SAAS,CAAC;MAC3C;IAEF,CAAC,MAAM;MACLT,cAAc,CAACyB,GAAG,CAACvB,OAAO,CAACgB,IAAI,CAAC;IAClC;IACAK,WAAW,CAACrB,OAAO,CAACgB,IAAI,CAAC,GAAGI,UAAU,EAAE;EAC1C;EAGA,KAAK,MAAMb,SAAS,IAAIZ,YAAY,CAACS,UAAU,EAAE;IAC/C,IAAI,CAACN,cAAc,CAACoB,GAAG,CAACX,SAAS,CAACS,IAAI,CAAC,EAAE;MACvCK,WAAW,CAACd,SAAS,CAACS,IAAI,CAAC,GAAGI,UAAU,EAAE;IAC5C;EACF;EAEA,OAAOC,WAAW;AACpB;AAOA,SAASZ,mBAAmBA,CAC1Bd,YAA0B,EAC1BqB,IAAY,EACZQ,cAA2B,EACL;EACtB,MAAMjB,SAAS,GAAGZ,YAAY,CAACS,UAAU,CAACqB,IAAI,CAAClB,SAAS,IAAIA,SAAS,CAACS,IAAI,KAAKA,IAAI,CAAC;EACpF,IAAI,CAACT,SAAS,EAAE;IACdnB,GAAG,CAACsC,IAAI,CAAE,qBAAoBV,IAAK,EAAC,CAAC,CAAC,CAAC;IACvC,OAAO,IAAI;EACb;EACA,IAAIQ,cAAc,CAACN,GAAG,CAACF,IAAI,CAAC,EAAE;IAC5B,MAAM,IAAIvB,KAAK,CAAE,uBAAsBuB,IAAK,EAAC,CAAC;EAChD;EACAQ,cAAc,CAACD,GAAG,CAACP,IAAI,CAAC;EACxB,OAAOT,SAAS;AAClB"}
|