Skip to main content

Module fullscreen

Module fullscreen 

Source
Expand description

Backend-agnostic fullscreen-pass encoder seam, the first pilot of a hardware abstraction layer over the three render backends. The bloom prefilter -> downsample -> upsample chain is structurally identical on every backend, so its orchestration lives here once and each backend implements BloomEncoder to bind + draw one sub-pass in its own command stream.

Two associated types absorb the only real divergence, so the trait names no backend types: Rec hides the per-backend command recorder, and Args carries the per-invocation binding context (DirectX passes the scene-colour SRV its prefilter samples; Vulkan threads the frame-in-flight index that selects its per-frame framebuffers + descriptor sets). Everything else each impl reads from &self, consistent with the read-only parallel-encode contract.

Implemented by DirectX + Vulkan. Metal keeps its hand-rolled encode_bloom, already factored through its own fullscreen_pass, so this seam is unused (dead code) on a Metal build.

Traits§

BloomEncoder
Per-backend hooks the shared bloom driver encodes through.
CompositeEncoder
The composite pass: tonemap (+ optional LUT grade) the post-stack scene onto the swapchain image, then layer the text overlay on top in the same pass. Its begin -> composite-draw -> text-loop -> end shape is identical on every backend; the swapchain target lifecycle, the descriptor binding, and the text-geometry uploads stay backend-specific behind the trait. Args carries the per-frame binding context each backend needs (DX: the swapchain back-buffer + its RTV, the scene SRV, the window size, the frame slot; VK: the acquired image index + the frame slot).
FullscreenPass
A single-draw fullscreen post pass (SSR resolve, TAA resolve, …): target a render target, bind a pipeline + inputs, draw one fullscreen triangle, restore. Unlike the bloom + composite chains (whose drivers hold a mip / text loop), a fullscreen pass has no loop, so the driver is a fixed begin -> draw -> end. The value is the shared per-backend lifecycle factored behind begin/end (DX: the PSR<->RENDER_TARGET barrier bracket + render-target bind; VK: the render-pass bracket), reused across every such pass instead of re-pasted per pass.

Functions§

align_up
Round offset up to the next multiple of align (a power of two).
clip_rect_to_scissor
Convert a TextDrawCall.clip_rect (a rectangle [x, y, w, h] in overlay units, already mapped through the overlay transform by gfx::text::band_to_window) into an integer scissor rect (x, y, w, h) in attachment pixels, clamped to the attachment’s bounds. Returns None when the clamped rectangle is empty (a row scrolled fully out of its band), so the caller skips the draw entirely.
encode_bloom_chain
The bloom chain orchestration, previously hand-duplicated in each backend’s encode_bloom. On return, mip 0 holds the accumulated glow the composite pass samples.
encode_composite_chain
The composite + text orchestration, previously hand-duplicated in each backend’s encode_composite_and_text. An error mid-text propagates without closing the pass, matching the prior DX/VK behaviour (the frame fails either way: the target is just left mis-stated). This is unused on Metal, where a render encoder must be endEncoding-ed before the command buffer commits: skipping end_composite on a text error would crash at commit, so Metal’s encode_composite_and_text ends the encoder on any ? with a ScopedEncoder RAII guard instead.
encode_fullscreen
The fullscreen-pass orchestration. Trivial by design (a single draw), but kept as a driver so every fullscreen post pass shares one begin -> draw -> end contract across backends, matching encode_bloom_chain / encode_composite_chain.
text_upload_bytes
Total bytes a frame’s text geometry occupies in a backend’s per-frame upload buffer, once each label’s vertex and index blocks start on an align-byte boundary. Every sub-allocation aligns its start up and a prior aligned start plus an aligned size stays aligned, so this sum is an exact upper bound on the buffer cursor after all of a frame’s blocks are appended: a slot reserved to it can never overflow mid-frame.