@luma.gl/webgpu 9.0.0-alpha.30 → 9.0.0-alpha.31

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.
@@ -1,4 +1,4 @@
1
- import type {ShaderLayout, BufferMapping, AttributeLayout, VertexFormat} from '@luma.gl/core';
1
+ import type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';
2
2
  import {decodeVertexFormat} from '@luma.gl/core';
3
3
 
4
4
  /** Throw error on any WebGL-only vertex formats */
@@ -13,15 +13,18 @@ function getWebGPUVertexFormat(format: VertexFormat): GPUVertexFormat {
13
13
  * Build a WebGPU vertex buffer layout intended for use in a GPURenderPassDescriptor.
14
14
  * Converts luma.gl attribute definitions to a WebGPU GPUVertexBufferLayout[] array
15
15
  * @param layout
16
- * @param bufferMap The buffer map is optional
16
+ * @param bufferLayout The buffer map is optional
17
17
  * @returns WebGPU layout intended for a GPURenderPassDescriptor.
18
18
  */
19
- export function getVertexBufferLayout(layout: ShaderLayout, bufferMap: BufferMapping[]): GPUVertexBufferLayout[] {
19
+ export function getVertexBufferLayout(
20
+ shaderLayout: ShaderLayout,
21
+ bufferLayout: BufferLayout[]
22
+ ): GPUVertexBufferLayout[] {
20
23
  const vertexBufferLayouts: GPUVertexBufferLayout[] = [];
21
24
  const usedAttributes = new Set<string>();
22
25
 
23
- // First handle any buffers mentioned in `bufferMapping`
24
- for (const mapping of bufferMap) {
26
+ // First handle any buffers mentioned in `bufferLayout`
27
+ for (const mapping of bufferLayout) {
25
28
  // Build vertex attributes for one buffer
26
29
  const vertexAttributes: GPUVertexAttribute[] = [];
27
30
 
@@ -31,28 +34,28 @@ export function getVertexBufferLayout(layout: ShaderLayout, bufferMap: BufferMap
31
34
  const byteOffset = mapping.byteOffset || 0;
32
35
 
33
36
  // interleaved mapping {..., attributes: [{...}, ...]}
34
- if ('attributes' in mapping) {
35
- // const arrayStride = mapping.byteStride; TODO
37
+ if (mapping.attributes) {
38
+ // const arrayStride = mapping.byteStride; TODO
36
39
  for (const interleaved of mapping.attributes) {
37
- const attributeLayout = findAttributeLayout(layout, interleaved.name, usedAttributes);
40
+ const attributeLayout = findAttributeLayout(shaderLayout, interleaved.name, usedAttributes);
38
41
 
39
42
  stepMode = attributeLayout.stepMode || 'vertex';
40
43
  vertexAttributes.push({
41
- format: getWebGPUVertexFormat(attributeLayout.format),
44
+ format: getWebGPUVertexFormat(interleaved.format || mapping.format),
42
45
  offset: byteOffset + byteStride,
43
46
  shaderLocation: attributeLayout.location
44
47
  });
45
48
 
46
- byteStride += decodeVertexFormat(attributeLayout.format).byteLength;
49
+ byteStride += decodeVertexFormat(mapping.format).byteLength;
47
50
  }
48
51
  // non-interleaved mapping (just set offset and stride)
49
52
  } else {
50
- const attributeLayout = findAttributeLayout(layout, mapping.name, usedAttributes);
51
- byteStride = decodeVertexFormat(attributeLayout.format).byteLength;
53
+ const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);
54
+ byteStride = decodeVertexFormat(mapping.format).byteLength;
52
55
 
53
56
  stepMode = attributeLayout.stepMode || 'vertex';
54
57
  vertexAttributes.push({
55
- format: getWebGPUVertexFormat(attributeLayout.format),
58
+ format: getWebGPUVertexFormat(mapping.format),
56
59
  offset: byteOffset,
57
60
  shaderLocation: attributeLayout.location
58
61
  });
@@ -66,17 +69,19 @@ export function getVertexBufferLayout(layout: ShaderLayout, bufferMap: BufferMap
66
69
  });
67
70
  }
68
71
 
69
- // Add any non-mapped attributes
70
- for (const attribute of layout.attributes) {
72
+ // Add any non-mapped attributes - TODO - avoid hardcoded types
73
+ for (const attribute of shaderLayout.attributes) {
71
74
  if (!usedAttributes.has(attribute.name)) {
72
75
  vertexBufferLayouts.push({
73
- arrayStride: decodeVertexFormat(attribute.format).byteLength,
76
+ arrayStride: decodeVertexFormat('float32x3').byteLength,
74
77
  stepMode: attribute.stepMode || 'vertex',
75
- attributes: [{
76
- format: getWebGPUVertexFormat(attribute.format),
77
- offset: 0,
78
- shaderLocation: attribute.location
79
- }]
78
+ attributes: [
79
+ {
80
+ format: getWebGPUVertexFormat('float32x3'),
81
+ offset: 0,
82
+ shaderLocation: attribute.location
83
+ }
84
+ ]
80
85
  });
81
86
  }
82
87
  }
@@ -84,13 +89,16 @@ export function getVertexBufferLayout(layout: ShaderLayout, bufferMap: BufferMap
84
89
  return vertexBufferLayouts;
85
90
  }
86
91
 
87
- export function getBufferSlots(layout: ShaderLayout, bufferMap: BufferMapping[]): Record<string, number> {
92
+ export function getBufferSlots(
93
+ shaderLayout: ShaderLayout,
94
+ bufferLayout: BufferLayout[]
95
+ ): Record<string, number> {
88
96
  const usedAttributes = new Set<string>();
89
97
  let bufferSlot = 0;
90
98
  const bufferSlots: Record<string, number> = {};
91
99
 
92
- // First handle any buffers mentioned in `bufferMapping`
93
- for (const mapping of bufferMap) {
100
+ // First handle any buffers mentioned in `bufferLayout`
101
+ for (const mapping of bufferLayout) {
94
102
  // interleaved mapping {..., attributes: [{...}, ...]}
95
103
  if ('attributes' in mapping) {
96
104
  for (const interleaved of mapping.attributes) {
@@ -104,7 +112,7 @@ export function getBufferSlots(layout: ShaderLayout, bufferMap: BufferMapping[])
104
112
  }
105
113
 
106
114
  // Add any non-mapped attributes
107
- for (const attribute of layout.attributes) {
115
+ for (const attribute of shaderLayout.attributes) {
108
116
  if (!usedAttributes.has(attribute.name)) {
109
117
  bufferSlots[attribute.name] = bufferSlot++;
110
118
  }
@@ -118,8 +126,12 @@ export function getBufferSlots(layout: ShaderLayout, bufferMap: BufferMapping[])
118
126
  * @throws if name is not in ShaderLayout
119
127
  * @throws if name has already been referenced
120
128
  */
121
- function findAttributeLayout(layout: ShaderLayout, name: string, attributeNames: Set<string>): AttributeLayout {
122
- const attribute = layout.attributes.find(attribute => attribute.name === name);
129
+ function findAttributeLayout(
130
+ shaderLayout: ShaderLayout,
131
+ name: string,
132
+ attributeNames: Set<string>
133
+ ): AttributeDeclaration {
134
+ const attribute = shaderLayout.attributes.find(attribute => attribute.name === name);
123
135
  if (!attribute) {
124
136
  throw new Error(`Unknown attribute ${name}`);
125
137
  }
@@ -13,7 +13,7 @@ export class WebGPUCommandEncoder extends CommandEncoder {
13
13
  readonly handle: GPUCommandEncoder;
14
14
 
15
15
  constructor(device: WebGPUDevice, props: CommandEncoderProps) {
16
- super(props);
16
+ super(device, props);
17
17
  this.device = device;
18
18
  this.handle = props.handle || this.device.handle.createCommandEncoder({
19
19
  // TODO was this removed in standard?
@@ -44,7 +44,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
44
44
  this.vs = cast<WebGPUShader>(props.vs);
45
45
  this.fs = cast<WebGPUShader>(props.fs);
46
46
 
47
- this._bufferSlots = getBufferSlots(this.props.layout, this.props.bufferMap);
47
+ this._bufferSlots = getBufferSlots(this.props.shaderLayout, this.props.bufferLayout);
48
48
  this._buffers = new Array<Buffer>(Object.keys(this._bufferSlots).length).fill(null);
49
49
  this._bindGroupLayout = this.handle.getBindGroupLayout(0);
50
50
  }
@@ -87,7 +87,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
87
87
 
88
88
  /** Constant attributes are not available in WebGPU */
89
89
  setConstantAttributes(attributes: Record<string, TypedArray>): void {
90
- console.error('not implemented');
90
+ throw new Error('not implemented');
91
91
  }
92
92
 
93
93
  /** Set the bindings */
@@ -98,7 +98,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
98
98
  this._bindGroup = getBindGroup(
99
99
  this.device.handle,
100
100
  this._bindGroupLayout,
101
- this.props.layout,
101
+ this.props.shaderLayout,
102
102
  this.props.bindings
103
103
  );
104
104
  }
@@ -126,7 +126,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
126
126
  const vertex: GPUVertexState = {
127
127
  module: cast<WebGPUShader>(this.props.vs).handle,
128
128
  entryPoint: this.props.vsEntryPoint || 'main',
129
- buffers: getVertexBufferLayout(this.props.layout, this.props.bufferMap)
129
+ buffers: getVertexBufferLayout(this.props.shaderLayout, this.props.bufferLayout)
130
130
  };
131
131
 
132
132
  // Set up the fragment stage
@@ -221,7 +221,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
221
221
  for (let i = 0; i < buffers.length; ++i) {
222
222
  const buffer = cast<WebGPUBuffer>(buffers[i]);
223
223
  if (!buffer) {
224
- const attribute = this.props.layout.attributes.find(
224
+ const attribute = this.props.shaderLayout.attributes.find(
225
225
  (attribute) => attribute.location === i
226
226
  );
227
227
  throw new Error(
@@ -233,7 +233,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
233
233
 
234
234
  // TODO - HANDLE buffer maps
235
235
  /*
236
- for (const [bufferName, attributeMapping] of Object.entries(this.props.bufferMap)) {
236
+ for (const [bufferName, attributeMapping] of Object.entries(this.props.bufferLayout)) {
237
237
  const buffer = cast<WebGPUBuffer>(this.props.attributes[bufferName]);
238
238
  if (!buffer) {
239
239
  log.warn(`Missing buffer for buffer map ${bufferName}`)();