@luma.gl/webgpu 9.0.0-alpha.21 → 9.0.0-alpha.23

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 (37) hide show
  1. package/dist/adapter/resources/webgpu-command-encoder.d.ts +3 -11
  2. package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
  3. package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
  4. package/dist/adapter/resources/webgpu-framebuffer.d.ts +0 -17
  5. package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
  6. package/dist/adapter/resources/webgpu-framebuffer.js +2 -84
  7. package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
  8. package/dist/adapter/resources/webgpu-render-pass.d.ts +6 -1
  9. package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
  10. package/dist/adapter/resources/webgpu-render-pass.js +19 -1
  11. package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
  12. package/dist/adapter/resources/webgpu-shader.js +3 -2
  13. package/dist/adapter/resources/webgpu-shader.js.map +1 -1
  14. package/dist/adapter/resources/webgpu-texture.d.ts +10 -2
  15. package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
  16. package/dist/adapter/resources/webgpu-texture.js +8 -1
  17. package/dist/adapter/resources/webgpu-texture.js.map +1 -1
  18. package/dist/adapter/webgpu-canvas-context.d.ts +1 -1
  19. package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
  20. package/dist/adapter/webgpu-canvas-context.js.map +1 -1
  21. package/dist/adapter/webgpu-device.d.ts +16 -2
  22. package/dist/adapter/webgpu-device.d.ts.map +1 -1
  23. package/dist/adapter/webgpu-device.js +31 -2
  24. package/dist/adapter/webgpu-device.js.map +1 -1
  25. package/dist/dist.dev.js +384 -171
  26. package/dist/index.cjs +80 -87
  27. package/dist.min.js +4 -4
  28. package/package.json +3 -3
  29. package/src/adapter/resources/webgpu-command-encoder.ts +40 -21
  30. package/src/adapter/resources/webgpu-framebuffer.ts +6 -107
  31. package/src/adapter/resources/webgpu-render-pass.ts +34 -4
  32. package/src/adapter/resources/webgpu-shader.ts +2 -2
  33. package/src/adapter/resources/webgpu-texture.ts +8 -2
  34. package/src/adapter/webgpu-canvas-context.ts +2 -1
  35. package/src/adapter/webgpu-device.ts +71 -3
  36. package/src/.DS_Store +0 -0
  37. package/src/adapter/.DS_Store +0 -0
package/dist/dist.dev.js CHANGED
@@ -119,9 +119,9 @@ var __exports__ = (() => {
119
119
  }
120
120
 
121
121
  // ../../node_modules/@probe.gl/log/dist/utils/local-storage.js
122
- function getStorage(type2) {
122
+ function getStorage(type) {
123
123
  try {
124
- const storage = window[type2];
124
+ const storage = window[type];
125
125
  const x = "__storage_test__";
126
126
  storage.setItem(x, x);
127
127
  storage.removeItem(x);
@@ -132,11 +132,11 @@ var __exports__ = (() => {
132
132
  }
133
133
  var LocalStorage = class {
134
134
  constructor(id, defaultConfig) {
135
- let type2 = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "sessionStorage";
135
+ let type = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "sessionStorage";
136
136
  _defineProperty(this, "storage", void 0);
137
137
  _defineProperty(this, "id", void 0);
138
138
  _defineProperty(this, "config", void 0);
139
- this.storage = getStorage(type2);
139
+ this.storage = getStorage(type);
140
140
  this.id = id;
141
141
  this.config = defaultConfig;
142
142
  this._loadConfiguration();
@@ -633,7 +633,7 @@ var __exports__ = (() => {
633
633
 
634
634
  // ../../node_modules/@probe.gl/stats/dist/lib/stat.js
635
635
  var Stat = class {
636
- constructor(name, type2) {
636
+ constructor(name, type) {
637
637
  _defineProperty(this, "name", void 0);
638
638
  _defineProperty(this, "type", void 0);
639
639
  _defineProperty(this, "sampleSize", 1);
@@ -649,7 +649,7 @@ var __exports__ = (() => {
649
649
  _defineProperty(this, "_startTime", 0);
650
650
  _defineProperty(this, "_timerPending", false);
651
651
  this.name = name;
652
- this.type = type2;
652
+ this.type = type;
653
653
  this.reset();
654
654
  }
655
655
  reset() {
@@ -754,10 +754,10 @@ var __exports__ = (() => {
754
754
  Object.seal(this);
755
755
  }
756
756
  get(name) {
757
- let type2 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "count";
757
+ let type = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "count";
758
758
  return this._getOrCreate({
759
759
  name,
760
- type: type2
760
+ type
761
761
  });
762
762
  }
763
763
  get size() {
@@ -793,14 +793,14 @@ var __exports__ = (() => {
793
793
  _getOrCreate(stat) {
794
794
  const {
795
795
  name,
796
- type: type2
796
+ type
797
797
  } = stat;
798
798
  let result = this.stats[name];
799
799
  if (!result) {
800
800
  if (stat instanceof Stat) {
801
801
  result = stat;
802
802
  } else {
803
- result = new Stat(name, type2);
803
+ result = new Stat(name, type);
804
804
  }
805
805
  this.stats[name] = result;
806
806
  }
@@ -869,14 +869,17 @@ var __exports__ = (() => {
869
869
  var DEFAULT_RESOURCE_PROPS = {
870
870
  id: "undefined",
871
871
  handle: void 0,
872
- userData: {}
872
+ userData: void 0
873
873
  };
874
874
  var Resource = class {
875
875
  /** props.id, for debugging. */
876
876
  userData = {};
877
+ /** Whether this resource has been destroyed */
877
878
  destroyed = false;
878
879
  /** For resources that allocate GPU memory */
879
880
  allocatedBytes = 0;
881
+ /** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
882
+ _attachedResources = /* @__PURE__ */ new Set();
880
883
  /**
881
884
  * Create a new Resource. Called from Subclass
882
885
  */
@@ -896,7 +899,7 @@ var __exports__ = (() => {
896
899
  * destroy can be called on any resource to release it before it is garbage collected.
897
900
  */
898
901
  destroy() {
899
- this.removeStats();
902
+ this.destroyResource();
900
903
  }
901
904
  /** @deprecated Use destroy() */
902
905
  delete() {
@@ -913,14 +916,41 @@ var __exports__ = (() => {
913
916
  getProps() {
914
917
  return this.props;
915
918
  }
919
+ // ATTACHED RESOURCES
920
+ /**
921
+ * Attaches a resource. Attached resources are auto destroyed when this resource is destroyed
922
+ * Called automatically when sub resources are auto created but can be called by application
923
+ */
924
+ attachResource(resource) {
925
+ this._attachedResources.add(resource);
926
+ }
927
+ /**
928
+ * Detach an attached resource. The resource will no longer be auto-destroyed when this resource is destroyed.
929
+ */
930
+ detachResource(resource) {
931
+ this._attachedResources.delete(resource);
932
+ }
933
+ /**
934
+ * Destroys a resource (only if owned), and removes from the owned (auto-destroy) list for this resource.
935
+ */
936
+ destroyAttachedResource(resource) {
937
+ if (this._attachedResources.delete(resource)) {
938
+ resource.destroy();
939
+ }
940
+ }
941
+ /** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
942
+ destroyAttachedResources() {
943
+ for (const resource of Object.values(this._attachedResources)) {
944
+ resource.destroy();
945
+ }
946
+ this._attachedResources = /* @__PURE__ */ new Set();
947
+ }
916
948
  // PROTECTED METHODS
917
- /** Called by resource constructor to track object creation */
918
- addStats() {
919
- const stats = this._device.statsManager.getStats("Resource Counts");
920
- const name = this[Symbol.toStringTag];
921
- stats.get("Resources Created").incrementCount();
922
- stats.get(`${name}s Created`).incrementCount();
923
- stats.get(`${name}s Active`).incrementCount();
949
+ /** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
950
+ destroyResource() {
951
+ this.destroyAttachedResources();
952
+ this.removeStats();
953
+ this.destroyed = true;
924
954
  }
925
955
  /** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
926
956
  removeStats() {
@@ -942,7 +972,17 @@ var __exports__ = (() => {
942
972
  stats.get(`${name} Memory`).subtractCount(this.allocatedBytes);
943
973
  this.allocatedBytes = 0;
944
974
  }
975
+ /** Called by resource constructor to track object creation */
976
+ addStats() {
977
+ const stats = this._device.statsManager.getStats("Resource Counts");
978
+ const name = this[Symbol.toStringTag];
979
+ stats.get("Resources Created").incrementCount();
980
+ stats.get(`${name}s Created`).incrementCount();
981
+ stats.get(`${name}s Active`).incrementCount();
982
+ }
945
983
  };
984
+ /** Default properties for resource */
985
+ __publicField(Resource, "defaultProps", DEFAULT_RESOURCE_PROPS);
946
986
  function selectivelyMerge(props, defaultProps) {
947
987
  const mergedProps = {
948
988
  ...defaultProps
@@ -970,6 +1010,7 @@ var __exports__ = (() => {
970
1010
  get [Symbol.toStringTag]() {
971
1011
  return "Buffer";
972
1012
  }
1013
+ /** Length of buffer in bytes */
973
1014
  constructor(device, props) {
974
1015
  const deducedProps = {
975
1016
  ...props
@@ -1090,34 +1131,30 @@ var __exports__ = (() => {
1090
1131
  }
1091
1132
  statsManager = lumaStats;
1092
1133
  userData = {};
1134
+ // Capabilities
1093
1135
  /** Information about the device (vendor, versions etc) */
1094
1136
  /** Optional capability discovery */
1095
1137
  /** WebGPU style device limits */
1096
1138
  /** Check if device supports a specific texture format (creation and `nearest` sampling) */
1097
1139
  /** Check if linear filtering (sampler interpolation) is supported for a specific texture format */
1098
1140
  /** Check if device supports rendering to a specific texture format */
1099
- /** True context is already lost */
1100
- /** Promise that resolves when context is lost */
1101
- /** default canvas context */
1141
+ // Device loss
1142
+ /** `true` if device is already lost */
1143
+ /** Promise that resolves when device is lost */
1144
+ /**
1145
+ * Trigger device loss.
1146
+ * @returns `true` if context loss could actually be triggered.
1147
+ * @note primarily intended for testing how application reacts to device loss
1148
+ */
1149
+ loseDevice() {
1150
+ return false;
1151
+ }
1152
+ // Canvas context
1153
+ /** Default / primary canvas context. Can be null as WebGPU devices can be created without a CanvasContext */
1102
1154
  /** Creates a new CanvasContext (WebGPU only) */
1103
1155
  /** Call after rendering a frame (necessary e.g. on WebGL OffscreenCanvas) */
1104
1156
  // Resource creation
1105
1157
  /** Create a buffer */
1106
- createBuffer(props) {
1107
- if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
1108
- return this._createBuffer({
1109
- data: props
1110
- });
1111
- }
1112
- if ((props.usage || 0) & Buffer2.INDEX && !props.indexType) {
1113
- if (props.data instanceof Uint32Array) {
1114
- props.indexType = "uint32";
1115
- } else if (props.data instanceof Uint16Array) {
1116
- props.indexType = "uint16";
1117
- }
1118
- }
1119
- return this._createBuffer(props);
1120
- }
1121
1158
  /** Create a texture */
1122
1159
  createTexture(props) {
1123
1160
  if (props instanceof Promise || typeof props === "string") {
@@ -1132,9 +1169,31 @@ var __exports__ = (() => {
1132
1169
  /** Create a shader */
1133
1170
  /** Create a render pipeline (aka program) */
1134
1171
  /** Create a compute pipeline (aka program) */
1172
+ createCommandEncoder(props = {}) {
1173
+ throw new Error("not implemented");
1174
+ }
1135
1175
  /** Create a RenderPass */
1136
1176
  /** Create a ComputePass */
1137
- // Implementation
1177
+ /** Get a renderpass that is set up to render to the primary CanvasContext */
1178
+ // Resource creation helpers
1179
+ _getBufferProps(props) {
1180
+ if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
1181
+ return {
1182
+ data: props
1183
+ };
1184
+ }
1185
+ const newProps = {
1186
+ ...props
1187
+ };
1188
+ if ((props.usage || 0) & Buffer2.INDEX && !props.indexType) {
1189
+ if (props.data instanceof Uint32Array) {
1190
+ props.indexType = "uint32";
1191
+ } else if (props.data instanceof Uint16Array) {
1192
+ props.indexType = "uint16";
1193
+ }
1194
+ }
1195
+ return newProps;
1196
+ }
1138
1197
  };
1139
1198
  __publicField(Device, "VERSION", VERSION2);
1140
1199
 
@@ -1222,13 +1281,15 @@ var __exports__ = (() => {
1222
1281
  if (typeof OffscreenCanvas !== "undefined" && this.canvas instanceof OffscreenCanvas) {
1223
1282
  return 1;
1224
1283
  }
1225
- if (typeof useDevicePixels === "number") {
1226
- return useDevicePixels > 0 ? useDevicePixels : 1;
1284
+ useDevicePixels = useDevicePixels === void 0 ? this.props.useDevicePixels : useDevicePixels;
1285
+ if (!useDevicePixels || useDevicePixels <= 0) {
1286
+ return 1;
1227
1287
  }
1228
- if (typeof this.props.useDevicePixels === "number") {
1229
- return this.props.useDevicePixels > 0 ? this.props.useDevicePixels : 1;
1288
+ if (useDevicePixels === true) {
1289
+ const dpr = typeof window !== "undefined" && window.devicePixelRatio;
1290
+ return dpr || 1;
1230
1291
  }
1231
- return useDevicePixels || this.props.useDevicePixels ? typeof window !== "undefined" && window.devicePixelRatio || 1 : 1;
1292
+ return useDevicePixels;
1232
1293
  }
1233
1294
  /**
1234
1295
  * Returns the size of drawing buffer in device pixels.
@@ -1421,8 +1482,8 @@ var __exports__ = (() => {
1421
1482
  data: null,
1422
1483
  dimension: "2d",
1423
1484
  format: "rgba8unorm",
1424
- // width: undefined,
1425
- // height: undefined,
1485
+ width: void 0,
1486
+ height: void 0,
1426
1487
  depth: 1,
1427
1488
  mipmaps: true,
1428
1489
  sampler: {},
@@ -1430,20 +1491,28 @@ var __exports__ = (() => {
1430
1491
  compressed: false,
1431
1492
  // mipLevels: 1,
1432
1493
  usage: 0,
1433
- parameters: {},
1434
- pixelStore: {},
1435
- pixels: null,
1436
- border: 0,
1437
- recreate: false
1494
+ mipLevels: void 0,
1495
+ samples: void 0,
1496
+ type: void 0
1438
1497
  };
1439
1498
  var Texture = class extends Resource {
1440
1499
  get [Symbol.toStringTag]() {
1441
1500
  return "Texture";
1442
1501
  }
1443
- constructor(device, props) {
1444
- super(device, props, DEFAULT_TEXTURE_PROPS);
1502
+ /** dimension of this texture */
1503
+ /** format of this texture */
1504
+ /** width in pixels of this texture */
1505
+ /** height in pixels of this texture */
1506
+ /** depth of this texture */
1507
+ /** Default sampler for this texture */
1508
+ constructor(device, props, defaultProps = DEFAULT_TEXTURE_PROPS) {
1509
+ super(device, props, defaultProps);
1510
+ this.dimension = this.props.dimension;
1511
+ this.format = this.props.format;
1512
+ this.width = this.props.width;
1513
+ this.height = this.props.height;
1514
+ this.depth = this.props.depth;
1445
1515
  }
1446
- /** Default sampler for this device */
1447
1516
  };
1448
1517
  __publicField(Texture, "COPY_SRC", 1);
1449
1518
  __publicField(Texture, "COPY_DST", 2);
@@ -1527,6 +1596,10 @@ var __exports__ = (() => {
1527
1596
  }
1528
1597
  /** Width of all attachments in this framebuffer */
1529
1598
  /** Height of all attachments in this framebuffer */
1599
+ /** Color attachments */
1600
+ colorAttachments = [];
1601
+ /** Depth-stencil attachment, if provided */
1602
+ depthStencilAttachment = null;
1530
1603
  constructor(device, props = {}) {
1531
1604
  super(device, props, DEFAULT_FRAMEBUFFER_PROPS);
1532
1605
  this.width = this.props.width;
@@ -1537,16 +1610,162 @@ var __exports__ = (() => {
1537
1610
  * @note resize() destroys existing textures (if size has changed).
1538
1611
  */
1539
1612
  resize(size) {
1540
- const updateSize = !size || size.height !== this.height || size.width !== this.width;
1613
+ let updateSize = !size;
1541
1614
  if (size) {
1542
- this.width = size?.width;
1543
- this.height = size?.height;
1615
+ const [width, height] = Array.isArray(size) ? size : [size.width, size.height];
1616
+ updateSize = updateSize || height !== this.height || width !== this.width;
1617
+ this.width = width;
1618
+ this.height = height;
1544
1619
  }
1545
1620
  if (updateSize) {
1546
- this._resizeAttachments(this.width, this.height);
1621
+ log.log(2, `Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)();
1622
+ this.resizeAttachments(this.width, this.height);
1623
+ }
1624
+ }
1625
+ // /** Returns fully populated attachment object. */
1626
+ // protected normalizeColorAttachment(
1627
+ // attachment: Texture | ColorTextureFormat
1628
+ // ): Required<ColorAttachment> {
1629
+ // const COLOR_ATTACHMENT_DEFAULTS: Required<ColorAttachment> = {
1630
+ // texture: undefined!,
1631
+ // format: undefined!,
1632
+ // clearValue: [0.0, 0.0, 0.0, 0.0],
1633
+ // loadOp: 'clear',
1634
+ // storeOp: 'store'
1635
+ // };
1636
+ // if (attachment instanceof Texture) {
1637
+ // return {...COLOR_ATTACHMENT_DEFAULTS, texture: attachment};
1638
+ // }
1639
+ // if (typeof attachment === 'string') {
1640
+ // return {...COLOR_ATTACHMENT_DEFAULTS, format: attachment};
1641
+ // }
1642
+ // return {...COLOR_ATTACHMENT_DEFAULTS, ...attachment};
1643
+ // }
1644
+ // /** Wraps texture inside fully populated attachment object. */
1645
+ // protected normalizeDepthStencilAttachment(
1646
+ // attachment: DepthStencilAttachment | Texture | DepthStencilTextureFormat
1647
+ // ): Required<DepthStencilAttachment> {
1648
+ // const DEPTH_STENCIL_ATTACHMENT_DEFAULTS: Required<DepthStencilAttachment> = {
1649
+ // texture: undefined!,
1650
+ // format: undefined!,
1651
+ // depthClearValue: 1.0,
1652
+ // depthLoadOp: 'clear',
1653
+ // depthStoreOp: 'store',
1654
+ // depthReadOnly: false,
1655
+ // stencilClearValue: 0,
1656
+ // stencilLoadOp: 'clear',
1657
+ // stencilStoreOp: 'store',
1658
+ // stencilReadOnly: false
1659
+ // };
1660
+ // if (typeof attachment === 'string') {
1661
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, format: attachment};
1662
+ // }
1663
+ // // @ts-expect-error attachment instanceof Texture doesn't cover Renderbuffer
1664
+ // if (attachment.handle || attachment instanceof Texture) {
1665
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, texture: attachment as Texture};
1666
+ // }
1667
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, ...attachment};
1668
+ // }
1669
+ /** Auto creates any textures */
1670
+ autoCreateAttachmentTextures() {
1671
+ this.colorAttachments = this.props.colorAttachments.map((attachment) => {
1672
+ if (typeof attachment === "string") {
1673
+ const texture = this.createColorTexture(attachment);
1674
+ this.attachResource(texture);
1675
+ return texture;
1676
+ }
1677
+ return attachment;
1678
+ });
1679
+ if (this.props.depthStencilAttachment) {
1680
+ if (typeof this.props.depthStencilAttachment === "string") {
1681
+ const texture = this.createDepthStencilTexture(this.props.depthStencilAttachment);
1682
+ this.attachResource(texture);
1683
+ this.depthStencilAttachment = texture;
1684
+ } else {
1685
+ this.depthStencilAttachment = this.props.depthStencilAttachment;
1686
+ }
1687
+ }
1688
+ }
1689
+ /** Create a color texture */
1690
+ createColorTexture(format) {
1691
+ return this.device.createTexture({
1692
+ id: "color-attachment",
1693
+ usage: Texture.RENDER_ATTACHMENT,
1694
+ format,
1695
+ width: this.width,
1696
+ height: this.height
1697
+ });
1698
+ }
1699
+ /** Create depth stencil texture */
1700
+ createDepthStencilTexture(format) {
1701
+ return this.device.createTexture({
1702
+ id: "depth-stencil-attachment",
1703
+ usage: Texture.RENDER_ATTACHMENT,
1704
+ format,
1705
+ width: this.width,
1706
+ height: this.height
1707
+ });
1708
+ }
1709
+ /**
1710
+ * Default implementation of resize
1711
+ * Creates new textures with correct size for all attachments.
1712
+ * and destroys existing textures if owned
1713
+ */
1714
+ resizeAttachments(width, height) {
1715
+ for (let i = 0; i < this.colorAttachments.length; ++i) {
1716
+ if (this.colorAttachments[i]) {
1717
+ const resizedTexture = this.device._createTexture({
1718
+ ...this.colorAttachments[i].props,
1719
+ width,
1720
+ height
1721
+ });
1722
+ this.destroyAttachedResource(this.colorAttachments[i]);
1723
+ this.colorAttachments[i] = resizedTexture;
1724
+ this.attachResource(resizedTexture);
1725
+ }
1726
+ }
1727
+ if (this.depthStencilAttachment) {
1728
+ const resizedTexture = this.device._createTexture({
1729
+ ...this.depthStencilAttachment.props,
1730
+ width,
1731
+ height
1732
+ });
1733
+ this.destroyAttachedResource(this.depthStencilAttachment);
1734
+ this.depthStencilAttachment = resizedTexture;
1735
+ this.attachResource(resizedTexture);
1547
1736
  }
1548
1737
  }
1549
- /** Implementation of resize */
1738
+ /** Create a color attachment for WebGL *
1739
+ protected override createColorTexture(colorAttachment: Required<ColorAttachment>): Required<ColorAttachment> {
1740
+ return this.device._createTexture({
1741
+ id: `${this.id}-color`,
1742
+ data: null, // reserves texture memory, but texels are undefined
1743
+ format,
1744
+ // type: GL.UNSIGNED_BYTE,
1745
+ width: this.width,
1746
+ height: this.height,
1747
+ // Note: Mipmapping can be disabled by texture resource when we resize the texture
1748
+ // to a non-power-of-two dimenstion (NPOT texture) under WebGL1. To have consistant
1749
+ // behavior we always disable mipmaps.
1750
+ mipmaps: false,
1751
+ // Set MIN and MAG filtering parameters so mipmaps are not used in sampling.
1752
+ // Use LINEAR so subpixel algos like fxaa work.
1753
+ // Set WRAP modes that support NPOT textures too.
1754
+ sampler: {
1755
+ minFilter: 'linear',
1756
+ magFilter: 'linear',
1757
+ addressModeU: 'clamp-to-edge',
1758
+ addressModeV: 'clamp-to-edge'
1759
+ }
1760
+ // parameters: {
1761
+ // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR,
1762
+ // [GL.TEXTURE_MAG_FILTER]: GL.LINEAR,
1763
+ // [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,
1764
+ // [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE
1765
+ // }
1766
+ });
1767
+ }
1768
+ */
1550
1769
  };
1551
1770
 
1552
1771
  // ../api/src/adapter/resources/render-pipeline.ts
@@ -1609,18 +1828,14 @@ var __exports__ = (() => {
1609
1828
  };
1610
1829
 
1611
1830
  // ../api/src/adapter/resources/render-pass.ts
1612
- var DEFAULT_RENDERPASS_PROPS = {
1613
- ...DEFAULT_RESOURCE_PROPS,
1614
- framebuffer: null,
1615
- parameters: null
1616
- };
1617
- var RenderPass = class extends Resource {
1831
+ var _RenderPass = class extends Resource {
1618
1832
  get [Symbol.toStringTag]() {
1619
1833
  return "RenderPass";
1620
1834
  }
1621
1835
  constructor(device, props) {
1622
- super(device, props, DEFAULT_RENDERPASS_PROPS);
1836
+ super(device, props, _RenderPass.defaultProps);
1623
1837
  }
1838
+ /** A small set of parameters can be changed between every draw call (viewport, scissorRect, blendColor, stencilReference) */
1624
1839
  // writeTimestamp(querySet: GPUQuerySet, queryIndex: number): void;
1625
1840
  // beginOcclusionQuery(queryIndex: number): void;
1626
1841
  // endOcclusionQuery(): void;
@@ -1651,6 +1866,19 @@ var __exports__ = (() => {
1651
1866
  drawIndexedIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): void;
1652
1867
  */
1653
1868
  };
1869
+ var RenderPass = _RenderPass;
1870
+ /** Default properties for RenderPass */
1871
+ __publicField(RenderPass, "defaultProps", {
1872
+ ...Resource.defaultProps,
1873
+ framebuffer: null,
1874
+ parameters: void 0,
1875
+ clearColor: [0, 0, 0, 0],
1876
+ clearDepth: 1,
1877
+ clearStencil: 0,
1878
+ depthReadOnly: false,
1879
+ stencilReadOnly: false,
1880
+ discard: false
1881
+ });
1654
1882
 
1655
1883
  // ../api/src/adapter/resources/compute-pass.ts
1656
1884
  var ComputePass = class extends Resource {
@@ -1679,22 +1907,22 @@ var __exports__ = (() => {
1679
1907
  };
1680
1908
 
1681
1909
  // ../api/src/adapter/utils/decode-data-type.ts
1682
- function decodeVertexType(type2) {
1683
- const dataType = TYPE_MAP[type2];
1910
+ function decodeVertexType(type) {
1911
+ const dataType = TYPE_MAP[type];
1684
1912
  const bytes = getDataTypeBytes(dataType);
1685
- const integer = !type2.startsWith("float");
1686
- const normalized = type2.includes("norm");
1687
- const signed = type2.startsWith("s");
1913
+ const integer = !type.startsWith("float");
1914
+ const normalized = type.includes("norm");
1915
+ const signed = type.startsWith("s");
1688
1916
  return {
1689
- dataType: TYPE_MAP[type2],
1917
+ dataType: TYPE_MAP[type],
1690
1918
  byteLength: bytes,
1691
1919
  integer,
1692
1920
  signed,
1693
1921
  normalized
1694
1922
  };
1695
1923
  }
1696
- function getDataTypeBytes(type2) {
1697
- const bytes = TYPE_SIZES[type2];
1924
+ function getDataTypeBytes(type) {
1925
+ const bytes = TYPE_SIZES[type];
1698
1926
  return bytes;
1699
1927
  }
1700
1928
  var TYPE_MAP = {
@@ -1725,11 +1953,11 @@ var __exports__ = (() => {
1725
1953
  // ../api/src/adapter/utils/decode-vertex-format.ts
1726
1954
  function decodeVertexFormat(format) {
1727
1955
  const [type_, count] = format.split("x");
1728
- const type2 = type_;
1956
+ const type = type_;
1729
1957
  const components = count ? parseInt(count) : 1;
1730
- const decodedType = decodeVertexType(type2);
1958
+ const decodedType = decodeVertexType(type);
1731
1959
  return {
1732
- type: type2,
1960
+ type,
1733
1961
  components,
1734
1962
  byteLength: decodedType.byteLength * components,
1735
1963
  integer: decodedType.integer,
@@ -1858,6 +2086,8 @@ var __exports__ = (() => {
1858
2086
  data: this.props.data
1859
2087
  });
1860
2088
  }
2089
+ this.width = this.handle.width;
2090
+ this.height = this.handle.height;
1861
2091
  this.sampler = props.sampler instanceof WebGPUSampler ? props.sampler : new WebGPUSampler(this.device, props.sampler);
1862
2092
  this.view = this.handle.createView({
1863
2093
  // format: this.props.format,
@@ -1939,7 +2169,10 @@ var __exports__ = (() => {
1939
2169
  // copySize: GPUExtent3D
1940
2170
  [width, height, depth]
1941
2171
  );
1942
- return this;
2172
+ return {
2173
+ width,
2174
+ height
2175
+ };
1943
2176
  }
1944
2177
  /*
1945
2178
  async readPixels() {
@@ -2057,7 +2290,8 @@ var __exports__ = (() => {
2057
2290
  }
2058
2291
  createHandle() {
2059
2292
  const {
2060
- source
2293
+ source,
2294
+ stage
2061
2295
  } = this.props;
2062
2296
  let language = this.props.language;
2063
2297
  if (!language) {
@@ -2072,7 +2306,7 @@ var __exports__ = (() => {
2072
2306
  return this.device.handle.createShaderModule({
2073
2307
  code: source,
2074
2308
  // @ts-expect-error
2075
- transform: (glsl) => this.device.glslang.compileGLSL(glsl, type)
2309
+ transform: (glsl) => this.device.glslang.compileGLSL(glsl, stage)
2076
2310
  });
2077
2311
  default:
2078
2312
  throw new Error(language);
@@ -2556,7 +2790,7 @@ var __exports__ = (() => {
2556
2790
  super(device, props);
2557
2791
  this.device = device;
2558
2792
  const framebuffer = props.framebuffer || device.canvasContext.getCurrentFramebuffer();
2559
- const renderPassDescriptor = framebuffer.renderPassDescriptor;
2793
+ const renderPassDescriptor = this.getRenderPassDescriptor(framebuffer);
2560
2794
  this.handle = this.props.handle || device.commandEncoder.beginRenderPass(renderPassDescriptor);
2561
2795
  this.handle.label = this.props.id;
2562
2796
  }
@@ -2627,6 +2861,31 @@ var __exports__ = (() => {
2627
2861
  // beginPipelineStatisticsQuery(querySet: GPUQuerySet, queryIndex: number): void;
2628
2862
  // endPipelineStatisticsQuery(querySet: GPUQuerySet, queryIndex: number): void;
2629
2863
  // executeBundles(bundles: Iterable<GPURenderBundle>): void;
2864
+ // INTERNAL
2865
+ /**
2866
+ * Partial render pass descriptor. Used by WebGPURenderPass.
2867
+ * @returns attachments fields of a renderpass descriptor.
2868
+ */
2869
+ getRenderPassDescriptor(framebuffer) {
2870
+ const renderPassDescriptor = {
2871
+ colorAttachments: []
2872
+ };
2873
+ renderPassDescriptor.colorAttachments = framebuffer.colorAttachments.map((colorAttachment) => ({
2874
+ // clear values
2875
+ loadOp: "clear",
2876
+ colorClearValue: this.props.clearColor || [0, 0, 0, 0],
2877
+ storeOp: this.props.discard ? "discard" : "store",
2878
+ // ...colorAttachment,
2879
+ view: colorAttachment.handle.createView()
2880
+ }));
2881
+ if (framebuffer.depthStencilAttachment) {
2882
+ renderPassDescriptor.depthStencilAttachment = {
2883
+ ...this.props,
2884
+ view: framebuffer.depthStencilAttachment.handle.createView()
2885
+ };
2886
+ }
2887
+ return renderPassDescriptor;
2888
+ }
2630
2889
  };
2631
2890
 
2632
2891
  // src/adapter/resources/webgpu-compute-pass.ts
@@ -2688,98 +2947,10 @@ var __exports__ = (() => {
2688
2947
 
2689
2948
  // src/adapter/resources/webgpu-framebuffer.ts
2690
2949
  var WebGPUFramebuffer = class extends Framebuffer {
2691
- colorAttachments = [];
2692
- depthStencilAttachment = null;
2693
- /** Partial render pass descriptor. Used by WebGPURenderPass */
2694
- renderPassDescriptor = {
2695
- colorAttachments: []
2696
- };
2697
2950
  constructor(device, props) {
2698
2951
  super(device, props);
2699
2952
  this.device = device;
2700
- if (props.depthStencilAttachment) {
2701
- this.depthStencilAttachment = this.createDepthStencilTexture(props);
2702
- }
2703
- if (props.colorAttachments) {
2704
- this.colorAttachments = props.colorAttachments.map((colorAttachment) => this.createColorTexture(this.props, colorAttachment));
2705
- }
2706
- if (this.depthStencilAttachment) {
2707
- this.renderPassDescriptor.depthStencilAttachment = {
2708
- view: this.depthStencilAttachment.handle.createView(),
2709
- // Add default clear values
2710
- depthClearValue: 1,
2711
- depthStoreOp: "store",
2712
- stencilClearValue: 0,
2713
- stencilStoreOp: "store"
2714
- };
2715
- }
2716
- if (this.colorAttachments.length > 0) {
2717
- this.renderPassDescriptor.colorAttachments = this.colorAttachments.map((colorAttachment) => ({
2718
- view: colorAttachment.handle.createView(),
2719
- loadOp: "clear",
2720
- loadValue: [0, 0, 0, 0],
2721
- storeOp: "store"
2722
- }));
2723
- }
2724
- }
2725
- /** Create depth stencil texture */
2726
- createDepthStencilTexture(props) {
2727
- if (props.depthStencilAttachment instanceof WebGPUTexture) {
2728
- return props.depthStencilAttachment;
2729
- }
2730
- if (typeof props.depthStencilAttachment === "string") {
2731
- return this.device._createTexture({
2732
- id: "depth-stencil-attachment",
2733
- format: props.depthStencilAttachment,
2734
- width: props.width,
2735
- height: props.height,
2736
- usage: Texture.RENDER_ATTACHMENT
2737
- });
2738
- }
2739
- throw new Error("type");
2740
- }
2741
- createColorTexture(props, texture) {
2742
- if (texture instanceof WebGPUTexture) {
2743
- return texture;
2744
- }
2745
- if (typeof texture === "string") {
2746
- return this.device._createTexture({
2747
- id: "color-attachment",
2748
- format: texture,
2749
- width: props.width,
2750
- height: props.height,
2751
- usage: Texture.RENDER_ATTACHMENT
2752
- });
2753
- }
2754
- throw new Error("type");
2755
- }
2756
- /**
2757
- * Create new textures with correct size for all attachments.
2758
- * @note destroys existing textures.
2759
- */
2760
- _resizeAttachments(width, height) {
2761
- for (let i = 0; i < this.colorAttachments.length; ++i) {
2762
- if (this.colorAttachments[i]) {
2763
- const resizedTexture = this.device._createTexture({
2764
- ...this.colorAttachments[i].props,
2765
- width,
2766
- height
2767
- });
2768
- this.colorAttachments[i].destroy();
2769
- this.colorAttachments[i] = resizedTexture;
2770
- this.renderPassDescriptor.colorAttachments[i].view = resizedTexture.handle.createView();
2771
- }
2772
- }
2773
- if (this.depthStencilAttachment) {
2774
- const resizedTexture = this.device._createTexture({
2775
- ...this.depthStencilAttachment.props,
2776
- width,
2777
- height
2778
- });
2779
- this.depthStencilAttachment.destroy();
2780
- this.depthStencilAttachment = resizedTexture;
2781
- this.renderPassDescriptor.depthStencilAttachment.view = resizedTexture.handle.createView();
2782
- }
2953
+ this.autoCreateAttachmentTextures();
2783
2954
  }
2784
2955
  };
2785
2956
 
@@ -2958,8 +3129,9 @@ var __exports__ = (() => {
2958
3129
  get isLost() {
2959
3130
  return this._isLost;
2960
3131
  }
2961
- _createBuffer(props) {
2962
- return new WebGPUBuffer(this, props);
3132
+ createBuffer(props) {
3133
+ const newProps = this._getBufferProps(props);
3134
+ return new WebGPUBuffer(this, newProps);
2963
3135
  }
2964
3136
  _createTexture(props) {
2965
3137
  return new WebGPUTexture(this, props);
@@ -2995,6 +3167,9 @@ var __exports__ = (() => {
2995
3167
  this.commandEncoder = this.commandEncoder || this.handle.createCommandEncoder();
2996
3168
  return new WebGPUComputePass(this, props);
2997
3169
  }
3170
+ // createCommandEncoder(props: CommandEncoderProps): WebGPUCommandEncoder {
3171
+ // return new WebGPUCommandEncoder(this, props);
3172
+ // }
2998
3173
  createCanvasContext(props) {
2999
3174
  return new WebGPUCanvasContext(this, this.adapter, props);
3000
3175
  }
@@ -3051,6 +3226,44 @@ var __exports__ = (() => {
3051
3226
  features.add("glsl-texture-lod");
3052
3227
  return features;
3053
3228
  }
3229
+ copyExternalImageToTexture(options) {
3230
+ const {
3231
+ source,
3232
+ sourceX = 0,
3233
+ sourceY = 0,
3234
+ texture,
3235
+ mipLevel = 0,
3236
+ aspect = "all",
3237
+ colorSpace = "display-p3",
3238
+ premultipliedAlpha = false,
3239
+ // destinationX,
3240
+ // destinationY,
3241
+ // desitnationZ,
3242
+ width = texture.width,
3243
+ height = texture.height,
3244
+ depth = 1
3245
+ } = options;
3246
+ const webGpuTexture = texture;
3247
+ this.handle?.queue.copyExternalImageToTexture(
3248
+ // source: GPUImageCopyExternalImage
3249
+ {
3250
+ source,
3251
+ origin: [sourceX, sourceY]
3252
+ },
3253
+ // destination: GPUImageCopyTextureTagged
3254
+ {
3255
+ texture: webGpuTexture.handle,
3256
+ origin: [0, 0, 0],
3257
+ // [x, y, z],
3258
+ mipLevel,
3259
+ aspect,
3260
+ colorSpace,
3261
+ premultipliedAlpha
3262
+ },
3263
+ // copySize: GPUExtent3D
3264
+ [width, height, depth]
3265
+ );
3266
+ }
3054
3267
  };
3055
3268
  var WebGPUDevice = _WebGPUDevice;
3056
3269
  __publicField(WebGPUDevice, "type", "webgpu");