| .. | ||
| closesthit.glsl | ||
| closesthit.wgsl | ||
| main.cpp | ||
| miss.glsl | ||
| miss.wgsl | ||
| project.cpp | ||
| raygen.glsl | ||
| raygen.wgsl | ||
| README.md | ||
VulkanTriangle
The minimal ray-traced example. Renders a single static triangle through
vkCmdTraceRaysKHR. No UI.
What it shows
Device::Initialize()+Window+ swapchain bring-up.- A
DescriptorHeapVulkansized for one image + one buffer slot, with slot ranges allocated via the bump-allocator API (AllocateImageSlots,AllocateBufferSlots). - A
PipelineRTVulkanbuilt from raygen / miss / closesthit SPIR-V shaders compiled at build time. Mesh::Buildconstructing a BLAS andRenderingElement3D::BuildTLASthe per-frame TLAS.- Direct descriptor writes via
vkWriteResourceDescriptorsEXTfor the swapchain views and TLAS device addresses. RTPass{&pipeline}plugged intowindow.passes— the canonical way to add ray tracing to a window in this library.
It's the smallest sensible test of the bindless VK_EXT_descriptor_heap
- ray-tracing path.
Run
cd examples/VulkanTriangle
crafter-build -r
You should see a 1280×720 window with an RGB-barycentric triangle filling roughly the centre. On the NVIDIA driver this works through an engine-side workaround for a driver fault — see below.
Native status — NVIDIA driver fault, worked around
On NVIDIA driver 610.43.02 (Vulkan 1.4) reading the acceleration
structure through VK_EXT_descriptor_heap aborts the device with
VK_ERROR_DEVICE_LOST on the first frame. This is a driver-side fault
in the brand-new descriptor-heap acceleration-structure path, not an engine
bug (full investigation in #7, summarised below).
The engine works around it transparently (issue #15). On the NVIDIA
proprietary driver only, VulkanShader rewrites the compiled SPIR-V at
module-load time so that every OpLoad of an accelerationStructureEXT
out of the heap becomes a load of the TLAS device address (from a
push-constant block) followed by
OpConvertUToAccelerationStructureKHR — which reads no descriptor and so
never touches the faulting path. RTPass feeds the active frame's TLAS
address in as push data. SPIR-V allows only one push-constant block per
entry point, so when a shader already declares one the TLAS address is
appended to that block (rather than adding a second, which would fail
validation — issue #18); shaders without a push constant get a freshly
synthesized single-member block. raygen.glsl and the example code are
unchanged; acceleration structures still bind into the heap normally. On
every other driver the workaround is inert. It's gated on
Device::workaroundDescriptorHeapAS and confined to one fenced block in
interfaces/Crafter.Graphics-ShaderVulkan.cppm so it can be deleted wholesale
once a fixed NVIDIA driver ships.
The underlying fault (#7)
The fault was traced to the acceleration-structure read through
VK_EXT_descriptor_heap, not to the engine's RT setup:
- The BLAS/TLAS build is correct and finishes before rendering
(
Window::FinishInitdoesvkQueueWaitIdle). The built TLAS instance has an identity transform,mask = 0xFF, and the correct BLAS device address. - The AS descriptor is written correctly —
vkWriteResourceDescriptorsEXTstores the TLAS device address at the expected heap byte offset (verified by dumping the raw heap bytes after the write). - The Khronos validation layers (1.4.350, current) report zero errors
for the whole frame, including the SBT regions handed to
vkCmdTraceRaysKHR. - Storage images and buffers bound through the same descriptor heap
work — with
traceRayEXTremoved, the raygen shader'simageStorerenders correctly, so the heap binding / image path is sound. - Both the ray-tracing pipeline (
traceRayEXT) and inline ray query (rayQueryEXT, which uses no shader binding table) fault identically when they read the acceleration structure from the heap. That isolates the fault to the AS-via-heap read, not the SBT or the RT pipeline. - The fault reproduces even with the AS descriptor written at heap byte 0
and read at shader index 0 (no descriptor offset/stride ambiguity), and
is unaffected by the
pAddressRangesize. VK_EXT_descriptor_heapis brand new; on this machine NVIDIA is the only implementation that advertises it (llvmpipe does not), so there is no second conformant implementation to cross-check against.
Conclusion: this is a driver-side fault in NVIDIA's
VK_EXT_descriptor_heap acceleration-structure path, not an engine bug, and
it should be reported to NVIDIA. Until a fixed driver ships, the SPIR-V
rewrite above keeps the native RT path working; once it does, remove the
workaround and the heap AS read becomes the direct path again.