Move the offscreen scene target into the render graph #9

Open
opened 2026-09-21 01:31:31 -07:00 by burkkyy · 0 comments
Owner

Summary

The swapchain backbuffer is now rendered through RenderGraph (engine/src/rendering/), but the offscreen scene target still does its own layout transitions and beginRendering/endRendering in Application::Impl::run (engine/src/application.cpp). Move the scene target into the graph so every pass in a frame goes through it.

Background

  • RenderGraph derives barriers and layout transitions from what each pass declares it does to an image (writeColor, sample, use), and begins/ends rendering for passes that write color attachments.
  • Image::transitionLayout now uses the same Access table (engine/src/rendering/access.hpp), so it no longer throws on unlisted layout pairs.
  • The scene target block in application.cpp still calls transitionLayout and beginColorPass by hand, and the backbuffer pass has an if (!sceneTarget) branch to decide whether it also draws the scene.
  • SceneRenderer (engine/src/scene_renderer.hpp) is an empty stub. render() does nothing.
  • The scene target is being reworked separately, so this should be designed together with that rework rather than bolted on first.

Proposal

  • Import the target's image into the graph with final access SampledRead. A "scene" pass writes it; the "ui" pass calls sample() on it and writeColor() on the backbuffer.
  • Replace SceneRenderer::render with addPasses(RenderGraph&, const Scene&, RenderTargetHandle) so the scene renderer registers its own passes.
  • If there is no target, the scene pass writes the backbuffer instead of application.cpp branching.
  • Delete beginColorPass and the manual transitionLayout calls in application.cpp.

Open question: ImGui's reads are dynamic

Panels decide which targets they display during panelRegistry.update, so the ui pass's sample() list has to come from that. Options:

  • The UI reports which targets it displayed this frame, and the graph is built after panelRegistry.update.
  • The ui pass always samples the scene target.

The first is needed once several panels can show different targets. Note ImGui's descriptor assumes eShaderReadOnlyOptimal, which is what Access::SampledRead maps to.

Out of scope

Transient/aliased resources, pass culling and reordering, and depth attachments in PassBuilder. Revisit once there are more passes.

## Summary The swapchain backbuffer is now rendered through `RenderGraph` (`engine/src/rendering/`), but the offscreen scene target still does its own layout transitions and `beginRendering`/`endRendering` in `Application::Impl::run` (`engine/src/application.cpp`). Move the scene target into the graph so every pass in a frame goes through it. ## Background - `RenderGraph` derives barriers and layout transitions from what each pass declares it does to an image (`writeColor`, `sample`, `use`), and begins/ends rendering for passes that write color attachments. - `Image::transitionLayout` now uses the same `Access` table (`engine/src/rendering/access.hpp`), so it no longer throws on unlisted layout pairs. - The scene target block in `application.cpp` still calls `transitionLayout` and `beginColorPass` by hand, and the backbuffer pass has an `if (!sceneTarget)` branch to decide whether it also draws the scene. - `SceneRenderer` (`engine/src/scene_renderer.hpp`) is an empty stub. `render()` does nothing. - The scene target is being reworked separately, so this should be designed together with that rework rather than bolted on first. ## Proposal - Import the target's image into the graph with final access `SampledRead`. A `"scene"` pass writes it; the `"ui"` pass calls `sample()` on it and `writeColor()` on the backbuffer. - Replace `SceneRenderer::render` with `addPasses(RenderGraph&, const Scene&, RenderTargetHandle)` so the scene renderer registers its own passes. - If there is no target, the scene pass writes the backbuffer instead of `application.cpp` branching. - Delete `beginColorPass` and the manual `transitionLayout` calls in `application.cpp`. ## Open question: ImGui's reads are dynamic Panels decide which targets they display during `panelRegistry.update`, so the ui pass's `sample()` list has to come from that. Options: - The UI reports which targets it displayed this frame, and the graph is built after `panelRegistry.update`. - The ui pass always samples the scene target. The first is needed once several panels can show different targets. Note ImGui's descriptor assumes `eShaderReadOnlyOptimal`, which is what `Access::SampledRead` maps to. ## Out of scope Transient/aliased resources, pass culling and reordering, and depth attachments in `PassBuilder`. Revisit once there are more passes.
burkkyy added the enhancement label 2026-09-21 01:31:31 -07:00
burkkyy added this to the sophia project 2026-09-21 01:38:29 -07:00
burkkyy moved this to Blocked / Discussion in sophia on 2026-09-25 20:43:48 -07:00
Sign in to join this conversation.