From 449d5da5530690cf88aed6e55c7b7dedd5833864 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Mon, 19 Oct 2026 03:03:17 +0200 Subject: [PATCH] docs: where the NVIDIA descriptor-heap faults stand on 615.78.08 The heap acceleration-structure read still needs the rewrite on 615.78.08; the READMEs say so and point at HeapASRead --no-workaround for checking a newer driver. Dynamic descriptor indexing in hit shaders is fixed there, which the README and the Sponza and SponzaBench notes now say, and the VulkanTriangle investigation no longer contradicts itself about llvmpipe, which advertises VK_EXT_descriptor_heap now. Co-Authored-By: Claude Opus 5.5 --- README.md | 20 ++++++++++++++------ examples/Sponza/README.md | 7 +++++-- examples/SponzaBench/README.md | 4 ++-- examples/VulkanTriangle/README.md | 18 +++++++++++++++--- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8c2d371..642c626 100644 --- a/README.md +++ b/README.md @@ -41,15 +41,23 @@ shaded through an intersection shader with an any-hit cut-out. > reads no descriptor), and `RTPass` supplies the address as push data. > Shaders and example code are unchanged, and it's a single fenced block > gated on `Device::workaroundDescriptorHeapAS`, removable once a fixed -> driver ships. See +> driver ships. **Still present on `615.78.08`**: with the rewrite off, +> `traceRayEXT` still loses the device and an inline ray query renders +> nothing. `tests/HeapASRead` covers the engine path; run +> `HeapASRead --no-workaround` to check a newer driver (it tries both paths +> with the rewrite off). Any app runs with the rewrite off while +> `CRAFTER_GRAPHICS_NO_AS_WORKAROUND` is set, to any value. See > [examples/VulkanTriangle/README.md](examples/VulkanTriangle/README.md) > for the full investigation. WebGPU RT is unaffected. -> **Native RT limitation — dynamic `descriptor_heap` indexing in hit -> shaders:** on the same NVIDIA driver, indexing a `descriptor_heap` -> array with a **runtime (non-constant)** index inside a ray-tracing -> **hit** shader also device-losts (`VK_ERROR_DEVICE_LOST`), for plain -> SSBO **and** sampled-image descriptors. A **constant / spec-constant** +> **Native RT limitation (fixed in NVIDIA `615.78.08`) — dynamic +> `descriptor_heap` indexing in hit shaders:** on NVIDIA `610.43.02`, indexing +> a `descriptor_heap` array with a **runtime (non-constant)** index inside a +> ray-tracing **hit** shader also device-losts (`VK_ERROR_DEVICE_LOST`), for +> plain SSBO **and** sampled-image descriptors. On `615.78.08` it works: +> `tests/HeapDynamicIndexHit` picks a buffer and a texture by a runtime index +> in a closest-hit, including different descriptors in neighbouring lanes of +> a wave. The rest of this note applies to the older drivers. A **constant / spec-constant** > index is fine (that's why [Sponza](examples/Sponza/README.md)'s > closest-hit reads `albedo[albedoSlot]` through a spec constant), and > the identical dynamic pattern works in fragment shaders (the UI diff --git a/examples/Sponza/README.md b/examples/Sponza/README.md index 7ba3d7c..f7a198d 100644 --- a/examples/Sponza/README.md +++ b/examples/Sponza/README.md @@ -20,6 +20,11 @@ below. ## Native RT limitation: dynamic `descriptor_heap` indexing in hit shaders +Fixed in NVIDIA `615.78.08`: `tests/HeapDynamicIndexHit` selects buffers and +textures with a runtime index in a closest-hit, including different +descriptors in neighbouring lanes of a wave. This example still uses the +spec-constant pattern below, which also runs on the older drivers. + On NVIDIA driver `610.43.02` (Vulkan 1.4), indexing a `layout(descriptor_heap)` array with a **runtime (non-constant)** index inside a ray-tracing **hit** shader aborts the device with @@ -122,8 +127,6 @@ This is precisely what the WebGPU path already does — bucketed texture arrays plus a single geometry buffer — so it is a proven, cross-backend pattern, and it sidesteps the NVIDIA RT fault on the native path. -Remove this section once a fixed NVIDIA driver ships and dynamic -`descriptor_heap` indexing in hit shaders stops faulting. ## Asset fetch diff --git a/examples/SponzaBench/README.md b/examples/SponzaBench/README.md index fdf3426..1b79677 100644 --- a/examples/SponzaBench/README.md +++ b/examples/SponzaBench/README.md @@ -20,8 +20,8 @@ exits. `Window::Render()`, reporting per-frame wall-clock stats and throughput. Unlike the interactive Sponza example — which is single-material on native -because of the hit-shader dynamic-`descriptor_heap`-index driver fault -(see `examples/Sponza/README.md`) — SponzaBench's closest-hit shades from +because of the hit-shader dynamic-`descriptor_heap`-index driver fault, fixed +in NVIDIA `615.78.08` (see `examples/Sponza/README.md`) — SponzaBench's closest-hit shades from barycentric coordinates and samples **no** texture, so it can build the **full multi-mesh atrium** (25 mesh groups, ~262 k triangles) as one multi-instance TLAS. The albedo is still decompressed and uploaded during diff --git a/examples/VulkanTriangle/README.md b/examples/VulkanTriangle/README.md index 45f9fd7..6201ff7 100644 --- a/examples/VulkanTriangle/README.md +++ b/examples/VulkanTriangle/README.md @@ -58,6 +58,17 @@ every other driver the workaround is inert. It's gated on `interfaces/Crafter.Graphics-ShaderVulkan.cppm` so it can be deleted wholesale once a fixed NVIDIA driver ships. +### Status on later drivers + +On `615.78.08` the fault is still there. With the rewrite off +(`CRAFTER_GRAPHICS_NO_AS_WORKAROUND` set), `traceRayEXT` still loses the device, +and an inline ray query that reads the TLAS from the heap no longer faults but +renders nothing. Mesa's llvmpipe now advertises `VK_EXT_descriptor_heap` too +and renders the plain heap read correctly, which is a second implementation +backing the conclusion below. `tests/HeapASRead` renders this triangle through +both paths and checks the pixels; `HeapASRead --no-workaround` is the quick +check for a new driver, reporting each path on its own. + ### The underlying fault (#7) The fault was traced to the **acceleration-structure read through @@ -83,9 +94,10 @@ The fault was traced to the **acceleration-structure read through - 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 `pAddressRange` size. -- `VK_EXT_descriptor_heap` is 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. +- `VK_EXT_descriptor_heap` is brand new; at the time NVIDIA was the only + implementation on this machine that advertised it (llvmpipe did not), so + there was no second conformant implementation to cross-check against. + Mesa's llvmpipe has it now; see "Status on later drivers" above. **Conclusion:** this is a driver-side fault in NVIDIA's `VK_EXT_descriptor_heap` acceleration-structure path, not an engine bug, and