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 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-19 03:03:17 +02:00
commit 449d5da553
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
4 changed files with 36 additions and 13 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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