@luma.gl/webgpu 9.2.6 → 9.3.0-alpha.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/cpu-hotspot-profiler.d.ts +54 -0
- package/dist/adapter/helpers/cpu-hotspot-profiler.d.ts.map +1 -0
- package/dist/adapter/helpers/cpu-hotspot-profiler.js +26 -0
- package/dist/adapter/helpers/cpu-hotspot-profiler.js.map +1 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.d.ts +7 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.d.ts.map +1 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.js +490 -0
- package/dist/adapter/helpers/generate-mipmaps-webgpu.js.map +1 -0
- package/dist/adapter/helpers/get-bind-group.d.ts +4 -6
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +39 -32
- package/dist/adapter/helpers/get-bind-group.js.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts +3 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +17 -12
- 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 +1 -0
- package/dist/adapter/helpers/webgpu-parameters.js.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.d.ts +7 -0
- package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.js +58 -15
- package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-command-buffer.js +1 -1
- package/dist/adapter/resources/webgpu-command-buffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.d.ts +7 -16
- package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.js +89 -32
- package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.d.ts +3 -3
- package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js +30 -12
- package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +7 -9
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.js +30 -17
- package/dist/adapter/resources/webgpu-compute-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgpu-fence.d.ts +13 -0
- package/dist/adapter/resources/webgpu-fence.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-fence.js +33 -0
- package/dist/adapter/resources/webgpu-fence.js.map +1 -0
- package/dist/adapter/resources/webgpu-framebuffer.d.ts +6 -0
- package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.js +16 -0
- package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-pipeline-layout.d.ts +1 -1
- package/dist/adapter/resources/webgpu-pipeline-layout.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-pipeline-layout.js +11 -18
- package/dist/adapter/resources/webgpu-pipeline-layout.js.map +1 -1
- package/dist/adapter/resources/webgpu-query-set.d.ts +33 -4
- package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-query-set.js +145 -4
- package/dist/adapter/resources/webgpu-query-set.js.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.d.ts +6 -3
- package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.js +78 -34
- package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts +14 -10
- package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pipeline.js +56 -35
- package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.js +4 -0
- package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
- package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-shader.js +17 -1
- package/dist/adapter/resources/webgpu-shader.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture-view.d.ts +6 -0
- package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture-view.js +47 -11
- package/dist/adapter/resources/webgpu-texture-view.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture.d.ts +25 -3
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +211 -43
- package/dist/adapter/resources/webgpu-texture.js.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -1
- package/dist/adapter/webgpu-adapter.d.ts.map +1 -1
- package/dist/adapter/webgpu-adapter.js +34 -34
- package/dist/adapter/webgpu-adapter.js.map +1 -1
- package/dist/adapter/webgpu-canvas-context.d.ts +6 -3
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +90 -30
- package/dist/adapter/webgpu-canvas-context.js.map +1 -1
- package/dist/adapter/webgpu-device.d.ts +12 -2
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +173 -16
- package/dist/adapter/webgpu-device.js.map +1 -1
- package/dist/adapter/webgpu-presentation-context.d.ts +25 -0
- package/dist/adapter/webgpu-presentation-context.d.ts.map +1 -0
- package/dist/adapter/webgpu-presentation-context.js +144 -0
- package/dist/adapter/webgpu-presentation-context.js.map +1 -0
- package/dist/dist.dev.js +8070 -547
- package/dist/dist.min.js +169 -6
- package/dist/index.cjs +1929 -410
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/wgsl/get-shader-layout-wgsl.d.ts +8 -0
- package/dist/wgsl/get-shader-layout-wgsl.d.ts.map +1 -0
- package/dist/wgsl/get-shader-layout-wgsl.js +144 -0
- package/dist/wgsl/get-shader-layout-wgsl.js.map +1 -0
- package/package.json +6 -5
- package/src/adapter/helpers/cpu-hotspot-profiler.ts +70 -0
- package/src/adapter/helpers/generate-mipmaps-webgpu.ts +583 -0
- package/src/adapter/helpers/get-bind-group.ts +52 -46
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +31 -12
- package/src/adapter/helpers/webgpu-parameters.ts +2 -0
- package/src/adapter/resources/webgpu-buffer.ts +61 -15
- package/src/adapter/resources/webgpu-command-buffer.ts +1 -1
- package/src/adapter/resources/webgpu-command-encoder.ts +129 -50
- package/src/adapter/resources/webgpu-compute-pass.ts +48 -13
- package/src/adapter/resources/webgpu-compute-pipeline.ts +49 -18
- package/src/adapter/resources/webgpu-fence.ts +38 -0
- package/src/adapter/resources/webgpu-framebuffer.ts +21 -0
- package/src/adapter/resources/webgpu-pipeline-layout.ts +18 -17
- package/src/adapter/resources/webgpu-query-set.ts +185 -9
- package/src/adapter/resources/webgpu-render-pass.ts +92 -40
- package/src/adapter/resources/webgpu-render-pipeline.ts +83 -44
- package/src/adapter/resources/webgpu-sampler.ts +5 -0
- package/src/adapter/resources/webgpu-shader.ts +16 -1
- package/src/adapter/resources/webgpu-texture-view.ts +51 -11
- package/src/adapter/resources/webgpu-texture.ts +281 -101
- package/src/adapter/resources/webgpu-vertex-array.ts +1 -1
- package/src/adapter/webgpu-adapter.ts +40 -42
- package/src/adapter/webgpu-canvas-context.ts +107 -40
- package/src/adapter/webgpu-device.ts +231 -21
- package/src/adapter/webgpu-presentation-context.ts +180 -0
- package/src/index.ts +3 -0
- package/src/wgsl/get-shader-layout-wgsl.ts +165 -0
- package/dist/adapter/helpers/accessor-to-format.d.ts +0 -1
- package/dist/adapter/helpers/accessor-to-format.d.ts.map +0 -1
- package/dist/adapter/helpers/accessor-to-format.js +0 -105
- package/dist/adapter/helpers/accessor-to-format.js.map +0 -1
- package/src/adapter/helpers/accessor-to-format.ts +0 -104
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// prettier-ignore
|
|
6
|
+
// / <reference types="@webgpu/types" />
|
|
7
|
+
|
|
8
|
+
import type {PresentationContextProps, TextureFormatDepthStencil} from '@luma.gl/core';
|
|
9
|
+
import {PresentationContext, Texture, log} from '@luma.gl/core';
|
|
10
|
+
import type {WebGPUDevice} from './webgpu-device';
|
|
11
|
+
import {WebGPUFramebuffer} from './resources/webgpu-framebuffer';
|
|
12
|
+
import {WebGPUTexture} from './resources/webgpu-texture';
|
|
13
|
+
import {getCpuHotspotProfiler, getTimestamp} from './helpers/cpu-hotspot-profiler';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A WebGPU PresentationContext renders directly into its destination canvas.
|
|
17
|
+
*/
|
|
18
|
+
export class WebGPUPresentationContext extends PresentationContext {
|
|
19
|
+
readonly device: WebGPUDevice;
|
|
20
|
+
readonly handle: GPUCanvasContext;
|
|
21
|
+
|
|
22
|
+
private colorAttachment: WebGPUTexture | null = null;
|
|
23
|
+
private depthStencilAttachment: WebGPUTexture | null = null;
|
|
24
|
+
private framebuffer: WebGPUFramebuffer | null = null;
|
|
25
|
+
|
|
26
|
+
get [Symbol.toStringTag](): string {
|
|
27
|
+
return 'WebGPUPresentationContext';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
constructor(device: WebGPUDevice, props: PresentationContextProps = {}) {
|
|
31
|
+
super(props);
|
|
32
|
+
const contextLabel = `${this[Symbol.toStringTag]}(${this.id})`;
|
|
33
|
+
|
|
34
|
+
const context = this.canvas.getContext('webgpu');
|
|
35
|
+
if (!context) {
|
|
36
|
+
throw new Error(`${contextLabel}: Failed to create WebGPU presentation context`);
|
|
37
|
+
}
|
|
38
|
+
this.device = device;
|
|
39
|
+
this.handle = context;
|
|
40
|
+
|
|
41
|
+
this._setAutoCreatedCanvasId(`${this.device.id}-presentation-canvas`);
|
|
42
|
+
this._configureDevice();
|
|
43
|
+
this._startObservers();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override destroy(): void {
|
|
47
|
+
if (this.framebuffer) {
|
|
48
|
+
this.framebuffer.destroy();
|
|
49
|
+
this.framebuffer = null;
|
|
50
|
+
}
|
|
51
|
+
if (this.colorAttachment) {
|
|
52
|
+
this.colorAttachment.destroy();
|
|
53
|
+
this.colorAttachment = null;
|
|
54
|
+
}
|
|
55
|
+
if (this.depthStencilAttachment) {
|
|
56
|
+
this.depthStencilAttachment.destroy();
|
|
57
|
+
this.depthStencilAttachment = null;
|
|
58
|
+
}
|
|
59
|
+
this.handle.unconfigure();
|
|
60
|
+
super.destroy();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
present(): void {
|
|
64
|
+
this.device.submit();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
protected override _configureDevice(): void {
|
|
68
|
+
if (this.depthStencilAttachment) {
|
|
69
|
+
this.depthStencilAttachment.destroy();
|
|
70
|
+
this.depthStencilAttachment = null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.handle.configure({
|
|
74
|
+
device: this.device.handle,
|
|
75
|
+
format: this.device.preferredColorFormat,
|
|
76
|
+
colorSpace: this.props.colorSpace,
|
|
77
|
+
alphaMode: this.props.alphaMode
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
this._createDepthStencilAttachment(this.device.preferredDepthFormat);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
protected override _getCurrentFramebuffer(
|
|
84
|
+
options: {depthStencilFormat?: TextureFormatDepthStencil | false} = {
|
|
85
|
+
depthStencilFormat: 'depth24plus'
|
|
86
|
+
}
|
|
87
|
+
): WebGPUFramebuffer {
|
|
88
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
89
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
90
|
+
if (profiler) {
|
|
91
|
+
profiler.framebufferAcquireCount = (profiler.framebufferAcquireCount || 0) + 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const currentColorAttachment = this._getCurrentTexture();
|
|
96
|
+
if (
|
|
97
|
+
currentColorAttachment.width !== this.drawingBufferWidth ||
|
|
98
|
+
currentColorAttachment.height !== this.drawingBufferHeight
|
|
99
|
+
) {
|
|
100
|
+
const [oldWidth, oldHeight] = this.getDrawingBufferSize();
|
|
101
|
+
this.drawingBufferWidth = currentColorAttachment.width;
|
|
102
|
+
this.drawingBufferHeight = currentColorAttachment.height;
|
|
103
|
+
log.log(
|
|
104
|
+
1,
|
|
105
|
+
`${this[Symbol.toStringTag]}(${this.id}): Resized to compensate for initial canvas size mismatch ${oldWidth}x${oldHeight} => ${this.drawingBufferWidth}x${this.drawingBufferHeight}px`
|
|
106
|
+
)();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (options?.depthStencilFormat) {
|
|
110
|
+
this._createDepthStencilAttachment(options.depthStencilFormat);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.framebuffer ||= new WebGPUFramebuffer(this.device, {
|
|
114
|
+
id: `${this.id}#framebuffer`,
|
|
115
|
+
colorAttachments: [currentColorAttachment],
|
|
116
|
+
depthStencilAttachment: null
|
|
117
|
+
});
|
|
118
|
+
this.framebuffer._reinitialize(
|
|
119
|
+
currentColorAttachment.view,
|
|
120
|
+
options?.depthStencilFormat ? this.depthStencilAttachment?.view || null : null
|
|
121
|
+
);
|
|
122
|
+
return this.framebuffer;
|
|
123
|
+
} finally {
|
|
124
|
+
if (profiler) {
|
|
125
|
+
profiler.framebufferAcquireTimeMs =
|
|
126
|
+
(profiler.framebufferAcquireTimeMs || 0) + (getTimestamp() - startTime);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private _getCurrentTexture(): WebGPUTexture {
|
|
132
|
+
const profiler = getCpuHotspotProfiler(this.device);
|
|
133
|
+
const currentTextureStartTime = profiler ? getTimestamp() : 0;
|
|
134
|
+
const handle = this.handle.getCurrentTexture();
|
|
135
|
+
if (profiler) {
|
|
136
|
+
profiler.currentTextureAcquireCount = (profiler.currentTextureAcquireCount || 0) + 1;
|
|
137
|
+
profiler.currentTextureAcquireTimeMs =
|
|
138
|
+
(profiler.currentTextureAcquireTimeMs || 0) + (getTimestamp() - currentTextureStartTime);
|
|
139
|
+
}
|
|
140
|
+
if (!this.colorAttachment) {
|
|
141
|
+
this.colorAttachment = this.device.createTexture({
|
|
142
|
+
id: `${this.id}#color-texture`,
|
|
143
|
+
handle,
|
|
144
|
+
format: this.device.preferredColorFormat,
|
|
145
|
+
width: handle.width,
|
|
146
|
+
height: handle.height
|
|
147
|
+
});
|
|
148
|
+
return this.colorAttachment;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.colorAttachment._reinitialize(handle, {
|
|
152
|
+
handle,
|
|
153
|
+
format: this.device.preferredColorFormat,
|
|
154
|
+
width: handle.width,
|
|
155
|
+
height: handle.height
|
|
156
|
+
});
|
|
157
|
+
return this.colorAttachment;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private _createDepthStencilAttachment(
|
|
161
|
+
depthStencilFormat: TextureFormatDepthStencil
|
|
162
|
+
): WebGPUTexture {
|
|
163
|
+
const needsNewDepthStencilAttachment =
|
|
164
|
+
!this.depthStencilAttachment ||
|
|
165
|
+
this.depthStencilAttachment.width !== this.drawingBufferWidth ||
|
|
166
|
+
this.depthStencilAttachment.height !== this.drawingBufferHeight ||
|
|
167
|
+
this.depthStencilAttachment.format !== depthStencilFormat;
|
|
168
|
+
if (needsNewDepthStencilAttachment) {
|
|
169
|
+
this.depthStencilAttachment?.destroy();
|
|
170
|
+
this.depthStencilAttachment = this.device.createTexture({
|
|
171
|
+
id: `${this.id}#depth-stencil-texture`,
|
|
172
|
+
usage: Texture.RENDER_ATTACHMENT,
|
|
173
|
+
format: depthStencilFormat,
|
|
174
|
+
width: this.drawingBufferWidth,
|
|
175
|
+
height: this.drawingBufferHeight
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return this.depthStencilAttachment!;
|
|
179
|
+
}
|
|
180
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -12,3 +12,6 @@ export {WebGPUBuffer} from './adapter/resources/webgpu-buffer';
|
|
|
12
12
|
export {WebGPUTexture} from './adapter/resources/webgpu-texture';
|
|
13
13
|
export {WebGPUSampler} from './adapter/resources/webgpu-sampler';
|
|
14
14
|
export {WebGPUShader} from './adapter/resources/webgpu-shader';
|
|
15
|
+
export {WebGPUFence} from './adapter/resources/webgpu-fence';
|
|
16
|
+
|
|
17
|
+
export {getShaderLayoutFromWGSL} from './wgsl/get-shader-layout-wgsl';
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {AttributeShaderType, ShaderLayout, TextureBindingLayout, log} from '@luma.gl/core';
|
|
6
|
+
import {TypeInfo, VariableInfo, WgslReflect, ResourceType} from 'wgsl_reflect';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Parse a ShaderLayout from WGSL shader source code.
|
|
10
|
+
* @param source WGSL source code (can contain both @vertex and @fragment entry points)
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export function getShaderLayoutFromWGSL(source: string): ShaderLayout {
|
|
14
|
+
const shaderLayout: ShaderLayout = {attributes: [], bindings: []};
|
|
15
|
+
|
|
16
|
+
let parsedWGSL: WgslReflect;
|
|
17
|
+
try {
|
|
18
|
+
parsedWGSL = parseWGSL(source);
|
|
19
|
+
} catch (error: any) {
|
|
20
|
+
log.error(error.message)();
|
|
21
|
+
return shaderLayout;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (const uniform of parsedWGSL.uniforms) {
|
|
25
|
+
const members = [];
|
|
26
|
+
// @ts-expect-error
|
|
27
|
+
for (const attribute of uniform.type?.members || []) {
|
|
28
|
+
members.push({
|
|
29
|
+
name: attribute.name,
|
|
30
|
+
type: getType(attribute.type)
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
shaderLayout.bindings.push({
|
|
35
|
+
type: 'uniform',
|
|
36
|
+
name: uniform.name,
|
|
37
|
+
group: uniform.group,
|
|
38
|
+
location: uniform.binding,
|
|
39
|
+
// @ts-expect-error TODO - unused for now but needs fixing
|
|
40
|
+
members
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const storageBuffer of parsedWGSL.storage) {
|
|
45
|
+
shaderLayout.bindings.push({
|
|
46
|
+
type: storageBuffer.access === 'read' ? 'read-only-storage' : 'storage',
|
|
47
|
+
name: storageBuffer.name,
|
|
48
|
+
group: storageBuffer.group,
|
|
49
|
+
location: storageBuffer.binding
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (const texture of parsedWGSL.textures) {
|
|
54
|
+
const bindingDeclaration: TextureBindingLayout = {
|
|
55
|
+
type: 'texture',
|
|
56
|
+
name: texture.name,
|
|
57
|
+
group: texture.group,
|
|
58
|
+
location: texture.binding,
|
|
59
|
+
...getTextureBindingFromReflect(texture)
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
shaderLayout.bindings.push(bindingDeclaration);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
for (const sampler of parsedWGSL.samplers) {
|
|
66
|
+
shaderLayout.bindings.push({
|
|
67
|
+
type: 'sampler',
|
|
68
|
+
name: sampler.name,
|
|
69
|
+
group: sampler.group,
|
|
70
|
+
location: sampler.binding
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const vertex = parsedWGSL.entry.vertex[0]; // "main"
|
|
75
|
+
|
|
76
|
+
// Vertex shader inputs
|
|
77
|
+
const attributeCount = vertex?.inputs.length || 0; // inputs to "main"
|
|
78
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
79
|
+
const wgslAttribute = vertex.inputs[i];
|
|
80
|
+
|
|
81
|
+
// locationType can be "builtin"
|
|
82
|
+
if (wgslAttribute.locationType === 'location') {
|
|
83
|
+
const type = getType(wgslAttribute.type);
|
|
84
|
+
|
|
85
|
+
shaderLayout.attributes.push({
|
|
86
|
+
name: wgslAttribute.name,
|
|
87
|
+
location: Number(wgslAttribute.location),
|
|
88
|
+
type
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return shaderLayout;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Get a valid shader attribute type string from a wgsl-reflect type */
|
|
96
|
+
function getType(type: TypeInfo | null): AttributeShaderType {
|
|
97
|
+
// @ts-expect-error WgslReflect type checks needed
|
|
98
|
+
return type?.format ? `${type.name}<${type.format.name}>` : type.name;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function parseWGSL(source: string): WgslReflect {
|
|
102
|
+
try {
|
|
103
|
+
return new WgslReflect(source);
|
|
104
|
+
} catch (error: any) {
|
|
105
|
+
if (error instanceof Error) {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
let message = 'WGSL parse error';
|
|
109
|
+
if (typeof error === 'object' && error?.message) {
|
|
110
|
+
message += `: ${error.message} `;
|
|
111
|
+
}
|
|
112
|
+
if (typeof error === 'object' && error?.token) {
|
|
113
|
+
message += error.token.line || '';
|
|
114
|
+
}
|
|
115
|
+
throw new Error(message, {cause: error});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getTextureBindingFromReflect(
|
|
120
|
+
v: VariableInfo, // VariableInfo for a texture
|
|
121
|
+
opts?: {format?: GPUTextureFormat} // optional: if you know the runtime format
|
|
122
|
+
): {
|
|
123
|
+
viewDimension: GPUTextureViewDimension;
|
|
124
|
+
/** @note sampleType float vs unfilterable-float cannot be determined without checking texture format and features */
|
|
125
|
+
sampleType: GPUTextureSampleType;
|
|
126
|
+
multisampled: boolean;
|
|
127
|
+
} {
|
|
128
|
+
if (v.resourceType !== ResourceType.Texture) {
|
|
129
|
+
throw new Error('Not a texture binding');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const typeName = v.type.name; // e.g. "texture_2d", "texture_cube_array", "texture_multisampled_2d"
|
|
133
|
+
// @ts-expect-error v.type.format is not always defined
|
|
134
|
+
const component = v.type.format?.name as 'f32' | 'i32' | 'u32' | undefined;
|
|
135
|
+
|
|
136
|
+
// viewDimension
|
|
137
|
+
const viewDimension: GPUTextureViewDimension = typeName.includes('cube_array')
|
|
138
|
+
? 'cube-array'
|
|
139
|
+
: typeName.includes('cube')
|
|
140
|
+
? 'cube'
|
|
141
|
+
: typeName.includes('2d_array')
|
|
142
|
+
? '2d-array'
|
|
143
|
+
: typeName.includes('3d')
|
|
144
|
+
? '3d'
|
|
145
|
+
: typeName.includes('1d')
|
|
146
|
+
? '1d'
|
|
147
|
+
: '2d';
|
|
148
|
+
|
|
149
|
+
// multisampled
|
|
150
|
+
const multisampled = typeName === 'texture_multisampled_2d';
|
|
151
|
+
|
|
152
|
+
// sampleType
|
|
153
|
+
let sampleType: GPUTextureSampleType;
|
|
154
|
+
if (typeName.startsWith('texture_depth')) {
|
|
155
|
+
sampleType = 'depth';
|
|
156
|
+
} else if (component === 'i32') {
|
|
157
|
+
sampleType = 'sint';
|
|
158
|
+
} else if (component === 'u32') {
|
|
159
|
+
sampleType = 'uint';
|
|
160
|
+
} else {
|
|
161
|
+
sampleType = 'float'; // default to float
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return {viewDimension, sampleType, multisampled};
|
|
165
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=accessor-to-format.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"accessor-to-format.d.ts","sourceRoot":"","sources":["../../../src/adapter/helpers/accessor-to-format.ts"],"names":[],"mappings":""}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// luma.gl
|
|
3
|
-
// SPDX-License-Identifier: MIT
|
|
4
|
-
// Copyright (c) vis.gl contributors
|
|
5
|
-
/*
|
|
6
|
-
import {assert} from '@luma.gl/core';
|
|
7
|
-
|
|
8
|
-
type Accessor = Record<string, any>;
|
|
9
|
-
|
|
10
|
-
const FORMAT_TO_ACCESSOR: Record<GPUVertexFormat, Accessor> = {
|
|
11
|
-
uchar2: {type: 'uchar', size: 2},
|
|
12
|
-
uchar4: {type: 'uchar', size: 4},
|
|
13
|
-
char2: {type: 'char', size: 2},
|
|
14
|
-
char4: {type: 'char', size: 4},
|
|
15
|
-
uchar2norm: {type: 'uchar', size: 2, normalized: true},
|
|
16
|
-
uchar4norm: {type: 'uchar', size: 4, normalized: true},
|
|
17
|
-
char2norm: {type: 'char', size: 2, normalized: true},
|
|
18
|
-
char4norm: {type: 'char', size: 4, normalized: true},
|
|
19
|
-
ushort2: {type: 'ushort', size: 2},
|
|
20
|
-
ushort4: {type: 'ushort', size: 4},
|
|
21
|
-
short2: {type: 'short', size: 2},
|
|
22
|
-
short4: {type: 'short', size: 4},
|
|
23
|
-
ushort2norm: {type: 'ushort', size: 2, normalized: true},
|
|
24
|
-
ushort4norm: {type: 'ushort', size: 4, normalized: true},
|
|
25
|
-
short2norm: {type: 'short', size: 1, normalized: true},
|
|
26
|
-
short4norm: {type: 'short', size: 1, normalized: true},
|
|
27
|
-
half2: {type: 'half', size: 2},
|
|
28
|
-
half4: {type: 'half', size: 4},
|
|
29
|
-
float: {type: 'float', size: 1},
|
|
30
|
-
float2: {type: 'float', size: 2},
|
|
31
|
-
float3: {type: 'float', size: 3},
|
|
32
|
-
float4: {type: 'float', size: 4},
|
|
33
|
-
uint: {type: 'uint', size: 1, integer: true},
|
|
34
|
-
uint2: {type: 'uint', size: 2, integer: true},
|
|
35
|
-
uint3: {type: 'uint', size: 3, integer: true},
|
|
36
|
-
uint4: {type: 'uint', size: 4, integer: true},
|
|
37
|
-
int: {type: 'int', size: 1, integer: true},
|
|
38
|
-
int2: {type: 'int', size: 2, integer: true},
|
|
39
|
-
int3: {type: 'int', size: 3, integer: true},
|
|
40
|
-
int4: {type: 'int', size: 4, integer: true}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Convert from WebGPU attribute format strings to accessor {type, size, normalized, integer}
|
|
45
|
-
* @param {*} format
|
|
46
|
-
*
|
|
47
|
-
export function mapWebGPUFormatToAccessor(format) {
|
|
48
|
-
const accessorDefinition = FORMAT_TO_ACCESSOR[format];
|
|
49
|
-
assert(accessorDefinition, 'invalid attribute format');
|
|
50
|
-
return Object.freeze(accessorDefinition);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Convert from accessor {type, size, normalized, integer} to WebGPU attribute format strings
|
|
55
|
-
* @param {*} format
|
|
56
|
-
*
|
|
57
|
-
export function mapAccessorToWebGPUFormat(accessor) {
|
|
58
|
-
const {type = GL.FLOAT, size = 1, normalized = false, integer = false} = accessor;
|
|
59
|
-
assert(size >=1 && size <=4);
|
|
60
|
-
// `norm` suffix (uchar4norm)
|
|
61
|
-
const norm = normalized ? 'norm' : '';
|
|
62
|
-
// size 1 is ommitted in format names (float vs float2)
|
|
63
|
-
const count = size === 1 ? '' : size;
|
|
64
|
-
switch (type) {
|
|
65
|
-
case GL.UNSIGNED_BYTE:
|
|
66
|
-
switch (size) {
|
|
67
|
-
case 2:
|
|
68
|
-
case 4:
|
|
69
|
-
return `uchar${count}${norm}`;
|
|
70
|
-
}
|
|
71
|
-
case GL.BYTE:
|
|
72
|
-
switch (size) {
|
|
73
|
-
case 2:
|
|
74
|
-
case 4:
|
|
75
|
-
return `char${count}${norm}`;
|
|
76
|
-
}
|
|
77
|
-
case GL.UNSIGNED_SHORT:
|
|
78
|
-
switch (size) {
|
|
79
|
-
case 2:
|
|
80
|
-
case 4:
|
|
81
|
-
return `ushort${count}${norm}`;
|
|
82
|
-
}
|
|
83
|
-
case GL.SHORT:
|
|
84
|
-
switch (size) {
|
|
85
|
-
case 2:
|
|
86
|
-
case 4:
|
|
87
|
-
return `short${count}${norm}`;
|
|
88
|
-
}
|
|
89
|
-
case GL.HALF_FLOAT:
|
|
90
|
-
switch (size) {
|
|
91
|
-
case 2:
|
|
92
|
-
case 4:
|
|
93
|
-
return `half${count}`;
|
|
94
|
-
}
|
|
95
|
-
case GL.FLOAT:
|
|
96
|
-
return `float${count}`;
|
|
97
|
-
case GL.UNSIGNED_INT:
|
|
98
|
-
return `uint${count}`;
|
|
99
|
-
case GL.INT:
|
|
100
|
-
return `int${count}`;
|
|
101
|
-
}
|
|
102
|
-
throw new Error('illegal accessor');
|
|
103
|
-
}
|
|
104
|
-
*/
|
|
105
|
-
//# sourceMappingURL=accessor-to-format.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"accessor-to-format.js","sourceRoot":"","sources":["../../../src/adapter/helpers/accessor-to-format.ts"],"names":[],"mappings":";AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmGE"}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
// luma.gl
|
|
2
|
-
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Copyright (c) vis.gl contributors
|
|
4
|
-
|
|
5
|
-
/*
|
|
6
|
-
import {assert} from '@luma.gl/core';
|
|
7
|
-
|
|
8
|
-
type Accessor = Record<string, any>;
|
|
9
|
-
|
|
10
|
-
const FORMAT_TO_ACCESSOR: Record<GPUVertexFormat, Accessor> = {
|
|
11
|
-
uchar2: {type: 'uchar', size: 2},
|
|
12
|
-
uchar4: {type: 'uchar', size: 4},
|
|
13
|
-
char2: {type: 'char', size: 2},
|
|
14
|
-
char4: {type: 'char', size: 4},
|
|
15
|
-
uchar2norm: {type: 'uchar', size: 2, normalized: true},
|
|
16
|
-
uchar4norm: {type: 'uchar', size: 4, normalized: true},
|
|
17
|
-
char2norm: {type: 'char', size: 2, normalized: true},
|
|
18
|
-
char4norm: {type: 'char', size: 4, normalized: true},
|
|
19
|
-
ushort2: {type: 'ushort', size: 2},
|
|
20
|
-
ushort4: {type: 'ushort', size: 4},
|
|
21
|
-
short2: {type: 'short', size: 2},
|
|
22
|
-
short4: {type: 'short', size: 4},
|
|
23
|
-
ushort2norm: {type: 'ushort', size: 2, normalized: true},
|
|
24
|
-
ushort4norm: {type: 'ushort', size: 4, normalized: true},
|
|
25
|
-
short2norm: {type: 'short', size: 1, normalized: true},
|
|
26
|
-
short4norm: {type: 'short', size: 1, normalized: true},
|
|
27
|
-
half2: {type: 'half', size: 2},
|
|
28
|
-
half4: {type: 'half', size: 4},
|
|
29
|
-
float: {type: 'float', size: 1},
|
|
30
|
-
float2: {type: 'float', size: 2},
|
|
31
|
-
float3: {type: 'float', size: 3},
|
|
32
|
-
float4: {type: 'float', size: 4},
|
|
33
|
-
uint: {type: 'uint', size: 1, integer: true},
|
|
34
|
-
uint2: {type: 'uint', size: 2, integer: true},
|
|
35
|
-
uint3: {type: 'uint', size: 3, integer: true},
|
|
36
|
-
uint4: {type: 'uint', size: 4, integer: true},
|
|
37
|
-
int: {type: 'int', size: 1, integer: true},
|
|
38
|
-
int2: {type: 'int', size: 2, integer: true},
|
|
39
|
-
int3: {type: 'int', size: 3, integer: true},
|
|
40
|
-
int4: {type: 'int', size: 4, integer: true}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Convert from WebGPU attribute format strings to accessor {type, size, normalized, integer}
|
|
45
|
-
* @param {*} format
|
|
46
|
-
*
|
|
47
|
-
export function mapWebGPUFormatToAccessor(format) {
|
|
48
|
-
const accessorDefinition = FORMAT_TO_ACCESSOR[format];
|
|
49
|
-
assert(accessorDefinition, 'invalid attribute format');
|
|
50
|
-
return Object.freeze(accessorDefinition);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Convert from accessor {type, size, normalized, integer} to WebGPU attribute format strings
|
|
55
|
-
* @param {*} format
|
|
56
|
-
*
|
|
57
|
-
export function mapAccessorToWebGPUFormat(accessor) {
|
|
58
|
-
const {type = GL.FLOAT, size = 1, normalized = false, integer = false} = accessor;
|
|
59
|
-
assert(size >=1 && size <=4);
|
|
60
|
-
// `norm` suffix (uchar4norm)
|
|
61
|
-
const norm = normalized ? 'norm' : '';
|
|
62
|
-
// size 1 is ommitted in format names (float vs float2)
|
|
63
|
-
const count = size === 1 ? '' : size;
|
|
64
|
-
switch (type) {
|
|
65
|
-
case GL.UNSIGNED_BYTE:
|
|
66
|
-
switch (size) {
|
|
67
|
-
case 2:
|
|
68
|
-
case 4:
|
|
69
|
-
return `uchar${count}${norm}`;
|
|
70
|
-
}
|
|
71
|
-
case GL.BYTE:
|
|
72
|
-
switch (size) {
|
|
73
|
-
case 2:
|
|
74
|
-
case 4:
|
|
75
|
-
return `char${count}${norm}`;
|
|
76
|
-
}
|
|
77
|
-
case GL.UNSIGNED_SHORT:
|
|
78
|
-
switch (size) {
|
|
79
|
-
case 2:
|
|
80
|
-
case 4:
|
|
81
|
-
return `ushort${count}${norm}`;
|
|
82
|
-
}
|
|
83
|
-
case GL.SHORT:
|
|
84
|
-
switch (size) {
|
|
85
|
-
case 2:
|
|
86
|
-
case 4:
|
|
87
|
-
return `short${count}${norm}`;
|
|
88
|
-
}
|
|
89
|
-
case GL.HALF_FLOAT:
|
|
90
|
-
switch (size) {
|
|
91
|
-
case 2:
|
|
92
|
-
case 4:
|
|
93
|
-
return `half${count}`;
|
|
94
|
-
}
|
|
95
|
-
case GL.FLOAT:
|
|
96
|
-
return `float${count}`;
|
|
97
|
-
case GL.UNSIGNED_INT:
|
|
98
|
-
return `uint${count}`;
|
|
99
|
-
case GL.INT:
|
|
100
|
-
return `int${count}`;
|
|
101
|
-
}
|
|
102
|
-
throw new Error('illegal accessor');
|
|
103
|
-
}
|
|
104
|
-
*/
|