The native ray-tracing examples never rewrite their swapchain image descriptors on onResize #171

Open
opened 2026-10-31 14:57:15 +00:00 by jorijnvdgraaf · 0 comments

Summary

Sponza, SponzaBench, RTVolume and VulkanTriangle write window.imageViews[] into their descriptor heaps once, at start-up, and none of them listens to window.onResize. Window rebuilds the swapchain, destroying the old images, on a resize, on an out-of-date acquire and on a suboptimal or out-of-date present, and fires onResize so that passes holding those descriptors can rewrite them (interfaces/Crafter.Graphics-Window.cppm:82-85). After a rebuild, these examples' raygen writes through descriptors of destroyed images. Line numbers refer to 670df31.

Details

Example Writes the views Frames drawn
examples/Sponza/main.cpp :194 one Render(), then StartSync() (:274-275)
examples/RTVolume/main.cpp :189 one (:231-232)
examples/VulkanTriangle/main.cpp :122-134 one (:215-216)
examples/SponzaBench/main.cpp :207 a warm-up and a timed loop of Render() (:254, :262)
  • implementations/Crafter.Graphics-Window.cpp:1269-1278: an out-of-date acquire rebuilds the swapchain, fires onResize and goes on to record the passes in the same Render.
  • :1462-1472: a suboptimal or out-of-date present rebuilds it too. Mesa's Wayland WSI reports suboptimal when the compositor's dmabuf feedback changes, which going fullscreen can do.

So SponzaBench can fault mid-run, and the one-frame examples fault if their single acquire is out of date. The one-frame examples also never draw again, so a resized window shows a stale or undefined frame. That may be fine for a static scene, but these are the examples people copy, and they teach the missing onResize along with it.

Found by reading the code; not reproduced.

Suggested fix

In each example, move the swapchain descriptor writes into a function and call it from an onResize listener as well, as UIRenderer does for its own descriptors. For the one-frame examples, also render again after a resize, or StartUpdate, so the window shows the scene at its new size.

Also, while in Sponza: examples/Sponza/raygen.glsl:11-12 still says its spec constant is "shared with closesthit.glsl". Since 6e94cc6 closesthit's constant_id = 0 is the albedo's image slot, and the host passes each stage its own constants (main.cpp:87-113), so only the comment is wrong.

## Summary Sponza, SponzaBench, RTVolume and VulkanTriangle write `window.imageViews[]` into their descriptor heaps once, at start-up, and none of them listens to `window.onResize`. `Window` rebuilds the swapchain, destroying the old images, on a resize, on an out-of-date acquire and on a suboptimal or out-of-date present, and fires `onResize` so that passes holding those descriptors can rewrite them (`interfaces/Crafter.Graphics-Window.cppm:82-85`). After a rebuild, these examples' raygen writes through descriptors of destroyed images. Line numbers refer to `670df31`. ## Details | Example | Writes the views | Frames drawn | |---|---|---| | `examples/Sponza/main.cpp` | `:194` | one `Render()`, then `StartSync()` (`:274-275`) | | `examples/RTVolume/main.cpp` | `:189` | one (`:231-232`) | | `examples/VulkanTriangle/main.cpp` | `:122-134` | one (`:215-216`) | | `examples/SponzaBench/main.cpp` | `:207` | a warm-up and a timed loop of `Render()` (`:254`, `:262`) | - `implementations/Crafter.Graphics-Window.cpp:1269-1278`: an out-of-date acquire rebuilds the swapchain, fires `onResize` and goes on to record the passes in the same `Render`. - `:1462-1472`: a suboptimal or out-of-date present rebuilds it too. Mesa's Wayland WSI reports suboptimal when the compositor's dmabuf feedback changes, which going fullscreen can do. So SponzaBench can fault mid-run, and the one-frame examples fault if their single acquire is out of date. The one-frame examples also never draw again, so a resized window shows a stale or undefined frame. That may be fine for a static scene, but these are the examples people copy, and they teach the missing `onResize` along with it. Found by reading the code; not reproduced. ## Suggested fix In each example, move the swapchain descriptor writes into a function and call it from an `onResize` listener as well, as `UIRenderer` does for its own descriptors. For the one-frame examples, also render again after a resize, or `StartUpdate`, so the window shows the scene at its new size. Also, while in Sponza: `examples/Sponza/raygen.glsl:11-12` still says its spec constant is "shared with closesthit.glsl". Since 6e94cc6 closesthit's `constant_id = 0` is the albedo's image slot, and the host passes each stage its own constants (`main.cpp:87-113`), so only the comment is wrong.
Sign in to join this conversation.
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#171
No description provided.