test(rt): read the TLAS from the descriptor heap, with a probe for the NVIDIA fault

HeapASRead renders a triangle, tracing half the frame with traceRayEXT
and ray querying the other half, both reading the TLAS out of the
descriptor heap, and checks the read-back pixels. The test runner runs
it through the engine's normal path, so on NVIDIA it covers the rewrite
too: an inherited CRAFTER_GRAPHICS_NO_AS_WORKAROUND is cleared, and the
test checks the rewrite is on exactly where the driver needs it.

HeapASRead --no-workaround is the check for a newer driver. Each path
renders in its own child process with the rewrite off and validation
off (GPU-assisted validation instruments the shaders), so a device loss
on one doesn't hide the other. On 615.78.08 traceRayEXT still loses the
device and the ray query renders nothing.

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

View file

@ -439,6 +439,38 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
parityImpls.emplace_back("tests/UIFallbackParity/main");
up.GetInterfacesAndImplementations(ifaces, parityImpls);
cfg.tests.push_back(std::move(parityTest));
// Reading the TLAS from the descriptor heap (#7/#15): renders a
// triangle through traceRayEXT and an inline ray query and checks
// the read-back pixels, through the engine's normal path (so on
// NVIDIA through the SPIR-V rewrite). `HeapASRead --no-workaround`
// is the manual probe for whether a driver still has the fault.
// Needs the Wayland backend, a real compositor and an RT device
// (skips without RT).
Test heapAsTest;
Configuration& ha = heapAsTest.config;
ha.path = cfg.path;
ha.name = "HeapASRead";
ha.outputName = "HeapASRead";
ha.type = ConfigurationType::Executable;
ha.target = cfg.target;
ha.march = cfg.march;
ha.mtune = cfg.mtune;
ha.debug = cfg.debug;
ha.sysroot = cfg.sysroot;
ha.dependencies = cfg.dependencies;
ha.externalDependencies = cfg.externalDependencies;
ha.compileFlags = cfg.compileFlags;
ha.linkFlags = cfg.linkFlags;
ha.defines = cfg.defines;
ha.cFiles = cfg.cFiles;
ha.shaders.emplace_back(fs::path("tests/HeapASRead/heapas-raygen.glsl"), std::string("main"), ShaderType::RayGen);
ha.shaders.emplace_back(fs::path("tests/HeapASRead/heapas-closesthit.glsl"), std::string("main"), ShaderType::ClosestHit);
ha.shaders.emplace_back(fs::path("tests/HeapASRead/heapas-miss.glsl"), std::string("main"), ShaderType::Miss);
std::vector<fs::path> heapAsImpls(impls.begin(), impls.end());
heapAsImpls.emplace_back("tests/HeapASRead/main");
ha.GetInterfacesAndImplementations(ifaces, heapAsImpls);
cfg.tests.push_back(std::move(heapAsTest));
}
// Issue #36: BLAS build options. Drives the real hardware AS-build