feat(vulkan-rt): BLAS build options — fast-build/fast-trace + in-place refit (#36) #38

Merged
catbot merged 2 commits from claude/issue-36 into master 2026-06-16 15:38:35 +02:00
Member

Resolves #36.

BLAS builds can now be tuned and refit.

API

Mesh::Build / Mesh::BuildProcedural take an RTBuildOptions:

struct RTBuildOptions {
    RTBuildPreference preference = RTBuildPreference::FastTrace; // or FastBuild
    bool              allowUpdate = false;                       // enable refit
};
  • preferenceVK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR (default, slower build / faster traversal) or …PREFER_FAST_BUILD_BIT_KHR.
  • allowUpdateVK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, required before a BLAS can be refit.

New Mesh::Refit(verts, indices, cmd) / Mesh::RefitProcedural(aabbs, cmd):

  • When the original build opted into allowUpdate and the topology is unchanged, they record an in-place UPDATE-mode build (src == dst) — much cheaper than a rebuild, and the AS handle + blasAddr are preserved so TLAS instances referencing the mesh stay valid. This mirrors the existing TLAS refit path.
  • Otherwise (no allowUpdate, or vertex/primitive count changed) they fall back to a full rebuild.

The shared build tail also now destroys a stale AS handle on re-Build (it was previously leaked) and guards the in-place update with an acceleration-structure read→write barrier.

Cross-backend

The portable RTBuildPreference / RTBuildOptions types and the Refit / RefitProcedural methods also exist on the WebGPU backend so portable code compiles unchanged. The software BVH has no hardware AS, so the preference is a no-op and a "refit" rebuilds the host BVH (documented: this re-registers the handle, unlike the in-place Vulkan path).

Testing

crafter-build test — 3 passed (MouseScroll, PushConstantRewrite, BLASBuildOptions).

The new BLASBuildOptions test drives the real hardware AS-build path on the GPU (headless — a BLAS build only needs the queue + command pool). It builds and refits both triangle and procedural BLASes and asserts:

  • the requested preference + ALLOW_UPDATE bits land in Mesh::buildFlags;
  • an allowUpdate refit keeps the same AS handle and blasAddr (proves the in-place UPDATE path);
  • the no-update / topology-change fallback still produces a valid BLAS;
  • the Vulkan validation layer reports zero errors across all builds/refits — verified against VK_LAYER_KHRONOS_validation on an RTX 4090.

To support that last check, Device::validationErrorCount now counts ERROR-severity debug-messenger messages.

🤖 Generated with Claude Code

Resolves #36. BLAS builds can now be tuned and refit. ## API `Mesh::Build` / `Mesh::BuildProcedural` take an `RTBuildOptions`: ```cpp struct RTBuildOptions { RTBuildPreference preference = RTBuildPreference::FastTrace; // or FastBuild bool allowUpdate = false; // enable refit }; ``` - `preference` → `VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR` (default, slower build / faster traversal) or `…PREFER_FAST_BUILD_BIT_KHR`. - `allowUpdate` → `VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR`, required before a BLAS can be refit. New `Mesh::Refit(verts, indices, cmd)` / `Mesh::RefitProcedural(aabbs, cmd)`: - When the original build opted into `allowUpdate` and the topology is unchanged, they record an **in-place `UPDATE`-mode build** (`src == dst`) — much cheaper than a rebuild, and the AS handle + `blasAddr` are preserved so TLAS instances referencing the mesh stay valid. This mirrors the existing TLAS refit path. - Otherwise (no `allowUpdate`, or vertex/primitive count changed) they fall back to a full rebuild. The shared build tail also now destroys a stale AS handle on re-`Build` (it was previously leaked) and guards the in-place update with an acceleration-structure read→write barrier. ## Cross-backend The portable `RTBuildPreference` / `RTBuildOptions` types and the `Refit` / `RefitProcedural` methods also exist on the WebGPU backend so portable code compiles unchanged. The software BVH has no hardware AS, so the preference is a no-op and a "refit" rebuilds the host BVH (documented: this re-registers the handle, unlike the in-place Vulkan path). ## Testing `crafter-build test` — 3 passed (`MouseScroll`, `PushConstantRewrite`, **`BLASBuildOptions`**). The new `BLASBuildOptions` test drives the real hardware AS-build path on the GPU (headless — a BLAS build only needs the queue + command pool). It builds and refits both triangle and procedural BLASes and asserts: - the requested preference + `ALLOW_UPDATE` bits land in `Mesh::buildFlags`; - an `allowUpdate` refit keeps the same AS handle and `blasAddr` (proves the in-place `UPDATE` path); - the no-update / topology-change fallback still produces a valid BLAS; - **the Vulkan validation layer reports zero errors** across all builds/refits — verified against `VK_LAYER_KHRONOS_validation` on an RTX 4090. To support that last check, `Device::validationErrorCount` now counts ERROR-severity debug-messenger messages. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Mesh::Build / BuildProcedural now take an RTBuildOptions { preference,
allowUpdate }. `preference` maps to PREFER_FAST_TRACE (default) or
PREFER_FAST_BUILD; `allowUpdate` sets ALLOW_UPDATE so the BLAS can be
refit later.

Adds Mesh::Refit / RefitProcedural: when the original build opted into
allowUpdate and the topology is unchanged, they record an in-place
UPDATE-mode build (src == dst) — much cheaper than a rebuild, and the
AS handle + blasAddr are preserved so TLAS instances stay valid. They
fall back to a full rebuild otherwise. The shared build tail also now
destroys a stale AS handle on re-Build (previously leaked) and guards
the in-place update with an AS read→write barrier.

The portable RTBuildPreference/RTBuildOptions types and Refit methods
also exist on the WebGPU backend for API symmetry; the software BVH has
no hardware AS, so the preference is a no-op and a "refit" rebuilds the
BVH (re-registering the handle).

Also adds Device::validationErrorCount, bumped by the debug-messenger
callback on ERROR-severity messages, so tests can assert a Vulkan
operation produced no validation errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Exercises the real hardware AS-build path: builds and refits triangle
and procedural BLASes with fast-build/fast-trace + allow-update flags
via one-time command buffers, asserting the requested flags land, that
an allowUpdate refit keeps the same AS handle/blasAddr (in-place
UPDATE), that the no-update / topology-change fallback still produces a
valid BLAS, and that the validation layer reports zero errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
catbot merged commit e3940d99c3 into master 2026-06-16 15:38:35 +02:00
catbot deleted branch claude/issue-36 2026-06-16 15:38:35 +02:00
Sign in to join this conversation.
No reviewers
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!38
No description provided.