Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion docs/DEVELOPMENT_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ See [CSHARP.md](CSHARP.md). Lua `Engine.*` bindings register on the **client** w

### FreeUSD (default ON)

`USE_FREEUSD=ON` is the CMake default. The library lives in the **Git submodule** `src/external/FreeUSD` ([gopexllc/FreeUSD](https://github.com/gopexllc/FreeUSD)); `./scripts/compile_engine.sh` runs `git submodule update --init` when needed. If the submodule is missing, CMake **FetchContent** can fetch the same pin (network). Init manually with `./scripts/init_optional_submodules.sh --freeusd`. Disable with `./scripts/compile_engine.sh vulkan nofreeusd` or `-DUSE_FREEUSD=OFF`.
`USE_FREEUSD=ON` is the CMake default. The library lives in the **Git submodule** `third_party/FreeUSD` ([gopexllc/FreeUSD](https://github.com/gopexllc/FreeUSD)); `./scripts/compile_engine.sh` runs `git submodule update --init` when needed. If the submodule is missing, CMake **FetchContent** can fetch the same pin (network). Init manually with `./scripts/init_optional_submodules.sh --freeusd`. Disable with `./scripts/compile_engine.sh vulkan nofreeusd` or `-DUSE_FREEUSD=OFF`.

See [FREEUSD.md](FREEUSD.md) for mesh import cvars (`r_freeusd`, `r_freeusdPickLargest`, …) and console tools (`usd_info`, `usd_meshes`, `usd_load`, …). Test USDA files: `tests/data/usd/`.

Expand Down Expand Up @@ -304,6 +304,24 @@ cd build-vk-Release && ctest -C Release --output-on-failure
ctest --preset test-vulkan-release
```

### Renderer Spine static checks (headless)

For Vulkan renderer, G-buffer, Ambient Visibility, temporal-history, and profile-contract changes, run the Spine static gates before GPU work:

```bash
./scripts/spine_stability_check.sh # umbrella: profiles + gbuffer/AV + temporal + WBOIT guards
./scripts/gbuffer_av_lifecycle_check.sh # G-buffer / AV soft-fail, presentation teardown/restore
./scripts/temporal_ownership_check.sh # shared temporal resets, weapon-after-TAA, portal isolation
```

These scripts grep source contracts only (no GPU). In-game diagnostics after boot or `vid_restart`:

```cfg
exec demo_gbuffer_av_lifecycle.cfg
```

Console: `deferred_gbuffer_status`, `ambient_visibility_status`, `temporal_status`, `havenrp_renderer_status`. Recovery from bad experiments: `exec gfx_safe.cfg` then `vid_restart`. See [RENDERER_SPINE_1.0.md](RENDERER_SPINE_1.0.md) and [RENDERER_CONFIDENCE.md](RENDERER_CONFIDENCE.md).

## IDE Setup

### VS Code / Cursor
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Documentation is grouped by **tier**. Most files remain at their historical path

## Repository layout (2026)

Top-level symlinks (`engine/`, `runtime/`, `modules/`, `extensions/`, `renderers/`) → canonical `src/*` tree. **Legacy paths under `src/` remain authoritative.** See [core/REPOSITORY_LAYOUT_2026.md](core/REPOSITORY_LAYOUT_2026.md), [core/LEGACY_AND_MODERN.md](core/LEGACY_AND_MODERN.md), and [ENGINE_REORG_PLAN.md](ENGINE_REORG_PLAN.md).
Canonical sources live under **`engine/`**, **`runtime/`**, **`modules/`**, **`extensions/`**, and **`renderers/`** (Phase 5c/5e). **`src/`** is README-only after shim removal; cross-domain `#include` paths still use **`scripts/layout_forwarding_symlinks.sh`** until the include rewrite finishes. See [core/REPOSITORY_LAYOUT_2026.md](core/REPOSITORY_LAYOUT_2026.md), [core/SHIM_REMOVAL_CHECKLIST.md](core/SHIM_REMOVAL_CHECKLIST.md), [core/LEGACY_AND_MODERN.md](core/LEGACY_AND_MODERN.md), and [ENGINE_REORG_PLAN.md](ENGINE_REORG_PLAN.md).

## Archive

Expand Down
54 changes: 52 additions & 2 deletions docs/RENDERERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ renderer_deferred_safe
vid_restart
```

This profile sets `r_renderMode 1`, `r_deferredGBuffer 1`, `r_deferredGBufferFill 1`, and `r_deferredLighting 1`. It uses the same **opaque deferred + Forward+ transparent** split as mode 3 (`r_forwardPlusShade 1` on transparent; opaque handoff skips Forward+ add). Prefer `r_ext_multisample 0` for direct material export; MSAA uses depth-fallback fill with `deferredMsaaSafeMaterials` confidence floor. Safe debug: `renderer_deferred_safe`. Shipping default remains `modern_vulkan.cfg` (mode 3).
This profile sets `r_renderMode 1`, `r_deferredGBuffer 1`, `r_deferredGBufferFill 1`, and `r_deferredLighting 1`. It uses the same **opaque deferred + Forward+ transparent** split as mode 3 (`r_forwardPlusShade 1` on transparent; opaque handoff skips Forward+ add). Prefer `r_ext_multisample 0` for direct material export; MSAA uses depth-fallback fill with `deferredMsaaSafeMaterials` confidence floor. Safe debug: `renderer_deferred_safe`. Shipping default remains `modern_vulkan.cfg` → `modern_vulkan_stable.cfg` (**mode 2** Forward+).

The G-buffer fill copies scene albedo. On **non-MSAA** FBO frames, opaque PBR shaders **directly export** normals and material (metalness/roughness/AO). **MSAA** forces the depth-derived fallback (default metal/rough/AO=1). Prefer `r_ext_multisample 0` with `modern_vulkan.cfg` for true material export. Fallback defaults: `r_deferredDefaultMetalness`, `r_deferredDefaultRoughness`, `r_deferredNormalEdgeThreshold`.

Expand Down Expand Up @@ -308,7 +308,7 @@ The old SSAO/HBAO implementation remains available only as mode 1 and as a fallb
|------|---------|-------------|
| `r_fbo` | 1 | Framebuffer objects (required for PBR, HDR, bloom, MSAA, SMAA, SSAO). Use vid_restart after changing. |
| `r_pbr` | 1 | Physically Based Rendering (metalness/roughness, IBL). Requires r_fbo 1. |
| `r_renderMode` | 0 | **0** forward, **1** deferred lighting mode, **2** Forward+ primary, **3** Unified Clustered (heterogeneous shading / lighting ownership). `modern_vulkan.cfg` sets **3**. Latched; `vid_restart`. |
| `r_renderMode` | 0 | **0** forward, **1** deferred lighting mode, **2** Forward+ primary (**Spine shipping default** via `modern_vulkan_stable.cfg`), **3** Unified Clustered (heterogeneous shading / lighting ownership; `modern_clustered.cfg`). Latched; `vid_restart`. |
| `r_deferredGBuffer` | 0 | With `r_renderMode` 1/2/3: allocate albedo/normal/material/lighting G-buffer images. `modern_vulkan.cfg` sets **1** as a sidecar. Latched; `r_fbo` 1. |
| `r_deferredGBufferFill` | 0 | With G-buffer RTs: copy scene albedo after geometry (mode 3: after opaque). On non-MSAA FBO frames, opaque PBR material shaders directly export normals and material; MSAA/legacy paths keep the depth-derived fallback. Material is RGBA16F: metalness, roughness, AO, source confidence. `modern_vulkan.cfg` sets **1**. |
| `r_deferredGBufferDebug` | 0 | Before bloom: show G-buffer on scene color (1=albedo, 2=normal, 3=material, 4=lighting, 5=normal confidence, 6=motion vectors from the main material pass). |
Expand Down Expand Up @@ -445,6 +445,56 @@ See [HDR_GAPS.md](HDR_GAPS.md) for HDR pipeline gaps, risks, and render order.
- Cvars: `r_svgRasterScale`, `r_svgMaxRasterSize`, `r_svgMaxFileBytes`
- Use `.svg` files in textures/ or gfx/ for scalable UI elements

### Spine diagnostics and recovery

Use these when bisecting black frames, temporal trails, AO regressions, resize/`vid_restart` failures, or DEVICE_LOST on the modern Vulkan path. Full exit criteria: [RENDERER_SPINE_1.0.md](RENDERER_SPINE_1.0.md).

**Headless static gates** (run after renderer/G-buffer/temporal changes):

```bash
./scripts/spine_stability_check.sh
./scripts/gbuffer_av_lifecycle_check.sh
./scripts/temporal_ownership_check.sh
```

**In-game status dump** (packaged as `demo_gbuffer_av_lifecycle.cfg`):

```cfg
exec demo_gbuffer_av_lifecycle.cfg
```

| Command | What it reports |
|---------|-----------------|
| `deferred_gbuffer_status` | G-buffer scaffold extent, generation, fill/lighting/composite availability, soft-fail fallback reason |
| `ambient_visibility_status` | Requested/effective AV mode, TLAS/RTAO readiness, history state, GPU timings, reference-error metrics |
| `temporal_status` | Shared reset reasons (applied/sticky/pending), TAA history validity, weapon-after-TAA, world-matrix capture |
| `havenrp_renderer_status` | Aggregated renderer spine summary (gbuffer, temporal, weapon deferral, lighting rows) |
| `input_status` | Relative mouse / focus lifecycle (Spine presentation path) |

**Recovery presets:**

```cfg
exec gfx_safe.cfg
vid_restart

renderer_modern_safe
vid_restart
```

**Dev fail-inject cvars** (`CVAR_CHEAT`, clear to recover without `vid_restart` where noted):

| Cvar | Values | Effect |
|------|--------|--------|
| `r_dgbFailInject` | `alloc`, `view`, `pipeline`, `descriptor`, `all` | Forces G-buffer soft-fail → legacy SSAO owner; clears when set `0` |
| `r_avFailInject` | `history`, `rtao`, `all` | Demotes AO only (`legacy_ssao`); G-buffer fill stays live. `history` thrash-resets AV temporal each frame |

**Common pitfalls:**

- `r_ambientVisibilityMode 4` (adaptive hybrid) is **not** promoted in `modern_vulkan_quality.cfg` until the manual GPU matrix in `gbuffer_av_lifecycle_check.sh` passes.
- Presentation teardown+restore sticky-resets temporal history (`VK_TEMPORAL_RESET_SWAPCHAIN_CHANGE`) and rebinds deferred/AV — expect one-frame resets after resize/alt-tab.
- RDF_NOWORLDMODEL after `doneWorldScene` does not thrash shared temporal history; weapon draws defer until after world TAA when temporal reconstruction is on (`r_temporalWeaponAfterTaa`).
- Set `r_temporalDebug 2` for reset-reason logging during TAA/OIT bisects.

## Future Renderers (Planned)

See [RENDERERS_FUTURE.md](RENDERERS_FUTURE.md) for architecture and implementation plans:
Expand Down
4 changes: 2 additions & 2 deletions docs/RENDERER_2027.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ This is more than “deferred plus Forward+.” Shipping today uses those as fou

| Layer | Role |
|-------|------|
| **`r_renderMode 2`** | Forward+ primary (opt-in overlay / legacy modern path) |
| **`r_renderMode 3`** | [Unified Clustered](UNIFIED_CLUSTERED_RENDERER.md) — unified heterogeneous shading / lighting ownership (2D tiles today; depth clusters planned). **Shipping default** (`modern_vulkan.cfg`) and **spine** for 2027 layers |
| **`r_renderMode 2`** | Forward+ primary — **Spine 1.0 shipping default** (`modern_vulkan.cfg` → `modern_vulkan_stable.cfg`) |
| **`r_renderMode 3`** | [Unified Clustered](UNIFIED_CLUSTERED_RENDERER.md) — unified heterogeneous shading / lighting ownership (2D tiles today; depth clusters planned). **Experimental** until Spine exit; opt-in via `modern_clustered.cfg` |
| **2027 target** | Mode 3 + visibility buffer + meshlets + reservoir RT + neural reconstruction |

Do **not** invent `r_renderMode 4` for this architecture. Opt-in sidecars stack on mode 3.
Expand Down
6 changes: 5 additions & 1 deletion docs/RENDERER_CONFIDENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This document lists **automated** checks you can run today and **manual** passes

Treat this file as a **default gate** for any change that touches rendering, shaders, mesh tangents, or image loaders used by the renderer:

1. Run **automated** rows in the table below (at minimum `renderer_regression_check.sh` + your usual build).
1. Run **automated** rows in the table below (at minimum `renderer_regression_check.sh` + **`spine_stability_check.sh`** for renderer/G-buffer/temporal changes + your usual build).
2. For **graphics PRs**, run the **manual** short list or note why it is N/A (e.g. docs-only).
3. Prefer **first-party** warning/correctness fixes over new subsystems until the gate is green.

Expand All @@ -21,6 +21,9 @@ On **`main`**, GitHub Actions **`.github/workflows/build.yml`** runs **`renderer
| Check | Command | What it proves |
|--------|---------|----------------|
| Renderer regression (repo) | `./scripts/renderer_regression_check.sh` | Regression docs present (manifest includes `docs/ARCHITECTURE.md`, `docs/ROADMAP.md`, `BUILD.md`, `docs/FORWARD_PLUS_PIPELINE_AUDIT.md`, `src/renderers/vulkan/vk_temporal.h`, …); `shader_data.c` / `shader_binding.c` exist; recursive GLSL `glslang` pass; IQM/glTF morph **#define** parity; Forward+ **tile cull vs `tr_types.h` / `vk_forward_plus.c`** caps; **`gen_frag.tmpl`** tile stride `tileId * Nu` matches **`MAX_PER_TILE`**; **`r_forwardPlusMaxPerTile`** range wired to `vk_forward_plus_get_*_per_tile_cap`; PBR **`forward_plus_shade_strength`** `constant_id` matches `vk_create_pipeline.c`; Forward+ **`depthCull`** push + depth binding **3**; volumetric VDB binding **17** + **`vdbParams`** UBO fields; **`vk_temporal`** reset bitmask count matches switch + `knownReasons[]` table. Manifest lines strip **CRLF** so Windows checkouts do not false-fail path existence. Optional: set `GAME_BASE` and uncomment BSP paths in `OPTIONAL_GAME_ASSETS.txt` to require packaged maps. |
| **Renderer Spine stability** | `./scripts/spine_stability_check.sh` | Umbrella static contract for [Spine 1.0](RENDERER_SPINE_1.0.md): `modern_vulkan_stable.cfg` / quality / gfx_safe profile pins, mouse `input_status` symbols, WBOIT clears/barriers, packaging. Delegates to `gbuffer_av_lifecycle_check.sh` and `temporal_ownership_check.sh`. |
| **G-buffer / AV lifecycle** | `./scripts/gbuffer_av_lifecycle_check.sh` | Soft-fail create paths for deferred G-buffer, Ambient Visibility, and visibility-buffer scaffolds; presentation teardown/restore order; `r_dgbFailInject` / `r_avFailInject`; descriptor generation; TLAS→AV history invalidation; stable profile keeps `r_ambientVisibilityMode 2`. |
| **Temporal ownership** | `./scripts/temporal_ownership_check.sh` | Shared `apply_resets` (TAA/AV/volumetric/motion/occlusion); RDF_NOWORLDMODEL thrash guard; weapon-after-TAA deferral; portal/world-matrix isolation; `temporal_status` registration; stable profile must not enable `r_taa 1`. |
| Map load sanity (content) | `GAME_BASE=/abs/path/to/base ./scripts/renderer_regression_maps.sh` | Dedicated server runs `+map` for each `rtest_*` map; log scanned for `ERROR:`, `couldn't load`, `CM_LoadMap`, crashes. Requires full game base (VM + assets), not the regression pk3 alone. `RELEASE_DIR` optional (default `<repo>/release`). Optional `MAPS_EXTRA="name1 name2"` (or repo var `IDTECH3_MAPS_EXTRA` on Tier B self-hosted) appends more BSPs. Mixed dlights checklist: `docs/samples/renderer_regression/scenes/08_tier_b_mixed_dlights.md`. |
| Full local CI parity | `./scripts/validate_ci_build.sh` | SPIR-V generation, Vulkan Release build, smoke test, renderer regression check. |
| CMake smoke + artifacts | `ctest --output-on-failure` (from `build-vk-Release`) | Smoke, **renderer_regression_check**, artifacts, unit hooks, **demo_game pk3 layout** (`test_demo_game_pk3`). |
Expand Down Expand Up @@ -138,5 +141,6 @@ That sequence closes the gap between engine-side confidence and renderer evidenc
## See also

- [RENDERERS.md](RENDERERS.md) - feature inventory and cvars
- [RENDERER_SPINE_1.0.md](RENDERER_SPINE_1.0.md) - production-certified frame matrix and exit criteria
- [RELEASE_CHECKLIST.md](RELEASE_CHECKLIST.md) - pre-release steps
- `./scripts/validate_ci_build.sh` - local mirror of Ubuntu CI expectations
2 changes: 1 addition & 1 deletion docs/UNIFIED_CLUSTERED_RENDERER.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Also called historically: Hybrid Clustered Deferred Renderer / Deferred + Forwar

## Enable

Shipping default is **`modern_vulkan.cfg`** (`r_renderMode 3`). Equivalent profile: `exec modern_clustered.cfg`.
**Shipping default** is **`modern_vulkan.cfg`** → **`modern_vulkan_stable.cfg`** (`r_renderMode 2` Forward+). Mode 3 is opt-in: `exec modern_clustered.cfg` or `exec vulkan_overlay_unified_clustered.cfg`.

```
exec vulkan_overlay_unified_clustered.cfg
Expand Down
Loading