From bde581a961f7859368aa863d71384bb6d3e1694e Mon Sep 17 00:00:00 2001 From: Emil <65846814+emil28092005@users.noreply.github.com> Date: Wed, 23 Sep 2026 23:27:19 +0300 Subject: [PATCH] docs: reconcile P2 optimization and Linux validation --- PLAN.md | 6 +- README.md | 2 +- docs/ARCHITECTURE.md | 2 +- docs/IMPLEMENTATION.md | 57 ++++++++++++++++--- docs/manual/editor/profiling.md | 26 +++++++-- .../plans/2026-09-23-p2-gpu-visibility.md | 42 +++++++------- docs/validation/README.md | 1 + 7 files changed, 96 insertions(+), 40 deletions(-) diff --git a/PLAN.md b/PLAN.md index 79da5d7..747e78a 100644 --- a/PLAN.md +++ b/PLAN.md @@ -2,7 +2,7 @@ Версия 1.3 · 23 сентября 2026 года. -**Статус:** C++ MVP реализован и принят; первый tag — **v0.1.0-mvp**. Его исходники проверены на `4cb82556de31268d2bde73948dd1ff1b6c02f162`; [досье M0–M9](docs/validation/mvp-acceptance.md) связывает этапы с проверками и revisions. После MVP реализованы Lua-модуль и P2 GPU visibility/mesh LOD. Для P2 сохранён direct-эталон; [протокол приёмки](docs/studies/19-p2-gpu-visibility-acceptance.md) и [первое измерение](docs/studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) описывают Linux GPU-проверки и границы производительности. В Debug/validation GPU MainCull пока значительно дороже direct GPU-пути, поэтому P2 не означает готовое ускорение. Windows P2 и дополнительные семейства GPU/драйверов не подтверждены этим протоколом. Для MVP Linux проверен на RTX 2080 Ti, Windows — в native CI через SwiftShader; это не сертификация всех GPU/драйверов. Системный IME и физические переходы между мониторами не проверены, native Wayland restore имеет явный skip; XWayland и Windows lifecycle прошли. Контракты находятся в [ARCHITECTURE.md](docs/ARCHITECTURE.md), история — в [журнале реализации](docs/IMPLEMENTATION.md). +**Статус:** C++ MVP реализован и принят; первый tag — **v0.1.0-mvp**. Его исходники проверены на `4cb82556de31268d2bde73948dd1ff1b6c02f162`; [досье M0–M9](docs/validation/mvp-acceptance.md) связывает этапы с проверками и revisions. После MVP реализованы Lua-модуль и P2 GPU visibility/mesh LOD. Для P2 сохранён direct-эталон; [досье Linux-проверок](docs/validation/p2-gpu-visibility-2026-09-23/README.md), [протокол приёмки](docs/studies/19-p2-gpu-visibility-acceptance.md), [первое измерение](docs/studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) и [повтор после оптимизации](docs/studies/21-p2-gpu-visibility-optimization-2026-09-23.md) фиксируют функциональную и измерительную область. Первый Debug-профиль обнаружил дорогой MainCull; перенос GPU-выходов в device-local память и bounded atomic append устранили эту стоимость в повторном синтетическом тесте. Это не доказывает ускорение любой игры. Windows P2 и дополнительные семейства физических GPU/драйверов не подтверждены этими проверками. Для MVP Linux проверен на RTX 2080 Ti, Windows — в native CI через SwiftShader; это не сертификация всех GPU/драйверов. Системный IME и физические переходы между мониторами не проверены, native Wayland restore имеет явный skip; XWayland и Windows lifecycle прошли. Контракты находятся в [ARCHITECTURE.md](docs/ARCHITECTURE.md), история — в [журнале реализации](docs/IMPLEMENTATION.md). ## 1. Результат MVP @@ -185,7 +185,7 @@ Lua runtime/editor пакет реализован как необязатель ### P2. GPU-driven visibility и LOD -**Реализовано для opaque static meshes на Linux reference GPU; остальные платформы/устройства требуют отдельной проверки.** Direct renderer остался выбираемым эталоном. Реализованы устойчивые instance IDs с generation, GPU frustum culling, фиксированные indirect bins, current HZB и его редакторский preview, main/post occlusion с проверяемой историей, выбор заранее подготовленного mesh LOD по проецируемому размеру и hysteresis. Прозрачные meshes, спрайты, UI и shadow pass сохраняют свои упорядоченные/независимые пути. Система не генерирует LOD-модели из исходного mesh автоматически. +**Реализовано для opaque static meshes на Linux reference GPU; остальные платформы/устройства требуют отдельной проверки.** Direct renderer остался выбираемым эталоном. Реализованы устойчивые instance IDs с generation, GPU frustum culling, фиксированные indirect bins, current HZB и его редакторский preview, main/post occlusion с проверяемой историей, выбор заранее подготовленного mesh LOD по проецируемому размеру и hysteresis. Редактор переключает режимы через diagnostics, Player — через явный флаг `--visibility direct|gpu-frustum|gpu-occlusion`; по умолчанию остаётся Direct. Прозрачные meshes, спрайты, UI и shadow pass сохраняют свои упорядоченные/независимые пути. Система не генерирует LOD-модели из исходного mesh автоматически. - [x] GPU instance records, frustum culling и fixed indirect draws без CPU feedback для решения видимости. - [x] Current HZB, двухпроходное исправление ошибочной previous-frame occlusion и инвалидация истории при cut, resize, смене view/projection/instance. @@ -193,7 +193,7 @@ Lua runtime/editor пакет реализован как необязатель - [x] Автоматические adversarial-сценарии: пустота, граница ёмкости, дверь/телепорт, тени, near plane, resize, несколько views, lifecycle, прозрачность и открытая сцена. - [x] Профиль direct/frustum/occlusion на закрытой и открытой сценах с raw samples и без обещания универсального ускорения. -Основой проектирования было [исследование 15](docs/studies/15-renderer-implementation-notes.md); фактическая проверка и методика — в [P2 acceptance](docs/studies/19-p2-gpu-visibility-acceptance.md), [результаты и raw samples](docs/studies/20-p2-gpu-visibility-benchmark-2026-09-23.md), реализация — в [журнале](docs/IMPLEMENTATION.md). Счётчики GPU и HZB preview включаются только для диагностики; существующий framebuffer capture по-прежнему синхронен, поэтому end-to-end benchmark отражает этот путь. Первое измерение выявило дорогой MainCull в Debug/validation на reference GPU; до выбора GPU-режима по умолчанию нужны разбор затрат и Release-повтор. Открытые сцены и дополнительная стоимость HZB публикуются наравне с закрытыми. +Основой проектирования было [исследование 15](docs/studies/15-renderer-implementation-notes.md); фактическая проверка — в [Linux-досье](docs/validation/p2-gpu-visibility-2026-09-23/README.md) и [P2 acceptance](docs/studies/19-p2-gpu-visibility-acceptance.md), методика и значения — в [исходном benchmark](docs/studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) и [повторе после оптимизации](docs/studies/21-p2-gpu-visibility-optimization-2026-09-23.md), реализация — в [журнале](docs/IMPLEMENTATION.md). Счётчики GPU и HZB preview включаются только для диагностики; существующий framebuffer capture по-прежнему синхронен, поэтому end-to-end benchmark отражает этот путь. В первом измерении MainCull оказался дорогим; device-local выходные буферы и atomic add уменьшили его p50 до 0,030–0,042 мс в повторном Debug/validation тесте на reference GPU. Direct остаётся начальным режимом: до изменения default нужны Release-профиль и реальные игровые сцены. Открытые сцены и дополнительная стоимость HZB публикуются наравне с закрытыми. ### P3. Освещение, тени и temporal reconstruction diff --git a/README.md b/README.md index c21562d..6afaa67 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Faset is an independent engine project for desktop **2D and 3D games on Linux and Windows**. Its priorities are a custom editor that is comfortable to use by hand and through MCP, integration with Blender, and a path toward advanced graphics. -**Current status: the C++ MVP is accepted for the recorded Linux and Windows test profiles; Lua and P2 GPU visibility were added afterward.** The MVP includes the native Editor, shared GUI/MCP authoring, gameplay builds, Vulkan Player, Blender import and standalone export. Both playable games passed Release export and relocated execution on both operating systems. P2 adds optional GPU frustum and two-pass HZB occlusion modes, fixed indirect mesh bins, prepared mesh LOD selection, and an Editor HZB diagnostic view. The direct renderer remains the default and comparison reference. P2 GPU acceptance and measurements cover the Linux reference device; Windows P2 and additional physical GPUs need separate validation. The first Debug/validation benchmark found GPU culling substantially slower than direct GPU work, so the optional modes are not presented as a performance win. Windows MVP graphics acceptance used software Vulkan. See the [MVP acceptance dossier](docs/validation/mvp-acceptance.md), [P2 acceptance protocol](docs/studies/19-p2-gpu-visibility-acceptance.md), [measured P2 results](docs/studies/20-p2-gpu-visibility-benchmark-2026-09-23.md), and [implementation checkpoints](docs/IMPLEMENTATION.md) for exact scope and limits. +**Current status: the C++ MVP is accepted for the recorded Linux and Windows test profiles; Lua and P2 GPU visibility were added afterward.** The MVP includes the native Editor, shared GUI/MCP authoring, gameplay builds, Vulkan Player, Blender import and standalone export. Both playable games passed Release export and relocated execution on both operating systems. P2 adds optional GPU frustum and two-pass HZB occlusion modes, fixed indirect mesh bins, prepared mesh LOD selection, and an Editor HZB diagnostic view. Direct remains the default and comparison reference; an exported Player can explicitly select a mode with `--visibility direct|gpu-frustum|gpu-occlusion`. P2 GPU acceptance and measurements cover the Linux reference device, with a separate software-Vulkan functional check; Windows P2 and additional physical GPUs need separate validation. The first Debug/validation benchmark exposed slow GPU culling; device-local outputs and a bounded atomic append improved the same synthetic workloads in the repeat. Neither run establishes a general game-speed benefit. Windows MVP graphics acceptance used software Vulkan. See the [MVP acceptance dossier](docs/validation/mvp-acceptance.md), [P2 Linux evidence](docs/validation/p2-gpu-visibility-2026-09-23/README.md), [P2 acceptance protocol](docs/studies/19-p2-gpu-visibility-acceptance.md), [initial benchmark](docs/studies/20-p2-gpu-visibility-benchmark-2026-09-23.md), [optimized benchmark](docs/studies/21-p2-gpu-visibility-optimization-2026-09-23.md), and [implementation checkpoints](docs/IMPLEMENTATION.md) for exact scope and limits. ## Start here diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index e42910d..ba5a120 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -89,7 +89,7 @@ Catch-up ограничен числом ticks за проход главног Slang компилирует шейдеры в SPIR-V и выдаёт сведения для согласования CPU/GPU данных. Совместимый HLSL проходит выбранный pipeline; поддержка любого существующего HLSL-кода не обещается. Cook учитывает compiler/version, includes, defines и GPU profile. Nanite/Lumen-подобные системы остаются исследовательскими направлениями, не готовыми возможностями MVP. -P2 не требует синхронного чтения GPU-счётчиков для решения видимости: readback включается редакторской диагностикой. Current HZB preview также читается только по запросу. Существующий путь полного framebuffer capture всё ещё ждёт GPU, поэтому измерения полной длительности кадра включают эту стоимость; `gpu_ms` и времена отдельных проходов не заменяют полную CPU/GPU-профилировку. [Первое измерение](studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) обнаружило дорогой MainCull на Linux reference GPU в Debug/validation, несмотря на сокращение CPU-времени вызова renderer; архитектура не объявляет GPU-режим новым performance default. Mesh LOD выбирается среди заранее подготовленных вариантов с hysteresis; генерация LOD, streaming и cluster geometry пока не реализованы. GPU-режимы дополнительно проверяют необходимые limits/formats устройства и не считаются доступными на любом Vulkan 1.3 GPU без такой проверки. +P2 не требует синхронного чтения GPU-счётчиков для решения видимости: readback включается редакторской диагностикой. Current HZB preview также читается только по запросу. Существующий путь полного framebuffer capture всё ещё ждёт GPU, поэтому измерения полной длительности кадра включают эту стоимость; `gpu_ms` и времена отдельных проходов не заменяют полную CPU/GPU-профилировку. [Первое измерение](studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) обнаружило дорогой MainCull на Linux reference GPU в Debug/validation. [Повтор после оптимизации](studies/21-p2-gpu-visibility-optimization-2026-09-23.md) отдельно измерил эффект device-local выходных буферов и замены CAS-цикла на atomic add: MainCull p50 уменьшился до 0,030–0,042 мс в тех же синтетических сценах. Direct остаётся performance default до проверки Release-сборки и игровых нагрузок. Mesh LOD выбирается среди заранее подготовленных вариантов с hysteresis; генерация LOD, streaming и cluster geometry пока не реализованы. GPU-режимы дополнительно проверяют необходимые limits/formats устройства и не считаются доступными на любом Vulkan 1.3 GPU без такой проверки. ## 8. Blender и ассеты — принято diff --git a/docs/IMPLEMENTATION.md b/docs/IMPLEMENTATION.md index 4422007..ee94352 100644 --- a/docs/IMPLEMENTATION.md +++ b/docs/IMPLEMENTATION.md @@ -362,8 +362,12 @@ Shader reload rebuilds both direct and GPU scene pipelines, preserving the worki pipelines on failure. The Editor's ImGui diagnostics can select Direct, GPU frustum or GPU occlusion, -inspect pass timings/counters and request a current-HZB preview. Counter and HZB -readback are opt-in diagnostics; the visibility decision itself stays on the GPU. +inspect pass timings/counters and request a current-HZB preview. A Player run can +choose `--visibility direct|gpu-frustum|gpu-occlusion`; Direct remains its default. +The profile records the requested mode and per-frame `gpu_visibility_active` so a +silent fallback is not mistaken for measured GPU work. The Release Player CLI test +checks all three modes and rejects an invalid value. Counter and HZB readback are +opt-in diagnostics; the visibility decision itself stays on the GPU. The existing framebuffer capture still waits for completion and reads back each frame. Consequently, full-frame benchmark times include that path and must not be presented as isolated culling costs. @@ -376,13 +380,48 @@ multi-view history, LOD hysteresis, shadow independence and transparency. Shader reflection/export and GPU shader reload have focused tests. The [P2 acceptance protocol](studies/19-p2-gpu-visibility-acceptance.md) contains the command, tolerance and scene definitions. The -[three-run benchmark report](studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) +[initial three-run benchmark report](studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) retains all 810 raw frame records, device/build details, p50/p95 values and limits. -In that Debug build with validation and diagnostic counters, GPU `MainCull` took -about 3.9–18.2 ms p50 across the three synthetic scenes, far above the direct -path's 0.24–0.50 ms whole-GPU p50. The GPU route reduced synchronous CPU render-call -time, but this is not evidence of a shipping-frame speedup. Profile the cull pass -and repeat in Release before considering a different default. These checks establish -the tested Linux configuration; they do not +At that pre-optimization checkpoint, GPU `MainCull` took about 3.9–18.2 ms p50 in +three synthetic Debug/validation scenes, far above the direct path's 0.24–0.50 ms +whole-GPU p50. This was an actionable regression, not the final P2 performance. + +Optimization checkpoint `3be3d0d` moves GPU-written indirect arguments, visible IDs +and deferred buffers into device-local memory, uses staging copies for initialization +and optional diagnostics, and replaces contended CAS loops with bounded atomic add. +The [three-variant follow-up](studies/21-p2-gpu-visibility-optimization-2026-09-23.md) +isolates memory placement and then the shader change. With the same Debug/validation +scenes, `MainCull` p50 fell to 0.030–0.042 ms. Full GPU-command p50 for the open +GPU-frustum scene was 0.139 ms versus 0.498 ms direct; the occluded GPU-occlusion +scene was 0.188 ms versus 0.496 ms direct. All 2,430 sampled frames across variants +reported zero Vulkan validation errors; the final focused suite passed 18/18 and +both culling shaders passed `spirv-val`. These synthetic results do not establish +a shipping-frame speedup, especially on another device or game scene. These checks +establish the tested Linux configuration; they do not establish P2 behavior on a physical Windows GPU or a broad driver matrix. The [profiling manual](manual/editor/profiling.md) explains how to interpret the timings. + +The independent Linux Release build completed all targets, including the prepared +LOD example. Its full CTest run reported 57 registered tests, zero failures and +one existing native-window lifecycle skip. The focused Release Player CLI test +selected all three visibility modes, verified active GPU status in the profile, +and rejected an invalid mode. Release build/test success establishes functional +coverage; it does not replace a Release performance comparison or a Windows P2 run. + +As an additional Linux software-Vulkan check, Lavapipe ran all 15 labelled P2 +acceptance cases plus the standalone GPU visibility test and both example modes. +The GPU route was active and Vulkan validation reported zero errors. This adds a +second implementation for functional checks; Lavapipe timings are not physical-GPU +performance evidence. + +The [P2 Linux evidence dossier](validation/p2-gpu-visibility-2026-09-23/README.md) +retains the exact Release builds, labelled GPU cases and relocated standalone Player +checks. Both sample games passed a fresh Release export, Unicode relocation away +from the SDK and 120 headless frames with validation and zero errors. Their packages +also ran six frames in each GPU visibility mode with an active GPU path and zero +validation errors. The 2D Direct/GPU captures matched pixel-for-pixel. The 3D GPU +modes matched each other; each differed from Direct at 7 of 921,600 raster-edge +pixels, with no missing geometry. Direct CPU vertex transformation and GPU shader +vertex transformation round differently at subpixel triangle boundaries. The +Debug benchmarks above and this Release functional record have different purposes; +neither establishes physical Windows GPU coverage. diff --git a/docs/manual/editor/profiling.md b/docs/manual/editor/profiling.md index e00bab5..9e2378a 100644 --- a/docs/manual/editor/profiling.md +++ b/docs/manual/editor/profiling.md @@ -72,9 +72,19 @@ correct execution, not a frame-time threshold. The Editor diagnostics panel (**F12**) can switch its current viewport between **Direct**, **GPU frustum**, and **GPU occlusion**. Direct is the default reference. The selector is an Editor viewport setting; it does not change the saved scene or -automatically change an exported Player. Check **Path: active** in the panel before -interpreting a GPU-mode measurement: a selected mode alone does not prove that the -GPU path ran. See [Diagnostics](diagnostics.md) for the counters and HZB preview. +automatically change an exported Player. An exported Player can select a mode for a +bounded run: + +```sh +./faset_player --headless --frames 240 --profile gpu-frustum.json --visibility gpu-frustum +``` + +Accepted values are `direct`, `gpu-frustum`, and `gpu-occlusion`; Direct is the +default. The profile records the requested `visibility_mode` and each frame's +`gpu_visibility_active` state. Check that state when interpreting a GPU run: a +requested mode can fall back if the required device profile is unavailable. The +Editor reports the same distinction as **Path: active**. See +[Diagnostics](diagnostics.md) for the counters and HZB preview. For a repeatable offscreen comparison, build and run the P2 benchmark harness: @@ -89,9 +99,13 @@ shader bundle, validation state and source revision with any published result. T [P2 acceptance protocol](https://github.com/emil28092005/Faset_Engine/blob/main/docs/studies/19-p2-gpu-visibility-acceptance.md) documents the scenes and CSV columns. The [first measured report](https://github.com/emil28092005/Faset_Engine/blob/main/docs/studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) -retains three raw runs, p50/p95 and limits. Its Debug/validation profile found -GPU MainCull substantially more expensive than direct GPU work, even though the -GPU route reduced synchronous CPU render-call time. +is a **pre-optimization baseline**: its Debug/validation profile found GPU MainCull +substantially more expensive than direct GPU work. The +[optimized follow-up](https://github.com/emil28092005/Faset_Engine/blob/main/docs/studies/21-p2-gpu-visibility-optimization-2026-09-23.md) +retains three additional raw runs and isolates the effects of device-local output +buffers and bounded atomic append. MainCull p50 fell to 0.030–0.042 ms in those +synthetic scenes. That comparison is useful for diagnosis, not a guarantee that +GPU visibility speeds up a particular game or device. The harness enables GPU visibility counters, so diagnostic readback is part of its timings. In the Editor, opening diagnostics likewise enables these counters, and diff --git a/docs/superpowers/plans/2026-09-23-p2-gpu-visibility.md b/docs/superpowers/plans/2026-09-23-p2-gpu-visibility.md index 1e9face..7476dbd 100644 --- a/docs/superpowers/plans/2026-09-23-p2-gpu-visibility.md +++ b/docs/superpowers/plans/2026-09-23-p2-gpu-visibility.md @@ -30,13 +30,15 @@ --- +**Implementation note, 23 September 2026:** this checklist records the proposed execution sequence. A checked item has direct code/test/commit evidence; an unchecked item may be an unrecorded test-first step or a narrower validation/documentation gap, even where the corresponding P2 feature works. The [acceptance protocol](../../studies/19-p2-gpu-visibility-acceptance.md), [initial benchmark](../../studies/20-p2-gpu-visibility-benchmark-2026-09-23.md) and [optimized repeat](../../studies/21-p2-gpu-visibility-optimization-2026-09-23.md) report the observed Linux scope. Other platforms and real-game performance require separate evidence. + ### Task 1: Stable instances, conservative bounds, and LOD policy **Files:** Modify `include/faset/render/renderer.hpp`, `src/player/SceneView.cpp`, `cmake/Renderer.cmake`; create `include/faset/render/visibility.hpp`, `src/render/visibility.cpp`, `tests/render_visibility_policy_tests.cpp`. **Interfaces:** Produce `InstanceTracker::update(key, meshIdentity, model, bounds, viewId)` returning slot, generation, previous bounds and `previousValid`; `select_lod(projectedPixels, previousLevel, thresholds, hysteresis)`; `transformed_bounds(mesh, model)`. Add optional `DrawItem::instance_key`, `DrawItem::lod_meshes`, `Snapshot::view_id`, `Snapshot::camera_cut` without changing existing aggregate initialization order. -- [ ] **Step 1: Write failing CPU tests.** Assert transformed bounds for rotated, negative/nonuniform scaled meshes; stable slot through reorder; generation change after removal/reuse or mesh replacement; no previous state on camera cut; LOD hysteresis on both sides of a threshold; fallback when a level is absent. Include this core assertion: +- [x] **Step 1: Write failing CPU tests.** Assert transformed bounds for rotated, negative/nonuniform scaled meshes; stable slot through reorder; generation change after removal/reuse or mesh replacement; no previous state on camera cut; LOD hysteresis on both sides of a threshold; fallback when a level is absent. Include this core assertion: ```cpp auto first = tracker.update("object/primitive", meshA, identity, box, "game"); auto second = tracker.update("object/primitive", meshA, moved, box, "game"); @@ -45,9 +47,9 @@ require(!tracker.update("object/primitive", meshB, moved, box, "game").previous_valid); ``` - [ ] **Step 2: Run the focused test target and record the expected missing-interface failure.** `cmake --build --preset linux-debug --target faset_render_visibility_policy_tests -j 6` must fail before implementation because the new interfaces/target do not exist. -- [ ] **Step 3: Implement the policy and extraction keys.** Derive keys from persistent scene object and imported primitive identity; anonymous draws remain renderable without temporal state. Use all eight local AABB corners and finite-value checks. Define an explicit LOD threshold/hysteresis contract in the header. -- [ ] **Step 4: Rebuild/run the focused CPU test, then the existing scene-view tests.** `ctest --test-dir build/linux-debug --output-on-failure -R 'visibility_policy|player_scene_contracts'` must pass. -- [ ] **Step 5: Commit** `Introduce stable render instances and prepared LOD policy`. +- [x] **Step 3: Implement the policy and extraction keys.** Derive keys from persistent scene object and imported primitive identity; anonymous draws remain renderable without temporal state. Use all eight local AABB corners and finite-value checks. Define an explicit LOD threshold/hysteresis contract in the header. +- [x] **Step 4: Rebuild/run the focused CPU test, then the existing scene-view tests.** `ctest --test-dir build/linux-debug --output-on-failure -R 'visibility_policy|player_scene_contracts'` must pass. +- [x] **Step 5: Commit** `Introduce stable render instances and prepared LOD policy`. ### Task 2: P2 Slang bundle and checked shader metadata @@ -55,11 +57,11 @@ **Interfaces:** Compile and validate `gpuVertexMain`, `gpuShadowMain`, `gpuCullMain`, `gpuHzbMain`, `gpuPostCullMain` with documented set/binding layouts. Baseline `vertexMain`, `fragmentMain`, `shadowMain` and their hot-reload fingerprint contract remain valid. Export includes each new `.spv` and `.reflection.json` pair. -- [ ] **Step 1: Write failing reflection/package tests.** A storage-buffer/storage-image Slang reflection fixture must normalize to a typed descriptor; missing or tampered P2 SPIR-V/metadata must fail validation; a packaged Player must contain all required P2 shaders. +- [x] **Step 1: Write failing reflection/package tests.** A storage-buffer/storage-image Slang reflection fixture must normalize to a typed descriptor; missing or tampered P2 SPIR-V/metadata must fail validation; a packaged Player must contain all required P2 shaders. - [ ] **Step 2: Run focused tests and verify the expected rejection or missing-artifact failure.** `ctest --test-dir build/linux-debug --output-on-failure -R 'render_shader_reload|build_schema_publication'` plus the new reflection test target. -- [ ] **Step 3: Extend the compiler's descriptor normalization and add the P2 shader entries.** Vertex resolves `visibleIds[binBase + SV_InstanceID]`; compute writes bounded per-bin IDs/counts; HZB computes max of valid children and far depth for padding. Keep C++/Slang record strides explicit and checked. -- [ ] **Step 4: Validate generated reflection and package.** Rebuild `faset_shaders`, run the focused tests and inspect each generated metadata stage/binding/fingerprint. -- [ ] **Step 5: Commit** `Add checked Slang shaders for GPU visibility and HZB`. +- [x] **Step 3: Extend the compiler's descriptor normalization and add the P2 shader entries.** Vertex resolves `visibleIds[binBase + SV_InstanceID]`; compute writes bounded per-bin IDs/counts; HZB computes max of valid children and far depth for padding. Keep C++/Slang record strides explicit and checked. +- [x] **Step 4: Validate generated reflection and package.** Rebuild `faset_shaders`, run the focused tests and inspect each generated metadata stage/binding/fingerprint. +- [x] **Step 5: Commit** `Add checked Slang shaders for GPU visibility and HZB`. ### Task 3: GPU frustum culling and fixed indirect bins @@ -69,9 +71,9 @@ - [ ] **Step 1: Write GPU integration tests.** Direct/GPU images must agree on the same opaque cube/plane scene; empty and one-instance scenes have zero/one visible instances; over-capacity growth and all-six-plane rejects remain validation-clean; an offscreen caster continues to affect a visible receiver. - [ ] **Step 2: Run the new GPU test and verify that GPU mode is absent/fails for the intended reason.** Use `ctest --test-dir build/linux-debug --output-on-failure -R '^render_gpu_visibility$'`. -- [ ] **Step 3: Add checked device capability selection and distinct GPU scene resources.** Build mesh+texture bins, upload local vertices once per unique mesh each frame, reserve one ID range per bin, create/update descriptors, dispatch frustum cull, barrier compute writes to indirect and vertex-storage reads, and issue fixed indirect draws. Keep the direct path byte-for-byte selectable. -- [ ] **Step 4: Run the focused GPU test with Khronos validation and the existing offscreen renderer tests.** No Vulkan errors, no visible image holes, and no shadow regression. -- [ ] **Step 5: Commit** `Render opaque meshes through GPU culling and fixed indirect bins`. +- [x] **Step 3: Add checked device capability selection and distinct GPU scene resources.** Build mesh+texture bins, upload local vertices once per unique mesh each frame, reserve one ID range per bin, create/update descriptors, dispatch frustum cull, barrier compute writes to indirect and vertex-storage reads, and issue fixed indirect draws. Keep the direct path byte-for-byte selectable. +- [x] **Step 4: Run the focused GPU test with Khronos validation and the existing offscreen renderer tests.** No Vulkan errors, no visible image holes, and no shadow regression. +- [x] **Step 5: Commit** `Render opaque meshes through GPU culling and fixed indirect bins`. ### Task 4: Current HZB and diagnostic view @@ -81,9 +83,9 @@ - [ ] **Step 1: Write failing tests.** Assert odd 319×241 extent, a far-depth hole, mip chain dimensions/padding, resized target recreation and an HZB debug image with non-uniform depth. - [ ] **Step 2: Run the tests and confirm the missing HZB/debug capability is the failure.** `ctest --test-dir build/linux-debug --output-on-failure -R '^render_gpu_visibility$'`. -- [ ] **Step 3: Split Main opaque raster from sprites/UI, store depth, allocate sampled/storage HZB mip views, dispatch each reduction with explicit depth→compute and mip→mip barriers, and draw a selectable debug visualization.** Preserve existing forward-Z convention. -- [ ] **Step 4: Run focused GPU tests and baseline image tests under validation; compare HZB-off output with direct mode.** -- [ ] **Step 5: Commit** `Build and visualize current-frame max-depth HZB`. +- [x] **Step 3: Split Main opaque raster from sprites/UI, store depth, allocate sampled/storage HZB mip views, dispatch each reduction with explicit depth→compute and mip→mip barriers, and draw a selectable debug visualization.** Preserve existing forward-Z convention. +- [x] **Step 4: Run focused GPU tests and baseline image tests under validation; compare HZB-off output with direct mode.** +- [x] **Step 5: Commit** `Build and visualize current-frame max-depth HZB`. ### Task 5: Previous-HZB main pass and same-frame post repair @@ -93,9 +95,9 @@ - [ ] **Step 1: Write failing frame-sequence tests.** A wall hides an object in frame N; opening/deleting/teleporting it in N+1 reveals that object in the final N+1 image. Camera cut, projection change, view ID change and resize force history invalid; near-plane crossing fails open. Compare every frame against HZB-disabled output. - [ ] **Step 2: Run the tests and observe the missing deferral/post behavior.** `ctest --test-dir build/linux-debug --output-on-failure -R '^render_gpu_visibility$'`. -- [ ] **Step 3: Implement previous/current projection tests, bounded deferred/post buffers, history ping-pong and invalidation, explicit compute→indirect/vertex barriers and Main/CurrentHZB/Post pass order.** Use ordinary-Z max-depth comparison with precision bias and full projected rectangle. -- [ ] **Step 4: Run the sequence and full GPU render suites with validation; confirm no same-frame holes.** -- [ ] **Step 5: Commit** `Repair temporal occlusion with current-frame post pass`. +- [x] **Step 3: Implement previous/current projection tests, bounded deferred/post buffers, history ping-pong and invalidation, explicit compute→indirect/vertex barriers and Main/CurrentHZB/Post pass order.** Use ordinary-Z max-depth comparison with precision bias and full projected rectangle. +- [x] **Step 4: Run the sequence and full GPU render suites with validation; confirm no same-frame holes.** +- [x] **Step 5: Commit** `Repair temporal occlusion with current-frame post pass`. ### Task 6: Prepared mesh LOD, editor controls and profiling @@ -103,11 +105,11 @@ **Interfaces:** Imported or C++-supplied prepared LOD meshes are selected by projected size and Task 1 hysteresis. Changing level changes the bin but keeps the logical instance key and invalidates previous occlusion. Editor can switch direct/GPU/HZB modes and inspect culling/LOD counters without adding MCP access to the Player. -- [ ] **Step 1: Write failing tests.** Jitter around both thresholds must retain the previous LOD; moving well across a threshold selects a different mesh/bin; missing levels fall back; both modes keep a valid image through level changes. +- [x] **Step 1: Write failing tests.** Jitter around both thresholds must retain the previous LOD; moving well across a threshold selects a different mesh/bin; missing levels fall back; both modes keep a valid image through level changes. - [ ] **Step 2: Run focused tests and verify the missing selection/control behavior.** - [ ] **Step 3: Hook prepared LODs into extraction and GPU binning, expose compact editor controls/statistics and a documented C++/asset authoring path.** Keep source scene IDs unchanged. -- [ ] **Step 4: Run CPU/GPU/editor UI suites and capture a representative debug screenshot.** -- [ ] **Step 5: Commit** `Expose prepared mesh LOD and GPU visibility diagnostics`. +- [x] **Step 4: Run CPU/GPU/editor UI suites and capture a representative debug screenshot.** +- [x] **Step 5: Commit** `Expose prepared mesh LOD and GPU visibility diagnostics`. ### Task 7: Adversarial validation, baselines and publication diff --git a/docs/validation/README.md b/docs/validation/README.md index 476fa2b..b63ef40 100644 --- a/docs/validation/README.md +++ b/docs/validation/README.md @@ -3,6 +3,7 @@ These files preserve bounded checks and their inputs. Each record states its source revision or working-tree limitation; a passing record does not certify later commits or every supported platform. - [MVP acceptance dossier](mvp-acceptance.md): criterion-by-criterion closure, tested revisions and remaining compatibility coverage. +- [P2 GPU visibility Linux evidence](p2-gpu-visibility-2026-09-23/README.md): Debug/Release GPU acceptance, lavapipe functional checks, relocated Player exports, and explicit platform/performance limits. - [Windows software Vulkan](windows-software-vulkan-2026-09-18/README.md): fresh native build, 35 tests, launcher/window/MCP workflows and both relocated Release games on SwiftShader. - [Checkpoint 5 Linux acceptance](checkpoint5-linux-2026-09-18/README.md): clean offline source build, first Editor launch, exact-candidate standalone games and live Blender checks. - [Final Linux source checks](final-linux-2026-09-18/README.md): `4cb8255` integrated test results and both Release games after the asset-relocation correction, including package manifests and standalone captures.