@forgeax/engine-render 0.1.21 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. package/README.md +281 -38
  2. package/dist/assembly/backend-contract.d.ts +13 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/bundler-contract.d.ts +9 -0
  5. package/dist/assembly/bundler-contract.d.ts.map +1 -0
  6. package/dist/assembly/device-feature-admission.d.ts +8 -0
  7. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  8. package/dist/assembly/extended-lighting-fallback.d.ts +13 -0
  9. package/dist/assembly/extended-lighting-fallback.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +7 -235
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/host-contract.d.ts +10 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +3 -2
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material/standard-layer-projection.d.ts +10 -0
  17. package/dist/assembly/material/standard-layer-projection.d.ts.map +1 -0
  18. package/dist/assembly/material-shader-policy.d.ts +168 -0
  19. package/dist/assembly/material-shader-policy.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-prewarm.d.ts +21 -0
  21. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -0
  22. package/dist/assembly/mesh-ssbo-grow.d.ts +88 -0
  23. package/dist/assembly/mesh-ssbo-grow.d.ts.map +1 -0
  24. package/dist/assembly/recovery/device-loss-fanout.d.ts +14 -0
  25. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -0
  26. package/dist/assembly/recovery/generation.d.ts +46 -0
  27. package/dist/assembly/recovery/generation.d.ts.map +1 -0
  28. package/dist/assembly/recovery/recovery-attempt.d.ts +63 -0
  29. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -0
  30. package/dist/assembly/recovery/renderer-recover.d.ts +115 -0
  31. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -0
  32. package/dist/assembly/renderer-facade.d.ts +10 -0
  33. package/dist/assembly/renderer-facade.d.ts.map +1 -0
  34. package/dist/assembly/renderer-frame-transaction.d.ts +17 -0
  35. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  36. package/dist/assembly/renderer-helpers.d.ts +19 -0
  37. package/dist/assembly/renderer-helpers.d.ts.map +1 -0
  38. package/dist/assembly/renderer-lifecycle.d.ts +34 -0
  39. package/dist/assembly/renderer-lifecycle.d.ts.map +1 -1
  40. package/dist/assembly/shader-prewarm-policy.d.ts +15 -0
  41. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -0
  42. package/dist/assembly/webgpu-ready-contract.d.ts +9 -0
  43. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-ready.d.ts +55 -0
  45. package/dist/assembly/webgpu-ready.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-renderer.d.ts +152 -0
  47. package/dist/assembly/webgpu-renderer.d.ts.map +1 -0
  48. package/dist/authoring.mjs +1 -1
  49. package/dist/{chunk-PCHBPYML.mjs → chunk-GE3SDD72.mjs} +37 -5
  50. package/dist/chunk-GE3SDD72.mjs.map +1 -0
  51. package/dist/chunk-KZFTK6DO.mjs +1191 -0
  52. package/dist/chunk-KZFTK6DO.mjs.map +1 -0
  53. package/dist/{chunk-FS2KNUQH.mjs → chunk-Q752SHI5.mjs} +332 -568
  54. package/dist/chunk-Q752SHI5.mjs.map +1 -0
  55. package/dist/{chunk-6OPXDQ2E.mjs → chunk-RR5L4SRS.mjs} +33 -294
  56. package/dist/chunk-RR5L4SRS.mjs.map +1 -0
  57. package/dist/chunk-TFH5I7JJ.mjs +296 -0
  58. package/dist/chunk-TFH5I7JJ.mjs.map +1 -0
  59. package/dist/chunk-UQYS7FRM.mjs +1003 -0
  60. package/dist/chunk-UQYS7FRM.mjs.map +1 -0
  61. package/dist/chunk-YKB5DQV7.mjs +345 -0
  62. package/dist/chunk-YKB5DQV7.mjs.map +1 -0
  63. package/dist/{chunk-5YADUCA7.mjs → chunk-YRUYGA4A.mjs} +1189 -1217
  64. package/dist/chunk-YRUYGA4A.mjs.map +1 -0
  65. package/dist/chunk-Z3YYH2MB.mjs +5082 -0
  66. package/dist/chunk-Z3YYH2MB.mjs.map +1 -0
  67. package/dist/cluster-binner.d.ts +5 -0
  68. package/dist/cluster-binner.d.ts.map +1 -1
  69. package/dist/components/index.d.ts +3 -0
  70. package/dist/components/index.d.ts.map +1 -1
  71. package/dist/components/light-helpers.d.ts +4 -0
  72. package/dist/components/light-helpers.d.ts.map +1 -1
  73. package/dist/components/light-probe.d.ts +9 -0
  74. package/dist/components/light-probe.d.ts.map +1 -0
  75. package/dist/components/rect-area-light.d.ts +12 -0
  76. package/dist/components/rect-area-light.d.ts.map +1 -0
  77. package/dist/components/scene-instance.d.ts +4 -0
  78. package/dist/components/scene-instance.d.ts.map +1 -1
  79. package/dist/components/spot-light.d.ts +3 -0
  80. package/dist/components/spot-light.d.ts.map +1 -1
  81. package/dist/construct-renderer.mjs +27276 -23232
  82. package/dist/construct-renderer.mjs.map +1 -1
  83. package/dist/device/device-scope.d.ts +2 -0
  84. package/dist/device/device-scope.d.ts.map +1 -1
  85. package/dist/device/gpu-residency.d.ts +32 -5
  86. package/dist/device/gpu-residency.d.ts.map +1 -1
  87. package/dist/device/lifecycle-transaction.d.ts +2 -0
  88. package/dist/device/lifecycle-transaction.d.ts.map +1 -0
  89. package/dist/environment/frame.d.ts +5 -0
  90. package/dist/environment/frame.d.ts.map +1 -1
  91. package/dist/environment/inspection.d.ts +7 -0
  92. package/dist/environment/inspection.d.ts.map +1 -1
  93. package/dist/environment/lifecycle.d.ts +20 -2
  94. package/dist/environment/lifecycle.d.ts.map +1 -1
  95. package/dist/errors/gpu-driven.d.ts +26 -0
  96. package/dist/errors/gpu-driven.d.ts.map +1 -0
  97. package/dist/errors/index.d.ts +1 -0
  98. package/dist/errors/index.d.ts.map +1 -1
  99. package/dist/errors/recover.d.ts +67 -3
  100. package/dist/errors/recover.d.ts.map +1 -1
  101. package/dist/errors/render.d.ts +39 -1
  102. package/dist/errors/render.d.ts.map +1 -1
  103. package/dist/extract/contracts.d.ts +899 -0
  104. package/dist/extract/contracts.d.ts.map +1 -0
  105. package/dist/extract/gpu-driven.d.ts +50 -0
  106. package/dist/extract/gpu-driven.d.ts.map +1 -0
  107. package/dist/extract/visibility.d.ts.map +1 -1
  108. package/dist/features/host.d.ts +2 -0
  109. package/dist/features/host.d.ts.map +1 -1
  110. package/dist/features/prepared-gpu-work.d.ts +3 -0
  111. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  112. package/dist/features/prepared-graphics-store.d.ts +2 -0
  113. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  114. package/dist/gpu-driven/batch-topology.d.ts +34 -0
  115. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  116. package/dist/gpu-driven/prepared-draw.d.ts +63 -0
  117. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
  118. package/dist/gpu-driven/production-raster.d.ts +126 -2
  119. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  120. package/dist/gpu-driven/view-gpu.d.ts +64 -1
  121. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  122. package/dist/gpu-scene-schema.d.ts +14 -0
  123. package/dist/gpu-scene-schema.d.ts.map +1 -1
  124. package/dist/gpu-scene.d.ts +9 -1
  125. package/dist/gpu-scene.d.ts.map +1 -1
  126. package/dist/gpu-usage.d.ts +0 -1
  127. package/dist/gpu-usage.d.ts.map +1 -1
  128. package/dist/hdrp-buffers.d.ts +3 -3
  129. package/dist/hdrp-buffers.d.ts.map +1 -1
  130. package/dist/ibl/IblPipelineCache.d.ts +7 -6
  131. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  132. package/dist/ibl/skylight-bind-group.d.ts +7 -1
  133. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  134. package/dist/index.d.ts +13 -2
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.mjs +90 -5
  137. package/dist/index.mjs.map +1 -1
  138. package/dist/inspection-types.d.ts +163 -1
  139. package/dist/inspection-types.d.ts.map +1 -1
  140. package/dist/internal.d.ts +9 -0
  141. package/dist/internal.d.ts.map +1 -1
  142. package/dist/internal.mjs +23 -2
  143. package/dist/internal.mjs.map +1 -1
  144. package/dist/light-buffer-layout.d.ts +60 -148
  145. package/dist/light-buffer-layout.d.ts.map +1 -1
  146. package/dist/materials.d.ts +34 -10
  147. package/dist/materials.d.ts.map +1 -1
  148. package/dist/mesh-material-bindings.d.ts +56 -0
  149. package/dist/mesh-material-bindings.d.ts.map +1 -1
  150. package/dist/occlusion-proxy.d.ts +4 -0
  151. package/dist/occlusion-proxy.d.ts.map +1 -0
  152. package/dist/pbr-pipeline.d.ts +58 -21
  153. package/dist/pbr-pipeline.d.ts.map +1 -1
  154. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  155. package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -1
  156. package/dist/pipeline/standard-lighting/light-frame.d.ts +3 -3
  157. package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -1
  158. package/dist/pipeline/standard-lighting/topology.d.ts +1 -1
  159. package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -1
  160. package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -1
  161. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  162. package/dist/pipeline-builder.d.ts +2 -0
  163. package/dist/pipeline-builder.d.ts.map +1 -1
  164. package/dist/pipeline-spec.d.ts +1 -1
  165. package/dist/pipeline-spec.d.ts.map +1 -1
  166. package/dist/plugin.d.ts.map +1 -1
  167. package/dist/points-lines/prepare.d.ts +3 -0
  168. package/dist/points-lines/prepare.d.ts.map +1 -1
  169. package/dist/points-lines/standard-owner.d.ts +33 -0
  170. package/dist/points-lines/standard-owner.d.ts.map +1 -0
  171. package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
  172. package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
  173. package/dist/prepare/extended-lighting/resources.d.ts +72 -0
  174. package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
  175. package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
  176. package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
  177. package/dist/prepare/extended-lighting/state.d.ts +24 -0
  178. package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
  179. package/dist/record/frame-lighting.d.ts +8 -6
  180. package/dist/record/frame-lighting.d.ts.map +1 -1
  181. package/dist/record/frame-snapshot.d.ts +55 -10
  182. package/dist/record/frame-snapshot.d.ts.map +1 -1
  183. package/dist/record/frame-targets.d.ts.map +1 -1
  184. package/dist/record/frame.d.ts +21 -5
  185. package/dist/record/frame.d.ts.map +1 -1
  186. package/dist/record/gpu-timing.d.ts +19 -7
  187. package/dist/record/gpu-timing.d.ts.map +1 -1
  188. package/dist/record/helpers.d.ts +0 -20
  189. package/dist/record/helpers.d.ts.map +1 -1
  190. package/dist/record/main-pass-geometry.d.ts +20 -2
  191. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  192. package/dist/record/main-pass-material.d.ts +10 -18
  193. package/dist/record/main-pass-material.d.ts.map +1 -1
  194. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  195. package/dist/record/main-pass.d.ts.map +1 -1
  196. package/dist/record/mesh-ssbo.d.ts +11 -3
  197. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  198. package/dist/record/recovery-pipeline.d.ts +30 -0
  199. package/dist/record/recovery-pipeline.d.ts.map +1 -0
  200. package/dist/record/render-context.d.ts +82 -9
  201. package/dist/record/render-context.d.ts.map +1 -1
  202. package/dist/record/shadow-pass.d.ts.map +1 -1
  203. package/dist/record/typed-frame-graph.d.ts +49 -2
  204. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  205. package/dist/record/view-ubo.d.ts +1 -2
  206. package/dist/record/view-ubo.d.ts.map +1 -1
  207. package/dist/recovery/render-system-candidate.d.ts +65 -0
  208. package/dist/recovery/render-system-candidate.d.ts.map +1 -0
  209. package/dist/reflection/inspection.d.ts +10 -0
  210. package/dist/reflection/inspection.d.ts.map +1 -0
  211. package/dist/reflection/projection.d.ts +49 -0
  212. package/dist/reflection/projection.d.ts.map +1 -1
  213. package/dist/reflection/record-owner.d.ts +60 -0
  214. package/dist/reflection/record-owner.d.ts.map +1 -0
  215. package/dist/render-contract.d.ts +78 -15
  216. package/dist/render-contract.d.ts.map +1 -1
  217. package/dist/render-pipeline.d.ts +7 -0
  218. package/dist/render-pipeline.d.ts.map +1 -1
  219. package/dist/render-system-extract-tail.d.ts +12 -0
  220. package/dist/render-system-extract-tail.d.ts.map +1 -0
  221. package/dist/render-system-extract.d.ts +252 -30
  222. package/dist/render-system-extract.d.ts.map +1 -1
  223. package/dist/render-system.d.ts +140 -5
  224. package/dist/render-system.d.ts.map +1 -1
  225. package/dist/scene/probe-blend-record.d.ts +22 -0
  226. package/dist/scene/probe-blend-record.d.ts.map +1 -0
  227. package/dist/scene/probe-blend.d.ts +142 -0
  228. package/dist/scene/probe-blend.d.ts.map +1 -0
  229. package/dist/scene/render-scene-types.d.ts +0 -6
  230. package/dist/scene/render-scene-types.d.ts.map +1 -1
  231. package/dist/scene/render-scene.d.ts +122 -9
  232. package/dist/scene/render-scene.d.ts.map +1 -1
  233. package/dist/scene/visibility/bounds.d.ts +20 -0
  234. package/dist/scene/visibility/bounds.d.ts.map +1 -0
  235. package/dist/scene/visibility/budget.d.ts +16 -0
  236. package/dist/scene/visibility/budget.d.ts.map +1 -0
  237. package/dist/scene/visibility/facet.d.ts +73 -0
  238. package/dist/scene/visibility/facet.d.ts.map +1 -0
  239. package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
  240. package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
  241. package/dist/scene/visibility/gpu-lod.d.ts +46 -0
  242. package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
  243. package/dist/scene/visibility/inspection.d.ts +132 -0
  244. package/dist/scene/visibility/inspection.d.ts.map +1 -0
  245. package/dist/scene/visibility/lod-selector.d.ts +25 -0
  246. package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
  247. package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
  248. package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
  249. package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
  250. package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
  251. package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
  252. package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
  253. package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
  254. package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
  255. package/dist/scene/visibility/types.d.ts +34 -0
  256. package/dist/scene/visibility/types.d.ts.map +1 -0
  257. package/dist/ssr/admission.d.ts +122 -0
  258. package/dist/ssr/admission.d.ts.map +1 -0
  259. package/dist/ssr/composition.d.ts +32 -0
  260. package/dist/ssr/composition.d.ts.map +1 -0
  261. package/dist/ssr/errors.d.ts +39 -0
  262. package/dist/ssr/errors.d.ts.map +1 -0
  263. package/dist/ssr/identity.d.ts +13 -0
  264. package/dist/ssr/identity.d.ts.map +1 -0
  265. package/dist/systems/skin-palette-allocator.d.ts +1 -1
  266. package/dist/temporal/frame-coordinator.d.ts +13 -0
  267. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  268. package/dist/temporal/frame.d.ts +2 -0
  269. package/dist/temporal/frame.d.ts.map +1 -1
  270. package/dist/temporal/index.mjs +6 -5
  271. package/dist/temporal/taa-history-store.d.ts +15 -1
  272. package/dist/temporal/taa-history-store.d.ts.map +1 -1
  273. package/dist/temporal/transaction.d.ts +5 -0
  274. package/dist/temporal/transaction.d.ts.map +1 -1
  275. package/dist/temporal/view.d.ts +7 -0
  276. package/dist/temporal/view.d.ts.map +1 -1
  277. package/dist/tilemap-chunk-extract-system.d.ts +1 -1
  278. package/dist/typed-render-graph-primitives.d.ts +4 -0
  279. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  280. package/dist/volume/passes.d.ts +8 -4
  281. package/dist/volume/passes.d.ts.map +1 -1
  282. package/package.json +20 -20
  283. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +5 -0
  284. package/src/__tests__/detached-inspection.integration.test.ts +6 -0
  285. package/src/__tests__/device-feature-admission.unit.test.ts +19 -1
  286. package/src/__tests__/device-loss-fanout.unit.test.ts +107 -0
  287. package/src/__tests__/device-scope-lifecycle.unit.test.ts +21 -0
  288. package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
  289. package/src/__tests__/environment-generation.integration.test.ts +39 -0
  290. package/src/__tests__/evidence-identity.ts +13 -0
  291. package/src/__tests__/evidence-identity.unit.test.ts +24 -0
  292. package/src/__tests__/expose-renderer-errors.unit.test.ts +34 -0
  293. package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
  294. package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
  295. package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
  296. package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
  297. package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
  298. package/src/__tests__/factory-contract.integration.test.ts +154 -6
  299. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +4 -1
  300. package/src/__tests__/frame-observation.contract.test.ts +15 -0
  301. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
  302. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +1 -0
  303. package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +1 -0
  304. package/src/__tests__/gpu-driven-production.integration.test.ts +572 -9
  305. package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
  306. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
  307. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +89 -2
  308. package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
  309. package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
  310. package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
  311. package/src/__tests__/gpu-lod-evidence.ts +188 -0
  312. package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
  313. package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
  314. package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
  315. package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
  316. package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
  317. package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
  318. package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
  319. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
  320. package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
  321. package/src/__tests__/gpu-scene.unit.test.ts +49 -3
  322. package/src/__tests__/ibl/face-uniforms.unit.test.ts +2 -0
  323. package/src/__tests__/ibl-residency-publication.unit.test.ts +113 -0
  324. package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
  325. package/src/__tests__/light-inspection.unit.test.ts +55 -0
  326. package/src/__tests__/light-resource-error.unit.test.ts +43 -0
  327. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
  328. package/src/__tests__/lod-bounds.unit.test.ts +42 -0
  329. package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
  330. package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
  331. package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
  332. package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
  333. package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
  334. package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
  335. package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
  336. package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
  337. package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
  338. package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
  339. package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
  340. package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
  341. package/src/__tests__/lod-selector.profile.test.ts +35 -0
  342. package/src/__tests__/lod-selector.unit.test.ts +68 -0
  343. package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
  344. package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
  345. package/src/__tests__/ltc-resources.unit.test.ts +32 -0
  346. package/src/__tests__/material-contract-inventory.unit.test.ts +41 -9
  347. package/src/__tests__/material-cooked-projection.unit.test.ts +19 -1
  348. package/src/__tests__/material-static-dynamic-route.unit.test.ts +29 -0
  349. package/src/__tests__/material-stride-surface.unit.test.ts +7 -3
  350. package/src/__tests__/materials-standard-contract.unit.test.ts +104 -0
  351. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
  352. package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
  353. package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
  354. package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
  355. package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
  356. package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
  357. package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
  358. package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
  359. package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
  360. package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
  361. package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
  362. package/src/__tests__/occlusion-query.evidence.ts +178 -0
  363. package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
  364. package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
  365. package/src/__tests__/physical-clearcoat.integration.test.ts +89 -0
  366. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
  367. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +1 -1
  368. package/src/__tests__/probe-bindings.unit.test.ts +200 -0
  369. package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
  370. package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
  371. package/src/__tests__/probe-capacity.integration.test.ts +97 -0
  372. package/src/__tests__/probe-recovery.integration.test.ts +104 -0
  373. package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
  374. package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
  375. package/src/__tests__/profiler-phase-token.test.ts +1 -0
  376. package/src/__tests__/recover-error-policy-owner.unit.test.ts +6 -3
  377. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +140 -0
  378. package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
  379. package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
  380. package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
  381. package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
  382. package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
  383. package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
  384. package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
  385. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
  386. package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
  387. package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
  388. package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
  389. package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
  390. package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
  391. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +160 -17
  392. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +47 -0
  393. package/src/__tests__/renderer-generation-assembly.unit.test.ts +77 -0
  394. package/src/__tests__/renderer-generation-failure.unit.test.ts +108 -0
  395. package/src/__tests__/renderer-producer-root-matrix.integration.test.ts +33 -0
  396. package/src/__tests__/renderer-recovery-capability-matrix.unit.test.ts +59 -0
  397. package/src/__tests__/renderer-recovery-contract.unit.test.ts +73 -0
  398. package/src/__tests__/renderer-recovery-lifecycle.unit.test.ts +216 -0
  399. package/src/__tests__/renderer-target-history-recovery.integration.test.ts +80 -0
  400. package/src/__tests__/shader-manifest-fixture.ts +13 -16
  401. package/src/__tests__/shader-stage-surface.unit.test.ts +1 -1
  402. package/src/__tests__/skin-motion-regression.unit.test.ts +22 -0
  403. package/src/__tests__/skinned-shadow-caster.test.ts +2 -2
  404. package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
  405. package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
  406. package/src/__tests__/ssr-composition.unit.test.ts +46 -0
  407. package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
  408. package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
  409. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +67 -0
  410. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +7 -0
  411. package/src/__tests__/standard-layer-projection.unit.test.ts +23 -0
  412. package/src/__tests__/standard-lighting-inspection.integration.test.ts +1 -1
  413. package/src/__tests__/standard-lighting-write.unit.test.ts +66 -2
  414. package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
  415. package/src/__tests__/temporal-view.unit.test.ts +3 -3
  416. package/src/__tests__/transmission-prewarm.unit.test.ts +111 -32
  417. package/src/__tests__/visibility-budget.integration.test.ts +140 -0
  418. package/src/__tests__/visibility-budget.unit.test.ts +70 -0
  419. package/src/__tests__/visibility-extract.integration.test.ts +11 -6
  420. package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
  421. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
  422. package/src/__tests__/volumetric-fog-topology.unit.test.ts +3 -1
  423. package/src/assembly/backend-contract.ts +13 -0
  424. package/src/assembly/bundler-contract.ts +9 -0
  425. package/src/assembly/device-feature-admission.ts +26 -9
  426. package/src/assembly/extended-lighting-fallback.ts +216 -0
  427. package/src/assembly/factory.ts +81 -9634
  428. package/src/assembly/host-contract.ts +10 -0
  429. package/src/assembly/material/assembly.ts +18 -2
  430. package/src/assembly/material/standard-layer-projection.ts +16 -0
  431. package/src/assembly/material-shader-policy.ts +854 -0
  432. package/src/assembly/material-shader-prewarm.ts +88 -0
  433. package/src/assembly/mesh-ssbo-grow.ts +270 -0
  434. package/src/assembly/recovery/device-loss-fanout.ts +89 -0
  435. package/src/assembly/recovery/generation.ts +141 -0
  436. package/src/assembly/recovery/recovery-attempt.ts +800 -0
  437. package/src/assembly/recovery/renderer-recover.ts +906 -0
  438. package/src/assembly/renderer-facade.ts +342 -0
  439. package/src/assembly/renderer-frame-transaction.ts +45 -0
  440. package/src/assembly/renderer-helpers.ts +99 -0
  441. package/src/assembly/renderer-lifecycle.ts +159 -0
  442. package/src/assembly/shader-prewarm-policy.ts +157 -0
  443. package/src/assembly/webgpu-ready-contract.ts +14 -0
  444. package/src/assembly/webgpu-ready.ts +4079 -0
  445. package/src/assembly/webgpu-renderer.ts +4095 -0
  446. package/src/cluster-binner.ts +31 -0
  447. package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
  448. package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
  449. package/src/components/camera.ts +1 -1
  450. package/src/components/index.ts +3 -0
  451. package/src/components/light-helpers.ts +52 -1
  452. package/src/components/light-probe.ts +13 -0
  453. package/src/components/rect-area-light.ts +15 -0
  454. package/src/components/scene-instance.ts +6 -0
  455. package/src/components/spot-light.ts +3 -0
  456. package/src/debug-draw-glue.ts +1 -1
  457. package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
  458. package/src/device/device-scope.ts +35 -6
  459. package/src/device/gpu-residency.ts +334 -35
  460. package/src/device/lifecycle-transaction.ts +12 -0
  461. package/src/environment/frame.ts +6 -0
  462. package/src/environment/inspection.ts +10 -0
  463. package/src/environment/lifecycle.ts +122 -9
  464. package/src/errors/gpu-driven.ts +92 -0
  465. package/src/errors/index.ts +1 -0
  466. package/src/errors/recover.ts +108 -5
  467. package/src/errors/render.ts +72 -1
  468. package/src/extract/camera.ts +3 -3
  469. package/src/extract/contracts.ts +974 -0
  470. package/src/extract/gpu-driven.ts +108 -0
  471. package/src/extract/visibility.ts +0 -23
  472. package/src/features/host.ts +16 -0
  473. package/src/features/prepared-gpu-work.ts +20 -2
  474. package/src/features/prepared-graphics-store.ts +17 -0
  475. package/src/gpu-driven/batch-topology.ts +206 -28
  476. package/src/gpu-driven/prepared-draw.ts +208 -0
  477. package/src/gpu-driven/production-raster.ts +1046 -39
  478. package/src/gpu-driven/view-gpu.ts +411 -29
  479. package/src/gpu-scene-schema.ts +13 -0
  480. package/src/gpu-scene.ts +137 -67
  481. package/src/gpu-usage.ts +0 -1
  482. package/src/hdrp-buffers.ts +6 -6
  483. package/src/ibl/IblPipelineCache.ts +134 -50
  484. package/src/ibl/skylight-bind-group.ts +26 -0
  485. package/src/index.ts +83 -1
  486. package/src/inspection-types.ts +220 -1
  487. package/src/internal.ts +38 -0
  488. package/src/light-buffer-layout.ts +157 -324
  489. package/src/materials.ts +278 -47
  490. package/src/mesh-material-bindings.ts +59 -0
  491. package/src/occlusion-proxy.ts +64 -0
  492. package/src/pbr-pipeline.ts +290 -60
  493. package/src/pipeline/standard-forward-lane.ts +47 -0
  494. package/src/pipeline/standard-lighting/graph.ts +2 -1
  495. package/src/pipeline/standard-lighting/light-frame.ts +3 -2
  496. package/src/pipeline/standard-lighting/topology.ts +1 -1
  497. package/src/pipeline/standard-lighting/transport.ts +2 -1
  498. package/src/pipeline/standard-pipeline.ts +2 -0
  499. package/src/pipeline-builder.ts +5 -2
  500. package/src/pipeline-spec.ts +12 -1
  501. package/src/plugin.ts +4 -0
  502. package/src/points-lines/__tests__/cache-recovery.unit.test.ts +22 -0
  503. package/src/points-lines/prepare.ts +9 -0
  504. package/src/points-lines/standard-owner.ts +403 -0
  505. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
  506. package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
  507. package/src/prepare/extended-lighting/resources.ts +389 -0
  508. package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
  509. package/src/prepare/extended-lighting/state.ts +92 -0
  510. package/src/record/__tests__/frame-targets-recovery.unit.test.ts +60 -0
  511. package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
  512. package/src/record/__tests__/main-pass-geometry.unit.test.ts +26 -1
  513. package/src/record/__tests__/mesh-ssbo.unit.test.ts +38 -0
  514. package/src/record/__tests__/recovery-pipeline.unit.test.ts +124 -0
  515. package/src/record/__tests__/sprite-material-abi.unit.test.ts +28 -13
  516. package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +47 -4
  517. package/src/record/__tests__/temporal-payload.unit.test.ts +29 -28
  518. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +21 -2
  519. package/src/record/frame-lighting.ts +252 -53
  520. package/src/record/frame-snapshot.ts +72 -12
  521. package/src/record/frame-targets.ts +11 -1
  522. package/src/record/frame.ts +416 -95
  523. package/src/record/gpu-timing.ts +108 -44
  524. package/src/record/helpers.ts +1 -59
  525. package/src/record/main-pass-geometry.ts +434 -44
  526. package/src/record/main-pass-material.ts +324 -210
  527. package/src/record/main-pass-sprite-draws.ts +58 -92
  528. package/src/record/main-pass.ts +94 -6
  529. package/src/record/mesh-ssbo.ts +79 -46
  530. package/src/record/recovery-pipeline.ts +695 -0
  531. package/src/record/render-context.ts +99 -7
  532. package/src/record/shadow-pass.ts +66 -40
  533. package/src/record/typed-frame-graph.ts +270 -84
  534. package/src/record/view-ubo.ts +17 -27
  535. package/src/recovery/render-system-candidate.ts +839 -0
  536. package/src/reflection/inspection.ts +67 -0
  537. package/src/reflection/projection.ts +196 -1
  538. package/src/reflection/record-owner.ts +1283 -0
  539. package/src/render-contract.ts +82 -12
  540. package/src/render-pipeline.ts +5 -0
  541. package/src/render-system-extract-tail.ts +2983 -0
  542. package/src/render-system-extract.ts +290 -2784
  543. package/src/render-system.ts +1597 -1192
  544. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
  545. package/src/scene/probe-blend-record.ts +54 -0
  546. package/src/scene/probe-blend.ts +813 -0
  547. package/src/scene/render-scene-types.ts +0 -7
  548. package/src/scene/render-scene.ts +972 -184
  549. package/src/scene/visibility/bounds.ts +57 -0
  550. package/src/scene/visibility/budget.ts +40 -0
  551. package/src/scene/visibility/facet.ts +400 -0
  552. package/src/scene/visibility/gpu-frame-timing.ts +101 -0
  553. package/src/scene/visibility/gpu-lod.ts +119 -0
  554. package/src/scene/visibility/inspection.ts +313 -0
  555. package/src/scene/visibility/lod-selector.ts +84 -0
  556. package/src/scene/visibility/occlusion-confidence.ts +478 -0
  557. package/src/scene/visibility/occlusion-pass.ts +165 -0
  558. package/src/scene/visibility/occlusion-query-pool.ts +178 -0
  559. package/src/scene/visibility/occlusion-runtime.ts +672 -0
  560. package/src/scene/visibility/types.ts +50 -0
  561. package/src/ssr/admission.ts +451 -0
  562. package/src/ssr/composition.ts +73 -0
  563. package/src/ssr/errors.ts +76 -0
  564. package/src/ssr/identity.ts +12 -0
  565. package/src/systems/skin-palette-allocator.ts +1 -1
  566. package/src/temporal/frame-coordinator.ts +30 -1
  567. package/src/temporal/frame.ts +14 -1
  568. package/src/temporal/taa-history-store.ts +46 -2
  569. package/src/temporal/temporal-view.ts +1 -1
  570. package/src/temporal/transaction.ts +9 -0
  571. package/src/temporal/view.ts +11 -0
  572. package/src/tilemap-chunk-extract-system.ts +5 -5
  573. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +19 -12
  574. package/src/typed-render-graph-primitives.ts +48 -0
  575. package/src/volume/passes.ts +46 -49
  576. package/dist/.tsbuildinfo +0 -1
  577. package/dist/chunk-5YADUCA7.mjs.map +0 -1
  578. package/dist/chunk-6OPXDQ2E.mjs.map +0 -1
  579. package/dist/chunk-BXBQQKFQ.mjs +0 -67
  580. package/dist/chunk-BXBQQKFQ.mjs.map +0 -1
  581. package/dist/chunk-FS2KNUQH.mjs.map +0 -1
  582. package/dist/chunk-PCHBPYML.mjs.map +0 -1
  583. package/dist/chunk-VFPLTKCU.mjs +0 -192
  584. package/dist/chunk-VFPLTKCU.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { err, ok, type Result } from '@forgeax/engine-types';
2
- import type { DeviceScope } from '../device/device-scope';
2
+ import type { DeviceScope, LifecycleResourceSpec } from '../device/device-scope';
3
3
  import { EnvironmentGenerationFailedError } from '../errors/render';
4
- import type { EnvironmentFrame } from './frame';
4
+ import { type EnvironmentFrame, SKYLIGHT_RECOVERY_FALLBACK } from './frame';
5
5
  import type { EnvironmentGeneration, EnvironmentGenerationFailure } from './generation';
6
6
  import { sharedEnvironmentFrame } from './graph';
7
7
  import {
@@ -20,8 +20,11 @@ interface RetiredGeneration {
20
20
  readonly generation: EnvironmentGeneration;
21
21
  }
22
22
 
23
+ let nextEnvironmentToken = 1;
24
+
23
25
  /** Owns candidate, active, LKG, and DeviceScope generation transitions. */
24
26
  export class EnvironmentLifecycle {
27
+ private readonly token = nextEnvironmentToken++;
25
28
  private currentScope: DeviceScope;
26
29
  private nextGeneration = 0;
27
30
  private active: EnvironmentGeneration | undefined;
@@ -31,6 +34,13 @@ export class EnvironmentLifecycle {
31
34
  private readonly retired: RetiredGeneration[] = [];
32
35
  private readonly leaseCounts = new Map<number, number>();
33
36
  private lastCandidateFailure: EnvironmentInspectionFailure | undefined;
37
+ private recovery:
38
+ | {
39
+ readonly deviceGeneration: number;
40
+ readonly frame: EnvironmentFrame;
41
+ readonly lane: 'direct' | 'clustered';
42
+ }
43
+ | undefined;
34
44
 
35
45
  constructor(scope: DeviceScope) {
36
46
  this.currentScope = scope;
@@ -41,8 +51,69 @@ export class EnvironmentLifecycle {
41
51
  this.currentScope = scope;
42
52
  }
43
53
 
54
+ resetForRecover(deviceGeneration: number): void {
55
+ if (!Number.isSafeInteger(deviceGeneration) || deviceGeneration < 0) {
56
+ throw new RangeError('deviceGeneration must be a non-negative safe integer.');
57
+ }
58
+ const frame = this.active === undefined ? undefined : this.frames.get(this.active.signature);
59
+ if (frame !== undefined) {
60
+ this.recovery = Object.freeze({
61
+ deviceGeneration,
62
+ frame,
63
+ lane: this.active?.lane ?? 'direct',
64
+ });
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Create an environment owner for a recovery candidate without moving the
70
+ * active owner's scope or generation maps. Only the selected CPU frame and
71
+ * its lane are shared; every candidate generation/frame map starts empty.
72
+ */
73
+ createRecoveryCandidate(scope: DeviceScope): EnvironmentLifecycle {
74
+ const candidate = new EnvironmentLifecycle(scope);
75
+ const activeFrame =
76
+ this.recovery?.frame ??
77
+ (this.active === undefined ? undefined : this.frames.get(this.active.signature));
78
+ if (activeFrame !== undefined) {
79
+ candidate.recovery = Object.freeze({
80
+ deviceGeneration: scope.generation,
81
+ frame: activeFrame,
82
+ lane: this.recovery?.lane ?? this.active?.lane ?? 'direct',
83
+ });
84
+ }
85
+ candidate.lastCandidateFailure = this.lastCandidateFailure;
86
+ return candidate;
87
+ }
88
+
89
+ /** True when a CPU environment frame is available for candidate recovery. */
90
+ hasRecoveryFrame(): boolean {
91
+ return (
92
+ this.recovery?.frame !== undefined ||
93
+ (this.active !== undefined && this.frames.has(this.active.signature))
94
+ );
95
+ }
96
+
97
+ createRecoveryRoot(scope: DeviceScope): LifecycleResourceSpec<unknown> {
98
+ return {
99
+ kind: 'texture',
100
+ create: async () => {
101
+ const recovered = await this.recover(scope);
102
+ if (!recovered.ok) throw recovered.error;
103
+ return recovered.value;
104
+ },
105
+ cleanup: (value) => {
106
+ this.discard(value as EnvironmentGeneration);
107
+ },
108
+ };
109
+ }
110
+
44
111
  isActive(generation: EnvironmentGeneration): boolean {
45
- return this.active === generation;
112
+ return (
113
+ this.active?.generation === generation.generation &&
114
+ this.active.signature === generation.signature &&
115
+ this.active.scope === generation.scope
116
+ );
46
117
  }
47
118
 
48
119
  discard(generation: EnvironmentGeneration): void {
@@ -52,6 +123,14 @@ export class EnvironmentLifecycle {
52
123
  this.frames.delete(generation.signature);
53
124
  generation.retired = true;
54
125
  generation.scope.retire();
126
+ if (this.recovery?.frame.signature === generation.signature) this.recovery = undefined;
127
+ if (this.candidates.size === 0) this.recovery = undefined;
128
+ }
129
+
130
+ /** Drop every uncommitted generation owned by an abandoned candidate. */
131
+ discardRecoveryCandidates(): void {
132
+ for (const generation of [...this.candidates.values()]) this.discard(generation);
133
+ this.recovery = undefined;
55
134
  }
56
135
 
57
136
  recordCandidateFailure(error: EnvironmentGenerationFailedError): void {
@@ -106,6 +185,9 @@ export class EnvironmentLifecycle {
106
185
  ),
107
186
  );
108
187
  }
188
+ if (this.active?.signature === frame.signature && this.active.scope.isAlive()) {
189
+ return ok(this.active.lane === lane ? this.active : this.laneView(this.active, lane));
190
+ }
109
191
  const existing = this.candidates.get(frame.signature);
110
192
  if (existing?.scope.isAlive()) {
111
193
  return ok(existing.lane === lane ? existing : this.laneView(existing, lane));
@@ -150,6 +232,28 @@ export class EnvironmentLifecycle {
150
232
  }
151
233
  this.active = generation;
152
234
  this.lkg = generation;
235
+ this.recovery = undefined;
236
+ }
237
+
238
+ /** Close the old active generation before a replacement owner is installed. */
239
+ retireActiveForReplacement(): void {
240
+ const active = this.active;
241
+ if (active === undefined) return;
242
+ this.active = undefined;
243
+ if (this.lkg === active) this.lkg = undefined;
244
+ active.retired = true;
245
+ active.scope.retire();
246
+ this.recovery = undefined;
247
+ }
248
+
249
+ /** Close an already-published generation when its owning scope retires. */
250
+ retirePublishedGeneration(generation: EnvironmentGeneration): void {
251
+ if (this.active !== generation) return;
252
+ this.active = undefined;
253
+ if (this.lkg === generation) this.lkg = undefined;
254
+ generation.retired = true;
255
+ generation.scope.retire();
256
+ this.recovery = undefined;
153
257
  }
154
258
 
155
259
  acquire(): EnvironmentLease {
@@ -230,24 +334,33 @@ export class EnvironmentLifecycle {
230
334
  ...(this.lastCandidateFailure === undefined
231
335
  ? {}
232
336
  : { lastCandidateFailure: this.lastCandidateFailure }),
337
+ ...(this.recovery === undefined
338
+ ? {}
339
+ : {
340
+ recovery: {
341
+ token: this.token,
342
+ deviceGeneration: this.recovery.deviceGeneration,
343
+ status: 'uninitialized' as const,
344
+ fallback: SKYLIGHT_RECOVERY_FALLBACK.kind,
345
+ },
346
+ }),
233
347
  });
234
348
  }
235
349
 
236
350
  async recover(
237
351
  scope: DeviceScope,
238
352
  ): Promise<Result<EnvironmentGeneration, EnvironmentGenerationFailedError>> {
239
- if (this.active === undefined)
240
- return err(new EnvironmentGenerationFailedError('none', 'prepare'));
241
353
  this.currentScope = scope;
242
354
  const previous = this.active;
243
- this.candidates.delete(previous.signature);
244
- const previousFrame = this.frames.get(previous.signature);
355
+ const previousFrame =
356
+ this.recovery?.frame ??
357
+ (previous === undefined ? undefined : this.frames.get(previous.signature));
245
358
  if (previousFrame === undefined) {
246
359
  return err(new EnvironmentGenerationFailedError('none', 'prepare'));
247
360
  }
248
361
  const result = await this.ensure(
249
- sharedEnvironmentFrame(previousFrame, previous.lane),
250
- previous.lane,
362
+ sharedEnvironmentFrame(previousFrame, previous?.lane ?? 'direct'),
363
+ this.recovery?.lane ?? previous?.lane ?? 'direct',
251
364
  );
252
365
  if (!result.ok) return result;
253
366
  return ok(result.value);
@@ -0,0 +1,92 @@
1
+ import type { MaterialShaderArtifactReceipt } from '@forgeax/engine-shader';
2
+
3
+ export type GpuDrivenPreparationErrorCode =
4
+ | 'missing-material-receipt'
5
+ | 'missing-uv'
6
+ | 'reflection-mismatch'
7
+ | 'vertex-input-mismatch'
8
+ | 'alpha-mask-mismatch'
9
+ | 'resource-not-ready'
10
+ | 'stale-generation'
11
+ | 'skin-receipt-mismatch';
12
+
13
+ export type GpuDrivenPreparationReason =
14
+ | 'material-receipt-missing'
15
+ | 'uv-set-missing'
16
+ | 'reflection-receipt-mismatch'
17
+ | 'vertex-semantic-mismatch'
18
+ | 'alpha-mask-receipt-missing'
19
+ | 'material-resource-missing'
20
+ | 'generation-stale'
21
+ | 'skin-address-missing';
22
+
23
+ export interface GpuDrivenPreparationErrorDetail {
24
+ readonly reason: GpuDrivenPreparationReason;
25
+ readonly owner: 'material' | 'geometry' | 'skin' | 'generation';
26
+ readonly expected?: string;
27
+ readonly actual?: string;
28
+ readonly expectedGeneration?: number;
29
+ readonly actualGeneration?: number;
30
+ }
31
+
32
+ const ERROR_POLICY: Readonly<
33
+ Record<GpuDrivenPreparationErrorCode, { readonly expected: string; readonly hint: string }>
34
+ > = {
35
+ 'missing-material-receipt': {
36
+ expected: 'a producer-owned Standard PBR material receipt is present',
37
+ hint: 'cook and load the Standard PBR artifact, then retry preparation',
38
+ },
39
+ 'missing-uv': {
40
+ expected: 'the geometry exposes every UV set named by the material receipt',
41
+ hint: 'repair the geometry UV semantic or route the draw to the CPU semantic lane',
42
+ },
43
+ 'reflection-mismatch': {
44
+ expected: 'the loaded reflection receipt matches the artifact layout identity',
45
+ hint: 'rebuild the material artifact and reflection from one source, then retry',
46
+ },
47
+ 'vertex-input-mismatch': {
48
+ expected: 'geometry vertex semantics match the material reflection receipt',
49
+ hint: 'repair the geometry vertex semantic layout or route the draw to the CPU lane',
50
+ },
51
+ 'alpha-mask-mismatch': {
52
+ expected: 'the Alpha Mask cutoff is present in the material receipt',
53
+ hint: 'declare alphaCutoff in the Standard PBR material schema and recook it',
54
+ },
55
+ 'resource-not-ready': {
56
+ expected: 'all material resource slots have resolved handles',
57
+ hint: 'resolve the declared texture and sampler resources before recording',
58
+ },
59
+ 'stale-generation': {
60
+ expected: 'receipt and prepared inputs belong to the requested generation',
61
+ hint: 'discard stale GPU facts, rebuild the producer receipt, and retry the same draw',
62
+ },
63
+ 'skin-receipt-mismatch': {
64
+ expected: 'skinned geometry has a current palette address receipt',
65
+ hint: 'rebuild the Skin palette receipt for this generation before recording',
66
+ },
67
+ };
68
+
69
+ export class GpuDrivenPreparationError extends Error {
70
+ readonly code: GpuDrivenPreparationErrorCode;
71
+ readonly expected: string;
72
+ readonly hint: string;
73
+ readonly detail: GpuDrivenPreparationErrorDetail;
74
+
75
+ constructor(code: GpuDrivenPreparationErrorCode, detail: GpuDrivenPreparationErrorDetail) {
76
+ const policy = ERROR_POLICY[code];
77
+ super(`[GpuDrivenPreparationError ${code}] ${policy.expected}`);
78
+ this.name = 'GpuDrivenPreparationError';
79
+ this.code = code;
80
+ this.expected = policy.expected;
81
+ this.hint = policy.hint;
82
+ this.detail = detail;
83
+ }
84
+ }
85
+
86
+ export interface GpuDrivenPreparedMaterial {
87
+ readonly receipt: MaterialShaderArtifactReceipt;
88
+ readonly resourceSlots: MaterialShaderArtifactReceipt['resourceSlots'];
89
+ readonly uvSets: MaterialShaderArtifactReceipt['uvSets'];
90
+ readonly vertexInputs: MaterialShaderArtifactReceipt['vertexInputs'];
91
+ readonly alphaMask: MaterialShaderArtifactReceipt['alphaMask'];
92
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './ecs-validation';
2
+ export * from './gpu-driven';
2
3
  export * from './recover';
3
4
  export * from './render';
@@ -6,7 +6,51 @@
6
6
  // `recover(): Promise<Result<void, RecoverFailure>>`, NOT the onError fanout
7
7
  // channel (see render-contract.ts RendererError composition).
8
8
 
9
- import type { DeviceScopeReceipt } from '../device/resource-types';
9
+ import type { RecoveryGuidance, RecoveryPhase } from '../assembly/renderer-lifecycle';
10
+ import type { DeviceResourceKind, DeviceScopeReceipt } from '../device/resource-types';
11
+ import type { ReflectionFallbackRecoveryAction } from '../inspection-types';
12
+ import type { SsrAdmissionError, SsrOwnerRecoveryAction } from '../ssr/errors';
13
+
14
+ export type { RecoveryGuidance, RecoveryPhase } from '../assembly/renderer-lifecycle';
15
+ export { RECOVERY_PHASES } from '../assembly/renderer-lifecycle';
16
+ export type { ReflectionFallbackRecoveryAction } from '../inspection-types';
17
+
18
+ export function reflectionFallbackRecoveryAction(
19
+ source: 'probe' | 'skylight' | 'neutral',
20
+ hasLastKnownGood: boolean,
21
+ ): ReflectionFallbackRecoveryAction {
22
+ if (source === 'probe' && hasLastKnownGood) return 'use-LKG';
23
+ if (source === 'skylight') return 'use-Skylight';
24
+ return 'use-neutral';
25
+ }
26
+
27
+ /**
28
+ * Maps a detached admission failure to the owning producer action. This is
29
+ * an instruction projection only; SSR never performs the recovery itself.
30
+ */
31
+ export function ssrAdmissionRecoveryAction(error: SsrAdmissionError): SsrOwnerRecoveryAction {
32
+ switch (error.code) {
33
+ case 'ssr-not-requested':
34
+ case 'ssr-receipt-stale':
35
+ return 'retry';
36
+ case 'ssr-reflection-fallback-unavailable':
37
+ return error.detail.action;
38
+ case 'ssr-format-unavailable':
39
+ case 'ssr-temporal-unavailable':
40
+ return error.detail.action;
41
+ case 'ssr-receipt-identity-mismatch':
42
+ return 'rebuild';
43
+ }
44
+ }
45
+
46
+ /** Closed outcome vocabulary shared by recovery inspection and errors. */
47
+ export type RecoveryOutcome = 'none' | 'succeeded' | 'failed' | 'disposed';
48
+
49
+ /**
50
+ * `RecoveryPhase` is the stable lower-case hyphenated phase union used by
51
+ * inspect/recovery detail. `RecoveryGuidance` is the closed next-action union:
52
+ * retry the attempt, repair its owner, or rebuild the Renderer.
53
+ */
10
54
 
11
55
  // ── RecoverError (feat-20260621-renderer-health-recover-skeleton M1) ─────────
12
56
 
@@ -41,13 +85,13 @@ const RECOVER_ERROR_POLICY = {
41
85
  'recover-not-needed': {
42
86
  message: 'recover-not-needed: renderer is not in a degraded state',
43
87
  expected:
44
- 'renderer is healthy; call health() first to confirm degraded state before calling recover()',
45
- hint: 'call health() first to confirm degraded state before calling recover()',
88
+ 'renderer is healthy; use state() or inspect() to confirm degraded state before calling recover()',
89
+ hint: 'use state() or inspect().state to confirm degraded state before calling recover()',
46
90
  },
47
91
  'recover-not-implemented': {
48
92
  message: 'recover-not-implemented: self-heal recovery is not yet implemented',
49
93
  expected: 'recovery is not yet implemented; self-heal lands in S5',
50
- hint: 'self-heal recovery lands in S5; health().reason still reflects the degraded state',
94
+ hint: 'self-heal recovery lands in S5; inspect().state still reflects the lifecycle state',
51
95
  },
52
96
  'recover-adapter-unavailable': {
53
97
  message: 'recover-adapter-unavailable: requestAdapter returned no adapter during rebuild',
@@ -95,6 +139,60 @@ export class RecoverError extends Error {
95
139
  }
96
140
  }
97
141
 
142
+ export interface RecoveryFailureDetail {
143
+ /** The bounded phase that produced this failure. */
144
+ readonly phase: RecoveryPhase;
145
+ /** Active generation before the attempt; it changes only on publish. */
146
+ readonly oldGeneration: number;
147
+ /** Candidate generation; it changes only on publish. */
148
+ readonly candidateGeneration: number;
149
+ /** Monotonic explicit recovery attempt number. */
150
+ readonly attempt: number;
151
+ /** Wall-clock duration of this bounded attempt. */
152
+ readonly elapsedMs: number;
153
+ /** Whether the caller may explicitly retry without recreating the Renderer. */
154
+ readonly retryable: boolean;
155
+ /** Next action selected by the recovery owner. */
156
+ readonly guidance: RecoveryGuidance;
157
+ /** Producer or lifecycle owner that must be inspected first. */
158
+ readonly owner: string;
159
+ /** Structured resource category, never a raw GPU handle. */
160
+ readonly resourceKind: DeviceResourceKind;
161
+ /** Terminal outcome of this attempt. */
162
+ readonly lastOutcome: Exclude<RecoveryOutcome, 'none' | 'succeeded'>;
163
+ /** Number of candidate roots committed before publication. */
164
+ readonly rehydratedRoots: number;
165
+ /** Number of late notifications ignored from retired generations. */
166
+ readonly staleLossEvents: number;
167
+ /** Original structured cause retained for diagnostics. */
168
+ readonly cause: unknown;
169
+ /** Cleanup failures that prevented a complete candidate publication. */
170
+ readonly cleanupFailures: readonly unknown[];
171
+ /** Detached lifecycle receipt for the failed candidate. */
172
+ readonly receipt: DeviceScopeReceipt;
173
+ }
174
+
175
+ /** Stable structured failure returned by one bounded recovery attempt. */
176
+ export class RecoveryFailedError extends Error {
177
+ readonly code = 'recovery-failed' as const;
178
+ readonly expected = 'one recovery attempt publishes a complete replacement device generation';
179
+ readonly hint = 'inspect detail and follow its guidance';
180
+ readonly detail: RecoveryFailureDetail;
181
+
182
+ constructor(detail: RecoveryFailureDetail) {
183
+ super('renderer recovery failed');
184
+ this.name = 'RecoveryFailedError';
185
+ this.detail = Object.freeze({
186
+ ...detail,
187
+ cleanupFailures: Object.freeze([...detail.cleanupFailures]),
188
+ });
189
+ }
190
+ }
191
+
192
+ export function createRecoveryFailedError(detail: RecoveryFailureDetail): RecoveryFailedError {
193
+ return new RecoveryFailedError(detail);
194
+ }
195
+
98
196
  const RENDER_RECOVERY_ERROR_POLICY = {
99
197
  'recover-lifecycle-failed': {
100
198
  expected: 'the replacement DeviceScope must publish only after lifecycle cleanup succeeds',
@@ -109,10 +207,15 @@ const RENDER_RECOVERY_ERROR_POLICY = {
109
207
  export type RenderRecoveryErrorCode = keyof typeof RENDER_RECOVERY_ERROR_POLICY;
110
208
 
111
209
  export interface RenderRecoveryFailureDetail {
210
+ /** Producer/lifecycle owner whose recovery operation failed. */
112
211
  readonly owner: string;
212
+ /** Device generation associated with the failed recovery operation. */
113
213
  readonly generation: number;
214
+ /** Closed operation kind; no implicit background retry is represented. */
114
215
  readonly recovery: 'recover' | 'rebuild' | 'stop';
216
+ /** Lifecycle receipt retained as structured evidence, not a live handle. */
115
217
  readonly receipt: DeviceScopeReceipt;
218
+ /** Original structured cause for the failed operation. */
116
219
  readonly cause: unknown;
117
220
  }
118
221
 
@@ -133,7 +236,7 @@ export class RenderRecoveryError extends Error {
133
236
  }
134
237
  }
135
238
 
136
- export type RecoverFailure = RecoverError | RenderRecoveryError;
239
+ export type RecoverFailure = RecoverError | RenderRecoveryError | RecoveryFailedError;
137
240
 
138
241
  export type IblCapabilityLossCode = 'ibl-hdr-capability-loss';
139
242
 
@@ -27,6 +27,11 @@ import type {
27
27
  } from '../features/vocabulary';
28
28
  import type { SceneDataLane, SceneDataSchemaId } from '../temporal/scene-data';
29
29
  import type { TransmissionCapabilityFact } from '../transmission/backdrop';
30
+ import type { RecoveryOutcome, RecoveryPhase } from './recover';
31
+
32
+ // Public render errors keep one machine-readable order: closed `code`,
33
+ // expected state, actionable `hint`, then typed `detail`. Consumers branch on
34
+ // that shape and never use Error.message as a protocol.
30
35
 
31
36
  export interface LifecycleConstructionFailureDetail {
32
37
  readonly owner: string;
@@ -116,6 +121,60 @@ export function createRenderSurfaceError(
116
121
  return new RenderSurfaceError(`surface-${kind}-failed` as SurfaceFailureCode, detail);
117
122
  }
118
123
 
124
+ export type LightResourceFailureReason = 'asset' | 'format' | 'capability' | 'capacity';
125
+
126
+ export interface LightResourceUnavailableDetail {
127
+ readonly entity: number;
128
+ readonly feature: 'ies' | 'cookie' | 'probe';
129
+ readonly generation: number;
130
+ readonly sourceKey: string;
131
+ readonly reason: LightResourceFailureReason;
132
+ }
133
+
134
+ export class LightResourceUnavailableError extends Error {
135
+ readonly code = 'light-resource-unavailable' as const;
136
+ readonly expected: string;
137
+ readonly hint: string;
138
+ readonly detail: LightResourceUnavailableDetail;
139
+
140
+ constructor(
141
+ detail: LightResourceUnavailableDetail,
142
+ expected: string,
143
+ actual: string,
144
+ hint: string,
145
+ ) {
146
+ super(`light-resource-unavailable: ${detail.feature} ${actual}`);
147
+ this.name = 'LightResourceUnavailableError';
148
+ this.expected = expected;
149
+ this.hint = hint;
150
+ this.detail = detail;
151
+ }
152
+ }
153
+
154
+ export function createLightResourceUnavailable(input: {
155
+ readonly entity: number;
156
+ readonly feature: LightResourceUnavailableDetail['feature'];
157
+ readonly generation: number;
158
+ readonly sourceKey: string;
159
+ readonly reason: LightResourceFailureReason;
160
+ readonly expected: string;
161
+ readonly actual: string;
162
+ readonly hint: string;
163
+ }): LightResourceUnavailableError {
164
+ return new LightResourceUnavailableError(
165
+ {
166
+ entity: input.entity,
167
+ feature: input.feature,
168
+ generation: input.generation,
169
+ sourceKey: input.sourceKey,
170
+ reason: input.reason,
171
+ },
172
+ input.expected,
173
+ input.actual,
174
+ input.hint,
175
+ );
176
+ }
177
+
119
178
  export interface TemporalFrameSubmitDetail {
120
179
  readonly reason: 'queue-submit-failed';
121
180
  }
@@ -132,7 +191,6 @@ export class TemporalFrameSubmitError extends Error {
132
191
  this.detail = { reason };
133
192
  }
134
193
  }
135
-
136
194
  // ── ShadowInvalidConfigError ──────────────────────────────────────────────
137
195
 
138
196
  /**
@@ -1306,7 +1364,19 @@ export interface RendererOperationDetailByCode {
1306
1364
  };
1307
1365
  readonly 'recovery-failed': {
1308
1366
  readonly operation: 'recover';
1367
+ readonly phase: RecoveryPhase;
1309
1368
  readonly oldGeneration: number;
1369
+ readonly candidateGeneration: number;
1370
+ readonly attempt: number;
1371
+ readonly elapsedMs: number;
1372
+ readonly retryable: boolean;
1373
+ readonly guidance: 'retry' | 'repair-owner' | 'rebuild-renderer';
1374
+ readonly owner: string;
1375
+ readonly resourceKind: string;
1376
+ readonly lastOutcome: RecoveryOutcome;
1377
+ readonly rehydratedRoots: number;
1378
+ readonly staleLossEvents: number;
1379
+ readonly cleanupFailures: readonly RendererOperationCause[];
1310
1380
  readonly cause: RendererOperationCause;
1311
1381
  };
1312
1382
  readonly 'cleanup-failed': {
@@ -1821,6 +1891,7 @@ export type RenderError =
1821
1891
  | PointsLinesMaterialUnsupportedError
1822
1892
  | PointsLinesBudgetExceededError
1823
1893
  | PointsLinesPrepareFailedError
1894
+ | LightResourceUnavailableError
1824
1895
  | RenderTargetDescriptorInvalidError
1825
1896
  | RenderTargetCapabilityMissingError
1826
1897
  | RenderTargetStateInvalidError
@@ -1,7 +1,7 @@
1
1
  import type { EntityHandle, World } from '@forgeax/engine-ecs';
2
2
  import { readRenderArrayView } from '@forgeax/engine-ecs/projection';
3
3
  import { mat4, vec3 } from '@forgeax/engine-math';
4
- import { Transform } from '@forgeax/engine-scene';
4
+ import { GlobalTransform } from '@forgeax/engine-scene';
5
5
  import {
6
6
  antialiasFromF32,
7
7
  bloomEnabledFromF32,
@@ -14,7 +14,7 @@ import type { CameraSnapshot } from '../render-contract';
14
14
  import { getActiveCamera, selectActiveCameraIndex } from '../systems/active-camera';
15
15
 
16
16
  function readWorldMatrix(world: World, entity: EntityHandle): Float32Array | undefined {
17
- const view = readRenderArrayView(world, entity, Transform, 'world');
17
+ const view = readRenderArrayView(world, entity, GlobalTransform, 'world');
18
18
  return view === undefined ? undefined : new Float32Array(view);
19
19
  }
20
20
 
@@ -23,7 +23,7 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
23
23
  const cameras: CameraSnapshot[] = [];
24
24
  const cameraEntities: number[] = [];
25
25
  const cameraQuery = world
26
- .query({ read: [Camera], optional: [MotionBlur], with: [Transform] })
26
+ .query({ read: [Camera], optional: [MotionBlur], with: [GlobalTransform] })
27
27
  .unwrap();
28
28
  for (const row of cameraQuery) {
29
29
  const cam = row.get(Camera);