[perf] Per-mesh dedicated scratch buffer (VRAM waste) #66

Closed
opened 2026-06-16 16:51:34 +02:00 by jorijnvdgraaf · 0 comments

Subsystem: Mesh / RT acceleration structures
Location: implementations/Crafter.Graphics-Mesh.cpp:90-93, 138
Impact: VRAM waste · Effort: Small (primary fix) · Not hot path (no per-frame scratch alloc)
Builds on: #101 / #102 (fence-keyed deferred-deletion queue — landed)

Problem

Per-mesh dedicated scratch buffer — one persistent DEVICE_LOCAL scratch per mesh. Real VRAM waste, but refits reuse it (no per-frame alloc). For static (!allowUpdate) meshes — the ones that proliferate in many-mesh scenes — the scratch is dead weight the moment the build's GPU work completes.

Proposed fix (primary, small — now unblocked)

Key the release on allowUpdate (already recorded at Mesh.cpp:196): for allowUpdate == false meshes the scratch can never be reused by a refit, so release it after the build. The old hazard — "free after build is a UAF because the GPU is still building" — is solved by the deferred-deletion queue (#102): call scratchBuffer.DeferredClear(), which retires the allocation only once the build's frame has retired past the fence. No explicit ReleaseScratch() hook needed. Refit-capable (allowUpdate == true) meshes keep their scratch as today.

**Subsystem:** Mesh / RT acceleration structures **Location:** `implementations/Crafter.Graphics-Mesh.cpp:90-93, 138` **Impact:** VRAM waste · **Effort:** Small (primary fix) · Not hot path (no per-frame scratch alloc) **Builds on:** #101 / #102 (fence-keyed deferred-deletion queue — landed) ### Problem Per-mesh dedicated scratch buffer — one persistent DEVICE_LOCAL scratch per mesh. Real VRAM waste, but refits reuse it (no per-frame alloc). For static (`!allowUpdate`) meshes — the ones that proliferate in many-mesh scenes — the scratch is dead weight the moment the build's GPU work completes. ### Proposed fix (primary, small — now unblocked) Key the release on `allowUpdate` (already recorded at `Mesh.cpp:196`): for `allowUpdate == false` meshes the scratch can never be reused by a refit, so release it after the build. The old hazard — "free after build is a UAF because the GPU is still building" — is **solved by the deferred-deletion queue (#102)**: call `scratchBuffer.DeferredClear()`, which retires the allocation only once the build's frame has retired past the fence. No explicit `ReleaseScratch()` hook needed. Refit-capable (`allowUpdate == true`) meshes keep their scratch as today.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Catcrafts/Crafter.Graphics#66
No description provided.