Expose and package temporal rendering with guarded edge history
Native and manual checks / native (ubuntu-24.04) (push) Failing after 37s
Native and manual checks / manual (push) Successful in 27s
Windows editor and software Vulkan / windows-graphics (push) Canceled after 0s
Native and manual checks / native (windows-2025) (push) Canceled after 0s

This commit is contained in:
Emil
2026-09-24 03:59:22 +03:00
parent 0dcc8790a0
commit 7297d01436
19 changed files with 633 additions and 29 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

+6
View File
@@ -12,6 +12,12 @@ On Windows, use `windows-debug` for both presets and `build/windows-debug/faset_
Use the **Visibility** selector to compare **Direct**, **GPU frustum**, and **GPU occlusion** on the same open scene. This is a live renderer setting for the Editor viewport; it does not change the scene or exported game. The selected mode is independent of **Freeze counters**. The counters describe the previous completed frame, so render one more frame after changing modes before reading them. **Effective path** names the algorithm that actually ran. A **Fallback from** line appears when device or target capabilities prevent the selected mode; for example, GPU occlusion may use GPU frustum if HZB is unavailable.
Use the **Temporal** selector for **Off**, **TAA**, or **Upscale**. Upscale shows a
50–99% render-scale slider; output UI remains sharp. The requested/effective
mode, fallback reason, internal extent, history reset reason and temporal GPU
pass times are shown separately from visibility and HZB history. This selector
only changes the live Editor viewport. See [Temporal rendering](temporal.md).
The panel reports the previous completed frame: renderer wall time, GPU timestamp time where available, synchronous readback time, draw calls, packed vertices, culled meshes, textures, explicit Vulkan allocation sizes, actual validation availability/errors, and GPU pass-label count. It also shows whether GPU visibility ran, submitted indirect bins, visible instances, frustum rejects, deferred and post-pass visible instances, HZB history validity, counts per prepared LOD level, and GPU pass timings where available. GPU counts are explicitly marked unavailable until the first frame rendered with diagnostics open; only a displayed zero is a measured zero. **Previous HZB history: invalid** is expected after a camera cut or resize until compatible depth history is available. A current HZB preview can still exist after that first frame because it was built from the current depth. Renderer wall time includes waiting for GPU work; it is not thread CPU usage. Memory excludes driver-internal allocations. The overlay itself adds drawing work, so hide it for a baseline performance measurement.
In **GPU occlusion** mode, enable **Show HZB** to inspect the current grayscale depth pyramid. The **Mip** slider selects a pyramid level; the preview starts at mip 3 to keep its readback small. A larger mip number shows coarser depth. The preview reads the HZB only while the panel and toggle are open, and only once per completed frame or mip change. Switching it off or closing the panel releases the preview; its GPU texture retires when the next frame begins. Opening diagnostics also enables readback of GPU visibility counters, which is disabled again when the panel closes. Disable the HZB preview for performance comparisons: its diagnostic copy and texture upload add GPU and CPU work. **Freeze counters** does not freeze the HZB image.
+26
View File
@@ -118,6 +118,32 @@ and reads back the full image, so `cpu_ms` is wall time including waits, not CPU
utilization. An open scene can run slower with HZB; visibility correctness and
full-frame speed are separate findings.
## Compare temporal modes
Use one scene, output resolution, camera sequence, visibility path, binary and GPU
for Off, TAA and Upscale. Run enough frames to include both the first-frame reset
and steady-state accumulation. Keep the raw captures as well as timing samples:
```sh
./faset_player --headless --frames 240 --profile off.json --temporal off
./faset_player --headless --frames 240 --profile taa.json --temporal taa
./faset_player --headless --frames 240 --profile upscale.json \
--temporal upscale --render-scale 0.67
```
The profile records requested and effective temporal modes, fallback and history
reset reason, internal/output extent, jitter, and valid previous-transform count
per completed frame. `gpu_temporal_resolve_ms`, `gpu_temporal_composite_ms`, and
`gpu_ui_ms` are separate submitted GPU pass times when timestamp queries work;
otherwise they are `null`. `gpu_allocated_bytes` includes live temporal targets
and histories, subject to the allocation limits described above. Compare full
frame GPU and renderer wall time too: scene raster savings can be offset by
resolve, memory and synchronous readback. A valid frame-level history flag says
the previous frame may be sampled, not that every pixel accepted it. For image
quality, inspect a still thin edge, a slow pan and a newly uncovered surface, and
compare the same frame against Off. See [Temporal rendering](temporal.md) for
mode controls and native C++ configuration.
## Current performance scope
The accepted MVP path uses direct draws and CPU culling; P2 adds optional GPU
+54
View File
@@ -0,0 +1,54 @@
# Temporal rendering
Faset renders the scene with **Off** by default. In the optional Editor diagnostics
panel (**F12**), choose **TAA** to accumulate a full-resolution scene over successive
frames, or **Upscale** to render the scene at a lower resolution and reconstruct it
at the output resolution. The Upscale slider accepts 50–99%; 67% is a useful
starting point for visual comparison. UI text and controls always render at output
resolution after the scene resolve. Shadow maps keep their own unjittered views.
The diagnostic selector affects only the current Editor viewport. It does not edit
the scene, gameplay code, or an exported Player. The panel's **Requested** and
**Effective** fields identify a device fallback. It also shows internal and output
extent, whether the previous completed frame's color history was eligible, the
reason it reset, and separate GPU times for resolve, composite and UI where
timestamp queries are available. A reset on the first frame, camera cut, changed
view, resize, scale switch or compatible shader reload is expected. A valid history
does not imply every pixel reused it: newly visible surfaces can still reject
their individual history samples.
For a Player or exported game, select the mode at launch:
```sh
./faset_player --headless --frames 120 --temporal taa --profile taa.json
./faset_player --headless --frames 120 --temporal upscale \
--render-scale 0.67 --profile upscale.json
```
`--temporal` accepts `off`, `taa`, or `upscale`. Off and TAA use scale `1`; Upscale
requires a scale from `0.5` inclusive to `1` exclusive. An invalid mode or scale
stops startup with an error. If Vulkan compute or the required image formats are
unavailable, the renderer falls back to Off and records its effective mode and
reason in the profile. Direct, GPU frustum and GPU occlusion visibility can be
combined with either temporal mode. See [Profiling](profiling.md) for how to compare
their timings fairly.
Native renderer users can make the same choice without modifying gameplay scripts:
```cpp
faset::render::RendererConfig config;
config.temporal_mode = faset::render::TemporalMode::Upscale;
config.render_scale = 0.67f;
faset::render::Renderer renderer(config);
// A live viewport switch recreates scene targets and resets color history.
renderer.set_temporal_mode(faset::render::TemporalMode::TAA);
```
Provide a stable `DrawItem::instance_key` for moving opaque objects so the renderer
can find their previous model transform. Camera cuts must be marked in the
`Snapshot`; cuts, teleports and incompatible projection changes reject old history.
World transparency and sprites use the scene depth/order and reject stale color on
their reactive pixels. TAA and Upscale are optional image-quality paths; compare
them against Off on the actual game scene, especially thin geometry, slow pans,
newly revealed surfaces and moving transparent content.