test(rt): BuildTLAS's read barrier makes the build visible to TLAS reads

TLASBuildBarrier drives BuildTlasReadBarrier with no GPU device: the
dependency starts at the acceleration-structure build, reaches the
ray-tracing and compute shader stages, and carries the
acceleration-structure write -> read memory dependency that the old
execution-only barrier lacked.

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 5d25c1f825
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
2 changed files with 77 additions and 0 deletions

View file

@ -0,0 +1,51 @@
//SPDX-License-Identifier: LGPL-3.0-only
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
// The dependency RenderingElement3D::BuildTLAS records after its build, which
// orders the build before the shaders that read the TLAS: traceRayEXT in a
// ray-tracing pass, rayQueryEXT in a compute pass, recorded after it in the
// same command buffer (BuildTLAS in onUpdate, then RTPass, is the documented
// per-frame flow). It used to be an execution-only barrier with no memory
// barrier, which orders the commands but never makes the build's
// acceleration-structure writes available and visible to those reads. The
// dependency is built by BuildTlasReadBarrier, pure CPU logic that this test
// drives directly with no GPU device, like SwapchainBarrierScope.
#include <cstdlib>
#include "vulkan/vulkan.h"
import Crafter.Graphics;
import std;
using namespace Crafter;
namespace {
int failures = 0;
void Check(bool ok, std::string_view what) {
std::println("{} {}", ok ? "PASS" : "FAIL", what);
if (!ok) ++failures;
}
} // namespace
int main() {
const TlasReadBarrier barrier = BuildTlasReadBarrier();
Check(barrier.srcStage == VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
"the dependency starts at the acceleration-structure build");
Check((barrier.dstStage & VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR) != 0,
"it reaches ray-tracing shaders (traceRayEXT)");
Check((barrier.dstStage & VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) != 0,
"it reaches compute shaders (rayQueryEXT)");
Check(barrier.memory.sType == VK_STRUCTURE_TYPE_MEMORY_BARRIER, "it carries a memory barrier");
Check((barrier.memory.srcAccessMask & VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR) != 0,
"the build's acceleration-structure writes are made available");
Check((barrier.memory.dstAccessMask & VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR) != 0,
"and visible to acceleration-structure reads");
std::println("{}", failures == 0 ? "all checks passed" : "check(s) failed");
return failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}