Validate and document P2 GPU visibility milestone
Native and manual checks / native (windows-2025) (push) Waiting to run
Native and manual checks / native (ubuntu-24.04) (push) Failing after 31s
Native and manual checks / manual (push) Successful in 29s
Windows editor and software Vulkan / windows-graphics (push) Canceled after 0s

This commit is contained in:
Emil
2026-09-24 00:48:54 +03:00
parent 22012c1a80
commit d18c5d77b3
13 changed files with 650 additions and 13 deletions
+5 -3
View File
@@ -2,7 +2,7 @@
Версия 1.3 · 23 сентября 2026 года.
**Статус:** C++ MVP реализован и принят; первый tag — **v0.1.0-mvp**. Его исходники проверены на `4cb82556de31268d2bde73948dd1ff1b6c02f162`; [досье M0M9](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).
**Статус:** C++ MVP реализован и принят; первый tag — **v0.1.0-mvp**. Его исходники проверены на `4cb82556de31268d2bde73948dd1ff1b6c02f162`; [досье M0M9](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), [проверка Windows SwiftShader](docs/validation/p2-swiftshader-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 функционально проверен в native CI через SwiftShader; физический Windows 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,9 @@ 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. Редактор переключает режимы через diagnostics, Player — через явный флаг `--visibility direct|gpu-frustum|gpu-occlusion`; по умолчанию остаётся Direct. Прозрачные meshes, спрайты, UI и shadow pass сохраняют свои упорядоченные/независимые пути. Система не генерирует LOD-модели из исходного mesh автоматически.
**Реализовано для opaque static meshes; проверено на Linux reference GPU и функционально на Windows SwiftShader. Физический Windows 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 автоматически.
GPU instance record содержит стабильные slot/generation; плотный индекс кандидата остаётся адресом в буфере текущего кадра. Диагностика отдельно показывает запрошенный и фактический режим: при отсутствии HZB запрос occlusion явно исполняется как frustum, при отсутствии GPU culling — как Direct. Проверка этих контрактов добавлена после независимого ревью.
- [x] GPU instance records, frustum culling и fixed indirect draws без CPU feedback для решения видимости.
- [x] Current HZB, двухпроходное исправление ошибочной previous-frame occlusion и инвалидация истории при cut, resize, смене view/projection/instance.
@@ -193,7 +195,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); фактическая проверка — в [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 публикуются наравне с закрытыми.
Основой проектирования было [исследование 15](docs/studies/15-renderer-implementation-notes.md); фактическая проверка — в [Linux-досье](docs/validation/p2-gpu-visibility-2026-09-23/README.md), [Windows SwiftShader CI](docs/validation/p2-swiftshader-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
+2 -2
View File
@@ -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. 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.
**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 functional checks passed on pinned SwiftShader; physical Windows GPUs and broader driver families remain untested. 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 SwiftShader compatibility](docs/validation/p2-swiftshader-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
@@ -39,7 +39,7 @@ This README is in English. The current planning documents, studies, and research
- **Editor-only MCP:** authoring, assets, import, builds, export, Play/Stop, and editor diagnostics. MCP is absent from the Player and exported games.
- Standard, **unmodified Blender**, glTF/GLB import, and an optional add-on for convenient export and stable IDs.
The MVP provides two small games, one 2D and one 3D, with scene editing, C++ behavior, physics, Play and standalone export. A [Lua-only example](examples/lua) demonstrates the optional scripting module. P2 GPU visibility applies to opaque static meshes; ordered sprites/UI and the shadow pass keep their separate rendering paths. Its LOD policy chooses among meshes supplied by the project; automatic LOD generation, advanced shadows, temporal reconstruction and dynamic global illumination remain future work. See [profiling guidance](docs/manual/editor/profiling.md) before interpreting full-frame measurements.
The MVP provides two small games, one 2D and one 3D, with scene editing, C++ behavior, physics, Play and standalone export. A [Lua-only example](examples/lua) demonstrates the optional scripting module. P2 GPU visibility applies to opaque static meshes; ordered sprites/UI and the shadow pass keep their separate rendering paths. Its LOD policy chooses among meshes supplied by the project; the Editor and Player report the effective visibility mode if device capabilities force a fallback. Automatic LOD generation, advanced shadows, temporal reconstruction and dynamic global illumination remain future work. See [profiling guidance](docs/manual/editor/profiling.md) before interpreting full-frame measurements.
## Run the research map
+5 -1
View File
@@ -83,14 +83,18 @@ Catch-up ограничен числом ticks за проход главног
2D и 3D имеют отдельные миры и spatial-типы. Для динамического тела итоговым transform владеет физика; teleport и кинематическое управление — отдельные операции. Физическое тело связано с entity через проверяемый handle. Миры 2D и 3D не сталкиваются автоматически. Внутренние substeps solver настраиваются отдельно от частоты gameplay ticks; начальная настройка — четыре substeps с проверкой на сценах проекта.
Собственный Vulkan 1.3 renderer получает подготовленный snapshot, не обходит изменяемый EnTT registry с render thread. RenderGraph описывает reads/writes ресурсов, порядок проходов, barriers и lifetimes. MVP создал проверяемый raster-путь 2D/3D без обязательных RT/mesh shaders. P2 добавил выбираемые GPU frustum и GPU occlusion режимы для opaque static meshes; Direct остаётся начальным режимом и эталоном. Scene extraction задаёт устойчивые keys для постоянных объектов; renderer отслеживает generation и консервативные bounds. `DrawItem` может содержать заранее подготовленные LOD meshes. CPU формирует фиксированные совместимые bins, GPU заполняет visible IDs и `instanceCount` для indirect draws. В occlusion-режиме previous HZB даёт предварительное решение, а current HZB и PostCull возвращают объекты, которые открылись в этом кадре. Camera cut, несовместимые view/projection/extent и смена instance generation инвалидируют историю. Тени, прозрачные meshes, спрайты и UI не теряют независимый порядок из-за camera culling. Точная реализованная область и проверка приведены в [P2 acceptance](studies/19-p2-gpu-visibility-acceptance.md).
Собственный Vulkan 1.3 renderer получает подготовленный snapshot, не обходит изменяемый EnTT registry с render thread. RenderGraph описывает reads/writes ресурсов, порядок проходов, barriers и lifetimes. MVP создал проверяемый raster-путь 2D/3D без обязательных RT/mesh shaders. P2 добавил выбираемые GPU frustum и GPU occlusion режимы для opaque static meshes; Direct остаётся начальным режимом и эталоном. Scene extraction задаёт устойчивые keys для постоянных объектов; renderer отслеживает generation и консервативные bounds. GPU instance record несёт стабильные slot и generation, а компактный индекс в candidate/visible буферах служит адресом записи только текущего кадра. `DrawItem` может содержать заранее подготовленные LOD meshes. CPU формирует фиксированные совместимые bins, GPU заполняет visible IDs и `instanceCount` для indirect draws. В occlusion-режиме previous HZB даёт предварительное решение, а current HZB и PostCull возвращают объекты, которые открылись в этом кадре. Camera cut, несовместимые view/projection/extent и смена instance generation инвалидируют историю. Тени, прозрачные meshes, спрайты и UI не теряют независимый порядок из-за camera culling. Точная реализованная область и проверка приведены в [P2 acceptance](studies/19-p2-gpu-visibility-acceptance.md).
**Vulkan API вызывается напрямую внутри собственного backend Faset.** Он владеет Vulkan handles, созданием GPU-ресурсов и pipelines, записью команд, синхронизацией и отправкой в очереди. Renderer и RenderGraph используют небольшой внутренний интерфейс ресурсов и команд Faset; Vulkan-типы и вызовы `vk*` не входят в gameplay API или команды редактора. SDL3 обеспечивает окно и создание Vulkan surface, но не заменяет графический backend; Slang отвечает за компиляцию шейдеров. Универсальная абстракция нескольких графических API не является задачей MVP.
Slang компилирует шейдеры в SPIR-V и выдаёт сведения для согласования CPU/GPU данных. Совместимый HLSL проходит выбранный pipeline; поддержка любого существующего HLSL-кода не обещается. Cook учитывает compiler/version, includes, defines и GPU profile. Nanite/Lumen-подобные системы остаются исследовательскими направлениями, не готовыми возможностями MVP.
Граница зависимости проходит через **готовый пакет SPIR-V + нормализованную reflection-метаинформацию Faset**. В текущей реализации CMake требует `slangc` для сборки этого пакета, а `compile_shader.py` преобразует Slang reflection в формат `faset.shader-reflection` с hash и layout fingerprint. Сам Vulkan backend создаёт pipelines из SPIR-V и проверяет этот контракт; он не вызывает Slang во время игры и не линкует его runtime. Однако структура descriptor sets, push constants, входов вершин и соглашение о матрицах сейчас явно согласованы с существующими Slang-шейдерами. Поэтому новый компилятор возможен без переписывания команд Vulkan, если он выдаёт эквивалентный SPIR-V и тот же проверяемый контракт. При появлении второго компилятора отдельным шагом вводится интерфейс shader package producer и тесты эквивалентности ABI; преждевременная абстракция компиляторов в MVP/P2 не нужна.
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 без такой проверки.
Диагностика различает запрошенный и фактически выполненный visibility mode в каждом кадре. Если GPU culling недоступен, фактический режим Direct; если доступен frustum, но нет подходящего HZB, запрос GPU occlusion явно понижается до GPU frustum. Player записывает оба режима в профиль и сообщает о fallback в stderr, редактор показывает Effective path и факт расхождения с выбранным режимом.
## 8. Blender и ассеты — принято
Используется **обычный Blender**, без обязательного форка или установленного MCP-плагина. Базовый обмен — **GLB и manifest со стабильными asset/subasset IDs**. Обычный экспорт принимается движком; удобный add-on для публикации, UUID и повторного экспорта остаётся необязательным помощником. Если источник не предоставляет устойчивые subasset IDs, importer не обещает надёжно угадать соответствие после произвольного rename/reparent: сохраняет mapping и показывает конфликты.
+42 -1
View File
@@ -406,7 +406,7 @@ 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.
coverage; at that checkpoint, Windows P2 was still unverified.
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.
@@ -425,3 +425,44 @@ pixels, with no missing geometry. Direct CPU vertex transformation and GPU shade
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.
Compatibility checkpoint `433bce0` followed the first red Windows P2 CI run. The
pinned SwiftShader device does not expose `shaderDrawParameters`; the Slang
`SV_InstanceID` builtin had emitted a SPIR-V `DrawParameters` capability, so the
renderer rejected the GPU route. Both GPU vertex entries now use raw
`SV_VulkanInstanceID` while their fixed indirect commands keep `firstInstance = 0`.
The renderer no longer requests that optional feature. The GPU smoke case now has
the `gpu;p2` CTest labels, so CPU-only native checks exclude it. A reflection test
rejects `DrawParameters` in the two generated vertex modules. On matching Linux
SwiftShader, all 16 P2 cases passed with the GPU path active; a deliberately
driverless CPU-only selection passed 26/26.
At this revision, [Windows graphics CI](https://github.com/emil28092005/Faset_Engine/actions/runs/35918597688)
passed all 58 tests on pinned SwiftShader, including the P2 route and Windows
window/editor tests. Its two relocated Release example games each rendered 120
frames in the default Direct mode. [Native/manual CI](https://github.com/emil28092005/Faset_Engine/actions/runs/35918597686)
also passed. The [SwiftShader compatibility dossier](validation/p2-swiftshader-2026-09-23/README.md)
records the cause, local commands, CI run and export report. Windows did not have
the Khronos validation layer, and no physical Windows GPU or driver-family
performance claim follows from this software-Vulkan result.
Independent P2 source review then found two contract gaps. Requested GPU occlusion
could silently run GPU frustum when HZB was unavailable, and stable instance
slot/generation lived only in the CPU tracker while GPU candidates used dense
frame-local indices. Follow-up `22012c1` records the requested and effective
visibility mode per frame in renderer statistics, Player profiles/output and
Editor diagnostics, with a CPU capability-policy regression. GPU instance records
now carry stable slot and all 64 generation bits in previously reserved metadata;
dense indices remain addresses into the current frame's instance buffer. A focused
reorder/replacement/anonymous-instance test covers the metadata packing. The
reviewer rechecked both fixes and found no remaining load-bearing issue in those
paths. On this revision, full Linux Debug and Release CTest each reported 57
registered tests, zero failures and one existing native-window lifecycle skip. The dedicated ImGui overlay test passed
1/1; pinned Linux SwiftShader passed all 16 P2 cases and Player diagnostics; a
driverless CPU-only Release selection passed 26/26. The final
[Windows graphics CI run](https://github.com/emil28092005/Faset_Engine/actions/runs/35922643226)
passed all 58 tests without skips on SwiftShader; both relocated Release games
rendered 120 frames in Direct mode. The corresponding
[native/manual CI run](https://github.com/emil28092005/Faset_Engine/actions/runs/35922643004)
passed on Linux and Windows. Unsupported-HZB integration and physical Windows
GPU coverage remain untested.
@@ -30,7 +30,7 @@
---
**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.
**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), [optimized repeat](../../studies/21-p2-gpu-visibility-optimization-2026-09-23.md) and [SwiftShader compatibility record](../../validation/p2-swiftshader-2026-09-23/README.md) report their tested configurations. Real-game performance and physical Windows GPUs require separate evidence.
### Task 1: Stable instances, conservative bounds, and LOD policy
@@ -59,7 +59,7 @@
- [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.
- [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 3: Extend the compiler's descriptor normalization and add the P2 shader entries.** Vertex resolves `visibleIds[binBase + SV_VulkanInstanceID]`; 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`.
@@ -118,7 +118,7 @@
**Interfaces:** Close P2 only with exact revision, compiler/driver/GPU/OS, scene/camera paths, commands, full-frame direct/GPU timings, pass counters, image comparison and stated coverage limits.
- [ ] **Step 1: Add adversarial fixtures for mass deletion/reuse, near-plane, camera inside bounds, odd/offset viewport, door/wall, open scene and offscreen shadow caster; confirm at least one fails before its corresponding fix.**
- [ ] **Step 2: Run Debug and Release build/test suites, GPU validation, shader reload, two sample-game export/relaunch checks, and available Windows CI.** Record exact outputs; a platform without executed GPU coverage remains explicitly unverified.
- [ ] **Step 3: Profile the same closed and open scenes in direct and GPU modes.** Record CPU extraction/upload/submission, GPU pass and full-frame time, readback conditions, memory and culling counters. Do not turn a scene-specific result into a universal performance claim.
- [ ] **Step 4: Review all PLAN P2 criteria against evidence, update docs, run `graphify update .`, request independent code review and fix load-bearing findings.**
- [ ] **Step 5: Commit** `Validate and document P2 GPU visibility milestone`; publish only after all checks are green.
- [x] **Step 2: Run Debug and Release build/test suites, GPU validation, shader reload, two sample-game export/relaunch checks, and available Windows CI.** Record exact outputs; a platform without executed GPU coverage remains explicitly unverified.
- [x] **Step 3: Profile the same closed and open scenes in direct and GPU modes.** Record CPU extraction/upload/submission, GPU pass and full-frame time, readback conditions, memory and culling counters. Do not turn a scene-specific result into a universal performance claim.
- [x] **Step 4: Review all PLAN P2 criteria against evidence, update docs, run `graphify update .`, request independent code review and fix load-bearing findings.**
- [x] **Step 5: Commit** `Validate and document P2 GPU visibility milestone`; publish only after all checks are green.
+1
View File
@@ -4,6 +4,7 @@ These files preserve bounded checks and their inputs. Each record states its sou
- [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.
- [P2 pinned SwiftShader compatibility](p2-swiftshader-2026-09-23/README.md): the Windows CI regression, shader capability fix, independent review closure, final native CI and relocated Player evidence.
- [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.
@@ -0,0 +1,15 @@
# P2 visibility on the pinned SwiftShader device — 2026-09-23
The first Windows CI run of P2 at `ba3efa8` exposed two related problems. The native CPU-only job ran `gpu_visibility` because its CTest registration lacked the `gpu` label. The graphics job had a Vulkan driver, but every P2 rendering test fell back to Direct. Its pinned SwiftShader device reports `shaderDrawParameters = false`. Slang generated `OpCapability DrawParameters` and a `BaseInstance` input for `SV_InstanceID`, and Faset therefore excluded the device from GPU visibility. The graphics failures in shader reload, Player diagnostics and the HZB overlay followed from that same fallback. The failing runs are [Windows graphics](https://github.com/emil28092005/Faset_Engine/actions/runs/35916372091) and [native/manual checks](https://github.com/emil28092005/Faset_Engine/actions/runs/35916372071).
Commit `433bce0` changes both GPU vertex entries to `SV_VulkanInstanceID`, which reads Vulkan's raw `InstanceIndex`. Every fixed-bin indirect command has `firstInstance = 0` and passes its visible-ID range base separately, so indexing is unchanged. The renderer no longer requests `shaderDrawParameters`. A shader reflection regression test rejects `OpCapability DrawParameters` in both compiled vertex entries. The GPU smoke test now carries `gpu;p2` labels: a CPU-only `ctest -LE gpu` excludes it, while P2 runs include it. [Slang's SPIR-V semantics](https://github.com/shader-slang/slang/blob/master/docs/user-guide/a2-01-spirv-target-specific.md#using-sv_instanceid-and-sv_vertexid-with-spir-v-target) explain why `SV_InstanceID` had introduced `BaseInstance`.
The matching Linux build of the [pinned SwiftShader source](https://github.com/google/swiftshader/tree/1e80438d2b93ef36a7c05f8d2b81233bac0e3d16) reports the same unsupported feature and sufficient storage-buffer/workgroup limits in the [capability record](local-capabilities.txt). After the change, [both vertex SPIR-V modules](spirv-instance-capabilities.txt) contain only the core `Shader` capability and pass `spirv-val`. [All 16 P2 cases](local-p2-ctest.txt) pass with GPU visibility active on this device. The three previously failing ancillary checks — shader reload, Player diagnostics and HZB overlay — also [pass](local-gpu-contracts.txt). With Vulkan deliberately unavailable, the [26 CPU-only Release tests](local-cpu-without-vulkan.txt) passed and `ctest -LE gpu` excluded `gpu_visibility`.
The first green [Windows graphics CI run at `433bce0`](https://github.com/emil28092005/Faset_Engine/actions/runs/35918597688) used the pinned SwiftShader Win32 driver: all 58 registered tests passed, including GPU visibility, shader reload, HZB overlay, Player mode diagnostics and native window/editor tests. Its export integration test built and launched 2D and 3D Release games. The matching [native/manual CI run](https://github.com/emil28092005/Faset_Engine/actions/runs/35918597686) also passed, including Windows CPU-only selection and strict documentation.
The Linux SwiftShader ICD in this local build does not expose a Wayland surface, so its window lifecycle and GUI/MCP tests cannot be used as a native-window acceptance result. The Windows graphics workflow checks those paths on its Win32 surface. The Windows runner did not provide the Khronos validation layer; its reported zero validation errors are **not** a validation-layer pass. Software Vulkan establishes compatibility and functional behavior, not frame-time performance or coverage of physical Windows GPUs. The [Linux NVIDIA/Lavapipe dossier](../p2-gpu-visibility-2026-09-23/README.md) keeps the earlier benchmark, exported Player and visual-comparison evidence at its original revision.
An independent review of the complete P2 branch found two reporting/identity gaps, fixed in `22012c1`. The renderer now records the effective visibility mode separately from the requested mode; an occlusion request on a device without HZB is reported as GPU frustum, and missing GPU culling is reported as Direct. A CPU policy test covers both capability fallbacks. The stable slot and full 64-bit generation from `InstanceTracker` now travel in each GPU instance record; compact candidate/visible indices remain frame-local buffer addresses. A focused test covers reorder, mesh replacement, anonymous records and upper generation bits. The reviewer confirmed both fixes. At `22012c1`, full Linux Debug and Release CTest each reported 57 registered tests, zero failures and one existing native-window skip; the ImGui overlay test passed 1/1; pinned Linux SwiftShader passed P2 16/16 and Player diagnostics 1/1; a driverless CPU-only Release selection passed 26/26.
The final [Windows graphics CI run at `22012c1`](https://github.com/emil28092005/Faset_Engine/actions/runs/35922643226) passed all 58 registered tests with no skips on pinned SwiftShader. Its export integration test and the separate [playable-export report](windows-playable-report.json), retained from that run's artifact, record both checked-in 2D/3D Release games after Unicode-path relocation and 120 headless frames each with captured image hashes. Those exported games used the default Direct mode; P2 GPU-mode Player execution was exercised by Windows CTest and by relocated Linux exports, not by this Windows export script. The [native/manual CI run at `22012c1`](https://github.com/emil28092005/Faset_Engine/actions/runs/35922643004) passed on Linux and Windows, including the Windows CPU-only selection and strict documentation build.
@@ -0,0 +1,12 @@
Pinned SwiftShader source: google/swiftshader@1e80438d2b93ef36a7c05f8d2b81233bac0e3d16
VK_ICD_FILENAMES=/home/emil/Desktop/Faset_Engine/.cache/ci-vulkan/swift-build/Linux/vk_swiftshader_icd.json
vulkaninfo --text (selected lines)
apiVersion = 1.3.0 (4206592)
driverVersion = 5.0.0 (20971520)
deviceName = SwiftShader Device (LLVM 10.0.0)
maxPerStageDescriptorStorageBuffers = 30
maxDescriptorSetStorageBuffers = 96
maxDescriptorSetStorageBuffersDynamic = 4
maxComputeWorkGroupInvocations = 256
maxComputeWorkGroupSize: count = 3
shaderDrawParameters = false
@@ -0,0 +1,57 @@
Test project /home/emil/Desktop/.worktrees/Faset_Engine-p2/build/p2-release
Start 37: build_schema_publication
Start 12: render_shader_reflection
Start 36: process_and_cook
Start 49: editor_mcp_stdio
Start 33: lua_cli_contracts
Start 40: ui_widgets
1/26 Test #40: ui_widgets ....................... Passed 0.14 sec
Start 4: assets_blender_bundle
2/26 Test #33: lua_cli_contracts ................ Passed 0.17 sec
Start 57: playable_3d
3/26 Test #49: editor_mcp_stdio ................. Passed 0.26 sec
Start 6: lua_safety_contracts
4/26 Test #4: assets_blender_bundle ............ Passed 0.11 sec
Start 51: core
5/26 Test #57: playable_3d ...................... Passed 0.11 sec
Start 56: playable_2d
6/26 Test #36: process_and_cook ................. Passed 0.29 sec
Start 3: assets_pipeline
7/26 Test #56: playable_2d ...................... Passed 0.05 sec
Start 5: lua_contracts
8/26 Test #3: assets_pipeline .................. Passed 0.04 sec
Start 55: tutorial_physics
9/26 Test #51: core ............................. Passed 0.08 sec
Start 2: runtime_contracts
10/26 Test #55: tutorial_physics ................. Passed 0.01 sec
Start 1: authoring
11/26 Test #6: lua_safety_contracts ............. Passed 0.09 sec
Start 11: render_gpu_shader_contract
12/26 Test #5: lua_contracts .................... Passed 0.03 sec
Start 39: editor_session_settings
13/26 Test #2: runtime_contracts ................ Passed 0.02 sec
14/26 Test #1: authoring ........................ Passed 0.02 sec
Start 38: editor_plugins
Start 54: tutorial_spawning
15/26 Test #11: render_gpu_shader_contract ....... Passed 0.02 sec
16/26 Test #39: editor_session_settings .......... Passed 0.01 sec
Start 31: player_scene_contracts
Start 7: render_graph
17/26 Test #38: editor_plugins ................... Passed 0.01 sec
18/26 Test #54: tutorial_spawning ................ Passed 0.01 sec
Start 14: visibility_policy
Start 52: tutorial_moving
19/26 Test #31: player_scene_contracts ........... Passed 0.01 sec
20/26 Test #7: render_graph ..................... Passed 0.01 sec
21/26 Test #14: visibility_policy ................ Passed 0.01 sec
Start 35: editor_mcp
Start 53: tutorial_following
22/26 Test #52: tutorial_moving .................. Passed 0.02 sec
23/26 Test #35: editor_mcp ....................... Passed 0.01 sec
24/26 Test #53: tutorial_following ............... Passed 0.01 sec
25/26 Test #37: build_schema_publication ......... Passed 1.76 sec
26/26 Test #12: render_shader_reflection ......... Passed 2.41 sec
100% tests passed, 0 tests failed out of 26
Total Test time (real) = 2.41 sec
@@ -0,0 +1,27 @@
$ ctest --test-dir build/p2-release -R render_shader_reload|player_shutdown_diagnostics --output-on-failure -j2
Test project /home/emil/Desktop/.worktrees/Faset_Engine-p2/build/p2-release
Start 10: render_shader_reload
Start 32: player_shutdown_diagnostics
1/2 Test #32: player_shutdown_diagnostics ...... Passed 1.59 sec
2/2 Test #10: render_shader_reload ............. Passed 5.17 sec
100% tests passed, 0 tests failed out of 2
Label Time Summary:
gpu = 6.76 sec*proc (2 tests)
Total Test time (real) = 5.17 sec
exit=0
$ ctest --test-dir build/p2-ui-debug -R editor_debug_overlay --output-on-failure
Test project /home/emil/Desktop/.worktrees/Faset_Engine-p2/build/p2-ui-debug
Start 58: editor_debug_overlay
1/1 Test #58: editor_debug_overlay ............. Passed 2.13 sec
100% tests passed, 0 tests failed out of 1
Label Time Summary:
gpu = 2.13 sec*proc (1 test)
Total Test time (real) = 2.13 sec
exit=0
@@ -0,0 +1,41 @@
Test project /home/emil/Desktop/.worktrees/Faset_Engine-p2/build/p2-release
Start 29: render_gpu_open_sequence
Start 26: render_gpu_lifecycle
1/16 Test #29: render_gpu_open_sequence ......... Passed 2.46 sec
Start 15: gpu_visibility
2/16 Test #26: render_gpu_lifecycle ............. Passed 2.89 sec
Start 30: render_gpu_transparent
3/16 Test #30: render_gpu_transparent ........... Passed 1.58 sec
Start 23: render_gpu_lod
4/16 Test #15: gpu_visibility ................... Passed 2.25 sec
Start 17: render_gpu_capacity
5/16 Test #23: render_gpu_lod ................... Passed 1.26 sec
Start 27: render_gpu_views
6/16 Test #17: render_gpu_capacity .............. Passed 1.24 sec
Start 28: render_gpu_projection
7/16 Test #27: render_gpu_views ................. Passed 1.30 sec
Start 25: render_gpu_near
8/16 Test #28: render_gpu_projection ............ Passed 1.28 sec
Start 22: render_gpu_resize
9/16 Test #25: render_gpu_near .................. Passed 1.31 sec
Start 24: render_gpu_teleport
10/16 Test #22: render_gpu_resize ................ Passed 1.34 sec
Start 19: render_gpu_door
11/16 Test #24: render_gpu_teleport .............. Passed 1.28 sec
Start 21: render_gpu_cut
12/16 Test #19: render_gpu_door .................. Passed 1.28 sec
Start 18: render_gpu_dense
13/16 Test #21: render_gpu_cut ................... Passed 1.42 sec
Start 20: render_gpu_shadow
14/16 Test #18: render_gpu_dense ................. Passed 1.36 sec
Start 16: render_gpu_empty
15/16 Test #16: render_gpu_empty ................. Passed 0.91 sec
16/16 Test #20: render_gpu_shadow ................ Passed 1.27 sec
100% tests passed, 0 tests failed out of 16
Label Time Summary:
gpu = 24.44 sec*proc (16 tests)
p2 = 24.44 sec*proc (16 tests)
Total Test time (real) = 12.33 sec
@@ -0,0 +1,2 @@
gpuVertexMain: sha256=4647ef4fe1a68ab623ee9c19dac56631907f825cba0becd30869c5221c2a0385, OpCapability=[1], spirv-val exit=0
gpuShadowMain: sha256=ffcdb91e70c41ce9452094865546a009b9203140cf8eeb3ad1b4e5868d82b815, OpCapability=[1], spirv-val exit=0
@@ -0,0 +1,435 @@
{
"format": "faset.playable-export-verification",
"version": 1,
"started_utc": "2026-09-23T21:40:31.909912+00:00",
"platform": "win32",
"engine": "D:\\a\\Faset_Engine\\Faset_Engine",
"editor": "D:\\a\\Faset_Engine\\Faset_Engine\\build\\windows-debug\\faset_editor.exe",
"standalone_root": "C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\faset-playable-exports-4j4y2er4",
"frames_per_game": 120,
"status": "passed",
"projects": [
{
"name": "collect-2d",
"dimension": 2,
"source_inputs": [
{
"path": ".gitignore",
"sha256": "3bb936ff6f84f3db041c75d6e207138a9107997cc9ad372621f657456c9c0665"
},
{
"path": "project.faset.json",
"sha256": "27bd0e432381f8f884e78f6d68e9d0dc13d49222e70f3a5e34fef1d57d379b0b"
},
{
"path": "README.md",
"sha256": "7d7b95b16b29b1ed7fb1775d062d5ff599777189414d3e9500d0af0cc998201b"
},
{
"path": "Scenes/main.scene.json",
"sha256": "9e2ad049f60a9ff7f98e31061a8f107648fbf672e5b9292f53e6672e5bae66f1"
},
{
"path": "Scripts/Gameplay.cpp",
"sha256": "99fb965e6589b138049a2e6cf95c5c61baea70761ffab33082a8058c91a687ff"
},
{
"path": "Scripts/Gameplay.hpp",
"sha256": "9d1fa36da50886fa7d84f8a8b3d1ae42856ae74aae1e52be5015b60977634dc0"
}
],
"generation": "03828fcf-eaf8-4f40-867c-3b9983f6fd8c",
"configuration": "Release",
"standalone_directory": "C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\faset-playable-exports-4j4y2er4\\Faset Café 世界\\collect-2d",
"executable": "faset_player.exe",
"package_file_count": 28,
"asset_generations": {},
"device": "SwiftShader Device (LLVM 10.0.0)",
"validation_enabled": false,
"validation_errors": 0,
"completed_frames": 120,
"summary_ms": {
"gpu": {
"max": 124.4213,
"min": 1.8237,
"p50": 1.9292,
"p95": 2.4677,
"samples": 120
},
"render_call": {
"max": 125.3953,
"min": 2.03,
"p50": 2.1378,
"p95": 2.6926,
"samples": 120
},
"renderer_cpu": {
"max": 125.3859,
"min": 2.0269,
"p50": 2.1343,
"p95": 2.6893,
"samples": 120
},
"renderer_readback_cpu": {
"max": 0.8208,
"min": 0.1451,
"p50": 0.1505,
"p95": 0.1779,
"samples": 120
},
"simulation": {
"max": 0.4785,
"min": 0.2313,
"p50": 0.2809,
"p95": 0.3112,
"samples": 120
},
"snapshot": {
"max": 0.2835,
"min": 0.1394,
"p50": 0.2153,
"p95": 0.2375,
"samples": 120
},
"wall": {
"max": 126.454,
"min": 2.5272,
"p50": 2.6398,
"p95": 3.2053,
"samples": 120
}
},
"capture": {
"width": 1280,
"height": 720,
"sampled_colors": 7,
"sha256": "f9d74067d87c1ebf30c6db372a26d93b7285791c8cb0307a24af5adb23bf201a"
},
"source_project_paths_unavailable": true,
"status": "passed"
},
{
"name": "collect-3d",
"dimension": 3,
"source_inputs": [
{
"path": ".gitignore",
"sha256": "3bb936ff6f84f3db041c75d6e207138a9107997cc9ad372621f657456c9c0665"
},
{
"path": "Assets/exit-arch/create.py",
"sha256": "5d9dc30a3f939376d2474cf958065e6daab140c7220444cedecd3bf5edf6e3d1"
},
{
"path": "Assets/exit-arch/manifest.json",
"sha256": "d72d44184d665148109de74782bc695d79392e43be12782e48096a7d79e37c4f"
},
{
"path": "Assets/exit-arch/manifest.json.faset-import.json",
"sha256": "7639d4fa33f2ac52e10d1cf79280a93aeb680399d217fda167acec1c6edcae00"
},
{
"path": "Assets/exit-arch/payload/ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3.glb",
"sha256": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3"
},
{
"path": "Assets/exit-arch/source.blend",
"sha256": "ff2676bec97ab778e531e87a185ad716049ea3b05b4a4f0027a6345737735035"
},
{
"path": "project.faset.json",
"sha256": "9a0ee78fa0ea56982a99cf707948a33db37266ab84de9d3f12a24aabb98afda5"
},
{
"path": "README.md",
"sha256": "a2378adc9dbd5ffb6bfa65abb7770051827d08279e48761046f30d932a5eab8c"
},
{
"path": "Scenes/main.scene.json",
"sha256": "b1b668a2d633deda0074b475460c82019dbcf592b76502906192eaf1f2345a7e"
},
{
"path": "Scripts/Extensions/Beacon.hpp",
"sha256": "650e75bbc55a3339647bcf67ba10fd9b20cece3531bb688b4221155e97959d5e"
},
{
"path": "Scripts/Gameplay.cpp",
"sha256": "c76fbb0bf28a85cc88732a905f2bc9be3e24c58d02cbf2ecccbf77c99093c029"
},
{
"path": "Scripts/Gameplay.hpp",
"sha256": "9d1fa36da50886fa7d84f8a8b3d1ae42856ae74aae1e52be5015b60977634dc0"
}
],
"import": {
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
"cache_hit": false,
"diagnostics": [],
"generation": "e8eb8805673cc22596d1c5b48fc6b8fbdf600d1c6a15c9633d14014a7eb1d11f",
"manifest": {
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
"files": [
{
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh",
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
"size": 928
},
{
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh",
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
"size": 928
},
{
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh",
"sha256": "3875c16ea628d4126373ebfe07816621fbad3961596a2fcd112f1eec0e378071",
"size": 928
}
],
"generation": "e8eb8805673cc22596d1c5b48fc6b8fbdf600d1c6a15c9633d14014a7eb1d11f",
"importer": "faset-gltf-1/cgltf-1.15",
"input_key": {
"bundle_sha256": "d72d44184d665148109de74782bc695d79392e43be12782e48096a7d79e37c4f",
"dependencies": {},
"importer": "faset-gltf-1/cgltf-1.15",
"settings": {},
"source": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
"target_profile": "desktop-static-pbr-v1",
"toolchain": {
"cgltf": "360db1a95480fe102ae9c69b27c5d101167ff5ba",
"stb": "2c980bb59875b0d32144a71867fbdebb2f77cd20"
}
},
"kind": "scene",
"materials": [
{
"alpha_cutoff": 0.5,
"alpha_mode": "OPAQUE",
"base_color": [
0.2199999988079071,
0.28999999165534973,
0.3400000035762787,
1.0
],
"base_color_texture": -1,
"double_sided": true,
"emissive": [
0.0,
0.0,
0.0
],
"emissive_texture": -1,
"format": "faset.material",
"id": "material-bb63b094febbf90bb7049c9bcf7587bc",
"metallic": 0.07999999821186066,
"metallic_roughness_texture": -1,
"name": "Weathered stone",
"normal_texture": -1,
"occlusion_texture": -1,
"roughness": 0.800000011920929,
"unlit": false,
"version": 1
}
],
"meshes": [
{
"id": "mesh-fc069a07a87e0f831fd92efdbc4efa1f",
"name": "Cube.001",
"primitives": [
{
"material": 0,
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh"
}
]
},
{
"id": "mesh-0961e2a3f92977836a3aa80cab09277e",
"name": "Cube.002",
"primitives": [
{
"material": 0,
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh"
}
]
},
{
"id": "mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
"name": "Cube.003",
"primitives": [
{
"material": 0,
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh"
}
]
}
],
"nodes": [
{
"id": "node-cec6e8cea80cf5a98ba3263a0156bee4",
"local_transform": [
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
1.4500000476837158,
1.2999999523162842,
1.0
],
"mesh": 0,
"name": "Left post",
"parent_id": "",
"stable_source_id": true
},
{
"id": "node-5f8a90a6c4d27020d20bd4fa81d1d958",
"local_transform": [
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
1.4500000476837158,
-1.2999999523162842,
1.0
],
"mesh": 1,
"name": "Right post",
"parent_id": "",
"stable_source_id": true
},
{
"id": "node-482463e486a8d1fd741340c653cd128f",
"local_transform": [
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
3.0,
0.0,
1.0
],
"mesh": 2,
"name": "Lintel",
"parent_id": "",
"stable_source_id": true
}
],
"outputs": [
"node-cec6e8cea80cf5a98ba3263a0156bee4",
"node-5f8a90a6c4d27020d20bd4fa81d1d958",
"node-482463e486a8d1fd741340c653cd128f",
"mesh-fc069a07a87e0f831fd92efdbc4efa1f",
"mesh-0961e2a3f92977836a3aa80cab09277e",
"mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
"material-bb63b094febbf90bb7049c9bcf7587bc"
],
"payload_source": "D:\\a\\Faset_Engine\\Faset_Engine\\.cache\\windows-playable-exports\\Faset Café 世界\\collect-3d\\Assets\\exit-arch\\payload/ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3.glb",
"schema_version": 1,
"settings": {},
"source": "D:\\a\\Faset_Engine\\Faset_Engine\\.cache\\windows-playable-exports\\Faset Café 世界\\collect-3d\\Assets\\exit-arch\\manifest.json",
"source_sha256": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
"textures": []
},
"previous_generation": "",
"removed_output_ids": []
},
"generation": "fb34b94f-e92e-4f33-942e-8e455a80ba05",
"configuration": "Release",
"standalone_directory": "C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\faset-playable-exports-4j4y2er4\\Faset Café 世界\\collect-3d",
"executable": "faset_player.exe",
"package_file_count": 33,
"asset_generations": {
"5832763b-3ed0-44d6-9088-0b524f196a91": "e8eb8805673cc22596d1c5b48fc6b8fbdf600d1c6a15c9633d14014a7eb1d11f"
},
"device": "SwiftShader Device (LLVM 10.0.0)",
"validation_enabled": false,
"validation_errors": 0,
"completed_frames": 120,
"summary_ms": {
"gpu": {
"max": 192.1948,
"min": 14.8173,
"p50": 15.0605,
"p95": 19.4159,
"samples": 120
},
"render_call": {
"max": 193.3314,
"min": 15.0805,
"p50": 15.3525,
"p95": 19.7263,
"samples": 120
},
"renderer_cpu": {
"max": 193.3234,
"min": 15.0747,
"p50": 15.3444,
"p95": 19.7182,
"samples": 120
},
"renderer_readback_cpu": {
"max": 0.8808,
"min": 0.1453,
"p50": 0.1501,
"p95": 0.1755,
"samples": 120
},
"simulation": {
"max": 0.4996,
"min": 0.2851,
"p50": 0.42,
"p95": 0.4731,
"samples": 120
},
"snapshot": {
"max": 2.7253,
"min": 0.1887,
"p50": 0.2443,
"p95": 0.2837,
"samples": 120
},
"wall": {
"max": 197.1112,
"min": 15.7803,
"p50": 16.0214,
"p95": 20.4582,
"samples": 120
}
},
"capture": {
"width": 1280,
"height": 720,
"sampled_colors": 43,
"sha256": "0edc88eef9f641a780ef44664f58c811a22bd201c8d29e1fcb7531b88f251900"
},
"source_project_paths_unavailable": true,
"status": "passed"
}
],
"finished_utc": "2026-09-23T21:44:53.130001+00:00"
}