@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.
Files changed (121) hide show
  1. package/LICENSE +3 -1
  2. package/dist/adapter/helpers/accessor-to-format.js.map +1 -1
  3. package/dist/adapter/helpers/convert-texture-format.d.ts +2 -2
  4. package/dist/adapter/helpers/convert-texture-format.d.ts.map +1 -1
  5. package/dist/adapter/helpers/convert-texture-format.js +0 -1
  6. package/dist/adapter/helpers/convert-texture-format.js.map +1 -1
  7. package/dist/adapter/helpers/generate-mipmaps.d.ts +1 -1
  8. package/dist/adapter/helpers/generate-mipmaps.js +20 -15
  9. package/dist/adapter/helpers/generate-mipmaps.js.map +1 -1
  10. package/dist/adapter/helpers/get-bind-group.d.ts +4 -4
  11. package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
  12. package/dist/adapter/helpers/get-bind-group.js +8 -17
  13. package/dist/adapter/helpers/get-bind-group.js.map +1 -1
  14. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts +5 -5
  15. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
  16. package/dist/adapter/helpers/get-vertex-buffer-layout.js +32 -40
  17. package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -1
  18. package/dist/adapter/helpers/webgpu-parameters.d.ts +2 -2
  19. package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
  20. package/dist/adapter/helpers/webgpu-parameters.js +51 -48
  21. package/dist/adapter/helpers/webgpu-parameters.js.map +1 -1
  22. package/dist/adapter/resources/webgpu-buffer.d.ts +5 -6
  23. package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
  24. package/dist/adapter/resources/webgpu-buffer.js +19 -33
  25. package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
  26. package/dist/adapter/resources/webgpu-command-encoder.d.ts +6 -15
  27. package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
  28. package/dist/adapter/resources/webgpu-command-encoder.js +11 -29
  29. package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
  30. package/dist/adapter/resources/webgpu-compute-pass.d.ts +6 -6
  31. package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
  32. package/dist/adapter/resources/webgpu-compute-pass.js +14 -27
  33. package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
  34. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +4 -4
  35. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
  36. package/dist/adapter/resources/webgpu-compute-pipeline.js +6 -11
  37. package/dist/adapter/resources/webgpu-compute-pipeline.js.map +1 -1
  38. package/dist/adapter/resources/webgpu-external-texture.d.ts +5 -5
  39. package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
  40. package/dist/adapter/resources/webgpu-external-texture.js +6 -14
  41. package/dist/adapter/resources/webgpu-external-texture.js.map +1 -1
  42. package/dist/adapter/resources/webgpu-framebuffer.d.ts +4 -21
  43. package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
  44. package/dist/adapter/resources/webgpu-framebuffer.js +4 -105
  45. package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
  46. package/dist/adapter/resources/webgpu-query.js.map +1 -1
  47. package/dist/adapter/resources/webgpu-render-pass.d.ts +12 -7
  48. package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
  49. package/dist/adapter/resources/webgpu-render-pass.js +59 -36
  50. package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
  51. package/dist/adapter/resources/webgpu-render-pipeline.d.ts +14 -10
  52. package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
  53. package/dist/adapter/resources/webgpu-render-pipeline.js +50 -67
  54. package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
  55. package/dist/adapter/resources/webgpu-sampler.d.ts +5 -5
  56. package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
  57. package/dist/adapter/resources/webgpu-sampler.js +11 -11
  58. package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
  59. package/dist/adapter/resources/webgpu-shader.d.ts +7 -7
  60. package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
  61. package/dist/adapter/resources/webgpu-shader.js +11 -25
  62. package/dist/adapter/resources/webgpu-shader.js.map +1 -1
  63. package/dist/adapter/resources/webgpu-texture.d.ts +15 -8
  64. package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
  65. package/dist/adapter/resources/webgpu-texture.js +17 -27
  66. package/dist/adapter/resources/webgpu-texture.js.map +1 -1
  67. package/dist/adapter/resources/webgpu-vertex-array.d.ts +26 -0
  68. package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -0
  69. package/dist/adapter/resources/webgpu-vertex-array.js +39 -0
  70. package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -0
  71. package/dist/adapter/webgpu-canvas-context.d.ts +16 -12
  72. package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
  73. package/dist/adapter/webgpu-canvas-context.js +26 -47
  74. package/dist/adapter/webgpu-canvas-context.js.map +1 -1
  75. package/dist/adapter/webgpu-device.d.ts +39 -22
  76. package/dist/adapter/webgpu-device.d.ts.map +1 -1
  77. package/dist/adapter/webgpu-device.js +94 -95
  78. package/dist/adapter/webgpu-device.js.map +1 -1
  79. package/dist/adapter/webgpu-types.js.map +1 -1
  80. package/dist/dist.dev.js +2988 -0
  81. package/dist/glsl/glsllang.js +0 -1
  82. package/dist/glsl/glsllang.js.map +1 -1
  83. package/dist/index.cjs +1518 -0
  84. package/dist/index.d.ts +5 -7
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +5 -7
  87. package/dist/index.js.map +1 -1
  88. package/dist.min.js +20 -0
  89. package/package.json +18 -9
  90. package/src/adapter/helpers/accessor-to-format.ts +1 -2
  91. package/src/adapter/helpers/convert-texture-format.ts +1 -1
  92. package/src/adapter/helpers/generate-mipmaps.ts +2 -2
  93. package/src/adapter/helpers/get-bind-group.ts +22 -12
  94. package/src/adapter/helpers/get-vertex-buffer-layout.ts +55 -34
  95. package/src/adapter/helpers/webgpu-parameters.ts +56 -47
  96. package/src/adapter/resources/webgpu-buffer.ts +11 -12
  97. package/src/adapter/resources/webgpu-command-encoder.ts +62 -41
  98. package/src/adapter/resources/webgpu-compute-pass.ts +13 -13
  99. package/src/adapter/resources/webgpu-compute-pipeline.ts +6 -5
  100. package/src/adapter/resources/webgpu-external-texture.ts +5 -5
  101. package/src/adapter/resources/webgpu-framebuffer.ts +8 -109
  102. package/src/adapter/resources/webgpu-query.ts +3 -3
  103. package/src/adapter/resources/webgpu-render-pass.ts +74 -18
  104. package/src/adapter/resources/webgpu-render-pipeline.ts +64 -39
  105. package/src/adapter/resources/webgpu-sampler.ts +12 -5
  106. package/src/adapter/resources/webgpu-shader.ts +13 -10
  107. package/src/adapter/resources/webgpu-texture.ts +22 -8
  108. package/src/adapter/resources/webgpu-vertex-array.ts +74 -0
  109. package/src/adapter/webgpu-canvas-context.ts +52 -27
  110. package/src/adapter/webgpu-device.ts +158 -64
  111. package/src/index.ts +7 -9
  112. package/dist/bundle.d.ts +0 -2
  113. package/dist/bundle.d.ts.map +0 -1
  114. package/dist/bundle.js +0 -5
  115. package/dist/bundle.js.map +0 -1
  116. package/dist/init.d.ts +0 -2
  117. package/dist/init.d.ts.map +0 -1
  118. package/dist/init.js +0 -4
  119. package/dist/init.js.map +0 -1
  120. package/src/bundle.ts +0 -4
  121. package/src/init.ts +0 -4
@@ -1,15 +1,19 @@
1
1
  // luma.gl, MIT license
2
- import type {ShaderLayout, BindingLayout, Binding} from '@luma.gl/api';
3
- import {Buffer, Sampler, Texture, log, cast} from '@luma.gl/api';
4
- import type WebGPUBuffer from '../resources/webgpu-buffer';
5
- import type WebGPUSampler from '../resources/webgpu-sampler';
6
- import type WebGPUTexture from '../resources/webgpu-texture';
2
+ import type {ShaderLayout, BindingDeclaration, Binding} from '@luma.gl/core';
3
+ import {Buffer, Sampler, Texture, log, cast} from '@luma.gl/core';
4
+ import type {WebGPUBuffer} from '../resources/webgpu-buffer';
5
+ import type {WebGPUSampler} from '../resources/webgpu-sampler';
6
+ import type {WebGPUTexture} from '../resources/webgpu-texture';
7
7
 
8
8
  /**
9
9
  * Create a WebGPU "bind group layout" from an array of luma.gl bindings
10
10
  * @note bind groups can be automatically generated by WebGPU.
11
11
  */
12
- export function makeBindGroupLayout(device: GPUDevice, layout: GPUBindGroupLayout, bindings: Binding[]): GPUBindGroupLayout {
12
+ export function makeBindGroupLayout(
13
+ device: GPUDevice,
14
+ layout: GPUBindGroupLayout,
15
+ bindings: Binding[]
16
+ ): GPUBindGroupLayout {
13
17
  throw new Error('not implemented');
14
18
  // return device.createBindGroupLayout({
15
19
  // layout,
@@ -23,18 +27,21 @@ import type WebGPUTexture from '../resources/webgpu-texture';
23
27
  export function getBindGroup(
24
28
  device: GPUDevice,
25
29
  bindGroupLayout: GPUBindGroupLayout,
26
- layout: ShaderLayout,
30
+ shaderLayout: ShaderLayout,
27
31
  bindings: Record<string, Binding>
28
32
  ): GPUBindGroup {
29
- const entries = getBindGroupEntries(bindings, layout);
33
+ const entries = getBindGroupEntries(bindings, shaderLayout);
30
34
  return device.createBindGroup({
31
35
  layout: bindGroupLayout,
32
36
  entries
33
37
  });
34
38
  }
35
39
 
36
- export function getShaderLayoutBinding(layout: ShaderLayout, bindingName: string): BindingLayout {
37
- const bindingLayout = layout.bindings.find(binding => binding.name === bindingName);
40
+ export function getShaderLayoutBinding(
41
+ shaderLayout: ShaderLayout,
42
+ bindingName: string
43
+ ): BindingDeclaration {
44
+ const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName);
38
45
  if (!bindingLayout) {
39
46
  log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
40
47
  }
@@ -45,11 +52,14 @@ export function getShaderLayoutBinding(layout: ShaderLayout, bindingName: string
45
52
  * @param bindings
46
53
  * @returns
47
54
  */
48
- function getBindGroupEntries(bindings: Record<string, Binding>, layout: ShaderLayout): GPUBindGroupEntry[] {
55
+ function getBindGroupEntries(
56
+ bindings: Record<string, Binding>,
57
+ shaderLayout: ShaderLayout
58
+ ): GPUBindGroupEntry[] {
49
59
  const entries: GPUBindGroupEntry[] = [];
50
60
 
51
61
  for (const [bindingName, value] of Object.entries(bindings)) {
52
- const bindingLayout = getShaderLayoutBinding(layout, bindingName);
62
+ const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
53
63
  if (bindingLayout) {
54
64
  entries.push(getBindGroupEntry(value, bindingLayout.location));
55
65
  }
@@ -1,51 +1,63 @@
1
- import type {ShaderLayout, BufferMapping, AttributeLayout} from '@luma.gl/api';
2
- import {decodeVertexFormat} from '@luma.gl/api';
1
+ // luma.gl, MIT license
2
+ import type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';
3
+ import {decodeVertexFormat} from '@luma.gl/core';
4
+
5
+ /** Throw error on any WebGL-only vertex formats */
6
+ function getWebGPUVertexFormat(format: VertexFormat): GPUVertexFormat {
7
+ if (format.endsWith('-webgl')) {
8
+ throw new Error(`WebGPU does not support vertex format ${format}`);
9
+ }
10
+ return format as GPUVertexFormat;
11
+ }
3
12
 
4
13
  /**
5
14
  * Build a WebGPU vertex buffer layout intended for use in a GPURenderPassDescriptor.
6
15
  * Converts luma.gl attribute definitions to a WebGPU GPUVertexBufferLayout[] array
7
16
  * @param layout
8
- * @param bufferMap The buffer map is optional
17
+ * @param bufferLayout The buffer map is optional
9
18
  * @returns WebGPU layout intended for a GPURenderPassDescriptor.
10
19
  */
11
- export function getVertexBufferLayout(layout: ShaderLayout, bufferMap: BufferMapping[]): GPUVertexBufferLayout[] {
20
+ export function getVertexBufferLayout(
21
+ shaderLayout: ShaderLayout,
22
+ bufferLayout: BufferLayout[]
23
+ ): GPUVertexBufferLayout[] {
12
24
  const vertexBufferLayouts: GPUVertexBufferLayout[] = [];
13
25
  const usedAttributes = new Set<string>();
14
26
 
15
- // First handle any buffers mentioned in `bufferMapping`
16
- for (const mapping of bufferMap) {
27
+ // First handle any buffers mentioned in `bufferLayout`
28
+ for (const mapping of bufferLayout) {
17
29
  // Build vertex attributes for one buffer
18
30
  const vertexAttributes: GPUVertexAttribute[] = [];
19
31
 
20
32
  // TODO verify that all stepModes for one buffer are the same
21
33
  let stepMode: 'vertex' | 'instance' = 'vertex';
22
34
  let byteStride = 0;
23
- let byteOffset = mapping.byteOffset || 0;
24
-
25
35
  // interleaved mapping {..., attributes: [{...}, ...]}
26
- if ('attributes' in mapping) {
27
- const arrayStride = mapping.byteStride;
28
- for (const interleaved of mapping.attributes) {
29
- const attributeLayout = findAttributeLayout(layout, interleaved.name, usedAttributes);
36
+ if (mapping.attributes) {
37
+ // const arrayStride = mapping.byteStride; TODO
38
+ for (const attributeMapping of mapping.attributes) {
39
+ const attributeName = attributeMapping.attribute;
40
+ const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
30
41
 
31
42
  stepMode = attributeLayout.stepMode || 'vertex';
32
43
  vertexAttributes.push({
33
- format: attributeLayout.format,
34
- offset: byteOffset + byteStride,
44
+ format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
45
+ offset: attributeMapping.byteOffset,
35
46
  shaderLocation: attributeLayout.location
36
47
  });
37
48
 
38
- byteStride += decodeVertexFormat(attributeLayout.format).byteLength;
49
+ byteStride += decodeVertexFormat(mapping.format).byteLength;
39
50
  }
40
51
  // non-interleaved mapping (just set offset and stride)
41
52
  } else {
42
- const attributeLayout = findAttributeLayout(layout, mapping.name, usedAttributes);
43
- byteStride = decodeVertexFormat(attributeLayout.format).byteLength,
53
+ const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);
54
+ byteStride = decodeVertexFormat(mapping.format).byteLength;
44
55
 
45
56
  stepMode = attributeLayout.stepMode || 'vertex';
46
57
  vertexAttributes.push({
47
- format: attributeLayout.format,
48
- offset: byteOffset,
58
+ format: getWebGPUVertexFormat(mapping.format),
59
+ // We only support 0 offset for non-interleaved buffer layouts
60
+ offset: 0,
49
61
  shaderLocation: attributeLayout.location
50
62
  });
51
63
  }
@@ -58,17 +70,19 @@ export function getVertexBufferLayout(layout: ShaderLayout, bufferMap: BufferMap
58
70
  });
59
71
  }
60
72
 
61
- // Add any non-mapped attributes
62
- for (const attribute of layout.attributes) {
73
+ // Add any non-mapped attributes - TODO - avoid hardcoded types
74
+ for (const attribute of shaderLayout.attributes) {
63
75
  if (!usedAttributes.has(attribute.name)) {
64
76
  vertexBufferLayouts.push({
65
- arrayStride: decodeVertexFormat(attribute.format).byteLength,
77
+ arrayStride: decodeVertexFormat('float32x3').byteLength,
66
78
  stepMode: attribute.stepMode || 'vertex',
67
- attributes: [{
68
- format: attribute.format,
69
- offset: 0,
70
- shaderLocation: attribute.location
71
- }]
79
+ attributes: [
80
+ {
81
+ format: getWebGPUVertexFormat('float32x3'),
82
+ offset: 0,
83
+ shaderLocation: attribute.location
84
+ }
85
+ ]
72
86
  });
73
87
  }
74
88
  }
@@ -76,17 +90,20 @@ export function getVertexBufferLayout(layout: ShaderLayout, bufferMap: BufferMap
76
90
  return vertexBufferLayouts;
77
91
  }
78
92
 
79
- export function getBufferSlots(layout: ShaderLayout, bufferMap: BufferMapping[]): Record<string, number> {
93
+ export function getBufferSlots(
94
+ shaderLayout: ShaderLayout,
95
+ bufferLayout: BufferLayout[]
96
+ ): Record<string, number> {
80
97
  const usedAttributes = new Set<string>();
81
98
  let bufferSlot = 0;
82
99
  const bufferSlots: Record<string, number> = {};
83
100
 
84
- // First handle any buffers mentioned in `bufferMapping`
85
- for (const mapping of bufferMap) {
101
+ // First handle any buffers mentioned in `bufferLayout`
102
+ for (const mapping of bufferLayout) {
86
103
  // interleaved mapping {..., attributes: [{...}, ...]}
87
104
  if ('attributes' in mapping) {
88
105
  for (const interleaved of mapping.attributes) {
89
- usedAttributes.add(interleaved.name);
106
+ usedAttributes.add(interleaved.attribute);
90
107
  }
91
108
  // non-interleaved mapping (just set offset and stride)
92
109
  } else {
@@ -96,7 +113,7 @@ export function getBufferSlots(layout: ShaderLayout, bufferMap: BufferMapping[])
96
113
  }
97
114
 
98
115
  // Add any non-mapped attributes
99
- for (const attribute of layout.attributes) {
116
+ for (const attribute of shaderLayout.attributes) {
100
117
  if (!usedAttributes.has(attribute.name)) {
101
118
  bufferSlots[attribute.name] = bufferSlot++;
102
119
  }
@@ -110,8 +127,12 @@ export function getBufferSlots(layout: ShaderLayout, bufferMap: BufferMapping[])
110
127
  * @throws if name is not in ShaderLayout
111
128
  * @throws if name has already been referenced
112
129
  */
113
- function findAttributeLayout(layout: ShaderLayout, name: string, attributeNames: Set<string>): AttributeLayout {
114
- const attribute = layout.attributes.find(attribute => attribute.name === name);
130
+ function findAttributeLayout(
131
+ shaderLayout: ShaderLayout,
132
+ name: string,
133
+ attributeNames: Set<string>
134
+ ): AttributeDeclaration {
135
+ const attribute = shaderLayout.attributes.find(attribute => attribute.name === name);
115
136
  if (!attribute) {
116
137
  throw new Error(`Unknown attribute ${name}`);
117
138
  }
@@ -1,12 +1,16 @@
1
- import {Parameters} from '@luma.gl/api';
1
+ import {Parameters} from '@luma.gl/core';
2
2
 
3
- function addDepthStencil(descriptor: GPURenderPipelineDescriptor): void {
3
+ function addDepthStencil(descriptor: GPURenderPipelineDescriptor): GPUDepthStencilState {
4
4
  descriptor.depthStencil = descriptor.depthStencil || {
5
5
  // required, set something
6
6
  format: 'depth24plus',
7
7
  stencilFront: {},
8
- stencilBack: {}
8
+ stencilBack: {},
9
+ // TODO can this cause trouble? Should we set to WebGPU defaults? Are there defaults?
10
+ depthWriteEnabled: false,
11
+ depthCompare: 'less-equal'
9
12
  };
13
+ return descriptor.depthStencil;
10
14
  }
11
15
 
12
16
  /**
@@ -18,79 +22,81 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
18
22
  // RASTERIZATION PARAMETERS
19
23
 
20
24
  cullMode: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
25
+ descriptor.primitive = descriptor.primitive || {};
21
26
  descriptor.primitive.cullMode = value;
22
27
  },
23
28
 
24
29
  frontFace: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
30
+ descriptor.primitive = descriptor.primitive || {};
25
31
  descriptor.primitive.frontFace = value;
26
32
  },
27
33
 
28
34
  // DEPTH
29
35
 
30
36
  depthWriteEnabled: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
31
- addDepthStencil(descriptor);
32
- descriptor.depthStencil.depthWriteEnabled = value;
37
+ const depthStencil = addDepthStencil(descriptor);
38
+ depthStencil.depthWriteEnabled = value;
33
39
  },
34
40
 
35
41
  depthCompare: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
36
- addDepthStencil(descriptor);
37
- descriptor.depthStencil.depthCompare = value;
42
+ const depthStencil = addDepthStencil(descriptor);
43
+ depthStencil.depthCompare = value;
38
44
  },
39
45
 
40
46
  depthFormat: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
41
- addDepthStencil(descriptor);
42
- descriptor.depthStencil.format = value;
47
+ const depthStencil = addDepthStencil(descriptor);
48
+ depthStencil.format = value;
43
49
  },
44
50
 
45
51
  depthBias: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
46
- addDepthStencil(descriptor);
47
- descriptor.depthStencil.depthBias = value;
52
+ const depthStencil = addDepthStencil(descriptor);
53
+ depthStencil.depthBias = value;
48
54
  },
49
55
 
50
56
  depthBiasSlopeScale: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
51
- addDepthStencil(descriptor);
52
- descriptor.depthStencil.depthBiasSlopeScale = value;
57
+ const depthStencil = addDepthStencil(descriptor);
58
+ depthStencil.depthBiasSlopeScale = value;
53
59
  },
54
60
 
55
61
  depthBiasClamp: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
56
- addDepthStencil(descriptor);
57
- descriptor.depthStencil.depthBiasClamp = value;
62
+ const depthStencil = addDepthStencil(descriptor);
63
+ depthStencil.depthBiasClamp = value;
58
64
  },
59
65
 
60
66
  // STENCIL
61
67
 
62
68
  stencilReadMask: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
63
- addDepthStencil(descriptor);
64
- descriptor.depthStencil.stencilReadMask = value;
69
+ const depthStencil = addDepthStencil(descriptor);
70
+ depthStencil.stencilReadMask = value;
65
71
  },
66
72
 
67
73
  stencilWriteMask: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
68
- addDepthStencil(descriptor);
69
- descriptor.depthStencil.stencilWriteMask = value;
74
+ const depthStencil = addDepthStencil(descriptor);
75
+ depthStencil.stencilWriteMask = value;
70
76
  },
71
77
 
72
78
  stencilCompare: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
73
- addDepthStencil(descriptor);
74
- descriptor.depthStencil.stencilFront.compare = value;
75
- descriptor.depthStencil.stencilBack.compare = value;
79
+ const depthStencil = addDepthStencil(descriptor);
80
+ depthStencil.stencilFront.compare = value;
81
+ depthStencil.stencilBack.compare = value;
76
82
  },
77
83
 
78
84
  stencilPassOperation: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
79
- addDepthStencil(descriptor);
80
- descriptor.depthStencil.stencilFront.passOp = value;
81
- descriptor.depthStencil.stencilBack.passOp = value;
85
+ const depthStencil = addDepthStencil(descriptor);
86
+ depthStencil.stencilFront.passOp = value;
87
+ depthStencil.stencilBack.passOp = value;
82
88
  },
83
89
 
84
90
  stencilFailOperation: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
85
- addDepthStencil(descriptor);
86
- descriptor.depthStencil.stencilFront.failOp = value;
87
- descriptor.depthStencil.stencilBack.failOp = value;
91
+ const depthStencil = addDepthStencil(descriptor);
92
+ depthStencil.stencilFront.failOp = value;
93
+ depthStencil.stencilBack.failOp = value;
88
94
  },
89
95
 
90
96
  stencilDepthFailOperation: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
91
- addDepthStencil(descriptor);
92
- descriptor.depthStencil.stencilFront.depthFailOp = value;
93
- descriptor.depthStencil.stencilBack.depthFailOp = value;
97
+ const depthStencil = addDepthStencil(descriptor);
98
+ depthStencil.stencilFront.depthFailOp = value;
99
+ depthStencil.stencilBack.depthFailOp = value;
94
100
  },
95
101
 
96
102
  // MULTISAMPLE
@@ -113,18 +119,17 @@ export const PARAMETER_TABLE: Record<keyof Parameters, Function> = {
113
119
  // COLOR
114
120
 
115
121
  colorMask: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
116
- addColorState(descriptor);
117
- const targets = descriptor.fragment.targets as GPUColorTargetState[];
122
+ const targets = addColorState(descriptor);
118
123
  targets[0].writeMask = value;
119
124
  },
120
125
 
121
126
  blendColorOperation: (parameter: keyof Parameters, value: any, descriptor: GPURenderPipelineDescriptor) => {
122
127
  addColorState(descriptor);
123
- const targets = descriptor.fragment.targets as GPUColorTargetState[];
124
- // @ts-expect-error
125
- targets[0].blend = targets[0].blend || {};
126
- targets[0].blend.color = targets[0].blend.color || {};
127
- targets[0].blend.color.operation = value;
128
+ // const targets = addColorState(descriptor);
129
+ // const target = targets[0];
130
+ // const blend: GPUBlendState = target.blend || {color: {alpha: 0}};
131
+ // blend.color = blend.color || {};
132
+ // target.blend.color.operation = value;
128
133
  }
129
134
 
130
135
  /*
@@ -180,17 +185,19 @@ const DEFAULT_PIPELINE_DESCRIPTOR: GPURenderPipelineDescriptor = {
180
185
  },
181
186
 
182
187
  vertex: {
183
- module: undefined,
188
+ module: undefined!,
184
189
  entryPoint: 'main'
185
190
  },
186
191
 
187
192
  fragment: {
188
- module: undefined,
193
+ module: undefined!,
189
194
  entryPoint: 'main',
190
195
  targets: [
191
196
  // { format: props.color0Format || 'bgra8unorm' }
192
197
  ]
193
- }
198
+ },
199
+
200
+ layout: 'auto'
194
201
  };
195
202
 
196
203
  export function applyParametersToRenderPipelineDescriptor(
@@ -216,11 +223,13 @@ function setParameters(
216
223
  }
217
224
  }
218
225
 
219
- function addColorState(descriptor: GPURenderPipelineDescriptor): void {
220
- descriptor.fragment.targets = descriptor.fragment.targets || [];
221
- // @ts-expect-error
222
- if (descriptor.fragment.targets.length === 0) {
223
- // @ts-expect-error
224
- descriptor.fragment.targets.push({});
226
+ function addColorState(descriptor: GPURenderPipelineDescriptor): GPUColorTargetState[] {
227
+ descriptor.fragment.targets = descriptor.fragment?.targets || [];
228
+ if (!Array.isArray(descriptor.fragment?.targets)) {
229
+ throw new Error('colorstate');
230
+ }
231
+ if (descriptor.fragment?.targets?.length === 0) {
232
+ descriptor.fragment.targets?.push({});
225
233
  }
234
+ return descriptor.fragment?.targets as GPUColorTargetState[];
226
235
  }
@@ -1,12 +1,12 @@
1
1
  // WEBGPU Buffer implementation
2
- import {Buffer, BufferProps, assert} from '@luma.gl/api';
3
- import type WebGPUDevice from '../webgpu-device';
2
+ import {Buffer, BufferProps} from '@luma.gl/core';
3
+ import type {WebGPUDevice} from '../webgpu-device';
4
4
 
5
5
  function getByteLength(props: BufferProps): number {
6
6
  return props.byteLength || props.data?.byteLength || 0;
7
7
  }
8
8
 
9
- export default class WebGPUBuffer extends Buffer {
9
+ export class WebGPUBuffer extends Buffer {
10
10
  readonly device: WebGPUDevice;
11
11
  readonly handle: GPUBuffer;
12
12
  readonly byteLength: number;
@@ -18,8 +18,11 @@ export default class WebGPUBuffer extends Buffer {
18
18
  this.byteLength = getByteLength(props);
19
19
  const mapBuffer = Boolean(props.data);
20
20
 
21
+ // WebGPU buffers must be aligned to 4 bytes
22
+ const size = Math.ceil(this.byteLength / 4) * 4;
23
+
21
24
  this.handle = this.props.handle || this.device.handle.createBuffer({
22
- size: this.byteLength,
25
+ size,
23
26
  // usage defaults to vertex
24
27
  usage: this.props.usage || (GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),
25
28
  mappedAtCreation: this.props.mappedAtCreation || mapBuffer,
@@ -36,16 +39,12 @@ export default class WebGPUBuffer extends Buffer {
36
39
  }
37
40
  }
38
41
 
39
- protected createHandle(mapBuffer: boolean): GPUBuffer {
40
- return
41
- }
42
-
43
- destroy(): void {
42
+ override destroy(): void {
44
43
  this.handle.destroy();
45
44
  }
46
45
 
47
46
  // WebGPU provides multiple ways to write a buffer...
48
- write(data: ArrayBufferView, byteOffset = 0) {
47
+ override write(data: ArrayBufferView, byteOffset = 0) {
49
48
  this.device.handle.queue.writeBuffer(
50
49
  this.handle,
51
50
  byteOffset,
@@ -55,7 +54,7 @@ export default class WebGPUBuffer extends Buffer {
55
54
  );
56
55
  }
57
56
 
58
- async readAsync(byteOffset: number = 0, byteLength: number = this.byteLength): Promise<ArrayBuffer> {
57
+ override async readAsync(byteOffset: number = 0, byteLength: number = this.byteLength): Promise<Uint8Array> {
59
58
  // We need MAP_READ flag, but only COPY_DST buffers can have MAP_READ flag, so we need to create a temp buffer
60
59
  const tempBuffer = new WebGPUBuffer(this.device, {usage: Buffer.MAP_READ | Buffer.COPY_DST, byteLength});
61
60
 
@@ -71,7 +70,7 @@ export default class WebGPUBuffer extends Buffer {
71
70
  tempBuffer.handle.unmap();
72
71
  tempBuffer.destroy();
73
72
 
74
- return arrayBuffer;
73
+ return new Uint8Array(arrayBuffer);
75
74
  }
76
75
 
77
76
  _writeMapped<TypedArray>(typedArray: TypedArray): void {
@@ -1,26 +1,28 @@
1
- import {CommandEncoder, CommandEncoderProps, RenderPipeline, Buffer, Texture, cast} from '@luma.gl/api';
2
- import WebGPUDevice from '../webgpu-device';
3
- import WEBGPUBuffer from './webgpu-buffer';
4
- import WebGPUTexture from './webgpu-texture';
5
-
6
- export default class WebGPUCommandEncoder extends CommandEncoder {
1
+ import {CommandEncoder, CommandEncoderProps, Buffer, Texture, cast,
2
+ CopyTextureToTextureOptions,
3
+ CopyTextureToBufferOptions
4
+ // CopyBufferToTextureOptions,
5
+ // CopyBufferToBufferOptions,
6
+ } from '@luma.gl/core';
7
+ import {WebGPUDevice} from '../webgpu-device';
8
+ import {WebGPUBuffer} from './webgpu-buffer';
9
+ import {WebGPUTexture} from './webgpu-texture';
10
+
11
+ export class WebGPUCommandEncoder extends CommandEncoder {
7
12
  readonly device: WebGPUDevice;
8
13
  readonly handle: GPUCommandEncoder;
9
14
 
10
15
  constructor(device: WebGPUDevice, props: CommandEncoderProps) {
11
- super(props);
16
+ super(device, props);
12
17
  this.device = device;
13
- this.handle = this.handle || this.createHandle();
14
- this.handle.label = this.props.id;
15
- }
16
-
17
- protected createHandle(): GPUCommandEncoder {
18
- return this.device.handle.createCommandEncoder({
19
- measureExecutionTime: this.props.measureExecutionTime
18
+ this.handle = props.handle || this.device.handle.createCommandEncoder({
19
+ // TODO was this removed in standard?
20
+ // measureExecutionTime: this.props.measureExecutionTime
20
21
  });
22
+ this.handle.label = this.props.id;
21
23
  }
22
24
 
23
- destroy() {}
25
+ override destroy(): void {}
24
26
 
25
27
  finish(options?: {id?: string}): GPUCommandBuffer {
26
28
  return this.finish(options);
@@ -29,23 +31,26 @@ export default class WebGPUCommandEncoder extends CommandEncoder {
29
31
  // beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
30
32
  // beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
31
33
 
32
- copyBufferToBuffer(options: {
33
- source: Buffer,
34
- sourceOffset?: number,
35
- destination: Buffer,
36
- destinationOffset?: number,
37
- size?: number
38
- }): void {
34
+ copyBufferToBuffer(options: // CopyBufferToBufferOptions
35
+ {
36
+ source: Buffer,
37
+ sourceOffset?: number,
38
+ destination: Buffer,
39
+ destinationOffset?: number,
40
+ size?: number
41
+ }
42
+ ): void {
39
43
  this.handle.copyBufferToBuffer(
40
- cast<WEBGPUBuffer>(options.source).handle,
44
+ cast<WebGPUBuffer>(options.source).handle,
41
45
  options.sourceOffset ?? 0,
42
- cast<WEBGPUBuffer>(options.destination).handle,
46
+ cast<WebGPUBuffer>(options.destination).handle,
43
47
  options.destinationOffset ?? 0,
44
48
  options.size ?? 0
45
49
  );
46
50
  }
47
51
 
48
- copyBufferToTexture(options: {
52
+ copyBufferToTexture(options: // CopyBufferToTextureOptions
53
+ {
49
54
  source: Buffer,
50
55
  offset?: number,
51
56
  bytesPerRow: number,
@@ -57,10 +62,11 @@ export default class WebGPUCommandEncoder extends CommandEncoder {
57
62
 
58
63
  origin?: number[] | [number, number, number],
59
64
  extent?: number[] | [number, number, number]
60
- }): void {
65
+ }
66
+ ): void {
61
67
  this.handle.copyBufferToTexture(
62
68
  {
63
- buffer: cast<WEBGPUBuffer>(options.source).handle,
69
+ buffer: cast<WebGPUBuffer>(options.source).handle,
64
70
  offset: options.offset ?? 0,
65
71
  bytesPerRow: options.bytesPerRow,
66
72
  rowsPerImage: options.rowsPerImage,
@@ -71,31 +77,46 @@ export default class WebGPUCommandEncoder extends CommandEncoder {
71
77
  origin: options.origin ?? {},
72
78
  // aspect: options.aspect
73
79
  },
74
- options.extent // default depth?
80
+ {
81
+ // TODO exclamation mark hack
82
+ width: options.extent[0],
83
+ height: options.extent[1],
84
+ depthOrArrayLayers: options.extent[2]
85
+ }
75
86
  );
76
87
  }
77
88
 
78
- copyTextureToBuffer(options: {
79
- source: GPUImageCopyTexture,
80
- destination: GPUImageCopyBuffer,
81
- copySize: GPUExtent3D
82
- }): void {}
89
+ copyTextureToBuffer(options: CopyTextureToBufferOptions): void {
90
+ // this.handle.copyTextureToBuffer(
91
+ // // source
92
+ // {},
93
+ // // destination
94
+ // {},
95
+ // // copySize
96
+ // {}
97
+ // );
98
+ }
83
99
 
84
- copyTextureToTexture(options: {
85
- source: GPUImageCopyTexture ,
86
- destination: GPUImageCopyTexture,
87
- copySize: GPUExtent3D
88
- }): void {}
100
+ copyTextureToTexture(options: CopyTextureToTextureOptions): void {
101
+ // this.handle.copyTextureToTexture(
102
+ // // source
103
+ // {},
104
+ // // destination
105
+ // {},
106
+ // // copySize
107
+ // {}
108
+ // );
109
+ }
89
110
 
90
- pushDebugGroup(groupLabel: string): void {
111
+ override pushDebugGroup(groupLabel: string): void {
91
112
  this.handle.pushDebugGroup(groupLabel);
92
113
  }
93
114
 
94
- popDebugGroup(): void {
115
+ override popDebugGroup(): void {
95
116
  this.handle.popDebugGroup();
96
117
  }
97
118
 
98
- insertDebugMarker(markerLabel: string): void {
119
+ override insertDebugMarker(markerLabel: string): void {
99
120
  this.handle.insertDebugMarker(markerLabel);
100
121
  }
101
122