@forgeax/engine-render 0.1.28 → 0.1.30

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 (768) hide show
  1. package/README.md +856 -126
  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/device-feature-admission.d.ts +4 -3
  5. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  6. package/dist/assembly/dynamic-geometry-host.d.ts +27 -0
  7. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  8. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  9. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +3 -1
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  13. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  14. package/dist/assembly/host-contract.d.ts +14 -0
  15. package/dist/assembly/host-contract.d.ts.map +1 -1
  16. package/dist/assembly/material/assembly.d.ts +31 -1
  17. package/dist/assembly/material/assembly.d.ts.map +1 -1
  18. package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
  19. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-policy.d.ts +3 -1
  21. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  22. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  23. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  24. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  25. package/dist/assembly/recovery/recovery-attempt.d.ts +1 -6
  26. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
  27. package/dist/assembly/recovery/renderer-recover.d.ts +7 -4
  28. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  29. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  30. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  31. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  32. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  33. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  34. package/dist/assembly/renderer-helpers.d.ts +3 -0
  35. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  36. package/dist/assembly/renderer-inspection.d.ts +4 -0
  37. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  38. package/dist/assembly/shader-prewarm-policy.d.ts +7 -1
  39. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  40. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  41. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  42. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  43. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  45. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  48. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  49. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  50. package/dist/assembly/webgpu-ready.d.ts +7 -3
  51. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  52. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  53. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  54. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  55. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  56. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  57. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  58. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  59. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  60. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  61. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  62. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  63. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  64. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  65. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  66. package/dist/authoring.mjs +2 -2
  67. package/dist/capture/scene-projection.d.ts +41 -0
  68. package/dist/capture/scene-projection.d.ts.map +1 -0
  69. package/dist/{chunk-J52NMQKR.mjs → chunk-7MQ3XBSP.mjs} +1098 -844
  70. package/dist/chunk-7MQ3XBSP.mjs.map +1 -0
  71. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  72. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  73. package/dist/{chunk-VSL23LZE.mjs → chunk-C3DDSXYK.mjs} +1188 -463
  74. package/dist/chunk-C3DDSXYK.mjs.map +1 -0
  75. package/dist/{chunk-IQMKJLNU.mjs → chunk-FUUO4UND.mjs} +443 -30
  76. package/dist/chunk-FUUO4UND.mjs.map +1 -0
  77. package/dist/{chunk-J6KACNOH.mjs → chunk-JRBDO2KB.mjs} +617 -7
  78. package/dist/chunk-JRBDO2KB.mjs.map +1 -0
  79. package/dist/{chunk-GE3SDD72.mjs → chunk-MDQJPY3T.mjs} +20 -40
  80. package/dist/chunk-MDQJPY3T.mjs.map +1 -0
  81. package/dist/{chunk-MYJ5RPJO.mjs → chunk-NO4WZCAH.mjs} +3 -3
  82. package/dist/chunk-NO4WZCAH.mjs.map +1 -0
  83. package/dist/{chunk-RBDBZ5R7.mjs → chunk-PA5DRJNI.mjs} +2 -2
  84. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  85. package/dist/{chunk-MBU4ZVE7.mjs → chunk-PSEQ6QPH.mjs} +4655 -892
  86. package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
  87. package/dist/{chunk-JAASCMXA.mjs → chunk-S5UE2T5P.mjs} +289 -41
  88. package/dist/chunk-S5UE2T5P.mjs.map +1 -0
  89. package/dist/components/camera.d.ts +62 -2
  90. package/dist/components/camera.d.ts.map +1 -1
  91. package/dist/components/directional-light.d.ts +2 -2
  92. package/dist/components/dynamic-resolution.d.ts +15 -0
  93. package/dist/components/dynamic-resolution.d.ts.map +1 -0
  94. package/dist/components/index.d.ts +2 -0
  95. package/dist/components/index.d.ts.map +1 -1
  96. package/dist/components/instances.d.ts +6 -20
  97. package/dist/components/instances.d.ts.map +1 -1
  98. package/dist/components/light-helpers.d.ts.map +1 -1
  99. package/dist/components/reflection-probe.d.ts +1 -0
  100. package/dist/components/reflection-probe.d.ts.map +1 -1
  101. package/dist/components/scene-instance.d.ts +2 -1
  102. package/dist/components/scene-instance.d.ts.map +1 -1
  103. package/dist/components/screen-space-reflection.d.ts +14 -0
  104. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  105. package/dist/components/skylight.d.ts +4 -1
  106. package/dist/components/skylight.d.ts.map +1 -1
  107. package/dist/construct-renderer.mjs +14809 -7570
  108. package/dist/construct-renderer.mjs.map +1 -1
  109. package/dist/device/device-scope.d.ts +2 -0
  110. package/dist/device/device-scope.d.ts.map +1 -1
  111. package/dist/device/gpu-residency.d.ts +3 -14
  112. package/dist/device/gpu-residency.d.ts.map +1 -1
  113. package/dist/dynamic-geometry.d.ts.map +1 -1
  114. package/dist/environment/background.d.ts +7 -0
  115. package/dist/environment/background.d.ts.map +1 -0
  116. package/dist/environment/ibl.d.ts +11 -0
  117. package/dist/environment/ibl.d.ts.map +1 -0
  118. package/dist/environment/storage.d.ts +14 -0
  119. package/dist/environment/storage.d.ts.map +1 -0
  120. package/dist/errors/gpu-driven.d.ts +6 -3
  121. package/dist/errors/gpu-driven.d.ts.map +1 -1
  122. package/dist/errors/render.d.ts +41 -4
  123. package/dist/errors/render.d.ts.map +1 -1
  124. package/dist/extract/camera.d.ts.map +1 -1
  125. package/dist/extract/contracts.d.ts +7 -0
  126. package/dist/extract/contracts.d.ts.map +1 -1
  127. package/dist/extract/gpu-driven.d.ts +50 -3
  128. package/dist/extract/gpu-driven.d.ts.map +1 -1
  129. package/dist/features/host.d.ts +23 -1
  130. package/dist/features/host.d.ts.map +1 -1
  131. package/dist/features/noise-texture.d.ts +17 -0
  132. package/dist/features/noise-texture.d.ts.map +1 -0
  133. package/dist/features/plan.d.ts +83 -2
  134. package/dist/features/plan.d.ts.map +1 -1
  135. package/dist/features/prepared-gpu-work.d.ts +37 -4
  136. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  137. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  138. package/dist/features/prepared-graphics.d.ts +5 -0
  139. package/dist/features/prepared-graphics.d.ts.map +1 -1
  140. package/dist/features/render-graph-compute.d.ts +5 -3
  141. package/dist/features/render-graph-compute.d.ts.map +1 -1
  142. package/dist/features/render-graph-contribution.d.ts +11 -3
  143. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  144. package/dist/features/render-graph-raster.d.ts +19 -3
  145. package/dist/features/render-graph-raster.d.ts.map +1 -1
  146. package/dist/features/types.d.ts +11 -0
  147. package/dist/features/types.d.ts.map +1 -1
  148. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  149. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  150. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  151. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  152. package/dist/gpu-driven/material-artifacts.d.ts +24 -0
  153. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
  154. package/dist/gpu-driven/material-bindings.d.ts +7 -0
  155. package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
  156. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  157. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  158. package/dist/gpu-driven/prepared-draw.d.ts +2 -0
  159. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  160. package/dist/gpu-driven/production-raster.d.ts +169 -27
  161. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  162. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  163. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  164. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  165. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  166. package/dist/gpu-resource.d.ts +5 -2
  167. package/dist/gpu-resource.d.ts.map +1 -1
  168. package/dist/gpu-scene-schema.d.ts +2 -8
  169. package/dist/gpu-scene-schema.d.ts.map +1 -1
  170. package/dist/gpu-scene.d.ts +14 -0
  171. package/dist/gpu-scene.d.ts.map +1 -1
  172. package/dist/gpu-texture-usage.d.ts +1 -0
  173. package/dist/gpu-texture-usage.d.ts.map +1 -1
  174. package/dist/hdrp-buffers.d.ts +9 -0
  175. package/dist/hdrp-buffers.d.ts.map +1 -1
  176. package/dist/ibl/IblPipelineCache.d.ts +2 -0
  177. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  178. package/dist/ibl/frame-resources.d.ts +8 -0
  179. package/dist/ibl/frame-resources.d.ts.map +1 -0
  180. package/dist/ibl/skylight-bind-group.d.ts +3 -1
  181. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  182. package/dist/index.d.ts +87 -75
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.mjs +10 -8
  185. package/dist/index.mjs.map +1 -1
  186. package/dist/inspection-types.d.ts +180 -1
  187. package/dist/inspection-types.d.ts.map +1 -1
  188. package/dist/instances-derived-bounds.d.ts +11 -0
  189. package/dist/instances-derived-bounds.d.ts.map +1 -1
  190. package/dist/instances.d.ts +89 -44
  191. package/dist/instances.d.ts.map +1 -1
  192. package/dist/internal.d.ts +3 -0
  193. package/dist/internal.d.ts.map +1 -1
  194. package/dist/internal.mjs +117 -9
  195. package/dist/internal.mjs.map +1 -1
  196. package/dist/lifecycle.d.ts +2 -1
  197. package/dist/lifecycle.d.ts.map +1 -1
  198. package/dist/material-row.d.ts +15 -0
  199. package/dist/material-row.d.ts.map +1 -0
  200. package/dist/materials.d.ts +15 -0
  201. package/dist/materials.d.ts.map +1 -1
  202. package/dist/pbr-pipeline.d.ts +23 -5
  203. package/dist/pbr-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/render-extent.d.ts +51 -0
  205. package/dist/pipeline/render-extent.d.ts.map +1 -0
  206. package/dist/pipeline/standard-build-context.d.ts +7 -0
  207. package/dist/pipeline/standard-build-context.d.ts.map +1 -0
  208. package/dist/pipeline/standard-forward-lane.d.ts +3 -2
  209. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  210. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  211. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  212. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  213. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  214. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  215. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  216. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  217. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  218. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  219. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  220. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  221. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  222. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  223. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  224. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  225. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  226. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  227. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  228. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  229. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  230. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  231. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  232. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  233. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  234. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  235. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  236. package/dist/pipeline/standard-output/types.d.ts +39 -0
  237. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  238. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  239. package/dist/pipeline/standard-post.d.ts +2 -2
  240. package/dist/pipeline/standard-post.d.ts.map +1 -1
  241. package/dist/pipeline/standard-profile.d.ts +2 -1
  242. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  243. package/dist/pipeline-builder.d.ts +5 -2
  244. package/dist/pipeline-builder.d.ts.map +1 -1
  245. package/dist/pipeline-spec-types.d.ts +4 -0
  246. package/dist/pipeline-spec-types.d.ts.map +1 -1
  247. package/dist/pipeline-spec.d.ts +1 -9
  248. package/dist/pipeline-spec.d.ts.map +1 -1
  249. package/dist/plugin.d.ts.map +1 -1
  250. package/dist/points-lines/standard-owner.d.ts +1 -1
  251. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  252. package/dist/post-process-errors.d.ts +9 -2
  253. package/dist/post-process-errors.d.ts.map +1 -1
  254. package/dist/prepare/extended-lighting/resources.d.ts +3 -3
  255. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  256. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  257. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  258. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  259. package/dist/record/frame-lighting.d.ts +3 -3
  260. package/dist/record/frame-lighting.d.ts.map +1 -1
  261. package/dist/record/frame-snapshot.d.ts +109 -13
  262. package/dist/record/frame-snapshot.d.ts.map +1 -1
  263. package/dist/record/frame-targets.d.ts.map +1 -1
  264. package/dist/record/frame.d.ts +41 -5
  265. package/dist/record/frame.d.ts.map +1 -1
  266. package/dist/record/main-pass-geometry.d.ts +13 -9
  267. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  268. package/dist/record/main-pass-material.d.ts +43 -3
  269. package/dist/record/main-pass-material.d.ts.map +1 -1
  270. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  271. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  272. package/dist/record/main-pass.d.ts +14 -2
  273. package/dist/record/main-pass.d.ts.map +1 -1
  274. package/dist/record/mesh-ssbo.d.ts +15 -6
  275. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  276. package/dist/record/prepared-material-bindings.d.ts +19 -0
  277. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  278. package/dist/record/recovery-pipeline.d.ts +1 -0
  279. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  280. package/dist/record/render-context.d.ts +101 -22
  281. package/dist/record/render-context.d.ts.map +1 -1
  282. package/dist/record/shadow-pass.d.ts +62 -7
  283. package/dist/record/shadow-pass.d.ts.map +1 -1
  284. package/dist/record/skybox-post-pass.d.ts +1 -1
  285. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  286. package/dist/record/typed-frame-graph.d.ts +39 -8
  287. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  288. package/dist/record/view-ubo.d.ts +1 -0
  289. package/dist/record/view-ubo.d.ts.map +1 -1
  290. package/dist/recovery/render-system-candidate.d.ts +10 -2
  291. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  292. package/dist/recovery/render-system-roots.d.ts +11 -0
  293. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  294. package/dist/recovery/types.d.ts +76 -0
  295. package/dist/recovery/types.d.ts.map +1 -0
  296. package/dist/reflection/background.d.ts +14 -0
  297. package/dist/reflection/background.d.ts.map +1 -0
  298. package/dist/reflection/filter.d.ts.map +1 -1
  299. package/dist/reflection/projection.d.ts +1 -0
  300. package/dist/reflection/projection.d.ts.map +1 -1
  301. package/dist/reflection/record-owner.d.ts +4 -4
  302. package/dist/reflection/record-owner.d.ts.map +1 -1
  303. package/dist/render-contract.d.ts +211 -53
  304. package/dist/render-contract.d.ts.map +1 -1
  305. package/dist/render-graph-primitives.d.ts +1 -0
  306. package/dist/render-graph-primitives.d.ts.map +1 -1
  307. package/dist/render-pipeline.d.ts +81 -6
  308. package/dist/render-pipeline.d.ts.map +1 -1
  309. package/dist/render-system-extract-tail.d.ts +15 -6
  310. package/dist/render-system-extract-tail.d.ts.map +1 -1
  311. package/dist/render-system-extract.d.ts +128 -41
  312. package/dist/render-system-extract.d.ts.map +1 -1
  313. package/dist/render-system-projections.d.ts +22 -0
  314. package/dist/render-system-projections.d.ts.map +1 -0
  315. package/dist/render-system.d.ts +27 -77
  316. package/dist/render-system.d.ts.map +1 -1
  317. package/dist/scene/render-scene-types.d.ts +14 -7
  318. package/dist/scene/render-scene-types.d.ts.map +1 -1
  319. package/dist/scene/render-scene.d.ts +31 -11
  320. package/dist/scene/render-scene.d.ts.map +1 -1
  321. package/dist/scene/shadow-visibility.d.ts +5 -0
  322. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  323. package/dist/ssao-config.d.ts +8 -6
  324. package/dist/ssao-config.d.ts.map +1 -1
  325. package/dist/ssr/admission.d.ts +70 -1
  326. package/dist/ssr/admission.d.ts.map +1 -1
  327. package/dist/ssr/compose.d.ts +13 -0
  328. package/dist/ssr/compose.d.ts.map +1 -0
  329. package/dist/ssr/errors.d.ts +35 -0
  330. package/dist/ssr/errors.d.ts.map +1 -1
  331. package/dist/ssr/graph.d.ts +60 -0
  332. package/dist/ssr/graph.d.ts.map +1 -0
  333. package/dist/ssr/history.d.ts +97 -0
  334. package/dist/ssr/history.d.ts.map +1 -0
  335. package/dist/ssr/hiz.d.ts +37 -0
  336. package/dist/ssr/hiz.d.ts.map +1 -0
  337. package/dist/ssr/inspection.d.ts +42 -0
  338. package/dist/ssr/inspection.d.ts.map +1 -0
  339. package/dist/ssr/resources.d.ts +58 -0
  340. package/dist/ssr/resources.d.ts.map +1 -0
  341. package/dist/ssr/temporal.d.ts +38 -0
  342. package/dist/ssr/temporal.d.ts.map +1 -0
  343. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  344. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  345. package/dist/systems/skin-palette-types.d.ts +15 -0
  346. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  347. package/dist/systems/transparent-dispatch.d.ts +9 -0
  348. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  349. package/dist/targets/material-source.d.ts +7 -0
  350. package/dist/targets/material-source.d.ts.map +1 -1
  351. package/dist/temporal/frame-coordinator.d.ts +7 -0
  352. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  353. package/dist/temporal/gpu.d.ts +8 -0
  354. package/dist/temporal/gpu.d.ts.map +1 -1
  355. package/dist/temporal/history.d.ts.map +1 -1
  356. package/dist/temporal/index.mjs +6 -6
  357. package/dist/temporal/inspection.d.ts.map +1 -1
  358. package/dist/temporal/standard-scene-data.d.ts +4 -2
  359. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  360. package/dist/temporal/target-coverage-attachment.d.ts +15 -0
  361. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
  362. package/dist/temporal/temporal-view.d.ts +6 -0
  363. package/dist/temporal/temporal-view.d.ts.map +1 -1
  364. package/dist/temporal/view.d.ts +6 -0
  365. package/dist/temporal/view.d.ts.map +1 -1
  366. package/dist/typed-render-graph-primitives.d.ts +41 -1
  367. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  368. package/dist/typed-shadow-passes.d.ts +3 -1
  369. package/dist/typed-shadow-passes.d.ts.map +1 -1
  370. package/dist/volume/component.d.ts +1 -0
  371. package/dist/volume/component.d.ts.map +1 -1
  372. package/dist/volume/temporal.d.ts +6 -0
  373. package/dist/volume/temporal.d.ts.map +1 -1
  374. package/package.json +21 -20
  375. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  376. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  377. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  378. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  379. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  380. package/src/__tests__/capture-scene-projection.unit.test.ts +24 -0
  381. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  382. package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
  383. package/src/__tests__/device-loss-fanout.unit.test.ts +43 -0
  384. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  385. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  386. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  387. package/src/__tests__/dynamic-geometry-batch.unit.test.ts +157 -0
  388. package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
  389. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
  390. package/src/__tests__/factory-contract.integration.test.ts +231 -9
  391. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  392. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  393. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  394. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  395. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  396. package/src/__tests__/frame-observation.contract.test.ts +21 -0
  397. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  398. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  399. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  400. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  401. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +307 -7
  402. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  403. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  404. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +261 -0
  405. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +346 -0
  406. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1422 -0
  407. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  408. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  409. package/src/__tests__/gpu-driven-production.integration.test.ts +1076 -106
  410. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  411. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  412. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  413. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  414. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  415. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  416. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  417. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  418. package/src/__tests__/gpu-driven-view.unit.test.ts +160 -52
  419. package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
  420. package/src/__tests__/gpu-pass-timing.browser.test.ts +20 -2
  421. package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
  422. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  423. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  424. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  425. package/src/__tests__/gpu-scene.unit.test.ts +613 -33
  426. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  427. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  428. package/src/__tests__/instances-store.unit.test.ts +242 -39
  429. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  430. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  431. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  432. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  433. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  434. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  435. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  436. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  437. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  438. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  439. package/src/__tests__/materials-standard-contract.unit.test.ts +57 -3
  440. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  441. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
  442. package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -0
  443. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  444. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  445. package/src/__tests__/physical-clearcoat.integration.test.ts +42 -3
  446. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  447. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  448. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -5
  449. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  450. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  451. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +251 -9
  452. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  453. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  454. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  455. package/src/__tests__/public-surface.test-d.ts +3 -0
  456. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  457. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +171 -0
  458. package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
  459. package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
  460. package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
  461. package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
  462. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -14
  463. package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
  464. package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
  465. package/src/__tests__/render-error-detail-ssot.test-d.ts +27 -1
  466. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  467. package/src/__tests__/render-extent.unit.test.ts +63 -0
  468. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  469. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  470. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  471. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  472. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  473. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  474. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  475. package/src/__tests__/render-scene-projection.unit.test.ts +915 -23
  476. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  477. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  478. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  479. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  480. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +233 -9
  481. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  482. package/src/__tests__/shader-manifest-fixture.ts +45 -0
  483. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  484. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  485. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  486. package/src/__tests__/skinned-shadow-caster.test.ts +125 -14
  487. package/src/__tests__/specular-environment-scale.dawn.test.ts +158 -0
  488. package/src/__tests__/ssao-config.unit.test.ts +7 -0
  489. package/src/__tests__/ssao-surface.dawn.test.ts +252 -0
  490. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  491. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  492. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  493. package/src/__tests__/ssr-cube-silhouette.dawn.test.ts +270 -0
  494. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  495. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +99 -0
  496. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +116 -0
  497. package/src/__tests__/ssr-gpu-dispatch.ts +951 -0
  498. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  499. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  500. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  501. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  502. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  503. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  504. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  505. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  506. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  507. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  508. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  509. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  510. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  511. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  512. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  513. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  514. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  515. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  516. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  517. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  518. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  519. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  520. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +84 -12
  521. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  522. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  523. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  524. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  525. package/src/__tests__/standard-output.browser.test.ts +15 -0
  526. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  527. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +275 -0
  528. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  529. package/src/__tests__/standard-profile-oracle.unit.test.ts +49 -0
  530. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  531. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  532. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  533. package/src/__tests__/taa-coverage-edge.dawn.test.ts +199 -0
  534. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  535. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +782 -0
  536. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  537. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  538. package/src/__tests__/taa-stability-feedback.ts +342 -0
  539. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  540. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  541. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  542. package/src/__tests__/temporal-view.unit.test.ts +17 -0
  543. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  544. package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
  545. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  546. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  547. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  548. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  549. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  550. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  551. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
  552. package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
  553. package/src/assembly/atmosphere-shader-prewarm.ts +39 -0
  554. package/src/assembly/device-feature-admission.ts +9 -4
  555. package/src/assembly/dynamic-geometry-host.ts +284 -163
  556. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  557. package/src/assembly/factory.ts +4 -0
  558. package/src/assembly/gpu-driven-owner.ts +29 -0
  559. package/src/assembly/host-contract.ts +19 -0
  560. package/src/assembly/material/assembly.ts +383 -1
  561. package/src/assembly/material/pipeline-helpers.ts +100 -0
  562. package/src/assembly/material-shader-policy.ts +110 -46
  563. package/src/assembly/recovery/device-loss-fanout.ts +5 -0
  564. package/src/assembly/recovery/failure-location.ts +62 -0
  565. package/src/assembly/recovery/recovery-attempt.ts +2 -29
  566. package/src/assembly/recovery/renderer-recover.ts +16 -17
  567. package/src/assembly/renderer-facade.ts +34 -1
  568. package/src/assembly/renderer-feature-inspection.ts +13 -0
  569. package/src/assembly/renderer-frame-transaction.ts +63 -0
  570. package/src/assembly/renderer-helpers.ts +26 -0
  571. package/src/assembly/renderer-inspection.ts +6 -0
  572. package/src/assembly/shader-prewarm-policy.ts +46 -1
  573. package/src/assembly/skin-palette-owner.ts +21 -0
  574. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  575. package/src/assembly/webgpu-device-loss.ts +75 -0
  576. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  577. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  578. package/src/assembly/webgpu-ready.ts +161 -131
  579. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  580. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  581. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  582. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  583. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  584. package/src/assembly/webgpu-renderer.ts +744 -730
  585. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  586. package/src/capture/scene-projection.ts +37 -0
  587. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  588. package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
  589. package/src/components/__tests__/light-radius.integration.test.ts +59 -0
  590. package/src/components/camera.ts +287 -7
  591. package/src/components/directional-light.ts +3 -3
  592. package/src/components/dynamic-resolution.ts +67 -0
  593. package/src/components/index.ts +2 -0
  594. package/src/components/instances.ts +45 -18
  595. package/src/components/light-helpers.ts +6 -1
  596. package/src/components/reflection-probe.ts +1 -0
  597. package/src/components/scene-instance.ts +2 -1
  598. package/src/components/screen-space-reflection.ts +21 -0
  599. package/src/components/skylight.ts +4 -1
  600. package/src/components/sprite-animation.ts +2 -2
  601. package/src/components/sprite-instances.ts +1 -1
  602. package/src/device/device-scope.ts +13 -7
  603. package/src/device/gpu-residency.ts +45 -42
  604. package/src/dynamic-geometry.ts +13 -8
  605. package/src/environment/background.ts +281 -0
  606. package/src/environment/ibl.ts +211 -0
  607. package/src/environment/storage.ts +63 -0
  608. package/src/errors/gpu-driven.ts +49 -8
  609. package/src/errors/render.ts +91 -3
  610. package/src/extract/camera.ts +37 -1
  611. package/src/extract/contracts.ts +10 -0
  612. package/src/extract/gpu-driven.ts +240 -10
  613. package/src/features/host.ts +237 -19
  614. package/src/features/noise-texture.ts +91 -0
  615. package/src/features/plan.ts +553 -24
  616. package/src/features/prepared-gpu-work.ts +631 -49
  617. package/src/features/prepared-graphics-store.ts +31 -0
  618. package/src/features/prepared-graphics.ts +5 -0
  619. package/src/features/render-graph-compute.ts +41 -8
  620. package/src/features/render-graph-contribution.ts +141 -3
  621. package/src/features/render-graph-raster.ts +143 -30
  622. package/src/features/types.ts +11 -0
  623. package/src/fullscreen-post-process-pass.ts +3 -0
  624. package/src/gpu-driven/batch-topology.ts +452 -108
  625. package/src/gpu-driven/material-artifacts.ts +179 -0
  626. package/src/gpu-driven/material-bindings.ts +41 -0
  627. package/src/gpu-driven/pbr-program.ts +31 -0
  628. package/src/gpu-driven/prepared-draw.ts +42 -6
  629. package/src/gpu-driven/production-raster.ts +2806 -716
  630. package/src/gpu-driven/shadow-views.ts +539 -0
  631. package/src/gpu-driven/view-gpu.ts +188 -41
  632. package/src/gpu-resource.ts +21 -2
  633. package/src/gpu-scene-schema.ts +61 -11
  634. package/src/gpu-scene.ts +197 -99
  635. package/src/gpu-texture-usage.ts +1 -0
  636. package/src/hdrp-buffers.ts +141 -36
  637. package/src/ibl/IblPipelineCache.ts +5 -0
  638. package/src/ibl/frame-resources.ts +38 -0
  639. package/src/ibl/skylight-bind-group.ts +32 -21
  640. package/src/index.ts +194 -75
  641. package/src/inspection-types.ts +207 -1
  642. package/src/instances-derived-bounds.ts +258 -34
  643. package/src/instances.ts +459 -150
  644. package/src/internal.ts +22 -0
  645. package/src/lifecycle.ts +2 -0
  646. package/src/material-row.ts +194 -0
  647. package/src/materials.ts +44 -8
  648. package/src/pbr-pipeline.ts +172 -19
  649. package/src/pipeline/render-extent.ts +111 -0
  650. package/src/pipeline/standard-build-context.ts +7 -0
  651. package/src/pipeline/standard-forward-lane.ts +74 -29
  652. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  653. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  654. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  655. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  656. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  657. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  658. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  659. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  660. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  661. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  662. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  663. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  664. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  665. package/src/pipeline/standard-output/color-transform.ts +124 -0
  666. package/src/pipeline/standard-output/graph.ts +139 -0
  667. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  668. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  669. package/src/pipeline/standard-output/lut-state.ts +176 -0
  670. package/src/pipeline/standard-output/resources.ts +121 -0
  671. package/src/pipeline/standard-output/types.ts +58 -0
  672. package/src/pipeline/standard-pipeline.ts +232 -70
  673. package/src/pipeline/standard-post.ts +190 -27
  674. package/src/pipeline/standard-profile.ts +2 -1
  675. package/src/pipeline-builder.ts +28 -9
  676. package/src/pipeline-spec-types.ts +4 -0
  677. package/src/pipeline-spec.ts +37 -29
  678. package/src/plugin.ts +4 -0
  679. package/src/points-lines/standard-owner.ts +6 -14
  680. package/src/post-process-errors.ts +26 -18
  681. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
  682. package/src/prepare/extended-lighting/resources.ts +3 -3
  683. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  684. package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
  685. package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
  686. package/src/record/__tests__/material-slot-plan.unit.test.ts +57 -0
  687. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  688. package/src/record/__tests__/recovery-pipeline.unit.test.ts +20 -1
  689. package/src/record/__tests__/sprite-material-abi.unit.test.ts +41 -6
  690. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
  691. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  692. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  693. package/src/record/dynamic-geometry-consumption.ts +59 -0
  694. package/src/record/frame-lighting.ts +15 -12
  695. package/src/record/frame-snapshot.ts +146 -34
  696. package/src/record/frame-targets.ts +9 -0
  697. package/src/record/frame.ts +838 -170
  698. package/src/record/main-pass-geometry.ts +209 -103
  699. package/src/record/main-pass-material.ts +157 -40
  700. package/src/record/main-pass-sprite-draws.ts +16 -107
  701. package/src/record/main-pass.ts +141 -12
  702. package/src/record/material-uniforms.ts +1 -1
  703. package/src/record/mesh-ssbo.ts +59 -15
  704. package/src/record/prepared-material-bindings.ts +238 -0
  705. package/src/record/recovery-pipeline.ts +69 -90
  706. package/src/record/render-context.ts +123 -24
  707. package/src/record/shadow-pass.ts +1389 -230
  708. package/src/record/skybox-post-pass.ts +14 -3
  709. package/src/record/typed-frame-graph.ts +1064 -47
  710. package/src/record/view-ubo.ts +12 -1
  711. package/src/recovery/render-system-candidate.ts +135 -68
  712. package/src/recovery/render-system-roots.ts +113 -0
  713. package/src/recovery/types.ts +77 -0
  714. package/src/reflection/background.ts +151 -0
  715. package/src/reflection/filter.ts +3 -0
  716. package/src/reflection/projection.ts +16 -6
  717. package/src/reflection/record-owner.ts +308 -140
  718. package/src/render-contract.ts +237 -49
  719. package/src/render-graph-primitives.ts +34 -5
  720. package/src/render-pipeline.ts +90 -2
  721. package/src/render-system-extract-tail.ts +431 -162
  722. package/src/render-system-extract.ts +478 -119
  723. package/src/render-system-projections.ts +241 -0
  724. package/src/render-system.ts +715 -828
  725. package/src/scene/render-scene-types.ts +13 -4
  726. package/src/scene/render-scene.ts +577 -355
  727. package/src/scene/shadow-visibility.ts +21 -0
  728. package/src/ssao-config.ts +25 -8
  729. package/src/ssr/admission.ts +380 -14
  730. package/src/ssr/compose.ts +144 -0
  731. package/src/ssr/errors.ts +48 -0
  732. package/src/ssr/graph.ts +797 -0
  733. package/src/ssr/history.ts +436 -0
  734. package/src/ssr/hiz.ts +124 -0
  735. package/src/ssr/inspection.ts +124 -0
  736. package/src/ssr/resources.ts +202 -0
  737. package/src/ssr/temporal.ts +164 -0
  738. package/src/systems/skin-palette-allocator.ts +495 -148
  739. package/src/systems/skin-palette-types.ts +17 -0
  740. package/src/systems/transparent-dispatch.ts +90 -0
  741. package/src/targets/material-source.ts +34 -0
  742. package/src/temporal/coverage.ts +1 -1
  743. package/src/temporal/frame-coordinator.ts +23 -2
  744. package/src/temporal/gpu.ts +79 -12
  745. package/src/temporal/history.ts +3 -1
  746. package/src/temporal/inspection.ts +2 -1
  747. package/src/temporal/standard-scene-data.ts +10 -2
  748. package/src/temporal/target-coverage-attachment.ts +72 -0
  749. package/src/temporal/temporal-view.ts +11 -2
  750. package/src/temporal/view.ts +12 -2
  751. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +219 -139
  752. package/src/typed-render-graph-primitives.ts +304 -74
  753. package/src/typed-shadow-passes.ts +122 -12
  754. package/src/volume/component.ts +1 -0
  755. package/src/volume/passes.ts +3 -3
  756. package/src/volume/temporal.ts +10 -0
  757. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  758. package/dist/chunk-GF523LHF.mjs.map +0 -1
  759. package/dist/chunk-IQMKJLNU.mjs.map +0 -1
  760. package/dist/chunk-J52NMQKR.mjs.map +0 -1
  761. package/dist/chunk-J6KACNOH.mjs.map +0 -1
  762. package/dist/chunk-JAASCMXA.mjs.map +0 -1
  763. package/dist/chunk-MBU4ZVE7.mjs.map +0 -1
  764. package/dist/chunk-MYJ5RPJO.mjs.map +0 -1
  765. package/dist/chunk-RBDBZ5R7.mjs.map +0 -1
  766. package/dist/chunk-VSL23LZE.mjs.map +0 -1
  767. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  768. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
@@ -26,6 +26,7 @@ import {
26
26
  } from '../gpu-usage';
27
27
  import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
28
28
  import type { GpuDrivenCandidate, SubmissionPlan } from './batch-topology';
29
+ import { GPU_DRIVEN_SKIN_FLAG } from './batch-topology';
29
30
 
30
31
  const COMPUTE_STAGE = 0x4;
31
32
  const WORKGROUP_SIZE = 64;
@@ -94,9 +95,10 @@ struct CandidateRecord {
94
95
  batchIndex: u32,
95
96
  visibleBase: u32,
96
97
  visibleCapacity: u32,
97
- // Admission is separate from selector membership: suppressed candidates
98
- // still contribute to the all-candidate LOD histogram, but never enter the
99
- // compacted visible stream.
98
+ // Low bit is admission; upper bits carry the batch-local projected Mesh row.
99
+ // Suppressed candidates still contribute to the all-candidate LOD histogram,
100
+ // but never enter the compacted visible stream. Packing both facts here
101
+ // keeps the candidate ABI single-source when visibility compacts rows.
100
102
  submitAdmission: u32,
101
103
  projectedHeight: f32,
102
104
  previousLevel: u32,
@@ -232,7 +234,7 @@ fn cullView(@builtin(global_invocation_id) id: vec3<u32>) {
232
234
  // candidates outside the frustum and candidates suppressed by the CPU
233
235
  // visibility facet. Submission counters below remain compacted draw facts.
234
236
  atomicAdd(&counters[lodCounterIndex(candidate.batchIndex, selectedLod)], 1u);
235
- if (candidate.submitAdmission == 0u) { return; }
237
+ if ((candidate.submitAdmission & 1u) == 0u) { return; }
236
238
  if (!isVisible(primitive, world)) { return; }
237
239
  atomicAdd(
238
240
  &counters[counterIndex(candidate.batchIndex) + ${GEOMETRY_WORK_COUNTER_OFFSET}u],
@@ -247,9 +249,13 @@ fn cullView(@builtin(global_invocation_id) id: vec3<u32>) {
247
249
  atomicStore(&counters[overflowIndex(candidate.batchIndex)], 1u);
248
250
  return;
249
251
  }
252
+ var materialOrPalette = primitive.materialIndex + (candidate.materialSlot & 0x7fffffffu);
253
+ if ((candidate.materialSlot & 0x80000000u) != 0u) {
254
+ materialOrPalette = instance.customDataStart;
255
+ }
250
256
  visibleIndices[candidate.visibleBase + localVisible] = vec2<u32>(
251
- instanceIndex,
252
- primitive.materialIndex + candidate.materialSlot,
257
+ candidate.submitAdmission >> 1u,
258
+ materialOrPalette,
253
259
  );
254
260
  }
255
261
 
@@ -258,10 +264,16 @@ fn finalizeView(@builtin(global_invocation_id) id: vec3<u32>) {
258
264
  let batchIndex = id.x;
259
265
  if (batchIndex >= view.batchCount) { return; }
260
266
  let batch = batches[batchIndex];
261
- let visibleCount = min(
267
+ var visibleCount = min(
262
268
  atomicLoad(&counters[counterIndex(batchIndex)]),
263
269
  batch.visibleCapacity,
264
270
  );
271
+ // Overflow is a failed generation, never a partially valid draw. Keep the
272
+ // telemetry flag for the producer retry path but emit zero instances so no
273
+ // subset of a visible batch reaches the rasterizer.
274
+ if (atomicLoad(&counters[overflowIndex(batchIndex)]) != 0u) {
275
+ visibleCount = 0u;
276
+ }
265
277
  let args = batch.indirectIndex * 5u;
266
278
  let candidate = candidates[batch.candidateBase];
267
279
  let selectedLod = selectLodLevel(candidate.projectedHeight, candidate.previousLevel, candidate.historyValid != 0u, candidate.lodRows, candidate.lodCount);
@@ -286,6 +298,12 @@ interface ViewBuffers {
286
298
 
287
299
  type MutableViewBuffers = { -readonly [Name in keyof ViewBuffers]: ViewBuffers[Name] };
288
300
 
301
+ type LodTelemetryCopy = {
302
+ readonly buffers: ViewBuffers;
303
+ readonly plan: SubmissionPlan;
304
+ readonly resourceGeneration: number;
305
+ };
306
+
289
307
  export interface GpuDrivenViewGraphResources {
290
308
  readonly primitive: GraphBuffer;
291
309
  readonly instance: GraphBuffer;
@@ -329,12 +347,15 @@ export interface GpuDrivenLodSelectionInspection {
329
347
  readonly indirectDrawCount: number;
330
348
  readonly visible: number;
331
349
  readonly occluded: number;
350
+ /** True when the selector had to reject or clamp a visible candidate. */
351
+ readonly overflow: boolean;
332
352
  readonly lodHistogram: readonly { readonly level: number; readonly count: number }[];
333
353
  readonly batches: readonly {
334
354
  readonly batchId: number;
335
355
  readonly candidateCount: number;
336
356
  readonly visible: number;
337
357
  readonly occluded: number;
358
+ readonly overflow: boolean;
338
359
  readonly lodHistogram: readonly { readonly level: number; readonly count: number }[];
339
360
  }[];
340
361
  readonly worldSelections?: readonly {
@@ -408,7 +429,14 @@ export class GpuDrivenView {
408
429
  private bindGroupCreates = 0;
409
430
  private bufferRebuilds = 0;
410
431
  private resourceGeneration = 0;
411
- private telemetryPending = false;
432
+ /** The last readback copy that was actually encoded and is not consumed. */
433
+ private telemetryPending: LodTelemetryCopy | undefined;
434
+ /** Coalesce observers while the readback buffer is map-pending. */
435
+ private lodSelectionReadback:
436
+ | {
437
+ readonly promise: Promise<GpuDrivenLodSelectionInspection | undefined>;
438
+ }
439
+ | undefined;
412
440
  private lodSelection: GpuDrivenLodSelectionInspection | undefined;
413
441
 
414
442
  private constructor(
@@ -418,13 +446,16 @@ export class GpuDrivenView {
418
446
  private readonly resetPipeline: ComputePipeline,
419
447
  private readonly cullPipeline: ComputePipeline,
420
448
  private readonly finalizePipeline: ComputePipeline,
449
+ private readonly labelPrefix: string,
421
450
  ) {}
422
451
 
423
452
  static create(input: {
424
453
  readonly device: RhiDevice;
425
454
  readonly shaderModuleFactory: PipelineBuilderShaderModuleFactory;
455
+ readonly labelPrefix?: string;
426
456
  }): Result<GpuDrivenView, RhiError> {
427
457
  const { device, shaderModuleFactory } = input;
458
+ const labelPrefix = input.labelPrefix ?? 'gpu-driven-view';
428
459
  if (!device.caps.compute || !device.caps.storageBuffer || !device.caps.indirectDrawing) {
429
460
  return err(
430
461
  new RhiError({
@@ -435,7 +466,7 @@ export class GpuDrivenView {
435
466
  );
436
467
  }
437
468
  const layout = device.createBindGroupLayout({
438
- label: 'gpu-driven-view-bgl',
469
+ label: `${labelPrefix}-bgl`,
439
470
  entries: [
440
471
  { binding: 0, visibility: COMPUTE_STAGE, buffer: { type: 'read-only-storage' } },
441
472
  { binding: 1, visibility: COMPUTE_STAGE, buffer: { type: 'read-only-storage' } },
@@ -450,7 +481,7 @@ export class GpuDrivenView {
450
481
  });
451
482
  if (!layout.ok) return layout;
452
483
  const pipelineLayout = device.createPipelineLayout({
453
- label: 'gpu-driven-view-pl',
484
+ label: `${labelPrefix}-pl`,
454
485
  bindGroupLayouts: [layout.value],
455
486
  });
456
487
  if (!pipelineLayout.ok) return pipelineLayout;
@@ -461,7 +492,7 @@ export class GpuDrivenView {
461
492
  if (!module.ok) return module;
462
493
  const createPipeline = (entryPoint: string): Result<ComputePipeline, RhiError> =>
463
494
  device.createComputePipeline({
464
- label: `gpu-driven-view.${entryPoint}`,
495
+ label: `${labelPrefix}.${entryPoint}`,
465
496
  layout: pipelineLayout.value,
466
497
  compute: { module: module.value, entryPoint },
467
498
  });
@@ -479,6 +510,7 @@ export class GpuDrivenView {
479
510
  reset.value,
480
511
  cull.value,
481
512
  finalize.value,
513
+ labelPrefix,
482
514
  ),
483
515
  );
484
516
  }
@@ -488,11 +520,10 @@ export class GpuDrivenView {
488
520
  this.batchUploadBytes = 0;
489
521
  this.viewConstantsUploadBytes = 0;
490
522
  this.bindGroupCreates = 0;
491
- // The readback copy is part of the accepted graph and therefore executes
492
- // every submitted frame, not only when that graph is (re)compiled. Keep
493
- // the observation latch armed across per-frame view updates; clearing it
494
- // here would make a cached graph silently discard all later LOD samples.
495
- this.telemetryPending = true;
523
+ // The cached graph owns the readback copy. Do not arm an observation latch
524
+ // here: a graph can be compiled but not submitted, and its copy can be
525
+ // skipped while the previous mapAsync is pending. The encode callback
526
+ // records only a copy that really reached the command encoder.
496
527
  this.lodSelection = undefined;
497
528
  const topologyChanged = this.plan !== plan;
498
529
  let buffersRebuilt = false;
@@ -540,13 +571,19 @@ export class GpuDrivenView {
540
571
  batches.setUint32(batchOffset + 20, batch.batchId, true);
541
572
  batches.setUint32(batchOffset + 24, batch.key.drawKind === 'indexed' ? 1 : 0, true);
542
573
  batches.setUint32(batchOffset + 28, candidateIndex, true);
574
+ let visibleProjectionIndex = 0;
543
575
  for (const candidate of batch.candidates) {
544
576
  const admissionCandidate = candidate as GpuDrivenAdmissionCandidate;
545
577
  const candidateOffset = candidateIndex * CANDIDATE_STRIDE;
546
578
  candidates.setUint32(candidateOffset, candidate.primitiveIndex, true);
547
579
  candidates.setUint32(candidateOffset + 4, candidate.generation, true);
548
580
  candidates.setUint32(candidateOffset + 8, candidate.instanceOrdinal, true);
549
- candidates.setUint32(candidateOffset + 12, batch.key.materialSlot, true);
581
+ const isSkin = candidate.prepared?.identity.deformation === 'skin';
582
+ candidates.setUint32(
583
+ candidateOffset + 12,
584
+ batch.key.materialSlot | (isSkin ? GPU_DRIVEN_SKIN_FLAG : 0),
585
+ true,
586
+ );
550
587
  candidates.setUint32(candidateOffset + 16, batchIndex, true);
551
588
  candidates.setUint32(candidateOffset + 20, batch.visibleBase, true);
552
589
  candidates.setUint32(candidateOffset + 24, batch.visibleCapacity, true);
@@ -556,9 +593,10 @@ export class GpuDrivenView {
556
593
  ...(candidate.lodRanges ?? []),
557
594
  ];
558
595
  const lodCount = Math.min(LOD_ROW_CAPACITY, Math.max(1, coverages.length, ranges.length));
596
+ const admitted = admissionCandidate.submitAdmission !== false;
559
597
  candidates.setUint32(
560
598
  candidateOffset + 28,
561
- admissionCandidate.submitAdmission === false ? 0 : 1,
599
+ (visibleProjectionIndex << 1) | (admitted ? 1 : 0),
562
600
  true,
563
601
  );
564
602
  candidates.setFloat32(
@@ -584,6 +622,7 @@ export class GpuDrivenView {
584
622
  candidates.setFloat32(rowOffset + 24, candidate.lodHysteresis ?? 0.08, true);
585
623
  candidates.setUint32(rowOffset + 28, 1, true);
586
624
  }
625
+ if (admitted) visibleProjectionIndex += 1;
587
626
  candidateIndex += 1;
588
627
  }
589
628
  }
@@ -620,7 +659,7 @@ export class GpuDrivenView {
620
659
  this.sceneMaterial !== scene.materialBuffer;
621
660
  if (this.bindGroup === undefined || sceneChanged || buffersRebuilt) {
622
661
  const binding = this.device.createBindGroup({
623
- label: 'gpu-driven-view-bg',
662
+ label: `${this.labelPrefix}-bg`,
624
663
  layout: this.bindGroupLayout,
625
664
  entries: [
626
665
  { binding: 0, resource: bufferBinding(scene.primitiveBuffer) },
@@ -687,13 +726,37 @@ export class GpuDrivenView {
687
726
  }
688
727
 
689
728
  /** Read selected levels written by the GPU cull pass for the last submit. */
690
- async readLodSelection(): Promise<GpuDrivenLodSelectionInspection | undefined> {
729
+ readLodSelection(): Promise<GpuDrivenLodSelectionInspection | undefined> {
730
+ const inFlight = this.lodSelectionReadback;
731
+ if (inFlight !== undefined) return inFlight.promise;
732
+
691
733
  const buffers = this.buffers;
692
734
  const plan = this.plan;
693
- if (buffers === undefined || plan === undefined || !this.telemetryPending) {
694
- return this.lodSelection;
735
+ const copy = this.telemetryPending;
736
+ if (
737
+ buffers === undefined ||
738
+ plan === undefined ||
739
+ copy === undefined ||
740
+ copy.buffers !== buffers ||
741
+ copy.plan !== plan ||
742
+ copy.resourceGeneration !== this.resourceGeneration ||
743
+ typeof buffers.lodReadback.mapAsync !== 'function' ||
744
+ buffers.lodReadback.mapState !== 'unmapped'
745
+ ) {
746
+ return Promise.resolve(this.lodSelection);
695
747
  }
696
- this.telemetryPending = false;
748
+ const promise = this.readLodSelectionCopy(buffers, plan, copy).finally(() => {
749
+ if (this.lodSelectionReadback?.promise === promise) this.lodSelectionReadback = undefined;
750
+ });
751
+ this.lodSelectionReadback = { promise };
752
+ return promise;
753
+ }
754
+
755
+ private async readLodSelectionCopy(
756
+ buffers: ViewBuffers,
757
+ plan: SubmissionPlan,
758
+ copy: LodTelemetryCopy,
759
+ ): Promise<GpuDrivenLodSelectionInspection | undefined> {
697
760
  const mapped = await buffers.lodReadback.mapAsync(GPU_BUFFER_USAGE_MAP_READ);
698
761
  if (!mapped.ok) return undefined;
699
762
  const range = mapped.value.getMappedRange();
@@ -704,12 +767,21 @@ export class GpuDrivenView {
704
767
  try {
705
768
  const values = new DataView(range.value);
706
769
  let visible = 0;
770
+ let overflow = false;
707
771
  let geometryWork = 0;
708
772
  let rootGeometryWork = 0;
709
773
  const histogram = new Map<number, number>();
710
774
  for (let batchIndex = 0; batchIndex < plan.batches.length; batchIndex += 1) {
711
775
  const offset = batchIndex * COUNTER_STRIDE;
712
- visible += values.getUint32(offset, true);
776
+ const batchOverflow = values.getUint32(offset + 4, true) !== 0;
777
+ const batchVisible = batchOverflow
778
+ ? 0
779
+ : Math.min(
780
+ values.getUint32(offset, true),
781
+ plan.batches[batchIndex]?.visibleCapacity ?? 0,
782
+ );
783
+ visible += batchVisible;
784
+ overflow ||= batchOverflow;
713
785
  geometryWork += values.getUint32(offset + GEOMETRY_WORK_COUNTER_OFFSET * 4, true);
714
786
  rootGeometryWork += values.getUint32(offset + ROOT_GEOMETRY_WORK_COUNTER_OFFSET * 4, true);
715
787
  for (let level = 0; level < LOD_ROW_CAPACITY; level += 1) {
@@ -717,6 +789,16 @@ export class GpuDrivenView {
717
789
  if (count > 0) histogram.set(level, (histogram.get(level) ?? 0) + count);
718
790
  }
719
791
  }
792
+ // A topology/resource replacement may have happened while mapAsync was
793
+ // pending. Never publish those counters into the new plan/cache.
794
+ if (
795
+ this.buffers !== buffers ||
796
+ this.plan !== plan ||
797
+ this.resourceGeneration !== copy.resourceGeneration ||
798
+ this.telemetryPending !== copy
799
+ ) {
800
+ return undefined;
801
+ }
720
802
  const candidateCount = plan.candidateCount;
721
803
  this.lodSelection = Object.freeze({
722
804
  candidateCount,
@@ -732,6 +814,7 @@ export class GpuDrivenView {
732
814
  // histogram here would mislabel a visible candidate dropped only by an
733
815
  // indirect-capacity overflow as occluded.
734
816
  occluded: Math.max(0, candidateCount - visible),
817
+ overflow,
735
818
  lodHistogram: Object.freeze(
736
819
  [...histogram.entries()]
737
820
  .sort(([left], [right]) => left - right)
@@ -745,12 +828,16 @@ export class GpuDrivenView {
745
828
  const count = values.getUint32(offset + (2 + level) * 4, true);
746
829
  if (count > 0) batchHistogram.set(level, count);
747
830
  }
748
- const batchVisible = values.getUint32(offset, true);
831
+ const batchOverflow = values.getUint32(offset + 4, true) !== 0;
832
+ const batchVisible = batchOverflow
833
+ ? 0
834
+ : Math.min(values.getUint32(offset, true), batch.visibleCapacity);
749
835
  return Object.freeze({
750
836
  batchId: batch.batchId,
751
837
  candidateCount: batch.candidates.length,
752
838
  visible: batchVisible,
753
839
  occluded: Math.max(0, batch.candidates.length - batchVisible),
840
+ overflow: batchOverflow,
754
841
  lodHistogram: Object.freeze(
755
842
  [...batchHistogram.entries()]
756
843
  .sort(([left], [right]) => left - right)
@@ -762,6 +849,7 @@ export class GpuDrivenView {
762
849
  geometryWork,
763
850
  rootGeometryWork,
764
851
  });
852
+ this.telemetryPending = undefined;
765
853
  return this.lodSelection;
766
854
  } finally {
767
855
  mapped.value.unmap();
@@ -770,6 +858,8 @@ export class GpuDrivenView {
770
858
 
771
859
  addPasses<FrameCtx extends RenderGraphFrame>(
772
860
  builder: RenderGraphBuilder<FrameCtx>,
861
+ labelPrefix = 'gpu-driven',
862
+ includeCompute = true,
773
863
  ): Result<GpuDrivenViewGraphResources, RenderGraphError> {
774
864
  const buffers = this.buffers;
775
865
  const bindGroup = this.bindGroup;
@@ -791,84 +881,96 @@ export class GpuDrivenView {
791
881
  }
792
882
  const importBuffer = (name: string, buffer: Buffer, size: number, usage: number) =>
793
883
  builder.importBuffer(name, { size, usage }, () => buffer);
884
+ const scenePrefix = labelPrefix === 'gpu-driven' ? 'gpu-scene' : `${labelPrefix}.scene`;
794
885
  const primitive = importBuffer(
795
- 'gpu-scene.primitive',
886
+ `${scenePrefix}.primitive`,
796
887
  this.scenePrimitive as Buffer,
797
888
  this.sceneCapacity * GPU_SCENE_LAYOUTS.primitive.stride,
798
889
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST | GPU_BUFFER_USAGE_COPY_SRC,
799
890
  );
800
891
  if (!primitive.ok) return primitive;
801
892
  const transform = importBuffer(
802
- 'gpu-scene.transform',
893
+ `${scenePrefix}.transform`,
803
894
  this.sceneTransform as Buffer,
804
895
  this.sceneCapacity * GPU_SCENE_LAYOUTS.transform.stride,
805
896
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST | GPU_BUFFER_USAGE_COPY_SRC,
806
897
  );
807
898
  if (!transform.ok) return transform;
808
899
  const instance = importBuffer(
809
- 'gpu-scene.instance',
900
+ `${scenePrefix}.instance`,
810
901
  this.sceneInstance as Buffer,
811
902
  this.sceneCapacity * GPU_SCENE_LAYOUTS.instance.stride,
812
903
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST | GPU_BUFFER_USAGE_COPY_SRC,
813
904
  );
814
905
  if (!instance.ok) return instance;
815
906
  const material = importBuffer(
816
- 'gpu-scene.material',
907
+ `${scenePrefix}.material`,
817
908
  this.sceneMaterial as Buffer,
818
909
  this.sceneCapacity * GPU_SCENE_LAYOUTS.material.stride,
819
910
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST | GPU_BUFFER_USAGE_COPY_SRC,
820
911
  );
821
912
  if (!material.ok) return material;
822
913
  const candidates = importBuffer(
823
- 'gpu-driven.candidates',
914
+ `${labelPrefix}.candidates`,
824
915
  buffers.candidates,
825
916
  this.candidateCapacity * CANDIDATE_STRIDE,
826
917
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST,
827
918
  );
828
919
  if (!candidates.ok) return candidates;
829
920
  const batches = importBuffer(
830
- 'gpu-driven.batches',
921
+ `${labelPrefix}.batches`,
831
922
  buffers.batches,
832
923
  this.batchCapacity * BATCH_STRIDE,
833
924
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST,
834
925
  );
835
926
  if (!batches.ok) return batches;
836
927
  const view = importBuffer(
837
- 'gpu-driven.view',
928
+ `${labelPrefix}.view`,
838
929
  buffers.view,
839
930
  VIEW_BYTES,
840
931
  GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
841
932
  );
842
933
  if (!view.ok) return view;
843
934
  const counters = importBuffer(
844
- 'gpu-driven.counters',
935
+ `${labelPrefix}.counters`,
845
936
  buffers.counters,
846
937
  this.batchCapacity * COUNTER_STRIDE,
847
938
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_SRC,
848
939
  );
849
940
  if (!counters.ok) return counters;
850
941
  const lodReadback = importBuffer(
851
- 'gpu-driven.lod-selection-readback',
942
+ `${labelPrefix}.lod-selection-readback`,
852
943
  buffers.lodReadback,
853
944
  this.batchCapacity * COUNTER_STRIDE,
854
945
  GPU_BUFFER_USAGE_MAP_READ | GPU_BUFFER_USAGE_COPY_DST,
855
946
  );
856
947
  if (!lodReadback.ok) return lodReadback;
857
948
  const visible = importBuffer(
858
- 'gpu-driven.visible',
949
+ `${labelPrefix}.visible`,
859
950
  buffers.visible,
860
951
  this.visibleBufferCapacity * 8,
861
952
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_SRC,
862
953
  );
863
954
  if (!visible.ok) return visible;
864
955
  const indirect = importBuffer(
865
- 'gpu-driven.indirect',
956
+ `${labelPrefix}.indirect`,
866
957
  buffers.indirect,
867
958
  this.indirectCapacity * 20,
868
959
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_INDIRECT | GPU_BUFFER_USAGE_COPY_SRC,
869
960
  );
870
961
  if (!indirect.ok) return indirect;
871
- const reset = builder.addComputePass('gpu-driven.view-reset', {
962
+ if (!includeCompute) {
963
+ return ok({
964
+ visible: visible.value,
965
+ primitive: primitive.value,
966
+ instance: instance.value,
967
+ transform: transform.value,
968
+ material: material.value,
969
+ indirect: indirect.value,
970
+ overflow: counters.value,
971
+ });
972
+ }
973
+ const reset = builder.addComputePass(`${labelPrefix}.view-reset`, {
872
974
  accesses: [
873
975
  { resource: view.value, usage: 'uniform-read' },
874
976
  { resource: counters.value, usage: 'storage-read-write' },
@@ -880,7 +982,7 @@ export class GpuDrivenView {
880
982
  },
881
983
  });
882
984
  if (!reset.ok) return reset;
883
- const cull = builder.addComputePass('gpu-driven.frustum-compact', {
985
+ const cull = builder.addComputePass(`${labelPrefix}.frustum-compact`, {
884
986
  accesses: [
885
987
  { resource: primitive.value, usage: 'storage-read' },
886
988
  { resource: instance.value, usage: 'storage-read' },
@@ -897,7 +999,7 @@ export class GpuDrivenView {
897
999
  },
898
1000
  });
899
1001
  if (!cull.ok) return cull;
900
- const finalize = builder.addComputePass('gpu-driven.finalize-indirect', {
1002
+ const finalize = builder.addComputePass(`${labelPrefix}.finalize-indirect`, {
901
1003
  accesses: [
902
1004
  { resource: batches.value, usage: 'storage-read' },
903
1005
  { resource: view.value, usage: 'uniform-read' },
@@ -911,21 +1013,46 @@ export class GpuDrivenView {
911
1013
  },
912
1014
  });
913
1015
  if (!finalize.ok) return finalize;
914
- const readback = builder.addCopyPass('gpu-driven.lod-selection-readback', {
1016
+ const graphResourceGeneration = this.resourceGeneration;
1017
+ const readback = builder.addCopyPass(`${labelPrefix}.lod-selection-readback`, {
915
1018
  accesses: [
916
1019
  { resource: counters.value, usage: 'copy-src' },
917
1020
  { resource: lodReadback.value, usage: 'copy-dst' },
918
1021
  ],
919
1022
  encode: ({ encoder, resources }) => {
1023
+ // A cached graph may run while an observer is awaiting mapAsync on the
1024
+ // previous copy. WebGPU forbids submitting a copy into a
1025
+ // pending/mapped buffer; skip only this telemetry copy and keep the
1026
+ // raster/indirect work intact. RhiNull has no runtime mapState, so its
1027
+ // undefined value remains structurally executable.
1028
+ const mapState = buffers.lodReadback.mapState;
1029
+ if (mapState !== undefined && mapState !== 'unmapped') return;
920
1030
  encoder.copyBufferToBuffer(
921
1031
  resources.buffer(counters.value).unwrap(),
922
1032
  resources.buffer(lodReadback.value).unwrap(),
923
1033
  this.batchCapacity * COUNTER_STRIDE,
924
1034
  );
1035
+ // The render graph is cached across camera-only LOD projection
1036
+ // changes. The pass closure therefore retains the graph-generation
1037
+ // plan while `this.plan` carries the plan uploaded for the frame that
1038
+ // is actually being submitted. Counters belong to that current plan;
1039
+ // retaining the stale closure plan would make every observation fail
1040
+ // the identity fence and silently leave the CPU level-0 placeholder.
1041
+ const submittedPlan = this.plan;
1042
+ if (
1043
+ this.buffers === buffers &&
1044
+ submittedPlan !== undefined &&
1045
+ this.resourceGeneration === graphResourceGeneration
1046
+ ) {
1047
+ this.telemetryPending = {
1048
+ buffers,
1049
+ plan: submittedPlan,
1050
+ resourceGeneration: graphResourceGeneration,
1051
+ };
1052
+ }
925
1053
  },
926
1054
  });
927
1055
  if (!readback.ok) return readback;
928
- this.telemetryPending = true;
929
1056
  return ok({
930
1057
  visible: visible.value,
931
1058
  primitive: primitive.value,
@@ -952,6 +1079,9 @@ export class GpuDrivenView {
952
1079
  this.sceneTransform = undefined;
953
1080
  this.sceneMaterial = undefined;
954
1081
  this.sceneCapacity = 0;
1082
+ this.telemetryPending = undefined;
1083
+ this.lodSelectionReadback = undefined;
1084
+ this.lodSelection = undefined;
955
1085
  this.destroyAfterSubmittedWork(buffers);
956
1086
  void this.pipelineLayout;
957
1087
  }
@@ -969,6 +1099,22 @@ export class GpuDrivenView {
969
1099
  this.destroyAfterSubmittedWork(buffers);
970
1100
  }
971
1101
 
1102
+ /**
1103
+ * @internal
1104
+ * Grow every view buffer after a GPU overflow was observed. The next
1105
+ * `update` rewrites the same plan into the replacement generation, so the
1106
+ * failed generation cannot be reused even when topology identity is stable.
1107
+ */
1108
+ _recoverFromOverflow(): Result<void, RhiError> {
1109
+ if (this.buffers === undefined) return ok(undefined);
1110
+ return this.rebuildBuffers(
1111
+ this.candidateCapacity * 2,
1112
+ this.visibleBufferCapacity * 2,
1113
+ this.batchCapacity * 2,
1114
+ this.indirectCapacity * 2,
1115
+ );
1116
+ }
1117
+
972
1118
  private rebuildBuffers(
973
1119
  candidateCapacity: number,
974
1120
  visibleCapacity: number,
@@ -1067,6 +1213,7 @@ export class GpuDrivenView {
1067
1213
  this.indirectCapacity = nextIndirect;
1068
1214
  this.bufferRebuilds += 1;
1069
1215
  this.bindGroup = undefined;
1216
+ this.telemetryPending = undefined;
1070
1217
  return ok(undefined);
1071
1218
  }
1072
1219
 
@@ -52,6 +52,7 @@
52
52
  // introduced in feat-20260612 M1 / w1).
53
53
 
54
54
  import type { Buffer, Result, RhiDevice, RhiError, Texture } from '@forgeax/engine-rhi';
55
+ import type { DeviceScope } from './device/device-scope';
55
56
 
56
57
  /**
57
58
  * Runtime wrapper around an RHI `Buffer` opaque handle that exposes
@@ -81,10 +82,17 @@ export class GpuBuffer {
81
82
  // BUFFER_META_MAP. This local flag is a derived view written only on
82
83
  // the success branch of `device.destroyBuffer(...)`; charter §F1.
83
84
  private destroyed = false;
85
+ private releaseScope: (() => void) | undefined;
84
86
 
85
- constructor(device: RhiDevice, handle: Buffer) {
87
+ constructor(device: RhiDevice, handle: Buffer, scope?: DeviceScope) {
86
88
  this.device = device;
87
89
  this.handle = handle;
90
+ if (scope !== undefined) {
91
+ const ref = scope._adopt('buffer', this, (value) => {
92
+ if (!value.isDestroyed) value.destroy();
93
+ });
94
+ this.releaseScope = () => scope._release(ref);
95
+ }
88
96
  }
89
97
 
90
98
  get isDestroyed(): boolean {
@@ -101,6 +109,8 @@ export class GpuBuffer {
101
109
  const r = this.device.destroyBuffer(this.handle);
102
110
  if (r.ok) {
103
111
  this.destroyed = true;
112
+ this.releaseScope?.();
113
+ this.releaseScope = undefined;
104
114
  }
105
115
  return r;
106
116
  }
@@ -126,10 +136,17 @@ export class GpuTexture {
126
136
  readonly device: RhiDevice;
127
137
  readonly handle: Texture;
128
138
  private destroyed = false;
139
+ private releaseScope: (() => void) | undefined;
129
140
 
130
- constructor(device: RhiDevice, handle: Texture) {
141
+ constructor(device: RhiDevice, handle: Texture, scope?: DeviceScope) {
131
142
  this.device = device;
132
143
  this.handle = handle;
144
+ if (scope !== undefined) {
145
+ const ref = scope._adopt('texture', this, (value) => {
146
+ if (!value.isDestroyed) value.destroy();
147
+ });
148
+ this.releaseScope = () => scope._release(ref);
149
+ }
133
150
  }
134
151
 
135
152
  get isDestroyed(): boolean {
@@ -144,6 +161,8 @@ export class GpuTexture {
144
161
  const r = this.device.destroyTexture(this.handle);
145
162
  if (r.ok) {
146
163
  this.destroyed = true;
164
+ this.releaseScope?.();
165
+ this.releaseScope = undefined;
147
166
  }
148
167
  return r;
149
168
  }