Files
wsg/docs/tech/FRAME_LOOP.md
T
Jérôme Bousquié b72c4e43ae docs: align tech/ docs with current vs target state
Clarify for each docs/tech document whether it describes the current
(implemented) or target (planned) architecture, and reconcile with the
readme/roadmap source of truth:

- ARCHI_APP, ARCHI_CPU_GPU, ARCHI_RENDU: mark status=target and add a
  banner stating the GPU-driven two-pass pipeline, persistent VRAM buffers
  and scene auto-render are not implemented (they are ROADMAP Phase 3 /
  README roadmap items 1-3). render() still cannot draw the scene.
- ARCHI_ARENES: status=target/deferred. String IDs are the current design;
  slotmap generational handles are the deferred 'typed handles' step and
  the slotmap dependency is currently absent (supersedes the retired dep).
- FRAME_LOOP: stays status=current; correct the described API flow (Frame
  based via get_next_frame/Renderer::present, plus the low-level
  begin_frame/end_frame variant) and move the single-buffer VRAM note to
  target.
- README: label each tech doc as current or target in the Documentation
  section.
2026-09-14 16:11:42 +02:00

59 lines
3.2 KiB
Markdown

---
type: Technical Specification
title: Frame Loop Architecture
description: Technical specification for the frame loop architecture in wsg_lib, detailing the immutable frame lifetime cycle and resource management
tags: [architecture, rendering, frame-loop, gpu, wgpu]
actor: person/jerome
sources: []
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
verified: true
status: current
stale_after: 2027-01-31
---
# La Boucle de Rendu (Frame Loop)
> **État du document : ACTUEL (implémenté).** Ce document décrit la frame lifetime telle qu'elle est
> réellement implémentée. Il concerne le rendu **CPU-piloté actuel** (objet par objet, exemple `manual`).
> Le pipeline GPU-driven de l'état **visé** est décrit dans ARCHI_APP.md / ARCHI_CPU_GPU.md (cible).
Pour afficher quelque chose, nous suivons un cycle immuable appelé la Frame Lifetime. Deux flux coexistent, tous deux basés sur `Frame` :
**Flux `Frame` (utilisé par `App::run` et l'exemple `manual`) :**
- **`Context::get_next_frame()`** (ou `Frame::try_new(&context.surface)`) : acquiert la surface texture et crée sa `TextureView` (dans `Frame`).
- **`Renderer::render(&view, &mesh, &material)`** : crée un `CommandEncoder`, écrit les ordres de dessin dans la `TextureView`, puis soumet à la file (`queue`).
- **`Renderer::present(frame)`** : présente l'image à l'écran.
**Variante bas niveau (API `Context` brute, sans `Frame`) :**
- **`Context::begin_frame()`** : acquiert la surface et renvoie la `wgpu::SurfaceTexture` (sans vue).
- **`Context::end_frame(surface_texture)`** : soumet et présente cette texture.
---
## Pourquoi cette séparation est vitale
Le bloc `{ let mut render_pass = ... }` est crucial. Dans Rust, `render_pass` emprunte mutablement `encoder`. Il doit être détruit (via la fin du bloc ou un `drop()`) avant que tu puisses appeler `encoder.finish()`. Si tu oublies cela, le compilateur Rust refusera de compiler, empêchant ainsi des bugs critiques de synchronisation GPU.
---
## Ressources : Persistantes vs Par-Frame
Avec notre nouvelle architecture "Atelier", la distinction est devenue encore plus nette :
| Élément | Durée de vie | Pourquoi ? |
|---------|-------------|------------|
| SurfaceConfiguration | Persistante | Ne change qu'au redimensionnement. |
| RenderPipeline | Persistante | Stocké dans le PipelineCache (`Arc`), compilation unique. |
| Material | Persistante | Définit le look ; partage le pipeline via `Arc`. |
| Mesh | Persistante | Les données géométriques sont envoyées une fois au GPU. |
| CommandEncoder | Par-Frame | Ton "carnet de notes" temporaire pour les ordres du GPU. |
| TextureView | Par-Frame | Fenêtre temporaire sur la texture active du swapchain. |
> **Ressources GPU persistantes (single buffer) — CIBLE, non implémenté** : À l'état **visé**, les
> buffers Transform et Matrix vivent en VRAM avec un single buffer en phase initiale (le CPU écrit
> pendant `update()`, le compute shader lit au frame suivant, séquencé par `queue.submit()`), puis un
> double buffering si des artefacts apparaissent à haute fréquence. **Aucune de ces ressources n'existe
> encore dans le code** — c'est la cible GPU-driven (ROADMAP Phase 3 / ARCHI_CPU_GPU).
---