fix(rt): make BuildTLAS's read barrier a memory dependency

BuildTLAS ended with an execution-only barrier from the
acceleration-structure build to the ray-tracing and compute shader
stages. That orders the commands, but without a memory barrier the
build's writes are never made available and visible to the traceRayEXT
and rayQueryEXT reads recorded after it in the same command buffer,
which is the documented per-frame flow (BuildTLAS in onUpdate, then
RTPass): the trace may read a stale or half-written BVH.

The barrier now carries ACCELERATION_STRUCTURE_WRITE ->
ACCELERATION_STRUCTURE_READ. BuildTlasReadBarrier builds it as pure CPU
logic, so a test can check it without a GPU, as with the swapchain
barriers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-19 03:03:16 +02:00
commit 824436e67c
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
2 changed files with 25 additions and 9 deletions

View file

@ -295,13 +295,6 @@ void RenderingElement3D::BuildTLAS(VkCommandBuffer cmd, std::uint32_t index, RTB
VkAccelerationStructureBuildRangeInfoKHR* tlasRangeInfoPP = &tlasRangeInfo;
Device::vkCmdBuildAccelerationStructuresKHR(cmd, 1, &tlasBuildGeometryInfo, &tlasRangeInfoPP);
vkCmdPipelineBarrier(
cmd,
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0,
0, nullptr,
0, nullptr,
0, nullptr
);
const TlasReadBarrier readBarrier = BuildTlasReadBarrier();
vkCmdPipelineBarrier(cmd, readBarrier.srcStage, readBarrier.dstStage, 0, 1, &readBarrier.memory, 0, nullptr, 0, nullptr);
}