@luma.gl/core 9.2.0-alpha.1 → 9.2.0-alpha.5

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 (167) hide show
  1. package/dist/adapter/canvas-context.d.ts +19 -5
  2. package/dist/adapter/canvas-context.d.ts.map +1 -1
  3. package/dist/adapter/canvas-context.js +53 -3
  4. package/dist/adapter/canvas-context.js.map +1 -1
  5. package/dist/adapter/device.d.ts +56 -11
  6. package/dist/adapter/device.d.ts.map +1 -1
  7. package/dist/adapter/device.js +78 -22
  8. package/dist/adapter/device.js.map +1 -1
  9. package/dist/adapter/luma.js +1 -1
  10. package/dist/adapter/resources/buffer.d.ts +13 -7
  11. package/dist/adapter/resources/buffer.d.ts.map +1 -1
  12. package/dist/adapter/resources/buffer.js +1 -5
  13. package/dist/adapter/resources/buffer.js.map +1 -1
  14. package/dist/adapter/resources/command-encoder.d.ts +0 -1
  15. package/dist/adapter/resources/command-encoder.d.ts.map +1 -1
  16. package/dist/adapter/resources/command-encoder.js.map +1 -1
  17. package/dist/adapter/resources/framebuffer.d.ts +3 -3
  18. package/dist/adapter/resources/framebuffer.d.ts.map +1 -1
  19. package/dist/adapter/resources/pipeline-layout.d.ts +13 -0
  20. package/dist/adapter/resources/pipeline-layout.d.ts.map +1 -0
  21. package/dist/adapter/resources/pipeline-layout.js +21 -0
  22. package/dist/adapter/resources/pipeline-layout.js.map +1 -0
  23. package/dist/adapter/resources/render-pipeline.d.ts +4 -4
  24. package/dist/adapter/resources/render-pipeline.d.ts.map +1 -1
  25. package/dist/adapter/resources/resource.d.ts +1 -0
  26. package/dist/adapter/resources/resource.d.ts.map +1 -1
  27. package/dist/adapter/resources/resource.js.map +1 -1
  28. package/dist/adapter/resources/texture-view.d.ts +1 -1
  29. package/dist/adapter/resources/texture-view.d.ts.map +1 -1
  30. package/dist/adapter/resources/texture.d.ts +1 -1
  31. package/dist/adapter/resources/texture.d.ts.map +1 -1
  32. package/dist/adapter/resources/vertex-array.js +1 -1
  33. package/dist/adapter/resources/vertex-array.js.map +1 -1
  34. package/dist/adapter/types/attachments.d.ts +3 -3
  35. package/dist/adapter/types/attachments.d.ts.map +1 -1
  36. package/dist/adapter/types/buffer-layout.d.ts +1 -1
  37. package/dist/adapter/types/buffer-layout.d.ts.map +1 -1
  38. package/dist/adapter/types/parameters.d.ts +2 -2
  39. package/dist/adapter/types/parameters.d.ts.map +1 -1
  40. package/dist/adapter/types/shader-layout.d.ts +5 -6
  41. package/dist/adapter/types/shader-layout.d.ts.map +1 -1
  42. package/dist/adapter-utils/get-attribute-from-layouts.d.ts +3 -3
  43. package/dist/adapter-utils/get-attribute-from-layouts.d.ts.map +1 -1
  44. package/dist/adapter-utils/get-attribute-from-layouts.js +2 -2
  45. package/dist/adapter-utils/get-attribute-from-layouts.js.map +1 -1
  46. package/dist/dist.dev.js +430 -274
  47. package/dist/dist.min.js +5 -4
  48. package/dist/index.cjs +426 -273
  49. package/dist/index.cjs.map +4 -4
  50. package/dist/index.d.ts +18 -20
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +8 -7
  53. package/dist/index.js.map +1 -1
  54. package/dist/portable/uniform-block.d.ts +1 -1
  55. package/dist/portable/uniform-block.d.ts.map +1 -1
  56. package/dist/portable/uniform-buffer-layout.d.ts +3 -3
  57. package/dist/portable/uniform-buffer-layout.d.ts.map +1 -1
  58. package/dist/portable/uniform-buffer-layout.js +8 -9
  59. package/dist/portable/uniform-buffer-layout.js.map +1 -1
  60. package/dist/portable/uniform-store.d.ts +2 -1
  61. package/dist/portable/uniform-store.d.ts.map +1 -1
  62. package/dist/portable/uniform-store.js +1 -1
  63. package/dist/portable/uniform-store.js.map +1 -1
  64. package/dist/shadertypes/{data-types.d.ts → data-types/data-types.d.ts} +4 -0
  65. package/dist/shadertypes/data-types/data-types.d.ts.map +1 -0
  66. package/dist/shadertypes/data-types/data-types.js.map +1 -0
  67. package/dist/shadertypes/{utils → data-types}/decode-data-types.d.ts +4 -4
  68. package/dist/shadertypes/data-types/decode-data-types.d.ts.map +1 -0
  69. package/dist/shadertypes/data-types/decode-data-types.js +74 -0
  70. package/dist/shadertypes/data-types/decode-data-types.js.map +1 -0
  71. package/dist/shadertypes/{utils → data-types}/decode-shader-types.d.ts +2 -2
  72. package/dist/shadertypes/data-types/decode-shader-types.d.ts.map +1 -0
  73. package/dist/shadertypes/data-types/decode-shader-types.js.map +1 -0
  74. package/dist/shadertypes/data-types/shader-types.d.ts.map +1 -0
  75. package/dist/shadertypes/data-types/shader-types.js.map +1 -0
  76. package/dist/shadertypes/textures/pixel-utils.d.ts +112 -0
  77. package/dist/shadertypes/textures/pixel-utils.d.ts.map +1 -0
  78. package/dist/shadertypes/textures/pixel-utils.js +193 -0
  79. package/dist/shadertypes/textures/pixel-utils.js.map +1 -0
  80. package/dist/shadertypes/textures/texture-format-decoder.d.ts +18 -0
  81. package/dist/shadertypes/textures/texture-format-decoder.d.ts.map +1 -0
  82. package/dist/shadertypes/{utils/decode-texture-format.js → textures/texture-format-decoder.js} +48 -35
  83. package/dist/shadertypes/textures/texture-format-decoder.js.map +1 -0
  84. package/dist/shadertypes/textures/texture-format-generics.d.ts +33 -0
  85. package/dist/shadertypes/textures/texture-format-generics.d.ts.map +1 -0
  86. package/dist/shadertypes/{texture-formats.js → textures/texture-format-generics.js} +1 -1
  87. package/dist/shadertypes/textures/texture-format-generics.js.map +1 -0
  88. package/dist/shadertypes/{utils → textures}/texture-format-table.d.ts +2 -1
  89. package/dist/shadertypes/textures/texture-format-table.d.ts.map +1 -0
  90. package/dist/shadertypes/{utils → textures}/texture-format-table.js +41 -42
  91. package/dist/shadertypes/textures/texture-format-table.js.map +1 -0
  92. package/dist/shadertypes/textures/texture-formats.d.ts +90 -0
  93. package/dist/shadertypes/textures/texture-formats.d.ts.map +1 -0
  94. package/dist/shadertypes/textures/texture-formats.js +58 -0
  95. package/dist/shadertypes/textures/texture-formats.js.map +1 -0
  96. package/dist/shadertypes/{utils → vertex-arrays}/decode-vertex-format.d.ts +2 -2
  97. package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts.map +1 -0
  98. package/dist/shadertypes/{utils → vertex-arrays}/decode-vertex-format.js +4 -4
  99. package/dist/shadertypes/vertex-arrays/decode-vertex-format.js.map +1 -0
  100. package/dist/shadertypes/{vertex-formats.d.ts → vertex-arrays/vertex-formats.d.ts} +5 -3
  101. package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts.map +1 -0
  102. package/dist/shadertypes/vertex-arrays/vertex-formats.js.map +1 -0
  103. package/package.json +2 -2
  104. package/src/adapter/canvas-context.ts +66 -8
  105. package/src/adapter/device.ts +132 -47
  106. package/src/adapter/resources/buffer.ts +30 -14
  107. package/src/adapter/resources/command-encoder.ts +0 -2
  108. package/src/adapter/resources/framebuffer.ts +5 -5
  109. package/src/adapter/resources/pipeline-layout.ts +30 -0
  110. package/src/adapter/resources/render-pipeline.ts +6 -6
  111. package/src/adapter/resources/resource.ts +1 -0
  112. package/src/adapter/resources/texture-view.ts +1 -1
  113. package/src/adapter/resources/texture.ts +1 -1
  114. package/src/adapter/resources/vertex-array.ts +1 -1
  115. package/src/adapter/types/attachments.ts +5 -5
  116. package/src/adapter/types/buffer-layout.ts +1 -1
  117. package/src/adapter/types/parameters.ts +2 -2
  118. package/src/adapter/types/shader-layout.ts +8 -5
  119. package/src/adapter-utils/get-attribute-from-layouts.ts +5 -5
  120. package/src/index.ts +60 -36
  121. package/src/portable/uniform-block.ts +1 -1
  122. package/src/portable/uniform-buffer-layout.ts +13 -12
  123. package/src/portable/uniform-store.ts +6 -2
  124. package/src/shadertypes/data-types/data-types.ts +96 -0
  125. package/src/shadertypes/data-types/decode-data-types.ts +91 -0
  126. package/src/shadertypes/{utils → data-types}/decode-shader-types.ts +2 -2
  127. package/src/shadertypes/textures/pixel-utils.ts +239 -0
  128. package/src/shadertypes/{utils/decode-texture-format.ts → textures/texture-format-decoder.ts} +63 -47
  129. package/src/shadertypes/textures/texture-format-generics.ts +190 -0
  130. package/src/shadertypes/{utils → textures}/texture-format-table.ts +62 -52
  131. package/src/shadertypes/{texture-formats.ts → textures/texture-formats.ts} +229 -147
  132. package/src/shadertypes/{utils → vertex-arrays}/decode-vertex-format.ts +6 -10
  133. package/src/shadertypes/{vertex-formats.ts → vertex-arrays/vertex-formats.ts} +20 -6
  134. package/dist/adapter-utils/buffer-layout-helper.d.ts +0 -11
  135. package/dist/adapter-utils/buffer-layout-helper.d.ts.map +0 -1
  136. package/dist/adapter-utils/buffer-layout-helper.js +0 -33
  137. package/dist/adapter-utils/buffer-layout-helper.js.map +0 -1
  138. package/dist/shadertypes/data-types.d.ts.map +0 -1
  139. package/dist/shadertypes/data-types.js.map +0 -1
  140. package/dist/shadertypes/shader-types.d.ts.map +0 -1
  141. package/dist/shadertypes/shader-types.js.map +0 -1
  142. package/dist/shadertypes/texture-formats.d.ts +0 -74
  143. package/dist/shadertypes/texture-formats.d.ts.map +0 -1
  144. package/dist/shadertypes/texture-formats.js.map +0 -1
  145. package/dist/shadertypes/utils/decode-data-types.d.ts.map +0 -1
  146. package/dist/shadertypes/utils/decode-data-types.js +0 -114
  147. package/dist/shadertypes/utils/decode-data-types.js.map +0 -1
  148. package/dist/shadertypes/utils/decode-shader-types.d.ts.map +0 -1
  149. package/dist/shadertypes/utils/decode-shader-types.js.map +0 -1
  150. package/dist/shadertypes/utils/decode-texture-format.d.ts +0 -15
  151. package/dist/shadertypes/utils/decode-texture-format.d.ts.map +0 -1
  152. package/dist/shadertypes/utils/decode-texture-format.js.map +0 -1
  153. package/dist/shadertypes/utils/decode-vertex-format.d.ts.map +0 -1
  154. package/dist/shadertypes/utils/decode-vertex-format.js.map +0 -1
  155. package/dist/shadertypes/utils/texture-format-table.d.ts.map +0 -1
  156. package/dist/shadertypes/utils/texture-format-table.js.map +0 -1
  157. package/dist/shadertypes/vertex-formats.d.ts.map +0 -1
  158. package/dist/shadertypes/vertex-formats.js.map +0 -1
  159. package/src/adapter-utils/buffer-layout-helper.ts +0 -41
  160. package/src/shadertypes/data-types.ts +0 -42
  161. package/src/shadertypes/utils/decode-data-types.ts +0 -131
  162. /package/dist/shadertypes/{data-types.js → data-types/data-types.js} +0 -0
  163. /package/dist/shadertypes/{utils → data-types}/decode-shader-types.js +0 -0
  164. /package/dist/shadertypes/{shader-types.d.ts → data-types/shader-types.d.ts} +0 -0
  165. /package/dist/shadertypes/{shader-types.js → data-types/shader-types.js} +0 -0
  166. /package/dist/shadertypes/{vertex-formats.js → vertex-arrays/vertex-formats.js} +0 -0
  167. /package/src/shadertypes/{shader-types.ts → data-types/shader-types.ts} +0 -0
@@ -5,7 +5,8 @@
5
5
  import {StatsManager, lumaStats} from '../utils/stats-manager';
6
6
  import {log} from '../utils/log';
7
7
  import {uid} from '../utils/uid';
8
- import type {TextureFormat, TextureFormatInfo} from '../shadertypes/texture-formats';
8
+ import type {VertexFormat, VertexFormatInfo} from '../shadertypes/vertex-arrays/vertex-formats';
9
+ import type {TextureFormat, TextureFormatInfo} from '../shadertypes/textures/texture-formats';
9
10
  import type {CanvasContext, CanvasContextProps} from './canvas-context';
10
11
  import type {BufferProps} from './resources/buffer';
11
12
  import {Buffer} from './resources/buffer';
@@ -24,12 +25,8 @@ import type {VertexArray, VertexArrayProps} from './resources/vertex-array';
24
25
  import type {TransformFeedback, TransformFeedbackProps} from './resources/transform-feedback';
25
26
  import type {QuerySet, QuerySetProps} from './resources/query-set';
26
27
 
27
- import {
28
- isTextureFormatCompressed,
29
- getTextureFormatInfo,
30
- getTextureFormatCapabilities
31
- } from '../shadertypes/utils/decode-texture-format';
32
-
28
+ import {getVertexFormatInfo} from '../shadertypes/vertex-arrays/decode-vertex-format';
29
+ import {textureFormatDecoder} from '../shadertypes/textures/texture-format-decoder';
33
30
  import type {ExternalImage} from '../image-utils/image-types';
34
31
  import {isExternalImage, getExternalImageSize} from '../image-utils/image-types';
35
32
 
@@ -147,19 +144,29 @@ export type DeviceFeature =
147
144
  | WebGPUDeviceFeature
148
145
  | WebGLDeviceFeature
149
146
  | WebGLCompressedTextureFeatures;
147
+ // | ChromeExperimentalFeatures
148
+
149
+ /** Chrome-specific extensions. Expected to eventually become standard features. */
150
+ // export type ChromeExperimentalFeatures = ;
150
151
 
151
152
  export type WebGPUDeviceFeature =
152
153
  | 'depth-clip-control'
153
- | 'indirect-first-instance'
154
+ | 'depth32float-stencil8'
155
+ | 'texture-compression-bc'
156
+ | 'texture-compression-bc-sliced-3d'
157
+ | 'texture-compression-etc2'
158
+ | 'texture-compression-astc'
159
+ | 'texture-compression-astc-sliced-3d'
154
160
  | 'timestamp-query'
161
+ | 'indirect-first-instance'
155
162
  | 'shader-f16'
156
- | 'depth32float-stencil8'
157
163
  | 'rg11b10ufloat-renderable' // Is the rg11b10ufloat texture format renderable?
158
- | 'float32-filterable' // Is the float32 format filterable?
159
164
  | 'bgra8unorm-storage' // Can the bgra8unorm texture format be used in storage buffers?
160
- | 'texture-compression-bc'
161
- | 'texture-compression-etc2'
162
- | 'texture-compression-astc';
165
+ | 'float32-filterable' // Is the float32 format filterable?
166
+ | 'float32-blendable' // Is the float32 format blendable?
167
+ | 'clip-distances'
168
+ | 'dual-source-blending'
169
+ | 'subgroups';
163
170
  // | 'depth-clamping' // removed from the WebGPU spec...
164
171
  // | 'pipeline-statistics-query' // removed from the WebGPU spec...
165
172
 
@@ -231,20 +238,22 @@ export type DeviceProps = {
231
238
 
232
239
  // CALLBACKS
233
240
 
234
- /** Error handling - uncaught errors */
241
+ /** Error handler. If it returns a probe logger style function, it will be called at the site of the error to optimize console error links. */
235
242
  onError?: (error: Error, context?: unknown) => unknown;
236
- /** Called when the size of a canvas changes */
243
+ /** Called when the size of a CanvasContext's canvas changes */
237
244
  onResize?: (ctx: CanvasContext, info: {oldPixelSize: [number, number]}) => unknown;
238
- /** Called when the visibility of a canvas changes */
245
+ /** Called when the absolute position of a CanvasContext's canvas changes. Must set `CanvasContextProps.trackPosition: true` */
246
+ onPositionChange?: (ctx: CanvasContext, info: {oldPosition: [number, number]}) => unknown;
247
+ /** Called when the visibility of a CanvasContext's canvas changes */
239
248
  onVisibilityChange?: (ctx: CanvasContext) => unknown;
240
- /** Called when the device pixel ratio of a canvas changes */
249
+ /** Called when the device pixel ratio of a CanvasContext's canvas changes */
241
250
  onDevicePixelRatioChange?: (ctx: CanvasContext, info: {oldRatio: number}) => unknown;
242
251
 
243
252
  // DEBUG SETTINGS
244
253
 
245
254
  /** Turn on implementation defined checks that slow down execution but help break where errors occur */
246
255
  debug?: boolean;
247
- /** Show shader source in browser? The default is`'error'`, meaning that logs are shown when shader compilation has errors */
256
+ /** Show shader source in browser? The default is `'error'`, meaning that logs are shown when shader compilation has errors */
248
257
  debugShaders?: 'never' | 'errors' | 'warnings' | 'always';
249
258
  /** Renders a small version of updated Framebuffers into the primary canvas context. Can be set in console luma.log.set('debug-framebuffers', true) */
250
259
  debugFramebuffers?: boolean;
@@ -259,6 +268,8 @@ export type DeviceProps = {
259
268
 
260
269
  // EXPERIMENTAL SETTINGS - subject to change
261
270
 
271
+ /** adapter.create() returns the existing Device if the provided canvas' WebGL context is already associated with a Device. */
272
+ _reuseDevices?: boolean;
262
273
  /** WebGPU specific - Request a Device with the highest limits supported by platform. On WebGPU devices can be created with minimal limits. */
263
274
  _requestMaxLimits?: boolean;
264
275
  /** Disable specific features */
@@ -278,14 +289,24 @@ export type DeviceProps = {
278
289
 
279
290
  /** WebGL independent copy of WebGLContextAttributes */
280
291
  type WebGLContextProps = {
281
- alpha?: boolean; // indicates if the canvas contains an alpha buffer.
282
- desynchronized?: boolean; // hints the user agent to reduce the latency by desynchronizing the canvas paint cycle from the event loop
283
- antialias?: boolean; // indicates whether or not to perform anti-aliasing.
284
- depth?: boolean; // indicates that the drawing buffer has a depth buffer of at least 16 bits.
285
- failIfMajorPerformanceCaveat?: boolean; // indicates if a context will be created if the system performance is low or if no hardware GPU is available.
292
+ /** indicates if the canvas contains an alpha buffer. */
293
+ alpha?: boolean;
294
+ /** hints the user agent to reduce the latency by desynchronizing the canvas paint cycle from the event loop */
295
+ desynchronized?: boolean;
296
+ /** indicates whether or not to perform anti-aliasing. */
297
+ antialias?: boolean;
298
+ /** indicates that the render target has a stencil buffer of at least `8` bits. */
299
+ stencil?: boolean;
300
+ /** indicates that the drawing buffer has a depth buffer of at least 16 bits. */
301
+ depth?: boolean;
302
+ /** indicates if a context will be created if the system performance is low or if no hardware GPU is available. */
303
+ failIfMajorPerformanceCaveat?: boolean;
304
+ /** Selects GPU */
286
305
  powerPreference?: 'default' | 'high-performance' | 'low-power';
287
- premultipliedAlpha?: boolean; // page compositor will assume the drawing buffer contains colors with pre-multiplied alpha.
288
- preserveDrawingBuffer?: boolean; // buffers will not be cleared and will preserve their values until cleared or overwritten by the author.
306
+ /** page compositor will assume the drawing buffer contains colors with pre-multiplied alpha. */
307
+ premultipliedAlpha?: boolean;
308
+ /** buffers will not be cleared and will preserve their values until cleared or overwritten by the author. */
309
+ preserveDrawingBuffer?: boolean;
289
310
  };
290
311
 
291
312
  /**
@@ -312,11 +333,15 @@ export abstract class Device {
312
333
  webgl: {},
313
334
 
314
335
  // Callbacks
315
- onError: (error: Error, context: unknown) => log.error(error.message, context)(),
336
+ // eslint-disable-next-line handle-callback-err
337
+ onError: (error: Error, context: unknown) => {},
316
338
  onResize: (context: CanvasContext, info: {oldPixelSize: [number, number]}) => {
317
339
  const [width, height] = context.getDevicePixelSize();
318
- const [prevWidth, prevHeight] = info.oldPixelSize;
319
- log.log(1, `${context} Resized ${prevWidth}x${prevHeight} => ${width}x${height}px`)();
340
+ log.log(1, `${context} resized => ${width}x${height}px`)();
341
+ },
342
+ onPositionChange: (context: CanvasContext, info: {oldPosition: [number, number]}) => {
343
+ const [left, top] = context.getPosition();
344
+ log.log(1, `${context} repositioned => ${left},${top}`)();
320
345
  },
321
346
  onVisibilityChange: (context: CanvasContext) =>
322
347
  log.log(1, `${context} Visibility changed ${context.isVisible}`)(),
@@ -333,6 +358,7 @@ export abstract class Device {
333
358
  debugSpectorJSUrl: undefined!,
334
359
 
335
360
  // Experimental
361
+ _reuseDevices: false,
336
362
  _requestMaxLimits: true,
337
363
  _cacheShaders: false,
338
364
  _cachePipelines: false,
@@ -351,9 +377,8 @@ export abstract class Device {
351
377
  return 'Device';
352
378
  }
353
379
 
354
- constructor(props: DeviceProps) {
355
- this.props = {...Device.defaultProps, ...props};
356
- this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
380
+ toString(): string {
381
+ return `Device(${this.id})`;
357
382
  }
358
383
 
359
384
  /** id of this device, primarily for debugging */
@@ -372,11 +397,11 @@ export abstract class Device {
372
397
  /** An abstract timestamp used for change tracking */
373
398
  timestamp: number = 0;
374
399
 
400
+ /** True if this device has been reused during device creation (app has multiple references) */
401
+ _reused: boolean = false;
375
402
  /** Used by other luma.gl modules to store data on the device */
376
403
  _lumaData: {[key: string]: unknown} = {};
377
404
 
378
- abstract destroy(): void;
379
-
380
405
  // Capabilities
381
406
 
382
407
  /** Information about the device (vendor, versions etc) */
@@ -395,9 +420,24 @@ export abstract class Device {
395
420
 
396
421
  protected _textureCaps: Partial<Record<TextureFormat, DeviceTextureFormatCapabilities>> = {};
397
422
 
423
+ constructor(props: DeviceProps) {
424
+ this.props = {...Device.defaultProps, ...props};
425
+ this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
426
+ }
427
+
428
+ abstract destroy(): void;
429
+
430
+ getVertexFormatInfo(format: VertexFormat): VertexFormatInfo {
431
+ return getVertexFormatInfo(format);
432
+ }
433
+
434
+ isVertexFormatSupported(format: VertexFormat): boolean {
435
+ return true;
436
+ }
437
+
398
438
  /** Returns information about a texture format, such as data type, channels, bits per channel, compression etc */
399
439
  getTextureFormatInfo(format: TextureFormat): TextureFormatInfo {
400
- return getTextureFormatInfo(format);
440
+ return textureFormatDecoder.getInfo(format);
401
441
  }
402
442
 
403
443
  /** Determines what operations are supported on a texture format on this particular device (checks against supported device features) */
@@ -411,6 +451,9 @@ export abstract class Device {
411
451
  return textureCaps;
412
452
  }
413
453
 
454
+ /** Return the implementation specific alignment for a texture format. 1 on WebGL, 256 on WebGPU */
455
+ abstract getTextureByteAlignment(): number;
456
+
414
457
  /** Calculates the number of mip levels for a texture of width, height and in case of 3d textures only, depth */
415
458
  getMipLevelCount(width: number, height: number, depth3d: number = 1): number {
416
459
  const maxSize = Math.max(width, height, depth3d);
@@ -444,7 +487,7 @@ export abstract class Device {
444
487
 
445
488
  /** Check if a specific texture format is GPU compressed */
446
489
  isTextureFormatCompressed(format: TextureFormat): boolean {
447
- return isTextureFormatCompressed(format);
490
+ return textureFormatDecoder.isCompressed(format);
448
491
  }
449
492
 
450
493
  // DEBUG METHODS
@@ -483,13 +526,45 @@ export abstract class Device {
483
526
  return this.timestamp++;
484
527
  }
485
528
 
486
- /** Report error (normally called for unhandled device errors) */
487
- reportError(error: Error, context?: unknown): void {
529
+ /**
530
+ * Reports Device errors in a way that optimizes for developer experience / debugging.
531
+ * - Logs so that the console error links directly to the source code that generated the error.
532
+ * - Includes the object that reported the error in the log message, even if the error is asynchronous.
533
+ *
534
+ * Conventions when calling reportError():
535
+ * - Always call the returned function - to ensure error is logged, at the error site
536
+ * - Follow with a call to device.debug() - to ensure that the debugger breaks at the error site
537
+ *
538
+ * @param error - the error to report. If needed, just create a new Error object with the appropriate message.
539
+ * @param context - pass `this` as context, otherwise it may not be available in the debugger for async errors.
540
+ * @returns the logger function returned by device.props.onError() so that it can be called from the error site.
541
+ *
542
+ * @example
543
+ * device.reportError(new Error(...), this)();
544
+ * device.debug();
545
+ */
546
+ reportError(error: Error, context: unknown, ...args: unknown[]): () => unknown {
547
+ // Call the error handler
548
+ const isHandled = this.props.onError(error, context);
549
+ if (!isHandled) {
550
+ // Note: Returns a function that must be called: `device.reportError(...)()`
551
+ return log.error(error.message, context, ...args);
552
+ }
553
+ return () => {};
554
+ }
555
+
556
+ /** Break in the debugger - if device.props.debug is true */
557
+ debug(): void {
488
558
  if (this.props.debug) {
489
559
  // @ts-ignore
490
560
  debugger; // eslint-disable-line
561
+ } else {
562
+ // TODO(ibgreen): Does not appear to be printed in the console
563
+ const message = `\
564
+ 'Type luma.log.set({debug: true}) in console to enable debug breakpoints',
565
+ or create a device with the 'debug: true' prop.`;
566
+ log.once(0, message)();
491
567
  }
492
- this.props.onError(error, context);
493
568
  }
494
569
 
495
570
  // Canvas context
@@ -638,10 +713,15 @@ export abstract class Device {
638
713
 
639
714
  // IMPLEMENTATION
640
715
 
716
+ /** Helper to get the canvas context props */
717
+ static _getCanvasContextProps(props: DeviceProps): CanvasContextProps | undefined {
718
+ return props.createCanvasContext === true ? {} : props.createCanvasContext;
719
+ }
720
+
641
721
  protected _getDeviceTextureFormatCapabilities(
642
722
  format: TextureFormat
643
723
  ): DeviceTextureFormatCapabilities {
644
- const genericCapabilities = getTextureFormatCapabilities(format);
724
+ const genericCapabilities = textureFormatDecoder.getCapabilities(format);
645
725
 
646
726
  // Check standard features
647
727
  const checkFeature = (feature: DeviceFeature | boolean | undefined) =>
@@ -664,20 +744,25 @@ export abstract class Device {
664
744
  props = {data: props};
665
745
  }
666
746
 
667
- // TODO - fragile, as this is done before we merge with default options
747
+ // TODO(ibgreen) - fragile, as this is done before we merge with default options
668
748
  // inside the Buffer constructor
669
749
 
670
750
  const newProps = {...props};
671
751
  // Deduce indexType
672
- if ((props.usage || 0) & Buffer.INDEX && !props.indexType) {
673
- if (props.data instanceof Uint32Array) {
674
- newProps.indexType = 'uint32';
675
- } else if (props.data instanceof Uint16Array) {
676
- newProps.indexType = 'uint16';
677
- } else {
678
- log.warn('indices buffer content must be of type uint16 or uint32')();
752
+ const usage = props.usage || 0;
753
+ if (usage & Buffer.INDEX) {
754
+ if (!props.indexType) {
755
+ if (props.data instanceof Uint32Array) {
756
+ newProps.indexType = 'uint32';
757
+ } else if (props.data instanceof Uint16Array) {
758
+ newProps.indexType = 'uint16';
759
+ }
760
+ }
761
+ if (!newProps.indexType) {
762
+ throw new Error('indices buffer content must be of type uint16 or uint32');
679
763
  }
680
764
  }
765
+
681
766
  return newProps;
682
767
  }
683
768
  }
@@ -5,6 +5,9 @@
5
5
  import type {Device} from '../device';
6
6
  import {Resource, ResourceProps} from './resource';
7
7
 
8
+ /** Callback for Buffer.mapAndReadAsync */
9
+ export type BufferMapCallback<T> = (arrayBuffer: ArrayBuffer, lifetime: 'mapped' | 'copied') => T;
10
+
8
11
  export type BufferProps = ResourceProps & {
9
12
  /** Supply a handle to connect to an existing device-specific buffer */
10
13
  handle?: WebGLBuffer;
@@ -12,15 +15,14 @@ export type BufferProps = ResourceProps & {
12
15
  usage?: number;
13
16
  /** Length in bytes of memory to be allocated. If not specified, `byteLength` of `props.data` will be used. */
14
17
  byteLength?: number;
15
- /** Data to initialize the buffer with. */
16
- data?: ArrayBuffer | ArrayBufferView | null;
17
18
  /** Byte offset into the newly created Buffer to store data at */
18
19
  byteOffset?: number;
19
20
  /** If props.usage includes Buffer.INDEX */
20
21
  indexType?: 'uint16' | 'uint32';
21
-
22
- // TBD
23
- mappedAtCreation?: boolean;
22
+ /** Data to initialize the buffer with. */
23
+ data?: ArrayBuffer | ArrayBufferView | null;
24
+ /** Callback to initialize data without copy */
25
+ onMapped?: BufferMapCallback<void>;
24
26
  };
25
27
 
26
28
  /** Abstract GPU buffer */
@@ -88,15 +90,29 @@ export abstract class Buffer extends Resource<BufferProps> {
88
90
  }
89
91
 
90
92
  /** Write data to buffer */
91
- abstract write(data: ArrayBufferView, byteOffset?: number): void;
92
-
93
- /** Read data asynchronously */
93
+ abstract write(
94
+ data: ArrayBufferLike | ArrayBufferView | SharedArrayBuffer,
95
+ byteOffset?: number
96
+ ): void;
97
+
98
+ abstract mapAndWriteAsync(
99
+ onMapped: BufferMapCallback<void | Promise<void>>,
100
+ byteOffset?: number,
101
+ byteLength?: number
102
+ ): Promise<void>;
103
+
104
+ /** Reads data asynchronously, returns a copy of the buffer data */
94
105
  abstract readAsync(byteOffset?: number, byteLength?: number): Promise<Uint8Array>;
95
106
 
107
+ /** Maps buffer data to CPU memory. Mapped memory is only accessible in the callback */
108
+ abstract mapAndReadAsync<T>(
109
+ onMapped: BufferMapCallback<T>,
110
+ byteOffset?: number,
111
+ byteLength?: number
112
+ ): Promise<T>;
113
+
96
114
  /** Read data synchronously. @note WebGL2 only */
97
- readSyncWebGL(byteOffset?: number, byteLength?: number): Uint8Array {
98
- throw new Error('not implemented');
99
- }
115
+ abstract readSyncWebGL(byteOffset?: number, byteLength?: number): Uint8Array;
100
116
 
101
117
  // PROTECTED METHODS (INTENDED FOR USE BY OTHER FRAMEWORK CODE ONLY)
102
118
 
@@ -108,11 +124,11 @@ export abstract class Buffer extends Resource<BufferProps> {
108
124
 
109
125
  /** This doesn't handle partial non-zero offset updates correctly */
110
126
  protected _setDebugData(
111
- data: ArrayBufferView | ArrayBuffer | null,
127
+ data: ArrayBufferView | ArrayBufferLike | null,
112
128
  byteOffset: number,
113
129
  byteLength: number
114
130
  ): void {
115
- const arrayBuffer: ArrayBuffer | null = ArrayBuffer.isView(data) ? data.buffer : data;
131
+ const arrayBuffer: ArrayBufferLike | null = ArrayBuffer.isView(data) ? data.buffer : data;
116
132
  const debugDataLength = Math.min(
117
133
  data ? data.byteLength : byteLength,
118
134
  Buffer.DEBUG_DATA_MAX_LENGTH
@@ -133,6 +149,6 @@ export abstract class Buffer extends Resource<BufferProps> {
133
149
  byteOffset: 0,
134
150
  data: null,
135
151
  indexType: 'uint16',
136
- mappedAtCreation: false
152
+ onMapped: undefined!
137
153
  };
138
154
  }
@@ -134,8 +134,6 @@ export type CommandEncoderProps = ResourceProps & {
134
134
  * Encodes commands to queue that can be executed later
135
135
  */
136
136
  export abstract class CommandEncoder extends Resource<CommandEncoderProps> {
137
- abstract readonly handle: unknown;
138
-
139
137
  override get [Symbol.toStringTag](): string {
140
138
  return 'CommandEncoder';
141
139
  }
@@ -3,10 +3,10 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import type {
6
- ColorTextureFormat,
7
- DepthStencilTextureFormat,
6
+ TextureFormatColor,
7
+ TextureFormatDepthStencil,
8
8
  TextureFormat
9
- } from '../../shadertypes/texture-formats';
9
+ } from '../../shadertypes/textures/texture-formats';
10
10
  import type {Device} from '../device';
11
11
  import {Resource, ResourceProps} from './resource';
12
12
  import {Texture} from './texture';
@@ -16,8 +16,8 @@ import {log} from '../../utils/log';
16
16
  export type FramebufferProps = ResourceProps & {
17
17
  width?: number;
18
18
  height?: number;
19
- colorAttachments?: (TextureView | Texture | ColorTextureFormat)[];
20
- depthStencilAttachment?: (TextureView | Texture | DepthStencilTextureFormat) | null;
19
+ colorAttachments?: (TextureView | Texture | TextureFormatColor)[];
20
+ depthStencilAttachment?: (TextureView | Texture | TextureFormatDepthStencil) | null;
21
21
  };
22
22
 
23
23
  /**
@@ -0,0 +1,30 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {Device} from '../device';
6
+ import {ShaderLayout} from '../types/shader-layout';
7
+ import {Resource, ResourceProps} from './resource';
8
+
9
+ export type PipelineLayoutProps = ResourceProps & {
10
+ shaderLayout: ShaderLayout;
11
+ };
12
+
13
+ /** Immutable PipelineLayout object */
14
+ export abstract class PipelineLayout extends Resource<PipelineLayoutProps> {
15
+ get [Symbol.toStringTag](): string {
16
+ return 'PipelineLayout';
17
+ }
18
+
19
+ constructor(device: Device, props: PipelineLayoutProps) {
20
+ super(device, props, PipelineLayout.defaultProps);
21
+ }
22
+
23
+ static override defaultProps: Required<PipelineLayoutProps> = {
24
+ ...Resource.defaultProps,
25
+ shaderLayout: {
26
+ attributes: [],
27
+ bindings: []
28
+ }
29
+ };
30
+ }
@@ -8,9 +8,9 @@ import type {PrimitiveTopology, RenderPipelineParameters} from '../types/paramet
8
8
  import type {ShaderLayout, Binding} from '../types/shader-layout';
9
9
  import type {BufferLayout} from '../types/buffer-layout';
10
10
  import type {
11
- ColorTextureFormat,
12
- DepthStencilTextureFormat
13
- } from '@luma.gl/core/shadertypes/texture-formats';
11
+ TextureFormatColor,
12
+ TextureFormatDepthStencil
13
+ } from '@luma.gl/core/shadertypes/textures/texture-formats';
14
14
  import type {Shader} from './shader';
15
15
  import type {RenderPass} from './render-pass';
16
16
  import {Resource, ResourceProps} from './resource';
@@ -44,9 +44,9 @@ export type RenderPipelineProps = ResourceProps & {
44
44
  // color attachment information (needed on WebGPU)
45
45
 
46
46
  /** Color attachments expected by this pipeline. Defaults to [device.preferredColorFormat]. Array needs not be contiguous. */
47
- colorAttachmentFormats?: (ColorTextureFormat | null)[];
48
- /** Depth attachment expected by this pipeline (if depth parameters are specified). Defaults to device.preferredDepthFormat */
49
- depthStencilAttachmentFormat?: DepthStencilTextureFormat;
47
+ colorAttachmentFormats?: (TextureFormatColor | null)[];
48
+ /** Depth attachment expected by this pipeline. Defaults to device.preferredDepthFormat, if depthWriteEnables parameter is set */
49
+ depthStencilAttachmentFormat?: TextureFormatDepthStencil;
50
50
 
51
51
  /** Parameters that are controlled by pipeline */
52
52
  parameters?: RenderPipelineParameters;
@@ -36,6 +36,7 @@ export abstract class Resource<Props extends ResourceProps> {
36
36
  readonly props: Required<Props>;
37
37
  readonly userData: Record<string, unknown> = {};
38
38
  abstract readonly device: Device;
39
+ abstract readonly handle: unknown;
39
40
  private _device: Device;
40
41
 
41
42
  /** Whether this resource has been destroyed */
@@ -4,7 +4,7 @@
4
4
 
5
5
  import type {Device} from '../device';
6
6
  import type {Texture} from './texture';
7
- import type {TextureFormat} from '../../shadertypes/texture-formats';
7
+ import type {TextureFormat} from '../../shadertypes/textures/texture-formats';
8
8
  import {Resource, ResourceProps} from './resource';
9
9
 
10
10
  /** Properties for initializing a texture view */
@@ -4,7 +4,7 @@
4
4
 
5
5
  import {TypedArray} from '@math.gl/types';
6
6
  import type {Device} from '../device';
7
- import type {TextureFormat} from '../../shadertypes/texture-formats';
7
+ import type {TextureFormat} from '../../shadertypes/textures/texture-formats';
8
8
  import type {TextureView, TextureViewProps} from './texture-view';
9
9
  import {Resource, ResourceProps} from './resource';
10
10
  import {Sampler, SamplerProps} from './sampler';
@@ -71,6 +71,6 @@ export abstract class VertexArray extends Resource<VertexArrayProps> {
71
71
 
72
72
  /** @deprecated Set constant attributes (WebGL only) */
73
73
  setConstantWebGL(location: number, value: TypedArray | null): void {
74
- throw new Error('constant attributes not supported');
74
+ this.device.reportError(new Error('constant attributes not supported'), this)();
75
75
  }
76
76
  }
@@ -3,10 +3,10 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import type {
6
- ColorTextureFormat,
7
- DepthStencilTextureFormat,
6
+ TextureFormatColor,
7
+ TextureFormatDepthStencil,
8
8
  TextureFormat
9
- } from '../../shadertypes/texture-formats';
9
+ } from '../../shadertypes/textures/texture-formats';
10
10
  import type {Texture} from '../resources/texture'; // TextureView...
11
11
  import type {TextureView} from '../resources/texture-view'; // TextureView...
12
12
 
@@ -60,7 +60,7 @@ export type ColorAttachment = {
60
60
  /** Describes the texture subresource that will be output to for this color attachment. */
61
61
  texture?: TextureView | Texture;
62
62
  /** Format of the texture resource. Used to auto create texture if not supplied */
63
- format?: ColorTextureFormat;
63
+ format?: TextureFormatColor;
64
64
  /* Describes the texture subresource that will receive resolved output for this color attachment if multisampled. */
65
65
  // resolveTarget?: GPUTextureView;
66
66
 
@@ -80,7 +80,7 @@ export type DepthStencilAttachment = {
80
80
  /** Describes the texture subresource that will be output to and read from for this depth/stencil attachment. */
81
81
  texture?: TextureView | Texture;
82
82
  /** Format of the texture resource. Used to auto create texture if not supplied */
83
- format?: DepthStencilTextureFormat;
83
+ format?: TextureFormatDepthStencil;
84
84
 
85
85
  /** Value to clear depth component to prior to executing the render pass, if depthLoadOp is "clear". 0.0-1.0. */
86
86
  depthClearValue?: number;
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {VertexFormat} from '../../shadertypes/vertex-formats';
5
+ import type {VertexFormat} from '../../shadertypes/vertex-arrays/vertex-formats';
6
6
 
7
7
  /**
8
8
  * Provides specific details about the memory layout of the actual buffers
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import {NumberArray4, NumberArray6} from '@math.gl/types';
6
- import {DepthStencilTextureFormat} from '../../shadertypes/texture-formats';
6
+ import {TextureFormatDepthStencil} from '../../shadertypes/textures/texture-formats';
7
7
 
8
8
  export type CompareFunction =
9
9
  | 'never'
@@ -101,7 +101,7 @@ export type DepthStencilParameters = {
101
101
  /** The comparison operation used to test fragment depths against existing depthStencilAttachment depth values. */
102
102
  depthCompare?: CompareFunction;
103
103
  /** The format of depthStencilAttachment this GPURenderPipeline will be compatible with. */
104
- depthFormat?: DepthStencilTextureFormat;
104
+ depthFormat?: TextureFormatDepthStencil;
105
105
 
106
106
  /** Bitmask controlling which depthStencilAttachment stencil value bits are read when performing stencil comparison tests. */
107
107
  stencilReadMask?: number;
@@ -2,8 +2,11 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {TextureFormat} from '../../shadertypes/texture-formats';
6
- import type {VariableShaderType, AttributeShaderType} from '../../shadertypes/shader-types';
5
+ import type {TextureFormat} from '../../shadertypes/textures/texture-formats';
6
+ import type {
7
+ VariableShaderType,
8
+ AttributeShaderType
9
+ } from '../../shadertypes/data-types/shader-types';
7
10
  import type {Buffer} from '../resources/buffer';
8
11
  import type {Sampler} from '../resources/sampler';
9
12
  import type {Texture} from '../resources/texture';
@@ -110,7 +113,7 @@ export type StorageBufferBindingLayout = {
110
113
  minBindingSize?: number;
111
114
  };
112
115
 
113
- type TextureBindingLayout = {
116
+ export type TextureBindingLayout = {
114
117
  type: 'texture';
115
118
  /** Name of the binding. Used by luma to map bindings by name */
116
119
  name: string;
@@ -125,7 +128,7 @@ type TextureBindingLayout = {
125
128
  multisampled?: boolean;
126
129
  };
127
130
 
128
- type SamplerBindingLayout = {
131
+ export type SamplerBindingLayout = {
129
132
  type: 'sampler';
130
133
  /** Name of the binding. Used by luma to map bindings by name */
131
134
  name: string;
@@ -138,7 +141,7 @@ type SamplerBindingLayout = {
138
141
  samplerType?: 'filtering' | 'non-filtering' | 'comparison'; // default: filtering
139
142
  };
140
143
 
141
- type StorageTextureBindingLayout = {
144
+ export type StorageTextureBindingLayout = {
142
145
  type: 'storage';
143
146
  /** Name of the binding. Used by luma to map bindings by name */
144
147
  name: string;