diff --git a/README.md b/README.md index 2cc390f..0b62b8d 100644 --- a/README.md +++ b/README.md @@ -149,13 +149,13 @@ The `manual` example is the reference for the working, pixel-rendering workflow. ## Documentation -The architecture docs live in `docs/tech/` and are written in **French**: +The architecture docs live in `docs/tech/` and are written in **French**. Each document states whether it describes the **current** (implemented) state or the **target** (planned, not yet implemented) architecture: -- [ARCHI_APP](docs/tech/ARCHI_APP.md) — engine architecture. ⚠️ Describes the *target* architecture; the GPU-driven pipeline parts are not implemented yet. -- [ARCHI_CPU_GPU](docs/tech/ARCHI_CPU_GPU.md) — CPU/GPU workload split specification. -- [ARCHI_RENDU](docs/tech/ARCHI_RENDU.md) — update/render mutability model. -- [ARCHI_ARENES](docs/tech/ARCHI_ARENES.md) — planned slotmap-based generational resource handles. -- [FRAME_LOOP](docs/tech/FRAME_LOOP.md) — frame lifetime and resource persistence. +- [ARCHI_APP](docs/tech/ARCHI_APP.md) — engine architecture. 🎯 **Target** — the GPU-driven two-pass pipeline parts are not implemented yet. +- [ARCHI_CPU_GPU](docs/tech/ARCHI_CPU_GPU.md) — CPU/GPU workload split specification. 🎯 **Target** — GPU-driven pipeline, ROADMAP Phase 3. +- [ARCHI_RENDU](docs/tech/ARCHI_RENDU.md) — update/render mutability model. 🎯 **Target** — model for the future scene auto-render. +- [ARCHI_ARENES](docs/tech/ARCHI_ARENES.md) — 🎯 **Target/deferred** — slotmap generational handles; String IDs are used today. +- [FRAME_LOOP](docs/tech/FRAME_LOOP.md) — frame lifetime and resource persistence. ✅ **Current** — implemented. ## Roadmap diff --git a/docs/tech/ARCHI_APP.md b/docs/tech/ARCHI_APP.md index 7c0c155..3be65cd 100644 --- a/docs/tech/ARCHI_APP.md +++ b/docs/tech/ARCHI_APP.md @@ -7,7 +7,7 @@ actor: person/jerome sources: [] generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } verified: true -status: current +status: target stale_after: 2027-01-31 --- @@ -15,6 +15,15 @@ stale_after: 2027-01-31 wsg_lib est un moteur de rendu modulaire basé sur wgpu. Il adopte une architecture à deux niveaux : une façade de haut niveau pour la productivité et un accès bas niveau pour un contrôle total. +> **État du document : CIBLE (architecture visée, en grande partie non implémentée).** +> Les sections §1, §4B, §5 et §6 décrivent la **cible** : pipeline GPU-driven à deux passes +> (Compute Pass → `draw_indexed_indirect`), buffers persistants en VRAM (Transform/Matrix/BBox/Indirect) +> et synchronisation single/double buffer. **Rien de tout cela n'existe encore dans le code** — c'est +> la trajectoire de ROADMAP.md (et README étape 2-3). L'état **réel actuel** est dans README.md : +> workflow manuel uniquement, `Renderer` dessine un objet par soumission, shader en NDC sans MVP. +> La §3 (`App`/`AppHandler`) correspond à l'état actuel, à une nuance près : `render()` ne peut pas +> encore dessiner la scène (l'acquisition/présentation de frame fonctionne, pas le rendu de la scène). + ## 1. Philosophie et Principes - **Abstraction vs Transparence** : Le moteur masque la complexité (wgpu, winit, gestion des Frame) via `App`, tout en exposant les briques élémentaires pour les utilisateurs avancés. diff --git a/docs/tech/ARCHI_ARENES.md b/docs/tech/ARCHI_ARENES.md index abde17b..3816856 100644 --- a/docs/tech/ARCHI_ARENES.md +++ b/docs/tech/ARCHI_ARENES.md @@ -7,7 +7,7 @@ actor: person/jerome sources: [] generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } verified: true -status: current +status: target stale_after: 2027-01-31 --- @@ -15,6 +15,14 @@ stale_after: 2027-01-31 Cette fiche technique détaille l'implémentation recommandée pour gérer efficacement et en toute sécurité les ressources (maillages, textures, matériaux, lumières, etc.) au sein du moteur graphique WSG. Nous utilisons le concept d'**arène générationalle**, implémenté via la crate `slotmap`, pour bénéficier d'IDs stables, de performances optimales, de sécurité accrue et de fonctionnalités avancées comme les `SecondaryMap`. +> **État du document : CIBLE / REPORTÉ (migration future « handles typés »).** +> Ce document décrit la **future** migration vers des identifiants générationnels `slotmap`, reportée +> à l'étape « handles typés » (README Roadmap étape 5). L'état **actuel** de `Scene` utilise des +> **String IDs** (`HashMap>`, etc.) — décision prise dans ROADMAP.md (Notes de +> Décision). La dépendance `slotmap` n'est actuellement **pas** présente dans `lib/Cargo.toml`. +> Ce document ne sera applicable qu'au moment de lancer la migration ; ne suivez pas les extraits de +> code ci-dessous dans l'état actuel du moteur. + ## Objectifs * **Stabilité des IDs :** Garantir que les identifiants (Keys) des ressources restent valides même si d'autres ressources sont supprimées. @@ -48,7 +56,7 @@ Pour renforcer la sécurité, chaque Handle encapsule non seulement un **index** ### Dépendance -Ajoutez `slotmap` à votre `Cargo.toml` : +Ajoutez `slotmap` à votre `Cargo.toml` **uniquement lors de la migration future** (dépendance actuellement non présente dans le projet) : ```toml [dependencies] diff --git a/docs/tech/ARCHI_CPU_GPU.md b/docs/tech/ARCHI_CPU_GPU.md index 4a0c96b..2b30fa3 100644 --- a/docs/tech/ARCHI_CPU_GPU.md +++ b/docs/tech/ARCHI_CPU_GPU.md @@ -7,7 +7,7 @@ actor: person/jerome sources: [] generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } verified: true -status: current +status: target stale_after: 2027-01-31 --- @@ -16,6 +16,14 @@ Bonnes Pratiques & Guide d'Implémentation Ce document sert de spécification technique et de trame d'implémentation pour l'architecture de rendu 3D pilotée par le GPU (GPU-Driven Rendering) utilisant wgpu. L'objectif est de déléguer un maximum de charges de calcul au GPU pour soulager le CPU et maximiser les performances de parallélisme. +> **État du document : CIBLE (spécification du pipeline GPU-driven, non implémenté).** +> La répartition CPU/GPU, le compute pass (World Matrices + Frustum Culling), l'Indirect Draw Buffer +> et les buffers persistants en VRAM décrits ici correspondent à la **Phase 3 du ROADMAP** et aux +> README étapes 2-3. **Aucun de ces mécanismes n'existe encore dans le code.** Aujourd'hui le rendu est +> piloté par le CPU, **objet par objet** (une soumission par mesh, voir README.md et l'exemple `manual`). +> Considérez ce document comme la spécification de référence pour l'implémentation future du pipeline +> GPU-driven, pas comme une description de l'état actuel. + 1. Répartition des Rôles : CPU vs GPU (La Source de Vérité) Pour éviter les goulets d'étranglement dus aux allers-retours sur le bus PCIe, la règle d'or est la suivante : Le CPU est le cerveau logique, le GPU est l'exécutant visuel. diff --git a/docs/tech/ARCHI_RENDU.md b/docs/tech/ARCHI_RENDU.md index f0cef32..5d979ee 100644 --- a/docs/tech/ARCHI_RENDU.md +++ b/docs/tech/ARCHI_RENDU.md @@ -7,7 +7,7 @@ actor: person/jerome sources: [] generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } verified: true -status: current +status: target stale_after: 2027-01-31 --- @@ -15,6 +15,14 @@ stale_after: 2027-01-31 Ce document définit la stratégie de gestion de la mutabilité et des données du moteur wsg_lib, conçue pour maximiser la performance et garantir la sécurité mémoire via Rust. +> **État du document : CIBLE (modèle de mutabilité pour le futur rendu automatisé).** +> Le cycle update/render strict, l'itération **automatique** des entités et `renderer.render_scene()` +> décrits ici ne sont **pas implémentés** : c'est l'**étape 1 du Roadmap README** (scene auto-rendering). +> Aujourd'hui `App::run` acquiert/présente la frame mais `render()` ne peut pas encore dessiner la scène, +> et le `Renderer` ne dessine qu'un objet par soumission, à la main (exemple `manual`). La terminologie +> `MeshId`/`MaterialId` (handles typés) est celle de la **cible** ; l'état actuel utilise des **String IDs** +> dans `Scene`. La dichotomie update/render reste toutefois le modèle de référence retenu pour la suite. + ## 1. La Dichotomie Update / Render Pour éviter les conflits de données et optimiser le pipeline GPU, le moteur sépare strictement le cycle de vie de la frame en deux phases : @@ -57,4 +65,4 @@ Bien que cette architecture facilite la gestion de la mémoire, des règles stri > "Si vous devez changer la position d'un objet ou son matériau, faites-le dans `update()`. Si vous avez besoin d'afficher un élément de debug ou un rendu spécial, faites-le dans `render()`, mais traitez les objets de la scène comme des données en lecture seule." -Cette structure permet au projet d'être extrêmement scalable. L'ajout futur de fonctionnalités (Lumières, Textures, Caméras) ne nécessitera que d'ajouter de nouveaux conteneurs dans la Scene et de mettre à jour le système de tri dans `Renderer::render_scene()`. +Cette structure permet au projet d'être extrêmement scalable. L'ajout futur de fonctionnalités (Lumières, Textures, Caméras) ne nécessitera que d'ajouter de nouveaux conteneurs dans la Scene et de mettre à jour le système de tri dans `Renderer::render_scene()` (méthode à créer — cible de l'étape 1 du Roadmap README). diff --git a/docs/tech/FRAME_LOOP.md b/docs/tech/FRAME_LOOP.md index 031f03b..d0b2400 100644 --- a/docs/tech/FRAME_LOOP.md +++ b/docs/tech/FRAME_LOOP.md @@ -13,11 +13,20 @@ stale_after: 2027-01-31 # La Boucle de Rendu (Frame Loop) -Pour afficher quelque chose, nous suivons un cycle immuable appelé la Frame Lifetime. Dans ton `main.rs` (l'orchestrateur), le flux est désormais le suivant : +> **É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). -- **Context::begin_frame() :** Acquiert la surface texture et crée la TextureView. -- **Renderer::render(...)** : Utilise le CommandEncoder pour écrire les ordres de dessin. -- **Context::end_frame()** : Soumet les commandes à la file (`queue`) et présente l'image. +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. --- @@ -40,6 +49,10 @@ Avec notre nouvelle architecture "Atelier", la distinction est devenue encore pl | 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)** : Les buffers Transform et Matrix sont stockés en VRAM avec un **single buffer** en phase initiale. Le CPU écrit pendant `update()`, le compute shader lit au frame suivant via la séquence garantie par `queue.submit()`. Double buffering sera ajouté uniquement si des artefacts visuels apparaissent à haute fréquence. +> **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). ---