@luma.gl/webgpu 9.1.9 → 9.2.0-alpha.2

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.
Files changed (100) hide show
  1. package/dist/adapter/helpers/accessor-to-format.js +1 -0
  2. package/dist/adapter/helpers/accessor-to-format.js.map +1 -1
  3. package/dist/adapter/helpers/get-bind-group.d.ts +3 -1
  4. package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
  5. package/dist/adapter/helpers/get-bind-group.js +28 -10
  6. package/dist/adapter/helpers/get-bind-group.js.map +1 -1
  7. package/dist/adapter/helpers/get-vertex-buffer-layout.js +5 -5
  8. package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -1
  9. package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
  10. package/dist/adapter/helpers/webgpu-parameters.js +89 -75
  11. package/dist/adapter/helpers/webgpu-parameters.js.map +1 -1
  12. package/dist/adapter/resources/webgpu-buffer.d.ts +13 -16
  13. package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
  14. package/dist/adapter/resources/webgpu-buffer.js +132 -93
  15. package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
  16. package/dist/adapter/resources/webgpu-command-buffer.d.ts +10 -0
  17. package/dist/adapter/resources/webgpu-command-buffer.d.ts.map +1 -0
  18. package/dist/adapter/resources/webgpu-command-buffer.js +18 -0
  19. package/dist/adapter/resources/webgpu-command-buffer.js.map +1 -0
  20. package/dist/adapter/resources/webgpu-command-encoder.d.ts +12 -5
  21. package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
  22. package/dist/adapter/resources/webgpu-command-encoder.js +28 -5
  23. package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
  24. package/dist/adapter/resources/webgpu-compute-pass.js +1 -1
  25. package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
  26. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +2 -2
  27. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
  28. package/dist/adapter/resources/webgpu-compute-pipeline.js.map +1 -1
  29. package/dist/adapter/resources/webgpu-external-texture.d.ts +2 -2
  30. package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
  31. package/dist/adapter/resources/webgpu-external-texture.js.map +1 -1
  32. package/dist/adapter/resources/webgpu-framebuffer.d.ts +3 -2
  33. package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
  34. package/dist/adapter/resources/webgpu-framebuffer.js +1 -0
  35. package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
  36. package/dist/adapter/resources/webgpu-pipeline-layout.d.ts +2 -2
  37. package/dist/adapter/resources/webgpu-pipeline-layout.d.ts.map +1 -1
  38. package/dist/adapter/resources/webgpu-pipeline-layout.js +5 -2
  39. package/dist/adapter/resources/webgpu-pipeline-layout.js.map +1 -1
  40. package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
  41. package/dist/adapter/resources/webgpu-render-pass.js +11 -6
  42. package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
  43. package/dist/adapter/resources/webgpu-render-pipeline.d.ts +5 -4
  44. package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
  45. package/dist/adapter/resources/webgpu-render-pipeline.js +33 -20
  46. package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
  47. package/dist/adapter/resources/webgpu-sampler.js +1 -1
  48. package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
  49. package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
  50. package/dist/adapter/resources/webgpu-shader.js +7 -8
  51. package/dist/adapter/resources/webgpu-shader.js.map +1 -1
  52. package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
  53. package/dist/adapter/resources/webgpu-texture-view.js +15 -10
  54. package/dist/adapter/resources/webgpu-texture-view.js.map +1 -1
  55. package/dist/adapter/resources/webgpu-texture.d.ts +4 -37
  56. package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
  57. package/dist/adapter/resources/webgpu-texture.js +97 -126
  58. package/dist/adapter/resources/webgpu-texture.js.map +1 -1
  59. package/dist/adapter/resources/webgpu-vertex-array.d.ts +2 -2
  60. package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -1
  61. package/dist/adapter/resources/webgpu-vertex-array.js +2 -2
  62. package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -1
  63. package/dist/adapter/webgpu-adapter.d.ts +2 -3
  64. package/dist/adapter/webgpu-adapter.d.ts.map +1 -1
  65. package/dist/adapter/webgpu-adapter.js +54 -43
  66. package/dist/adapter/webgpu-adapter.js.map +1 -1
  67. package/dist/adapter/webgpu-canvas-context.d.ts +7 -15
  68. package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
  69. package/dist/adapter/webgpu-canvas-context.js +50 -72
  70. package/dist/adapter/webgpu-canvas-context.js.map +1 -1
  71. package/dist/adapter/webgpu-device.d.ts +16 -27
  72. package/dist/adapter/webgpu-device.d.ts.map +1 -1
  73. package/dist/adapter/webgpu-device.js +48 -65
  74. package/dist/adapter/webgpu-device.js.map +1 -1
  75. package/dist/dist.dev.js +1919 -1520
  76. package/dist/dist.min.js +6 -5
  77. package/dist/index.cjs +1749 -1397
  78. package/dist/index.cjs.map +4 -4
  79. package/package.json +3 -3
  80. package/src/adapter/helpers/get-bind-group.ts +31 -11
  81. package/src/adapter/helpers/get-vertex-buffer-layout.ts +5 -5
  82. package/src/adapter/helpers/webgpu-parameters.ts +114 -102
  83. package/src/adapter/resources/webgpu-buffer.ts +163 -102
  84. package/src/adapter/resources/webgpu-command-buffer.ts +24 -0
  85. package/src/adapter/resources/webgpu-command-encoder.ts +34 -4
  86. package/src/adapter/resources/webgpu-compute-pass.ts +1 -1
  87. package/src/adapter/resources/webgpu-compute-pipeline.ts +2 -2
  88. package/src/adapter/resources/webgpu-external-texture.ts +2 -2
  89. package/src/adapter/resources/webgpu-framebuffer.ts +3 -2
  90. package/src/adapter/resources/webgpu-pipeline-layout.ts +8 -3
  91. package/src/adapter/resources/webgpu-render-pass.ts +11 -6
  92. package/src/adapter/resources/webgpu-render-pipeline.ts +39 -24
  93. package/src/adapter/resources/webgpu-sampler.ts +1 -1
  94. package/src/adapter/resources/webgpu-shader.ts +11 -8
  95. package/src/adapter/resources/webgpu-texture-view.ts +14 -8
  96. package/src/adapter/resources/webgpu-texture.ts +106 -186
  97. package/src/adapter/resources/webgpu-vertex-array.ts +2 -2
  98. package/src/adapter/webgpu-adapter.ts +72 -58
  99. package/src/adapter/webgpu-canvas-context.ts +62 -82
  100. package/src/adapter/webgpu-device.ts +66 -105
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma.gl/webgpu",
3
- "version": "9.1.9",
3
+ "version": "9.2.0-alpha.2",
4
4
  "description": "WebGPU adapter for the luma.gl core API",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,11 +37,11 @@
37
37
  "prepublishOnly": "npm run build-minified-bundle && npm run build-dev-bundle"
38
38
  },
39
39
  "peerDependencies": {
40
- "@luma.gl/core": "^9.1.0"
40
+ "@luma.gl/core": "9.2.0-alpha.1"
41
41
  },
42
42
  "dependencies": {
43
43
  "@probe.gl/env": "^4.0.8",
44
44
  "@webgpu/types": "^0.1.34"
45
45
  },
46
- "gitHead": "2d0d93f337120d670e03bd2d5141d90d0d582b44"
46
+ "gitHead": "dc1e71675ea19a4afbb59d3b9dcd3b01deea3cae"
47
47
  }
@@ -34,22 +34,30 @@ export function getBindGroup(
34
34
  bindings: Record<string, Binding>
35
35
  ): GPUBindGroup {
36
36
  const entries = getBindGroupEntries(bindings, shaderLayout);
37
- return device.createBindGroup({
37
+ device.pushErrorScope('validation');
38
+ const bindGroup = device.createBindGroup({
38
39
  layout: bindGroupLayout,
39
40
  entries
40
41
  });
42
+ device.popErrorScope().then((error: GPUError | null) => {
43
+ if (error) {
44
+ log.error(`bindGroup creation: ${error.message}`, bindGroup)();
45
+ }
46
+ });
47
+ return bindGroup;
41
48
  }
42
49
 
43
50
  export function getShaderLayoutBinding(
44
51
  shaderLayout: ComputeShaderLayout,
45
- bindingName: string
52
+ bindingName: string,
53
+ options?: {ignoreWarnings?: boolean}
46
54
  ): BindingDeclaration | null {
47
55
  const bindingLayout = shaderLayout.bindings.find(
48
56
  binding =>
49
57
  binding.name === bindingName ||
50
58
  `${binding.name.toLocaleLowerCase()}uniforms` === bindingName.toLocaleLowerCase()
51
59
  );
52
- if (!bindingLayout) {
60
+ if (!bindingLayout && !options?.ignoreWarnings) {
53
61
  log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
54
62
  }
55
63
  return bindingLayout || null;
@@ -68,13 +76,23 @@ function getBindGroupEntries(
68
76
  for (const [bindingName, value] of Object.entries(bindings)) {
69
77
  let bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
70
78
  if (bindingLayout) {
71
- entries.push(getBindGroupEntry(value, bindingLayout.location));
79
+ const entry = getBindGroupEntry(value, bindingLayout.location);
80
+ if (entry) {
81
+ entries.push(entry);
82
+ }
72
83
  }
73
84
 
74
85
  // TODO - hack to automatically bind samplers to supplied texture default samplers
75
- bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`);
76
- if (bindingLayout) {
77
- entries.push(getBindGroupEntry(value, bindingLayout.location, {sampler: true}));
86
+ if (value instanceof Texture) {
87
+ bindingLayout = getShaderLayoutBinding(shaderLayout, `${bindingName}Sampler`, {
88
+ ignoreWarnings: true
89
+ });
90
+ if (bindingLayout) {
91
+ const entry = getBindGroupEntry(value, bindingLayout.location, {sampler: true});
92
+ if (entry) {
93
+ entries.push(entry);
94
+ }
95
+ }
78
96
  }
79
97
  }
80
98
 
@@ -85,7 +103,7 @@ function getBindGroupEntry(
85
103
  binding: Binding,
86
104
  index: number,
87
105
  options?: {sampler?: boolean}
88
- ): GPUBindGroupEntry {
106
+ ): GPUBindGroupEntry | null {
89
107
  if (binding instanceof Buffer) {
90
108
  return {
91
109
  binding: index,
@@ -99,7 +117,8 @@ function getBindGroupEntry(
99
117
  binding: index,
100
118
  resource: (binding as WebGPUSampler).handle
101
119
  };
102
- } else if (binding instanceof Texture) {
120
+ }
121
+ if (binding instanceof Texture) {
103
122
  if (options?.sampler) {
104
123
  return {
105
124
  binding: index,
@@ -108,8 +127,9 @@ function getBindGroupEntry(
108
127
  }
109
128
  return {
110
129
  binding: index,
111
- resource: (binding as WebGPUTexture).handle.createView({label: 'bind-group-auto-created'})
130
+ resource: (binding as WebGPUTexture).view.handle
112
131
  };
113
132
  }
114
- throw new Error('invalid binding');
133
+ log.warn(`invalid binding ${name}`, binding);
134
+ return null;
115
135
  }
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';
6
- import {log, decodeVertexFormat} from '@luma.gl/core';
6
+ import {log, getVertexFormatInfo} from '@luma.gl/core';
7
7
  // import {getAttributeInfosFromLayouts} from '@luma.gl/core';
8
8
 
9
9
  /** Throw error on any WebGL-only vertex formats */
@@ -59,7 +59,7 @@ export function getVertexBufferLayout(
59
59
  shaderLocation: location
60
60
  });
61
61
 
62
- byteStride += decodeVertexFormat(format).byteLength;
62
+ byteStride += getVertexFormatInfo(format).byteLength;
63
63
  }
64
64
  // non-interleaved mapping (just set offset and stride)
65
65
  } else {
@@ -67,7 +67,7 @@ export function getVertexBufferLayout(
67
67
  if (!attributeLayout) {
68
68
  continue; // eslint-disable-line no-continue
69
69
  }
70
- byteStride = decodeVertexFormat(format).byteLength;
70
+ byteStride = getVertexFormatInfo(format).byteLength;
71
71
 
72
72
  stepMode =
73
73
  attributeLayout.stepMode ||
@@ -92,7 +92,7 @@ export function getVertexBufferLayout(
92
92
  for (const attribute of shaderLayout.attributes) {
93
93
  if (!usedAttributes.has(attribute.name)) {
94
94
  vertexBufferLayouts.push({
95
- arrayStride: decodeVertexFormat('float32x3').byteLength,
95
+ arrayStride: getVertexFormatInfo('float32x3').byteLength,
96
96
  stepMode:
97
97
  attribute.stepMode || (attribute.name.startsWith('instance') ? 'instance' : 'vertex'),
98
98
  attributes: [
@@ -163,7 +163,7 @@ function findAttributeLayout(
163
163
  ): AttributeDeclaration | null {
164
164
  const attribute = shaderLayout.attributes.find(attribute_ => attribute_.name === name);
165
165
  if (!attribute) {
166
- log.warn(`Unknown attribute ${name}`)();
166
+ log.warn(`Supplied attribute not present in shader layout: ${name}`)();
167
167
  return null;
168
168
  }
169
169
  if (attributeNames) {
@@ -33,56 +33,45 @@ function addDepthStencilBack(descriptor: GPURenderPipelineDescriptor): GPUStenci
33
33
  * Supports for luma.gl's flat parameter space
34
34
  * Populates the corresponding sub-objects in a GPURenderPipelineDescriptor
35
35
  */
36
- // @ts-expect-error
37
36
  export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
38
37
  // RASTERIZATION PARAMETERS
39
38
 
40
- cullMode: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
39
+ cullMode: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
41
40
  descriptor.primitive = descriptor.primitive || {};
42
41
  descriptor.primitive.cullMode = value;
43
42
  },
44
43
 
45
- frontFace: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
44
+ frontFace: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
46
45
  descriptor.primitive = descriptor.primitive || {};
47
46
  descriptor.primitive.frontFace = value;
48
47
  },
49
48
 
50
49
  // DEPTH
51
50
 
52
- depthWriteEnabled: (
53
- parameter: keyof Parameters,
54
- value: any,
55
- descriptor: GPURenderPipelineDescriptor
56
- ) => {
57
- const depthStencil = addDepthStencil(descriptor);
58
- depthStencil.depthWriteEnabled = value;
51
+ depthWriteEnabled: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
52
+ if (value) {
53
+ const depthStencil = addDepthStencil(descriptor);
54
+ depthStencil.depthWriteEnabled = value;
55
+ }
59
56
  },
60
57
 
61
- depthCompare: (
62
- parameter: keyof Parameters,
63
- value: any,
64
- descriptor: GPURenderPipelineDescriptor
65
- ) => {
58
+ depthCompare: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
66
59
  const depthStencil = addDepthStencil(descriptor);
67
60
  depthStencil.depthCompare = value;
68
61
  },
69
62
 
70
- depthFormat: (
71
- parameter: keyof Parameters,
72
- value: any,
73
- descriptor: GPURenderPipelineDescriptor
74
- ) => {
63
+ depthFormat: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
75
64
  const depthStencil = addDepthStencil(descriptor);
76
65
  depthStencil.format = value;
77
66
  },
78
67
 
79
- depthBias: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
68
+ depthBias: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
80
69
  const depthStencil = addDepthStencil(descriptor);
81
70
  depthStencil.depthBias = value;
82
71
  },
83
72
 
84
73
  depthBiasSlopeScale: (
85
- parameter: keyof Parameters,
74
+ _: keyof Parameters,
86
75
  value: any,
87
76
  descriptor: GPURenderPipelineDescriptor
88
77
  ) => {
@@ -90,40 +79,24 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
90
79
  depthStencil.depthBiasSlopeScale = value;
91
80
  },
92
81
 
93
- depthBiasClamp: (
94
- parameter: keyof Parameters,
95
- value: any,
96
- descriptor: GPURenderPipelineDescriptor
97
- ) => {
82
+ depthBiasClamp: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
98
83
  const depthStencil = addDepthStencil(descriptor);
99
84
  depthStencil.depthBiasClamp = value;
100
85
  },
101
86
 
102
87
  // STENCIL
103
88
 
104
- stencilReadMask: (
105
- parameter: keyof Parameters,
106
- value: any,
107
- descriptor: GPURenderPipelineDescriptor
108
- ) => {
89
+ stencilReadMask: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
109
90
  const depthStencil = addDepthStencil(descriptor);
110
91
  depthStencil.stencilReadMask = value;
111
92
  },
112
93
 
113
- stencilWriteMask: (
114
- parameter: keyof Parameters,
115
- value: any,
116
- descriptor: GPURenderPipelineDescriptor
117
- ) => {
94
+ stencilWriteMask: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
118
95
  const depthStencil = addDepthStencil(descriptor);
119
96
  depthStencil.stencilWriteMask = value;
120
97
  },
121
98
 
122
- stencilCompare: (
123
- parameter: keyof Parameters,
124
- value: any,
125
- descriptor: GPURenderPipelineDescriptor
126
- ) => {
99
+ stencilCompare: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
127
100
  const stencilFront = addDepthStencilFront(descriptor);
128
101
  const stencilBack = addDepthStencilBack(descriptor);
129
102
  stencilFront.compare = value;
@@ -131,7 +104,7 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
131
104
  },
132
105
 
133
106
  stencilPassOperation: (
134
- parameter: keyof Parameters,
107
+ _: keyof Parameters,
135
108
  value: any,
136
109
  descriptor: GPURenderPipelineDescriptor
137
110
  ) => {
@@ -142,7 +115,7 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
142
115
  },
143
116
 
144
117
  stencilFailOperation: (
145
- parameter: keyof Parameters,
118
+ _: keyof Parameters,
146
119
  value: any,
147
120
  descriptor: GPURenderPipelineDescriptor
148
121
  ) => {
@@ -153,7 +126,7 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
153
126
  },
154
127
 
155
128
  stencilDepthFailOperation: (
156
- parameter: keyof Parameters,
129
+ _: keyof Parameters,
157
130
  value: any,
158
131
  descriptor: GPURenderPipelineDescriptor
159
132
  ) => {
@@ -165,26 +138,18 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
165
138
 
166
139
  // MULTISAMPLE
167
140
 
168
- sampleCount: (
169
- parameter: keyof Parameters,
170
- value: any,
171
- descriptor: GPURenderPipelineDescriptor
172
- ) => {
141
+ sampleCount: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
173
142
  descriptor.multisample = descriptor.multisample || {};
174
143
  descriptor.multisample.count = value;
175
144
  },
176
145
 
177
- sampleMask: (
178
- parameter: keyof Parameters,
179
- value: any,
180
- descriptor: GPURenderPipelineDescriptor
181
- ) => {
146
+ sampleMask: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
182
147
  descriptor.multisample = descriptor.multisample || {};
183
148
  descriptor.multisample.mask = value;
184
149
  },
185
150
 
186
151
  sampleAlphaToCoverageEnabled: (
187
- parameter: keyof Parameters,
152
+ _: keyof Parameters,
188
153
  value: any,
189
154
  descriptor: GPURenderPipelineDescriptor
190
155
  ) => {
@@ -194,62 +159,98 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
194
159
 
195
160
  // COLOR
196
161
 
197
- colorMask: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
198
- const targets = addColorState(descriptor);
199
- targets[0].writeMask = value;
162
+ colorMask: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
163
+ const target = addColorState(descriptor, 0);
164
+ target.writeMask = value;
165
+ },
166
+
167
+ blend: (_: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
168
+ if (value) {
169
+ addBlendState(descriptor, 0);
170
+ }
200
171
  },
201
172
 
202
173
  blendColorOperation: (
203
- parameter: keyof Parameters,
174
+ _: keyof Parameters,
204
175
  value: any,
205
176
  descriptor: GPURenderPipelineDescriptor
206
177
  ) => {
207
- addColorState(descriptor);
208
- // const targets = addColorState(descriptor);
209
- // const target = targets[0];
210
- // const blend: GPUBlendState = target.blend || {color: {alpha: 0}};
211
- // blend.color = blend.color || {};
212
- // target.blend.color.operation = value;
213
- }
178
+ const blend = addBlendState(descriptor, 0);
179
+ blend.color = blend.color || {};
180
+ blend.color.operation = value;
181
+ },
214
182
 
215
- /*
216
- blendColorSrcTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
217
- addColorState(descriptor);
218
- targets[0].blend = targets[0].blend || {};
219
- targets[0].blend.color = targets[0].blend.color || {};
220
- targets[0].blend.color.srcTarget = value;
183
+ blendColorSrcFactor: (
184
+ _: keyof Parameters,
185
+ value: any,
186
+ descriptor: GPURenderPipelineDescriptor
187
+ ) => {
188
+ const blend = addBlendState(descriptor, 0);
189
+ blend.color = blend.color || {};
190
+ blend.color.srcFactor = value;
221
191
  },
222
192
 
223
- blendColorDstTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
224
- addColorState(descriptor);
225
- targets[0].blend = targets[0].blend || {};
226
- targets[0].blend.color = targets[0].blend.color || {};
227
- targets[0].blend.color.dstTarget = value;
193
+ blendColorDstFactor: (
194
+ _: keyof Parameters,
195
+ value: any,
196
+ descriptor: GPURenderPipelineDescriptor
197
+ ) => {
198
+ const blend = addBlendState(descriptor, 0);
199
+ blend.color.dstFactor = value;
228
200
  },
229
201
 
230
- blendAlphaOperation: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
231
- addColorState(descriptor);
232
- targets[0].blend = targets[0].blend || {};
233
- targets[0].blend.alpha = targets[0].blend.alpha || {};
234
- targets[0].blend.alpha.operation = value;
202
+ blendAlphaOperation: (
203
+ _: keyof Parameters,
204
+ value: any,
205
+ descriptor: GPURenderPipelineDescriptor
206
+ ) => {
207
+ const blend = addBlendState(descriptor, 0);
208
+ blend.alpha = blend.alpha || {};
209
+ blend.alpha.operation = value;
235
210
  },
236
211
 
237
- blendAlphaSrcTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
238
- addColorState(descriptor);
239
- targets[0].blend = targets[0].blend || {};
240
- targets[0].blend.alpha = targets[0].blend.alpha || {};
241
- targets[0].blend.alpha.srcTarget = value;
212
+ blendAlphaSrcFactor: (
213
+ _: keyof Parameters,
214
+ value: any,
215
+ descriptor: GPURenderPipelineDescriptor
216
+ ) => {
217
+ const blend = addBlendState(descriptor, 0);
218
+ blend.alpha = blend.alpha || {};
219
+ blend.alpha.srcFactor = value;
242
220
  },
243
221
 
244
- blendAlphaDstTarget: (parameter, value, descriptor: GPURenderPipelineDescriptor) => {
245
- addColorState(descriptor);
246
- targets[0].blend = targets[0].blend || {};
247
- targets[0].blend.alpha = targets[0].blend.alpha || {};
248
- targets[0].blend.alpha.dstTarget = value;
222
+ blendAlphaDstFactor: (
223
+ _: keyof Parameters,
224
+ value: any,
225
+ descriptor: GPURenderPipelineDescriptor
226
+ ) => {
227
+ const blend = addBlendState(descriptor, 0);
228
+ blend.alpha = blend.alpha || {};
229
+ blend.alpha.dstFactor = value;
249
230
  },
250
- */
231
+
232
+ unclippedDepth: notSupported,
233
+ provokingVertex: notSupported,
234
+ polygonMode: notSupported,
235
+ polygonOffsetLine: notSupported,
236
+ clipDistance0: notSupported,
237
+ clipDistance1: notSupported,
238
+ clipDistance2: notSupported,
239
+ clipDistance3: notSupported,
240
+ clipDistance4: notSupported,
241
+ clipDistance5: notSupported,
242
+ clipDistance6: notSupported,
243
+ clipDistance7: notSupported
251
244
  };
252
245
 
246
+ function notSupported(
247
+ key: keyof Parameters,
248
+ value: any,
249
+ descriptor: GPURenderPipelineDescriptor
250
+ ): void {
251
+ log.warn(`${key} parameter not supported in WebGPU`)();
252
+ }
253
+
253
254
  const DEFAULT_PIPELINE_DESCRIPTOR: GPURenderPipelineDescriptor = {
254
255
  // depthStencil: {
255
256
  // stencilFront: {},
@@ -296,17 +297,21 @@ function setParameters(
296
297
  ): void {
297
298
  for (const [key, value] of Object.entries(parameters)) {
298
299
  const setterFunction = PARAMETER_TABLE[key as keyof Parameters];
299
- if (!setterFunction) {
300
- log.warn(`Illegal parameter ${key}`)();
301
- continue;
300
+ if (setterFunction) {
301
+ setterFunction(key, value, pipelineDescriptor);
302
+ } else {
303
+ log.error(`Illegal parameter ${key} in WebGPU`)();
302
304
  }
303
- setterFunction(key, value, pipelineDescriptor);
304
305
  }
305
306
  }
306
307
 
307
- function addColorState(descriptor: GPURenderPipelineDescriptor): GPUColorTargetState[] {
308
- // @ts-ignore GPU types as iterator
309
- descriptor.fragment.targets = descriptor.fragment?.targets || [];
308
+ /** @todo - support multiple color targets... */
309
+ function addColorState(
310
+ descriptor: GPURenderPipelineDescriptor,
311
+ attachment: number
312
+ ): GPUColorTargetState {
313
+ // @ts-ignore
314
+ descriptor.fragment.targets = descriptor.fragment?.targets || ([] as GPUColorTargetState[]);
310
315
  if (!Array.isArray(descriptor.fragment?.targets)) {
311
316
  log.warn('parameters: no targets array')();
312
317
  }
@@ -315,5 +320,12 @@ function addColorState(descriptor: GPURenderPipelineDescriptor): GPUColorTargetS
315
320
  // @ts-expect-error GPU types as iterator
316
321
  descriptor.fragment.targets?.push({});
317
322
  }
318
- return descriptor.fragment?.targets as GPUColorTargetState[];
323
+ // @ts-expect-error GPU types as iterator
324
+ return descriptor.fragment?.targets?.[0] as GPUColorTargetState;
325
+ }
326
+
327
+ function addBlendState(descriptor: GPURenderPipelineDescriptor, attachment: number): GPUBlendState {
328
+ const target = addColorState(descriptor, attachment);
329
+ target.blend = target.blend || {color: {}, alpha: {}};
330
+ return target.blend;
319
331
  }