feat(rt): BuildProcedural/RefitProcedural from a device AABB buffer (#37)
Add zero-copy procedural BLAS overloads that take the AABB build input straight from an existing device buffer instead of memcpy-ing a host span through Mesh::aabbBuffer — the input-source companion to #36's refit work. A GPU compute producer (e.g. a GPU-resident particle system) can now feed a moving procedural BLAS that builds/refits each frame with no host round-trip. Vulkan: new BuildProcedural(VkDeviceAddress, count, ...) and RefitProcedural(VkDeviceAddress, count, ...) feed the device address directly into VkAccelerationStructureGeometryAabbsDataKHR; the host-span path is refactored to share RecordProceduralBuildFromAddress and is otherwise unchanged. WebGPU: device-buffer BuildProcedural/RefitProcedural copy the boxes GPU->GPU into the mesh heap (new wgpuRegisterMeshBLASDeviceAabbs / wgpuRefitMeshBLAS- DeviceAabbs bridge fns) and wrap them in a single root leaf bounded by a caller-supplied worldBounds — no wasm round-trip, blasAddr stable across refit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
00d14d67cb
commit
f14441942a
5 changed files with 306 additions and 21 deletions
|
|
@ -195,6 +195,36 @@ namespace Crafter::WebGPU {
|
|||
const void* attribsPtr, std::int32_t attribsByteCount,
|
||||
std::int32_t geomType, std::int32_t opaqueFlag, std::int32_t primCount);
|
||||
|
||||
// Zero-copy procedural BLAS registration: the AABB build input already
|
||||
// lives in an existing device buffer (`aabbBufferHandle`, a GPUBuffer a
|
||||
// compute pass wrote) rather than a wasm host pointer. The bridge
|
||||
// copyBufferToBuffer's `count` boxes (24 bytes each, [min,max] vec3 — the
|
||||
// RTAabb / VkAabbPositionsKHR layout) straight into the vertices heap,
|
||||
// never round-tripping them through wasm memory. With no host copy of the
|
||||
// boxes there is nothing to run the SAH builder over, so the BLAS gets a
|
||||
// single root leaf spanning all `count` primitives bounded by the
|
||||
// caller-supplied object-space box (min/max) — the traversal then linearly
|
||||
// intersects every box. `opaqueFlag` is the geometry opaque bit. Returns
|
||||
// the mesh handle (0 on failure), same contract as wgpuRegisterMeshBLAS.
|
||||
__attribute__((import_module("env"), import_name("wgpuRegisterMeshBLASDeviceAabbs")))
|
||||
extern "C" std::uint32_t wgpuRegisterMeshBLASDeviceAabbs(
|
||||
WebGPUBufferRef aabbBufferHandle, std::int32_t count,
|
||||
float minX, float minY, float minZ,
|
||||
float maxX, float maxY, float maxZ,
|
||||
std::int32_t opaqueFlag);
|
||||
|
||||
// Zero-copy procedural BLAS refit: re-copy `count` boxes from the device
|
||||
// buffer into the existing mesh's vertices-heap region (count unchanged)
|
||||
// and update the root leaf bounds, preserving the mesh handle so
|
||||
// RTInstance::accelerationStructureReference stays valid. The device
|
||||
// counterpart of Mesh::RefitProcedural.
|
||||
__attribute__((import_module("env"), import_name("wgpuRefitMeshBLASDeviceAabbs")))
|
||||
extern "C" void wgpuRefitMeshBLASDeviceAabbs(
|
||||
std::uint32_t meshHandle,
|
||||
WebGPUBufferRef aabbBufferHandle, std::int32_t count,
|
||||
float minX, float minY, float minZ,
|
||||
float maxX, float maxY, float maxZ);
|
||||
|
||||
// RT pipeline build. The library composes WGSL by concatenating the
|
||||
// traversal library, generated hit-group switches, and the user-
|
||||
// supplied raygen / miss / closesthit / anyhit bodies. `bindings` is
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue