docs(vulkan-rt): document dynamic descriptor_heap-index hit-shader fault (#23) #24

Merged
catbot merged 1 commit from claude/issue-23 into master 2026-06-03 22:05:45 +02:00
Member

Summary

Documents the NVIDIA driver fault from #23: indexing a layout(descriptor_heap) array with a runtime (non-constant) index inside a ray-tracing hit shader device-losts (VK_ERROR_DEVICE_LOST) on driver 610.43.02, for both SSBO and sampled-image descriptors. A constant/spec-constant index is fine, and the same dynamic pattern works in fragment shaders — so it is an RT-stage-specific driver fault, the same family as #7/#15 and #21/#22.

Why documentation, not a transparent workaround

The AS-read fault (#15) is worked around transparently only because an acceleration structure has a device-address path (OpConvertUToAccelerationStructureKHR) and there is exactly one TLAS. Neither holds here:

  • Sampled images have no device-address escape hatch — a texture must be reached through a descriptor, so a dynamic heap texture index cannot be rewritten to avoid dynamic descriptor selection.
  • Buffers could use buffer_reference, but a per-mesh array selected by gl_InstanceCustomIndexEXT would need the engine to maintain/bind an address-table buffer and a SPIR-V rewrite far larger than the single-TLAS case — and it would still leave the texture half broken.

So the engine cannot paper over this; the resolution is the documented-limitation path (the precedent set by #7).

Changes

  • README.md — adds a Native RT limitation note alongside the existing AS-read note, with the recommended pattern and a link to the full write-up.
  • examples/Sponza/README.md — full investigation (isolation steps, why no transparent workaround exists) and the recommended consumer pattern with GLSL: bind one resource and index within it dynamically (single geometry SSBO / buffer_reference at a spec-constant slot; one texture2DArray indexed by layer) rather than selecting a descriptor dynamically. This is exactly what the WebGPU path already does (bucketed texture arrays + a single buffer). Sponza's closest-hit already reads albedo[albedoSlot] through a spec constant for precisely this reason.

Testing

crafter-build testPushConstantRewrite passes. Change is documentation-only (markdown), so no runtime behavior changes.

Resolves #23

## Summary Documents the NVIDIA driver fault from #23: indexing a `layout(descriptor_heap)` array with a **runtime (non-constant)** index inside a ray-tracing **hit** shader device-losts (`VK_ERROR_DEVICE_LOST`) on driver `610.43.02`, for both SSBO and sampled-image descriptors. A constant/spec-constant index is fine, and the same dynamic pattern works in fragment shaders — so it is an **RT-stage-specific** driver fault, the same family as #7/#15 and #21/#22. ## Why documentation, not a transparent workaround The AS-read fault (#15) is worked around transparently only because an acceleration structure has a device-address path (`OpConvertUToAccelerationStructureKHR`) and there is exactly one TLAS. Neither holds here: - **Sampled images have no device-address escape hatch** — a texture must be reached through a descriptor, so a dynamic heap texture index cannot be rewritten to avoid dynamic descriptor selection. - **Buffers** *could* use `buffer_reference`, but a per-mesh array selected by `gl_InstanceCustomIndexEXT` would need the engine to maintain/bind an address-table buffer and a SPIR-V rewrite far larger than the single-TLAS case — and it would still leave the texture half broken. So the engine cannot paper over this; the resolution is the documented-limitation path (the precedent set by #7). ## Changes - **README.md** — adds a *Native RT limitation* note alongside the existing AS-read note, with the recommended pattern and a link to the full write-up. - **examples/Sponza/README.md** — full investigation (isolation steps, why no transparent workaround exists) and the **recommended consumer pattern** with GLSL: bind one resource and index *within* it dynamically (single geometry SSBO / `buffer_reference` at a spec-constant slot; one `texture2DArray` indexed by layer) rather than selecting a descriptor dynamically. This is exactly what the WebGPU path already does (bucketed texture arrays + a single buffer). Sponza's closest-hit already reads `albedo[albedoSlot]` through a spec constant for precisely this reason. ## Testing `crafter-build test` → `PushConstantRewrite` passes. Change is documentation-only (markdown), so no runtime behavior changes. Resolves #23
Indexing a `layout(descriptor_heap)` array with a runtime (non-constant)
index inside a ray-tracing hit shader device-losts on NVIDIA 610.43.02,
for both SSBO and sampled-image descriptors. A constant/spec-constant
index is fine, and the same dynamic pattern works in fragment shaders, so
it's an RT-stage-specific driver fault — the same family as #7/#15
(descriptor-heap AS reads) and #21/#22 (RT recursion + compute TLAS push).

Unlike the AS-read fault, this cannot be worked around transparently: a
sampled image has no device-address escape hatch the way an acceleration
structure does (OpConvertUToAccelerationStructureKHR), and a buffer-only
buffer_reference rewrite would need a whole address-table architecture
while still leaving the texture half broken. So the resolution is the
documented-limitation path (the precedent set by #7).

Records the fault and its isolation in README's Native RT status and in
the Sponza example README (the textured-closest-hit example, which already
reads its albedo through a spec-constant slot for exactly this reason).
Documents the recommended consumer pattern: bind one resource and index
*within* it dynamically (single geometry SSBO / buffer_reference at a
spec-constant slot; one texture2DArray indexed by layer) rather than
selecting a descriptor dynamically — what the WebGPU path already does.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
catbot merged commit f9d23cd1f9 into master 2026-06-03 22:05:45 +02:00
catbot deleted branch claude/issue-23 2026-06-03 22:05:45 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Catcrafts/Crafter.Graphics!24
No description provided.