perf(webgpu): byteCount-bounded readback for over-provisioned buffers (#133) #151
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Catcrafts/Crafter.Graphics!151
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/issue-133"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Resolves #133
Problem
WebGPUBuffer::EnqueueReadback/PollReadbackalways passed the full buffersize, so over-provisioned event-queue buffers copied their full capacity GPU→staging→wasm on every drain even when only a small live prefix held data.Fix
interfaces/Crafter.Graphics-WebGPUBuffer.cppm): add an optionalbyteCountparameter to bothEnqueueReadbackandPollReadback(default0= whole buffer, so existing full-buffer callers are byte-for-byte unchanged). It bounds the readback to the live prefix and is clamped tosize. Callers pass the samebyteCountto the paired poll.additional/dom-webgpu.js): the staging buffer is now sized to the full device-buffer capacity (rather than the first call'sbyteSize), so a prefix length that varies call-to-call never overflows it. ThecopyBufferToBufferandmapAsync/getMappedRangeare bounded to the requested prefix — that is where the copy saving actually lands.Constraint (per the audit note)
Only the fixed header/used prefix is trivially shrinkable here; the live event count is GPU-written and unknown at enqueue, so a fully-dynamic array drain still needs a two-stage readback. This change delivers the trivially-shrinkable prefix case.
Verification
crafter-build test→ 24 passed.RayQueryPick(extended to exercise the new path):hit=1 customIndex=484→ PASS.byteCount=8):hit=1 customIndex=484 prim=0xEEEEEEEE— the first 8 bytes land whileprimitiveIndex(bytes 8–11) keeps its poison sentinel, proving the copy was bounded to the live prefix rather than the full 16-byte capacity → PASS.Backend/memory-path change with no visual output, so no screenshot.
🤖 Generated with Claude Code