feat(vulkan-rt): Mesh::BuildProcedural — AABB (procedural) BLAS build path (#33)
Adds the native counterpart of the WebGPU Mesh::BuildProcedural: uploads the boxes as a 24-byte-stride VkAabbPositionsKHR-compatible device buffer (AS-build-input read-only + device address) and builds the BLAS from one VK_GEOMETRY_TYPE_AABBS_KHR geometry. opaque maps to VK_GEOMETRY_OPAQUE_BIT_KHR, default-false semantics matching the WebGPU path so any-hit shaders run. The BLAS sizing/create/build tail is factored into a geometry-type-agnostic helper shared with the triangle path; no TLAS/instance changes needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c608d75a36
commit
a9e42f9c90
2 changed files with 88 additions and 26 deletions
|
|
@ -39,31 +39,10 @@ namespace {
|
|||
constexpr VkBufferUsageFlags2 kIndexUsageBase =
|
||||
kVertexUsageBase | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
|
||||
void RecordBLASBuild(Mesh& self, std::uint32_t vertexCount, std::uint32_t indexCount, VkCommandBuffer cmd) {
|
||||
VkDeviceOrHostAddressConstKHR vertexAddr;
|
||||
vertexAddr.deviceAddress = self.vertexBuffer.address;
|
||||
|
||||
VkDeviceOrHostAddressConstKHR indexAddr;
|
||||
indexAddr.deviceAddress = self.indexBuffer.address;
|
||||
|
||||
auto trianglesData = VkAccelerationStructureGeometryTrianglesDataKHR {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
|
||||
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.vertexData = vertexAddr,
|
||||
.vertexStride = sizeof(Vector<float, 3, 3>),
|
||||
.maxVertex = vertexCount - 1,
|
||||
.indexType = VK_INDEX_TYPE_UINT32,
|
||||
.indexData = indexAddr,
|
||||
.transformData = {.deviceAddress = 0}
|
||||
};
|
||||
VkAccelerationStructureGeometryDataKHR geometryData(trianglesData);
|
||||
VkAccelerationStructureGeometryKHR blasGeometry {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
|
||||
.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR,
|
||||
.geometry = geometryData,
|
||||
.flags = VK_GEOMETRY_OPAQUE_BIT_KHR
|
||||
};
|
||||
|
||||
// Shared BLAS sizing / creation / build-record tail — geometry-type
|
||||
// agnostic; both the triangle and the AABB (procedural) paths feed
|
||||
// their single geometry through here.
|
||||
void RecordBLASBuildFromGeometry(Mesh& self, const VkAccelerationStructureGeometryKHR& blasGeometry, std::uint32_t primitiveCount, VkCommandBuffer cmd) {
|
||||
VkAccelerationStructureBuildGeometryInfoKHR blasBuildGeometryInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
|
||||
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
|
||||
|
|
@ -72,7 +51,6 @@ namespace {
|
|||
.pGeometries = &blasGeometry,
|
||||
};
|
||||
|
||||
auto primitiveCount = indexCount / 3;
|
||||
VkAccelerationStructureBuildSizesInfoKHR blasBuildSizes = {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR
|
||||
};
|
||||
|
|
@ -122,6 +100,34 @@ namespace {
|
|||
};
|
||||
self.blasAddr = Device::vkGetAccelerationStructureDeviceAddressKHR(Device::device, &addrInfo);
|
||||
}
|
||||
|
||||
void RecordBLASBuild(Mesh& self, std::uint32_t vertexCount, std::uint32_t indexCount, VkCommandBuffer cmd) {
|
||||
VkDeviceOrHostAddressConstKHR vertexAddr;
|
||||
vertexAddr.deviceAddress = self.vertexBuffer.address;
|
||||
|
||||
VkDeviceOrHostAddressConstKHR indexAddr;
|
||||
indexAddr.deviceAddress = self.indexBuffer.address;
|
||||
|
||||
auto trianglesData = VkAccelerationStructureGeometryTrianglesDataKHR {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
|
||||
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.vertexData = vertexAddr,
|
||||
.vertexStride = sizeof(Vector<float, 3, 3>),
|
||||
.maxVertex = vertexCount - 1,
|
||||
.indexType = VK_INDEX_TYPE_UINT32,
|
||||
.indexData = indexAddr,
|
||||
.transformData = {.deviceAddress = 0}
|
||||
};
|
||||
VkAccelerationStructureGeometryDataKHR geometryData(trianglesData);
|
||||
VkAccelerationStructureGeometryKHR blasGeometry {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
|
||||
.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR,
|
||||
.geometry = geometryData,
|
||||
.flags = VK_GEOMETRY_OPAQUE_BIT_KHR
|
||||
};
|
||||
|
||||
RecordBLASBuildFromGeometry(self, blasGeometry, indexCount / 3, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::Build(std::span<Vector<float, 3, 3>> verticies, std::span<std::uint32_t> indicies, VkCommandBuffer cmd) {
|
||||
|
|
@ -203,3 +209,32 @@ void Mesh::Build(const CompressedMeshAsset& asset, VkCommandBuffer cmd) {
|
|||
RecordBLASBuild(*this, asset.vertexCount, asset.indexCount, cmd);
|
||||
}
|
||||
|
||||
void Mesh::BuildProcedural(std::span<const RTAabb> aabbs, bool opaque, VkCommandBuffer cmd) {
|
||||
this->opaque = opaque;
|
||||
|
||||
// 24-byte-stride VkAabbPositionsKHR-compatible build input
|
||||
// (static_assert'd in the interface). Same usage set as the triangle
|
||||
// inputs: AS-build read-only + device address.
|
||||
aabbBuffer.Resize(kVertexUsageBase, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, static_cast<std::uint32_t>(aabbs.size()));
|
||||
std::memcpy(aabbBuffer.value, aabbs.data(), aabbs.size() * sizeof(RTAabb));
|
||||
aabbBuffer.FlushDevice(cmd, VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR);
|
||||
|
||||
VkAccelerationStructureGeometryAabbsDataKHR aabbsData {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR,
|
||||
.data = { .deviceAddress = aabbBuffer.address },
|
||||
.stride = sizeof(RTAabb)
|
||||
};
|
||||
VkAccelerationStructureGeometryDataKHR geometryData;
|
||||
geometryData.aabbs = aabbsData;
|
||||
VkAccelerationStructureGeometryKHR blasGeometry {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
|
||||
.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR,
|
||||
.geometry = geometryData,
|
||||
// Non-opaque by default (mirrors the WebGPU path) so any-hit
|
||||
// shaders run for procedural geometry unless the caller opts out.
|
||||
.flags = opaque ? static_cast<VkGeometryFlagsKHR>(VK_GEOMETRY_OPAQUE_BIT_KHR) : VkGeometryFlagsKHR{}
|
||||
};
|
||||
|
||||
RecordBLASBuildFromGeometry(*this, blasGeometry, static_cast<std::uint32_t>(aabbs.size()), cmd);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue