@forgeax/engine-render 0.1.27 → 0.1.29

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 (655) hide show
  1. package/README.md +842 -124
  2. package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
  3. package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
  4. package/dist/assembly/dynamic-geometry-host.d.ts +52 -0
  5. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
  6. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  7. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  8. package/dist/assembly/factory.d.ts +3 -1
  9. package/dist/assembly/factory.d.ts.map +1 -1
  10. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  11. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  12. package/dist/assembly/host-contract.d.ts +19 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +7 -0
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material-shader-policy.d.ts +3 -1
  17. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  18. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  19. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  20. package/dist/assembly/recovery/renderer-recover.d.ts +6 -4
  21. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  22. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  23. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  24. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  25. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  26. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  27. package/dist/assembly/renderer-helpers.d.ts +3 -0
  28. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  29. package/dist/assembly/renderer-inspection.d.ts +4 -0
  30. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  31. package/dist/assembly/shader-prewarm-policy.d.ts +6 -0
  32. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  33. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  34. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  35. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  36. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  37. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  38. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  39. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  40. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  41. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  42. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  43. package/dist/assembly/webgpu-ready.d.ts +7 -3
  44. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  45. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  46. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  47. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  48. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  49. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  50. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  51. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  52. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  53. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  54. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  55. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  56. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  57. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  58. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  59. package/dist/authoring.mjs +3 -3
  60. package/dist/{chunk-ADHHVYLW.mjs → chunk-33XZFTQU.mjs} +245 -39
  61. package/dist/chunk-33XZFTQU.mjs.map +1 -0
  62. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  63. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  64. package/dist/{chunk-KM2NOX2I.mjs → chunk-BQVQOQJH.mjs} +958 -254
  65. package/dist/chunk-BQVQOQJH.mjs.map +1 -0
  66. package/dist/{chunk-HKXTW355.mjs → chunk-BTWH7BP4.mjs} +386 -17
  67. package/dist/chunk-BTWH7BP4.mjs.map +1 -0
  68. package/dist/{chunk-TMIASV2N.mjs → chunk-FUODTTIA.mjs} +3934 -676
  69. package/dist/chunk-FUODTTIA.mjs.map +1 -0
  70. package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
  71. package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
  72. package/dist/{chunk-E34VL5VI.mjs → chunk-JQTSEI3Z.mjs} +3 -3
  73. package/dist/{chunk-E34VL5VI.mjs.map → chunk-JQTSEI3Z.mjs.map} +1 -1
  74. package/dist/{chunk-GE3SDD72.mjs → chunk-NICXSHAT.mjs} +16 -38
  75. package/dist/chunk-NICXSHAT.mjs.map +1 -0
  76. package/dist/{chunk-ZZ4YQ474.mjs → chunk-NRNXBLIJ.mjs} +577 -7
  77. package/dist/chunk-NRNXBLIJ.mjs.map +1 -0
  78. package/dist/{chunk-JDWARUOI.mjs → chunk-PA5DRJNI.mjs} +17 -3
  79. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  80. package/dist/{chunk-XDP6XE5V.mjs → chunk-S4DNKQYQ.mjs} +1118 -446
  81. package/dist/chunk-S4DNKQYQ.mjs.map +1 -0
  82. package/dist/components/camera.d.ts +62 -2
  83. package/dist/components/camera.d.ts.map +1 -1
  84. package/dist/components/index.d.ts +1 -0
  85. package/dist/components/index.d.ts.map +1 -1
  86. package/dist/components/instances.d.ts +6 -20
  87. package/dist/components/instances.d.ts.map +1 -1
  88. package/dist/components/scene-instance.d.ts +2 -1
  89. package/dist/components/scene-instance.d.ts.map +1 -1
  90. package/dist/components/screen-space-reflection.d.ts +14 -0
  91. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  92. package/dist/construct-renderer.mjs +13805 -7186
  93. package/dist/construct-renderer.mjs.map +1 -1
  94. package/dist/device/gpu-residency.d.ts +11 -17
  95. package/dist/device/gpu-residency.d.ts.map +1 -1
  96. package/dist/device/mesh-residency-lifetime.d.ts +21 -0
  97. package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
  98. package/dist/dynamic-geometry.d.ts +125 -0
  99. package/dist/dynamic-geometry.d.ts.map +1 -0
  100. package/dist/environment/background.d.ts +6 -0
  101. package/dist/environment/background.d.ts.map +1 -0
  102. package/dist/errors/gpu-driven.d.ts +6 -3
  103. package/dist/errors/gpu-driven.d.ts.map +1 -1
  104. package/dist/errors/render.d.ts +7 -4
  105. package/dist/errors/render.d.ts.map +1 -1
  106. package/dist/extract/camera.d.ts.map +1 -1
  107. package/dist/extract/gpu-driven.d.ts +33 -3
  108. package/dist/extract/gpu-driven.d.ts.map +1 -1
  109. package/dist/features/host.d.ts +23 -1
  110. package/dist/features/host.d.ts.map +1 -1
  111. package/dist/features/noise-texture.d.ts +17 -0
  112. package/dist/features/noise-texture.d.ts.map +1 -0
  113. package/dist/features/plan.d.ts +83 -2
  114. package/dist/features/plan.d.ts.map +1 -1
  115. package/dist/features/prepared-gpu-work.d.ts +37 -4
  116. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  117. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  118. package/dist/features/prepared-graphics.d.ts +5 -0
  119. package/dist/features/prepared-graphics.d.ts.map +1 -1
  120. package/dist/features/render-graph-compute.d.ts +5 -3
  121. package/dist/features/render-graph-compute.d.ts.map +1 -1
  122. package/dist/features/render-graph-contribution.d.ts +11 -3
  123. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  124. package/dist/features/render-graph-raster.d.ts +19 -3
  125. package/dist/features/render-graph-raster.d.ts.map +1 -1
  126. package/dist/features/types.d.ts +11 -0
  127. package/dist/features/types.d.ts.map +1 -1
  128. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  129. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  130. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  131. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  132. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  133. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  134. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  135. package/dist/gpu-driven/production-raster.d.ts +144 -23
  136. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  137. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  138. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  139. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  140. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  141. package/dist/gpu-scene-schema.d.ts +2 -8
  142. package/dist/gpu-scene-schema.d.ts.map +1 -1
  143. package/dist/gpu-scene.d.ts +14 -0
  144. package/dist/gpu-scene.d.ts.map +1 -1
  145. package/dist/gpu-texture-usage.d.ts +1 -0
  146. package/dist/gpu-texture-usage.d.ts.map +1 -1
  147. package/dist/hdrp-buffers.d.ts +6 -0
  148. package/dist/hdrp-buffers.d.ts.map +1 -1
  149. package/dist/ibl/frame-resources.d.ts +8 -0
  150. package/dist/ibl/frame-resources.d.ts.map +1 -0
  151. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  152. package/dist/index.d.ts +21 -8
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.mjs +8 -7
  155. package/dist/index.mjs.map +1 -1
  156. package/dist/inspection-types.d.ts +164 -0
  157. package/dist/inspection-types.d.ts.map +1 -1
  158. package/dist/instances-derived-bounds.d.ts +11 -0
  159. package/dist/instances-derived-bounds.d.ts.map +1 -1
  160. package/dist/instances.d.ts +89 -44
  161. package/dist/instances.d.ts.map +1 -1
  162. package/dist/internal.d.ts +3 -0
  163. package/dist/internal.d.ts.map +1 -1
  164. package/dist/internal.mjs +118 -10
  165. package/dist/internal.mjs.map +1 -1
  166. package/dist/lifecycle.d.ts +2 -1
  167. package/dist/lifecycle.d.ts.map +1 -1
  168. package/dist/material-row.d.ts +5 -0
  169. package/dist/material-row.d.ts.map +1 -0
  170. package/dist/materials.d.ts +15 -0
  171. package/dist/materials.d.ts.map +1 -1
  172. package/dist/pbr-pipeline.d.ts +21 -5
  173. package/dist/pbr-pipeline.d.ts.map +1 -1
  174. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  175. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  176. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  177. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  178. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  179. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  180. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  181. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  182. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  183. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  184. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  185. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  186. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  187. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  188. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  189. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  190. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  191. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  192. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  193. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  194. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  195. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  196. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  197. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  198. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  199. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  200. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  201. package/dist/pipeline/standard-output/types.d.ts +39 -0
  202. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  203. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/standard-post.d.ts +2 -2
  205. package/dist/pipeline/standard-post.d.ts.map +1 -1
  206. package/dist/pipeline-builder.d.ts +2 -1
  207. package/dist/pipeline-builder.d.ts.map +1 -1
  208. package/dist/pipeline-spec-types.d.ts +4 -0
  209. package/dist/pipeline-spec-types.d.ts.map +1 -1
  210. package/dist/pipeline-spec.d.ts +1 -9
  211. package/dist/pipeline-spec.d.ts.map +1 -1
  212. package/dist/points-lines/standard-owner.d.ts +1 -1
  213. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  214. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  215. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  216. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  217. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  218. package/dist/record/frame-lighting.d.ts +3 -3
  219. package/dist/record/frame-lighting.d.ts.map +1 -1
  220. package/dist/record/frame-snapshot.d.ts +106 -5
  221. package/dist/record/frame-snapshot.d.ts.map +1 -1
  222. package/dist/record/frame-targets.d.ts.map +1 -1
  223. package/dist/record/frame.d.ts +39 -4
  224. package/dist/record/frame.d.ts.map +1 -1
  225. package/dist/record/main-pass-geometry.d.ts +7 -8
  226. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  227. package/dist/record/main-pass-material.d.ts +38 -1
  228. package/dist/record/main-pass-material.d.ts.map +1 -1
  229. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  230. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  231. package/dist/record/main-pass.d.ts +12 -2
  232. package/dist/record/main-pass.d.ts.map +1 -1
  233. package/dist/record/mesh-ssbo.d.ts +15 -6
  234. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  235. package/dist/record/prepared-material-bindings.d.ts +19 -0
  236. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  237. package/dist/record/recovery-pipeline.d.ts +2 -9
  238. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  239. package/dist/record/render-context.d.ts +76 -26
  240. package/dist/record/render-context.d.ts.map +1 -1
  241. package/dist/record/shadow-pass.d.ts +62 -7
  242. package/dist/record/shadow-pass.d.ts.map +1 -1
  243. package/dist/record/skybox-post-pass.d.ts +1 -1
  244. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  245. package/dist/record/typed-frame-graph.d.ts +35 -7
  246. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  247. package/dist/record/view-ubo.d.ts +1 -0
  248. package/dist/record/view-ubo.d.ts.map +1 -1
  249. package/dist/recovery/render-system-candidate.d.ts +10 -2
  250. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  251. package/dist/recovery/render-system-roots.d.ts +11 -0
  252. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  253. package/dist/recovery/types.d.ts +76 -0
  254. package/dist/recovery/types.d.ts.map +1 -0
  255. package/dist/reflection/record-owner.d.ts +0 -2
  256. package/dist/reflection/record-owner.d.ts.map +1 -1
  257. package/dist/render-contract.d.ts +185 -30
  258. package/dist/render-contract.d.ts.map +1 -1
  259. package/dist/render-graph-primitives.d.ts +1 -0
  260. package/dist/render-graph-primitives.d.ts.map +1 -1
  261. package/dist/render-pipeline.d.ts +64 -5
  262. package/dist/render-pipeline.d.ts.map +1 -1
  263. package/dist/render-system-extract-tail.d.ts +7 -5
  264. package/dist/render-system-extract-tail.d.ts.map +1 -1
  265. package/dist/render-system-extract.d.ts +101 -41
  266. package/dist/render-system-extract.d.ts.map +1 -1
  267. package/dist/render-system-projections.d.ts +22 -0
  268. package/dist/render-system-projections.d.ts.map +1 -0
  269. package/dist/render-system.d.ts +34 -77
  270. package/dist/render-system.d.ts.map +1 -1
  271. package/dist/scene/render-scene-types.d.ts +14 -7
  272. package/dist/scene/render-scene-types.d.ts.map +1 -1
  273. package/dist/scene/render-scene.d.ts +29 -11
  274. package/dist/scene/render-scene.d.ts.map +1 -1
  275. package/dist/scene/shadow-visibility.d.ts +5 -0
  276. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  277. package/dist/ssr/admission.d.ts +70 -1
  278. package/dist/ssr/admission.d.ts.map +1 -1
  279. package/dist/ssr/compose.d.ts +13 -0
  280. package/dist/ssr/compose.d.ts.map +1 -0
  281. package/dist/ssr/errors.d.ts +35 -0
  282. package/dist/ssr/errors.d.ts.map +1 -1
  283. package/dist/ssr/graph.d.ts +60 -0
  284. package/dist/ssr/graph.d.ts.map +1 -0
  285. package/dist/ssr/history.d.ts +97 -0
  286. package/dist/ssr/history.d.ts.map +1 -0
  287. package/dist/ssr/hiz.d.ts +37 -0
  288. package/dist/ssr/hiz.d.ts.map +1 -0
  289. package/dist/ssr/inspection.d.ts +42 -0
  290. package/dist/ssr/inspection.d.ts.map +1 -0
  291. package/dist/ssr/resources.d.ts +58 -0
  292. package/dist/ssr/resources.d.ts.map +1 -0
  293. package/dist/ssr/temporal.d.ts +38 -0
  294. package/dist/ssr/temporal.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  296. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  297. package/dist/systems/skin-palette-types.d.ts +15 -0
  298. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  299. package/dist/systems/transparent-dispatch.d.ts +9 -0
  300. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  301. package/dist/targets/material-source.d.ts +7 -0
  302. package/dist/targets/material-source.d.ts.map +1 -1
  303. package/dist/temporal/frame-coordinator.d.ts +7 -0
  304. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  305. package/dist/temporal/gpu.d.ts +8 -0
  306. package/dist/temporal/gpu.d.ts.map +1 -1
  307. package/dist/temporal/history.d.ts.map +1 -1
  308. package/dist/temporal/index.mjs +6 -6
  309. package/dist/temporal/inspection.d.ts.map +1 -1
  310. package/dist/temporal/standard-scene-data.d.ts +2 -1
  311. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  312. package/dist/temporal/temporal-view.d.ts +2 -0
  313. package/dist/temporal/temporal-view.d.ts.map +1 -1
  314. package/dist/typed-render-graph-primitives.d.ts +35 -1
  315. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  316. package/dist/typed-shadow-passes.d.ts +3 -1
  317. package/dist/typed-shadow-passes.d.ts.map +1 -1
  318. package/dist/volume/temporal.d.ts +6 -0
  319. package/dist/volume/temporal.d.ts.map +1 -1
  320. package/package.json +21 -20
  321. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  322. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  323. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  324. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  325. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  326. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  327. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  328. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  329. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  330. package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
  331. package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
  332. package/src/__tests__/factory-contract.integration.test.ts +73 -22
  333. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  334. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  335. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  336. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  337. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  338. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  339. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  340. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  341. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  342. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +287 -6
  343. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  344. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  345. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +264 -0
  346. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +349 -0
  347. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1417 -0
  348. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  349. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  350. package/src/__tests__/gpu-driven-production.integration.test.ts +1075 -93
  351. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  352. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  353. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  354. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  355. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  356. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  357. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  358. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  359. package/src/__tests__/gpu-driven-view.unit.test.ts +159 -52
  360. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -1
  361. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  362. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  363. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  364. package/src/__tests__/gpu-scene.unit.test.ts +559 -33
  365. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  366. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  367. package/src/__tests__/instances-store.unit.test.ts +242 -39
  368. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  369. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  370. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  371. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  372. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  373. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  374. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  375. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  376. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  377. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  378. package/src/__tests__/materials-standard-contract.unit.test.ts +52 -2
  379. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  380. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
  381. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  382. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  383. package/src/__tests__/physical-clearcoat.integration.test.ts +37 -3
  384. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  385. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  386. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  387. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  388. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +35 -4
  389. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  390. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  391. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  392. package/src/__tests__/public-surface.test-d.ts +3 -0
  393. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  394. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +104 -0
  395. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +2 -1
  396. package/src/__tests__/render-error-code-owner.test-d.ts +4 -0
  397. package/src/__tests__/render-error-detail-ssot.test-d.ts +22 -0
  398. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  399. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  400. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  401. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  402. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  403. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  404. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  405. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  406. package/src/__tests__/render-scene-projection.unit.test.ts +914 -23
  407. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  408. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  409. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  410. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  411. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +61 -1
  412. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  413. package/src/__tests__/shader-manifest-fixture.ts +39 -0
  414. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  415. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  416. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  417. package/src/__tests__/skinned-shadow-caster.test.ts +118 -14
  418. package/src/__tests__/specular-environment-scale.dawn.test.ts +156 -0
  419. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  420. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  421. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  422. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  423. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +91 -0
  424. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +112 -0
  425. package/src/__tests__/ssr-gpu-dispatch.ts +946 -0
  426. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  427. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  428. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  429. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  430. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  431. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  432. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  433. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  434. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  435. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  436. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  437. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  438. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  439. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  440. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  441. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  442. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  443. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  444. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  445. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  446. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  447. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  448. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +44 -12
  449. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  450. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  451. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  452. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  453. package/src/__tests__/standard-output.browser.test.ts +15 -0
  454. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  455. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +38 -0
  456. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  457. package/src/__tests__/standard-profile-oracle.unit.test.ts +22 -0
  458. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  459. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  460. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  461. package/src/__tests__/taa-coverage-edge.dawn.test.ts +193 -0
  462. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  463. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +778 -0
  464. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  465. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  466. package/src/__tests__/taa-stability-feedback.ts +341 -0
  467. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  468. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  469. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  470. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  471. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  472. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  473. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  474. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  475. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  476. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  477. package/src/assembly/atmosphere-shader-prewarm.ts +38 -0
  478. package/src/assembly/dynamic-geometry-host.ts +887 -0
  479. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  480. package/src/assembly/factory.ts +4 -0
  481. package/src/assembly/gpu-driven-owner.ts +29 -0
  482. package/src/assembly/host-contract.ts +36 -0
  483. package/src/assembly/material/assembly.ts +38 -0
  484. package/src/assembly/material-shader-policy.ts +71 -28
  485. package/src/assembly/recovery/failure-location.ts +62 -0
  486. package/src/assembly/recovery/renderer-recover.ts +19 -17
  487. package/src/assembly/renderer-facade.ts +29 -0
  488. package/src/assembly/renderer-feature-inspection.ts +13 -0
  489. package/src/assembly/renderer-frame-transaction.ts +63 -0
  490. package/src/assembly/renderer-helpers.ts +26 -0
  491. package/src/assembly/renderer-inspection.ts +6 -0
  492. package/src/assembly/shader-prewarm-policy.ts +32 -0
  493. package/src/assembly/skin-palette-owner.ts +21 -0
  494. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  495. package/src/assembly/webgpu-device-loss.ts +75 -0
  496. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  497. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  498. package/src/assembly/webgpu-ready.ts +142 -121
  499. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  500. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  501. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  502. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  503. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  504. package/src/assembly/webgpu-renderer.ts +675 -614
  505. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  506. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  507. package/src/components/camera.ts +287 -7
  508. package/src/components/index.ts +1 -0
  509. package/src/components/instances.ts +45 -18
  510. package/src/components/scene-instance.ts +2 -1
  511. package/src/components/screen-space-reflection.ts +21 -0
  512. package/src/components/sprite-animation.ts +3 -3
  513. package/src/components/sprite-instances.ts +1 -1
  514. package/src/device/gpu-residency.ts +96 -93
  515. package/src/device/mesh-residency-lifetime.ts +73 -0
  516. package/src/dynamic-geometry.ts +736 -0
  517. package/src/environment/background.ts +263 -0
  518. package/src/errors/gpu-driven.ts +39 -5
  519. package/src/errors/render.ts +27 -3
  520. package/src/extract/camera.ts +26 -1
  521. package/src/extract/gpu-driven.ts +185 -10
  522. package/src/features/host.ts +237 -19
  523. package/src/features/noise-texture.ts +91 -0
  524. package/src/features/plan.ts +553 -24
  525. package/src/features/prepared-gpu-work.ts +631 -49
  526. package/src/features/prepared-graphics-store.ts +31 -0
  527. package/src/features/prepared-graphics.ts +5 -0
  528. package/src/features/render-graph-compute.ts +41 -8
  529. package/src/features/render-graph-contribution.ts +141 -3
  530. package/src/features/render-graph-raster.ts +143 -30
  531. package/src/features/types.ts +11 -0
  532. package/src/fullscreen-post-process-pass.ts +3 -0
  533. package/src/gpu-driven/batch-topology.ts +424 -102
  534. package/src/gpu-driven/pbr-program.ts +31 -0
  535. package/src/gpu-driven/prepared-draw.ts +29 -4
  536. package/src/gpu-driven/production-raster.ts +2267 -694
  537. package/src/gpu-driven/shadow-views.ts +539 -0
  538. package/src/gpu-driven/view-gpu.ts +188 -41
  539. package/src/gpu-scene-schema.ts +52 -11
  540. package/src/gpu-scene.ts +186 -99
  541. package/src/gpu-texture-usage.ts +1 -0
  542. package/src/hdrp-buffers.ts +72 -36
  543. package/src/ibl/frame-resources.ts +38 -0
  544. package/src/ibl/skylight-bind-group.ts +5 -4
  545. package/src/index.ts +125 -1
  546. package/src/inspection-types.ts +191 -0
  547. package/src/instances-derived-bounds.ts +258 -34
  548. package/src/instances.ts +459 -150
  549. package/src/internal.ts +22 -0
  550. package/src/lifecycle.ts +2 -0
  551. package/src/material-row.ts +145 -0
  552. package/src/materials.ts +44 -8
  553. package/src/pbr-pipeline.ts +159 -17
  554. package/src/pipeline/standard-forward-lane.ts +52 -24
  555. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  556. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  557. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  558. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  559. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  560. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  561. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  562. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  563. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  564. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  565. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  566. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  567. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  568. package/src/pipeline/standard-output/color-transform.ts +124 -0
  569. package/src/pipeline/standard-output/graph.ts +139 -0
  570. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  571. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  572. package/src/pipeline/standard-output/lut-state.ts +176 -0
  573. package/src/pipeline/standard-output/resources.ts +121 -0
  574. package/src/pipeline/standard-output/types.ts +58 -0
  575. package/src/pipeline/standard-pipeline.ts +192 -59
  576. package/src/pipeline/standard-post.ts +186 -27
  577. package/src/pipeline-builder.ts +16 -6
  578. package/src/pipeline-spec-types.ts +4 -0
  579. package/src/pipeline-spec.ts +37 -29
  580. package/src/points-lines/standard-owner.ts +6 -14
  581. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  582. package/src/record/__tests__/material-slot-plan.unit.test.ts +48 -0
  583. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  584. package/src/record/__tests__/recovery-pipeline.unit.test.ts +2 -29
  585. package/src/record/__tests__/sprite-material-abi.unit.test.ts +36 -5
  586. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  587. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  588. package/src/record/dynamic-geometry-consumption.ts +59 -0
  589. package/src/record/frame-lighting.ts +12 -11
  590. package/src/record/frame-snapshot.ts +133 -23
  591. package/src/record/frame-targets.ts +9 -0
  592. package/src/record/frame.ts +727 -133
  593. package/src/record/main-pass-geometry.ts +162 -98
  594. package/src/record/main-pass-material.ts +115 -26
  595. package/src/record/main-pass-sprite-draws.ts +18 -107
  596. package/src/record/main-pass.ts +78 -8
  597. package/src/record/material-uniforms.ts +1 -1
  598. package/src/record/mesh-ssbo.ts +59 -15
  599. package/src/record/prepared-material-bindings.ts +234 -0
  600. package/src/record/recovery-pipeline.ts +59 -136
  601. package/src/record/render-context.ts +92 -22
  602. package/src/record/shadow-pass.ts +1231 -209
  603. package/src/record/skybox-post-pass.ts +14 -3
  604. package/src/record/typed-frame-graph.ts +1006 -53
  605. package/src/record/view-ubo.ts +11 -0
  606. package/src/recovery/render-system-candidate.ts +90 -66
  607. package/src/recovery/render-system-roots.ts +113 -0
  608. package/src/recovery/types.ts +77 -0
  609. package/src/reflection/record-owner.ts +26 -54
  610. package/src/render-contract.ts +219 -25
  611. package/src/render-graph-primitives.ts +6 -2
  612. package/src/render-pipeline.ts +70 -1
  613. package/src/render-system-extract-tail.ts +409 -160
  614. package/src/render-system-extract.ts +376 -102
  615. package/src/render-system-projections.ts +241 -0
  616. package/src/render-system.ts +692 -791
  617. package/src/scene/render-scene-types.ts +13 -4
  618. package/src/scene/render-scene.ts +569 -355
  619. package/src/scene/shadow-visibility.ts +21 -0
  620. package/src/ssr/admission.ts +380 -14
  621. package/src/ssr/compose.ts +144 -0
  622. package/src/ssr/errors.ts +48 -0
  623. package/src/ssr/graph.ts +777 -0
  624. package/src/ssr/history.ts +436 -0
  625. package/src/ssr/hiz.ts +124 -0
  626. package/src/ssr/inspection.ts +124 -0
  627. package/src/ssr/resources.ts +202 -0
  628. package/src/ssr/temporal.ts +164 -0
  629. package/src/systems/skin-palette-allocator.ts +495 -148
  630. package/src/systems/skin-palette-types.ts +17 -0
  631. package/src/systems/transparent-dispatch.ts +90 -0
  632. package/src/targets/material-source.ts +34 -0
  633. package/src/temporal/coverage.ts +1 -1
  634. package/src/temporal/frame-coordinator.ts +23 -2
  635. package/src/temporal/gpu.ts +74 -12
  636. package/src/temporal/history.ts +3 -1
  637. package/src/temporal/inspection.ts +2 -1
  638. package/src/temporal/standard-scene-data.ts +3 -1
  639. package/src/temporal/temporal-view.ts +3 -0
  640. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +204 -139
  641. package/src/typed-render-graph-primitives.ts +266 -74
  642. package/src/typed-shadow-passes.ts +122 -12
  643. package/src/volume/temporal.ts +10 -0
  644. package/dist/chunk-ADHHVYLW.mjs.map +0 -1
  645. package/dist/chunk-FJ6P52EE.mjs.map +0 -1
  646. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  647. package/dist/chunk-GF523LHF.mjs.map +0 -1
  648. package/dist/chunk-HKXTW355.mjs.map +0 -1
  649. package/dist/chunk-JDWARUOI.mjs.map +0 -1
  650. package/dist/chunk-KM2NOX2I.mjs.map +0 -1
  651. package/dist/chunk-TMIASV2N.mjs.map +0 -1
  652. package/dist/chunk-XDP6XE5V.mjs.map +0 -1
  653. package/dist/chunk-ZZ4YQ474.mjs.map +0 -1
  654. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  655. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
@@ -0,0 +1,71 @@
1
+ import type { World } from '@forgeax/engine-ecs';
2
+ import type { GpuResidencyCache } from '../device/gpu-residency';
3
+ import {
4
+ createDynamicGeometryLifecycle,
5
+ type DynamicGeometryCandidate,
6
+ type DynamicGeometryLifecycle,
7
+ } from '../dynamic-geometry';
8
+ import { RendererContractFailureError, RendererOperationError } from '../errors/render';
9
+ import type { RenderSystem } from '../render-system';
10
+ import {
11
+ createDynamicGeometryHost,
12
+ type DynamicGeometryHostImplementation,
13
+ } from './dynamic-geometry-host';
14
+
15
+ export interface DynamicGeometryRuntime {
16
+ readonly lifecycle: DynamicGeometryLifecycle;
17
+ readonly host: DynamicGeometryHostImplementation;
18
+ }
19
+
20
+ /** Assemble the renderer-owned candidate lifecycle and its device host. */
21
+ export function createDynamicGeometryRuntime(options: {
22
+ readonly attachedWorlds: ReadonlySet<World>;
23
+ readonly getGpuStore: () => GpuResidencyCache;
24
+ readonly currentGeneration: () => number;
25
+ readonly renderSystem: Pick<
26
+ RenderSystem,
27
+ 'invalidateGeometryHistory' | 'isDynamicGeometryConsumed'
28
+ >;
29
+ }): DynamicGeometryRuntime {
30
+ const lifecycle = createDynamicGeometryLifecycle();
31
+ const host = createDynamicGeometryHost({
32
+ lifecycle,
33
+ attachedWorlds: options.attachedWorlds,
34
+ getGpuStore: options.getGpuStore,
35
+ currentGeneration: options.currentGeneration,
36
+ onTopologyChanged: () => options.renderSystem.invalidateGeometryHistory(),
37
+ isConsumedByRenderFrame: (candidate: DynamicGeometryCandidate) =>
38
+ options.renderSystem.isDynamicGeometryConsumed(
39
+ candidate.world as World,
40
+ candidate.entity ?? -1,
41
+ candidate.meshHandle,
42
+ ),
43
+ });
44
+ return { lifecycle, host };
45
+ }
46
+
47
+ /** Reject a draw while a derived-physics publication is still unsettled. */
48
+ export function validateDerivedPhysicsFrame(
49
+ worlds: readonly World[],
50
+ ): RendererOperationError<'frame-input-invalid'> | undefined {
51
+ for (const world of worlds) {
52
+ if (!world.hasResource('PhysicsWorld')) continue;
53
+ const physics = world.getResource<{
54
+ readonly getDerivedAdmission?: () => unknown;
55
+ readonly getDerivedRecoveryState?: () => string;
56
+ }>('PhysicsWorld');
57
+ if (
58
+ physics?.getDerivedAdmission?.() !== undefined ||
59
+ physics?.getDerivedRecoveryState?.() === 'rebuild-required'
60
+ ) {
61
+ return new RendererOperationError('frame-input-invalid', {
62
+ operation: 'draw',
63
+ cause: new RendererContractFailureError(
64
+ 'draw',
65
+ 'paired geometry admission must finish physics step and writeback in a healthy World before draw',
66
+ ),
67
+ });
68
+ }
69
+ }
70
+ return undefined;
71
+ }
@@ -9,6 +9,9 @@ import type { RendererAssemblyImplementation } from './host-contract';
9
9
  import { toError } from './renderer-facade';
10
10
  import { tryCreateWebGPURenderer } from './webgpu-renderer';
11
11
 
12
+ export { disposeObservationCaptureSet } from './webgpu-renderer';
13
+ export { particleMaterialInputVertexBuffers } from './webgpu-vertex-layouts';
14
+
12
15
  /*
13
16
  * Renderer ownership stays explicit even though the implementation is split:
14
17
  * the delegated target owner comes from './render-target-host'. The concrete
@@ -69,6 +72,7 @@ export {
69
72
  resolveMaterialShaderUvSetCount,
70
73
  resolveMaterialShaderVariantSet,
71
74
  resolveMaterialShaderVertexInputContract,
75
+ selectGpuDrivenSceneIndexVariant,
72
76
  selectHdrpPbrPrewarmVariants,
73
77
  selectNoColorPbrVariant,
74
78
  selectPipelineLayoutForVariant,
@@ -0,0 +1,29 @@
1
+ import { err, type RhiDevice, RhiError } from '@forgeax/engine-rhi';
2
+ import { GpuDrivenProduction } from '../gpu-driven/production-raster';
3
+ import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
4
+
5
+ /**
6
+ * Renderer-owned GPU-driven frame state boundary. The production object owns
7
+ * view resources and prepared generations; callers only supply the backend
8
+ * and shader factory and must not create a parallel frame loop.
9
+ */
10
+ export function createGpuDrivenOwner(
11
+ device: RhiDevice,
12
+ shaderModuleFactory?: PipelineBuilderShaderModuleFactory,
13
+ recoveryCount = 0,
14
+ ): GpuDrivenProduction {
15
+ return new GpuDrivenProduction(
16
+ device,
17
+ shaderModuleFactory ?? {
18
+ createShaderModule: () =>
19
+ err(
20
+ new RhiError({
21
+ code: 'rhi-not-available',
22
+ expected: 'the renderer backend exposes shader module creation',
23
+ hint: 'construct the renderer through the backend pack before activating GPU-driven rendering',
24
+ }),
25
+ ),
26
+ },
27
+ recoveryCount,
28
+ );
29
+ }
@@ -2,10 +2,18 @@ import type { AssetRegistry } from '@forgeax/engine-assets-runtime';
2
2
  import type { World } from '@forgeax/engine-ecs';
3
3
  import type { Result, RhiDevice, RhiError, ShaderModule } from '@forgeax/engine-rhi';
4
4
  import type { RenderPipelineAsset } from '@forgeax/engine-types';
5
+ import type {
6
+ DynamicGeometryCandidate,
7
+ DynamicGeometryError,
8
+ DynamicGeometryOrdering,
9
+ DynamicGeometryPrepareInput,
10
+ DynamicGeometryReceipt,
11
+ } from '../dynamic-geometry';
5
12
  import type { RecoverFailure } from '../errors/recover';
6
13
  import type { ObservationUnavailableError, RenderError } from '../errors/render';
7
14
  import type { RenderFeature, RenderFeatureDiagnostics } from '../features/types';
8
15
  import type { GpuDrivenProductionInspection, LodOcclusionInspection } from '../inspection-types';
16
+ import type { InstanceCollectionStore } from '../instances';
9
17
  import type { MeshMaterialBindingObservation } from '../mesh-material-bindings';
10
18
  import type { FrameObservation, FrameObservationOptions } from '../record/frame';
11
19
  import type { CurrentGraphTarget, GraphTargetCaptureRequest } from '../record/frame-snapshot';
@@ -26,6 +34,7 @@ import type {
26
34
  RenderWorldLease,
27
35
  } from '../render-contract';
28
36
  import type { RenderSceneInspection } from '../render-system';
37
+ import type { RenderSceneBounds } from '../scene/render-scene-types';
29
38
  import type {
30
39
  RenderTarget,
31
40
  RenderTargetDescriptor,
@@ -53,7 +62,28 @@ export type RendererHostEventListener = (event: RendererHostEvent) => void;
53
62
  * the public Renderer type.
54
63
  */
55
64
  export interface RendererHostImplementation {
65
+ /** Renderer-owned authoring and update path for large instance collections. */
66
+ readonly instances: InstanceCollectionStore;
56
67
  attach(world: World): RenderResult<RenderWorldLease, RenderError>;
68
+ prepareDynamicGeometry(
69
+ input: DynamicGeometryPrepareInput,
70
+ ): Result<DynamicGeometryCandidate, DynamicGeometryError>;
71
+ acceptDynamicGeometry(
72
+ candidate: DynamicGeometryCandidate,
73
+ ordering: DynamicGeometryOrdering,
74
+ ): Result<DynamicGeometryCandidate, DynamicGeometryError>;
75
+ dynamicGeometryReceipt(candidate: DynamicGeometryCandidate): DynamicGeometryReceipt | undefined;
76
+ cancelDynamicGeometry(candidate: DynamicGeometryCandidate): Result<void, DynamicGeometryError>;
77
+ retireDynamicGeometry(candidate: DynamicGeometryCandidate): Result<void, DynamicGeometryError>;
78
+ publishDynamicGeometry(
79
+ frame: {
80
+ readonly frameId: number;
81
+ readonly deviceGeneration: number;
82
+ readonly completed?: Promise<unknown>;
83
+ },
84
+ worlds?: readonly object[],
85
+ fixedStep?: number,
86
+ ): readonly DynamicGeometryReceipt[];
57
87
  createRenderTarget(descriptor: RenderTargetDescriptor): RenderResult<RenderTarget, RenderError>;
58
88
  resizeRenderTarget(
59
89
  target: RenderTarget,
@@ -69,6 +99,8 @@ export interface RendererHostImplementation {
69
99
  ): RenderResult<RenderTargetReadbackTicket, RenderError>;
70
100
  destroyRenderTarget(target: RenderTarget): RenderResult<void, RenderError>;
71
101
  setProfile(profile: RenderProfile): RenderResult<void, RenderError>;
102
+ /** Detached world bounds for one record in the last extracted World; undefined if unavailable. */
103
+ bounds(world: World, entity: number): RenderSceneBounds | undefined;
72
104
  inspect(): RenderInspection;
73
105
  /**
74
106
  * Internal bounded inspection for high-cardinality producers. The public
@@ -80,6 +112,10 @@ export interface RendererHostImplementation {
80
112
  readonly gpuDriven: GpuDrivenProductionInspection;
81
113
  };
82
114
  drawFrame(request: RenderFrameInput): RenderResult<FrameReceipt, RhiError | RenderError>;
115
+ /** Arm one upcoming frame for receipt-bound color observations. */
116
+ requestObservation?: (
117
+ domains: readonly import('../render-contract').FrameObservationDomain[],
118
+ ) => RenderResult<void, RenderError>;
83
119
  observe(
84
120
  receipt: FrameReceipt,
85
121
  request: FrameObservationRequest,
@@ -6,6 +6,10 @@ import {
6
6
  type CookedMaterialRecord,
7
7
  materialLayerPlanIdentity,
8
8
  } from '@forgeax/engine-pack/material-cook';
9
+ import {
10
+ createStandardPbrArtifactReceipt,
11
+ type MaterialShaderArtifact,
12
+ } from '@forgeax/engine-shader';
9
13
  import type { StandardLayerPlan } from '@forgeax/engine-types';
10
14
  import { projectStandardLayerPlan } from './standard-layer-projection.js';
11
15
 
@@ -30,3 +34,37 @@ export function assembleMaterialProjection(record: CookedMaterialRecord): Materi
30
34
  layerPlan,
31
35
  };
32
36
  }
37
+
38
+ /**
39
+ * Assemble the one built-in Standard PBR artifact from the selected producer WGSL.
40
+ * Both rigid and skinned identifiers use this producer; unsupported identifiers
41
+ * stay outside the GPU-driven Standard PBR lane.
42
+ */
43
+ export function assembleStandardPbrArtifact(
44
+ materialShaderId: string,
45
+ wgsl: string,
46
+ vertexColorAvailable = false,
47
+ ): MaterialShaderArtifact | undefined {
48
+ const skinned =
49
+ materialShaderId === 'forgeax::pbr-skin' ||
50
+ materialShaderId === 'forgeax::default-standard-pbr-skin';
51
+ if (materialShaderId !== 'forgeax::default-standard-pbr' && !skinned) return undefined;
52
+
53
+ const receipt = createStandardPbrArtifactReceipt(skinned, vertexColorAvailable);
54
+ return {
55
+ material: materialShaderId,
56
+ pass: 'forward',
57
+ wgsl,
58
+ layoutIdentity: receipt.reflection.layoutIdentity,
59
+ bindings: [],
60
+ deps: [],
61
+ vertexInputs: receipt.vertexInputs.map(
62
+ (input): Readonly<Record<string, unknown>> => ({
63
+ semantic: input.semantic,
64
+ location: input.location,
65
+ format: input.format,
66
+ }),
67
+ ),
68
+ receipt,
69
+ };
70
+ }
@@ -283,16 +283,16 @@ export async function prepareMaterialShaders(
283
283
  const capValue = (rhiDevice.limits as Readonly<Record<string, number>>)
284
284
  .maxStorageBuffersPerShaderStage;
285
285
  const webgl2Downlevel = rhiDevice.caps.backendKind === 'wgpu-webgl2';
286
- const storageBufferCapable = rhiDevice.caps.storageBuffer;
287
- if (storageBufferCapable && typeof capValue === 'number') {
286
+ let storageBufferCapable = !webgl2Downlevel && rhiDevice.caps.storageBuffer;
287
+ if (typeof capValue === 'number') {
288
288
  const capCheck = assertStorageBufferCap(capValue);
289
289
  if (!capCheck.ok) throw capCheck.error;
290
+ storageBufferCapable = !webgl2Downlevel && rhiDevice.caps.storageBuffer && capCheck.value;
290
291
  }
291
292
  const extendedLightingShaderAvailable = deriveExtendedLightingCapability(rhiDevice).admitted;
292
293
  const projectorAvailable =
293
294
  (rhiDevice.limits.maxSampledTexturesPerShaderStage ?? 0) >=
294
295
  STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES;
295
-
296
296
  // ── Step 1: manifest load ─────────────────────────────────────────────────
297
297
  const registry = getShader();
298
298
  const loaded = await registry.loadManifest();
@@ -301,35 +301,46 @@ export async function prepareMaterialShaders(
301
301
  }
302
302
 
303
303
  // ── Step 1b: material shader variant resolution + registration ───────────
304
- // feat-20260609-hdrp-cluster-fragment-ggx M1 / w7: dual-axis variant
305
- // resolution. At boot time isHdrpActive is always false (URP default),
306
- // so CLUSTER_FORWARD_AVAILABLE=false variant is selected. HDRP variant
307
- // (CLUSTER_FORWARD_AVAILABLE=true) is resolved later when
308
- // clustered Standard profile activation selects the clustered variant.
309
- const isHdrpActive = false; // M4: wire to actual renderSystem.frameState.isHdrpActive
304
+ // feat-20260609-hdrp-cluster-fragment-ggx M1 / w7: the boot resolver selects
305
+ // the non-clustered variant; clustered Standard activation resolves its own
306
+ // variant later at record time.
310
307
  for (const msEntry of registry.materialShaderManifestEntries()) {
311
308
  // bug-20260610: skip synthetic non-material engine entries piggy-backing
312
309
  // on the materialShaders channel for variant surfacing (shadow_caster).
313
310
  // They use the `forgeax::engine-` prefix and are consumed by Step 2's
314
311
  // engine-entry compile path, NOT by installMaterialArtifact.
315
312
  if (msEntry.identifier.startsWith('forgeax::engine-')) continue;
316
- // buildVariantKey logic: sorted key=value pairs joined with +; all-true = ''.
317
- const variantDefines: Record<string, boolean> = {};
318
- if (msEntry.variants.some((variant) => 'STORAGE_BUFFER_AVAILABLE' in variant.defines)) {
319
- variantDefines.STORAGE_BUFFER_AVAILABLE = storageBufferCapable;
320
- }
321
- // User material manifests may declare WEBGL2_COMPAT alongside the shared
322
- // mesh-storage axis. The fallback backend must select that authored
323
- // branch at boot; otherwise it asks for the impossible bare
324
- // `STORAGE_BUFFER_AVAILABLE=false` key and fails before the first frame.
313
+ // The same closed resolver drives every manifest axis at boot. This keeps
314
+ // registration aligned with record-time capability/feature selection and
315
+ // supplies explicit defaults for opt-in axes such as shadow alpha-mask and
316
+ // GPU-driven scene-index variants.
317
+ // Build the exact boot key from the capability facts and explicit defaults.
318
+ // Record-time callers use resolveMaterialShaderVariantSet below; keeping
319
+ // the same axes here prevents a physical-material variant from being
320
+ // registered under a key that cannot be selected by the renderer.
321
+ const variantDefines: Record<string, boolean> = {
322
+ STORAGE_BUFFER_AVAILABLE: storageBufferCapable,
323
+ };
325
324
  if (msEntry.variants.some((v) => 'WEBGL2_COMPAT' in v.defines)) {
326
325
  variantDefines.WEBGL2_COMPAT = webgl2Downlevel;
327
326
  }
328
- // Only include CLUSTER_FORWARD_AVAILABLE when the material shader declares
329
- // the axis (has a variant with this key), preserving backward compat for
330
- // entries without the pragma.
331
327
  if (msEntry.variants.some((v) => 'CLUSTER_FORWARD_AVAILABLE' in v.defines)) {
332
- variantDefines.CLUSTER_FORWARD_AVAILABLE = isHdrpActive;
328
+ variantDefines.CLUSTER_FORWARD_AVAILABLE = false;
329
+ }
330
+ if (msEntry.variants.some((v) => 'GPU_DRIVEN_SCENE_INDEX_AVAILABLE' in v.defines)) {
331
+ variantDefines.GPU_DRIVEN_SCENE_INDEX_AVAILABLE = false;
332
+ }
333
+ if (msEntry.variants.some((v) => 'GPU_DRIVEN_SCENE_INDEX_EXPLICIT' in v.defines)) {
334
+ // The boot material is the compact visible-stream path. Explicit
335
+ // scene-index dispatches select their own variant at record time; they
336
+ // must never make the default artifact key unsatisfiable.
337
+ variantDefines.GPU_DRIVEN_SCENE_INDEX_EXPLICIT = false;
338
+ }
339
+ if (msEntry.variants.some((v) => 'ALPHA_MASK' in v.defines)) {
340
+ // Alpha-mask admission is a per-draw producer fact. Keep the boot
341
+ // artifact opaque and resolve ALPHA_MASK=true only for a receipt-owned
342
+ // shadow batch.
343
+ variantDefines.ALPHA_MASK = false;
333
344
  }
334
345
  if (msEntry.variants.some((v) => 'DIRECTIONAL_PCSS_AVAILABLE' in v.defines)) {
335
346
  variantDefines.DIRECTIONAL_PCSS_AVAILABLE = directionalPcssCapable(
@@ -345,10 +356,12 @@ export async function prepareMaterialShaders(
345
356
  if (msEntry.variants.some((v) => 'EXTENDED_LIGHTING_AVAILABLE' in v.defines)) {
346
357
  variantDefines.EXTENDED_LIGHTING_AVAILABLE = extendedLightingShaderAvailable;
347
358
  }
348
- if (
349
- msEntry.identifier === 'forgeax::default-standard-pbr' &&
350
- msEntry.variants.some((v) => 'PROJECTOR_AVAILABLE' in v.defines)
351
- ) {
359
+ // A material shader that declares the projector axis owns the same
360
+ // capability-selected resource pair, regardless of whether it is the
361
+ // engine Standard entry or a VFX particle entry. Omitting this value for
362
+ // particle variants asks the manifest for a partial key and fails before
363
+ // the first frame when the shader does not use the Standard root.
364
+ if (msEntry.variants.some((v) => 'PROJECTOR_AVAILABLE' in v.defines)) {
352
365
  variantDefines.PROJECTOR_AVAILABLE = projectorAvailable;
353
366
  }
354
367
  if (msEntry.variants.some((v) => 'TRANSMISSION_AVAILABLE' in v.defines)) {
@@ -516,7 +529,15 @@ export async function prepareMaterialShaders(
516
529
  * material-shader layouts add a `LayoutKind` member + a PipelineState slot
517
530
  * + a switch arm here in one cut (charter P3 extensibility).
518
531
  */
519
- export type LayoutKind = 'pbr' | 'pbr-skin' | 'hdrp-pbr' | 'hdrp-skin' | 'sprite-urp' | 'unlit-urp';
532
+ export type LayoutKind =
533
+ | 'pbr'
534
+ | 'pbr-skin'
535
+ | 'gpu-driven-pbr'
536
+ | 'gpu-driven-skin'
537
+ | 'hdrp-pbr'
538
+ | 'hdrp-skin'
539
+ | 'sprite-urp'
540
+ | 'unlit-urp';
520
541
 
521
542
  function directionalPcssCapable(backendKind: RhiDevice['caps']['backendKind']): boolean {
522
543
  return backendKind === 'webgpu' || backendKind === 'wgpu-native';
@@ -627,6 +648,17 @@ export function resolveMaterialShaderBindingContract(
627
648
  /@group\s*\(\s*0\s*\)\s*@binding\s*\(\s*1\s*\)\s*var\s+scene_depth\s*:\s*texture_depth_2d\b/u.test(
628
649
  withoutComments,
629
650
  );
651
+ const declaresSceneDepthAtZero =
652
+ /@group\s*\(\s*0\s*\)\s*@binding\s*\(\s*0\s*\)\s*var\s+scene_depth\s*:\s*texture_depth_2d\b/u.test(
653
+ withoutComments,
654
+ );
655
+ const hasMaterialGroup = groups.includes(1);
656
+ if (declaresView && declaresSceneDepth && hasMaterialGroup) {
657
+ return 'render-material-and-scene-depth';
658
+ }
659
+ if (declaresSceneDepthAtZero && hasMaterialGroup) {
660
+ return 'render-material-with-scene-depth';
661
+ }
630
662
  if (declaresView && declaresSceneDepth && groups.every((group) => group === 0)) {
631
663
  return 'view-and-scene-depth';
632
664
  }
@@ -760,8 +792,11 @@ export function shouldDeferMissingPreparedMaterialShader(
760
792
  ): boolean {
761
793
  return (
762
794
  vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.billboardMaterialInstance ||
795
+ vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.billboardMaterialInputInstance ||
763
796
  vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.topologySegmentInstance ||
764
- vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.meshGeometryMaterialInstance
797
+ vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.topologySegmentMaterialInputInstance ||
798
+ vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.meshGeometryMaterialInstance ||
799
+ vertexLayout === RENDER_FEATURE_VERTEX_LAYOUTS.meshGeometryMaterialInputInstance
765
800
  );
766
801
  }
767
802
 
@@ -773,6 +808,8 @@ export function selectPipelineLayoutForVariant(
773
808
  readonly hdrpProbePbrPipelineLayout?: PipelineLayout | null;
774
809
  readonly pbrSkinPipelineLayout: PipelineLayout | null;
775
810
  readonly pbrSkinProbePipelineLayout?: PipelineLayout | null;
811
+ readonly gpuDrivenPbrPipelineLayout?: PipelineLayout | null;
812
+ readonly gpuDrivenPbrSkinPipelineLayout?: PipelineLayout | null;
776
813
  readonly hdrpSkinPipelineLayout?: PipelineLayout | null;
777
814
  } | null,
778
815
  variantSet: string | undefined,
@@ -780,6 +817,12 @@ export function selectPipelineLayoutForVariant(
780
817
  ): PipelineLayout | null {
781
818
  if (state === null) return null;
782
819
  const probeBlendVariant = variantSet?.includes('PROBE_BLEND_AVAILABLE=true') === true;
820
+ if (layoutKind === 'gpu-driven-pbr') {
821
+ return state.gpuDrivenPbrPipelineLayout ?? null;
822
+ }
823
+ if (layoutKind === 'gpu-driven-skin') {
824
+ return state.gpuDrivenPbrSkinPipelineLayout ?? null;
825
+ }
783
826
  // bug-20260611: skin layout selection takes precedence over HDRP variant
784
827
  // resolution. HDRP × skin is OOS-1 (plan-strategy R-2 — left for a
785
828
  // dedicated feat); when an HDRP-variant skin call ever lands, we fail
@@ -0,0 +1,62 @@
1
+ import type { DeviceResourceKind } from '../../device/resource-types';
2
+ import type { RecoveryGuidance, RecoveryPhase } from '../renderer-lifecycle';
3
+
4
+ export interface RecoveryFailureLocation {
5
+ readonly phase: RecoveryPhase;
6
+ readonly retryable: boolean;
7
+ readonly guidance: RecoveryGuidance;
8
+ readonly owner: string;
9
+ readonly resourceKind: DeviceResourceKind;
10
+ readonly cause: unknown;
11
+ }
12
+
13
+ function recoveryCauseCode(cause: unknown): string | undefined {
14
+ if (typeof cause !== 'object' || cause === null) return undefined;
15
+ const directCode = (cause as { readonly code?: unknown }).code;
16
+ if (typeof directCode === 'string') return directCode;
17
+ const detail = (cause as { readonly detail?: unknown }).detail;
18
+ if (typeof detail !== 'object' || detail === null) return undefined;
19
+ const detailCode = (detail as { readonly code?: unknown }).code;
20
+ if (typeof detailCode === 'string') return detailCode;
21
+ return recoveryCauseCode((detail as { readonly cause?: unknown }).cause);
22
+ }
23
+
24
+ export function createRecoveryFailureLocation(
25
+ phase: RecoveryPhase,
26
+ cause: unknown,
27
+ overrides: Partial<Omit<RecoveryFailureLocation, 'phase' | 'cause'>> = {},
28
+ ): RecoveryFailureLocation {
29
+ const code = recoveryCauseCode(cause) ?? '';
30
+ const resourceKind: DeviceResourceKind = code.includes('shader')
31
+ ? 'shader'
32
+ : code.includes('buffer')
33
+ ? 'buffer'
34
+ : code.includes('texture')
35
+ ? 'texture'
36
+ : code.includes('binding')
37
+ ? 'binding'
38
+ : phase === 'rehydrate'
39
+ ? 'shader'
40
+ : phase === 'acquire-adapter' || phase === 'acquire-device'
41
+ ? 'surface'
42
+ : phase === 'publish' || phase === 'cleanup'
43
+ ? 'surface'
44
+ : 'pipeline';
45
+ const owner =
46
+ code.includes('shader') || phase === 'rehydrate'
47
+ ? 'shader'
48
+ : phase === 'acquire-adapter' || phase === 'acquire-device'
49
+ ? 'backend'
50
+ : phase === 'compile-graph'
51
+ ? 'pipeline'
52
+ : 'renderer';
53
+ return {
54
+ phase,
55
+ retryable: false,
56
+ guidance: 'repair-owner',
57
+ owner,
58
+ resourceKind,
59
+ cause,
60
+ ...overrides,
61
+ };
62
+ }
@@ -19,18 +19,14 @@ import {
19
19
  postProcessShaderEntrySignature,
20
20
  postProcessShaderPipelineLabel,
21
21
  } from '../../fullscreen-post-process-pass';
22
- import { createRecoveryColdWorkGuard } from '../../record/recovery-pipeline';
23
- import type {
24
- PipelineState,
25
- RecoveryColdWorkGuard,
26
- RenderSystemInternals,
27
- } from '../../record/render-context';
22
+ import { resolveStandardPbrProgram } from '../../gpu-driven/pbr-program';
23
+ import type { PipelineState, RenderSystemInternals } from '../../record/render-context';
28
24
  import type {
29
25
  RecoveryGraphCandidate,
30
26
  RecoveryPostProcessResources,
31
27
  RecoveryRootBundle,
32
- RenderSystem,
33
- } from '../../render-system';
28
+ } from '../../recovery/types';
29
+ import type { RenderSystem } from '../../render-system';
34
30
  import type { RhiBackendPack } from '../backend-contract';
35
31
  import {
36
32
  type LayoutKind,
@@ -42,8 +38,9 @@ import type { MeshSsboGrowResult, MeshSsboState } from '../mesh-ssbo-grow';
42
38
  import { structuredRendererCause } from '../renderer-facade';
43
39
  import { ensureContextConfigured } from '../renderer-helpers';
44
40
  import type { RecoveryContinuation, RecoveryDeadline, RecoveryPhase } from '../renderer-lifecycle';
45
- import type { RecoveryFailureLocation, WebGPURendererInternals } from '../webgpu-renderer';
41
+ import type { WebGPURendererInternals } from '../webgpu-renderer';
46
42
  import { attachDeviceLostFanout } from './device-loss-fanout';
43
+ import type { RecoveryFailureLocation } from './failure-location';
47
44
  import { buildGenerationAggregate, type GenerationAggregate } from './generation';
48
45
  import {
49
46
  acquireDeviceGeneration,
@@ -166,7 +163,6 @@ export interface RendererRecoveryDependencies {
166
163
  candidatePostProcessResources: RecoveryPostProcessResources,
167
164
  recoveryRootBundle: RecoveryRootBundle,
168
165
  recoveryGraphCandidate: RecoveryGraphCandidate | undefined,
169
- recoveryColdWorkGuard: RecoveryColdWorkGuard,
170
166
  ) => void;
171
167
  }
172
168
 
@@ -253,7 +249,6 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
253
249
  // old roots remain authoritative until the final synchronous publication.
254
250
  const candidateGpuStore = new GpuResidencyCache();
255
251
  const candidateDynamicTextureStore = new DynamicTextureStore();
256
- const recoveryColdWorkGuard = createRecoveryColdWorkGuard();
257
252
  // Re-acquire through the SAME backend pack (the
258
253
  // idempotent factory primitives tryCreateWebGPURenderer uses). On the
259
254
  // adapter / device failure paths, health stays `device-lost` (A-AC-07):
@@ -568,14 +563,22 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
568
563
  const candidateInternals = Object.create(internals) as WebGPURendererInternals &
569
564
  RenderSystemInternals;
570
565
  Object.defineProperties(candidateInternals, {
566
+ assets: { value: assets },
571
567
  device: { value: candidateState.device },
572
568
  context: { value: candidateState.context },
573
569
  deviceScope: { value: candidateState.scope },
574
570
  gpuStore: { value: candidateState.gpuStore },
575
571
  dynamicTextureStore: { value: candidateState.dynamicTextureStore },
576
- recoveryColdWorkGuard: { value: undefined },
577
572
  getMaterialShaderPipeline: { value: getMaterialShaderPipeline },
578
573
  getMaterialShaderPipelineEntry: { value: getMaterialShaderPipelineEntry },
574
+ getMaterialShaderArtifact: {
575
+ value: (materialShaderId: string, vertexColorAvailable = false) =>
576
+ resolveStandardPbrProgram(
577
+ candidatePipelineState.gpuDrivenPbrPrograms,
578
+ materialShaderId,
579
+ vertexColorAvailable,
580
+ )?.artifact,
581
+ },
579
582
  getMaterialShaderBindingContract: { value: getCachedMaterialShaderBindingContract },
580
583
  getParamSchema: { value: getParamSchema },
581
584
  getMaterialBindGroupLayout: { value: getMaterialBindGroupLayout },
@@ -594,20 +597,20 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
594
597
  value: (
595
598
  id: string,
596
599
  bgl: BindGroupLayout,
597
- colorFormat: GPUTextureFormat,
600
+ colorFormats: readonly GPUTextureFormat[],
598
601
  entryOverride?: PostProcessShaderEntry,
599
602
  ) => {
600
603
  const entry = entryOverride ?? candidateInternals.lookupPostProcess?.(id);
601
604
  if (entry === undefined || candidateInternals.buildPostProcessPipeline === undefined) {
602
605
  return null;
603
606
  }
604
- const key = `${id}|${colorFormat}|${postProcessShaderEntrySignature(entry)}`;
607
+ const key = `${id}|${colorFormats.join(',')}|${postProcessShaderEntrySignature(entry)}`;
605
608
  const cached = candidatePostProcessPipelineCache.get(key);
606
609
  if (cached !== undefined) return cached;
607
610
  const built = candidateInternals.buildPostProcessPipeline(
608
611
  entry,
609
612
  bgl,
610
- colorFormat,
613
+ colorFormats,
611
614
  postProcessShaderPipelineLabel(id, entry.source),
612
615
  );
613
616
  if (built === null) return null;
@@ -632,7 +635,7 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
632
635
  releaseCandidate();
633
636
  return err(new RecoverError('recover-device-unavailable'));
634
637
  }
635
- const graphPreparation = await renderSystem.prepareRecoveryGraphCandidate({
638
+ const graphPreparation = renderSystem.prepareRecoveryGraphCandidate({
636
639
  internals: candidateInternals,
637
640
  pipelineState: candidatePipelineState,
638
641
  });
@@ -872,7 +875,6 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
872
875
  candidatePostProcessResources,
873
876
  preparedRecoveryRoots,
874
877
  recoveryGraphCandidate,
875
- recoveryColdWorkGuard,
876
878
  );
877
879
  if (recoveryGraphCandidate !== undefined) {
878
880
  recoveryGraphCandidate = undefined;
@@ -3,6 +3,11 @@
3
3
  // lease/receipt contract and owns the profile/error projection helpers.
4
4
 
5
5
  import { err, ok, type RhiError } from '@forgeax/engine-rhi';
6
+ import type {
7
+ DynamicGeometryCandidate,
8
+ DynamicGeometryOrdering,
9
+ DynamicGeometryPrepareInput,
10
+ } from '../dynamic-geometry';
6
11
  import { type RecoverFailure, RecoveryFailedError } from '../errors/recover';
7
12
  import {
8
13
  type RenderError,
@@ -16,6 +21,7 @@ import {
16
21
  STANDARD_POST_STAGE_NAMES,
17
22
  } from '../pipeline/standard-profile';
18
23
  import type {
24
+ FrameObservationDomain,
19
25
  Renderer,
20
26
  RendererError,
21
27
  RendererEventListener,
@@ -83,6 +89,8 @@ export function exposeRenderer(renderer: RendererHostImplementation): Renderer {
83
89
  });
84
90
 
85
91
  return {
92
+ instances: renderer.instances,
93
+ bounds: (world, entity) => (disposed ? undefined : renderer.bounds(world, entity)),
86
94
  attach: (world) => {
87
95
  const result = renderer.attach(world);
88
96
  return result.ok
@@ -94,6 +102,18 @@ export function exposeRenderer(renderer: RendererHostImplementation): Renderer {
94
102
  }),
95
103
  );
96
104
  },
105
+ prepareDynamicGeometry: (input: DynamicGeometryPrepareInput) =>
106
+ renderer.prepareDynamicGeometry(input),
107
+ acceptDynamicGeometry: (
108
+ candidate: DynamicGeometryCandidate,
109
+ ordering: DynamicGeometryOrdering,
110
+ ) => renderer.acceptDynamicGeometry(candidate, ordering),
111
+ dynamicGeometryReceipt: (candidate: DynamicGeometryCandidate) =>
112
+ renderer.dynamicGeometryReceipt(candidate),
113
+ cancelDynamicGeometry: (candidate: DynamicGeometryCandidate) =>
114
+ renderer.cancelDynamicGeometry(candidate),
115
+ retireDynamicGeometry: (candidate: DynamicGeometryCandidate) =>
116
+ renderer.retireDynamicGeometry(candidate),
97
117
  createRenderTarget: (descriptor) => renderer.createRenderTarget(descriptor),
98
118
  resizeRenderTarget: (target, descriptor) => renderer.resizeRenderTarget(target, descriptor),
99
119
  createRenderTargetTextureSource: (target, options) =>
@@ -130,10 +150,19 @@ export function exposeRenderer(renderer: RendererHostImplementation): Renderer {
130
150
  kind: 'frame-submitted',
131
151
  frameId: result.value.frameId,
132
152
  deviceGeneration: result.value.deviceGeneration,
153
+ receipt: result.value,
133
154
  }),
134
155
  );
135
156
  return ok(result.value);
136
157
  },
158
+ requestObservation: (domains: readonly FrameObservationDomain[]) =>
159
+ renderer.requestObservation?.(domains) ??
160
+ err(
161
+ new RendererOperationError('renderer-state-invalid', {
162
+ operation: 'request-observation',
163
+ state: lifecycle.state(),
164
+ }),
165
+ ),
137
166
  inspect: () => ({ ...renderer.inspect(), state: lifecycle.state() }),
138
167
  observe: (receipt, request) => renderer.observe(receipt, request),
139
168
  subscribe: (listener) => {