From db35e78eaf7a6da2efb5c296fa8e6d79be6c6835 Mon Sep 17 00:00:00 2001 From: catbot Date: Thu, 18 Jun 2026 13:56:21 +0000 Subject: [PATCH] perf(webgpu): range-flush only live TLAS metadata slots (#130) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The metadata mirror is padded to kNPadded (65536) but only primitiveCount slots are live. metadataBuffer.FlushDevice() wgpuWriteBuffer'd all 256 KB through the WASM->JS staging path every frame (~100-250x waste for a few-hundred-instance scene). Switch to the existing FlushDeviceRange overload — the same one the instanceBuffer loop directly above uses — sized to primitiveCount * sizeof(uint32_t). The Vulkan parallel already sizes its flush to primitiveCount, so this was WebGPU-specific. Co-Authored-By: Claude Opus 4.8 --- .../Crafter.Graphics-RenderingElement3D-WebGPU.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/implementations/Crafter.Graphics-RenderingElement3D-WebGPU.cpp b/implementations/Crafter.Graphics-RenderingElement3D-WebGPU.cpp index 326f049..2cafd67 100644 --- a/implementations/Crafter.Graphics-RenderingElement3D-WebGPU.cpp +++ b/implementations/Crafter.Graphics-RenderingElement3D-WebGPU.cpp @@ -159,7 +159,11 @@ void RenderingElement3D::BuildTLASUpload(WebGPUCommandEncoderRef /*cmd*/, std::u runOwned = currOwned; } - tlas.metadataBuffer.FlushDevice(); + // Only primitiveCount slots are live; the buffer is padded to kNPadded + // (65536). Flushing the whole thing wgpuWriteBuffers all 256 KB through + // the WASM->JS staging path every frame — ~100-250x waste for a + // few-hundred-instance scene. Range-flush just the live entries. + tlas.metadataBuffer.FlushDeviceRange(0, 0, primitiveCount * sizeof(std::uint32_t)); } void RenderingElement3D::BuildTLASBuild(WebGPUCommandEncoderRef /*cmd*/, std::uint32_t index) {