@plasius/gpu-renderer 0.2.42 → 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
  });
@@ -11152,7 +11341,9 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11152
11341
  if (!adapter) {
11153
11342
  throw new Error("Unable to acquire a WebGPU adapter for wavefront path tracing.");
11154
11343
  }
11155
- const device = await adapter.requestDevice(createWavefrontDeviceDescriptor(adapter, options));
11344
+ const device = await adapter.requestDevice(
11345
+ createWavefrontDeviceDescriptor(adapter, options, initialConfig.memory)
11346
+ );
11156
11347
  const gpuAdapterParallelism = createGpuAdapterParallelismDiagnostics(adapter, device);
11157
11348
  const context = canvas.getContext("webgpu");
11158
11349
  if (!context || typeof context.configure !== "function") {
@@ -11170,6 +11361,10 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11170
11361
  tileSize: safeTileSize
11171
11362
  });
11172
11363
  }
11364
+ config = Object.freeze({
11365
+ ...config,
11366
+ memory: estimateWavefrontPathTracingMemoryForConfig(config, device.limits)
11367
+ });
11173
11368
  canvas.width = config.width;
11174
11369
  canvas.height = config.height;
11175
11370
  context.configure({
@@ -11178,79 +11373,72 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11178
11373
  alphaMode: options.alpha === true ? "premultiplied" : "opaque"
11179
11374
  });
11180
11375
  const bufferUsage = constants.buffer.STORAGE | constants.buffer.COPY_DST;
11181
- const rayQueueBytes = config.tilePixelCapacity * RAY_RECORD_BYTES;
11182
- const hitBytes = config.tilePixelCapacity * HIT_RECORD_BYTES;
11183
- const accumulationBytes = config.tilePixelCapacity * ACCUMULATION_RECORD_BYTES;
11184
- const pathVertexBytes = config.tilePixelCapacity * (config.maxDepth + 1) * PATH_VERTEX_RECORD_BYTES;
11185
- const activeQueue = createBuffer(device, bufferUsage, rayQueueBytes, "plasius.wavefront.activeQueue");
11186
- const nextQueue = createBuffer(device, bufferUsage, rayQueueBytes, "plasius.wavefront.nextQueue");
11187
- 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");
11188
11380
  const accumulationBuffer = createBuffer(
11189
11381
  device,
11190
11382
  bufferUsage,
11191
- accumulationBytes,
11383
+ memory.accumulationBytes,
11192
11384
  "plasius.wavefront.accumulation"
11193
11385
  );
11194
11386
  const pathVertexBuffer = createBuffer(
11195
11387
  device,
11196
11388
  bufferUsage,
11197
- pathVertexBytes,
11389
+ memory.pathVertexBytes,
11198
11390
  "plasius.wavefront.pathVertices"
11199
11391
  );
11200
11392
  const sceneObjectBuffer = createBuffer(
11201
11393
  device,
11202
11394
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11203
- config.sceneObjectCapacity * SCENE_OBJECT_RECORD_BYTES,
11395
+ memory.sceneObjectBytes,
11204
11396
  "plasius.wavefront.sceneObjects"
11205
11397
  );
11206
11398
  const triangleBuffer = createBuffer(
11207
11399
  device,
11208
11400
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11209
- Math.max(1, config.triangleCapacity) * TRIANGLE_RECORD_BYTES,
11401
+ memory.triangleBytes,
11210
11402
  "plasius.wavefront.triangles"
11211
11403
  );
11212
11404
  const bvhNodeBuffer = createBuffer(
11213
11405
  device,
11214
11406
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11215
- Math.max(1, config.bvhNodeCapacity + config.emissiveTriangleCapacity) * BVH_NODE_RECORD_BYTES,
11407
+ memory.bvhCombinedBytes,
11216
11408
  "plasius.wavefront.bvhNodes"
11217
11409
  );
11218
11410
  const meshVertexBuffer = createBuffer(
11219
11411
  device,
11220
11412
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11221
- Math.max(1, config.gpuMeshSource.vertices.count) * MESH_VERTEX_RECORD_BYTES,
11413
+ memory.meshVertexBytes,
11222
11414
  "plasius.wavefront.meshVertices"
11223
11415
  );
11224
11416
  const meshIndexBuffer = createBuffer(
11225
11417
  device,
11226
11418
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11227
- Math.max(1, config.gpuMeshSource.indices.count) * 4,
11419
+ memory.meshIndexBytes,
11228
11420
  "plasius.wavefront.meshIndices"
11229
11421
  );
11230
11422
  const meshRangeBuffer = createBuffer(
11231
11423
  device,
11232
11424
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11233
- Math.max(1, config.gpuMeshSource.meshes.count) * MESH_RANGE_RECORD_BYTES,
11425
+ memory.meshRangeBytes,
11234
11426
  "plasius.wavefront.meshRanges"
11235
11427
  );
11236
11428
  const environmentPortalBuffer = createBuffer(
11237
11429
  device,
11238
11430
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11239
- Math.max(1, config.environmentPortalCapacity) * ENVIRONMENT_PORTAL_RECORD_BYTES,
11431
+ memory.environmentPortalBytes,
11240
11432
  "plasius.wavefront.environmentPortals"
11241
11433
  );
11242
11434
  const bvhLeafRefBuffer = createBuffer(
11243
11435
  device,
11244
11436
  constants.buffer.STORAGE | constants.buffer.COPY_DST,
11245
- Math.max(1, config.bvhLeafSortCapacity) * BVH_LEAF_REF_RECORD_BYTES,
11437
+ memory.bvhLeafReferenceBytes,
11246
11438
  "plasius.wavefront.bvhLeafRefs"
11247
11439
  );
11248
11440
  const tiles = createTiles(config.width, config.height, config.tileSize);
11249
- const uniformOffsetAlignment = Number(device?.limits?.minUniformBufferOffsetAlignment);
11250
- const configBufferStride = alignTo(
11251
- CONFIG_BUFFER_BYTES,
11252
- Number.isFinite(uniformOffsetAlignment) && uniformOffsetAlignment > 0 ? uniformOffsetAlignment : CONFIG_BUFFER_BYTES
11253
- );
11441
+ const configBufferStride = memory.configBufferStride;
11254
11442
  const outputConfigSlotCount = config.deferredPathResolve ? 0 : tiles.length;
11255
11443
  const frameConfigSlotCount = Math.max(
11256
11444
  1,
@@ -11259,26 +11447,25 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11259
11447
  const configBuffer = createBuffer(
11260
11448
  device,
11261
11449
  constants.buffer.UNIFORM | constants.buffer.COPY_DST,
11262
- frameConfigSlotCount * configBufferStride,
11450
+ memory.frameConfigBytes,
11263
11451
  "plasius.wavefront.frameConfig"
11264
11452
  );
11265
- const bvhBuildConfigSlots = 1 + config.bvhSortStages.length + config.bvhBuildLevels.length;
11266
11453
  const bvhBuildConfigBuffer = createBuffer(
11267
11454
  device,
11268
11455
  constants.buffer.UNIFORM | constants.buffer.COPY_DST,
11269
- Math.max(1, bvhBuildConfigSlots) * configBufferStride,
11456
+ memory.bvhBuildConfigBytes,
11270
11457
  "plasius.wavefront.bvhBuildConfig"
11271
11458
  );
11272
11459
  const counterBuffer = createBuffer(
11273
11460
  device,
11274
11461
  constants.buffer.STORAGE | constants.buffer.COPY_DST | constants.buffer.COPY_SRC,
11275
- COUNTER_BUFFER_BYTES,
11462
+ memory.counterBytes,
11276
11463
  "plasius.wavefront.counters"
11277
11464
  );
11278
11465
  const activeDispatchBuffer = createBuffer(
11279
11466
  device,
11280
11467
  constants.buffer.INDIRECT | constants.buffer.COPY_DST,
11281
- INDIRECT_DISPATCH_ARGS_BYTES,
11468
+ memory.indirectDispatchBytes,
11282
11469
  "plasius.wavefront.activeDispatchArgs"
11283
11470
  );
11284
11471
  let packedScene = packWavefrontSceneObjects(config.sceneObjects, config.sceneObjectCapacity);