Merge pull request 'perf(rt): place SBT in device-local memory via upload-strategy helper (#72)' (#107) from claude/issue-72 into master

This commit is contained in:
catbot 2026-06-17 19:42:02 +02:00
commit 87264bb2ec

View file

@ -103,7 +103,30 @@ export namespace Crafter {
hitRegion.size = hitGroups.size() * sbtStride; hitRegion.size = hitGroups.size() * sbtStride;
std::size_t bufferSize = hitRegion.deviceAddress + hitRegion.size; std::size_t bufferSize = hitRegion.deviceAddress + hitRegion.size;
sbtBuffer.Create(VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferSize); // The SBT is written once here (the memcpys below) and read by the
// GPU on every vkCmdTraceRaysKHR for the pipeline's lifetime — the
// textbook write-once/read-many buffer (issue #72). Get it into
// device-local memory so trace dispatches read raygen/miss/hit
// records out of VRAM instead of over PCIe from system RAM.
//
// Route the placement through #89: when a DEVICE_LOCAL|HOST_VISIBLE
// type exists (ReBAR/UMA, or a BAR window — the SBT is tiny so the
// window budget is never the constraint), prefer DEVICE_LOCAL on top
// of the required HOST_VISIBLE so the allocation lands in device
// memory we can still map. The one-time memcpy goes write-combined
// over PCIe (write-only, sequential — ideal); GPU reads then hit
// local VRAM. When no combined type exists at all (no spec
// guarantee), PreferDirectDeviceWrite returns false and the preferred
// hint is dropped, so GetMemoryType falls back to plain HOST_VISIBLE
// (current behaviour, the per-trace PCIe read) — the cheaper fallback
// the issue blesses while staging isn't wired here.
//
// Either way the buffer stays mapped, and the FlushDevice below gates
// its flush on the *chosen* memory type's flags (issue #60), so a
// direct-write type lacking HOST_COHERENT is still flushed correctly.
VkMemoryPropertyFlags sbtPreferred = Device::PreferDirectDeviceWrite(bufferSize)
? VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0;
sbtBuffer.Create(VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferSize, sbtPreferred);
std::uint8_t* offset = sbtBuffer.value; std::uint8_t* offset = sbtBuffer.value;
std::uint8_t* handleOffset = shaderHandles.data(); std::uint8_t* handleOffset = shaderHandles.data();