@luma.gl/webgpu 9.0.0-beta.1 → 9.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/adapter/helpers/accessor-to-format.js +102 -1
  2. package/dist/adapter/helpers/convert-texture-format.d.ts.map +1 -1
  3. package/dist/adapter/helpers/convert-texture-format.js +8 -5
  4. package/dist/adapter/helpers/get-bind-group.d.ts +3 -3
  5. package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
  6. package/dist/adapter/helpers/get-bind-group.js +57 -41
  7. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
  8. package/dist/adapter/helpers/get-vertex-buffer-layout.js +117 -80
  9. package/dist/adapter/helpers/webgpu-parameters.d.ts.map +1 -1
  10. package/dist/adapter/helpers/webgpu-parameters.js +185 -125
  11. package/dist/adapter/resources/webgpu-buffer.d.ts +1 -1
  12. package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
  13. package/dist/adapter/resources/webgpu-buffer.js +119 -62
  14. package/dist/adapter/resources/webgpu-command-encoder.d.ts +7 -1
  15. package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
  16. package/dist/adapter/resources/webgpu-command-encoder.js +81 -49
  17. package/dist/adapter/resources/webgpu-compute-pass.d.ts +15 -9
  18. package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
  19. package/dist/adapter/resources/webgpu-compute-pass.js +76 -41
  20. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts +14 -4
  21. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
  22. package/dist/adapter/resources/webgpu-compute-pipeline.js +46 -19
  23. package/dist/adapter/resources/webgpu-external-texture.d.ts +2 -2
  24. package/dist/adapter/resources/webgpu-external-texture.d.ts.map +1 -1
  25. package/dist/adapter/resources/webgpu-external-texture.js +35 -18
  26. package/dist/adapter/resources/webgpu-framebuffer.d.ts +1 -1
  27. package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
  28. package/dist/adapter/resources/webgpu-framebuffer.js +14 -7
  29. package/dist/adapter/resources/webgpu-query-set.d.ts +17 -0
  30. package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -0
  31. package/dist/adapter/resources/webgpu-query-set.js +27 -0
  32. package/dist/adapter/resources/webgpu-render-pass.d.ts +4 -2
  33. package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
  34. package/dist/adapter/resources/webgpu-render-pass.js +133 -105
  35. package/dist/adapter/resources/webgpu-render-pipeline.d.ts +52 -5
  36. package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
  37. package/dist/adapter/resources/webgpu-render-pipeline.js +151 -78
  38. package/dist/adapter/resources/webgpu-sampler.d.ts +1 -1
  39. package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
  40. package/dist/adapter/resources/webgpu-sampler.js +21 -15
  41. package/dist/adapter/resources/webgpu-shader.d.ts +2 -5
  42. package/dist/adapter/resources/webgpu-shader.d.ts.map +1 -1
  43. package/dist/adapter/resources/webgpu-shader.js +45 -44
  44. package/dist/adapter/resources/webgpu-texture-view.d.ts +20 -0
  45. package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -0
  46. package/dist/adapter/resources/webgpu-texture-view.js +35 -0
  47. package/dist/adapter/resources/webgpu-texture.d.ts +8 -8
  48. package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
  49. package/dist/adapter/resources/webgpu-texture.js +130 -107
  50. package/dist/adapter/resources/webgpu-vertex-array.d.ts +9 -8
  51. package/dist/adapter/resources/webgpu-vertex-array.d.ts.map +1 -1
  52. package/dist/adapter/resources/webgpu-vertex-array.js +60 -39
  53. package/dist/adapter/webgpu-canvas-context.d.ts +3 -3
  54. package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
  55. package/dist/adapter/webgpu-canvas-context.js +101 -67
  56. package/dist/adapter/webgpu-device.d.ts +26 -28
  57. package/dist/adapter/webgpu-device.d.ts.map +1 -1
  58. package/dist/adapter/webgpu-device.js +254 -220
  59. package/dist/dist.dev.js +804 -2270
  60. package/dist/dist.min.js +9 -0
  61. package/dist/index.cjs +366 -485
  62. package/dist/index.cjs.map +7 -0
  63. package/dist/index.d.ts +5 -5
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +5 -1
  66. package/dist.min.js +1 -22
  67. package/package.json +9 -7
  68. package/src/adapter/helpers/accessor-to-format.ts +5 -1
  69. package/src/adapter/helpers/convert-texture-format.ts +4 -1
  70. package/src/adapter/helpers/get-bind-group.ts +12 -6
  71. package/src/adapter/helpers/get-vertex-buffer-layout.ts +13 -5
  72. package/src/adapter/helpers/webgpu-parameters.ts +79 -15
  73. package/src/adapter/resources/webgpu-buffer.ts +24 -11
  74. package/src/adapter/resources/webgpu-command-encoder.ts +24 -9
  75. package/src/adapter/resources/webgpu-compute-pass.ts +45 -22
  76. package/src/adapter/resources/webgpu-compute-pipeline.ts +48 -16
  77. package/src/adapter/resources/webgpu-external-texture.ts +14 -6
  78. package/src/adapter/resources/webgpu-framebuffer.ts +4 -0
  79. package/src/adapter/resources/webgpu-query-set.ts +37 -0
  80. package/src/adapter/resources/webgpu-render-pass.ts +37 -14
  81. package/src/adapter/resources/webgpu-render-pipeline.ts +80 -119
  82. package/src/adapter/resources/webgpu-sampler.ts +4 -1
  83. package/src/adapter/resources/webgpu-shader.ts +14 -25
  84. package/src/adapter/resources/webgpu-texture-view.ts +46 -0
  85. package/src/adapter/resources/webgpu-texture.ts +33 -28
  86. package/src/adapter/resources/webgpu-vertex-array.ts +28 -20
  87. package/src/adapter/webgpu-canvas-context.ts +10 -4
  88. package/src/adapter/webgpu-device.ts +109 -106
  89. package/src/index.ts +2 -1
  90. package/dist/adapter/helpers/accessor-to-format.js.map +0 -1
  91. package/dist/adapter/helpers/convert-texture-format.js.map +0 -1
  92. package/dist/adapter/helpers/generate-mipmaps.d.ts +0 -10
  93. package/dist/adapter/helpers/generate-mipmaps.d.ts.map +0 -1
  94. package/dist/adapter/helpers/generate-mipmaps.js +0 -100
  95. package/dist/adapter/helpers/generate-mipmaps.js.map +0 -1
  96. package/dist/adapter/helpers/get-bind-group.js.map +0 -1
  97. package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +0 -1
  98. package/dist/adapter/helpers/webgpu-parameters.js.map +0 -1
  99. package/dist/adapter/resources/webgpu-buffer.js.map +0 -1
  100. package/dist/adapter/resources/webgpu-command-encoder.js.map +0 -1
  101. package/dist/adapter/resources/webgpu-compute-pass.js.map +0 -1
  102. package/dist/adapter/resources/webgpu-compute-pipeline.js.map +0 -1
  103. package/dist/adapter/resources/webgpu-external-texture.js.map +0 -1
  104. package/dist/adapter/resources/webgpu-framebuffer.js.map +0 -1
  105. package/dist/adapter/resources/webgpu-query.d.ts +0 -1
  106. package/dist/adapter/resources/webgpu-query.d.ts.map +0 -1
  107. package/dist/adapter/resources/webgpu-query.js +0 -2
  108. package/dist/adapter/resources/webgpu-query.js.map +0 -1
  109. package/dist/adapter/resources/webgpu-render-pass.js.map +0 -1
  110. package/dist/adapter/resources/webgpu-render-pipeline.js.map +0 -1
  111. package/dist/adapter/resources/webgpu-sampler.js.map +0 -1
  112. package/dist/adapter/resources/webgpu-shader.js.map +0 -1
  113. package/dist/adapter/resources/webgpu-texture.js.map +0 -1
  114. package/dist/adapter/resources/webgpu-vertex-array.js.map +0 -1
  115. package/dist/adapter/webgpu-canvas-context.js.map +0 -1
  116. package/dist/adapter/webgpu-device.js.map +0 -1
  117. package/dist/adapter/webgpu-types.d.ts +0 -1
  118. package/dist/adapter/webgpu-types.d.ts.map +0 -1
  119. package/dist/adapter/webgpu-types.js +0 -2
  120. package/dist/adapter/webgpu-types.js.map +0 -1
  121. package/dist/glsl/glsllang.d.ts +0 -3
  122. package/dist/glsl/glsllang.d.ts.map +0 -1
  123. package/dist/glsl/glsllang.js +0 -9
  124. package/dist/glsl/glsllang.js.map +0 -1
  125. package/dist/index.js.map +0 -1
  126. package/src/adapter/helpers/generate-mipmaps.ts +0 -107
  127. package/src/adapter/resources/webgpu-query.ts +0 -43
  128. package/src/adapter/webgpu-types.ts +0 -0
  129. package/src/glsl/glsllang.ts +0 -14
@@ -1,7 +1,8 @@
1
- // luma.gl, MIT license
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
- import type {Device, Buffer, VertexArrayProps, RenderPass, TypedArray} from '@luma.gl/core';
5
+ import type {Device, Buffer, VertexArrayProps, RenderPass} from '@luma.gl/core';
5
6
  import {VertexArray, log} from '@luma.gl/core';
6
7
  import {getBrowser} from '@probe.gl/env';
7
8
 
@@ -20,11 +21,6 @@ export class WebGPUVertexArray extends VertexArray {
20
21
  /** Vertex Array is a helper class under WebGPU */
21
22
  readonly handle: never;
22
23
 
23
- /** * Attribute 0 can not be disable on most desktop OpenGL based browsers */
24
- static isConstantAttributeZeroSupported(device: Device): boolean {
25
- return device.info.type === 'webgl2' || getBrowser() === 'Chrome';
26
- }
27
-
28
24
  // Create a VertexArray
29
25
  constructor(device: WebGPUDevice, props?: VertexArrayProps) {
30
26
  super(device, props);
@@ -35,40 +31,42 @@ export class WebGPUVertexArray extends VertexArray {
35
31
 
36
32
  /**
37
33
  * Set an elements buffer, for indexed rendering.
38
- * Must be a Buffer bound to buffer with usage bit Buffer.INDEX set.
34
+ * Must be a Buffer bound to buffer with usage bit Buffer.INDEX set.
39
35
  */
40
36
  setIndexBuffer(buffer: Buffer | null): void {
41
37
  // assert(!elementBuffer || elementBuffer.glTarget === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
42
38
  this.indexBuffer = buffer;
43
39
  }
44
40
 
45
- /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
46
- setBuffer(location: number, buffer: Buffer): void {
41
+ /** Set a bufferSlot in vertex attributes array to a buffer, enables the bufferSlot, sets divisor */
42
+ setBuffer(bufferSlot: number, buffer: Buffer): void {
47
43
  // Sanity check target
48
44
  // if (buffer.glUsage === GL.ELEMENT_ARRAY_BUFFER) {
49
45
  // throw new Error('Use setIndexBuffer');
50
46
  // }
51
47
 
52
- this.attributes[location] = buffer;
48
+ this.attributes[bufferSlot] = buffer;
53
49
  }
54
50
 
55
- /** Set a location in vertex attributes array to a constant value, disables the location */
56
- override setConstant(location: number, value: TypedArray): void {
57
- log.warn(`${this.id} constant attributes not supported on WebGPU`)
58
- }
59
-
60
- override bindBeforeRender(renderPass: RenderPass, firstIndex?: number, indexCount?: number): void {
51
+ override bindBeforeRender(
52
+ renderPass: RenderPass,
53
+ firstIndex?: number,
54
+ indexCount?: number
55
+ ): void {
61
56
  const webgpuRenderPass = renderPass as WebGPURenderPass;
62
57
  const webgpuIndexBuffer = this.indexBuffer as WebGPUBuffer;
63
58
  if (webgpuIndexBuffer?.handle) {
64
59
  // Note we can't unset an index buffer
65
60
  log.warn('setting index buffer', webgpuIndexBuffer?.handle, webgpuIndexBuffer?.indexType)();
66
- webgpuRenderPass.handle.setIndexBuffer(webgpuIndexBuffer?.handle, webgpuIndexBuffer?.indexType);
61
+ webgpuRenderPass.handle.setIndexBuffer(
62
+ webgpuIndexBuffer?.handle,
63
+ webgpuIndexBuffer?.indexType
64
+ );
67
65
  }
68
66
  for (let location = 0; location < this.maxVertexAttributes; location++) {
69
67
  const webgpuBuffer = this.attributes[location] as WebGPUBuffer;
70
68
  if (webgpuBuffer?.handle) {
71
- log.warn('setting vertex buffer', location, webgpuBuffer?.handle)();
69
+ log.warn(`setting vertex buffer ${location}`, webgpuBuffer?.handle)();
72
70
  webgpuRenderPass.handle.setVertexBuffer(location, webgpuBuffer?.handle);
73
71
  }
74
72
  }
@@ -76,8 +74,18 @@ export class WebGPUVertexArray extends VertexArray {
76
74
  }
77
75
 
78
76
  override unbindAfterRender(renderPass: RenderPass): void {
79
- // On WebGPU we don't need to unbind.
77
+ // On WebGPU we don't need to unbind.
80
78
  // In fact we can't easily do it. setIndexBuffer/setVertexBuffer don't accept null.
81
79
  // Unbinding presumably happens automatically when the render pass is ended.
82
80
  }
81
+
82
+ // DEPRECATED METHODS
83
+
84
+ /**
85
+ * @deprecated is this even an issue for WebGPU?
86
+ * Attribute 0 can not be disable on most desktop OpenGL based browsers
87
+ */
88
+ static isConstantAttributeZeroSupported(device: Device): boolean {
89
+ return getBrowser() === 'Chrome';
90
+ }
83
91
  }
@@ -1,4 +1,9 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
1
5
  // / <reference types="@webgpu/types" />
6
+
2
7
  import type {Texture, TextureFormat, CanvasContextProps} from '@luma.gl/core';
3
8
  import {CanvasContext, log} from '@luma.gl/core';
4
9
  import {getWebGPUTextureFormat} from './helpers/convert-texture-format';
@@ -6,7 +11,7 @@ import {WebGPUDevice} from './webgpu-device';
6
11
  import {WebGPUFramebuffer} from './resources/webgpu-framebuffer';
7
12
  import {WebGPUTexture} from './resources/webgpu-texture';
8
13
 
9
- /**
14
+ /**
10
15
  * Holds a WebGPU Canvas Context
11
16
  * The primary job of the CanvasContext is to generate textures for rendering into the current canvas
12
17
  * It also manages canvas sizing calculations and resizing.
@@ -15,7 +20,7 @@ export class WebGPUCanvasContext extends CanvasContext {
15
20
  readonly device: WebGPUDevice;
16
21
  readonly gpuCanvasContext: GPUCanvasContext;
17
22
  /** Format of returned textures: "bgra8unorm", "rgba8unorm", "rgba16float". */
18
- readonly format: TextureFormat = navigator.gpu.getPreferredCanvasFormat();
23
+ readonly format: TextureFormat = navigator.gpu.getPreferredCanvasFormat() as TextureFormat;
19
24
  /** Default stencil format for depth textures */
20
25
  depthStencilFormat: TextureFormat = 'depth24plus';
21
26
 
@@ -55,7 +60,7 @@ export class WebGPUCanvasContext extends CanvasContext {
55
60
  // height: this.height
56
61
  // });
57
62
 
58
- // Wrap the current canvas context texture in a luma.gl texture
63
+ // Wrap the current canvas context texture in a luma.gl texture
59
64
  const currentColorAttachment = this.getCurrentTexture();
60
65
  this.width = currentColorAttachment.width;
61
66
  this.height = currentColorAttachment.height;
@@ -107,7 +112,8 @@ export class WebGPUCanvasContext extends CanvasContext {
107
112
  getCurrentTexture(): WebGPUTexture {
108
113
  return this.device._createTexture({
109
114
  id: `${this.id}#color-texture`,
110
- handle: this.gpuCanvasContext.getCurrentTexture()
115
+ handle: this.gpuCanvasContext.getCurrentTexture(),
116
+ format: this.format
111
117
  });
112
118
  }
113
119
 
@@ -1,3 +1,7 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
1
5
  // prettier-ignore
2
6
  // / <reference types="@webgpu/types" />
3
7
 
@@ -22,9 +26,11 @@ import type {
22
26
  // CommandEncoderProps,
23
27
  VertexArrayProps,
24
28
  TransformFeedback,
25
- TransformFeedbackProps
29
+ TransformFeedbackProps,
30
+ QuerySet,
31
+ QuerySetProps
26
32
  } from '@luma.gl/core';
27
- import {Device, CanvasContext, log, uid} from '@luma.gl/core';
33
+ import {Device, DeviceFeatures, CanvasContext, log, uid} from '@luma.gl/core';
28
34
  import {WebGPUBuffer} from './resources/webgpu-buffer';
29
35
  import {WebGPUTexture} from './resources/webgpu-texture';
30
36
  import {WebGPUExternalTexture} from './resources/webgpu-external-texture';
@@ -39,23 +45,33 @@ import {WebGPUComputePass} from './resources/webgpu-compute-pass';
39
45
  import {WebGPUVertexArray} from './resources/webgpu-vertex-array';
40
46
 
41
47
  import {WebGPUCanvasContext} from './webgpu-canvas-context';
42
- // import {loadGlslangModule} from '../glsl/glslang';
48
+ import {WebGPUQuerySet} from './resources/webgpu-query-set';
43
49
 
44
50
  /** WebGPU Device implementation */
45
51
  export class WebGPUDevice extends Device {
52
+ static type: string = 'webgpu';
53
+
54
+ /** type of this device */
55
+ readonly type = 'webgpu';
56
+
57
+ /** The underlying WebGPU device */
46
58
  readonly handle: GPUDevice;
59
+ /* The underlying WebGPU adapter */
47
60
  readonly adapter: GPUAdapter;
61
+ /* The underlying WebGPU adapter's info */
62
+ readonly adapterInfo: GPUAdapterInfo;
63
+
64
+ readonly features: DeviceFeatures;
65
+ readonly info: DeviceInfo;
66
+ readonly limits: DeviceLimits;
67
+
48
68
  readonly lost: Promise<{reason: 'destroyed'; message: string}>;
49
69
  canvasContext: WebGPUCanvasContext | null = null;
50
70
 
71
+ private _isLost: boolean = false;
51
72
  commandEncoder: GPUCommandEncoder | null = null;
52
73
  renderPass: WebGPURenderPass | null = null;
53
74
 
54
- private _info: DeviceInfo;
55
- private _isLost: boolean = false;
56
-
57
- static type: string = 'webgpu';
58
-
59
75
  /** Check if WebGPU is available */
60
76
  static isSupported(): boolean {
61
77
  return Boolean(typeof navigator !== 'undefined' && navigator.gpu);
@@ -79,11 +95,23 @@ export class WebGPUDevice extends Device {
79
95
  const adapterInfo = await adapter.requestAdapterInfo();
80
96
  log.probe(2, 'Adapter available', adapterInfo)();
81
97
 
98
+ const requiredFeatures: GPUFeatureName[] = [];
99
+ const requiredLimits: Record<string, number> = {};
100
+
101
+ if (props.requestMaxLimits) {
102
+ requiredFeatures.push(...(Array.from(adapter.features) as GPUFeatureName[]));
103
+ for (const key in adapter.limits) {
104
+ requiredLimits[key] = adapter.limits[key];
105
+ }
106
+ delete requiredLimits.minSubgroupSize;
107
+ delete requiredLimits.maxSubgroupSize;
108
+ }
109
+
82
110
  const gpuDevice = await adapter.requestDevice({
83
- requiredFeatures: adapter.features as ReadonlySet<GPUFeatureName>
84
- // TODO ensure we obtain best limits
85
- // requiredLimits: adapter.limits
111
+ requiredFeatures,
112
+ requiredLimits
86
113
  });
114
+
87
115
  log.probe(1, 'GPUDevice available')();
88
116
 
89
117
  if (typeof props.canvas === 'string') {
@@ -93,41 +121,29 @@ export class WebGPUDevice extends Device {
93
121
 
94
122
  const device = new WebGPUDevice(gpuDevice, adapter, adapterInfo, props);
95
123
 
96
- log.probe(1, 'Device created. For more info, set chrome://flags/#enable-webgpu-developer-features')();
124
+ log.probe(
125
+ 1,
126
+ 'Device created. For more info, set chrome://flags/#enable-webgpu-developer-features'
127
+ )();
97
128
  log.table(1, device.info)();
98
129
  log.groupEnd(1)();
99
130
  return device;
100
131
  }
101
132
 
102
- constructor(device: GPUDevice, adapter: GPUAdapter, adapterInfo: GPUAdapterInfo, props: DeviceProps) {
133
+ constructor(
134
+ device: GPUDevice,
135
+ adapter: GPUAdapter,
136
+ adapterInfo: GPUAdapterInfo,
137
+ props: DeviceProps
138
+ ) {
103
139
  super({...props, id: props.id || uid('webgpu-device')});
104
140
  this.handle = device;
105
141
  this.adapter = adapter;
142
+ this.adapterInfo = adapterInfo;
106
143
 
107
- const [driver, driverVersion] = ((adapterInfo as any).driver || '').split(' Version ');
108
-
109
- // See https://developer.chrome.com/blog/new-in-webgpu-120#adapter_information_updates
110
- const vendor = adapterInfo.vendor || this.adapter.__brand || 'unknown';
111
- const renderer = driver || '';
112
- const version = driverVersion || '';
113
-
114
- const gpu = vendor === 'apple' ? 'apple' : 'unknown'; // 'nvidia' | 'amd' | 'intel' | 'apple' | 'unknown',
115
- const gpuArchitecture = adapterInfo.architecture || 'unknown';
116
- const gpuBackend = (adapterInfo as any).backend || 'unknown';
117
- const gpuType = ((adapterInfo as any).type || '').split(' ')[0].toLowerCase() || 'unknown'
118
-
119
- this._info = {
120
- type: 'webgpu',
121
- vendor,
122
- renderer,
123
- version,
124
- gpu,
125
- gpuType,
126
- gpuBackend,
127
- gpuArchitecture,
128
- shadingLanguage: 'wgsl',
129
- shadingLanguageVersion: 100
130
- };
144
+ this.info = this._getInfo();
145
+ this.features = this._getFeatures();
146
+ this.limits = this.handle.limits;
131
147
 
132
148
  // "Context" loss handling
133
149
  this.lost = new Promise<{reason: 'destroyed'; message: string}>(async resolve => {
@@ -145,8 +161,6 @@ export class WebGPUDevice extends Device {
145
161
  container: props.container
146
162
  });
147
163
  // }
148
-
149
- this.features = this._getFeatures();
150
164
  }
151
165
 
152
166
  // TODO
@@ -158,23 +172,17 @@ export class WebGPUDevice extends Device {
158
172
  this.handle.destroy();
159
173
  }
160
174
 
161
- get info(): DeviceInfo {
162
- return this._info;
163
- }
164
-
165
- features: Set<DeviceFeature>;
166
-
167
- get limits(): DeviceLimits {
168
- return this.handle.limits;
169
- }
170
-
171
175
  isTextureFormatSupported(format: TextureFormat): boolean {
172
176
  return !format.includes('webgl');
173
177
  }
174
178
 
175
179
  /** @todo implement proper check? */
176
180
  isTextureFormatFilterable(format: TextureFormat): boolean {
177
- return this.isTextureFormatSupported(format);
181
+ return (
182
+ this.isTextureFormatSupported(format) &&
183
+ !format.startsWith('depth') &&
184
+ !format.startsWith('stencil')
185
+ );
178
186
  }
179
187
 
180
188
  /** @todo implement proper check? */
@@ -212,7 +220,7 @@ export class WebGPUDevice extends Device {
212
220
  }
213
221
 
214
222
  createFramebuffer(props: FramebufferProps): WebGPUFramebuffer {
215
- throw new Error('Not implemented');
223
+ return new WebGPUFramebuffer(this, props);
216
224
  }
217
225
 
218
226
  createComputePipeline(props: ComputePipelineProps): WebGPUComputePipeline {
@@ -247,24 +255,12 @@ export class WebGPUDevice extends Device {
247
255
  throw new Error('Transform feedback not supported in WebGPU');
248
256
  }
249
257
 
250
- createCanvasContext(props: CanvasContextProps): WebGPUCanvasContext {
251
- return new WebGPUCanvasContext(this, this.adapter, props);
258
+ override createQuerySet(props: QuerySetProps): QuerySet {
259
+ return new WebGPUQuerySet(this, props);
252
260
  }
253
261
 
254
- /**
255
- * Gets default renderpass encoder.
256
- * Creates a new encoder against default canvasContext if not already created
257
- * @note Called internally by Model.
258
- * @deprecated Create explicit pass with device.beginRenderPass
259
- */
260
- getDefaultRenderPass(): WebGPURenderPass {
261
- // this.renderPass =
262
- // this.renderPass ||
263
- // this.beginRenderPass({
264
- // framebuffer: this.canvasContext?.getCurrentFramebuffer()
265
- // });
266
- // return this.renderPass;
267
- throw new Error('a');
262
+ createCanvasContext(props: CanvasContextProps): WebGPUCanvasContext {
263
+ return new WebGPUCanvasContext(this, this.adapter, props);
268
264
  }
269
265
 
270
266
  submit(): void {
@@ -277,10 +273,38 @@ export class WebGPUDevice extends Device {
277
273
  // this.renderPass = null;
278
274
  }
279
275
 
280
- _getFeatures() {
281
- // WebGPU Features
282
- const features = new Set<DeviceFeature>(this.handle.features as Set<DeviceFeature>);
276
+ // PRIVATE METHODS
277
+
278
+ protected _getInfo(): DeviceInfo {
279
+ const [driver, driverVersion] = ((this.adapterInfo as any).driver || '').split(' Version ');
280
+
281
+ // See https://developer.chrome.com/blog/new-in-webgpu-120#adapter_information_updates
282
+ const vendor = this.adapterInfo.vendor || this.adapter.__brand || 'unknown';
283
+ const renderer = driver || '';
284
+ const version = driverVersion || '';
285
+
286
+ const gpu = vendor === 'apple' ? 'apple' : 'unknown'; // 'nvidia' | 'amd' | 'intel' | 'apple' | 'unknown',
287
+ const gpuArchitecture = this.adapterInfo.architecture || 'unknown';
288
+ const gpuBackend = (this.adapterInfo as any).backend || 'unknown';
289
+ const gpuType = ((this.adapterInfo as any).type || '').split(' ')[0].toLowerCase() || 'unknown';
290
+
291
+ return {
292
+ type: 'webgpu',
293
+ vendor,
294
+ renderer,
295
+ version,
296
+ gpu,
297
+ gpuType,
298
+ gpuBackend,
299
+ gpuArchitecture,
300
+ shadingLanguage: 'wgsl',
301
+ shadingLanguageVersion: 100
302
+ };
303
+ }
283
304
 
305
+ protected _getFeatures(): DeviceFeatures {
306
+ // Initialize with actual WebGPU Features (note that unknown features may not be in DeviceFeature type)
307
+ const features = new Set<DeviceFeature>(this.handle.features as Set<DeviceFeature>);
284
308
  // Fixups for pre-standard names: https://github.com/webgpu-native/webgpu-headers/issues/133
285
309
  // @ts-expect-error Chrome Canary v99
286
310
  if (features.has('depth-clamping')) {
@@ -289,47 +313,26 @@ export class WebGPUDevice extends Device {
289
313
  features.add('depth-clip-control');
290
314
  }
291
315
 
292
- // Add subsets
316
+ // Some subsets of WebGPU extensions correspond to WebGL extensions
293
317
  if (features.has('texture-compression-bc')) {
294
318
  features.add('texture-compression-bc5-webgl');
295
319
  }
296
320
 
297
- features.add('webgpu');
298
-
299
- features.add('timer-query-webgl');
300
-
301
- // WEBGL1 SUPPORT
302
- features.add('vertex-array-object-webgl1');
303
- features.add('instanced-rendering-webgl1');
304
- features.add('multiple-render-targets-webgl1');
305
- features.add('index-uint32-webgl1');
306
- features.add('blend-minmax-webgl1');
307
- features.add('texture-blend-float-webgl1');
308
-
309
- // TEXTURES, RENDERBUFFERS
310
- features.add('texture-formats-srgb-webgl1');
311
-
312
- // TEXTURES
313
- features.add('texture-formats-depth-webgl1');
314
- features.add('texture-formats-float32-webgl1');
315
- features.add('texture-formats-float16-webgl1');
316
-
317
- features.add('texture-filter-linear-float32-webgl');
318
- features.add('texture-filter-linear-float16-webgl');
319
- features.add('texture-filter-anisotropic-webgl');
320
-
321
- // FRAMEBUFFERS, TEXTURES AND RENDERBUFFERS
322
- features.add('texture-renderable-rgba32float-webgl');
323
- features.add('texture-renderable-float32-webgl');
324
- features.add('texture-renderable-float16-webgl');
325
-
326
- // GLSL extensions
327
- features.add('glsl-frag-data');
328
- features.add('glsl-frag-depth');
329
- features.add('glsl-derivatives');
330
- features.add('glsl-texture-lod');
321
+ const WEBGPU_ALWAYS_FEATURES: DeviceFeature[] = [
322
+ 'timer-query-webgl',
323
+ 'compilation-status-async-webgl',
324
+ 'float32-renderable-webgl',
325
+ 'float16-renderable-webgl',
326
+ 'norm16-renderable-webgl',
327
+ 'texture-filterable-anisotropic-webgl',
328
+ 'shader-noperspective-interpolation-webgl'
329
+ ];
330
+
331
+ for (const feature of WEBGPU_ALWAYS_FEATURES) {
332
+ features.add(feature);
333
+ }
331
334
 
332
- return features;
335
+ return new DeviceFeatures(Array.from(features), this.props.disabledFeatures);
333
336
  }
334
337
 
335
338
  copyExternalImageToTexture(options: {
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- // luma.gl, MIT license
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // WEBGPU ADAPTER
@@ -1 +0,0 @@
1
- {"version":3,"file":"accessor-to-format.js","names":[],"sources":["../../../src/adapter/helpers/accessor-to-format.ts"],"sourcesContent":["/*\nimport {assert} from '@luma.gl/core';\n\ntype Accessor = Record<string, any>;\n\nconst FORMAT_TO_ACCESSOR: Record<GPUVertexFormat, Accessor> = {\n uchar2: {type: 'uchar', size: 2},\n uchar4: {type: 'uchar', size: 4},\n char2: {type: 'char', size: 2},\n char4: {type: 'char', size: 4},\n uchar2norm: {type: 'uchar', size: 2, normalized: true},\n uchar4norm: {type: 'uchar', size: 4, normalized: true},\n char2norm: {type: 'char', size: 2, normalized: true},\n char4norm: {type: 'char', size: 4, normalized: true},\n ushort2: {type: 'ushort', size: 2},\n ushort4: {type: 'ushort', size: 4},\n short2: {type: 'short', size: 2},\n short4: {type: 'short', size: 4},\n ushort2norm: {type: 'ushort', size: 2, normalized: true},\n ushort4norm: {type: 'ushort', size: 4, normalized: true},\n short2norm: {type: 'short', size: 1, normalized: true},\n short4norm: {type: 'short', size: 1, normalized: true},\n half2: {type: 'half', size: 2},\n half4: {type: 'half', size: 4},\n float: {type: 'float', size: 1},\n float2: {type: 'float', size: 2},\n float3: {type: 'float', size: 3},\n float4: {type: 'float', size: 4},\n uint: {type: 'uint', size: 1, integer: true},\n uint2: {type: 'uint', size: 2, integer: true},\n uint3: {type: 'uint', size: 3, integer: true},\n uint4: {type: 'uint', size: 4, integer: true},\n int: {type: 'int', size: 1, integer: true},\n int2: {type: 'int', size: 2, integer: true},\n int3: {type: 'int', size: 3, integer: true},\n int4: {type: 'int', size: 4, integer: true}\n};\n\n/**\n * Convert from WebGPU attribute format strings to accessor {type, size, normalized, integer}\n * @param {*} format\n *\nexport function mapWebGPUFormatToAccessor(format) {\n const accessorDefinition = FORMAT_TO_ACCESSOR[format];\n assert(accessorDefinition, 'invalid attribute format');\n return Object.freeze(accessorDefinition);\n}\n\n/**\n * Convert from accessor {type, size, normalized, integer} to WebGPU attribute format strings\n * @param {*} format\n *\nexport function mapAccessorToWebGPUFormat(accessor) {\n const {type = GL.FLOAT, size = 1, normalized = false, integer = false} = accessor;\n assert(size >=1 && size <=4);\n // `norm` suffix (uchar4norm)\n const norm = normalized ? 'norm' : '';\n // size 1 is ommitted in format names (float vs float2)\n const count = size === 1 ? '' : size;\n switch (type) {\n case GL.UNSIGNED_BYTE:\n switch (size) {\n case 2:\n case 4:\n return `uchar${count}${norm}`;\n }\n case GL.BYTE:\n switch (size) {\n case 2:\n case 4:\n return `char${count}${norm}`;\n }\n case GL.UNSIGNED_SHORT:\n switch (size) {\n case 2:\n case 4:\n return `ushort${count}${norm}`;\n }\n case GL.SHORT:\n switch (size) {\n case 2:\n case 4:\n return `short${count}${norm}`;\n }\n case GL.HALF_FLOAT:\n switch (size) {\n case 2:\n case 4:\n return `half${count}`;\n }\n case GL.FLOAT:\n return `float${count}`;\n case GL.UNSIGNED_INT:\n return `uint${count}`;\n case GL.INT:\n return `int${count}`;\n }\n throw new Error('illegal accessor');\n}\n*/"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"convert-texture-format.js","names":["getWebGPUTextureFormat","format","includes","Error"],"sources":["../../../src/adapter/helpers/convert-texture-format.ts"],"sourcesContent":["// luma.gl, MIT license\nimport {TextureFormat} from '@luma.gl/core';\n\n/** Ensure a texture format is WebGPU compatible */\nexport function getWebGPUTextureFormat(format: TextureFormat): GPUTextureFormat {\n if (format.includes('webgl')) {\n throw new Error('webgl-only format');\n }\n return format as GPUTextureFormat;\n}\n"],"mappings":"AAIA,OAAO,SAASA,sBAAsBA,CAACC,MAAqB,EAAoB;EAC9E,IAAIA,MAAM,CAACC,QAAQ,CAAC,OAAO,CAAC,EAAE;IAC5B,MAAM,IAAIC,KAAK,CAAC,mBAAmB,CAAC;EACtC;EACA,OAAOF,MAAM;AACf"}
@@ -1,10 +0,0 @@
1
- /// <reference types="dist" />
2
- /** WebGPU does not have built-in mipmap creation */
3
- export declare class WebGPUMipmapGenerator {
4
- device: GPUDevice;
5
- mipmapSampler: GPUSampler;
6
- mipmapPipeline: GPURenderPipeline;
7
- constructor(device: GPUDevice, glslang: any);
8
- generateMipmappedTexture(imageBitmap: ImageBitmap): GPUTexture;
9
- }
10
- //# sourceMappingURL=generate-mipmaps.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-mipmaps.d.ts","sourceRoot":"","sources":["../../../src/adapter/helpers/generate-mipmaps.ts"],"names":[],"mappings":";AAuBA,oDAAoD;AACpD,qBAAa,qBAAqB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,iBAAiB,CAAC;gBAEtB,MAAM,EAAE,SAAS,EAAE,OAAO,KAAA;IAyBtC,wBAAwB,CAAC,WAAW,EAAE,WAAW;CAoDlD"}
@@ -1,100 +0,0 @@
1
- const VS_GEN_MIPMAP = `\#version 450
2
- const vec2 pos[4] = vec2[4](vec2(-1.0f, 1.0f), vec2(1.0f, 1.0f), vec2(-1.0f, -1.0f), vec2(1.0f, -1.0f));
3
- layout(location = 0) out vec2 vTex;
4
- void main() {
5
- gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
6
- vTex = gl_Position / 2.0f + vec2(0.5f);
7
- }`;
8
- const FS_GEN_MIPMAP = `#version 450
9
- layout(set = 0, binding = 0) uniform sampler imgSampler;
10
- layout(set = 0, binding = 1) uniform texture2D img;
11
- layout(location = 0) in vec2 vTex;
12
- layout(location = 0) out vec4 outColor;
13
- void main() {
14
- outColor = texture(sampler2D(img, imgSampler), vTex);
15
- }`;
16
- export class WebGPUMipmapGenerator {
17
- constructor(device, glslang) {
18
- this.device = void 0;
19
- this.mipmapSampler = void 0;
20
- this.mipmapPipeline = void 0;
21
- this.device = device;
22
- this.mipmapSampler = device.createSampler({
23
- minFilter: 'linear'
24
- });
25
- this.mipmapPipeline = device.createRenderPipeline({
26
- vertexStage: {
27
- module: device.createShaderModule({
28
- code: glslang.compileGLSL(VS_GEN_MIPMAP, 'vertex')
29
- }),
30
- entryPoint: 'main'
31
- },
32
- fragmentStage: {
33
- module: device.createShaderModule({
34
- code: glslang.compileGLSL(FS_GEN_MIPMAP, 'fragment')
35
- }),
36
- entryPoint: 'main'
37
- },
38
- primitiveTopology: 'triangle-strip',
39
- colorStates: [{
40
- format: 'rgba8unorm'
41
- }]
42
- });
43
- }
44
- generateMipmappedTexture(imageBitmap) {
45
- const textureSize = {
46
- width: imageBitmap.width,
47
- height: imageBitmap.height,
48
- depth: 1
49
- };
50
- const mipLevelCount = Math.floor(Math.log2(Math.max(imageBitmap.width, imageBitmap.height))) + 1;
51
- const texture = this.device.createTexture({
52
- size: textureSize,
53
- format: 'rgba8unorm',
54
- usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED | GPUTextureUsage.OUTPUT_ATTACHMENT,
55
- mipLevelCount
56
- });
57
- this.device.queue.copyImageBitmapToTexture({
58
- imageBitmap
59
- }, {
60
- texture
61
- }, textureSize);
62
- const commandEncoder = this.device.createCommandEncoder({});
63
- for (let i = 1; i < mipLevelCount; ++i) {
64
- const passEncoder = commandEncoder.beginRenderPass({
65
- colorAttachments: [{
66
- attachment: texture.createView({
67
- baseMipLevel: i,
68
- mipLevelCount: 1
69
- }),
70
- loadValue: {
71
- r: 1.0,
72
- g: 0.0,
73
- b: 0.0,
74
- a: 0.0
75
- }
76
- }]
77
- });
78
- const bindGroup = this.device.createBindGroup({
79
- layout: this.mipmapPipeline.getBindGroupLayout(0),
80
- bindings: [{
81
- binding: 0,
82
- resource: this.mipmapSampler
83
- }, {
84
- binding: 1,
85
- resource: texture.createView({
86
- baseMipLevel: i - 1,
87
- mipLevelCount: 1
88
- })
89
- }]
90
- });
91
- passEncoder.setPipeline(this.mipmapPipeline);
92
- passEncoder.setBindGroup(0, bindGroup);
93
- passEncoder.draw(4);
94
- passEncoder.endPass();
95
- }
96
- this.device.queue.submit([commandEncoder.finish()]);
97
- return texture;
98
- }
99
- }
100
- //# sourceMappingURL=generate-mipmaps.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-mipmaps.js","names":["VS_GEN_MIPMAP","FS_GEN_MIPMAP","WebGPUMipmapGenerator","constructor","device","glslang","mipmapSampler","mipmapPipeline","createSampler","minFilter","createRenderPipeline","vertexStage","module","createShaderModule","code","compileGLSL","entryPoint","fragmentStage","primitiveTopology","colorStates","format","generateMipmappedTexture","imageBitmap","textureSize","width","height","depth","mipLevelCount","Math","floor","log2","max","texture","createTexture","size","usage","GPUTextureUsage","COPY_DST","SAMPLED","OUTPUT_ATTACHMENT","queue","copyImageBitmapToTexture","commandEncoder","createCommandEncoder","i","passEncoder","beginRenderPass","colorAttachments","attachment","createView","baseMipLevel","loadValue","r","g","b","a","bindGroup","createBindGroup","layout","getBindGroupLayout","bindings","binding","resource","setPipeline","setBindGroup","draw","endPass","submit","finish"],"sources":["../../../src/adapter/helpers/generate-mipmaps.ts"],"sourcesContent":["// luma.gl, MIT license\n// Forked from Kangz/mipmapper.js under MIT license Copyright 2020 Brandon Jones\n// https://gist.github.com/Kangz/782d5f1ae502daf53910a13f55db2f83\n\n// @ts-nocheck this is written against outdated WebGPU API, needs an update pass\n\nconst VS_GEN_MIPMAP = `\\#version 450\nconst vec2 pos[4] = vec2[4](vec2(-1.0f, 1.0f), vec2(1.0f, 1.0f), vec2(-1.0f, -1.0f), vec2(1.0f, -1.0f));\nlayout(location = 0) out vec2 vTex;\nvoid main() {\n gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);\n vTex = gl_Position / 2.0f + vec2(0.5f);\n}`;\n\nconst FS_GEN_MIPMAP = `#version 450\nlayout(set = 0, binding = 0) uniform sampler imgSampler;\nlayout(set = 0, binding = 1) uniform texture2D img;\nlayout(location = 0) in vec2 vTex;\nlayout(location = 0) out vec4 outColor;\nvoid main() {\n outColor = texture(sampler2D(img, imgSampler), vTex);\n}`;\n\n/** WebGPU does not have built-in mipmap creation */\nexport class WebGPUMipmapGenerator {\n device: GPUDevice;\n mipmapSampler: GPUSampler;\n mipmapPipeline: GPURenderPipeline;\n\n constructor(device: GPUDevice, glslang) {\n this.device = device;\n\n this.mipmapSampler = device.createSampler({ minFilter: 'linear' });\n\n this.mipmapPipeline = device.createRenderPipeline({\n vertexStage: {\n module: device.createShaderModule({\n code: glslang.compileGLSL(VS_GEN_MIPMAP, 'vertex')\n }),\n entryPoint: 'main'\n },\n fragmentStage: {\n module: device.createShaderModule({\n code: glslang.compileGLSL(FS_GEN_MIPMAP, 'fragment')\n }),\n entryPoint: 'main'\n },\n primitiveTopology: 'triangle-strip',\n colorStates: [{\n format: 'rgba8unorm',\n }]\n });\n }\n\n generateMipmappedTexture(imageBitmap: ImageBitmap) {\n const textureSize = {\n width: imageBitmap.width,\n height: imageBitmap.height,\n depth: 1,\n }\n const mipLevelCount = Math.floor(Math.log2(Math.max(imageBitmap.width, imageBitmap.height))) + 1;\n\n // Populate the top level of the srcTexture with the imageBitmap.\n const texture = this.device.createTexture({\n size: textureSize,\n format: 'rgba8unorm',\n usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED | GPUTextureUsage.OUTPUT_ATTACHMENT,\n mipLevelCount\n });\n this.device.queue.copyImageBitmapToTexture({ imageBitmap }, { texture }, textureSize);\n\n const commandEncoder = this.device.createCommandEncoder({});\n for (let i = 1; i < mipLevelCount; ++i) {\n const passEncoder = commandEncoder.beginRenderPass({\n colorAttachments: [{\n attachment: texture.createView({\n baseMipLevel: i,\n mipLevelCount: 1\n }),\n loadValue: { r: 1.0, g: 0.0, b: 0.0, a: 0.0 },\n }],\n });\n\n const bindGroup = this.device.createBindGroup({\n layout: this.mipmapPipeline.getBindGroupLayout(0),\n bindings: [{\n binding: 0,\n resource: this.mipmapSampler,\n }, {\n binding: 1,\n resource: texture.createView({\n baseMipLevel: i - 1,\n mipLevelCount: 1\n }),\n }],\n });\n\n passEncoder.setPipeline(this.mipmapPipeline);\n passEncoder.setBindGroup(0, bindGroup);\n passEncoder.draw(4);\n passEncoder.endPass();\n }\n\n this.device.queue.submit([commandEncoder.finish()]);\n return texture;\n }\n}\n"],"mappings":"AAMA,MAAMA,aAAa,GAAI;AACvB;AACA;AACA;AACA;AACA;AACA,EAAE;AAEF,MAAMC,aAAa,GAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AAGF,OAAO,MAAMC,qBAAqB,CAAC;EAKjCC,WAAWA,CAACC,MAAiB,EAAEC,OAAO,EAAE;IAAA,KAJxCD,MAAM;IAAA,KACNE,aAAa;IAAA,KACbC,cAAc;IAGZ,IAAI,CAACH,MAAM,GAAGA,MAAM;IAEpB,IAAI,CAACE,aAAa,GAAGF,MAAM,CAACI,aAAa,CAAC;MAAEC,SAAS,EAAE;IAAS,CAAC,CAAC;IAElE,IAAI,CAACF,cAAc,GAAGH,MAAM,CAACM,oBAAoB,CAAC;MAChDC,WAAW,EAAE;QACXC,MAAM,EAAER,MAAM,CAACS,kBAAkB,CAAC;UAChCC,IAAI,EAAET,OAAO,CAACU,WAAW,CAACf,aAAa,EAAE,QAAQ;QACnD,CAAC,CAAC;QACFgB,UAAU,EAAE;MACd,CAAC;MACDC,aAAa,EAAE;QACbL,MAAM,EAAER,MAAM,CAACS,kBAAkB,CAAC;UAChCC,IAAI,EAAET,OAAO,CAACU,WAAW,CAACd,aAAa,EAAE,UAAU;QACrD,CAAC,CAAC;QACFe,UAAU,EAAE;MACd,CAAC;MACDE,iBAAiB,EAAE,gBAAgB;MACnCC,WAAW,EAAE,CAAC;QACZC,MAAM,EAAE;MACV,CAAC;IACH,CAAC,CAAC;EACJ;EAEAC,wBAAwBA,CAACC,WAAwB,EAAE;IACjD,MAAMC,WAAW,GAAG;MAClBC,KAAK,EAAEF,WAAW,CAACE,KAAK;MACxBC,MAAM,EAAEH,WAAW,CAACG,MAAM;MAC1BC,KAAK,EAAE;IACT,CAAC;IACD,MAAMC,aAAa,GAAGC,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,IAAI,CAACF,IAAI,CAACG,GAAG,CAACT,WAAW,CAACE,KAAK,EAAEF,WAAW,CAACG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IAGhG,MAAMO,OAAO,GAAG,IAAI,CAAC5B,MAAM,CAAC6B,aAAa,CAAC;MACxCC,IAAI,EAAEX,WAAW;MACjBH,MAAM,EAAE,YAAY;MACpBe,KAAK,EAAEC,eAAe,CAACC,QAAQ,GAAGD,eAAe,CAACE,OAAO,GAAGF,eAAe,CAACG,iBAAiB;MAC7FZ;IACF,CAAC,CAAC;IACF,IAAI,CAACvB,MAAM,CAACoC,KAAK,CAACC,wBAAwB,CAAC;MAAEnB;IAAY,CAAC,EAAE;MAAEU;IAAQ,CAAC,EAAET,WAAW,CAAC;IAErF,MAAMmB,cAAc,GAAG,IAAI,CAACtC,MAAM,CAACuC,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAC3D,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGjB,aAAa,EAAE,EAAEiB,CAAC,EAAE;MACtC,MAAMC,WAAW,GAAGH,cAAc,CAACI,eAAe,CAAC;QACjDC,gBAAgB,EAAE,CAAC;UACjBC,UAAU,EAAEhB,OAAO,CAACiB,UAAU,CAAC;YAC7BC,YAAY,EAAEN,CAAC;YACfjB,aAAa,EAAE;UACjB,CAAC,CAAC;UACFwB,SAAS,EAAE;YAAEC,CAAC,EAAE,GAAG;YAAEC,CAAC,EAAE,GAAG;YAAEC,CAAC,EAAE,GAAG;YAAEC,CAAC,EAAE;UAAI;QAC9C,CAAC;MACH,CAAC,CAAC;MAEF,MAAMC,SAAS,GAAG,IAAI,CAACpD,MAAM,CAACqD,eAAe,CAAC;QAC5CC,MAAM,EAAE,IAAI,CAACnD,cAAc,CAACoD,kBAAkB,CAAC,CAAC,CAAC;QACjDC,QAAQ,EAAE,CAAC;UACTC,OAAO,EAAE,CAAC;UACVC,QAAQ,EAAE,IAAI,CAACxD;QACjB,CAAC,EAAE;UACDuD,OAAO,EAAE,CAAC;UACVC,QAAQ,EAAE9B,OAAO,CAACiB,UAAU,CAAC;YAC3BC,YAAY,EAAEN,CAAC,GAAG,CAAC;YACnBjB,aAAa,EAAE;UACjB,CAAC;QACH,CAAC;MACH,CAAC,CAAC;MAEFkB,WAAW,CAACkB,WAAW,CAAC,IAAI,CAACxD,cAAc,CAAC;MAC5CsC,WAAW,CAACmB,YAAY,CAAC,CAAC,EAAER,SAAS,CAAC;MACtCX,WAAW,CAACoB,IAAI,CAAC,CAAC,CAAC;MACnBpB,WAAW,CAACqB,OAAO,CAAC,CAAC;IACvB;IAEA,IAAI,CAAC9D,MAAM,CAACoC,KAAK,CAAC2B,MAAM,CAAC,CAACzB,cAAc,CAAC0B,MAAM,CAAC,CAAC,CAAC,CAAC;IACnD,OAAOpC,OAAO;EAChB;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-bind-group.js","names":["Buffer","Sampler","Texture","log","cast","makeBindGroupLayout","device","layout","bindings","Error","getBindGroup","bindGroupLayout","shaderLayout","entries","getBindGroupEntries","createBindGroup","getShaderLayoutBinding","bindingName","bindingLayout","find","binding","name","warn","value","Object","push","getBindGroupEntry","location","index","resource","buffer","handle","createView","label"],"sources":["../../../src/adapter/helpers/get-bind-group.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BindingDeclaration, Binding} from '@luma.gl/core';\nimport {Buffer, Sampler, Texture, log, cast} from '@luma.gl/core';\nimport type {WebGPUBuffer} from '../resources/webgpu-buffer';\nimport type {WebGPUSampler} from '../resources/webgpu-sampler';\nimport type {WebGPUTexture} from '../resources/webgpu-texture';\n\n/**\n * Create a WebGPU \"bind group layout\" from an array of luma.gl bindings\n * @note bind groups can be automatically generated by WebGPU.\n */\nexport function makeBindGroupLayout(\n device: GPUDevice,\n layout: GPUBindGroupLayout,\n bindings: Binding[]\n): GPUBindGroupLayout {\n throw new Error('not implemented');\n // return device.createBindGroupLayout({\n // layout,\n // entries: getBindGroupEntries(bindings)\n // })\n}\n\n/**\n * Create a WebGPU \"bind group\" from an array of luma.gl bindings\n */\nexport function getBindGroup(\n device: GPUDevice,\n bindGroupLayout: GPUBindGroupLayout,\n shaderLayout: ShaderLayout,\n bindings: Record<string, Binding>\n): GPUBindGroup {\n const entries = getBindGroupEntries(bindings, shaderLayout);\n return device.createBindGroup({\n layout: bindGroupLayout,\n entries\n });\n}\n\nexport function getShaderLayoutBinding(\n shaderLayout: ShaderLayout,\n bindingName: string\n): BindingDeclaration {\n const bindingLayout = shaderLayout.bindings.find(binding => binding.name === bindingName);\n if (!bindingLayout) {\n log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();\n }\n return bindingLayout;\n}\n\n/**\n * @param bindings\n * @returns\n */\nfunction getBindGroupEntries(\n bindings: Record<string, Binding>,\n shaderLayout: ShaderLayout\n): GPUBindGroupEntry[] {\n const entries: GPUBindGroupEntry[] = [];\n\n for (const [bindingName, value] of Object.entries(bindings)) {\n const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);\n if (bindingLayout) {\n entries.push(getBindGroupEntry(value, bindingLayout.location));\n }\n }\n\n return entries;\n}\n\nfunction getBindGroupEntry(binding: Binding, index: number): GPUBindGroupEntry {\n if (binding instanceof Buffer) {\n return {\n binding: index,\n resource: {\n buffer: cast<WebGPUBuffer>(binding).handle\n }\n };\n }\n if (binding instanceof Sampler) {\n return {\n binding: index,\n resource: cast<WebGPUSampler>(binding).handle\n };\n } else if (binding instanceof Texture) {\n return {\n binding: index,\n resource: cast<WebGPUTexture>(binding).handle.createView({label: 'bind-group-auto-created'})\n };\n }\n throw new Error('invalid binding');\n}\n"],"mappings":"AAEA,SAAQA,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,QAAO,eAAe;AASjE,OAAO,SAASC,mBAAmBA,CACjCC,MAAiB,EACjBC,MAA0B,EAC1BC,QAAmB,EACC;EACpB,MAAM,IAAIC,KAAK,CAAC,iBAAiB,CAAC;AAKpC;AAKA,OAAO,SAASC,YAAYA,CAC1BJ,MAAiB,EACjBK,eAAmC,EACnCC,YAA0B,EAC1BJ,QAAiC,EACnB;EACd,MAAMK,OAAO,GAAGC,mBAAmB,CAACN,QAAQ,EAAEI,YAAY,CAAC;EAC3D,OAAON,MAAM,CAACS,eAAe,CAAC;IAC5BR,MAAM,EAAEI,eAAe;IACvBE;EACF,CAAC,CAAC;AACJ;AAEA,OAAO,SAASG,sBAAsBA,CACpCJ,YAA0B,EAC1BK,WAAmB,EACC;EACpB,MAAMC,aAAa,GAAGN,YAAY,CAACJ,QAAQ,CAACW,IAAI,CAACC,OAAO,IAAIA,OAAO,CAACC,IAAI,KAAKJ,WAAW,CAAC;EACzF,IAAI,CAACC,aAAa,EAAE;IAClBf,GAAG,CAACmB,IAAI,CAAE,WAAUL,WAAY,uCAAsC,CAAC,CAAC,CAAC;EAC3E;EACA,OAAOC,aAAa;AACtB;AAMA,SAASJ,mBAAmBA,CAC1BN,QAAiC,EACjCI,YAA0B,EACL;EACrB,MAAMC,OAA4B,GAAG,EAAE;EAEvC,KAAK,MAAM,CAACI,WAAW,EAAEM,KAAK,CAAC,IAAIC,MAAM,CAACX,OAAO,CAACL,QAAQ,CAAC,EAAE;IAC3D,MAAMU,aAAa,GAAGF,sBAAsB,CAACJ,YAAY,EAAEK,WAAW,CAAC;IACvE,IAAIC,aAAa,EAAE;MACjBL,OAAO,CAACY,IAAI,CAACC,iBAAiB,CAACH,KAAK,EAAEL,aAAa,CAACS,QAAQ,CAAC,CAAC;IAChE;EACF;EAEA,OAAOd,OAAO;AAChB;AAEA,SAASa,iBAAiBA,CAACN,OAAgB,EAAEQ,KAAa,EAAqB;EAC7E,IAAIR,OAAO,YAAYpB,MAAM,EAAE;IAC7B,OAAO;MACLoB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAE;QACRC,MAAM,EAAE1B,IAAI,CAAegB,OAAO,CAAC,CAACW;MACtC;IACF,CAAC;EACH;EACA,IAAIX,OAAO,YAAYnB,OAAO,EAAE;IAC9B,OAAO;MACLmB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAEzB,IAAI,CAAgBgB,OAAO,CAAC,CAACW;IACzC,CAAC;EACH,CAAC,MAAM,IAAIX,OAAO,YAAYlB,OAAO,EAAE;IACrC,OAAO;MACLkB,OAAO,EAAEQ,KAAK;MACdC,QAAQ,EAAEzB,IAAI,CAAgBgB,OAAO,CAAC,CAACW,MAAM,CAACC,UAAU,CAAC;QAACC,KAAK,EAAE;MAAyB,CAAC;IAC7F,CAAC;EACH;EACA,MAAM,IAAIxB,KAAK,CAAC,iBAAiB,CAAC;AACpC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-vertex-buffer-layout.js","names":["log","decodeVertexFormat","getWebGPUVertexFormat","format","endsWith","Error","getVertexBufferLayout","shaderLayout","bufferLayout","vertexBufferLayouts","usedAttributes","Set","mapping","vertexAttributes","stepMode","byteStride","attributes","attributeMapping","attributeName","attribute","attributeLayout","findAttributeLayout","push","offset","byteOffset","shaderLocation","location","byteLength","name","arrayStride","has","getBufferSlots","bufferSlot","bufferSlots","interleaved","add","attributeNames","find","warn"],"sources":["../../../src/adapter/helpers/get-vertex-buffer-layout.ts"],"sourcesContent":["// luma.gl, MIT license\nimport type {ShaderLayout, BufferLayout, AttributeDeclaration, VertexFormat} from '@luma.gl/core';\nimport {log, decodeVertexFormat} from '@luma.gl/core';\n// import {getAttributeInfosFromLayouts} from '@luma.gl/core';\n\n/** Throw error on any WebGL-only vertex formats */\nfunction getWebGPUVertexFormat(format: VertexFormat): GPUVertexFormat {\n if (format.endsWith('-webgl')) {\n throw new Error(`WebGPU does not support vertex format ${format}`);\n }\n return format as GPUVertexFormat;\n}\n\n/**\n * Build a WebGPU vertex buffer layout intended for use in a GPURenderPassDescriptor.\n * Converts luma.gl attribute definitions to a WebGPU GPUVertexBufferLayout[] array\n * @param layout\n * @param bufferLayout The buffer map is optional\n * @returns WebGPU layout intended for a GPURenderPassDescriptor.\n */\nexport function getVertexBufferLayout(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): GPUVertexBufferLayout[] {\n const vertexBufferLayouts: GPUVertexBufferLayout[] = [];\n const usedAttributes = new Set<string>();\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // Build vertex attributes for one buffer\n const vertexAttributes: GPUVertexAttribute[] = [];\n\n // TODO verify that all stepModes for one buffer are the same\n let stepMode: 'vertex' | 'instance' = 'vertex';\n let byteStride = 0;\n // interleaved mapping {..., attributes: [{...}, ...]}\n if (mapping.attributes) {\n // const arrayStride = mapping.byteStride; TODO\n for (const attributeMapping of mapping.attributes) {\n const attributeName = attributeMapping.attribute;\n const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);\n\n stepMode = attributeLayout.stepMode || 'vertex';\n vertexAttributes.push({\n format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),\n offset: attributeMapping.byteOffset,\n shaderLocation: attributeLayout.location\n });\n\n byteStride += decodeVertexFormat(mapping.format).byteLength;\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n const attributeLayout = findAttributeLayout(shaderLayout, mapping.name, usedAttributes);\n if (!attributeLayout) {\n continue; // eslint-disable-line no-continue\n }\n byteStride = decodeVertexFormat(mapping.format).byteLength;\n\n stepMode = attributeLayout.stepMode || 'vertex';\n vertexAttributes.push({\n format: getWebGPUVertexFormat(mapping.format),\n // We only support 0 offset for non-interleaved buffer layouts\n offset: 0,\n shaderLocation: attributeLayout.location\n });\n }\n\n // Store all the attribute bindings for one buffer\n vertexBufferLayouts.push({\n arrayStride: mapping.byteStride || byteStride,\n stepMode: stepMode || 'vertex',\n attributes: vertexAttributes\n });\n }\n\n // Add any non-mapped attributes - TODO - avoid hardcoded types\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n vertexBufferLayouts.push({\n arrayStride: decodeVertexFormat('float32x3').byteLength,\n stepMode: attribute.stepMode || 'vertex',\n attributes: [\n {\n format: getWebGPUVertexFormat('float32x3'),\n offset: 0,\n shaderLocation: attribute.location\n }\n ]\n });\n }\n }\n\n return vertexBufferLayouts;\n}\n\nexport function getBufferSlots(\n shaderLayout: ShaderLayout,\n bufferLayout: BufferLayout[]\n): Record<string, number> {\n const usedAttributes = new Set<string>();\n let bufferSlot = 0;\n const bufferSlots: Record<string, number> = {};\n\n // First handle any buffers mentioned in `bufferLayout`\n for (const mapping of bufferLayout) {\n // interleaved mapping {..., attributes: [{...}, ...]}\n if ('attributes' in mapping) {\n for (const interleaved of mapping.attributes) {\n usedAttributes.add(interleaved.attribute);\n }\n // non-interleaved mapping (just set offset and stride)\n } else {\n usedAttributes.add(mapping.name);\n }\n bufferSlots[mapping.name] = bufferSlot++;\n }\n\n // Add any non-mapped attributes\n for (const attribute of shaderLayout.attributes) {\n if (!usedAttributes.has(attribute.name)) {\n bufferSlots[attribute.name] = bufferSlot++;\n }\n }\n\n return bufferSlots;\n}\n\n/**\n * Looks up an attribute in the ShaderLayout.\n * @throws if name is not in ShaderLayout\n * @throws if name has already been referenced\n */\nfunction findAttributeLayout(\n shaderLayout: ShaderLayout,\n name: string,\n attributeNames: Set<string>\n): AttributeDeclaration {\n const attribute = shaderLayout.attributes.find(attribute => attribute.name === name);\n if (!attribute) {\n log.warn(`Unknown attribute ${name}`)();\n return null;\n }\n if (attributeNames.has(name)) {\n throw new Error(`Duplicate attribute ${name}`);\n }\n attributeNames.add(name);\n return attribute;\n}\n"],"mappings":"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"}