@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.
@@ -68,7 +68,7 @@ class BindGroupBuilder {
68
68
  withTexture(fieldName, texture) {
69
69
  const index = this._layout._getBindingIndex(fieldName);
70
70
  this._entries[index] = {
71
- binding: index, resource: texture._inner
71
+ binding: index, resource: texture._inner,
72
72
  };
73
73
  return this;
74
74
  }
@@ -151,7 +151,7 @@ class BindGroupLayoutBuilder {
151
151
  withUniformBuffer(index, field_name, layout, visibility) {
152
152
  this._entries[index] = {
153
153
  binding: index,
154
- visibility: visibility ?? GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
154
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Vertex | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
155
155
  buffer: { type: 'uniform' }
156
156
  };
157
157
  this._indices.set(field_name, index);
@@ -161,57 +161,65 @@ class BindGroupLayoutBuilder {
161
161
  /**
162
162
  * Add a storage buffer binding at the given index and record its layout.
163
163
  * @param index - binding index
164
- * @param field_name - a name used to reference the layout later
165
- * @param access_mode - Defines whether the storage buffer is read-only or not.
164
+ * @param fieldName - a name used to reference the layout later
165
+ * @param accessMode - Defines whether the storage buffer is read-only or not.
166
166
  * @param visibility - shader stage visibility flags (defaults to FRAGMENT|COMPUTE)
167
167
  */
168
- withStorageBuffer(index, field_name, access_mode, visibility) {
168
+ withStorageBuffer(index, fieldName, accessMode, minBindingSize = 4, visibility) {
169
169
  let type = "storage";
170
- if (access_mode === _enums__WEBPACK_IMPORTED_MODULE_2__.StorageAccess.Read) {
170
+ if (accessMode === _enums__WEBPACK_IMPORTED_MODULE_2__.StorageAccess.Read) {
171
171
  type = "read-only-storage";
172
172
  }
173
173
  this._entries[index] = {
174
174
  binding: index,
175
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
176
- buffer: { type, hasDynamicOffset: false, minBindingSize: 4 }
175
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
176
+ buffer: { type, hasDynamicOffset: false, minBindingSize }
177
177
  };
178
- this._indices.set(field_name, index);
178
+ this._indices.set(fieldName, index);
179
179
  return this;
180
180
  }
181
181
  /**
182
182
  * Add a storage texture binding at the given index. The texture will be
183
183
  * write-only and use RGBA8Unorm format.
184
184
  * @param index
185
- * @param field_name
185
+ * @param fieldName
186
186
  * @param format
187
- * @param access_mode
187
+ * @param accessMode
188
188
  * @param visibility
189
+ * @param viewDimension
189
190
  */
190
- withStorageTexture(index, field_name, format, access_mode, visibility) {
191
+ withStorageTexture(index, fieldName, format, accessMode, visibility, viewDimension) {
191
192
  this._entries[index] = {
192
193
  binding: index,
193
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
194
- storageTexture: { access: access_mode, format }
194
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
195
+ storageTexture: {
196
+ access: accessMode,
197
+ format,
198
+ viewDimension: viewDimension ?? "2d"
199
+ }
195
200
  };
196
- this._indices.set(field_name, index);
201
+ this._indices.set(fieldName, index);
197
202
  return this;
198
203
  }
199
- withTexture(index, field_name, visibility) {
204
+ withTexture(index, fieldName, visibility, viewDimension, sampleType = _enums__WEBPACK_IMPORTED_MODULE_2__.TextureSampleType.Float) {
200
205
  this._entries[index] = {
201
206
  binding: index,
202
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
203
- texture: { sampleType: 'float' }
207
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
208
+ texture: {
209
+ sampleType,
210
+ viewDimension: viewDimension ?? "2d"
211
+ }
204
212
  };
205
- this._indices.set(field_name, index);
213
+ this._indices.set(fieldName, index);
206
214
  return this;
207
215
  }
208
- withSampler(index, field_name, visibility) {
216
+ withSampler(index, fieldName, samplerType = _enums__WEBPACK_IMPORTED_MODULE_2__.SamplerType.Filtering, visibility) {
209
217
  this._entries[index] = {
210
218
  binding: index,
211
- visibility: visibility ?? GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
212
- sampler: { type: 'filtering' }
219
+ visibility: visibility ?? _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Fragment | _enums__WEBPACK_IMPORTED_MODULE_2__.ShaderStage.Compute,
220
+ sampler: { type: samplerType }
213
221
  };
214
- this._indices.set(field_name, index);
222
+ this._indices.set(fieldName, index);
215
223
  return this;
216
224
  }
217
225
  /**
@@ -446,12 +454,17 @@ class ComputePipeline {
446
454
  }
447
455
  class ComputePipelineBuilder {
448
456
  constructor(ctx) {
457
+ this._overrideConstants = {};
449
458
  this._ctx = ctx;
450
459
  }
451
460
  withLabel(label) {
452
461
  this._label = label;
453
462
  return this;
454
463
  }
464
+ withOverrideConstant(id, value) {
465
+ this._overrideConstants[id] = value;
466
+ return this;
467
+ }
455
468
  /** Select the shader entry point for the fragment stage. */
456
469
  withShader(shader, entry) {
457
470
  this._shader = shader;
@@ -468,7 +481,8 @@ class ComputePipelineBuilder {
468
481
  label: this._label,
469
482
  compute: {
470
483
  module: shader._inner,
471
- entryPoint: this._entry
484
+ entryPoint: this._entry,
485
+ constants: this._overrideConstants
472
486
  },
473
487
  layout
474
488
  };
@@ -514,7 +528,7 @@ class IndexBuffer {
514
528
  this.format = bytesPerElement === 2 ? IndexFormat.Uint16 : IndexFormat.Uint32;
515
529
  this.count = data.length;
516
530
  this.buffer = new _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferBuilder(ctx)
517
- .withData(data.buffer, keepData)
531
+ .withData(data.buffer, keepData, data.byteOffset, data.byteLength)
518
532
  .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.CopyDst | _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.Index)
519
533
  .build();
520
534
  }
@@ -732,9 +746,10 @@ class StreamBuilder {
732
746
  * Upload vertex data for this stream. `keepOnCPU` controls whether the
733
747
  * source ArrayBuffer is retained in memory for readback.
734
748
  */
735
- withData(data, keepOnCPU = false) {
749
+ withData(data, byteOffset = 0, byteLength, keepOnCPU = false) {
750
+ byteLength = byteLength ?? (data.byteLength - byteOffset);
736
751
  this._stream.buffer = new _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferBuilder(this._ctx)
737
- .withData(data, keepOnCPU)
752
+ .withData(data, keepOnCPU, byteOffset, byteLength)
738
753
  .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.Vertex | _buffers_Buffer__WEBPACK_IMPORTED_MODULE_0__.BufferUsage.CopyDst)
739
754
  .build();
740
755
  }
@@ -861,12 +876,26 @@ class RenderPass {
861
876
  /**
862
877
  * Issue a draw call using the currently set pipeline and mesh.
863
878
  */
864
- draw() {
879
+ draw(numInstances = 1) {
880
+ if (this._numIndices) {
881
+ this._inner.drawIndexed(this._numIndices, numInstances, 0, 0, 0);
882
+ }
883
+ else {
884
+ this._inner.draw(this._numVertices, numInstances, 0, 0);
885
+ }
886
+ return this;
887
+ }
888
+ /**
889
+ * Issue an indirect draw call using the currently set pipeline and mesh.
890
+ * @param indirectBuffer A Buffer containing the draw parameters. The buffer must have been created with the `Indirect` usage flag.
891
+ * @param indirectOffset The offset in bytes into the indirectBuffer where the draw parameters are stored. Must be a multiple of 4.
892
+ */
893
+ drawIndirect(indirectBuffer, indirectOffset = 0) {
865
894
  if (this._numIndices) {
866
- this._inner.drawIndexed(this._numIndices, 1, 0, 0, 0);
895
+ this._inner.drawIndexedIndirect(indirectBuffer._inner, indirectOffset);
867
896
  }
868
897
  else {
869
- this._inner.draw(this._numVertices, 1, 0, 0);
898
+ this._inner.drawIndirect(indirectBuffer._inner, indirectOffset);
870
899
  }
871
900
  return this;
872
901
  }
@@ -893,6 +922,7 @@ class RenderPassBuilder {
893
922
  constructor(commandEncoder, globalBindGroups, defaultTarget, defaultDepthTarget) {
894
923
  this._colorTargets = [];
895
924
  this._clearColors = [];
925
+ this._storeOps = [];
896
926
  this._encoder = commandEncoder;
897
927
  this._defaultTarget = defaultTarget;
898
928
  this._defaultDepthTarget = defaultDepthTarget;
@@ -937,6 +967,19 @@ class RenderPassBuilder {
937
967
  }
938
968
  return this;
939
969
  }
970
+ /**
971
+ * Set the store operation for the most recently added color target. Defaults to 'store' if not specified.
972
+ * @param storeOp
973
+ */
974
+ withStoreOp(storeOp) {
975
+ if (this._colorTargets.length === 0) {
976
+ this._storeOps[0] = storeOp;
977
+ }
978
+ else {
979
+ this._storeOps[this._colorTargets.length - 1] = storeOp;
980
+ }
981
+ return this;
982
+ }
940
983
  /**
941
984
  * Set the clear stencil value
942
985
  */
@@ -978,7 +1021,7 @@ class RenderPassBuilder {
978
1021
  const colorAttachments = targets.map((target, i) => ({
979
1022
  view: target._inner,
980
1023
  loadOp: this._clearColors[i] ? 'clear' : 'load',
981
- storeOp: 'store',
1024
+ storeOp: this._storeOps[i] ?? 'store',
982
1025
  clearValue: this._clearColors[i]
983
1026
  }));
984
1027
  const desc = {
@@ -1122,6 +1165,24 @@ class RenderPipelineBuilder {
1122
1165
  }
1123
1166
  return this;
1124
1167
  }
1168
+ /**
1169
+ * Sets the depth bias for each triangle.
1170
+ * @param depthBias Constant depth bias added to each triangle fragment.
1171
+ * @param slopeScale Depth bias that scales with the triangle fragment’s slope.
1172
+ * @param max The maximum depth bias of a triangle fragment.
1173
+ */
1174
+ withDepthBias(depthBias, slopeScale, max) {
1175
+ const target = this._depthState ?? this._defaultDepthState;
1176
+ if (!target) {
1177
+ console.warn("No depth target set. Setting depth compare function has no effect.");
1178
+ }
1179
+ else {
1180
+ target.depthBias = depthBias;
1181
+ target.depthBiasSlopeScale = slopeScale;
1182
+ target.depthBiasClamp = max;
1183
+ }
1184
+ return this;
1185
+ }
1125
1186
  /**
1126
1187
  * Enable or disable depth writes. Default is `true`.
1127
1188
  * @param enabled
@@ -1136,9 +1197,19 @@ class RenderPipelineBuilder {
1136
1197
  }
1137
1198
  return this;
1138
1199
  }
1139
- /** Override a shader constant for specialization. */
1140
- withOverrideConstant(id, value) {
1141
- this._overrideConstants[id] = value;
1200
+ /**
1201
+ * Override a shader constant for specialization. We do NOT use `ShaderStage.Vertex | ShaderStage.Fragment` as
1202
+ * default because some browser implementations (as of early 2026) have bugs when a non-existent constant is defined
1203
+ */
1204
+ withOverrideConstant(id, value, pipeline) {
1205
+ if (pipeline & GPUShaderStage.VERTEX) {
1206
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex] = this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex] || {};
1207
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex][id] = value;
1208
+ }
1209
+ if (pipeline & GPUShaderStage.FRAGMENT) {
1210
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment] = this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment] || {};
1211
+ this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment][id] = value;
1212
+ }
1142
1213
  return this;
1143
1214
  }
1144
1215
  /** Set the blend mode for the last assigned (or default) color target. */
@@ -1146,6 +1217,18 @@ class RenderPipelineBuilder {
1146
1217
  this.lastColorTarget.blend = blendMode._inner;
1147
1218
  return this;
1148
1219
  }
1220
+ /** Set the color write mask for the last assigned (or default) color target. */
1221
+ withColorWrite(r, g, b, a) {
1222
+ g ?? (g = r);
1223
+ b ?? (b = g);
1224
+ a ?? (a = b);
1225
+ this.lastColorTarget.writeMask =
1226
+ (r ? GPUColorWrite.RED : 0) |
1227
+ (g ? GPUColorWrite.GREEN : 0) |
1228
+ (b ? GPUColorWrite.BLUE : 0) |
1229
+ (a ? GPUColorWrite.ALPHA : 0);
1230
+ return this;
1231
+ }
1149
1232
  /**
1150
1233
  * Build and create the `RenderPipeline`. Throws if required pieces (shader/vertices)
1151
1234
  * are missing.
@@ -1205,13 +1288,13 @@ class RenderPipelineBuilder {
1205
1288
  buffers,
1206
1289
  module: shader._inner,
1207
1290
  entryPoint: this._vertexEntry,
1208
- constants: this._overrideConstants
1291
+ constants: this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Vertex]
1209
1292
  },
1210
1293
  fragment: (0,_utils_mapUndefined__WEBPACK_IMPORTED_MODULE_0__.mapUndefined)(this._fragmentEntry, entry => ({
1211
1294
  module: shader._inner,
1212
1295
  entryPoint: entry,
1213
1296
  targets: colorTargets,
1214
- constants: this._overrideConstants
1297
+ constants: this._overrideConstants[_enums__WEBPACK_IMPORTED_MODULE_1__.ShaderStage.Fragment]
1215
1298
  }))
1216
1299
  };
1217
1300
  const inner = this._ctx.device.createRenderPipeline(desc);
@@ -1287,16 +1370,17 @@ class RenderTargetBuilder {
1287
1370
  */
1288
1371
  build() {
1289
1372
  const tex = this._texture._inner;
1290
- const desc = {
1373
+ const view = this._texture._inner.createView({
1291
1374
  format: tex.format,
1292
1375
  dimension: tex.dimension,
1293
1376
  aspect: 'all',
1294
1377
  baseMipLevel: this._baseMipLevel,
1295
1378
  mipLevelCount: 1,
1296
1379
  baseArrayLayer: this._baseArrayLayer,
1297
- arrayLayerCount: 1
1298
- };
1299
- return new RenderTarget(this._texture._inner.createView(desc), this._texture.format);
1380
+ arrayLayerCount: 1,
1381
+ usage: GPUTextureUsage.RENDER_ATTACHMENT,
1382
+ });
1383
+ return new RenderTarget(view, this._texture.format);
1300
1384
  }
1301
1385
  }
1302
1386
 
@@ -1323,18 +1407,23 @@ class Sampler {
1323
1407
  }
1324
1408
  class SamplerBuilder {
1325
1409
  constructor(ctx) {
1410
+ this._desc = {};
1326
1411
  this._ctx = ctx;
1327
1412
  }
1413
+ withLabel(label) {
1414
+ this._desc.label = label;
1415
+ return this;
1416
+ }
1328
1417
  withAddressMode(u, v, w) {
1329
- this._addressModeU = u;
1330
- this._addressModeV = v ?? u;
1331
- this._addressModeW = w ?? u;
1418
+ this._desc.addressModeU = u;
1419
+ this._desc.addressModeV = v ?? u;
1420
+ this._desc.addressModeW = w ?? u;
1332
1421
  return this;
1333
1422
  }
1334
1423
  withFiltering(minFilter, magFilter, mipmapFilter) {
1335
- this._minFilter = minFilter;
1336
- this._magFilter = magFilter ?? minFilter;
1337
- this._mipmapFilter = mipmapFilter ?? minFilter;
1424
+ this._desc.minFilter = minFilter;
1425
+ this._desc.magFilter = magFilter ?? minFilter;
1426
+ this._desc.mipmapFilter = mipmapFilter ?? minFilter;
1338
1427
  return this;
1339
1428
  }
1340
1429
  withTrilinearFiltering() {
@@ -1347,34 +1436,23 @@ class SamplerBuilder {
1347
1436
  }
1348
1437
  withAnisotropicFiltering(maxAnisotropy) {
1349
1438
  this.withFiltering(_enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Linear);
1350
- this._maxAnisotropy = maxAnisotropy;
1439
+ this._desc.maxAnisotropy = maxAnisotropy;
1351
1440
  return this;
1352
1441
  }
1353
1442
  withMinMipLevel(level) {
1354
- this._minMipLevel = level;
1443
+ this._desc.lodMinClamp = level;
1355
1444
  return this;
1356
1445
  }
1357
1446
  withMaxMipLevel(level) {
1358
- this._maxMipLevel = level;
1447
+ this._desc.lodMaxClamp = level;
1359
1448
  return this;
1360
1449
  }
1361
1450
  withCompareFunction(compare) {
1362
- this._compare = compare;
1451
+ this._desc.compare = compare;
1363
1452
  return this;
1364
1453
  }
1365
1454
  build() {
1366
- return new Sampler(this._ctx.device.createSampler({
1367
- addressModeU: this._addressModeU,
1368
- addressModeV: this._addressModeV,
1369
- addressModeW: this._addressModeW,
1370
- magFilter: this._magFilter,
1371
- minFilter: this._minFilter,
1372
- mipmapFilter: this._mipmapFilter,
1373
- lodMinClamp: this._minMipLevel,
1374
- lodMaxClamp: this._maxMipLevel,
1375
- compare: this._compare,
1376
- maxAnisotropy: this._maxAnisotropy
1377
- }));
1455
+ return new Sampler(this._ctx.device.createSampler(this._desc));
1378
1456
  }
1379
1457
  }
1380
1458
 
@@ -1408,6 +1486,9 @@ class Shader {
1408
1486
  this._vertexAttributes = vertexAttributes;
1409
1487
  this._bindGroupLayouts = bindGroupLayouts;
1410
1488
  }
1489
+ getCompilationInfo() {
1490
+ return this._inner.getCompilationInfo();
1491
+ }
1411
1492
  /**
1412
1493
  * Get the shader location for a named vertex attribute. Returns undefined if the attribute
1413
1494
  * is not declared by the shader.
@@ -1468,7 +1549,7 @@ class ShaderBuilder {
1468
1549
  return this;
1469
1550
  }
1470
1551
  /** Declare a named vertex attribute and the location it maps to in the shader. */
1471
- withVertexAttribute(name, location) {
1552
+ withVertexAttribute(location, name) {
1472
1553
  this._vertexAttributes.set(name, location);
1473
1554
  return this;
1474
1555
  }
@@ -1490,9 +1571,21 @@ class ShaderBuilder {
1490
1571
  if (!this._code) {
1491
1572
  throw new Error("Shader code not specified. Use withCode() to set the shader source.");
1492
1573
  }
1493
- let code = this._code;
1574
+ const header = this._ctx.shaderF16Supported ?
1575
+ `enable f16;
1576
+ alias half = f16;
1577
+ alias vec2h = vec2<f16>;
1578
+ alias vec3h = vec3<f16>;
1579
+ alias vec4h = vec4<f16>;
1580
+ ` :
1581
+ `alias half = f32;
1582
+ alias vec2h = vec2<f32>;
1583
+ alias vec3h = vec3<f32>;
1584
+ alias vec4h = vec4<f32>;
1585
+ `;
1586
+ let code = header + "\n\n" + this._code;
1494
1587
  for (const [name, inc] of this._includes) {
1495
- // Create a regex to match the include directive while allowing
1588
+ // regex to match the include directive while allowing
1496
1589
  // optional whitespace between tokens, e.g.:
1497
1590
  // #include<name>
1498
1591
  // # include < name >
@@ -1522,10 +1615,15 @@ __webpack_require__.r(__webpack_exports__);
1522
1615
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1523
1616
  /* harmony export */ Texture: () => (/* binding */ Texture),
1524
1617
  /* harmony export */ TextureBuilder: () => (/* binding */ TextureBuilder),
1618
+ /* harmony export */ TextureUtils: () => (/* binding */ TextureUtils),
1525
1619
  /* harmony export */ TextureView: () => (/* binding */ TextureView),
1526
1620
  /* harmony export */ TextureViewBuilder: () => (/* binding */ TextureViewBuilder)
1527
1621
  /* harmony export */ });
1528
1622
  /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./enums */ "./src/enums.ts");
1623
+ /* harmony import */ var _utils_MipRenderer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/MipRenderer */ "./src/utils/MipRenderer.ts");
1624
+ /* harmony import */ var _utils_mapUndefined__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/mapUndefined */ "./src/utils/mapUndefined.ts");
1625
+
1626
+
1529
1627
 
1530
1628
  /**
1531
1629
  * Small wrapper around GPUTexture providing convenience constructors and
@@ -1533,15 +1631,16 @@ __webpack_require__.r(__webpack_exports__);
1533
1631
  */
1534
1632
  class Texture {
1535
1633
  /**
1536
- * Create a Texture wrapper from an existing GPUTexture.
1537
- * @param texture - The underlying GPUTexture
1634
+ * @internal
1538
1635
  */
1539
- static from_webgpu(texture, format) {
1540
- return new Texture(texture, format);
1636
+ static from_webgpu(texture, format, ctx, mipShader) {
1637
+ return new Texture(texture, format, ctx, mipShader);
1541
1638
  }
1542
- constructor(inner, format) {
1639
+ constructor(inner, format, ctx, mipShader) {
1543
1640
  this._inner = inner;
1544
1641
  this._format = format;
1642
+ this._ctx = ctx;
1643
+ this._mipper = (0,_utils_mapUndefined__WEBPACK_IMPORTED_MODULE_2__.mapUndefined)(mipShader, (mipShader) => new _utils_MipRenderer__WEBPACK_IMPORTED_MODULE_1__.MipRenderer(ctx, mipShader, this));
1545
1644
  }
1546
1645
  createView() {
1547
1646
  return new TextureViewBuilder(this);
@@ -1549,33 +1648,103 @@ class Texture {
1549
1648
  get format() {
1550
1649
  return this._format;
1551
1650
  }
1651
+ get mipLevelCount() {
1652
+ return this._inner.mipLevelCount;
1653
+ }
1654
+ get width() {
1655
+ return this._inner.width;
1656
+ }
1657
+ get height() {
1658
+ return this._inner.height;
1659
+ }
1660
+ get depthOrArrayLayers() {
1661
+ return this._inner.depthOrArrayLayers;
1662
+ }
1552
1663
  _getBufferResource() {
1553
1664
  return this._inner.createView();
1554
1665
  }
1666
+ uploadImage(data, mipLevel = 0) {
1667
+ this._ctx.device.queue.copyExternalImageToTexture({ source: data }, { texture: this._inner, mipLevel }, [data.width, data.height, 1]);
1668
+ }
1669
+ uploadData(data, mipLevel = 0) {
1670
+ const width = Math.max(this._inner.width >> mipLevel, 1);
1671
+ const height = Math.max(this._inner.height >> mipLevel, 1);
1672
+ const depthOrArrayLayers = Math.max(this._inner.depthOrArrayLayers >> mipLevel, 1);
1673
+ const blockWidth = TextureUtils.getBlockWidth(this._format);
1674
+ const blocksPerRow = Math.ceil(width / blockWidth);
1675
+ const bytesPerRow = blocksPerRow * TextureUtils.bytesPerBlock(this._format);
1676
+ this._ctx.device.queue.writeTexture({ texture: this._inner, mipLevel }, data, {
1677
+ bytesPerRow,
1678
+ rowsPerImage: height // This is what Mario is asking for!
1679
+ }, { width, height, depthOrArrayLayers });
1680
+ }
1681
+ generateMipmaps() {
1682
+ if (this._inner.dimension !== _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D2) {
1683
+ throw new Error('generateMipmaps currently only supports 2D textures.');
1684
+ }
1685
+ this._mipper.render();
1686
+ }
1687
+ dimension() {
1688
+ switch (this._inner.dimension) {
1689
+ case "1d":
1690
+ return _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D1;
1691
+ case "2d":
1692
+ return _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D2;
1693
+ case "3d":
1694
+ return _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D3;
1695
+ default:
1696
+ throw new Error(`Unknown texture dimension: ${this._inner.dimension}`);
1697
+ }
1698
+ }
1555
1699
  }
1556
1700
  class TextureBuilder {
1557
- constructor(ctx) {
1701
+ constructor(ctx, mipShader) {
1558
1702
  this._size = [1, 1, 1];
1559
- this._data = undefined;
1560
1703
  this._format = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb;
1561
1704
  this._usage = GPUTextureUsage.TEXTURE_BINDING;
1705
+ this._dimension = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D2;
1706
+ this._mipLevelCount = 1; // -1 will mean auto calculate based on size
1707
+ this._generateMips = false;
1708
+ this._mipShader = mipShader;
1562
1709
  this._ctx = ctx;
1563
1710
  }
1564
1711
  withSize(width, height, depthOrArrayLayers = 1) {
1565
1712
  this._size = [width, height, depthOrArrayLayers];
1713
+ if (depthOrArrayLayers > 1) {
1714
+ this._dimension = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureDimension.D3;
1715
+ }
1566
1716
  return this;
1567
1717
  }
1568
- withData(data) {
1569
- this._data = data;
1718
+ withDimension(dim) {
1719
+ this._dimension = dim;
1720
+ return this;
1721
+ }
1722
+ withMipLevels(count) {
1723
+ this._mipLevelCount = count ?? -1;
1570
1724
  return this;
1571
1725
  }
1572
1726
  withFormat(format) {
1573
1727
  this._format = format;
1574
1728
  return this;
1575
1729
  }
1576
- withImage(data) {
1577
- this._data = data;
1578
- this._size = [data.width, data.height, 1];
1730
+ withData(data, mipLevel = 0) {
1731
+ this._data = this._data ?? [];
1732
+ this._data[mipLevel] = data;
1733
+ this._mipLevelCount = Math.max(this._mipLevelCount, mipLevel + 1);
1734
+ return this;
1735
+ }
1736
+ withImage(data, mipLevel = 0) {
1737
+ this._data = this._data ?? [];
1738
+ this._data[mipLevel] = data;
1739
+ if (mipLevel === 0) {
1740
+ this._size = [data.width, data.height, 1];
1741
+ }
1742
+ this._mipLevelCount = Math.max(this._mipLevelCount, mipLevel + 1);
1743
+ return this;
1744
+ }
1745
+ withGeneratedMipmaps() {
1746
+ this._mipLevelCount = -1;
1747
+ this._generateMips = true;
1579
1748
  return this;
1580
1749
  }
1581
1750
  withUsage(usage) {
@@ -1586,20 +1755,38 @@ class TextureBuilder {
1586
1755
  if (this._data) {
1587
1756
  this._usage |= GPUTextureUsage.COPY_DST;
1588
1757
  }
1758
+ if (this._generateMips) {
1759
+ this._usage |= GPUTextureUsage.RENDER_ATTACHMENT;
1760
+ }
1761
+ if (this._mipLevelCount == -1) {
1762
+ const maxDimension = Math.max(this._size[0], this._size[1], this._size[2]);
1763
+ this._mipLevelCount = Math.floor(Math.log2(maxDimension)) + 1;
1764
+ }
1589
1765
  const inner = this._ctx.device.createTexture({
1590
- format: this._format, size: this._size, usage: this._usage
1766
+ format: this._format, size: this._size, usage: this._usage,
1767
+ dimension: this._dimension,
1768
+ mipLevelCount: this._mipLevelCount
1591
1769
  });
1592
- if (this._data instanceof ImageBitmap) {
1593
- this._ctx.device.queue.copyExternalImageToTexture({ source: this._data }, { texture: inner }, [this._size[0], this._size[1], 1]);
1594
- }
1595
- else if (this._data) {
1596
- const [width, height, depthOrArrayLayers] = this._size;
1597
- const blockWidth = getBlockWidth(this._format);
1598
- const blocksPerRow = Math.ceil(width / blockWidth);
1599
- const bytesPerRow = blocksPerRow * bytesPerBlock(this._format);
1600
- this._ctx.device.queue.writeTexture({ texture: inner }, this._data, { bytesPerRow }, { width, height, depthOrArrayLayers });
1770
+ const tex = new Texture(inner, this._format, this._ctx, this._generateMips ? this._mipShader : undefined);
1771
+ if (this._data) {
1772
+ const mipCount = this._generateMips ? 1 : this._mipLevelCount;
1773
+ for (let mipLevel = 0; mipLevel < mipCount; mipLevel++) {
1774
+ const data = this._data[mipLevel];
1775
+ if (!data)
1776
+ throw new Error(`TextureBuilder: Missing data for mip level ${mipLevel}`);
1777
+ if (data instanceof ImageBitmap) {
1778
+ tex.uploadImage(data, mipLevel);
1779
+ }
1780
+ else {
1781
+ tex.uploadData(data, mipLevel);
1782
+ }
1783
+ }
1784
+ if (this._generateMips) {
1785
+ // Generate mipmaps using a simple render pass approach
1786
+ tex.generateMipmaps();
1787
+ }
1601
1788
  }
1602
- return new Texture(inner, this._format);
1789
+ return tex;
1603
1790
  }
1604
1791
  }
1605
1792
  class TextureView {
@@ -1615,6 +1802,13 @@ class TextureViewBuilder {
1615
1802
  this._desc = {};
1616
1803
  this._texture = texture;
1617
1804
  }
1805
+ withUsage(usage) {
1806
+ if (this._desc.usage === undefined) {
1807
+ this._desc.usage = 0;
1808
+ }
1809
+ this._desc.usage |= usage;
1810
+ return this;
1811
+ }
1618
1812
  withSingleMip(level) {
1619
1813
  this._desc.baseMipLevel = level;
1620
1814
  this._desc.mipLevelCount = 1;
@@ -1635,212 +1829,219 @@ class TextureViewBuilder {
1635
1829
  this._desc.arrayLayerCount = end;
1636
1830
  return this;
1637
1831
  }
1832
+ withDimension(dim) {
1833
+ this._desc.dimension = dim;
1834
+ return this;
1835
+ }
1638
1836
  build() {
1639
1837
  return new TextureView(this._texture._inner.createView(this._desc));
1640
1838
  }
1641
1839
  }
1642
- function isBc(format) {
1643
- switch (format) {
1644
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1645
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1646
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1647
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
1648
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
1649
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
1650
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1651
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1652
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
1653
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
1654
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
1655
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
1656
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
1657
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
1658
- return true;
1659
- default: return false;
1840
+ class TextureUtils {
1841
+ static isBc(format) {
1842
+ switch (format) {
1843
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1844
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1845
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1846
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
1847
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
1848
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
1849
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1850
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1851
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
1852
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
1853
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
1854
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
1855
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
1856
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
1857
+ return true;
1858
+ default:
1859
+ return false;
1860
+ }
1660
1861
  }
1661
- }
1662
- function isEtc(format) {
1663
- switch (format) {
1664
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1665
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1666
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
1667
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
1668
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
1669
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
1670
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
1671
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
1672
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
1673
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
1674
- return true;
1675
- default:
1676
- return false;
1862
+ static isEtc(format) {
1863
+ switch (format) {
1864
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1865
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1866
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
1867
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
1868
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
1869
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
1870
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
1871
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
1872
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
1873
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
1874
+ return true;
1875
+ default:
1876
+ return false;
1877
+ }
1677
1878
  }
1678
- }
1679
- function getBlockWidth(format) {
1680
- if (isBc(format) || isEtc(format))
1681
- return 4;
1682
- switch (format) {
1683
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
1684
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
1879
+ static getBlockWidth(format) {
1880
+ if (TextureUtils.isBc(format) || TextureUtils.isEtc(format))
1685
1881
  return 4;
1686
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
1687
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
1688
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
1689
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
1690
- return 5;
1691
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
1692
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
1693
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
1694
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
1695
- return 6;
1696
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
1697
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
1698
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
1699
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
1700
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
1701
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
1702
- return 8;
1703
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
1704
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
1705
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
1706
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
1707
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
1708
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
1709
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
1710
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
1711
- return 10;
1712
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
1713
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
1714
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
1715
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
1716
- return 12;
1717
- default:
1718
- return 1;
1882
+ switch (format) {
1883
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
1884
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
1885
+ return 4;
1886
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
1887
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
1888
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
1889
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
1890
+ return 5;
1891
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
1892
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
1893
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
1894
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
1895
+ return 6;
1896
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
1897
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
1898
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
1899
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
1900
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
1901
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
1902
+ return 8;
1903
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
1904
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
1905
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
1906
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
1907
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
1908
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
1909
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
1910
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
1911
+ return 10;
1912
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
1913
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
1914
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
1915
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
1916
+ return 12;
1917
+ default:
1918
+ return 1;
1919
+ }
1719
1920
  }
1720
- }
1721
- /**
1722
- * Returns the number of bytes in a compressed or uncompressed block for the
1723
- * given texture format. Matches the mapping from the Rust implementation and
1724
- * throws for unsupported formats.
1725
- */
1726
- function bytesPerBlock(format) {
1727
- switch (format) {
1728
- // 1-byte formats
1729
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Unorm:
1730
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Snorm:
1731
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Uint:
1732
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Sint:
1733
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Stencil8:
1734
- return 1;
1735
- // 2-byte formats
1736
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Uint:
1737
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Sint:
1738
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Unorm:
1739
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Snorm:
1740
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Float:
1741
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Unorm:
1742
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Snorm:
1743
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Uint:
1744
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Sint:
1745
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth16Unorm:
1746
- return 2;
1747
- // 4-byte formats
1748
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Uint:
1749
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Sint:
1750
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Float:
1751
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Uint:
1752
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Sint:
1753
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Unorm:
1754
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Snorm:
1755
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Float:
1756
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Unorm:
1757
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb:
1758
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Snorm:
1759
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Uint:
1760
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Sint:
1761
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8Unorm:
1762
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8UnormSrgb:
1763
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb9e5Ufloat:
1764
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Uint:
1765
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Unorm:
1766
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24Plus:
1767
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24PlusStencil8:
1768
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32Float:
1769
- return 4;
1770
- // 8-byte formats
1771
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rg11b10Ufloat:
1772
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Uint:
1773
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Sint:
1774
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Float:
1775
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Uint:
1776
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Sint:
1777
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Unorm:
1778
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Snorm:
1779
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Float:
1780
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32FloatStencil8:
1781
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1782
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1783
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1784
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1785
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1786
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1787
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
1788
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
1789
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
1790
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
1791
- return 8;
1792
- // 16-byte formats
1793
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Uint:
1794
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Sint:
1795
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Float:
1796
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1797
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
1798
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
1799
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
1800
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
1801
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
1802
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
1803
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
1804
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
1805
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
1806
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
1807
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
1808
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
1809
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
1810
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
1811
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
1812
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
1813
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
1814
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
1815
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
1816
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
1817
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
1818
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
1819
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
1820
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
1821
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
1822
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
1823
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
1824
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
1825
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
1826
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
1827
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
1828
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
1829
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
1830
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
1831
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
1832
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
1833
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
1834
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
1835
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
1836
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
1837
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
1838
- case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1839
- // NOTE: Bc2RgbaUnorm is already listed above; duplicate entries are
1840
- // harmless but kept out of caution when mapping from Rust.
1841
- return 16;
1842
- default:
1843
- throw new Error(`Unsupported texture format: ${format}`);
1921
+ /**
1922
+ * Returns the number of bytes in a compressed or uncompressed block for the
1923
+ * given texture format. Matches the mapping from the Rust implementation and
1924
+ * throws for unsupported formats.
1925
+ */
1926
+ static bytesPerBlock(format) {
1927
+ switch (format) {
1928
+ // 1-byte formats
1929
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Unorm:
1930
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Snorm:
1931
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Uint:
1932
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R8Sint:
1933
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Stencil8:
1934
+ return 1;
1935
+ // 2-byte formats
1936
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Uint:
1937
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Sint:
1938
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Unorm:
1939
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Snorm:
1940
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R16Float:
1941
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Unorm:
1942
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Snorm:
1943
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Uint:
1944
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG8Sint:
1945
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth16Unorm:
1946
+ return 2;
1947
+ // 4-byte formats
1948
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Uint:
1949
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Sint:
1950
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.R32Float:
1951
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Uint:
1952
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Sint:
1953
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Unorm:
1954
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Snorm:
1955
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG16Float:
1956
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Unorm:
1957
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb:
1958
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Snorm:
1959
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Uint:
1960
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8Sint:
1961
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8Unorm:
1962
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bgra8UnormSrgb:
1963
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb9e5Ufloat:
1964
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Uint:
1965
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgb10a2Unorm:
1966
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24Plus:
1967
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth24PlusStencil8:
1968
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32Float:
1969
+ return 4;
1970
+ // 8-byte formats
1971
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rg11b10Ufloat:
1972
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Uint:
1973
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Sint:
1974
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.RG32Float:
1975
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Uint:
1976
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Sint:
1977
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Unorm:
1978
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Snorm:
1979
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba16Float:
1980
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Depth32FloatStencil8:
1981
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnorm:
1982
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc1RgbaUnormSrgb:
1983
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RUnorm:
1984
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc4RSnorm:
1985
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8Unorm:
1986
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8UnormSrgb:
1987
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1Unorm:
1988
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgb8A1UnormSrgb:
1989
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Unorm:
1990
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacR11Snorm:
1991
+ return 8;
1992
+ // 16-byte formats
1993
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Uint:
1994
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Sint:
1995
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba32Float:
1996
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
1997
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnormSrgb:
1998
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnorm:
1999
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc3RgbaUnormSrgb:
2000
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgUnorm:
2001
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc5RgSnorm:
2002
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbUfloat:
2003
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc6hRgbFloat:
2004
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnorm:
2005
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc7RgbaUnormSrgb:
2006
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8Unorm:
2007
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Etc2Rgba8UnormSrgb:
2008
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Unorm:
2009
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.EacRg11Snorm:
2010
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4Unorm:
2011
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc4x4UnormSrgb:
2012
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4Unorm:
2013
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x4UnormSrgb:
2014
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5Unorm:
2015
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc5x5UnormSrgb:
2016
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5Unorm:
2017
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x5UnormSrgb:
2018
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6Unorm:
2019
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc6x6UnormSrgb:
2020
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5Unorm:
2021
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x5UnormSrgb:
2022
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6Unorm:
2023
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x6UnormSrgb:
2024
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8Unorm:
2025
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc8x8UnormSrgb:
2026
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5Unorm:
2027
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x5UnormSrgb:
2028
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6Unorm:
2029
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x6UnormSrgb:
2030
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8Unorm:
2031
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x8UnormSrgb:
2032
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10Unorm:
2033
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc10x10UnormSrgb:
2034
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10Unorm:
2035
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x10UnormSrgb:
2036
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12Unorm:
2037
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Astc12x12UnormSrgb:
2038
+ case _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Bc2RgbaUnorm:
2039
+ // NOTE: Bc2RgbaUnorm is already listed above; duplicate entries are
2040
+ // harmless but kept out of caution when mapping from Rust.
2041
+ return 16;
2042
+ default:
2043
+ throw new Error(`Unsupported texture format: ${format}`);
2044
+ }
1844
2045
  }
1845
2046
  }
1846
2047
 
@@ -1870,6 +2071,8 @@ __webpack_require__.r(__webpack_exports__);
1870
2071
  /* harmony import */ var _ComputePipeline__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ComputePipeline */ "./src/ComputePipeline.ts");
1871
2072
  /* harmony import */ var _utils_mapUndefined__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils/mapUndefined */ "./src/utils/mapUndefined.ts");
1872
2073
  /* harmony import */ var _buffers_Buffer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./buffers/Buffer */ "./src/buffers/Buffer.ts");
2074
+ /* 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");
2075
+
1873
2076
 
1874
2077
 
1875
2078
 
@@ -1889,15 +2092,65 @@ __webpack_require__.r(__webpack_exports__);
1889
2092
  */
1890
2093
  class TinyHelix {
1891
2094
  /**
1892
- * Create a new TinyHelix instance. Call `initialize()` before rendering.
1893
- */
1894
- constructor(canvas) {
2095
+ * Create a new TinyHelix instance from a HTMLCanvasElement or an existing TinyHelix instance.
2096
+ * When creating from a Canvas, call `initialize()` before rendering to initialize the WebGPU context. When
2097
+ * using an existing TinyHelix instance, the new instance will share the same WebGPU context and resources.
2098
+ */
2099
+ constructor(canvasOrHX) {
2100
+ this._parent = null;
1895
2101
  this._options = {};
1896
2102
  this._shaderIncludes = new Map();
1897
- this._globalBindBufferLayouts = [];
1898
- this._globalBindBuffers = [];
1899
- this._context = new _WebGPUContext__WEBPACK_IMPORTED_MODULE_0__.WebGPUContext();
1900
- this._canvas = canvas;
2103
+ this._globalBindGroupLayouts = [];
2104
+ this._globalBindGroups = [];
2105
+ if (canvasOrHX instanceof TinyHelix) {
2106
+ this._context = canvasOrHX._context;
2107
+ this._canvas = canvasOrHX._canvas;
2108
+ this._mipShader = canvasOrHX._mipShader;
2109
+ this._depthStencil = canvasOrHX._depthStencil;
2110
+ this._depthStencilTarget = canvasOrHX._depthStencilTarget;
2111
+ }
2112
+ else {
2113
+ this._context = new _WebGPUContext__WEBPACK_IMPORTED_MODULE_0__.WebGPUContext();
2114
+ this._canvas = canvasOrHX;
2115
+ }
2116
+ }
2117
+ get shaderF16Supported() {
2118
+ return this._context.shaderF16Supported;
2119
+ }
2120
+ get floatFilteringSupported() {
2121
+ return this._context.floatFilteringSupported;
2122
+ }
2123
+ get adapter() {
2124
+ return this._context.adapter;
2125
+ }
2126
+ get device() {
2127
+ return this._context.device;
2128
+ }
2129
+ get context() {
2130
+ return this._context.context;
2131
+ }
2132
+ /**
2133
+ * Copies all shader includes from another TinyHelix instance.
2134
+ * @param hx - The TinyHelix instance to copy includes from.
2135
+ */
2136
+ copyIncludesFrom(hx) {
2137
+ hx._shaderIncludes.forEach((v, k) => this._shaderIncludes.set(k, v));
2138
+ return this;
2139
+ }
2140
+ /**
2141
+ * Copies all global bind groups from another TinyHelix instance.
2142
+ * @param hx - The TinyHelix instance to copy global bind groups from.
2143
+ */
2144
+ copyGlobalBindGroupsFrom(hx) {
2145
+ if (this._context != hx._context) {
2146
+ throw new Error("Cannot copy global bind groups from another TinyHelix instance with a different WebGPU context.");
2147
+ }
2148
+ if (this._globalBindGroups.length > 0 || this._globalBindGroupLayouts.length > 0) {
2149
+ throw new Error("Cannot copy global bind groups from another TinyHelix instance if this instance already has global bind groups set.");
2150
+ }
2151
+ this._globalBindGroupLayouts = [...hx._globalBindGroupLayouts];
2152
+ this._globalBindGroups = [...hx._globalBindGroups];
2153
+ return this;
1901
2154
  }
1902
2155
  /**
1903
2156
  * Initializes the underlying WebGPU context and prepares resources.
@@ -1909,6 +2162,10 @@ class TinyHelix {
1909
2162
  this._options = options;
1910
2163
  await this._context.initialize(options);
1911
2164
  this._createDepthStencil();
2165
+ this._mipShader = this._context.device.createShaderModule({
2166
+ code: _wgsl_mip_2d_2x2_wgsl__WEBPACK_IMPORTED_MODULE_13__,
2167
+ label: "MipRenderer Shader Module",
2168
+ });
1912
2169
  }
1913
2170
  resize(width, height) {
1914
2171
  this._canvas.width = width;
@@ -1980,9 +2237,17 @@ class TinyHelix {
1980
2237
  * @example tiny.startFrame();
1981
2238
  */
1982
2239
  startFrame() {
1983
- this._backbuffer = _Texture__WEBPACK_IMPORTED_MODULE_2__.Texture.from_webgpu(this._context.getCurrentTexture(), this._context.format);
1984
- this._backbufferTarget = this.createRenderTarget(this._backbuffer)
1985
- .build();
2240
+ if (this._parent) {
2241
+ this._backbuffer = this._parent.backbuffer;
2242
+ this._backbufferTarget = this._parent.backbufferTarget;
2243
+ return;
2244
+ }
2245
+ else {
2246
+ this._backbuffer = _Texture__WEBPACK_IMPORTED_MODULE_2__.Texture.from_webgpu(this._context.getCurrentTexture(), this._context.format, this._context);
2247
+ this._backbufferTarget = this.createRenderTarget(this._backbuffer)
2248
+ .withMipLevel(0)
2249
+ .build();
2250
+ }
1986
2251
  }
1987
2252
  /**
1988
2253
  * Create a RenderTargetBuilder for a given texture.
@@ -1996,7 +2261,7 @@ class TinyHelix {
1996
2261
  createShader() {
1997
2262
  let builder = new _Shader__WEBPACK_IMPORTED_MODULE_4__.ShaderBuilder(this._context);
1998
2263
  this._shaderIncludes.forEach((v, k) => builder = builder.withInclude(k, v));
1999
- this._globalBindBufferLayouts.forEach((layout, i) => builder.withBindGroup(i, layout));
2264
+ this._globalBindGroupLayouts.forEach((layout, i) => builder.withBindGroup(i, layout));
2000
2265
  return builder;
2001
2266
  }
2002
2267
  /**
@@ -2039,14 +2304,14 @@ class TinyHelix {
2039
2304
  * Create a TextureBuilder for creating a Texture.
2040
2305
  */
2041
2306
  createTexture() {
2042
- return new _Texture__WEBPACK_IMPORTED_MODULE_2__.TextureBuilder(this._context);
2307
+ return new _Texture__WEBPACK_IMPORTED_MODULE_2__.TextureBuilder(this._context, this._mipShader);
2043
2308
  }
2044
2309
  /**
2045
2310
  * Creates a command encoder for recording GPU commands for the current frame.
2046
2311
  * @param label - Optional debug label to assign to the encoder
2047
2312
  */
2048
2313
  createCommandEncoder(label) {
2049
- return new _CommandEncoder__WEBPACK_IMPORTED_MODULE_1__.CommandEncoder(this.backbufferTarget, this._globalBindBuffers, this._context, this._depthStencilTarget, label);
2314
+ return new _CommandEncoder__WEBPACK_IMPORTED_MODULE_1__.CommandEncoder(this.backbufferTarget, this._globalBindGroups, this._context, this._depthStencilTarget, label);
2050
2315
  }
2051
2316
  /**
2052
2317
  * Create a UniformBufferLayoutBuilder for creating a UniformBufferLayout.
@@ -2074,8 +2339,8 @@ class TinyHelix {
2074
2339
  * @param buffer - The bind group to set.
2075
2340
  */
2076
2341
  setGlobalBindGroup(index, layout, buffer) {
2077
- this._globalBindBufferLayouts[index] = layout;
2078
- this._globalBindBuffers[index] = buffer;
2342
+ this._globalBindGroupLayouts[index] = layout;
2343
+ this._globalBindGroups[index] = buffer;
2079
2344
  return this;
2080
2345
  }
2081
2346
  /**
@@ -2133,6 +2398,8 @@ class WebGPUContext {
2133
2398
  this._format = _enums__WEBPACK_IMPORTED_MODULE_0__.TextureFormat.Rgba8UnormSrgb;
2134
2399
  this._canvas = null;
2135
2400
  this._colorSpace = _enums__WEBPACK_IMPORTED_MODULE_0__.ColorSpace.sRGB;
2401
+ this._shaderF16Supported = false;
2402
+ this._floatFilteringSupported = false;
2136
2403
  }
2137
2404
  /**
2138
2405
  * Gets the WebGPU adapter. Throws if not initialized.
@@ -2192,6 +2459,26 @@ class WebGPUContext {
2192
2459
  if (!this._adapter) {
2193
2460
  throw new Error('Failed to get WebGPU adapter');
2194
2461
  }
2462
+ // By default, shader-f16 is enabled whenever available, while TinyHelix provides f32 fallback if it doesn't.
2463
+ // The user can ask for explicit support through the features. At this point, it will NOT provide a fallback
2464
+ // and fail to create the context.
2465
+ this._shaderF16Supported = this._adapter.features.has("shader-f16");
2466
+ this._floatFilteringSupported = this._adapter.features.has("float32-filterable");
2467
+ const requiresF16 = options.requiredFeatures?.includes("shader-f16");
2468
+ if (!this._shaderF16Supported) {
2469
+ if (requiresF16)
2470
+ throw new Error("shader-f16 feature requested but not available");
2471
+ else
2472
+ console.warn("WebGPU adapter does not support shader-f16 feature. Performance may be suboptimal for certain workloads.");
2473
+ }
2474
+ else if (!requiresF16) {
2475
+ options.requiredFeatures = options.requiredFeatures ?? [];
2476
+ options.requiredFeatures?.push("shader-f16");
2477
+ }
2478
+ if (this._floatFilteringSupported && !options.requiredFeatures?.includes("float32-filterable")) {
2479
+ options.requiredFeatures = options.requiredFeatures ?? [];
2480
+ options.requiredFeatures?.push("float32-filterable");
2481
+ }
2195
2482
  // Request device
2196
2483
  this._device = await this._adapter.requestDevice({
2197
2484
  requiredFeatures: options.requiredFeatures,
@@ -2202,11 +2489,11 @@ class WebGPUContext {
2202
2489
  }
2203
2490
  // Setup error handling
2204
2491
  this._device.lost.then((info) => {
2205
- console.error('WebGPU device lost:', info.message);
2206
- if (info.reason !== 'destroyed') {
2492
+ console.error("WebGPU device lost:", info.message, "\nReason:", info.reason);
2493
+ if (info.reason !== "destroyed") {
2207
2494
  // Attempt to reinitialize
2208
2495
  this.initialize(options).catch((error) => {
2209
- console.error('Failed to reinitialize WebGPU context:', error);
2496
+ console.error("Failed to reinitialize WebGPU context:", error);
2210
2497
  });
2211
2498
  }
2212
2499
  });
@@ -2235,6 +2522,19 @@ class WebGPUContext {
2235
2522
  console.warn("No canvas provided!");
2236
2523
  }
2237
2524
  }
2525
+ /**
2526
+ * Indicates whether the shaders support the f16 format. Use the type `half`, `vec2h`, `vec3h`, `vec4h`, etc. to
2527
+ * provide f32 fallbacks if f16 is not supported.
2528
+ */
2529
+ get shaderF16Supported() {
2530
+ return this._shaderF16Supported;
2531
+ }
2532
+ /**
2533
+ * Indicates whether the device supports filtering on float32 textures.
2534
+ */
2535
+ get floatFilteringSupported() {
2536
+ return this._floatFilteringSupported;
2537
+ }
2238
2538
  /**
2239
2539
  * Internal helper to fetch the current swapchain texture.
2240
2540
  * @internal
@@ -2315,6 +2615,7 @@ class BufferBuilder {
2315
2615
  this._size = 0;
2316
2616
  this._keepData = false;
2317
2617
  this._usage = 0;
2618
+ this._dataOffset = 0;
2318
2619
  this._ctx = ctx;
2319
2620
  }
2320
2621
  /**
@@ -2329,11 +2630,12 @@ class BufferBuilder {
2329
2630
  * ArrayBuffer is stored in the resulting `Buffer.data` field for readback or
2330
2631
  * reuse.
2331
2632
  */
2332
- withData(data, keepOnCPU = false) {
2633
+ withData(data, keepOnCPU = false, offset = 0, length = data.byteLength) {
2333
2634
  this._data = data;
2334
2635
  // round to the nearest multiple of 4 bytes, as required by GPUBuffer.writeBuffer()
2335
- this._size = data.byteLength;
2636
+ this._size = length ?? (data.byteLength - offset);
2336
2637
  this._keepData = keepOnCPU;
2638
+ this._dataOffset = offset;
2337
2639
  this._usage |= BufferUsage.CopyDst;
2338
2640
  return this;
2339
2641
  }
@@ -2348,9 +2650,13 @@ class BufferBuilder {
2348
2650
  * Create the GPU buffer and upload any provided data.
2349
2651
  */
2350
2652
  build() {
2351
- const data = (0,_utils_mapUndefined__WEBPACK_IMPORTED_MODULE_0__.mapUndefined)(this._data, data => (0,_utils_padArrayBuffer__WEBPACK_IMPORTED_MODULE_1__.padArrayBuffer)(data, 4));
2653
+ 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));
2654
+ if (this._keepData && data) {
2655
+ this._data = data;
2656
+ }
2657
+ this._size = data?.byteLength ?? this._size;
2352
2658
  const buffer = this._ctx.device.createBuffer({
2353
- size: data ? data.byteLength : this._size, // in case we don't have data, we need to specify the size explicitly'
2659
+ size: this._size,
2354
2660
  usage: this._usage
2355
2661
  });
2356
2662
  if (data) {
@@ -2638,6 +2944,8 @@ function sizeForBaseType(type) {
2638
2944
  case BaseType.Float16:
2639
2945
  return 2;
2640
2946
  case BaseType.Float32:
2947
+ case BaseType.Uint:
2948
+ case BaseType.Sint:
2641
2949
  return 4;
2642
2950
  case BaseType.Boolean:
2643
2951
  return 1;
@@ -2820,6 +3128,9 @@ class UniformBuffer {
2820
3128
  */
2821
3129
  setVec(name, values) {
2822
3130
  const [member, target] = this._dataViews.get(name);
3131
+ for (let i = 0; i < target.length; ++i) {
3132
+ target[i] = 0;
3133
+ }
2823
3134
  if (member.type.baseType == BaseType.Float16) {
2824
3135
  for (let i = 0; i < values.length; ++i) {
2825
3136
  target[i] = (0,_utils_float32ToFloat16__WEBPACK_IMPORTED_MODULE_1__.float32ToFloat16)(values[i]);
@@ -2842,6 +3153,9 @@ class UniformBuffer {
2842
3153
  const numCols = member.type.numCols;
2843
3154
  const numRows = member.type.numRows;
2844
3155
  const skipW = numRows === 3;
3156
+ for (let i = 0; i < target.length; ++i) {
3157
+ target[i] = 0;
3158
+ }
2845
3159
  // I know looping inside the cases looks ugly and the loops are tiny, but I just can't bring myself to put
2846
3160
  // a switch in a loop
2847
3161
  let i = 0;
@@ -2896,12 +3210,19 @@ __webpack_require__.r(__webpack_exports__);
2896
3210
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2897
3211
  /* harmony export */ AddressMode: () => (/* binding */ AddressMode),
2898
3212
  /* harmony export */ BlendFactor: () => (/* binding */ BlendFactor),
3213
+ /* harmony export */ ColorChannel: () => (/* binding */ ColorChannel),
2899
3214
  /* harmony export */ ColorSpace: () => (/* binding */ ColorSpace),
2900
3215
  /* harmony export */ CompareFunction: () => (/* binding */ CompareFunction),
2901
3216
  /* harmony export */ CullMode: () => (/* binding */ CullMode),
2902
3217
  /* harmony export */ FilterMode: () => (/* binding */ FilterMode),
3218
+ /* harmony export */ SamplerType: () => (/* binding */ SamplerType),
3219
+ /* harmony export */ ShaderStage: () => (/* binding */ ShaderStage),
2903
3220
  /* harmony export */ StorageAccess: () => (/* binding */ StorageAccess),
2904
- /* harmony export */ TextureFormat: () => (/* binding */ TextureFormat)
3221
+ /* harmony export */ StoreOp: () => (/* binding */ StoreOp),
3222
+ /* harmony export */ TextureDimension: () => (/* binding */ TextureDimension),
3223
+ /* harmony export */ TextureFormat: () => (/* binding */ TextureFormat),
3224
+ /* harmony export */ TextureSampleType: () => (/* binding */ TextureSampleType),
3225
+ /* harmony export */ TextureViewDimension: () => (/* binding */ TextureViewDimension)
2905
3226
  /* harmony export */ });
2906
3227
  var ColorSpace;
2907
3228
  (function (ColorSpace) {
@@ -3069,6 +3390,176 @@ var StorageAccess;
3069
3390
  StorageAccess["Read"] = "read-only";
3070
3391
  StorageAccess["Write"] = "write-only";
3071
3392
  })(StorageAccess || (StorageAccess = {}));
3393
+ var TextureSampleType;
3394
+ (function (TextureSampleType) {
3395
+ TextureSampleType["Float"] = "float";
3396
+ TextureSampleType["Sint"] = "sint";
3397
+ TextureSampleType["Uint"] = "uint";
3398
+ TextureSampleType["UnfilterableFloat"] = "unfilterable-float";
3399
+ TextureSampleType["Depth"] = "depth";
3400
+ })(TextureSampleType || (TextureSampleType = {}));
3401
+ var SamplerType;
3402
+ (function (SamplerType) {
3403
+ SamplerType["Filtering"] = "filtering";
3404
+ SamplerType["NonFiltering"] = "non-filtering";
3405
+ SamplerType["Comparison"] = "comparison";
3406
+ })(SamplerType || (SamplerType = {}));
3407
+ var ColorChannel;
3408
+ (function (ColorChannel) {
3409
+ ColorChannel[ColorChannel["Red"] = GPUColorWrite.RED] = "Red";
3410
+ ColorChannel[ColorChannel["Green"] = GPUColorWrite.GREEN] = "Green";
3411
+ ColorChannel[ColorChannel["Blue"] = GPUColorWrite.BLUE] = "Blue";
3412
+ })(ColorChannel || (ColorChannel = {}));
3413
+ var TextureDimension;
3414
+ (function (TextureDimension) {
3415
+ TextureDimension["D1"] = "1d";
3416
+ TextureDimension["D2"] = "2d";
3417
+ TextureDimension["D3"] = "3d";
3418
+ })(TextureDimension || (TextureDimension = {}));
3419
+ var TextureViewDimension;
3420
+ (function (TextureViewDimension) {
3421
+ TextureViewDimension["D1"] = "1d";
3422
+ TextureViewDimension["D2"] = "2d";
3423
+ TextureViewDimension["D2Array"] = "2d-array";
3424
+ TextureViewDimension["Cube"] = "cube";
3425
+ TextureViewDimension["CubeArray"] = "cube-array";
3426
+ TextureViewDimension["D3"] = "3d";
3427
+ })(TextureViewDimension || (TextureViewDimension = {}));
3428
+ var ShaderStage;
3429
+ (function (ShaderStage) {
3430
+ ShaderStage[ShaderStage["Vertex"] = GPUShaderStage.VERTEX] = "Vertex";
3431
+ ShaderStage[ShaderStage["Fragment"] = GPUShaderStage.FRAGMENT] = "Fragment";
3432
+ ShaderStage[ShaderStage["Compute"] = GPUShaderStage.COMPUTE] = "Compute";
3433
+ })(ShaderStage || (ShaderStage = {}));
3434
+ var StoreOp;
3435
+ (function (StoreOp) {
3436
+ StoreOp["Store"] = "store";
3437
+ StoreOp["Discard"] = "discard";
3438
+ })(StoreOp || (StoreOp = {}));
3439
+
3440
+
3441
+ /***/ }),
3442
+
3443
+ /***/ "./src/utils/MipRenderer.ts":
3444
+ /*!**********************************!*\
3445
+ !*** ./src/utils/MipRenderer.ts ***!
3446
+ \**********************************/
3447
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3448
+
3449
+ __webpack_require__.r(__webpack_exports__);
3450
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3451
+ /* harmony export */ MipRenderer: () => (/* binding */ MipRenderer)
3452
+ /* harmony export */ });
3453
+ /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums */ "./src/enums.ts");
3454
+ /* harmony import */ var _buffers_Buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../buffers/Buffer */ "./src/buffers/Buffer.ts");
3455
+
3456
+
3457
+ class MipRenderer {
3458
+ constructor(ctx, shader, texture) {
3459
+ this._bindgroups = [];
3460
+ this._views = [];
3461
+ this._passDescs = [];
3462
+ this._ctx = ctx;
3463
+ const sampler = ctx.device.createSampler({
3464
+ label: "MipRenderer Bilinear Sampler",
3465
+ magFilter: _enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Linear,
3466
+ minFilter: _enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Linear,
3467
+ mipmapFilter: _enums__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Nearest
3468
+ });
3469
+ this._bindgroupLayout = ctx.device.createBindGroupLayout({
3470
+ label: "MipRenderer BindGroup Layout",
3471
+ entries: [
3472
+ {
3473
+ binding: 0,
3474
+ visibility: GPUShaderStage.FRAGMENT,
3475
+ texture: {
3476
+ sampleType: "float",
3477
+ viewDimension: texture.dimension(),
3478
+ multisampled: false
3479
+ }
3480
+ },
3481
+ {
3482
+ binding: 1,
3483
+ visibility: GPUShaderStage.FRAGMENT,
3484
+ sampler: {
3485
+ type: "filtering"
3486
+ }
3487
+ }
3488
+ ]
3489
+ });
3490
+ this._pipeline = ctx.device.createRenderPipeline({
3491
+ label: "MipRenderer Pipeline",
3492
+ layout: ctx.device.createPipelineLayout({
3493
+ label: "MipRenderer Pipeline Layout",
3494
+ bindGroupLayouts: [this._bindgroupLayout]
3495
+ }),
3496
+ vertex: {
3497
+ module: shader,
3498
+ entryPoint: "vs_main"
3499
+ },
3500
+ fragment: {
3501
+ module: shader,
3502
+ entryPoint: "fs_main",
3503
+ targets: [
3504
+ {
3505
+ format: texture.format
3506
+ }
3507
+ ]
3508
+ },
3509
+ primitive: {
3510
+ topology: "triangle-list",
3511
+ stripIndexFormat: undefined,
3512
+ frontFace: "ccw",
3513
+ cullMode: "none"
3514
+ }
3515
+ });
3516
+ for (let level = 0; level < texture.mipLevelCount; ++level) {
3517
+ this._views.push(texture.createView()
3518
+ .withSingleMip(level)
3519
+ .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_1__.TextureUsage.RenderAttachment)
3520
+ .withUsage(_buffers_Buffer__WEBPACK_IMPORTED_MODULE_1__.TextureUsage.TextureBinding)
3521
+ .build()._inner);
3522
+ if (level === 0)
3523
+ continue;
3524
+ this._bindgroups.push(ctx.device.createBindGroup({
3525
+ label: `MipRenderer BindGroup Mip ${level}`,
3526
+ layout: this._bindgroupLayout,
3527
+ entries: [
3528
+ {
3529
+ binding: 0,
3530
+ resource: this._views[level - 1]
3531
+ },
3532
+ {
3533
+ binding: 1,
3534
+ resource: sampler
3535
+ }
3536
+ ]
3537
+ }));
3538
+ this._passDescs.push({
3539
+ label: `MipRenderer Render Pass mip ${level}`,
3540
+ colorAttachments: [{
3541
+ view: this._views[level],
3542
+ loadOp: 'clear',
3543
+ storeOp: 'store',
3544
+ clearValue: { r: 0, g: 0, b: 0, a: 0 }
3545
+ }]
3546
+ });
3547
+ }
3548
+ }
3549
+ render() {
3550
+ const encoder = this._ctx.device.createCommandEncoder({
3551
+ label: "MipRenderer Command Encoder"
3552
+ });
3553
+ this._passDescs.forEach((desc, level) => {
3554
+ const pass = encoder.beginRenderPass(desc);
3555
+ pass.setPipeline(this._pipeline);
3556
+ pass.setBindGroup(0, this._bindgroups[level]);
3557
+ pass.draw(3, 1, 0, 0);
3558
+ pass.end();
3559
+ });
3560
+ this._ctx.device.queue.submit([encoder.finish()]);
3561
+ }
3562
+ }
3072
3563
 
3073
3564
 
3074
3565
  /***/ }),
@@ -3154,20 +3645,33 @@ __webpack_require__.r(__webpack_exports__);
3154
3645
  *
3155
3646
  * @param input - The input ArrayBuffer or SharedArrayBuffer to pad
3156
3647
  * @param alignment - Desired byte alignment (e.g. 4 for 32-bit alignment)
3648
+ * @param offset - The offset in bytes from the start of the input buffer to begin copying from
3649
+ * @param size - The number of bytes to copy from the input buffer
3157
3650
  * @returns A buffer with byteLength rounded up to the nearest multiple of alignment
3158
3651
  */
3159
- function padArrayBuffer(input, alignment) {
3160
- const targetSize = Math.ceil(input.byteLength / alignment) * alignment;
3161
- if (targetSize === input.byteLength)
3652
+ function padArrayBuffer(input, alignment, offset, size) {
3653
+ const targetSize = Math.ceil(size / alignment) * alignment;
3654
+ const needsSlice = offset !== 0 || size !== input.byteLength;
3655
+ if (!needsSlice && targetSize === size)
3162
3656
  return input;
3163
3657
  const data = input instanceof ArrayBuffer ? new ArrayBuffer(targetSize) : new SharedArrayBuffer(targetSize);
3164
- const src = new Uint8Array(input);
3658
+ const src = new Uint8Array(input, offset, size);
3165
3659
  const dst = new Uint8Array(data);
3166
3660
  dst.set(src);
3167
3661
  return data;
3168
3662
  }
3169
3663
 
3170
3664
 
3665
+ /***/ }),
3666
+
3667
+ /***/ "./src/wgsl/mip_2d_2x2.wgsl":
3668
+ /*!**********************************!*\
3669
+ !*** ./src/wgsl/mip_2d_2x2.wgsl ***!
3670
+ \**********************************/
3671
+ /***/ ((module) => {
3672
+
3673
+ 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";
3674
+
3171
3675
  /***/ })
3172
3676
 
3173
3677
  /******/ });
@@ -3245,6 +3749,7 @@ __webpack_require__.r(__webpack_exports__);
3245
3749
  /* harmony export */ BufferBuilder: () => (/* reexport safe */ _buffers_Buffer__WEBPACK_IMPORTED_MODULE_15__.BufferBuilder),
3246
3750
  /* harmony export */ BufferDataWriter: () => (/* reexport safe */ _buffers_BufferDataWriter__WEBPACK_IMPORTED_MODULE_17__.BufferDataWriter),
3247
3751
  /* harmony export */ BufferUsage: () => (/* reexport safe */ _buffers_Buffer__WEBPACK_IMPORTED_MODULE_15__.BufferUsage),
3752
+ /* harmony export */ ColorChannel: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.ColorChannel),
3248
3753
  /* harmony export */ ColorSpace: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.ColorSpace),
3249
3754
  /* harmony export */ CommandEncoder: () => (/* reexport safe */ _CommandEncoder__WEBPACK_IMPORTED_MODULE_4__.CommandEncoder),
3250
3755
  /* harmony export */ CompareFunction: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.CompareFunction),
@@ -3267,16 +3772,23 @@ __webpack_require__.r(__webpack_exports__);
3267
3772
  /* harmony export */ RenderTargetBuilder: () => (/* reexport safe */ _RenderTarget__WEBPACK_IMPORTED_MODULE_11__.RenderTargetBuilder),
3268
3773
  /* harmony export */ Sampler: () => (/* reexport safe */ _Sampler__WEBPACK_IMPORTED_MODULE_12__.Sampler),
3269
3774
  /* harmony export */ SamplerBuilder: () => (/* reexport safe */ _Sampler__WEBPACK_IMPORTED_MODULE_12__.SamplerBuilder),
3775
+ /* harmony export */ SamplerType: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.SamplerType),
3270
3776
  /* harmony export */ Shader: () => (/* reexport safe */ _Shader__WEBPACK_IMPORTED_MODULE_13__.Shader),
3271
3777
  /* harmony export */ ShaderBuilder: () => (/* reexport safe */ _Shader__WEBPACK_IMPORTED_MODULE_13__.ShaderBuilder),
3778
+ /* harmony export */ ShaderStage: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.ShaderStage),
3272
3779
  /* harmony export */ StorageAccess: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.StorageAccess),
3780
+ /* harmony export */ StoreOp: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.StoreOp),
3273
3781
  /* harmony export */ StreamBuilder: () => (/* reexport safe */ _Mesh__WEBPACK_IMPORTED_MODULE_8__.StreamBuilder),
3274
3782
  /* harmony export */ Texture: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.Texture),
3275
3783
  /* harmony export */ TextureBuilder: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureBuilder),
3784
+ /* harmony export */ TextureDimension: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureDimension),
3276
3785
  /* harmony export */ TextureFormat: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureFormat),
3786
+ /* harmony export */ TextureSampleType: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureSampleType),
3277
3787
  /* harmony export */ TextureUsage: () => (/* reexport safe */ _buffers_Buffer__WEBPACK_IMPORTED_MODULE_15__.TextureUsage),
3788
+ /* harmony export */ TextureUtils: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureUtils),
3278
3789
  /* harmony export */ TextureView: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureView),
3279
3790
  /* harmony export */ TextureViewBuilder: () => (/* reexport safe */ _Texture__WEBPACK_IMPORTED_MODULE_14__.TextureViewBuilder),
3791
+ /* harmony export */ TextureViewDimension: () => (/* reexport safe */ _enums__WEBPACK_IMPORTED_MODULE_7__.TextureViewDimension),
3280
3792
  /* harmony export */ TinyHelix: () => (/* reexport safe */ _TinyHelix__WEBPACK_IMPORTED_MODULE_0__.TinyHelix),
3281
3793
  /* harmony export */ UniformBuffer: () => (/* reexport safe */ _buffers_UniformBuffer__WEBPACK_IMPORTED_MODULE_16__.UniformBuffer),
3282
3794
  /* harmony export */ UniformBufferLayout: () => (/* reexport safe */ _buffers_UniformBuffer__WEBPACK_IMPORTED_MODULE_16__.UniformBufferLayout),
@@ -3342,6 +3854,7 @@ const __webpack_exports__Buffer = __webpack_exports__.Buffer;
3342
3854
  const __webpack_exports__BufferBuilder = __webpack_exports__.BufferBuilder;
3343
3855
  const __webpack_exports__BufferDataWriter = __webpack_exports__.BufferDataWriter;
3344
3856
  const __webpack_exports__BufferUsage = __webpack_exports__.BufferUsage;
3857
+ const __webpack_exports__ColorChannel = __webpack_exports__.ColorChannel;
3345
3858
  const __webpack_exports__ColorSpace = __webpack_exports__.ColorSpace;
3346
3859
  const __webpack_exports__CommandEncoder = __webpack_exports__.CommandEncoder;
3347
3860
  const __webpack_exports__CompareFunction = __webpack_exports__.CompareFunction;
@@ -3364,16 +3877,23 @@ const __webpack_exports__RenderTarget = __webpack_exports__.RenderTarget;
3364
3877
  const __webpack_exports__RenderTargetBuilder = __webpack_exports__.RenderTargetBuilder;
3365
3878
  const __webpack_exports__Sampler = __webpack_exports__.Sampler;
3366
3879
  const __webpack_exports__SamplerBuilder = __webpack_exports__.SamplerBuilder;
3880
+ const __webpack_exports__SamplerType = __webpack_exports__.SamplerType;
3367
3881
  const __webpack_exports__Shader = __webpack_exports__.Shader;
3368
3882
  const __webpack_exports__ShaderBuilder = __webpack_exports__.ShaderBuilder;
3883
+ const __webpack_exports__ShaderStage = __webpack_exports__.ShaderStage;
3369
3884
  const __webpack_exports__StorageAccess = __webpack_exports__.StorageAccess;
3885
+ const __webpack_exports__StoreOp = __webpack_exports__.StoreOp;
3370
3886
  const __webpack_exports__StreamBuilder = __webpack_exports__.StreamBuilder;
3371
3887
  const __webpack_exports__Texture = __webpack_exports__.Texture;
3372
3888
  const __webpack_exports__TextureBuilder = __webpack_exports__.TextureBuilder;
3889
+ const __webpack_exports__TextureDimension = __webpack_exports__.TextureDimension;
3373
3890
  const __webpack_exports__TextureFormat = __webpack_exports__.TextureFormat;
3891
+ const __webpack_exports__TextureSampleType = __webpack_exports__.TextureSampleType;
3374
3892
  const __webpack_exports__TextureUsage = __webpack_exports__.TextureUsage;
3893
+ const __webpack_exports__TextureUtils = __webpack_exports__.TextureUtils;
3375
3894
  const __webpack_exports__TextureView = __webpack_exports__.TextureView;
3376
3895
  const __webpack_exports__TextureViewBuilder = __webpack_exports__.TextureViewBuilder;
3896
+ const __webpack_exports__TextureViewDimension = __webpack_exports__.TextureViewDimension;
3377
3897
  const __webpack_exports__TinyHelix = __webpack_exports__.TinyHelix;
3378
3898
  const __webpack_exports__UniformBuffer = __webpack_exports__.UniformBuffer;
3379
3899
  const __webpack_exports__UniformBufferLayout = __webpack_exports__.UniformBufferLayout;
@@ -3381,6 +3901,6 @@ const __webpack_exports__UniformBufferLayoutBuilder = __webpack_exports__.Unifor
3381
3901
  const __webpack_exports__VertexFormat = __webpack_exports__.VertexFormat;
3382
3902
  const __webpack_exports__WebGPUContext = __webpack_exports__.WebGPUContext;
3383
3903
  const __webpack_exports__default = __webpack_exports__["default"];
3384
- export { __webpack_exports__AddressMode as AddressMode, __webpack_exports__BaseType as BaseType, __webpack_exports__BindGroup as BindGroup, __webpack_exports__BindGroupBuilder as BindGroupBuilder, __webpack_exports__BindGroupLayout as BindGroupLayout, __webpack_exports__BlendFactor as BlendFactor, __webpack_exports__BlendMode as BlendMode, __webpack_exports__Buffer as Buffer, __webpack_exports__BufferBuilder as BufferBuilder, __webpack_exports__BufferDataWriter as BufferDataWriter, __webpack_exports__BufferUsage as BufferUsage, __webpack_exports__ColorSpace as ColorSpace, __webpack_exports__CommandEncoder as CommandEncoder, __webpack_exports__CompareFunction as CompareFunction, __webpack_exports__ComputePass as ComputePass, __webpack_exports__ComputePassBuilder as ComputePassBuilder, __webpack_exports__ComputePipeline as ComputePipeline, __webpack_exports__ComputePipelineBuilder as ComputePipelineBuilder, __webpack_exports__CullMode as CullMode, __webpack_exports__FilterMode as FilterMode, __webpack_exports__FrontFace as FrontFace, __webpack_exports__IndexFormat as IndexFormat, __webpack_exports__Mesh as Mesh, __webpack_exports__MeshBuilder as MeshBuilder, __webpack_exports__MeshTopology as MeshTopology, __webpack_exports__RenderPass as RenderPass, __webpack_exports__RenderPassBuilder as RenderPassBuilder, __webpack_exports__RenderPipeline as RenderPipeline, __webpack_exports__RenderPipelineBuilder as RenderPipelineBuilder, __webpack_exports__RenderTarget as RenderTarget, __webpack_exports__RenderTargetBuilder as RenderTargetBuilder, __webpack_exports__Sampler as Sampler, __webpack_exports__SamplerBuilder as SamplerBuilder, __webpack_exports__Shader as Shader, __webpack_exports__ShaderBuilder as ShaderBuilder, __webpack_exports__StorageAccess as StorageAccess, __webpack_exports__StreamBuilder as StreamBuilder, __webpack_exports__Texture as Texture, __webpack_exports__TextureBuilder as TextureBuilder, __webpack_exports__TextureFormat as TextureFormat, __webpack_exports__TextureUsage as TextureUsage, __webpack_exports__TextureView as TextureView, __webpack_exports__TextureViewBuilder as TextureViewBuilder, __webpack_exports__TinyHelix as TinyHelix, __webpack_exports__UniformBuffer as UniformBuffer, __webpack_exports__UniformBufferLayout as UniformBufferLayout, __webpack_exports__UniformBufferLayoutBuilder as UniformBufferLayoutBuilder, __webpack_exports__VertexFormat as VertexFormat, __webpack_exports__WebGPUContext as WebGPUContext, __webpack_exports__default as default };
3904
+ export { __webpack_exports__AddressMode as AddressMode, __webpack_exports__BaseType as BaseType, __webpack_exports__BindGroup as BindGroup, __webpack_exports__BindGroupBuilder as BindGroupBuilder, __webpack_exports__BindGroupLayout as BindGroupLayout, __webpack_exports__BlendFactor as BlendFactor, __webpack_exports__BlendMode as BlendMode, __webpack_exports__Buffer as Buffer, __webpack_exports__BufferBuilder as BufferBuilder, __webpack_exports__BufferDataWriter as BufferDataWriter, __webpack_exports__BufferUsage as BufferUsage, __webpack_exports__ColorChannel as ColorChannel, __webpack_exports__ColorSpace as ColorSpace, __webpack_exports__CommandEncoder as CommandEncoder, __webpack_exports__CompareFunction as CompareFunction, __webpack_exports__ComputePass as ComputePass, __webpack_exports__ComputePassBuilder as ComputePassBuilder, __webpack_exports__ComputePipeline as ComputePipeline, __webpack_exports__ComputePipelineBuilder as ComputePipelineBuilder, __webpack_exports__CullMode as CullMode, __webpack_exports__FilterMode as FilterMode, __webpack_exports__FrontFace as FrontFace, __webpack_exports__IndexFormat as IndexFormat, __webpack_exports__Mesh as Mesh, __webpack_exports__MeshBuilder as MeshBuilder, __webpack_exports__MeshTopology as MeshTopology, __webpack_exports__RenderPass as RenderPass, __webpack_exports__RenderPassBuilder as RenderPassBuilder, __webpack_exports__RenderPipeline as RenderPipeline, __webpack_exports__RenderPipelineBuilder as RenderPipelineBuilder, __webpack_exports__RenderTarget as RenderTarget, __webpack_exports__RenderTargetBuilder as RenderTargetBuilder, __webpack_exports__Sampler as Sampler, __webpack_exports__SamplerBuilder as SamplerBuilder, __webpack_exports__SamplerType as SamplerType, __webpack_exports__Shader as Shader, __webpack_exports__ShaderBuilder as ShaderBuilder, __webpack_exports__ShaderStage as ShaderStage, __webpack_exports__StorageAccess as StorageAccess, __webpack_exports__StoreOp as StoreOp, __webpack_exports__StreamBuilder as StreamBuilder, __webpack_exports__Texture as Texture, __webpack_exports__TextureBuilder as TextureBuilder, __webpack_exports__TextureDimension as TextureDimension, __webpack_exports__TextureFormat as TextureFormat, __webpack_exports__TextureSampleType as TextureSampleType, __webpack_exports__TextureUsage as TextureUsage, __webpack_exports__TextureUtils as TextureUtils, __webpack_exports__TextureView as TextureView, __webpack_exports__TextureViewBuilder as TextureViewBuilder, __webpack_exports__TextureViewDimension as TextureViewDimension, __webpack_exports__TinyHelix as TinyHelix, __webpack_exports__UniformBuffer as UniformBuffer, __webpack_exports__UniformBufferLayout as UniformBufferLayout, __webpack_exports__UniformBufferLayoutBuilder as UniformBufferLayoutBuilder, __webpack_exports__VertexFormat as VertexFormat, __webpack_exports__WebGPUContext as WebGPUContext, __webpack_exports__default as default };
3385
3905
 
3386
3906
  //# sourceMappingURL=tiny-helix.esm.debug.js.map