@derschmale/tiny-helix 0.1.0 → 0.2.0

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.
@@ -80,7 +80,7 @@ class BindGroupBuilder {
80
80
  withTexture(fieldName, texture) {
81
81
  const index = this._layout._getBindingIndex(fieldName);
82
82
  this._entries[index] = {
83
- binding: index, resource: texture._inner
83
+ binding: index, resource: texture._inner,
84
84
  };
85
85
  return this;
86
86
  }
@@ -163,7 +163,7 @@ class BindGroupLayoutBuilder {
163
163
  withUniformBuffer(index, field_name, layout, visibility) {
164
164
  this._entries[index] = {
165
165
  binding: index,
166
- visibility: visibility ?? GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
166
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Vertex | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
167
167
  buffer: { type: 'uniform' }
168
168
  };
169
169
  this._indices.set(field_name, index);
@@ -173,57 +173,65 @@ class BindGroupLayoutBuilder {
173
173
  /**
174
174
  * Add a storage buffer binding at the given index and record its layout.
175
175
  * @param index - binding index
176
- * @param field_name - a name used to reference the layout later
177
- * @param access_mode - Defines whether the storage buffer is read-only or not.
176
+ * @param fieldName - a name used to reference the layout later
177
+ * @param accessMode - Defines whether the storage buffer is read-only or not.
178
178
  * @param visibility - shader stage visibility flags (defaults to FRAGMENT|COMPUTE)
179
179
  */
180
- withStorageBuffer(index, field_name, access_mode, visibility) {
180
+ withStorageBuffer(index, fieldName, accessMode, minBindingSize = 4, visibility) {
181
181
  let type = "storage";
182
- if (access_mode === _enums__WEBPACK_IMPORTED_MODULE_2__.StorageAccess.Read) {
182
+ if (accessMode === _enums__WEBPACK_IMPORTED_MODULE_2__.StorageAccess.Read) {
183
183
  type = "read-only-storage";
184
184
  }
185
185
  this._entries[index] = {
186
186
  binding: index,
187
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
188
- buffer: { type, hasDynamicOffset: false, minBindingSize: 4 }
187
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
188
+ buffer: { type, hasDynamicOffset: false, minBindingSize }
189
189
  };
190
- this._indices.set(field_name, index);
190
+ this._indices.set(fieldName, index);
191
191
  return this;
192
192
  }
193
193
  /**
194
194
  * Add a storage texture binding at the given index. The texture will be
195
195
  * write-only and use RGBA8Unorm format.
196
196
  * @param index
197
- * @param field_name
197
+ * @param fieldName
198
198
  * @param format
199
- * @param access_mode
199
+ * @param accessMode
200
200
  * @param visibility
201
+ * @param viewDimension
201
202
  */
202
- withStorageTexture(index, field_name, format, access_mode, visibility) {
203
+ withStorageTexture(index, fieldName, format, accessMode, visibility, viewDimension) {
203
204
  this._entries[index] = {
204
205
  binding: index,
205
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
206
- storageTexture: { access: access_mode, format }
206
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
207
+ storageTexture: {
208
+ access: accessMode,
209
+ format,
210
+ viewDimension: viewDimension ?? "2d"
211
+ }
207
212
  };
208
- this._indices.set(field_name, index);
213
+ this._indices.set(fieldName, index);
209
214
  return this;
210
215
  }
211
- withTexture(index, field_name, visibility) {
216
+ withTexture(index, fieldName, visibility, viewDimension, sampleType = _enums__WEBPACK_IMPORTED_MODULE_2__.TextureSampleType.Float) {
212
217
  this._entries[index] = {
213
218
  binding: index,
214
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
215
- texture: { sampleType: 'float' }
219
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
220
+ texture: {
221
+ sampleType,
222
+ viewDimension: viewDimension ?? "2d"
223
+ }
216
224
  };
217
- this._indices.set(field_name, index);
225
+ this._indices.set(fieldName, index);
218
226
  return this;
219
227
  }
220
- withSampler(index, field_name, visibility) {
228
+ withSampler(index, fieldName, samplerType = _enums__WEBPACK_IMPORTED_MODULE_2__.SamplerType.Filtering, visibility) {
221
229
  this._entries[index] = {
222
230
  binding: index,
223
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
224
- sampler: { type: 'filtering' }
231
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
232
+ sampler: { type: samplerType }
225
233
  };
226
- this._indices.set(field_name, index);
234
+ this._indices.set(fieldName, index);
227
235
  return this;
228
236
  }
229
237
  /**
@@ -458,12 +466,17 @@ class ComputePipeline {
458
466
  }
459
467
  class ComputePipelineBuilder {
460
468
  constructor(ctx) {
469
+ this._overrideConstants = {};
461
470
  this._ctx = ctx;
462
471
  }
463
472
  withLabel(label) {
464
473
  this._label = label;
465
474
  return this;
466
475
  }
476
+ withOverrideConstant(id, value) {
477
+ this._overrideConstants[id] = value;
478
+ return this;
479
+ }
467
480
  /** Select the shader entry point for the fragment stage. */
468
481
  withShader(shader, entry) {
469
482
  this._shader = shader;
@@ -480,7 +493,8 @@ class ComputePipelineBuilder {
480
493
  label: this._label,
481
494
  compute: {
482
495
  module: shader._inner,
483
- entryPoint: this._entry
496
+ entryPoint: this._entry,
497
+ constants: this._overrideConstants
484
498
  },
485
499
  layout
486
500
  };
@@ -526,7 +540,7 @@ class IndexBuffer {
526
540
  this.format = bytesPerElement === 2 ? IndexFormat.Uint16 : IndexFormat.Uint32;
527
541
  this.count = data.length;
528
542
  this.buffer = new _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferBuilder(ctx)
529
- .withData(data.buffer, keepData)
543
+ .withData(data.buffer, keepData, data.byteOffset, data.byteLength)
530
544
  .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.CopyDst | _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.Index)
531
545
  .build();
532
546
  }
@@ -744,9 +758,10 @@ class StreamBuilder {
744
758
  * Upload vertex data for this stream. `keepOnCPU` controls whether the
745
759
  * source ArrayBuffer is retained in memory for readback.
746
760
  */
747
- withData(data, keepOnCPU = false) {
761
+ withData(data, byteOffset = 0, byteLength, keepOnCPU = false) {
762
+ byteLength = byteLength ?? (data.byteLength - byteOffset);
748
763
  this._stream.buffer = new _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferBuilder(this._ctx)
749
- .withData(data, keepOnCPU)
764
+ .withData(data, keepOnCPU, byteOffset, byteLength)
750
765
  .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.Vertex | _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.CopyDst)
751
766
  .build();
752
767
  }
@@ -873,12 +888,26 @@ class RenderPass {
873
888
  /**
874
889
  * Issue a draw call using the currently set pipeline and mesh.
875
890
  */
876
- draw() {
891
+ draw(numInstances = 1) {
892
+ if (this._numIndices) {
893
+ this._inner.drawIndexed(this._numIndices, numInstances, 0, 0, 0);
894
+ }
895
+ else {
896
+ this._inner.draw(this._numVertices, numInstances, 0, 0);
897
+ }
898
+ return this;
899
+ }
900
+ /**
901
+ * Issue an indirect draw call using the currently set pipeline and mesh.
902
+ * @param indirectBuffer A Buffer containing the draw parameters. The buffer must have been created with the `Indirect` usage flag.
903
+ * @param indirectOffset The offset in bytes into the indirectBuffer where the draw parameters are stored. Must be a multiple of 4.
904
+ */
905
+ drawIndirect(indirectBuffer, indirectOffset = 0) {
877
906
  if (this._numIndices) {
878
- this._inner.drawIndexed(this._numIndices, 1, 0, 0, 0);
907
+ this._inner.drawIndexedIndirect(indirectBuffer._inner, indirectOffset);
879
908
  }
880
909
  else {
881
- this._inner.draw(this._numVertices, 1, 0, 0);
910
+ this._inner.drawIndirect(indirectBuffer._inner, indirectOffset);
882
911
  }
883
912
  return this;
884
913
  }
@@ -905,6 +934,7 @@ class RenderPassBuilder {
905
934
  constructor(commandEncoder, globalBindGroups, defaultTarget, defaultDepthTarget) {
906
935
  this._colorTargets = [];
907
936
  this._clearColors = [];
937
+ this._storeOps = [];
908
938
  this._encoder = commandEncoder;
909
939
  this._defaultTarget = defaultTarget;
910
940
  this._defaultDepthTarget = defaultDepthTarget;
@@ -949,6 +979,19 @@ class RenderPassBuilder {
949
979
  }
950
980
  return this;
951
981
  }
982
+ /**
983
+ * Set the store operation for the most recently added color target. Defaults to 'store' if not specified.
984
+ * @param storeOp
985
+ */
986
+ withStoreOp(storeOp) {
987
+ if (this._colorTargets.length === 0) {
988
+ this._storeOps[0] = storeOp;
989
+ }
990
+ else {
991
+ this._storeOps[this._colorTargets.length - 1] = storeOp;
992
+ }
993
+ return this;
994
+ }
952
995
  /**
953
996
  * Set the clear stencil value
954
997
  */
@@ -990,7 +1033,7 @@ class RenderPassBuilder {
990
1033
  const colorAttachments = targets.map((target, i) => ({
991
1034
  view: target._inner,
992
1035
  loadOp: this._clearColors[i] ? 'clear' : 'load',
993
- storeOp: 'store',
1036
+ storeOp: this._storeOps[i] ?? 'store',
994
1037
  clearValue: this._clearColors[i]
995
1038
  }));
996
1039
  const desc = {
@@ -1134,6 +1177,24 @@ class RenderPipelineBuilder {
1134
1177
  }
1135
1178
  return this;
1136
1179
  }
1180
+ /**
1181
+ * Sets the depth bias for each triangle.
1182
+ * @param depthBias Constant depth bias added to each triangle fragment.
1183
+ * @param slopeScale Depth bias that scales with the triangle fragment’s slope.
1184
+ * @param max The maximum depth bias of a triangle fragment.
1185
+ */
1186
+ withDepthBias(depthBias, slopeScale, max) {
1187
+ const target = this._depthState ?? this._defaultDepthState;
1188
+ if (!target) {
1189
+ console.warn("No depth target set. Setting depth compare function has no effect.");
1190
+ }
1191
+ else {
1192
+ target.depthBias = depthBias;
1193
+ target.depthBiasSlopeScale = slopeScale;
1194
+ target.depthBiasClamp = max;
1195
+ }
1196
+ return this;
1197
+ }
1137
1198
  /**
1138
1199
  * Enable or disable depth writes. Default is `true`.
1139
1200
  * @param enabled
@@ -1148,9 +1209,19 @@ class RenderPipelineBuilder {
1148
1209
  }
1149
1210
  return this;
1150
1211
  }
1151
- /** Override a shader constant for specialization. */
1152
- withOverrideConstant(id, value) {
1153
- this._overrideConstants[id] = value;
1212
+ /**
1213
+ * Override a shader constant for specialization. We do NOT use `ShaderStage.Vertex | ShaderStage.Fragment` as
1214
+ * default because some browser implementations (as of early 2026) have bugs when a non-existent constant is defined
1215
+ */
1216
+ withOverrideConstant(id, value, pipeline) {
1217
+ if (pipeline & GPUShaderStage.VERTEX) {
1218
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex] = this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex] || {};
1219
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex][id] = value;
1220
+ }
1221
+ if (pipeline & GPUShaderStage.FRAGMENT) {
1222
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment] = this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment] || {};
1223
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment][id] = value;
1224
+ }
1154
1225
  return this;
1155
1226
  }
1156
1227
  /** Set the blend mode for the last assigned (or default) color target. */
@@ -1158,6 +1229,18 @@ class RenderPipelineBuilder {
1158
1229
  this.lastColorTarget.blend = blendMode._inner;
1159
1230
  return this;
1160
1231
  }
1232
+ /** Set the color write mask for the last assigned (or default) color target. */
1233
+ withColorWrite(r, g, b, a) {
1234
+ g ?? (g = r);
1235
+ b ?? (b = g);
1236
+ a ?? (a = b);
1237
+ this.lastColorTarget.writeMask =
1238
+ (r ? GPUColorWrite.RED : 0) |
1239
+ (g ? GPUColorWrite.GREEN : 0) |
1240
+ (b ? GPUColorWrite.BLUE : 0) |
1241
+ (a ? GPUColorWrite.ALPHA : 0);
1242
+ return this;
1243
+ }
1161
1244
  /**
1162
1245
  * Build and create the `RenderPipeline`. Throws if required pieces (shader/vertices)
1163
1246
  * are missing.
@@ -1217,13 +1300,13 @@ class RenderPipelineBuilder {
1217
1300
  buffers,
1218
1301
  module: shader._inner,
1219
1302
  entryPoint: this._vertexEntry,
1220
- constants: this._overrideConstants
1303
+ constants: this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex]
1221
1304
  },
1222
1305
  fragment: (0,_utils_mapUndefined__WEBPACK_IMPORTED_MODULE_0__.mapUndefined)(this._fragmentEntry, entry => ({
1223
1306
  module: shader._inner,
1224
1307
  entryPoint: entry,
1225
1308
  targets: colorTargets,
1226
- constants: this._overrideConstants
1309
+ constants: this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment]
1227
1310
  }))
1228
1311
  };
1229
1312
  const inner = this._ctx.device.createRenderPipeline(desc);
@@ -1299,16 +1382,17 @@ class RenderTargetBuilder {
1299
1382
  */
1300
1383
  build() {
1301
1384
  const tex = this._texture._inner;
1302
- const desc = {
1385
+ const view = this._texture._inner.createView({
1303
1386
  format: tex.format,
1304
1387
  dimension: tex.dimension,
1305
1388
  aspect: 'all',
1306
1389
  baseMipLevel: this._baseMipLevel,
1307
1390
  mipLevelCount: 1,
1308
1391
  baseArrayLayer: this._baseArrayLayer,
1309
- arrayLayerCount: 1
1310
- };
1311
- return new RenderTarget(this._texture._inner.createView(desc), this._texture.format);
1392
+ arrayLayerCount: 1,
1393
+ usage: GPUTextureUsage.RENDER_ATTACHMENT,
1394
+ });
1395
+ return new RenderTarget(view, this._texture.format);
1312
1396
  }
1313
1397
  }
1314
1398
 
@@ -1335,18 +1419,23 @@ class Sampler {
1335
1419
  }
1336
1420
  class SamplerBuilder {
1337
1421
  constructor(ctx) {
1422
+ this._desc = {};
1338
1423
  this._ctx = ctx;
1339
1424
  }
1425
+ withLabel(label) {
1426
+ this._desc.label = label;
1427
+ return this;
1428
+ }
1340
1429
  withAddressMode(u, v, w) {
1341
- this._addressModeU = u;
1342
- this._addressModeV = v ?? u;
1343
- this._addressModeW = w ?? u;
1430
+ this._desc.addressModeU = u;
1431
+ this._desc.addressModeV = v ?? u;
1432
+ this._desc.addressModeW = w ?? u;
1344
1433
  return this;
1345
1434
  }
1346
1435
  withFiltering(minFilter, magFilter, mipmapFilter) {
1347
- this._minFilter = minFilter;
1348
- this._magFilter = magFilter ?? minFilter;
1349
- this._mipmapFilter = mipmapFilter ?? minFilter;
1436
+ this._desc.minFilter = minFilter;
1437
+ this._desc.magFilter = magFilter ?? minFilter;
1438
+ this._desc.mipmapFilter = mipmapFilter ?? minFilter;
1350
1439
  return this;
1351
1440
  }
1352
1441
  withTrilinearFiltering() {
@@ -1359,34 +1448,23 @@ class SamplerBuilder {
1359
1448
  }
1360
1449
  withAnisotropicFiltering(maxAnisotropy) {
1361
1450
  this.withFiltering(_enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Linear);
1362
- this._maxAnisotropy = maxAnisotropy;
1451
+ this._desc.maxAnisotropy = maxAnisotropy;
1363
1452
  return this;
1364
1453
  }
1365
1454
  withMinMipLevel(level) {
1366
- this._minMipLevel = level;
1455
+ this._desc.lodMinClamp = level;
1367
1456
  return this;
1368
1457
  }
1369
1458
  withMaxMipLevel(level) {
1370
- this._maxMipLevel = level;
1459
+ this._desc.lodMaxClamp = level;
1371
1460
  return this;
1372
1461
  }
1373
1462
  withCompareFunction(compare) {
1374
- this._compare = compare;
1463
+ this._desc.compare = compare;
1375
1464
  return this;
1376
1465
  }
1377
1466
  build() {
1378
- return new Sampler(this._ctx.device.createSampler({
1379
- addressModeU: this._addressModeU,
1380
- addressModeV: this._addressModeV,
1381
- addressModeW: this._addressModeW,
1382
- magFilter: this._magFilter,
1383
- minFilter: this._minFilter,
1384
- mipmapFilter: this._mipmapFilter,
1385
- lodMinClamp: this._minMipLevel,
1386
- lodMaxClamp: this._maxMipLevel,
1387
- compare: this._compare,
1388
- maxAnisotropy: this._maxAnisotropy
1389
- }));
1467
+ return new Sampler(this._ctx.device.createSampler(this._desc));
1390
1468
  }
1391
1469
  }
1392
1470
 
@@ -1420,6 +1498,9 @@ class Shader {
1420
1498
  this._vertexAttributes = vertexAttributes;
1421
1499
  this._bindGroupLayouts = bindGroupLayouts;
1422
1500
  }
1501
+ getCompilationInfo() {
1502
+ return this._inner.getCompilationInfo();
1503
+ }
1423
1504
  /**
1424
1505
  * Get the shader location for a named vertex attribute. Returns undefined if the attribute
1425
1506
  * is not declared by the shader.
@@ -1480,7 +1561,7 @@ class ShaderBuilder {
1480
1561
  return this;
1481
1562
  }
1482
1563
  /** Declare a named vertex attribute and the location it maps to in the shader. */
1483
- withVertexAttribute(name, location) {
1564
+ withVertexAttribute(location, name) {
1484
1565
  this._vertexAttributes.set(name, location);
1485
1566
  return this;
1486
1567
  }
@@ -1502,9 +1583,21 @@ class ShaderBuilder {
1502
1583
  if (!this._code) {
1503
1584
  throw new Error("Shader code not specified. Use withCode() to set the shader source.");
1504
1585
  }
1505
- let code = this._code;
1586
+ const header = this._ctx.shaderF16Supported ?
1587
+ `enable f16;
1588
+ alias half = f16;
1589
+ alias vec2h = vec2<f16>;
1590
+ alias vec3h = vec3<f16>;
1591
+ alias vec4h = vec4<f16>;
1592
+ ` :
1593
+ `alias half = f32;
1594
+ alias vec2h = vec2<f32>;
1595
+ alias vec3h = vec3<f32>;
1596
+ alias vec4h = vec4<f32>;
1597
+ `;
1598
+ let code = header + "\n\n" + this._code;
1506
1599
  for (const [name, inc] of this._includes) {
1507
- // Create a regex to match the include directive while allowing
1600
+ // regex to match the include directive while allowing
1508
1601
  // optional whitespace between tokens, e.g.:
1509
1602
  // #include<name>
1510
1603
  // # include < name >
@@ -1534,10 +1627,15 @@ __webpack_require__.r(__webpack_exports__);
1534
1627
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1535
1628
  /* harmony export */ Texture: () => (/* binding */ Texture),
1536
1629
  /* harmony export */ TextureBuilder: () => (/* binding */ TextureBuilder),
1630
+ /* harmony export */ TextureUtils: () => (/* binding */ TextureUtils),
1537
1631
  /* harmony export */ TextureView: () => (/* binding */ TextureView),
1538
1632
  /* harmony export */ TextureViewBuilder: () => (/* binding */ TextureViewBuilder)
1539
1633
  /* harmony export */ });
1540
1634
  /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./enums */ "./src/enums.ts");
1635
+ /* harmony import */ var _utils_MipRenderer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/MipRenderer */ "./src/utils/MipRenderer.ts");
1636
+ /* harmony import */ var _utils_mapUndefined__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/mapUndefined */ "./src/utils/mapUndefined.ts");
1637
+
1638
+
1541
1639
 
1542
1640
  /**
1543
1641
  * Small wrapper around GPUTexture providing convenience constructors and
@@ -1545,15 +1643,16 @@ __webpack_require__.r(__webpack_exports__);
1545
1643
  */
1546
1644
  class Texture {
1547
1645
  /**
1548
- * Create a Texture wrapper from an existing GPUTexture.
1549
- * @param texture - The underlying GPUTexture
1646
+ * @internal
1550
1647
  */
1551
- static from_webgpu(texture, format) {
1552
- return new Texture(texture, format);
1648
+ static from_webgpu(texture, format, ctx, mipShader) {
1649
+ return new Texture(texture, format, ctx, mipShader);
1553
1650
  }
1554
- constructor(inner, format) {
1651
+ constructor(inner, format, ctx, mipShader) {
1555
1652
  this._inner = inner;
1556
1653
  this._format = format;
1654
+ this._ctx = ctx;
1655
+ this._mipper = (0,_utils_mapUndefined__WEBPACK_IMPORTED_MODULE_2__.mapUndefined)(mipShader, (mipShader) => new _utils_MipRenderer__WEBPACK_IMPORTED_MODULE_1__.MipRenderer(ctx, mipShader, this));
1557
1656
  }
1558
1657
  createView() {
1559
1658
  return new TextureViewBuilder(this);
@@ -1561,33 +1660,103 @@ class Texture {
1561
1660
  get format() {
1562
1661
  return this._format;
1563
1662
  }
1663
+ get mipLevelCount() {
1664
+ return this._inner.mipLevelCount;
1665
+ }
1666
+ get width() {
1667
+ return this._inner.width;
1668
+ }
1669
+ get height() {
1670
+ return this._inner.height;
1671
+ }
1672
+ get depthOrArrayLayers() {
1673
+ return this._inner.depthOrArrayLayers;
1674
+ }
1564
1675
  _getBufferResource() {
1565
1676
  return this._inner.createView();
1566
1677
  }
1678
+ uploadImage(data, mipLevel = 0) {
1679
+ this._ctx.device.queue.copyExternalImageToTexture({ source: data }, { texture: this._inner, mipLevel }, [data.width, data.height, 1]);
1680
+ }
1681
+ uploadData(data, mipLevel = 0) {
1682
+ const width = Math.max(this._inner.width >> mipLevel, 1);
1683
+ const height = Math.max(this._inner.height >> mipLevel, 1);
1684
+ const depthOrArrayLayers = Math.max(this._inner.depthOrArrayLayers >> mipLevel, 1);
1685
+ const blockWidth = TextureUtils.getBlockWidth(this._format);
1686
+ const blocksPerRow = Math.ceil(width / blockWidth);
1687
+ const bytesPerRow = blocksPerRow * TextureUtils.bytesPerBlock(this._format);
1688
+ this._ctx.device.queue.writeTexture({ texture: this._inner, mipLevel }, data, {
1689
+ bytesPerRow,
1690
+ rowsPerImage: height // This is what Mario is asking for!
1691
+ }, { width, height, depthOrArrayLayers });
1692
+ }
1693
+ generateMipmaps() {
1694
+ if (this._inner.dimension !== _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D2) {
1695
+ throw new Error('generateMipmaps currently only supports 2D textures.');
1696
+ }
1697
+ this._mipper.render();
1698
+ }
1699
+ dimension() {
1700
+ switch (this._inner.dimension) {
1701
+ case "1d":
1702
+ return _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D1;
1703
+ case "2d":
1704
+ return _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D2;
1705
+ case "3d":
1706
+ return _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D3;
1707
+ default:
1708
+ throw new Error(`Unknown texture dimension: ${this._inner.dimension}`);
1709
+ }
1710
+ }
1567
1711
  }
1568
1712
  class TextureBuilder {
1569
- constructor(ctx) {
1713
+ constructor(ctx, mipShader) {
1570
1714
  this._size = [1, 1, 1];
1571
- this._data = undefined;
1572
1715
  this._format = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb;
1573
1716
  this._usage = GPUTextureUsage.TEXTURE_BINDING;
1717
+ this._dimension = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D2;
1718
+ this._mipLevelCount = 1; // -1 will mean auto calculate based on size
1719
+ this._generateMips = false;
1720
+ this._mipShader = mipShader;
1574
1721
  this._ctx = ctx;
1575
1722
  }
1576
1723
  withSize(width, height, depthOrArrayLayers = 1) {
1577
1724
  this._size = [width, height, depthOrArrayLayers];
1725
+ if (depthOrArrayLayers > 1) {
1726
+ this._dimension = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D3;
1727
+ }
1578
1728
  return this;
1579
1729
  }
1580
- withData(data) {
1581
- this._data = data;
1730
+ withDimension(dim) {
1731
+ this._dimension = dim;
1732
+ return this;
1733
+ }
1734
+ withMipLevels(count) {
1735
+ this._mipLevelCount = count ?? -1;
1582
1736
  return this;
1583
1737
  }
1584
1738
  withFormat(format) {
1585
1739
  this._format = format;
1586
1740
  return this;
1587
1741
  }
1588
- withImage(data) {
1589
- this._data = data;
1590
- this._size = [data.width, data.height, 1];
1742
+ withData(data, mipLevel = 0) {
1743
+ this._data = this._data ?? [];
1744
+ this._data[mipLevel] = data;
1745
+ this._mipLevelCount = Math.max(this._mipLevelCount, mipLevel + 1);
1746
+ return this;
1747
+ }
1748
+ withImage(data, mipLevel = 0) {
1749
+ this._data = this._data ?? [];
1750
+ this._data[mipLevel] = data;
1751
+ if (mipLevel === 0) {
1752
+ this._size = [data.width, data.height, 1];
1753
+ }
1754
+ this._mipLevelCount = Math.max(this._mipLevelCount, mipLevel + 1);
1755
+ return this;
1756
+ }
1757
+ withGeneratedMipmaps() {
1758
+ this._mipLevelCount = -1;
1759
+ this._generateMips = true;
1591
1760
  return this;
1592
1761
  }
1593
1762
  withUsage(usage) {
@@ -1598,20 +1767,38 @@ class TextureBuilder {
1598
1767
  if (this._data) {
1599
1768
  this._usage |= GPUTextureUsage.COPY_DST;
1600
1769
  }
1770
+ if (this._generateMips) {
1771
+ this._usage |= GPUTextureUsage.RENDER_ATTACHMENT;
1772
+ }
1773
+ if (this._mipLevelCount == -1) {
1774
+ const maxDimension = Math.max(this._size[0], this._size[1], this._size[2]);
1775
+ this._mipLevelCount = Math.floor(Math.log2(maxDimension)) + 1;
1776
+ }
1601
1777
  const inner = this._ctx.device.createTexture({
1602
- format: this._format, size: this._size, usage: this._usage
1778
+ format: this._format, size: this._size, usage: this._usage,
1779
+ dimension: this._dimension,
1780
+ mipLevelCount: this._mipLevelCount
1603
1781
  });
1604
- if (this._data instanceof ImageBitmap) {
1605
- this._ctx.device.queue.copyExternalImageToTexture({ source: this._data }, { texture: inner }, [this._size[0], this._size[1], 1]);
1606
- }
1607
- else if (this._data) {
1608
- const [width, height, depthOrArrayLayers] = this._size;
1609
- const blockWidth = getBlockWidth(this._format);
1610
- const blocksPerRow = Math.ceil(width / blockWidth);
1611
- const bytesPerRow = blocksPerRow * bytesPerBlock(this._format);
1612
- this._ctx.device.queue.writeTexture({ texture: inner }, this._data, { bytesPerRow }, { width, height, depthOrArrayLayers });
1782
+ const tex = new Texture(inner, this._format, this._ctx, this._generateMips ? this._mipShader : undefined);
1783
+ if (this._data) {
1784
+ const mipCount = this._generateMips ? 1 : this._mipLevelCount;
1785
+ for (let mipLevel = 0; mipLevel < mipCount; mipLevel++) {
1786
+ const data = this._data[mipLevel];
1787
+ if (!data)
1788
+ throw new Error(`TextureBuilder: Missing data for mip level ${mipLevel}`);
1789
+ if (data instanceof ImageBitmap) {
1790
+ tex.uploadImage(data, mipLevel);
1791
+ }
1792
+ else {
1793
+ tex.uploadData(data, mipLevel);
1794
+ }
1795
+ }
1796
+ if (this._generateMips) {
1797
+ // Generate mipmaps using a simple render pass approach
1798
+ tex.generateMipmaps();
1799
+ }
1613
1800
  }
1614
- return new Texture(inner, this._format);
1801
+ return tex;
1615
1802
  }
1616
1803
  }
1617
1804
  class TextureView {
@@ -1627,6 +1814,13 @@ class TextureViewBuilder {
1627
1814
  this._desc = {};
1628
1815
  this._texture = texture;
1629
1816
  }
1817
+ withUsage(usage) {
1818
+ if (this._desc.usage === undefined) {
1819
+ this._desc.usage = 0;
1820
+ }
1821
+ this._desc.usage |= usage;
1822
+ return this;
1823
+ }
1630
1824
  withSingleMip(level) {
1631
1825
  this._desc.baseMipLevel = level;
1632
1826
  this._desc.mipLevelCount = 1;
@@ -1647,212 +1841,219 @@ class TextureViewBuilder {
1647
1841
  this._desc.arrayLayerCount = end;
1648
1842
  return this;
1649
1843
  }
1844
+ withDimension(dim) {
1845
+ this._desc.dimension = dim;
1846
+ return this;
1847
+ }
1650
1848
  build() {
1651
1849
  return new TextureView(this._texture._inner.createView(this._desc));
1652
1850
  }
1653
1851
  }
1654
- function isBc(format) {
1655
- switch (format) {
1656
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1657
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1658
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1659
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
1660
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
1661
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
1662
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1663
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1664
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
1665
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
1666
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
1667
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
1668
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
1669
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
1670
- return true;
1671
- default: return false;
1852
+ class TextureUtils {
1853
+ static isBc(format) {
1854
+ switch (format) {
1855
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1856
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1857
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1858
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
1859
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
1860
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
1861
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1862
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1863
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
1864
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
1865
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
1866
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
1867
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
1868
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
1869
+ return true;
1870
+ default:
1871
+ return false;
1872
+ }
1672
1873
  }
1673
- }
1674
- function isEtc(format) {
1675
- switch (format) {
1676
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1677
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1678
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
1679
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
1680
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
1681
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
1682
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
1683
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
1684
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
1685
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
1686
- return true;
1687
- default:
1688
- return false;
1874
+ static isEtc(format) {
1875
+ switch (format) {
1876
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1877
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1878
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
1879
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
1880
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
1881
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
1882
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
1883
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
1884
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
1885
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
1886
+ return true;
1887
+ default:
1888
+ return false;
1889
+ }
1689
1890
  }
1690
- }
1691
- function getBlockWidth(format) {
1692
- if (isBc(format) || isEtc(format))
1693
- return 4;
1694
- switch (format) {
1695
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
1696
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
1891
+ static getBlockWidth(format) {
1892
+ if (TextureUtils.isBc(format) || TextureUtils.isEtc(format))
1697
1893
  return 4;
1698
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
1699
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
1700
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
1701
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
1702
- return 5;
1703
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
1704
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
1705
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
1706
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
1707
- return 6;
1708
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
1709
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
1710
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
1711
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
1712
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
1713
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
1714
- return 8;
1715
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
1716
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
1717
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
1718
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
1719
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
1720
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
1721
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
1722
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
1723
- return 10;
1724
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
1725
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
1726
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
1727
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
1728
- return 12;
1729
- default:
1730
- return 1;
1894
+ switch (format) {
1895
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
1896
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
1897
+ return 4;
1898
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
1899
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
1900
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
1901
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
1902
+ return 5;
1903
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
1904
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
1905
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
1906
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
1907
+ return 6;
1908
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
1909
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
1910
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
1911
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
1912
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
1913
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
1914
+ return 8;
1915
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
1916
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
1917
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
1918
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
1919
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
1920
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
1921
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
1922
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
1923
+ return 10;
1924
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
1925
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
1926
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
1927
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
1928
+ return 12;
1929
+ default:
1930
+ return 1;
1931
+ }
1731
1932
  }
1732
- }
1733
- /**
1734
- * Returns the number of bytes in a compressed or uncompressed block for the
1735
- * given texture format. Matches the mapping from the Rust implementation and
1736
- * throws for unsupported formats.
1737
- */
1738
- function bytesPerBlock(format) {
1739
- switch (format) {
1740
- // 1-byte formats
1741
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Unorm:
1742
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Snorm:
1743
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Uint:
1744
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Sint:
1745
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Stencil8:
1746
- return 1;
1747
- // 2-byte formats
1748
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Uint:
1749
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Sint:
1750
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Unorm:
1751
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Snorm:
1752
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Float:
1753
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Unorm:
1754
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Snorm:
1755
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Uint:
1756
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Sint:
1757
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth16Unorm:
1758
- return 2;
1759
- // 4-byte formats
1760
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Uint:
1761
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Sint:
1762
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Float:
1763
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Uint:
1764
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Sint:
1765
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Unorm:
1766
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Snorm:
1767
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Float:
1768
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Unorm:
1769
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb:
1770
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Snorm:
1771
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Uint:
1772
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Sint:
1773
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8Unorm:
1774
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8UnormSrgb:
1775
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb9e5Ufloat:
1776
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Uint:
1777
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Unorm:
1778
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24Plus:
1779
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24PlusStencil8:
1780
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32Float:
1781
- return 4;
1782
- // 8-byte formats
1783
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rg11b10Ufloat:
1784
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Uint:
1785
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Sint:
1786
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Float:
1787
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Uint:
1788
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Sint:
1789
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Unorm:
1790
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Snorm:
1791
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Float:
1792
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32FloatStencil8:
1793
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1794
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1795
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1796
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1797
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1798
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1799
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
1800
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
1801
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
1802
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
1803
- return 8;
1804
- // 16-byte formats
1805
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Uint:
1806
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Sint:
1807
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Float:
1808
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1809
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
1810
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
1811
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
1812
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
1813
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
1814
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
1815
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
1816
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
1817
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
1818
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
1819
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
1820
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
1821
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
1822
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
1823
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
1824
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
1825
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
1826
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
1827
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
1828
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
1829
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
1830
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
1831
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
1832
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
1833
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
1834
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
1835
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
1836
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
1837
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
1838
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
1839
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
1840
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
1841
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
1842
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
1843
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
1844
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
1845
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
1846
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
1847
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
1848
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
1849
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
1850
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1851
- // NOTE: Bc2RgbaUnorm is already listed above; duplicate entries are
1852
- // harmless but kept out of caution when mapping from Rust.
1853
- return 16;
1854
- default:
1855
- throw new Error(`Unsupported texture format: ${format}`);
1933
+ /**
1934
+ * Returns the number of bytes in a compressed or uncompressed block for the
1935
+ * given texture format. Matches the mapping from the Rust implementation and
1936
+ * throws for unsupported formats.
1937
+ */
1938
+ static bytesPerBlock(format) {
1939
+ switch (format) {
1940
+ // 1-byte formats
1941
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Unorm:
1942
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Snorm:
1943
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Uint:
1944
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Sint:
1945
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Stencil8:
1946
+ return 1;
1947
+ // 2-byte formats
1948
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Uint:
1949
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Sint:
1950
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Unorm:
1951
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Snorm:
1952
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Float:
1953
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Unorm:
1954
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Snorm:
1955
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Uint:
1956
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Sint:
1957
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth16Unorm:
1958
+ return 2;
1959
+ // 4-byte formats
1960
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Uint:
1961
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Sint:
1962
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Float:
1963
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Uint:
1964
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Sint:
1965
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Unorm:
1966
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Snorm:
1967
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Float:
1968
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Unorm:
1969
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb:
1970
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Snorm:
1971
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Uint:
1972
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Sint:
1973
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8Unorm:
1974
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8UnormSrgb:
1975
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb9e5Ufloat:
1976
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Uint:
1977
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Unorm:
1978
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24Plus:
1979
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24PlusStencil8:
1980
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32Float:
1981
+ return 4;
1982
+ // 8-byte formats
1983
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rg11b10Ufloat:
1984
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Uint:
1985
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Sint:
1986
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Float:
1987
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Uint:
1988
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Sint:
1989
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Unorm:
1990
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Snorm:
1991
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Float:
1992
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32FloatStencil8:
1993
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1994
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1995
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1996
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1997
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1998
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1999
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
2000
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
2001
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
2002
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
2003
+ return 8;
2004
+ // 16-byte formats
2005
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Uint:
2006
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Sint:
2007
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Float:
2008
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
2009
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
2010
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
2011
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
2012
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
2013
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
2014
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
2015
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
2016
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
2017
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
2018
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
2019
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
2020
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
2021
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
2022
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
2023
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
2024
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
2025
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
2026
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
2027
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
2028
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
2029
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
2030
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
2031
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
2032
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
2033
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
2034
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
2035
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
2036
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
2037
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
2038
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
2039
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
2040
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
2041
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
2042
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
2043
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
2044
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
2045
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
2046
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
2047
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
2048
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
2049
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
2050
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
2051
+ // NOTE: Bc2RgbaUnorm is already listed above; duplicate entries are
2052
+ // harmless but kept out of caution when mapping from Rust.
2053
+ return 16;
2054
+ default:
2055
+ throw new Error(`Unsupported texture format: ${format}`);
2056
+ }
1856
2057
  }
1857
2058
  }
1858
2059
 
@@ -1882,6 +2083,8 @@ __webpack_require__.r(__webpack_exports__);
1882
2083
  /* harmony import */ var _ComputePipeline__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ComputePipeline */ "./src/ComputePipeline.ts");
1883
2084
  /* harmony import */ var _utils_mapUndefined__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils/mapUndefined */ "./src/utils/mapUndefined.ts");
1884
2085
  /* harmony import */ var _buffers_Buffer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./buffers/Buffer */ "./src/buffers/Buffer.ts");
2086
+ /* harmony import */ var _wgsl_mip_2d_2x2_wgsl__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./wgsl/mip_2d_2x2.wgsl */ "./src/wgsl/mip_2d_2x2.wgsl");
2087
+
1885
2088
 
1886
2089
 
1887
2090
 
@@ -1901,15 +2104,65 @@ __webpack_require__.r(__webpack_exports__);
1901
2104
  */
1902
2105
  class TinyHelix {
1903
2106
  /**
1904
- * Create a new TinyHelix instance. Call `initialize()` before rendering.
1905
- */
1906
- constructor(canvas) {
2107
+ * Create a new TinyHelix instance from a HTMLCanvasElement or an existing TinyHelix instance.
2108
+ * When creating from a Canvas, call `initialize()` before rendering to initialize the WebGPU context. When
2109
+ * using an existing TinyHelix instance, the new instance will share the same WebGPU context and resources.
2110
+ */
2111
+ constructor(canvasOrHX) {
2112
+ this._parent = null;
1907
2113
  this._options = {};
1908
2114
  this._shaderIncludes = new Map();
1909
- this._globalBindBufferLayouts = [];
1910
- this._globalBindBuffers = [];
1911
- this._context = new _WebGPUContext__WEBPACK_IMPORTED_MODULE_0__.WebGPUContext();
1912
- this._canvas = canvas;
2115
+ this._globalBindGroupLayouts = [];
2116
+ this._globalBindGroups = [];
2117
+ if (canvasOrHX instanceof TinyHelix) {
2118
+ this._context = canvasOrHX._context;
2119
+ this._canvas = canvasOrHX._canvas;
2120
+ this._mipShader = canvasOrHX._mipShader;
2121
+ this._depthStencil = canvasOrHX._depthStencil;
2122
+ this._depthStencilTarget = canvasOrHX._depthStencilTarget;
2123
+ }
2124
+ else {
2125
+ this._context = new _WebGPUContext__WEBPACK_IMPORTED_MODULE_0__.WebGPUContext();
2126
+ this._canvas = canvasOrHX;
2127
+ }
2128
+ }
2129
+ get shaderF16Supported() {
2130
+ return this._context.shaderF16Supported;
2131
+ }
2132
+ get floatFilteringSupported() {
2133
+ return this._context.floatFilteringSupported;
2134
+ }
2135
+ get adapter() {
2136
+ return this._context.adapter;
2137
+ }
2138
+ get device() {
2139
+ return this._context.device;
2140
+ }
2141
+ get context() {
2142
+ return this._context.context;
2143
+ }
2144
+ /**
2145
+ * Copies all shader includes from another TinyHelix instance.
2146
+ * @param hx - The TinyHelix instance to copy includes from.
2147
+ */
2148
+ copyIncludesFrom(hx) {
2149
+ hx._shaderIncludes.forEach((v, k) => this._shaderIncludes.set(k, v));
2150
+ return this;
2151
+ }
2152
+ /**
2153
+ * Copies all global bind groups from another TinyHelix instance.
2154
+ * @param hx - The TinyHelix instance to copy global bind groups from.
2155
+ */
2156
+ copyGlobalBindGroupsFrom(hx) {
2157
+ if (this._context != hx._context) {
2158
+ throw new Error("Cannot copy global bind groups from another TinyHelix instance with a different WebGPU context.");
2159
+ }
2160
+ if (this._globalBindGroups.length > 0 || this._globalBindGroupLayouts.length > 0) {
2161
+ throw new Error("Cannot copy global bind groups from another TinyHelix instance if this instance already has global bind groups set.");
2162
+ }
2163
+ this._globalBindGroupLayouts = [...hx._globalBindGroupLayouts];
2164
+ this._globalBindGroups = [...hx._globalBindGroups];
2165
+ return this;
1913
2166
  }
1914
2167
  /**
1915
2168
  * Initializes the underlying WebGPU context and prepares resources.
@@ -1921,6 +2174,10 @@ class TinyHelix {
1921
2174
  this._options = options;
1922
2175
  await this._context.initialize(options);
1923
2176
  this._createDepthStencil();
2177
+ this._mipShader = this._context.device.createShaderModule({
2178
+ code: _wgsl_mip_2d_2x2_wgsl__WEBPACK_IMPORTED_MODULE_13__,
2179
+ label: "MipRenderer Shader Module",
2180
+ });
1924
2181
  }
1925
2182
  resize(width, height) {
1926
2183
  this._canvas.width = width;
@@ -1992,9 +2249,17 @@ class TinyHelix {
1992
2249
  * @example tiny.startFrame();
1993
2250
  */
1994
2251
  startFrame() {
1995
- this._backbuffer = _Texture__WEBPACK_IMPORTED_MODULE_2__.Texture.from_webgpu(this._context.getCurrentTexture(), this._context.format);
1996
- this._backbufferTarget = this.createRenderTarget(this._backbuffer)
1997
- .build();
2252
+ if (this._parent) {
2253
+ this._backbuffer = this._parent.backbuffer;
2254
+ this._backbufferTarget = this._parent.backbufferTarget;
2255
+ return;
2256
+ }
2257
+ else {
2258
+ this._backbuffer = _Texture__WEBPACK_IMPORTED_MODULE_2__.Texture.from_webgpu(this._context.getCurrentTexture(), this._context.format, this._context);
2259
+ this._backbufferTarget = this.createRenderTarget(this._backbuffer)
2260
+ .withMipLevel(0)
2261
+ .build();
2262
+ }
1998
2263
  }
1999
2264
  /**
2000
2265
  * Create a RenderTargetBuilder for a given texture.
@@ -2008,7 +2273,7 @@ class TinyHelix {
2008
2273
  createShader() {
2009
2274
  let builder = new _Shader__WEBPACK_IMPORTED_MODULE_4__.ShaderBuilder(this._context);
2010
2275
  this._shaderIncludes.forEach((v, k) => builder = builder.withInclude(k, v));
2011
- this._globalBindBufferLayouts.forEach((layout, i) => builder.withBindGroup(i, layout));
2276
+ this._globalBindGroupLayouts.forEach((layout, i) => builder.withBindGroup(i, layout));
2012
2277
  return builder;
2013
2278
  }
2014
2279
  /**
@@ -2051,14 +2316,14 @@ class TinyHelix {
2051
2316
  * Create a TextureBuilder for creating a Texture.
2052
2317
  */
2053
2318
  createTexture() {
2054
- return new _Texture__WEBPACK_IMPORTED_MODULE_2__.TextureBuilder(this._context);
2319
+ return new _Texture__WEBPACK_IMPORTED_MODULE_2__.TextureBuilder(this._context, this._mipShader);
2055
2320
  }
2056
2321
  /**
2057
2322
  * Creates a command encoder for recording GPU commands for the current frame.
2058
2323
  * @param label - Optional debug label to assign to the encoder
2059
2324
  */
2060
2325
  createCommandEncoder(label) {
2061
- return new _CommandEncoder__WEBPACK_IMPORTED_MODULE_1__.CommandEncoder(this.backbufferTarget, this._globalBindBuffers, this._context, this._depthStencilTarget, label);
2326
+ return new _CommandEncoder__WEBPACK_IMPORTED_MODULE_1__.CommandEncoder(this.backbufferTarget, this._globalBindGroups, this._context, this._depthStencilTarget, label);
2062
2327
  }
2063
2328
  /**
2064
2329
  * Create a UniformBufferLayoutBuilder for creating a UniformBufferLayout.
@@ -2086,8 +2351,8 @@ class TinyHelix {
2086
2351
  * @param buffer - The bind group to set.
2087
2352
  */
2088
2353
  setGlobalBindGroup(index, layout, buffer) {
2089
- this._globalBindBufferLayouts[index] = layout;
2090
- this._globalBindBuffers[index] = buffer;
2354
+ this._globalBindGroupLayouts[index] = layout;
2355
+ this._globalBindGroups[index] = buffer;
2091
2356
  return this;
2092
2357
  }
2093
2358
  /**
@@ -2145,6 +2410,8 @@ class WebGPUContext {
2145
2410
  this._format = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb;
2146
2411
  this._canvas = null;
2147
2412
  this._colorSpace = _enums__WEBPACK_IMPORTED_MODULE_0__.ColorSpace.sRGB;
2413
+ this._shaderF16Supported = false;
2414
+ this._floatFilteringSupported = false;
2148
2415
  }
2149
2416
  /**
2150
2417
  * Gets the WebGPU adapter. Throws if not initialized.
@@ -2204,6 +2471,26 @@ class WebGPUContext {
2204
2471
  if (!this._adapter) {
2205
2472
  throw new Error('Failed to get WebGPU adapter');
2206
2473
  }
2474
+ // By default, shader-f16 is enabled whenever available, while TinyHelix provides f32 fallback if it doesn't.
2475
+ // The user can ask for explicit support through the features. At this point, it will NOT provide a fallback
2476
+ // and fail to create the context.
2477
+ this._shaderF16Supported = this._adapter.features.has("shader-f16");
2478
+ this._floatFilteringSupported = this._adapter.features.has("float32-filterable");
2479
+ const requiresF16 = options.requiredFeatures?.includes("shader-f16");
2480
+ if (!this._shaderF16Supported) {
2481
+ if (requiresF16)
2482
+ throw new Error("shader-f16 feature requested but not available");
2483
+ else
2484
+ console.warn("WebGPU adapter does not support shader-f16 feature. Performance may be suboptimal for certain workloads.");
2485
+ }
2486
+ else if (!requiresF16) {
2487
+ options.requiredFeatures = options.requiredFeatures ?? [];
2488
+ options.requiredFeatures?.push("shader-f16");
2489
+ }
2490
+ if (this._floatFilteringSupported && !options.requiredFeatures?.includes("float32-filterable")) {
2491
+ options.requiredFeatures = options.requiredFeatures ?? [];
2492
+ options.requiredFeatures?.push("float32-filterable");
2493
+ }
2207
2494
  // Request device
2208
2495
  this._device = await this._adapter.requestDevice({
2209
2496
  requiredFeatures: options.requiredFeatures,
@@ -2214,11 +2501,11 @@ class WebGPUContext {
2214
2501
  }
2215
2502
  // Setup error handling
2216
2503
  this._device.lost.then((info) => {
2217
- console.error('WebGPU device lost:', info.message);
2218
- if (info.reason !== 'destroyed') {
2504
+ console.error("WebGPU device lost:", info.message, "\nReason:", info.reason);
2505
+ if (info.reason !== "destroyed") {
2219
2506
  // Attempt to reinitialize
2220
2507
  this.initialize(options).catch((error) => {
2221
- console.error('Failed to reinitialize WebGPU context:', error);
2508
+ console.error("Failed to reinitialize WebGPU context:", error);
2222
2509
  });
2223
2510
  }
2224
2511
  });
@@ -2247,6 +2534,19 @@ class WebGPUContext {
2247
2534
  console.warn("No canvas provided!");
2248
2535
  }
2249
2536
  }
2537
+ /**
2538
+ * Indicates whether the shaders support the f16 format. Use the type `half`, `vec2h`, `vec3h`, `vec4h`, etc. to
2539
+ * provide f32 fallbacks if f16 is not supported.
2540
+ */
2541
+ get shaderF16Supported() {
2542
+ return this._shaderF16Supported;
2543
+ }
2544
+ /**
2545
+ * Indicates whether the device supports filtering on float32 textures.
2546
+ */
2547
+ get floatFilteringSupported() {
2548
+ return this._floatFilteringSupported;
2549
+ }
2250
2550
  /**
2251
2551
  * Internal helper to fetch the current swapchain texture.
2252
2552
  * @internal
@@ -2327,6 +2627,7 @@ class BufferBuilder {
2327
2627
  this._size = 0;
2328
2628
  this._keepData = false;
2329
2629
  this._usage = 0;
2630
+ this._dataOffset = 0;
2330
2631
  this._ctx = ctx;
2331
2632
  }
2332
2633
  /**
@@ -2341,11 +2642,12 @@ class BufferBuilder {
2341
2642
  * ArrayBuffer is stored in the resulting `Buffer.data` field for readback or
2342
2643
  * reuse.
2343
2644
  */
2344
- withData(data, keepOnCPU = false) {
2645
+ withData(data, keepOnCPU = false, offset = 0, length = data.byteLength) {
2345
2646
  this._data = data;
2346
2647
  // round to the nearest multiple of 4 bytes, as required by GPUBuffer.writeBuffer()
2347
- this._size = data.byteLength;
2648
+ this._size = length ?? (data.byteLength - offset);
2348
2649
  this._keepData = keepOnCPU;
2650
+ this._dataOffset = offset;
2349
2651
  this._usage |= BufferUsage.CopyDst;
2350
2652
  return this;
2351
2653
  }
@@ -2360,9 +2662,13 @@ class BufferBuilder {
2360
2662
  * Create the GPU buffer and upload any provided data.
2361
2663
  */
2362
2664
  build() {
2363
- const data = (0,_utils_mapUndefined__WEBPACK_IMPORTED_MODULE_0__.mapUndefined)(this._data, data => (0,_utils_padArrayBuffer__WEBPACK_IMPORTED_MODULE_1__.padArrayBuffer)(data, 4));
2665
+ const data = (0,_utils_mapUndefined__WEBPACK_IMPORTED_MODULE_0__.mapUndefined)(this._data, data => (0,_utils_padArrayBuffer__WEBPACK_IMPORTED_MODULE_1__.padArrayBuffer)(data, 4, this._dataOffset, this._size));
2666
+ if (this._keepData && data) {
2667
+ this._data = data;
2668
+ }
2669
+ this._size = data?.byteLength ?? this._size;
2364
2670
  const buffer = this._ctx.device.createBuffer({
2365
- size: data ? data.byteLength : this._size, // in case we don't have data, we need to specify the size explicitly'
2671
+ size: this._size,
2366
2672
  usage: this._usage
2367
2673
  });
2368
2674
  if (data) {
@@ -2650,6 +2956,8 @@ function sizeForBaseType(type) {
2650
2956
  case BaseType.Float16:
2651
2957
  return 2;
2652
2958
  case BaseType.Float32:
2959
+ case BaseType.Uint:
2960
+ case BaseType.Sint:
2653
2961
  return 4;
2654
2962
  case BaseType.Boolean:
2655
2963
  return 1;
@@ -2832,6 +3140,9 @@ class UniformBuffer {
2832
3140
  */
2833
3141
  setVec(name, values) {
2834
3142
  const [member, target] = this._dataViews.get(name);
3143
+ for (let i = 0; i < target.length; ++i) {
3144
+ target[i] = 0;
3145
+ }
2835
3146
  if (member.type.baseType == BaseType.Float16) {
2836
3147
  for (let i = 0; i < values.length; ++i) {
2837
3148
  target[i] = (0,_utils_float32ToFloat16__WEBPACK_IMPORTED_MODULE_1__.float32ToFloat16)(values[i]);
@@ -2854,6 +3165,9 @@ class UniformBuffer {
2854
3165
  const numCols = member.type.numCols;
2855
3166
  const numRows = member.type.numRows;
2856
3167
  const skipW = numRows === 3;
3168
+ for (let i = 0; i < target.length; ++i) {
3169
+ target[i] = 0;
3170
+ }
2857
3171
  // I know looping inside the cases looks ugly and the loops are tiny, but I just can't bring myself to put
2858
3172
  // a switch in a loop
2859
3173
  let i = 0;
@@ -2908,12 +3222,19 @@ __webpack_require__.r(__webpack_exports__);
2908
3222
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2909
3223
  /* harmony export */ AddressMode: () => (/* binding */ AddressMode),
2910
3224
  /* harmony export */ BlendFactor: () => (/* binding */ BlendFactor),
3225
+ /* harmony export */ ColorChannel: () => (/* binding */ ColorChannel),
2911
3226
  /* harmony export */ ColorSpace: () => (/* binding */ ColorSpace),
2912
3227
  /* harmony export */ CompareFunction: () => (/* binding */ CompareFunction),
2913
3228
  /* harmony export */ CullMode: () => (/* binding */ CullMode),
2914
3229
  /* harmony export */ FilterMode: () => (/* binding */ FilterMode),
3230
+ /* harmony export */ SamplerType: () => (/* binding */ SamplerType),
3231
+ /* harmony export */ ShaderStage: () => (/* binding */ ShaderStage),
2915
3232
  /* harmony export */ StorageAccess: () => (/* binding */ StorageAccess),
2916
- /* harmony export */ TextureFormat: () => (/* binding */ TextureFormat)
3233
+ /* harmony export */ StoreOp: () => (/* binding */ StoreOp),
3234
+ /* harmony export */ TextureDimension: () => (/* binding */ TextureDimension),
3235
+ /* harmony export */ TextureFormat: () => (/* binding */ TextureFormat),
3236
+ /* harmony export */ TextureSampleType: () => (/* binding */ TextureSampleType),
3237
+ /* harmony export */ TextureViewDimension: () => (/* binding */ TextureViewDimension)
2917
3238
  /* harmony export */ });
2918
3239
  var ColorSpace;
2919
3240
  (function (ColorSpace) {
@@ -3081,6 +3402,176 @@ var StorageAccess;
3081
3402
  StorageAccess["Read"] = "read-only";
3082
3403
  StorageAccess["Write"] = "write-only";
3083
3404
  })(StorageAccess || (StorageAccess = {}));
3405
+ var TextureSampleType;
3406
+ (function (TextureSampleType) {
3407
+ TextureSampleType["Float"] = "float";
3408
+ TextureSampleType["Sint"] = "sint";
3409
+ TextureSampleType["Uint"] = "uint";
3410
+ TextureSampleType["UnfilterableFloat"] = "unfilterable-float";
3411
+ TextureSampleType["Depth"] = "depth";
3412
+ })(TextureSampleType || (TextureSampleType = {}));
3413
+ var SamplerType;
3414
+ (function (SamplerType) {
3415
+ SamplerType["Filtering"] = "filtering";
3416
+ SamplerType["NonFiltering"] = "non-filtering";
3417
+ SamplerType["Comparison"] = "comparison";
3418
+ })(SamplerType || (SamplerType = {}));
3419
+ var ColorChannel;
3420
+ (function (ColorChannel) {
3421
+ ColorChannel[ColorChannel["Red"] = GPUColorWrite.RED] = "Red";
3422
+ ColorChannel[ColorChannel["Green"] = GPUColorWrite.GREEN] = "Green";
3423
+ ColorChannel[ColorChannel["Blue"] = GPUColorWrite.BLUE] = "Blue";
3424
+ })(ColorChannel || (ColorChannel = {}));
3425
+ var TextureDimension;
3426
+ (function (TextureDimension) {
3427
+ TextureDimension["D1"] = "1d";
3428
+ TextureDimension["D2"] = "2d";
3429
+ TextureDimension["D3"] = "3d";
3430
+ })(TextureDimension || (TextureDimension = {}));
3431
+ var TextureViewDimension;
3432
+ (function (TextureViewDimension) {
3433
+ TextureViewDimension["D1"] = "1d";
3434
+ TextureViewDimension["D2"] = "2d";
3435
+ TextureViewDimension["D2Array"] = "2d-array";
3436
+ TextureViewDimension["Cube"] = "cube";
3437
+ TextureViewDimension["CubeArray"] = "cube-array";
3438
+ TextureViewDimension["D3"] = "3d";
3439
+ })(TextureViewDimension || (TextureViewDimension = {}));
3440
+ var ShaderStage;
3441
+ (function (ShaderStage) {
3442
+ ShaderStage[ShaderStage["Vertex"] = GPUShaderStage.VERTEX] = "Vertex";
3443
+ ShaderStage[ShaderStage["Fragment"] = GPUShaderStage.FRAGMENT] = "Fragment";
3444
+ ShaderStage[ShaderStage["Compute"] = GPUShaderStage.COMPUTE] = "Compute";
3445
+ })(ShaderStage || (ShaderStage = {}));
3446
+ var StoreOp;
3447
+ (function (StoreOp) {
3448
+ StoreOp["Store"] = "store";
3449
+ StoreOp["Discard"] = "discard";
3450
+ })(StoreOp || (StoreOp = {}));
3451
+
3452
+
3453
+ /***/ }),
3454
+
3455
+ /***/ "./src/utils/MipRenderer.ts":
3456
+ /*!**********************************!*\
3457
+ !*** ./src/utils/MipRenderer.ts ***!
3458
+ \**********************************/
3459
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3460
+
3461
+ __webpack_require__.r(__webpack_exports__);
3462
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3463
+ /* harmony export */ MipRenderer: () => (/* binding */ MipRenderer)
3464
+ /* harmony export */ });
3465
+ /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums */ "./src/enums.ts");
3466
+ /* harmony import */ var _buffers_Buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../buffers/Buffer */ "./src/buffers/Buffer.ts");
3467
+
3468
+
3469
+ class MipRenderer {
3470
+ constructor(ctx, shader, texture) {
3471
+ this._bindgroups = [];
3472
+ this._views = [];
3473
+ this._passDescs = [];
3474
+ this._ctx = ctx;
3475
+ const sampler = ctx.device.createSampler({
3476
+ label: "MipRenderer Bilinear Sampler",
3477
+ magFilter: _enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Linear,
3478
+ minFilter: _enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Linear,
3479
+ mipmapFilter: _enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Nearest
3480
+ });
3481
+ this._bindgroupLayout = ctx.device.createBindGroupLayout({
3482
+ label: "MipRenderer BindGroup Layout",
3483
+ entries: [
3484
+ {
3485
+ binding: 0,
3486
+ visibility: GPUShaderStage.FRAGMENT,
3487
+ texture: {
3488
+ sampleType: "float",
3489
+ viewDimension: texture.dimension(),
3490
+ multisampled: false
3491
+ }
3492
+ },
3493
+ {
3494
+ binding: 1,
3495
+ visibility: GPUShaderStage.FRAGMENT,
3496
+ sampler: {
3497
+ type: "filtering"
3498
+ }
3499
+ }
3500
+ ]
3501
+ });
3502
+ this._pipeline = ctx.device.createRenderPipeline({
3503
+ label: "MipRenderer Pipeline",
3504
+ layout: ctx.device.createPipelineLayout({
3505
+ label: "MipRenderer Pipeline Layout",
3506
+ bindGroupLayouts: [this._bindgroupLayout]
3507
+ }),
3508
+ vertex: {
3509
+ module: shader,
3510
+ entryPoint: "vs_main"
3511
+ },
3512
+ fragment: {
3513
+ module: shader,
3514
+ entryPoint: "fs_main",
3515
+ targets: [
3516
+ {
3517
+ format: texture.format
3518
+ }
3519
+ ]
3520
+ },
3521
+ primitive: {
3522
+ topology: "triangle-list",
3523
+ stripIndexFormat: undefined,
3524
+ frontFace: "ccw",
3525
+ cullMode: "none"
3526
+ }
3527
+ });
3528
+ for (let level = 0; level < texture.mipLevelCount; ++level) {
3529
+ this._views.push(texture.createView()
3530
+ .withSingleMip(level)
3531
+ .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_1__.TextureUsage.RenderAttachment)
3532
+ .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_1__.TextureUsage.TextureBinding)
3533
+ .build()._inner);
3534
+ if (level === 0)
3535
+ continue;
3536
+ this._bindgroups.push(ctx.device.createBindGroup({
3537
+ label: `MipRenderer BindGroup Mip ${level}`,
3538
+ layout: this._bindgroupLayout,
3539
+ entries: [
3540
+ {
3541
+ binding: 0,
3542
+ resource: this._views[level - 1]
3543
+ },
3544
+ {
3545
+ binding: 1,
3546
+ resource: sampler
3547
+ }
3548
+ ]
3549
+ }));
3550
+ this._passDescs.push({
3551
+ label: `MipRenderer Render Pass mip ${level}`,
3552
+ colorAttachments: [{
3553
+ view: this._views[level],
3554
+ loadOp: 'clear',
3555
+ storeOp: 'store',
3556
+ clearValue: { r: 0, g: 0, b: 0, a: 0 }
3557
+ }]
3558
+ });
3559
+ }
3560
+ }
3561
+ render() {
3562
+ const encoder = this._ctx.device.createCommandEncoder({
3563
+ label: "MipRenderer Command Encoder"
3564
+ });
3565
+ this._passDescs.forEach((desc, level) => {
3566
+ const pass = encoder.beginRenderPass(desc);
3567
+ pass.setPipeline(this._pipeline);
3568
+ pass.setBindGroup(0, this._bindgroups[level]);
3569
+ pass.draw(3, 1, 0, 0);
3570
+ pass.end();
3571
+ });
3572
+ this._ctx.device.queue.submit([encoder.finish()]);
3573
+ }
3574
+ }
3084
3575
 
3085
3576
 
3086
3577
  /***/ }),
@@ -3166,20 +3657,33 @@ __webpack_require__.r(__webpack_exports__);
3166
3657
  *
3167
3658
  * @param input - The input ArrayBuffer or SharedArrayBuffer to pad
3168
3659
  * @param alignment - Desired byte alignment (e.g. 4 for 32-bit alignment)
3660
+ * @param offset - The offset in bytes from the start of the input buffer to begin copying from
3661
+ * @param size - The number of bytes to copy from the input buffer
3169
3662
  * @returns A buffer with byteLength rounded up to the nearest multiple of alignment
3170
3663
  */
3171
- function padArrayBuffer(input, alignment) {
3172
- const targetSize = Math.ceil(input.byteLength / alignment) * alignment;
3173
- if (targetSize === input.byteLength)
3664
+ function padArrayBuffer(input, alignment, offset, size) {
3665
+ const targetSize = Math.ceil(size / alignment) * alignment;
3666
+ const needsSlice = offset !== 0 || size !== input.byteLength;
3667
+ if (!needsSlice && targetSize === size)
3174
3668
  return input;
3175
3669
  const data = input instanceof ArrayBuffer ? new ArrayBuffer(targetSize) : new SharedArrayBuffer(targetSize);
3176
- const src = new Uint8Array(input);
3670
+ const src = new Uint8Array(input, offset, size);
3177
3671
  const dst = new Uint8Array(data);
3178
3672
  dst.set(src);
3179
3673
  return data;
3180
3674
  }
3181
3675
 
3182
3676
 
3677
+ /***/ }),
3678
+
3679
+ /***/ "./src/wgsl/mip_2d_2x2.wgsl":
3680
+ /*!**********************************!*\
3681
+ !*** ./src/wgsl/mip_2d_2x2.wgsl ***!
3682
+ \**********************************/
3683
+ /***/ ((module) => {
3684
+
3685
+ module.exports = "@group(0) @binding(0) var source_tex: texture_2d<f32>;\n@group(0) @binding(1) var bilinear_sampler: sampler;\n\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n}\n\n@vertex\nfn vs_main(@builtin(vertex_index) i: u32) -> VertexOutput {\n var output: VertexOutput;\n\n // Full-screen triangle\n let x = f32((i << 1u) & 2u);\n let y = f32(i & 2u);\n\n output.position = vec4f(x * 2.0 - 1.0, 1.0 - y * 2.0, 0.0, 1.0);\n output.uv = vec2f(x, y);\n\n return output;\n}\n\n@fragment\nfn fs_main(input: VertexOutput) -> @location(0) vec4f {\n return textureSample(source_tex, bilinear_sampler, input.uv);\n}\n\n";
3686
+
3183
3687
  /***/ })
3184
3688
 
3185
3689
  /******/ });
@@ -3257,6 +3761,7 @@ __webpack_require__.r(__webpack_exports__);
3257
3761
  /* harmony export */ BufferBuilder: () => (/* reexport safe */ _buffers_Buffer__WEBPACK_IMPORTED_MODULE_15__.BufferBuilder),
3258
3762
  /* harmony export */ BufferDataWriter: () => (/* reexport safe */ _buffers_BufferDataWriter__WEBPACK_IMPORTED_MODULE_17__.BufferDataWriter),
3259
3763
  /* harmony export */ BufferUsage: () => (/* reexport safe */ _buffers_Buffer__WEBPACK_IMPORTED_MODULE_15__.BufferUsage),
3764
+ /* harmony export */ ColorChannel: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.ColorChannel),
3260
3765
  /* harmony export */ ColorSpace: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.ColorSpace),
3261
3766
  /* harmony export */ CommandEncoder: () => (/* reexport safe */ _CommandEncoder__WEBPACK_IMPORTED_MODULE_4__.CommandEncoder),
3262
3767
  /* harmony export */ CompareFunction: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.CompareFunction),
@@ -3279,16 +3784,23 @@ __webpack_require__.r(__webpack_exports__);
3279
3784
  /* harmony export */ RenderTargetBuilder: () => (/* reexport safe */ _RenderTarget__WEBPACK_IMPORTED_MODULE_11__.RenderTargetBuilder),
3280
3785
  /* harmony export */ Sampler: () => (/* reexport safe */ _Sampler__WEBPACK_IMPORTED_MODULE_12__.Sampler),
3281
3786
  /* harmony export */ SamplerBuilder: () => (/* reexport safe */ _Sampler__WEBPACK_IMPORTED_MODULE_12__.SamplerBuilder),
3787
+ /* harmony export */ SamplerType: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.SamplerType),
3282
3788
  /* harmony export */ Shader: () => (/* reexport safe */ _Shader__WEBPACK_IMPORTED_MODULE_13__.Shader),
3283
3789
  /* harmony export */ ShaderBuilder: () => (/* reexport safe */ _Shader__WEBPACK_IMPORTED_MODULE_13__.ShaderBuilder),
3790
+ /* harmony export */ ShaderStage: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.ShaderStage),
3284
3791
  /* harmony export */ StorageAccess: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.StorageAccess),
3792
+ /* harmony export */ StoreOp: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.StoreOp),
3285
3793
  /* harmony export */ StreamBuilder: () => (/* reexport safe */ _Mesh__WEBPACK_IMPORTED_MODULE_8__.StreamBuilder),
3286
3794
  /* harmony export */ Texture: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.Texture),
3287
3795
  /* harmony export */ TextureBuilder: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureBuilder),
3796
+ /* harmony export */ TextureDimension: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureDimension),
3288
3797
  /* harmony export */ TextureFormat: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureFormat),
3798
+ /* harmony export */ TextureSampleType: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureSampleType),
3289
3799
  /* harmony export */ TextureUsage: () => (/* reexport safe */ _buffers_Buffer__WEBPACK_IMPORTED_MODULE_15__.TextureUsage),
3800
+ /* harmony export */ TextureUtils: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureUtils),
3290
3801
  /* harmony export */ TextureView: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureView),
3291
3802
  /* harmony export */ TextureViewBuilder: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureViewBuilder),
3803
+ /* harmony export */ TextureViewDimension: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureViewDimension),
3292
3804
  /* harmony export */ TinyHelix: () => (/* reexport safe */ _TinyHelix__WEBPACK_IMPORTED_MODULE_0__.TinyHelix),
3293
3805
  /* harmony export */ UniformBuffer: () => (/* reexport safe */ _buffers_UniformBuffer__WEBPACK_IMPORTED_MODULE_16__.UniformBuffer),
3294
3806
  /* harmony export */ UniformBufferLayout: () => (/* reexport safe */ _buffers_UniformBuffer__WEBPACK_IMPORTED_MODULE_16__.UniformBufferLayout),