@plasius/gpu-renderer 0.2.41 → 0.2.43

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.
package/dist/index.js CHANGED
@@ -4438,6 +4438,13 @@ function dispatchWavefrontGpuAccelerationBuild({
4438
4438
  }
4439
4439
 
4440
4440
  // src/wavefront-config.js
4441
+ var WEBGPU_DEFAULT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 256;
4442
+ function allocatedRecordBytes(count, recordBytes) {
4443
+ return Math.max(1, count) * recordBytes;
4444
+ }
4445
+ function alignByteSize(value, alignment) {
4446
+ return Math.ceil(value / alignment) * alignment;
4447
+ }
4441
4448
  function resolveEnvironmentLighting(input, environmentColor, ambientColor) {
4442
4449
  const source = input ?? {};
4443
4450
  return Object.freeze({
@@ -4614,6 +4621,18 @@ function resolveCamera(input, width, height) {
4614
4621
  });
4615
4622
  }
4616
4623
  function estimateWavefrontPathTracingMemory(options = {}) {
4624
+ const width = readPositiveInteger2("width", options.width, DEFAULT_WIDTH);
4625
+ const height = readPositiveInteger2("height", options.height, DEFAULT_HEIGHT);
4626
+ const tileSize = readPositiveInteger2("tileSize", options.tileSize, DEFAULT_TILE_SIZE);
4627
+ const samplesPerPixel = clamp2(
4628
+ readPositiveInteger2(
4629
+ "samplesPerPixel",
4630
+ options.samplesPerPixel,
4631
+ DEFAULT_SAMPLES_PER_PIXEL
4632
+ ),
4633
+ 1,
4634
+ MAX_SAMPLES_PER_PIXEL
4635
+ );
4617
4636
  const tilePixelCapacity = readPositiveInteger2(
4618
4637
  "tilePixelCapacity",
4619
4638
  options.tilePixelCapacity,
@@ -4646,18 +4665,89 @@ function estimateWavefrontPathTracingMemory(options = {}) {
4646
4665
  options.environmentPortalCapacity,
4647
4666
  0
4648
4667
  );
4649
- const materialCapacity = readNonNegativeInteger2("materialCapacity", options.materialCapacity, 0);
4668
+ readNonNegativeInteger2("materialCapacity", options.materialCapacity, 0);
4669
+ const meshVertexCount = readNonNegativeInteger2(
4670
+ "meshVertexCount",
4671
+ options.meshVertexCount,
4672
+ 0
4673
+ );
4674
+ const meshIndexCount = readNonNegativeInteger2(
4675
+ "meshIndexCount",
4676
+ options.meshIndexCount,
4677
+ 0
4678
+ );
4679
+ const meshRangeCount = readNonNegativeInteger2(
4680
+ "meshRangeCount",
4681
+ options.meshRangeCount,
4682
+ 0
4683
+ );
4684
+ const bvhSortStageCount = readNonNegativeInteger2(
4685
+ "bvhSortStageCount",
4686
+ options.bvhSortStageCount,
4687
+ 0
4688
+ );
4689
+ const bvhBuildLevelCount = readNonNegativeInteger2(
4690
+ "bvhBuildLevelCount",
4691
+ options.bvhBuildLevelCount,
4692
+ 0
4693
+ );
4694
+ const minUniformBufferOffsetAlignment = readPositiveInteger2(
4695
+ "minUniformBufferOffsetAlignment",
4696
+ options.minUniformBufferOffsetAlignment,
4697
+ WEBGPU_DEFAULT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT
4698
+ );
4699
+ const denoise = options.denoise !== false;
4700
+ const deferredPathResolve = options.deferredPathResolve !== false;
4650
4701
  const queueBytes = tilePixelCapacity * RAY_RECORD_BYTES;
4651
4702
  const hitBytes = tilePixelCapacity * HIT_RECORD_BYTES;
4652
4703
  const accumulationBytes = tilePixelCapacity * ACCUMULATION_RECORD_BYTES;
4653
4704
  const pathVertexBytes = tilePixelCapacity * (maxDepth + 1) * PATH_VERTEX_RECORD_BYTES;
4654
4705
  const sceneObjectBytes = sceneObjectCapacity * SCENE_OBJECT_RECORD_BYTES;
4655
- const triangleBytes = triangleCapacity * TRIANGLE_RECORD_BYTES;
4656
- const materialTableBytes = materialCapacity * GPU_MATERIAL_RECORD_BYTES;
4706
+ const triangleBytes = allocatedRecordBytes(triangleCapacity, TRIANGLE_RECORD_BYTES);
4707
+ const materialTableBytes = 0;
4657
4708
  const bvhNodeBytes = bvhNodeCapacity * BVH_NODE_RECORD_BYTES;
4658
- const bvhLeafReferenceBytes = bvhLeafSortCapacity * BVH_LEAF_REF_RECORD_BYTES;
4709
+ const bvhLeafReferenceBytes = allocatedRecordBytes(
4710
+ bvhLeafSortCapacity,
4711
+ BVH_LEAF_REF_RECORD_BYTES
4712
+ );
4659
4713
  const emissiveTriangleMetadataBytes = emissiveTriangleCapacity * BVH_NODE_RECORD_BYTES;
4660
- const environmentPortalBytes = environmentPortalCapacity * ENVIRONMENT_PORTAL_RECORD_BYTES;
4714
+ const bvhCombinedBytes = allocatedRecordBytes(
4715
+ bvhNodeCapacity + emissiveTriangleCapacity,
4716
+ BVH_NODE_RECORD_BYTES
4717
+ );
4718
+ const meshVertexBytes = allocatedRecordBytes(meshVertexCount, MESH_VERTEX_RECORD_BYTES);
4719
+ const meshIndexBytes = allocatedRecordBytes(meshIndexCount, 4);
4720
+ const meshRangeBytes = allocatedRecordBytes(meshRangeCount, MESH_RANGE_RECORD_BYTES);
4721
+ const environmentPortalBytes = allocatedRecordBytes(
4722
+ environmentPortalCapacity,
4723
+ ENVIRONMENT_PORTAL_RECORD_BYTES
4724
+ );
4725
+ const tileCount = Math.ceil(width / tileSize) * Math.ceil(height / tileSize);
4726
+ const outputConfigSlotCount = deferredPathResolve ? 0 : tileCount;
4727
+ const frameConfigSlotCount = Math.max(
4728
+ 1,
4729
+ tileCount * samplesPerPixel + outputConfigSlotCount + (denoise ? 1 : 0)
4730
+ );
4731
+ const configBufferStride = alignByteSize(
4732
+ CONFIG_BUFFER_BYTES,
4733
+ minUniformBufferOffsetAlignment
4734
+ );
4735
+ const frameConfigBytes = frameConfigSlotCount * configBufferStride;
4736
+ const bvhBuildConfigBytes = Math.max(
4737
+ 1,
4738
+ 1 + bvhSortStageCount + bvhBuildLevelCount
4739
+ ) * configBufferStride;
4740
+ const sceneStorageBufferBindingBytes = Math.max(
4741
+ sceneObjectBytes,
4742
+ triangleBytes,
4743
+ bvhCombinedBytes,
4744
+ meshVertexBytes,
4745
+ meshIndexBytes,
4746
+ meshRangeBytes,
4747
+ environmentPortalBytes,
4748
+ bvhLeafReferenceBytes
4749
+ );
4750
+ const totalHotBufferBytes = queueBytes * 2 + hitBytes + accumulationBytes + pathVertexBytes + sceneObjectBytes + triangleBytes + bvhCombinedBytes + meshVertexBytes + meshIndexBytes + meshRangeBytes + bvhLeafReferenceBytes + environmentPortalBytes + frameConfigBytes + bvhBuildConfigBytes + COUNTER_BUFFER_BYTES + INDIRECT_DISPATCH_ARGS_BYTES;
4661
4751
  return Object.freeze({
4662
4752
  queueBytes,
4663
4753
  queuePairBytes: queueBytes * 2,
@@ -4668,13 +4758,45 @@ function estimateWavefrontPathTracingMemory(options = {}) {
4668
4758
  triangleBytes,
4669
4759
  materialTableBytes,
4670
4760
  bvhNodeBytes,
4761
+ bvhCombinedBytes,
4671
4762
  bvhLeafReferenceBytes,
4672
4763
  emissiveTriangleMetadataBytes,
4764
+ meshVertexBytes,
4765
+ meshIndexBytes,
4766
+ meshRangeBytes,
4673
4767
  environmentPortalBytes,
4674
4768
  configBytes: CONFIG_BUFFER_BYTES,
4769
+ configBufferStride,
4770
+ frameConfigBytes,
4771
+ bvhBuildConfigBytes,
4675
4772
  counterBytes: COUNTER_BUFFER_BYTES,
4676
4773
  indirectDispatchBytes: INDIRECT_DISPATCH_ARGS_BYTES,
4677
- totalHotBufferBytes: queueBytes * 2 + hitBytes + accumulationBytes + pathVertexBytes + sceneObjectBytes + triangleBytes + materialTableBytes + bvhNodeBytes + bvhLeafReferenceBytes + emissiveTriangleMetadataBytes + environmentPortalBytes + CONFIG_BUFFER_BYTES + COUNTER_BUFFER_BYTES + INDIRECT_DISPATCH_ARGS_BYTES
4774
+ sceneStorageBufferBindingBytes,
4775
+ totalHotBufferBytes
4776
+ });
4777
+ }
4778
+ function estimateWavefrontPathTracingMemoryForConfig(config, limits = {}) {
4779
+ return estimateWavefrontPathTracingMemory({
4780
+ width: config.width,
4781
+ height: config.height,
4782
+ tileSize: config.tileSize,
4783
+ samplesPerPixel: config.samplesPerPixel,
4784
+ tilePixelCapacity: config.tilePixelCapacity,
4785
+ maxDepth: config.maxDepth,
4786
+ sceneObjectCapacity: config.sceneObjectCapacity,
4787
+ triangleCapacity: config.triangleCapacity,
4788
+ bvhNodeCapacity: config.bvhNodeCapacity,
4789
+ bvhLeafSortCapacity: config.bvhLeafSortCapacity,
4790
+ emissiveTriangleCapacity: config.emissiveTriangleCapacity,
4791
+ environmentPortalCapacity: config.environmentPortalCapacity,
4792
+ meshVertexCount: config.gpuMeshSource.vertices.count,
4793
+ meshIndexCount: config.gpuMeshSource.indices.count,
4794
+ meshRangeCount: config.gpuMeshSource.meshes.count,
4795
+ bvhSortStageCount: config.bvhSortStages.length,
4796
+ bvhBuildLevelCount: config.bvhBuildLevels.length,
4797
+ denoise: config.denoise,
4798
+ deferredPathResolve: config.deferredPathResolve,
4799
+ minUniformBufferOffsetAlignment: limits.minUniformBufferOffsetAlignment ?? WEBGPU_DEFAULT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT
4678
4800
  });
4679
4801
  }
4680
4802
  function createWavefrontPathTracingComputeConfig(options = {}) {
@@ -4819,15 +4941,25 @@ function createWavefrontPathTracingComputeConfig(options = {}) {
4819
4941
  denoise: options.denoise !== false,
4820
4942
  frameIndex: readNonNegativeInteger2("frameIndex", options.frameIndex, 0),
4821
4943
  memory: estimateWavefrontPathTracingMemory({
4944
+ width,
4945
+ height,
4946
+ tileSize,
4947
+ samplesPerPixel,
4822
4948
  tilePixelCapacity,
4823
4949
  maxDepth,
4824
4950
  sceneObjectCapacity,
4825
4951
  triangleCapacity,
4826
- materialCapacity: gpuMaterialSource.count,
4827
4952
  bvhNodeCapacity,
4828
4953
  bvhLeafSortCapacity,
4829
4954
  emissiveTriangleCapacity: emissiveTriangleIndices.capacity,
4830
- environmentPortalCapacity
4955
+ environmentPortalCapacity,
4956
+ meshVertexCount: gpuMeshSource.vertices.count,
4957
+ meshIndexCount: gpuMeshSource.indices.count,
4958
+ meshRangeCount: gpuMeshSource.meshes.count,
4959
+ bvhSortStageCount: bvhSortStages.length,
4960
+ bvhBuildLevelCount: bvhBuildLevels.length,
4961
+ denoise: options.denoise !== false,
4962
+ deferredPathResolve
4831
4963
  })
4832
4964
  });
4833
4965
  }
@@ -5672,6 +5804,32 @@ function createWavefrontPresentBindGroup({
5672
5804
  }
5673
5805
 
5674
5806
  // src/wavefront-runtime-support.js
5807
+ var WEBGPU_DEFAULT_MAX_STORAGE_BUFFER_BINDING_SIZE = 128 * 1024 * 1024;
5808
+ var WEBGPU_DEFAULT_MAX_BUFFER_SIZE = 256 * 1024 * 1024;
5809
+ function readRequestedDeviceLimit(source, name) {
5810
+ const rawValue = source?.[name];
5811
+ if (rawValue === void 0 || rawValue === null) {
5812
+ return 0;
5813
+ }
5814
+ const value = Number(rawValue);
5815
+ if (!Number.isSafeInteger(value) || value < 0) {
5816
+ throw new Error(`${name} must be a non-negative safe integer.`);
5817
+ }
5818
+ return value;
5819
+ }
5820
+ function assertAdapterSupportsRequiredLimit(adapter, name, requiredValue) {
5821
+ const availableValue = Number(adapter?.limits?.[name]);
5822
+ if (!Number.isFinite(availableValue)) {
5823
+ throw new Error(
5824
+ `Wavefront scene buffers require ${name}>=${requiredValue} bytes, but this adapter does not expose that limit.`
5825
+ );
5826
+ }
5827
+ if (availableValue < requiredValue) {
5828
+ throw new Error(
5829
+ `Wavefront scene buffers require ${name}>=${requiredValue} bytes, but this adapter exposes ${availableValue} bytes.`
5830
+ );
5831
+ }
5832
+ }
5675
5833
  function getGpuUsageConstants() {
5676
5834
  if (typeof GPUBufferUsage === "undefined" || typeof GPUTextureUsage === "undefined" || typeof GPUShaderStage === "undefined") {
5677
5835
  throw new Error("WebGPU runtime unavailable. Required GPU constants are missing.");
@@ -5769,8 +5927,13 @@ async function createRenderPipeline(device, descriptor) {
5769
5927
  }
5770
5928
  return device.createRenderPipeline(descriptor);
5771
5929
  }
5772
- function createWavefrontDeviceDescriptor(adapter, options = {}) {
5773
- const requiredLimits = { ...options.requiredLimits ?? {} };
5930
+ function createWavefrontDeviceDescriptor(adapter, options = {}, memory = null) {
5931
+ const descriptor = { ...options.deviceDescriptor ?? {} };
5932
+ const descriptorRequiredLimits = { ...descriptor.requiredLimits ?? {} };
5933
+ const requiredLimits = {
5934
+ ...descriptorRequiredLimits,
5935
+ ...options.requiredLimits ?? {}
5936
+ };
5774
5937
  const exposedStorageBufferLimit = Number(adapter?.limits?.maxStorageBuffersPerShaderStage);
5775
5938
  if (Number.isFinite(exposedStorageBufferLimit)) {
5776
5939
  if (exposedStorageBufferLimit < TRACE_STORAGE_BUFFER_BINDINGS) {
@@ -5795,7 +5958,32 @@ function createWavefrontDeviceDescriptor(adapter, options = {}) {
5795
5958
  TRACE_SAMPLED_TEXTURE_BINDINGS
5796
5959
  );
5797
5960
  }
5798
- const descriptor = { ...options.deviceDescriptor ?? {} };
5961
+ const sceneStorageBufferBindingBytes = Number(
5962
+ memory?.sceneStorageBufferBindingBytes ?? 0
5963
+ );
5964
+ const requestedStorageBufferBindingSize = Math.max(
5965
+ readRequestedDeviceLimit(descriptorRequiredLimits, "maxStorageBufferBindingSize"),
5966
+ readRequestedDeviceLimit(options.requiredLimits, "maxStorageBufferBindingSize"),
5967
+ sceneStorageBufferBindingBytes > WEBGPU_DEFAULT_MAX_STORAGE_BUFFER_BINDING_SIZE ? sceneStorageBufferBindingBytes : 0
5968
+ );
5969
+ if (requestedStorageBufferBindingSize > 0) {
5970
+ assertAdapterSupportsRequiredLimit(
5971
+ adapter,
5972
+ "maxStorageBufferBindingSize",
5973
+ requestedStorageBufferBindingSize
5974
+ );
5975
+ requiredLimits.maxStorageBufferBindingSize = requestedStorageBufferBindingSize;
5976
+ }
5977
+ const requestedMaxBufferSize = Math.max(
5978
+ readRequestedDeviceLimit(descriptorRequiredLimits, "maxBufferSize"),
5979
+ readRequestedDeviceLimit(options.requiredLimits, "maxBufferSize"),
5980
+ sceneStorageBufferBindingBytes > WEBGPU_DEFAULT_MAX_BUFFER_SIZE ? sceneStorageBufferBindingBytes : 0,
5981
+ requestedStorageBufferBindingSize > WEBGPU_DEFAULT_MAX_BUFFER_SIZE ? requestedStorageBufferBindingSize : 0
5982
+ );
5983
+ if (requestedMaxBufferSize > 0) {
5984
+ assertAdapterSupportsRequiredLimit(adapter, "maxBufferSize", requestedMaxBufferSize);
5985
+ requiredLimits.maxBufferSize = requestedMaxBufferSize;
5986
+ }
5799
5987
  const requiredFeatures = Array.from(descriptor.requiredFeatures ?? []);
5800
5988
  const adapterFeatures = adapter?.features;
5801
5989
  const timestampQuerySupported = typeof adapterFeatures?.has === "function" ? adapterFeatures.has("timestamp-query") : adapterFeatures && typeof adapterFeatures[Symbol.iterator] === "function" ? Array.from(adapterFeatures).includes("timestamp-query") : false;
@@ -5846,7 +6034,8 @@ function createGpuAdapterParallelismDiagnostics(adapter, device) {
5846
6034
  maxComputeWorkgroupSizeZ: readGpuLimit(adapter, device, "maxComputeWorkgroupSizeZ"),
5847
6035
  maxComputeWorkgroupsPerDimension: readGpuLimit(adapter, device, "maxComputeWorkgroupsPerDimension"),
5848
6036
  maxStorageBuffersPerShaderStage: readGpuLimit(adapter, device, "maxStorageBuffersPerShaderStage"),
5849
- maxStorageBufferBindingSize: readGpuLimit(adapter, device, "maxStorageBufferBindingSize")
6037
+ maxStorageBufferBindingSize: readGpuLimit(adapter, device, "maxStorageBufferBindingSize"),
6038
+ maxBufferSize: readGpuLimit(adapter, device, "maxBufferSize")
5850
6039
  }),
5851
6040
  configuredWorkgroupSize: WORKGROUP_SIZE
5852
6041
  });
@@ -6256,7 +6445,11 @@ function createWavefrontFrameTelemetryResources({
6256
6445
  const rayCounts = new Uint32Array(rayCopy, 0, recordCount);
6257
6446
  rayCountReadbackBuffer.unmap();
6258
6447
  rayReadbackMapped = false;
6259
- const bounceHistogram = Array.from({ length: Math.max(0, ...bounceIndices) + 1 }, () => 0);
6448
+ let maximumBounceIndex = 0;
6449
+ for (const bounceIndex of bounceIndices) {
6450
+ maximumBounceIndex = Math.max(maximumBounceIndex, bounceIndex);
6451
+ }
6452
+ const bounceHistogram = Array.from({ length: maximumBounceIndex + 1 }, () => 0);
6260
6453
  let observedPrimaryRays = 0;
6261
6454
  let secondaryRays = 0;
6262
6455
  let totalPathSegments = 0;
@@ -11148,7 +11341,9 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11148
11341
  if (!adapter) {
11149
11342
  throw new Error("Unable to acquire a WebGPU adapter for wavefront path tracing.");
11150
11343
  }
11151
- const device = await adapter.requestDevice(createWavefrontDeviceDescriptor(adapter, options));
11344
+ const device = await adapter.requestDevice(
11345
+ createWavefrontDeviceDescriptor(adapter, options, initialConfig.memory)
11346
+ );
11152
11347
  const gpuAdapterParallelism = createGpuAdapterParallelismDiagnostics(adapter, device);
11153
11348
  const context = canvas.getContext("webgpu");
11154
11349
  if (!context || typeof context.configure !== "function") {
@@ -11166,6 +11361,10 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11166
11361
  tileSize: safeTileSize
11167
11362
  });
11168
11363
  }
11364
+ config = Object.freeze({
11365
+ ...config,
11366
+ memory: estimateWavefrontPathTracingMemoryForConfig(config, device.limits)
11367
+ });
11169
11368
  canvas.width = config.width;
11170
11369
  canvas.height = config.height;
11171
11370
  context.configure({
@@ -11174,79 +11373,72 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11174
11373
  alphaMode: options.alpha === true ? "premultiplied" : "opaque"
11175
11374
  });
11176
11375
  const bufferUsage = constants.buffer.STORAGE | constants.buffer.COPY_DST;
11177
- const rayQueueBytes = config.tilePixelCapacity * RAY_RECORD_BYTES;
11178
- const hitBytes = config.tilePixelCapacity * HIT_RECORD_BYTES;
11179
- const accumulationBytes = config.tilePixelCapacity * ACCUMULATION_RECORD_BYTES;
11180
- const pathVertexBytes = config.tilePixelCapacity * (config.maxDepth + 1) * PATH_VERTEX_RECORD_BYTES;
11181
- const activeQueue = createBuffer(device, bufferUsage, rayQueueBytes, "plasius.wavefront.activeQueue");
11182
- const nextQueue = createBuffer(device, bufferUsage, rayQueueBytes, "plasius.wavefront.nextQueue");
11183
- const hitBuffer = createBuffer(device, bufferUsage, hitBytes, "plasius.wavefront.hitBuffer");
11376
+ const memory = config.memory;
11377
+ const activeQueue = createBuffer(device, bufferUsage, memory.queueBytes, "plasius.wavefront.activeQueue");
11378
+ const nextQueue = createBuffer(device, bufferUsage, memory.queueBytes, "plasius.wavefront.nextQueue");
11379
+ const hitBuffer = createBuffer(device, bufferUsage, memory.hitBytes, "plasius.wavefront.hitBuffer");
11184
11380
  const accumulationBuffer = createBuffer(
11185
11381
  device,
11186
11382
  bufferUsage,
11187
- accumulationBytes,
11383
+ memory.accumulationBytes,
11188
11384
  "plasius.wavefront.accumulation"
11189
11385
  );
11190
11386
  const pathVertexBuffer = createBuffer(
11191
11387
  device,
11192
11388
  bufferUsage,
11193
- pathVertexBytes,
11389
+ memory.pathVertexBytes,
11194
11390
  "plasius.wavefront.pathVertices"
11195
11391
  );
11196
11392
  const sceneObjectBuffer = createBuffer(
11197
11393
  device,
11198
11394
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11199
- config.sceneObjectCapacity * SCENE_OBJECT_RECORD_BYTES,
11395
+ memory.sceneObjectBytes,
11200
11396
  "plasius.wavefront.sceneObjects"
11201
11397
  );
11202
11398
  const triangleBuffer = createBuffer(
11203
11399
  device,
11204
11400
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11205
- Math.max(1, config.triangleCapacity) * TRIANGLE_RECORD_BYTES,
11401
+ memory.triangleBytes,
11206
11402
  "plasius.wavefront.triangles"
11207
11403
  );
11208
11404
  const bvhNodeBuffer = createBuffer(
11209
11405
  device,
11210
11406
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11211
- Math.max(1, config.bvhNodeCapacity + config.emissiveTriangleCapacity) * BVH_NODE_RECORD_BYTES,
11407
+ memory.bvhCombinedBytes,
11212
11408
  "plasius.wavefront.bvhNodes"
11213
11409
  );
11214
11410
  const meshVertexBuffer = createBuffer(
11215
11411
  device,
11216
11412
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11217
- Math.max(1, config.gpuMeshSource.vertices.count) * MESH_VERTEX_RECORD_BYTES,
11413
+ memory.meshVertexBytes,
11218
11414
  "plasius.wavefront.meshVertices"
11219
11415
  );
11220
11416
  const meshIndexBuffer = createBuffer(
11221
11417
  device,
11222
11418
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11223
- Math.max(1, config.gpuMeshSource.indices.count) * 4,
11419
+ memory.meshIndexBytes,
11224
11420
  "plasius.wavefront.meshIndices"
11225
11421
  );
11226
11422
  const meshRangeBuffer = createBuffer(
11227
11423
  device,
11228
11424
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11229
- Math.max(1, config.gpuMeshSource.meshes.count) * MESH_RANGE_RECORD_BYTES,
11425
+ memory.meshRangeBytes,
11230
11426
  "plasius.wavefront.meshRanges"
11231
11427
  );
11232
11428
  const environmentPortalBuffer = createBuffer(
11233
11429
  device,
11234
11430
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11235
- Math.max(1, config.environmentPortalCapacity) * ENVIRONMENT_PORTAL_RECORD_BYTES,
11431
+ memory.environmentPortalBytes,
11236
11432
  "plasius.wavefront.environmentPortals"
11237
11433
  );
11238
11434
  const bvhLeafRefBuffer = createBuffer(
11239
11435
  device,
11240
11436
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11241
- Math.max(1, config.bvhLeafSortCapacity) * BVH_LEAF_REF_RECORD_BYTES,
11437
+ memory.bvhLeafReferenceBytes,
11242
11438
  "plasius.wavefront.bvhLeafRefs"
11243
11439
  );
11244
11440
  const tiles = createTiles(config.width, config.height, config.tileSize);
11245
- const uniformOffsetAlignment = Number(device?.limits?.minUniformBufferOffsetAlignment);
11246
- const configBufferStride = alignTo(
11247
- CONFIG_BUFFER_BYTES,
11248
- Number.isFinite(uniformOffsetAlignment) && uniformOffsetAlignment > 0 ? uniformOffsetAlignment : CONFIG_BUFFER_BYTES
11249
- );
11441
+ const configBufferStride = memory.configBufferStride;
11250
11442
  const outputConfigSlotCount = config.deferredPathResolve ? 0 : tiles.length;
11251
11443
  const frameConfigSlotCount = Math.max(
11252
11444
  1,
@@ -11255,26 +11447,25 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11255
11447
  const configBuffer = createBuffer(
11256
11448
  device,
11257
11449
  constants.buffer.UNIFORM | constants.buffer.COPY_DST,
11258
- frameConfigSlotCount * configBufferStride,
11450
+ memory.frameConfigBytes,
11259
11451
  "plasius.wavefront.frameConfig"
11260
11452
  );
11261
- const bvhBuildConfigSlots = 1 + config.bvhSortStages.length + config.bvhBuildLevels.length;
11262
11453
  const bvhBuildConfigBuffer = createBuffer(
11263
11454
  device,
11264
11455
  constants.buffer.UNIFORM | constants.buffer.COPY_DST,
11265
- Math.max(1, bvhBuildConfigSlots) * configBufferStride,
11456
+ memory.bvhBuildConfigBytes,
11266
11457
  "plasius.wavefront.bvhBuildConfig"
11267
11458
  );
11268
11459
  const counterBuffer = createBuffer(
11269
11460
  device,
11270
11461
  constants.buffer.STORAGE | constants.buffer.COPY_DST | constants.buffer.COPY_SRC,
11271
- COUNTER_BUFFER_BYTES,
11462
+ memory.counterBytes,
11272
11463
  "plasius.wavefront.counters"
11273
11464
  );
11274
11465
  const activeDispatchBuffer = createBuffer(
11275
11466
  device,
11276
11467
  constants.buffer.INDIRECT | constants.buffer.COPY_DST,
11277
- INDIRECT_DISPATCH_ARGS_BYTES,
11468
+ memory.indirectDispatchBytes,
11278
11469
  "plasius.wavefront.activeDispatchArgs"
11279
11470
  );
11280
11471
  let packedScene = packWavefrontSceneObjects(config.sceneObjects, config.sceneObjectCapacity);