@luma.gl/webgpu 9.0.0-alpha.5 → 9.0.0-alpha.50
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/LICENSE +3 -1
- package/dist/adapter/helpers/accessor-to-format.js.map +1 -1
- package/dist/adapter/helpers/convert-texture-format.d.ts +2 -2
- package/dist/adapter/helpers/convert-texture-format.d.ts.map +1 -1
- package/dist/adapter/helpers/convert-texture-format.js +0 -1
- package/dist/adapter/helpers/convert-texture-format.js.map +1 -1
- package/dist/adapter/helpers/generate-mipmaps.d.ts +1 -1
- package/dist/adapter/helpers/generate-mipmaps.js +20 -15
- package/dist/adapter/helpers/generate-mipmaps.js.map +1 -1
- package/dist/adapter/helpers/get-bind-group.d.ts +4 -4
- package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
- package/dist/adapter/helpers/get-bind-group.js +8 -17
- package/dist/adapter/helpers/get-bind-group.js.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts +5 -5
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +32 -40
- package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.d.ts +2 -2
- package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
- package/dist/adapter/helpers/webgpu-parameters.js +51 -48
- package/dist/adapter/helpers/webgpu-parameters.js.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.d.ts +5 -6
- package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-buffer.js +19 -33
- package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.d.ts +6 -15
- package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-command-encoder.js +11 -29
- package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.d.ts +6 -6
- package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pass.js +14 -27
- package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +4 -4
- package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-compute-pipeline.js +6 -11
- package/dist/adapter/resources/webgpu-compute-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgpu-external-texture.d.ts +5 -5
- package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-external-texture.js +6 -14
- package/dist/adapter/resources/webgpu-external-texture.js.map +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.d.ts +4 -21
- package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-framebuffer.js +4 -105
- package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
- package/dist/adapter/resources/webgpu-query.js.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.d.ts +12 -7
- package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-render-pass.js +59 -36
- 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 +50 -67
- package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.d.ts +5 -5
- package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-sampler.js +11 -11
- package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
- package/dist/adapter/resources/webgpu-shader.d.ts +7 -7
- package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-shader.js +11 -25
- package/dist/adapter/resources/webgpu-shader.js.map +1 -1
- package/dist/adapter/resources/webgpu-texture.d.ts +15 -8
- package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgpu-texture.js +17 -27
- package/dist/adapter/resources/webgpu-texture.js.map +1 -1
- package/dist/adapter/resources/webgpu-vertex-array.d.ts +26 -0
- package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -0
- package/dist/adapter/resources/webgpu-vertex-array.js +39 -0
- package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -0
- package/dist/adapter/webgpu-canvas-context.d.ts +16 -12
- package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgpu-canvas-context.js +26 -47
- package/dist/adapter/webgpu-canvas-context.js.map +1 -1
- package/dist/adapter/webgpu-device.d.ts +39 -22
- package/dist/adapter/webgpu-device.d.ts.map +1 -1
- package/dist/adapter/webgpu-device.js +94 -95
- package/dist/adapter/webgpu-device.js.map +1 -1
- package/dist/adapter/webgpu-types.js.map +1 -1
- package/dist/dist.dev.js +2988 -0
- package/dist/glsl/glsllang.js +0 -1
- package/dist/glsl/glsllang.js.map +1 -1
- package/dist/index.cjs +1518 -0
- package/dist/index.d.ts +5 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -7
- package/dist/index.js.map +1 -1
- package/dist.min.js +20 -0
- package/package.json +18 -9
- package/src/adapter/helpers/accessor-to-format.ts +1 -2
- package/src/adapter/helpers/convert-texture-format.ts +1 -1
- package/src/adapter/helpers/generate-mipmaps.ts +2 -2
- package/src/adapter/helpers/get-bind-group.ts +22 -12
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +55 -34
- package/src/adapter/helpers/webgpu-parameters.ts +56 -47
- package/src/adapter/resources/webgpu-buffer.ts +11 -12
- package/src/adapter/resources/webgpu-command-encoder.ts +62 -41
- package/src/adapter/resources/webgpu-compute-pass.ts +13 -13
- package/src/adapter/resources/webgpu-compute-pipeline.ts +6 -5
- package/src/adapter/resources/webgpu-external-texture.ts +5 -5
- package/src/adapter/resources/webgpu-framebuffer.ts +8 -109
- package/src/adapter/resources/webgpu-query.ts +3 -3
- package/src/adapter/resources/webgpu-render-pass.ts +74 -18
- package/src/adapter/resources/webgpu-render-pipeline.ts +64 -39
- package/src/adapter/resources/webgpu-sampler.ts +12 -5
- package/src/adapter/resources/webgpu-shader.ts +13 -10
- package/src/adapter/resources/webgpu-texture.ts +22 -8
- package/src/adapter/resources/webgpu-vertex-array.ts +74 -0
- package/src/adapter/webgpu-canvas-context.ts +52 -27
- package/src/adapter/webgpu-device.ts +158 -64
- package/src/index.ts +7 -9
- package/dist/bundle.d.ts +0 -2
- package/dist/bundle.d.ts.map +0 -1
- package/dist/bundle.js +0 -5
- package/dist/bundle.js.map +0 -1
- package/dist/init.d.ts +0 -2
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -4
- package/dist/init.js.map +0 -1
- package/src/bundle.ts +0 -4
- package/src/init.ts +0 -4
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import {ComputePass, ComputePassProps, ComputePipeline, Buffer, Binding, cast} from '@luma.gl/
|
|
2
|
-
import WebGPUDevice from '../webgpu-device';
|
|
3
|
-
import WebGPUBuffer from './webgpu-buffer';
|
|
4
|
-
// import WebGPUCommandEncoder from './webgpu-command-encoder';
|
|
5
|
-
import WebGPUComputePipeline from './webgpu-compute-pipeline';
|
|
1
|
+
import {ComputePass, ComputePassProps, ComputePipeline, Buffer, Binding, cast} from '@luma.gl/core';
|
|
2
|
+
import {WebGPUDevice} from '../webgpu-device';
|
|
3
|
+
import {WebGPUBuffer} from './webgpu-buffer';
|
|
4
|
+
// import {WebGPUCommandEncoder} from './webgpu-command-encoder';
|
|
5
|
+
import {WebGPUComputePipeline} from './webgpu-compute-pipeline';
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export class WebGPUComputePass extends ComputePass {
|
|
8
8
|
readonly device: WebGPUDevice;
|
|
9
9
|
readonly handle: GPUComputePassEncoder;
|
|
10
|
-
_bindGroupLayout: GPUBindGroupLayout;
|
|
10
|
+
_bindGroupLayout: GPUBindGroupLayout | null = null;
|
|
11
11
|
|
|
12
12
|
constructor(device: WebGPUDevice, props: ComputePassProps) {
|
|
13
13
|
super(device, props);
|
|
14
14
|
this.device = device;
|
|
15
15
|
|
|
16
|
-
this.handle = this.props.handle || device.commandEncoder
|
|
16
|
+
this.handle = this.props.handle || device.commandEncoder?.beginComputePass({
|
|
17
17
|
label: this.props.id,
|
|
18
18
|
// timestampWrites?: GPUComputePassTimestampWrites;
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/** @note no WebGPU destroy method, just gc */
|
|
23
|
-
destroy() {}
|
|
23
|
+
override destroy(): void {}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
this.handle.
|
|
25
|
+
end(): void {
|
|
26
|
+
this.handle.end();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
setPipeline(pipeline: ComputePipeline): void {
|
|
@@ -46,7 +46,7 @@ export default class WebGPUComputePass extends ComputePass {
|
|
|
46
46
|
* @param z Z dimension of the grid of workgroups to dispatch.
|
|
47
47
|
*/
|
|
48
48
|
dispatch(x: number, y?: number, z?: number): void {
|
|
49
|
-
this.handle.
|
|
49
|
+
this.handle.dispatchWorkgroups(x, y, z);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -55,7 +55,7 @@ export default class WebGPUComputePass extends ComputePass {
|
|
|
55
55
|
* @param indirectOffset
|
|
56
56
|
*/
|
|
57
57
|
dispatchIndirect(indirectBuffer: Buffer, indirectOffset: number = 0): void {
|
|
58
|
-
this.handle.
|
|
58
|
+
this.handle.dispatchWorkgroupsIndirect(cast<WebGPUBuffer>(indirectBuffer).handle, indirectOffset);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
pushDebugGroup(groupLabel: string): void {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// prettier-ignore
|
|
2
|
-
import {ComputePipeline, ComputePipelineProps, cast} from '@luma.gl/
|
|
2
|
+
import {ComputePipeline, ComputePipelineProps, cast} from '@luma.gl/core';
|
|
3
3
|
|
|
4
|
-
import WebGPUDevice from '../webgpu-device';
|
|
5
|
-
import WebGPUShader from './webgpu-shader';
|
|
4
|
+
import {WebGPUDevice} from '../webgpu-device';
|
|
5
|
+
import {WebGPUShader} from './webgpu-shader';
|
|
6
6
|
|
|
7
7
|
// COMPUTE PIPELINE
|
|
8
8
|
|
|
9
9
|
/** Creates a new compute pipeline when parameters change */
|
|
10
|
-
export
|
|
10
|
+
export class WebGPUComputePipeline extends ComputePipeline {
|
|
11
11
|
device: WebGPUDevice;
|
|
12
12
|
handle: GPUComputePipeline;
|
|
13
13
|
|
|
@@ -22,7 +22,8 @@ export default class WebGPUComputePipeline extends ComputePipeline {
|
|
|
22
22
|
module,
|
|
23
23
|
entryPoint: this.props.csEntryPoint,
|
|
24
24
|
// constants: this.props.csConstants
|
|
25
|
-
}
|
|
25
|
+
},
|
|
26
|
+
layout: 'auto'
|
|
26
27
|
});
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// luma.gl, MIT license
|
|
2
|
-
import {ExternalTexture, ExternalTextureProps, Sampler, SamplerProps} from '@luma.gl/
|
|
3
|
-
import type WebGPUDevice from '../webgpu-device';
|
|
4
|
-
import WebGPUSampler from './webgpu-sampler';
|
|
2
|
+
import {ExternalTexture, ExternalTextureProps, Sampler, SamplerProps} from '@luma.gl/core';
|
|
3
|
+
import type {WebGPUDevice} from '../webgpu-device';
|
|
4
|
+
import {WebGPUSampler} from './webgpu-sampler';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Cheap, temporary texture view for videos
|
|
8
8
|
* Only valid within same callback, destroyed automatically as a microtask.
|
|
9
9
|
*/
|
|
10
|
-
export
|
|
10
|
+
export class WebGPUExternalTexture extends ExternalTexture {
|
|
11
11
|
readonly device: WebGPUDevice;
|
|
12
12
|
readonly handle: GPUExternalTexture;
|
|
13
13
|
sampler: WebGPUSampler;
|
|
@@ -22,7 +22,7 @@ export default class WebGPUExternalTexture extends ExternalTexture {
|
|
|
22
22
|
this.sampler = null;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
destroy(): void {
|
|
25
|
+
override destroy(): void {
|
|
26
26
|
// External textures are destroyed automatically,
|
|
27
27
|
// as a microtask, instead of manually or upon garbage collection like other resources.
|
|
28
28
|
// this.handle.destroy();
|
|
@@ -1,120 +1,19 @@
|
|
|
1
|
-
import type {FramebufferProps
|
|
2
|
-
import {Framebuffer
|
|
3
|
-
import WebGPUDevice from '../webgpu-device';
|
|
4
|
-
// import WebGPUCanvasContext from '../webgpu-canvas-context';
|
|
5
|
-
import WEBGPUTexture from './webgpu-texture';
|
|
6
|
-
import WebGPUTexture from './webgpu-texture';
|
|
7
|
-
|
|
8
|
-
// const DEFAULT_DEPTH_STENCIL_FORMAT: DepthStencilTextureFormat = 'depth24plus';
|
|
9
|
-
|
|
10
|
-
const MAX_COLOR_ATTACHMENTS = 8;
|
|
1
|
+
import type {FramebufferProps} from '@luma.gl/core';
|
|
2
|
+
import {Framebuffer} from '@luma.gl/core';
|
|
3
|
+
import {WebGPUDevice} from '../webgpu-device';
|
|
11
4
|
|
|
12
5
|
/**
|
|
13
|
-
* Create new textures with correct size for all attachments.
|
|
14
|
-
* @note resize() destroys existing textures (if size has changed).
|
|
6
|
+
* Create new textures with correct size for all attachments.
|
|
7
|
+
* @note resize() destroys existing textures (if size has changed).
|
|
15
8
|
*/
|
|
16
|
-
export
|
|
9
|
+
export class WebGPUFramebuffer extends Framebuffer {
|
|
17
10
|
readonly device: WebGPUDevice;
|
|
18
11
|
|
|
19
|
-
colorAttachments: WebGPUTexture[] = [];
|
|
20
|
-
depthStencilAttachment: WebGPUTexture;
|
|
21
|
-
|
|
22
|
-
/** Partial render pass descriptor. Used by WebGPURenderPass */
|
|
23
|
-
renderPassDescriptor: {
|
|
24
|
-
colorAttachments: GPURenderPassColorAttachment[];
|
|
25
|
-
depthStencilAttachment?: GPURenderPassDepthStencilAttachment;
|
|
26
|
-
} = {
|
|
27
|
-
colorAttachments: []
|
|
28
|
-
};
|
|
29
|
-
|
|
30
12
|
constructor(device: WebGPUDevice, props: FramebufferProps) {
|
|
31
13
|
super(device, props);
|
|
32
14
|
this.device = device;
|
|
33
15
|
|
|
34
|
-
if
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (props.colorAttachments) {
|
|
39
|
-
this.colorAttachments = props.colorAttachments.map(colorAttachment => this.createColorTexture(this.props, colorAttachment));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (this.depthStencilAttachment) {
|
|
43
|
-
this.renderPassDescriptor.depthStencilAttachment = {
|
|
44
|
-
view: this.depthStencilAttachment.handle.createView(),
|
|
45
|
-
// Add default clear values
|
|
46
|
-
depthLoadValue: 1.0,
|
|
47
|
-
depthStoreOp: 'store',
|
|
48
|
-
stencilLoadValue: 0,
|
|
49
|
-
stencilStoreOp: 'store',
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (this.colorAttachments.length > 0) {
|
|
54
|
-
this.renderPassDescriptor.colorAttachments = this.colorAttachments.map(colorAttachment => ({
|
|
55
|
-
view: colorAttachment.handle.createView(),
|
|
56
|
-
loadValue: [0.0, 0.0, 0.0, 0.0],
|
|
57
|
-
storeOp: 'store'
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Create depth stencil texture */
|
|
63
|
-
private createDepthStencilTexture(props: FramebufferProps): WEBGPUTexture {
|
|
64
|
-
if (props.depthStencilAttachment instanceof WEBGPUTexture) {
|
|
65
|
-
return props.depthStencilAttachment;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (typeof props.depthStencilAttachment === 'string') {
|
|
69
|
-
return this.device._createTexture({
|
|
70
|
-
id: 'depth-stencil-attachment',
|
|
71
|
-
format: props.depthStencilAttachment,
|
|
72
|
-
width: props.width,
|
|
73
|
-
height: props.height,
|
|
74
|
-
usage: Texture.RENDER_ATTACHMENT
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
throw new Error('type');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private createColorTexture(props: FramebufferProps, texture: Texture | ColorTextureFormat): WEBGPUTexture {
|
|
82
|
-
if (texture instanceof WEBGPUTexture) {
|
|
83
|
-
return texture;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (typeof texture === 'string') {
|
|
87
|
-
return this.device._createTexture({
|
|
88
|
-
id: 'color-attachment',
|
|
89
|
-
format: texture,
|
|
90
|
-
width: props.width,
|
|
91
|
-
height: props.height,
|
|
92
|
-
usage: Texture.RENDER_ATTACHMENT
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
throw new Error('type');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Create new textures with correct size for all attachments.
|
|
101
|
-
* @note destroys existing textures.
|
|
102
|
-
*/
|
|
103
|
-
protected _resizeAttachments(width: number, height: number): void {
|
|
104
|
-
for (let i = 0; i < this.colorAttachments.length; ++i) {
|
|
105
|
-
if (this.colorAttachments[i]) {
|
|
106
|
-
const resizedTexture = this.device._createTexture({...this.colorAttachments[i].props, width, height})
|
|
107
|
-
this.colorAttachments[i].destroy();
|
|
108
|
-
this.colorAttachments[i] = resizedTexture;
|
|
109
|
-
this.renderPassDescriptor.colorAttachments[i].view = resizedTexture.handle.createView();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (this.depthStencilAttachment) {
|
|
114
|
-
const resizedTexture = this.device._createTexture({...this.depthStencilAttachment.props, width, height})
|
|
115
|
-
this.depthStencilAttachment.destroy();
|
|
116
|
-
this.depthStencilAttachment = resizedTexture;
|
|
117
|
-
this.renderPassDescriptor.depthStencilAttachment.view = resizedTexture.handle.createView();
|
|
118
|
-
}
|
|
16
|
+
// Auto create textures for attachments if needed
|
|
17
|
+
this.autoCreateAttachmentTextures();
|
|
119
18
|
}
|
|
120
19
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
import {Resource, Query, QueryProps} from '@luma.gl/
|
|
3
|
-
import WebGPUDevice from '../webgpu-device';
|
|
2
|
+
import {Resource, Query, QueryProps} from '@luma.gl/core';
|
|
3
|
+
import {WebGPUDevice} from '../webgpu-device';
|
|
4
4
|
|
|
5
5
|
export type WebGPUQueryProps = QueryProps & {
|
|
6
6
|
handle?: any;
|
|
@@ -36,7 +36,7 @@ class WebGPUQuery extends Resource<WebGPUQueryProps> implements Query {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
destroy() {
|
|
39
|
+
override destroy(): void {
|
|
40
40
|
this.handle.destroy();
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {RenderPassProps, RenderPassParameters, Binding} from '@luma.gl/
|
|
2
|
-
import {Buffer, RenderPass, RenderPipeline, cast, log} from '@luma.gl/
|
|
3
|
-
import WebGPUDevice from '../webgpu-device';
|
|
4
|
-
import WebGPUBuffer from './webgpu-buffer';
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import type {RenderPassProps, RenderPassParameters, Binding, Framebuffer} from '@luma.gl/core';
|
|
2
|
+
import {Buffer, RenderPass, RenderPipeline, cast, log} from '@luma.gl/core';
|
|
3
|
+
import {WebGPUDevice} from '../webgpu-device';
|
|
4
|
+
import {WebGPUBuffer} from './webgpu-buffer';
|
|
5
|
+
import {WebGPUTexture} from './webgpu-texture';
|
|
6
|
+
// import {WebGPUCommandEncoder} from './webgpu-command-encoder';
|
|
7
|
+
import {WebGPURenderPipeline} from './webgpu-render-pipeline';
|
|
8
|
+
|
|
9
|
+
export class WebGPURenderPass extends RenderPass {
|
|
9
10
|
readonly device: WebGPUDevice;
|
|
10
11
|
readonly handle: GPURenderPassEncoder;
|
|
11
12
|
|
|
@@ -15,17 +16,19 @@ export default class WebGPURenderPass extends RenderPass {
|
|
|
15
16
|
constructor(device: WebGPUDevice, props: RenderPassProps = {}) {
|
|
16
17
|
super(device, props);
|
|
17
18
|
this.device = device;
|
|
18
|
-
const framebuffer = props.framebuffer || device.canvasContext.getCurrentFramebuffer();
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const framebuffer = props.framebuffer || device.canvasContext.getCurrentFramebuffer() ;
|
|
20
|
+
const renderPassDescriptor = this.getRenderPassDescriptor(framebuffer);
|
|
21
|
+
log.groupCollapsed(1, `new WebGPURenderPass(${this.id})`)();
|
|
22
|
+
log.probe(1, JSON.stringify(renderPassDescriptor, null, 2))();
|
|
23
|
+
log.groupEnd(1)();
|
|
21
24
|
this.handle = this.props.handle || device.commandEncoder.beginRenderPass(renderPassDescriptor);
|
|
22
25
|
this.handle.label = this.props.id;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
destroy() {}
|
|
28
|
+
override destroy(): void {}
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
this.handle.
|
|
30
|
+
end(): void {
|
|
31
|
+
this.handle.end();
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
setPipeline(pipeline: RenderPipeline): void {
|
|
@@ -35,8 +38,11 @@ export default class WebGPURenderPass extends RenderPass {
|
|
|
35
38
|
|
|
36
39
|
/** Sets an array of bindings (uniform buffers, samplers, textures, ...) */
|
|
37
40
|
setBindings(bindings: Record<string, Binding>): void {
|
|
38
|
-
this.pipeline
|
|
39
|
-
|
|
41
|
+
this.pipeline?.setBindings(bindings);
|
|
42
|
+
const bindGroup = this.pipeline?._getBindGroup();
|
|
43
|
+
if (bindGroup) {
|
|
44
|
+
this.handle.setBindGroup(0, bindGroup);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
setIndexBuffer(
|
|
@@ -71,8 +77,8 @@ export default class WebGPURenderPass extends RenderPass {
|
|
|
71
77
|
);
|
|
72
78
|
} else {
|
|
73
79
|
this.handle.draw(
|
|
74
|
-
options.vertexCount,
|
|
75
|
-
options.instanceCount,
|
|
80
|
+
options.vertexCount || 0,
|
|
81
|
+
options.instanceCount || 1,
|
|
76
82
|
options.firstIndex,
|
|
77
83
|
options.firstInstance
|
|
78
84
|
);
|
|
@@ -125,4 +131,54 @@ export default class WebGPURenderPass extends RenderPass {
|
|
|
125
131
|
// endPipelineStatisticsQuery(querySet: GPUQuerySet, queryIndex: number): void;
|
|
126
132
|
|
|
127
133
|
// executeBundles(bundles: Iterable<GPURenderBundle>): void;
|
|
134
|
+
|
|
135
|
+
// INTERNAL
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Partial render pass descriptor. Used by WebGPURenderPass.
|
|
139
|
+
* @returns attachments fields of a renderpass descriptor.
|
|
140
|
+
*/
|
|
141
|
+
protected getRenderPassDescriptor(framebuffer: Framebuffer): GPURenderPassDescriptor {
|
|
142
|
+
const renderPassDescriptor: GPURenderPassDescriptor = {
|
|
143
|
+
colorAttachments: []
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
renderPassDescriptor.colorAttachments = framebuffer.colorAttachments.map(colorAttachment => ({
|
|
147
|
+
// clear values
|
|
148
|
+
loadOp: this.props.clearColor !== false ? 'clear' : 'load',
|
|
149
|
+
colorClearValue: this.props.clearColor || [0, 0, 0, 0],
|
|
150
|
+
storeOp: this.props.discard? 'discard': 'store',
|
|
151
|
+
// ...colorAttachment,
|
|
152
|
+
view: (colorAttachment as WebGPUTexture).handle.createView()
|
|
153
|
+
}));
|
|
154
|
+
|
|
155
|
+
if (framebuffer.depthStencilAttachment) {
|
|
156
|
+
renderPassDescriptor.depthStencilAttachment = {
|
|
157
|
+
view: (framebuffer.depthStencilAttachment as WebGPUTexture).handle.createView()
|
|
158
|
+
};
|
|
159
|
+
const {depthStencilAttachment} = renderPassDescriptor;
|
|
160
|
+
|
|
161
|
+
// DEPTH
|
|
162
|
+
if (this.props.depthReadOnly) {
|
|
163
|
+
depthStencilAttachment.depthReadOnly = true;
|
|
164
|
+
}
|
|
165
|
+
depthStencilAttachment.depthClearValue = this.props.clearDepth || 0;
|
|
166
|
+
|
|
167
|
+
// WebGPU only wants us to set these parameters if the texture format actually has a depth aspect
|
|
168
|
+
const hasDepthAspect = true;
|
|
169
|
+
if (hasDepthAspect) {
|
|
170
|
+
depthStencilAttachment.depthLoadOp = this.props.clearDepth !== false ? 'clear' : 'load';
|
|
171
|
+
depthStencilAttachment.depthStoreOp = 'store'; // TODO - support 'discard'?
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// WebGPU only wants us to set these parameters if the texture format actually has a stencil aspect
|
|
175
|
+
const hasStencilAspect = false;
|
|
176
|
+
if (hasStencilAspect) {
|
|
177
|
+
depthStencilAttachment.stencilLoadOp = this.props.clearStencil !== false ? 'clear' : 'load';
|
|
178
|
+
depthStencilAttachment.stencilStoreOp = 'store'; // TODO - support 'discard'?
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return renderPassDescriptor;
|
|
183
|
+
}
|
|
128
184
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// luma.gl MIT license
|
|
2
|
+
|
|
3
|
+
import type {TypedArray, Binding, UniformValue, RenderPass} from '@luma.gl/core';
|
|
4
|
+
import {Buffer, RenderPipeline, RenderPipelineProps, cast, log, isObjectEmpty} from '@luma.gl/core';
|
|
3
5
|
import {applyParametersToRenderPipelineDescriptor} from '../helpers/webgpu-parameters';
|
|
4
6
|
import {getWebGPUTextureFormat} from '../helpers/convert-texture-format';
|
|
5
7
|
import {getBindGroup} from '../helpers/get-bind-group';
|
|
@@ -8,49 +10,52 @@ import {getVertexBufferLayout, getBufferSlots} from '../helpers/get-vertex-buffe
|
|
|
8
10
|
// import {mapAccessorToWebGPUFormat} from './helpers/accessor-to-format';
|
|
9
11
|
// import type {BufferAccessors} from './webgpu-pipeline';
|
|
10
12
|
|
|
11
|
-
import type WebGPUDevice from '../webgpu-device';
|
|
12
|
-
import type WebGPUBuffer from './webgpu-buffer';
|
|
13
|
-
import type WebGPUShader from './webgpu-shader';
|
|
14
|
-
import type WebGPURenderPass from './webgpu-render-pass';
|
|
13
|
+
import type {WebGPUDevice} from '../webgpu-device';
|
|
14
|
+
import type {WebGPUBuffer} from './webgpu-buffer';
|
|
15
|
+
import type {WebGPUShader} from './webgpu-shader';
|
|
16
|
+
import type {WebGPURenderPass} from './webgpu-render-pass';
|
|
15
17
|
|
|
16
18
|
// RENDER PIPELINE
|
|
17
19
|
|
|
18
20
|
/** Creates a new render pipeline when parameters change */
|
|
19
|
-
export
|
|
21
|
+
export class WebGPURenderPipeline extends RenderPipeline {
|
|
20
22
|
device: WebGPUDevice;
|
|
21
23
|
handle: GPURenderPipeline;
|
|
22
24
|
|
|
25
|
+
vs: WebGPUShader;
|
|
26
|
+
fs: WebGPUShader | null = null;
|
|
27
|
+
|
|
23
28
|
private _bufferSlots: Record<string, number>;
|
|
24
29
|
private _buffers: Buffer[];
|
|
25
|
-
private _indexBuffer: WebGPUBuffer;
|
|
30
|
+
private _indexBuffer: WebGPUBuffer | null = null;
|
|
26
31
|
// private _firstIndex: number;
|
|
27
32
|
// private _lastIndex: number;
|
|
28
33
|
|
|
29
34
|
/** For internal use to create BindGroups */
|
|
30
|
-
private _bindGroupLayout: GPUBindGroupLayout;
|
|
31
|
-
private _bindGroup: GPUBindGroup = null;
|
|
35
|
+
private _bindGroupLayout: GPUBindGroupLayout | null = null;
|
|
36
|
+
private _bindGroup: GPUBindGroup | null = null;
|
|
32
37
|
|
|
33
38
|
constructor(device: WebGPUDevice, props: RenderPipelineProps) {
|
|
34
39
|
super(device, props);
|
|
35
40
|
this.device = device;
|
|
36
|
-
this.handle =
|
|
41
|
+
this.handle = this.props.handle as GPURenderPipeline;
|
|
42
|
+
if (!this.handle) {
|
|
43
|
+
const descriptor = this._getRenderPipelineDescriptor();
|
|
44
|
+
log.groupCollapsed(1, `new WebGPURenderPipeline(${this.id})`)();
|
|
45
|
+
log.probe(1, JSON.stringify(descriptor, null, 2))();
|
|
46
|
+
log.groupEnd(1)();
|
|
47
|
+
this.handle = this.device.handle.createRenderPipeline(descriptor);
|
|
48
|
+
}
|
|
37
49
|
this.handle.label = this.props.id;
|
|
38
50
|
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
41
|
-
this._bindGroupLayout = this.handle.getBindGroupLayout(0);
|
|
42
|
-
}
|
|
51
|
+
this.vs = cast<WebGPUShader>(props.vs);
|
|
52
|
+
this.fs = cast<WebGPUShader>(props.fs);
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const renderPipeline = this.device.handle.createRenderPipeline(descriptor);
|
|
47
|
-
log.groupCollapsed(1, `new WebGPRenderPipeline(${this.id})`)();
|
|
48
|
-
log.log(1, JSON.stringify(descriptor, null, 2))();
|
|
49
|
-
log.groupEnd(1)();
|
|
50
|
-
return renderPipeline;
|
|
54
|
+
this._bufferSlots = getBufferSlots(this.props.shaderLayout, this.props.bufferLayout);
|
|
55
|
+
this._buffers = new Array<Buffer>(Object.keys(this._bufferSlots).length).fill(null);
|
|
51
56
|
}
|
|
52
57
|
|
|
53
|
-
destroy() {
|
|
58
|
+
override destroy(): void {
|
|
54
59
|
// WebGPURenderPipeline has no destroy method.
|
|
55
60
|
}
|
|
56
61
|
|
|
@@ -77,21 +82,29 @@ export default class WebGPURenderPipeline extends RenderPipeline {
|
|
|
77
82
|
// }
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
|
|
85
|
+
setConstantAttributes(attributes: Record<string, TypedArray>): void {
|
|
86
|
+
throw new Error('not implemented');
|
|
87
|
+
}
|
|
88
|
+
|
|
81
89
|
setBindings(bindings: Record<string, Binding>): void {
|
|
82
90
|
if (!isObjectEmpty(this.props.bindings)) {
|
|
91
|
+
// Do we want to save things on CPU side?
|
|
83
92
|
Object.assign(this.props.bindings, bindings);
|
|
93
|
+
|
|
94
|
+
// Get hold of the bind group layout. We don't want to do this unless we know there is at least one bind group
|
|
95
|
+
this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
|
|
96
|
+
|
|
84
97
|
// Set up the bindings
|
|
85
98
|
this._bindGroup = getBindGroup(
|
|
86
99
|
this.device.handle,
|
|
87
100
|
this._bindGroupLayout,
|
|
88
|
-
this.props.
|
|
101
|
+
this.props.shaderLayout,
|
|
89
102
|
this.props.bindings
|
|
90
103
|
);
|
|
91
104
|
}
|
|
92
105
|
}
|
|
93
106
|
|
|
94
|
-
setUniforms(uniforms: Record<string,
|
|
107
|
+
setUniforms(uniforms: Record<string, UniformValue>): void {
|
|
95
108
|
if (!isObjectEmpty(uniforms)) {
|
|
96
109
|
throw new Error('WebGPU does not support uniforms');
|
|
97
110
|
}
|
|
@@ -107,13 +120,15 @@ export default class WebGPURenderPipeline extends RenderPipeline {
|
|
|
107
120
|
return this._bindGroup;
|
|
108
121
|
}
|
|
109
122
|
|
|
110
|
-
/**
|
|
123
|
+
/**
|
|
124
|
+
* Populate the complex WebGPU GPURenderPipelineDescriptor
|
|
125
|
+
*/
|
|
111
126
|
protected _getRenderPipelineDescriptor() {
|
|
112
127
|
// Set up the vertex stage
|
|
113
128
|
const vertex: GPUVertexState = {
|
|
114
129
|
module: cast<WebGPUShader>(this.props.vs).handle,
|
|
115
130
|
entryPoint: this.props.vsEntryPoint || 'main',
|
|
116
|
-
buffers: getVertexBufferLayout(this.props.
|
|
131
|
+
buffers: getVertexBufferLayout(this.props.shaderLayout, this.props.bufferLayout)
|
|
117
132
|
};
|
|
118
133
|
|
|
119
134
|
// Set up the fragment stage
|
|
@@ -124,19 +139,29 @@ export default class WebGPURenderPipeline extends RenderPipeline {
|
|
|
124
139
|
entryPoint: this.props.fsEntryPoint || 'main',
|
|
125
140
|
targets: [
|
|
126
141
|
{
|
|
127
|
-
|
|
142
|
+
// TODO exclamation mark hack!
|
|
143
|
+
format: getWebGPUTextureFormat(this.device?.canvasContext?.format)
|
|
128
144
|
}
|
|
129
145
|
]
|
|
130
146
|
};
|
|
131
147
|
}
|
|
132
148
|
|
|
149
|
+
// WebGPU has more restrictive topology support than WebGL
|
|
150
|
+
switch (this.props.topology) {
|
|
151
|
+
case 'triangle-fan-webgl':
|
|
152
|
+
case 'line-loop-webgl':
|
|
153
|
+
throw new Error(`WebGPU does not support primitive topology ${this.props.topology}`);
|
|
154
|
+
default:
|
|
155
|
+
}
|
|
156
|
+
|
|
133
157
|
// Create a partially populated descriptor
|
|
134
|
-
|
|
158
|
+
const descriptor: GPURenderPipelineDescriptor = {
|
|
135
159
|
vertex,
|
|
136
160
|
fragment,
|
|
137
161
|
primitive: {
|
|
138
162
|
topology: this.props.topology
|
|
139
|
-
}
|
|
163
|
+
},
|
|
164
|
+
layout: 'auto'
|
|
140
165
|
};
|
|
141
166
|
|
|
142
167
|
// Set parameters on the descriptor
|
|
@@ -155,15 +180,16 @@ export default class WebGPURenderPipeline extends RenderPipeline {
|
|
|
155
180
|
firstInstance?: number;
|
|
156
181
|
baseVertex?: number;
|
|
157
182
|
}): void {
|
|
158
|
-
const webgpuRenderPass =
|
|
183
|
+
const webgpuRenderPass: WebGPURenderPass =
|
|
159
184
|
cast<WebGPURenderPass>(options.renderPass) || this.device.getDefaultRenderPass();
|
|
160
185
|
|
|
161
186
|
// Set pipeline
|
|
162
187
|
webgpuRenderPass.handle.setPipeline(this.handle);
|
|
163
188
|
|
|
164
189
|
// Set bindings (uniform buffers, textures etc)
|
|
165
|
-
|
|
166
|
-
|
|
190
|
+
const bindGroup = this._getBindGroup();
|
|
191
|
+
if (bindGroup) {
|
|
192
|
+
webgpuRenderPass.handle.setBindGroup(0, bindGroup);
|
|
167
193
|
}
|
|
168
194
|
|
|
169
195
|
// Set attributes
|
|
@@ -180,9 +206,8 @@ export default class WebGPURenderPipeline extends RenderPipeline {
|
|
|
180
206
|
);
|
|
181
207
|
} else {
|
|
182
208
|
webgpuRenderPass.handle.draw(
|
|
183
|
-
options.vertexCount,
|
|
184
|
-
options.instanceCount,
|
|
185
|
-
options.firstIndex,
|
|
209
|
+
options.vertexCount || 0,
|
|
210
|
+
options.instanceCount || 1, // If 0, nothing will be drawn
|
|
186
211
|
options.firstInstance
|
|
187
212
|
);
|
|
188
213
|
}
|
|
@@ -197,7 +222,7 @@ export default class WebGPURenderPipeline extends RenderPipeline {
|
|
|
197
222
|
for (let i = 0; i < buffers.length; ++i) {
|
|
198
223
|
const buffer = cast<WebGPUBuffer>(buffers[i]);
|
|
199
224
|
if (!buffer) {
|
|
200
|
-
const attribute = this.props.
|
|
225
|
+
const attribute = this.props.shaderLayout.attributes.find(
|
|
201
226
|
(attribute) => attribute.location === i
|
|
202
227
|
);
|
|
203
228
|
throw new Error(
|
|
@@ -209,7 +234,7 @@ export default class WebGPURenderPipeline extends RenderPipeline {
|
|
|
209
234
|
|
|
210
235
|
// TODO - HANDLE buffer maps
|
|
211
236
|
/*
|
|
212
|
-
for (const [bufferName, attributeMapping] of Object.entries(this.props.
|
|
237
|
+
for (const [bufferName, attributeMapping] of Object.entries(this.props.bufferLayout)) {
|
|
213
238
|
const buffer = cast<WebGPUBuffer>(this.props.attributes[bufferName]);
|
|
214
239
|
if (!buffer) {
|
|
215
240
|
log.warn(`Missing buffer for buffer map ${bufferName}`)();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {Sampler, SamplerProps} from '@luma.gl/
|
|
2
|
-
import type WebGPUDevice from '../webgpu-device';
|
|
1
|
+
import {Sampler, SamplerProps} from '@luma.gl/core';
|
|
2
|
+
import type {WebGPUDevice} from '../webgpu-device';
|
|
3
3
|
|
|
4
4
|
export type WebGPUSamplerProps = SamplerProps & {
|
|
5
5
|
handle?: GPUSampler;
|
|
@@ -8,18 +8,25 @@ export type WebGPUSamplerProps = SamplerProps & {
|
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
|
-
export
|
|
11
|
+
export class WebGPUSampler extends Sampler {
|
|
12
12
|
readonly device: WebGPUDevice;
|
|
13
13
|
readonly handle: GPUSampler;
|
|
14
14
|
|
|
15
15
|
constructor(device: WebGPUDevice, props: WebGPUSamplerProps) {
|
|
16
16
|
super(device, props);
|
|
17
17
|
this.device = device;
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
// Prepare sampler props
|
|
20
|
+
const samplerProps: Partial<WebGPUSamplerProps> = {...this.props};
|
|
21
|
+
if (samplerProps.type !== 'comparison-sampler') {
|
|
22
|
+
delete samplerProps.compare;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.handle = this.handle || this.device.handle.createSampler(samplerProps);
|
|
19
26
|
this.handle.label = this.props.id;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
destroy(): void {
|
|
29
|
+
override destroy(): void {
|
|
23
30
|
// this.handle.destroy();
|
|
24
31
|
}
|
|
25
32
|
}
|