feat(vulkan-rt): BLAS build options — fast-build/fast-trace + in-place refit (#36)
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>
This commit is contained in:
parent
27bfb36e60
commit
1a81f115c3
5 changed files with 315 additions and 82 deletions
|
|
@ -271,12 +271,17 @@ namespace {
|
|||
|
||||
void Mesh::Build(std::span<Vector<float, 3, 3>> vertices,
|
||||
std::span<std::uint32_t> indices,
|
||||
WebGPUCommandEncoderRef /*cmd*/) {
|
||||
WebGPUCommandEncoderRef /*cmd*/,
|
||||
RTBuildOptions /*options*/) {
|
||||
// The build preference (FastTrace/FastBuild) and allowUpdate have no
|
||||
// effect on the software-RT path — there is no hardware AS to tune or
|
||||
// refit. The SAH BVH2 is always built the same way.
|
||||
BuildBVHAndRegister(*this, vertices, indices, {});
|
||||
}
|
||||
|
||||
void Mesh::Build(const CompressedMeshAsset& asset,
|
||||
WebGPUCommandEncoderRef /*cmd*/) {
|
||||
WebGPUCommandEncoderRef /*cmd*/,
|
||||
RTBuildOptions /*options*/) {
|
||||
std::vector<Vector<float, 3, 3>> vertices(asset.vertexCount);
|
||||
std::vector<std::uint32_t> indices(asset.indexCount);
|
||||
std::vector<std::byte> dataBytes(
|
||||
|
|
@ -298,7 +303,8 @@ void Mesh::Build(const CompressedMeshAsset& asset,
|
|||
|
||||
void Mesh::BuildProcedural(std::span<const RTAabb> aabbs,
|
||||
bool opaque_,
|
||||
WebGPUCommandEncoderRef /*cmd*/) {
|
||||
WebGPUCommandEncoderRef /*cmd*/,
|
||||
RTBuildOptions /*options*/) {
|
||||
const std::uint32_t count = static_cast<std::uint32_t>(aabbs.size());
|
||||
opaque = opaque_;
|
||||
triangleCount = 0; // not a triangle mesh
|
||||
|
|
@ -335,3 +341,21 @@ void Mesh::BuildProcedural(std::span<const RTAabb> aabbs,
|
|||
/*opaqueFlag*/ opaque ? 1 : 0,
|
||||
/*primCount*/ static_cast<std::int32_t>(count));
|
||||
}
|
||||
|
||||
void Mesh::Refit(std::span<Vector<float, 3, 3>> vertices,
|
||||
std::span<std::uint32_t> indices,
|
||||
WebGPUCommandEncoderRef cmd) {
|
||||
// No hardware AS to update in place — the software path rebuilds the
|
||||
// host BVH and registers it afresh. Unlike the Vulkan UPDATE path, this
|
||||
// assigns a NEW blasAddr (the JS heap append is not in-place), so any
|
||||
// RTInstance::accelerationStructureReference pointing at this mesh must
|
||||
// be re-pointed at the updated mesh.blasAddr afterwards. Refit is far
|
||||
// better suited to the hardware backend; on WebGPU prefer rebuilding
|
||||
// and re-publishing the handle.
|
||||
Build(vertices, indices, cmd);
|
||||
}
|
||||
|
||||
void Mesh::RefitProcedural(std::span<const RTAabb> aabbs,
|
||||
WebGPUCommandEncoderRef cmd) {
|
||||
BuildProcedural(aabbs, opaque, cmd);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue