@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
@@ -44,6 +44,15 @@ function snapshot(entityKey: number, x: number): RenderableSnapshot {
44
44
  };
45
45
  }
46
46
 
47
+ function updateSnapshot(value: RenderableSnapshot) {
48
+ return {
49
+ kind: 'update' as const,
50
+ worldId: value.worldId,
51
+ entityKey: value.entityKey,
52
+ snapshot: value,
53
+ };
54
+ }
55
+
47
56
  export interface GpuDrivenViewGpuEvidence {
48
57
  readonly visibleInstance: number;
49
58
  readonly indexCount: number;
@@ -90,12 +99,17 @@ export async function runGpuDrivenViewLifecycleEvidence(
90
99
  for (let frame = 0; frame < frames; frame += 1) {
91
100
  const targetCount = frame < 4 ? 2 ** frame : frame % 2 === 0 ? 1 : 8;
92
101
  const operations: Array<
93
- | { readonly kind: 'create'; readonly snapshot: RenderableSnapshot }
102
+ | {
103
+ readonly kind: 'update';
104
+ readonly worldId: number;
105
+ readonly entityKey: number;
106
+ readonly snapshot: RenderableSnapshot;
107
+ }
94
108
  | { readonly kind: 'remove'; readonly worldId: number; readonly entityKey: number }
95
109
  > = [];
96
110
  while (activeCount < targetCount) {
97
111
  activeCount += 1;
98
- operations.push({ kind: 'create', snapshot: snapshot(activeCount, activeCount * 0.05) });
112
+ operations.push(updateSnapshot(snapshot(activeCount, activeCount * 0.05)));
99
113
  }
100
114
  while (activeCount > targetCount) {
101
115
  operations.push({ kind: 'remove', worldId: 0, entityKey: activeCount });
@@ -140,6 +154,9 @@ export async function runGpuDrivenViewLifecycleEvidence(
140
154
  export async function runGpuDrivenViewGpuEvidence(): Promise<GpuDrivenViewGpuEvidence> {
141
155
  const adapter = (await rhi.requestAdapter()).unwrap();
142
156
  const device = (await adapter.requestDevice()).unwrap();
157
+ const rawDevice = _internal_getRawDevice(device);
158
+ if (rawDevice === undefined) throw new Error('GPU-driven evidence raw device unavailable');
159
+ rawDevice.pushErrorScope('validation');
143
160
  const shader = (
144
161
  await rhi.createShaderModule(device, {
145
162
  code: GPU_DRIVEN_VIEW_WGSL,
@@ -168,19 +185,16 @@ export async function runGpuDrivenViewGpuEvidence(): Promise<GpuDrivenViewGpuEvi
168
185
  ],
169
186
  };
170
187
  const delta = projection.apply([
171
- {
172
- kind: 'create',
173
- snapshot: {
174
- ...instancedWithLod,
175
- instances: {
176
- transforms: new Float32Array([...visibleInstance, ...culledInstance]),
177
- instanceCount: 2,
178
- cacheKey: 1,
179
- archVersion: 1,
180
- },
188
+ updateSnapshot({
189
+ ...instancedWithLod,
190
+ instances: {
191
+ transforms: new Float32Array([...visibleInstance, ...culledInstance]),
192
+ instanceCount: 2,
193
+ cacheKey: 1,
194
+ archVersion: 1,
181
195
  },
182
- },
183
- { kind: 'create', snapshot: snapshot(2, 10) },
196
+ }),
197
+ updateSnapshot(snapshot(2, 10)),
184
198
  ]);
185
199
  const sceneAvailability = GpuScene.create(device, 2).unwrap();
186
200
  if (sceneAvailability.status !== 'available') throw new Error('GPU Scene unavailable');
@@ -248,16 +262,54 @@ export async function runGpuDrivenViewGpuEvidence(): Promise<GpuDrivenViewGpuEvi
248
262
  64,
249
263
  );
250
264
  device.queue.submit([encoder.finish().unwrap()]).unwrap();
251
- await device.queue.onSubmittedWorkDone();
252
265
 
253
- // Exercise the real GPU telemetry readback before any mapped range is
254
- // unmapped. This is intentionally on the same submit as the visible and
255
- // indirect readbacks so a detached DataView cannot be hidden by a mock or a
256
- // separate inspection path.
257
- const lodSelection = await view.readLodSelection();
266
+ // Start observing immediately, then submit the cached graph again before
267
+ // the first mapAsync settles. The second copy must be skipped while the
268
+ // readback is pending; compute/raster work remains submit-able.
269
+ const pendingLodSelection = view.readLodSelection();
270
+ if (view.readLodSelection() !== pendingLodSelection) {
271
+ throw new Error('GPU-driven LOD telemetry did not coalesce concurrent observers');
272
+ }
273
+ const overlappingEncoder = device
274
+ .createCommandEncoder({ label: 'gpu-driven-evidence-overlap' })
275
+ .unwrap();
276
+ compiled.execute({ encoder: overlappingEncoder }).unwrap();
277
+ device.queue.submit([overlappingEncoder.finish().unwrap()]).unwrap();
278
+ const lodSelection = await pendingLodSelection;
258
279
  if (lodSelection === undefined || lodSelection.batches.length !== lodSelection.batchCount) {
259
280
  throw new Error('GPU-driven LOD selection readback unavailable or incomplete');
260
281
  }
282
+ await device.queue.onSubmittedWorkDone();
283
+
284
+ // After unmap, a later cached-graph submission must restore telemetry
285
+ // observation rather than leaving the latch permanently consumed.
286
+ const recoveryProjection = mat4.identity(mat4.create());
287
+ recoveryProjection[12] = 10;
288
+ view
289
+ .update(
290
+ topology.plan(),
291
+ sceneAvailability.scene,
292
+ frustum.fromViewProjection(frustum.create(), recoveryProjection),
293
+ )
294
+ .unwrap();
295
+ const recoveryEncoder = device
296
+ .createCommandEncoder({ label: 'gpu-driven-evidence-recovery' })
297
+ .unwrap();
298
+ compiled.execute({ encoder: recoveryEncoder }).unwrap();
299
+ device.queue.submit([recoveryEncoder.finish().unwrap()]).unwrap();
300
+ await device.queue.onSubmittedWorkDone();
301
+ const recoveredLodSelection = await view.readLodSelection();
302
+ if (
303
+ recoveredLodSelection === undefined ||
304
+ recoveredLodSelection === lodSelection ||
305
+ recoveredLodSelection.visible === lodSelection.visible
306
+ ) {
307
+ throw new Error('GPU-driven LOD telemetry did not recover after a skipped copy');
308
+ }
309
+ const validationError = await rawDevice.popErrorScope();
310
+ if (validationError !== null) {
311
+ throw new Error(`GPU-driven telemetry overlap validation failed: ${validationError.message}`);
312
+ }
261
313
 
262
314
  const visibleMap = (await visibleReadback.mapAsync(GPU_MAP_MODE_READ)).unwrap();
263
315
  const visibleValue = new DataView(visibleMap.getMappedRange().unwrap()).getUint32(0, true);
@@ -53,11 +53,26 @@ function snapshot(entityKey: number): RenderableSnapshot {
53
53
  };
54
54
  }
55
55
 
56
+ function updateSnapshot(value: RenderableSnapshot) {
57
+ return {
58
+ kind: 'update' as const,
59
+ worldId: value.worldId,
60
+ entityKey: value.entityKey,
61
+ snapshot: value,
62
+ };
63
+ }
64
+
56
65
  function preparedFrame(view: GpuDrivenView): PreparedGpuDrivenFrame {
57
66
  return {
58
67
  topologySignature: `view-generation:${view.inspect().resourceGeneration}`,
59
- entityKeys: new Set(),
60
- ownsAllRenderables: true,
68
+ ownsAllDrawItems: true,
69
+ standardPbrFrameResources: {
70
+ materialBindGroups: [],
71
+ materialSlotIndicesByEntity: new Map(),
72
+ instancesBindGroup: {} as never,
73
+ materialStride: 0,
74
+ sceneMaterialBuffer: {} as never,
75
+ },
61
76
  _commitResourceReplacement: () => view._commitResourceReplacement(),
62
77
  project: (graph) => {
63
78
  const projected = view.addPasses(graph);
@@ -126,8 +141,14 @@ describe('GpuDrivenView graph projection', () => {
126
141
  if (first === null) return;
127
142
  const prepared: PreparedGpuDrivenFrame = {
128
143
  topologySignature: 'stable-gpu-driven-test',
129
- entityKeys: new Set(),
130
- ownsAllRenderables: true,
144
+ ownsAllDrawItems: true,
145
+ standardPbrFrameResources: {
146
+ materialBindGroups: [],
147
+ materialSlotIndicesByEntity: new Map(),
148
+ instancesBindGroup: {} as never,
149
+ materialStride: 0,
150
+ sceneMaterialBuffer: {} as never,
151
+ },
131
152
  _commitResourceReplacement: () => undefined,
132
153
  project: (graph) => {
133
154
  const pass = graph.addComputePass('gpu-driven-test', {
@@ -153,7 +174,7 @@ describe('GpuDrivenView graph projection', () => {
153
174
  const device = (await adapter.requestDevice()).unwrap();
154
175
  const shader = (await rhi.createShaderModule(device, { code: 'synthetic' })).unwrap();
155
176
  const projection = new RenderScene();
156
- const delta = projection.apply([{ kind: 'create', snapshot: snapshot(1) }]);
177
+ const delta = projection.apply([updateSnapshot(snapshot(1))]);
157
178
  const sceneAvailability = GpuScene.create(device, 1).unwrap();
158
179
  expect(sceneAvailability.status).toBe('available');
159
180
  if (sceneAvailability.status !== 'available') return;
@@ -240,7 +261,7 @@ describe('GpuDrivenView graph projection', () => {
240
261
  const shader = (await rhi.createShaderModule(device, { code: 'synthetic' })).unwrap();
241
262
  const destroyBuffer = vi.spyOn(device, 'destroyBuffer');
242
263
  const projection = new RenderScene();
243
- const firstDelta = projection.apply([{ kind: 'create', snapshot: snapshot(1) }]);
264
+ const firstDelta = projection.apply([updateSnapshot(snapshot(1))]);
244
265
  const sceneAvailability = GpuScene.create(device, 2).unwrap();
245
266
  expect(sceneAvailability.status).toBe('available');
246
267
  if (sceneAvailability.status !== 'available') return;
@@ -351,7 +372,7 @@ describe('GpuDrivenView graph projection', () => {
351
372
  delete (device as unknown as { caps?: unknown }).caps;
352
373
  delete (device as unknown as { surfaceViewFormats?: unknown }).surfaceViewFormats;
353
374
 
354
- const secondDelta = projection.apply([{ kind: 'create', snapshot: snapshot(2) }]);
375
+ const secondDelta = projection.apply([updateSnapshot(snapshot(2))]);
355
376
  sceneAvailability.scene.sync(secondDelta).unwrap();
356
377
  topology.rebuild(projection.slotsSnapshot());
357
378
  view.update(topology.plan(), sceneAvailability.scene, planes).unwrap();
@@ -389,7 +410,7 @@ describe('GpuDrivenView graph projection', () => {
389
410
  const shader = (await rhi.createShaderModule(device, { code: 'synthetic' })).unwrap();
390
411
  const destroyBuffer = vi.spyOn(device, 'destroyBuffer');
391
412
  const projection = new RenderScene();
392
- const firstDelta = projection.apply([{ kind: 'create', snapshot: snapshot(1) }]);
413
+ const firstDelta = projection.apply([updateSnapshot(snapshot(1))]);
393
414
  const sceneAvailability = GpuScene.create(device, 2).unwrap();
394
415
  expect(sceneAvailability.status).toBe('available');
395
416
  if (sceneAvailability.status !== 'available') return;
@@ -406,7 +427,7 @@ describe('GpuDrivenView graph projection', () => {
406
427
  expect(firstVisible).toBeDefined();
407
428
  if (firstVisible === undefined) return;
408
429
 
409
- const secondDelta = projection.apply([{ kind: 'create', snapshot: snapshot(2) }]);
430
+ const secondDelta = projection.apply([updateSnapshot(snapshot(2))]);
410
431
  sceneAvailability.scene.sync(secondDelta).unwrap();
411
432
  topology.rebuild(projection.slotsSnapshot());
412
433
  view.update(topology.plan(), sceneAvailability.scene, planes).unwrap();
@@ -1,6 +1,7 @@
1
1
  import { frustum, mat4 } from '@forgeax/engine-math';
2
2
  import { describe, expect, it } from 'vitest';
3
3
  import { BatchTopology } from '../gpu-driven/batch-topology';
4
+ import { GPU_DRIVEN_VIEW_WGSL } from '../gpu-driven/view-gpu';
4
5
  import type { MaterialSnapshot, RenderableSnapshot } from '../render-system-extract';
5
6
  import { RenderScene } from '../scene/render-scene';
6
7
  import { classifyGpuDrivenView } from './gpu-driven-view-reference';
@@ -9,6 +10,7 @@ const material = {
9
10
  baseColor: new Float32Array([1, 1, 1]),
10
11
  metallic: 0,
11
12
  roughness: 1,
13
+ materialShaderId: 'forgeax::default-standard-pbr',
12
14
  } as MaterialSnapshot;
13
15
 
14
16
  function snapshot(entityKey: number, x: number, resourceClass = 'plain'): RenderableSnapshot {
@@ -38,13 +40,22 @@ function snapshot(entityKey: number, x: number, resourceClass = 'plain'): Render
38
40
  };
39
41
  }
40
42
 
43
+ function updateSnapshot(value: RenderableSnapshot) {
44
+ return {
45
+ kind: 'update' as const,
46
+ worldId: value.worldId,
47
+ entityKey: value.entityKey,
48
+ snapshot: value,
49
+ };
50
+ }
51
+
41
52
  describe('GPU-driven batch topology and CPU oracle', () => {
42
53
  it('isolates LOD candidates so one indirect range cannot serve different meshes', () => {
43
54
  const projection = new RenderScene();
44
55
  const lods = [{ mesh: '00000000-0000-7000-8000-000000000001' as never, screenCoverage: 0.5 }];
45
56
  projection.apply([
46
- { kind: 'create', snapshot: { ...snapshot(1, 0), lods } },
47
- { kind: 'create', snapshot: { ...snapshot(2, 4), lods } },
57
+ updateSnapshot({ ...snapshot(1, 0), lods }),
58
+ updateSnapshot({ ...snapshot(2, 4), lods }),
48
59
  ]);
49
60
  const topology = new BatchTopology();
50
61
  topology.rebuild(projection.slotsSnapshot());
@@ -54,7 +65,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
54
65
 
55
66
  const transformOnly = projection.apply([
56
67
  {
57
- kind: 'update-transform',
68
+ kind: 'update',
58
69
  worldId: 0,
59
70
  entityKey: 1,
60
71
  world: snapshot(1, 0.25).transform.world,
@@ -64,22 +75,19 @@ describe('GPU-driven batch topology and CPU oracle', () => {
64
75
 
65
76
  const instancedProjection = new RenderScene();
66
77
  instancedProjection.apply([
67
- {
68
- kind: 'create',
69
- snapshot: {
70
- ...snapshot(3, 0),
71
- lods,
72
- instances: {
73
- transforms: new Float32Array([
74
- ...mat4.identity(mat4.create()),
75
- ...mat4.identity(mat4.create()),
76
- ]),
77
- instanceCount: 2,
78
- cacheKey: 3,
79
- archVersion: 1,
80
- },
78
+ updateSnapshot({
79
+ ...snapshot(3, 0),
80
+ lods,
81
+ instances: {
82
+ transforms: new Float32Array([
83
+ ...mat4.identity(mat4.create()),
84
+ ...mat4.identity(mat4.create()),
85
+ ]),
86
+ instanceCount: 2,
87
+ cacheKey: 3,
88
+ archVersion: 1,
81
89
  },
82
- },
90
+ }),
83
91
  ]);
84
92
  const instancedTopology = new BatchTopology();
85
93
  instancedTopology.rebuild(instancedProjection.slotsSnapshot());
@@ -89,12 +97,25 @@ describe('GPU-driven batch topology and CPU oracle', () => {
89
97
  );
90
98
  });
91
99
 
100
+ it('projects compact visible items into batch-local mesh and material indices', () => {
101
+ expect(GPU_DRIVEN_VIEW_WGSL).toMatch(
102
+ /vec2<u32>\(\s*candidate\.submitAdmission >> 1u,\s*materialOrPalette,/,
103
+ );
104
+ expect(GPU_DRIVEN_VIEW_WGSL).toContain('(candidate.submitAdmission & 1u)');
105
+ expect(GPU_DRIVEN_VIEW_WGSL).toContain('instance.customDataStart');
106
+ expect(GPU_DRIVEN_VIEW_WGSL).toContain('(candidate.materialSlot & 0x80000000u)');
107
+ expect(GPU_DRIVEN_VIEW_WGSL).toContain('visibleIndices[candidate.visibleBase + localVisible]');
108
+ expect(GPU_DRIVEN_VIEW_WGSL).toContain('overflowIndex(candidate.batchIndex)');
109
+ expect(GPU_DRIVEN_VIEW_WGSL).toContain('visibleCount = 0u');
110
+ expect(GPU_DRIVEN_VIEW_WGSL).toContain('indirectArgs[args + 4u] = 0u');
111
+ });
112
+
92
113
  it('patches topology only when compatibility membership changes', () => {
93
114
  const projection = new RenderScene();
94
115
  projection.apply([
95
- { kind: 'create', snapshot: snapshot(1, 0) },
96
- { kind: 'create', snapshot: snapshot(2, 0.5) },
97
- { kind: 'create', snapshot: snapshot(3, 0, 'textured') },
116
+ updateSnapshot(snapshot(1, 0)),
117
+ updateSnapshot(snapshot(2, 0.5)),
118
+ updateSnapshot(snapshot(3, 0, 'textured')),
98
119
  ]);
99
120
  const topology = new BatchTopology();
100
121
  topology.rebuild(projection.slotsSnapshot());
@@ -103,7 +124,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
103
124
 
104
125
  const transformOnly = projection.apply([
105
126
  {
106
- kind: 'update-transform',
127
+ kind: 'update',
107
128
  worldId: 0,
108
129
  entityKey: 1,
109
130
  world: snapshot(1, 0.25).transform.world,
@@ -120,10 +141,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
120
141
 
121
142
  it('compacts visible primitive indices and writes portable indexed indirect args', () => {
122
143
  const projection = new RenderScene();
123
- projection.apply([
124
- { kind: 'create', snapshot: snapshot(1, 0) },
125
- { kind: 'create', snapshot: snapshot(2, 10) },
126
- ]);
144
+ projection.apply([updateSnapshot(snapshot(1, 0)), updateSnapshot(snapshot(2, 10))]);
127
145
  const topology = new BatchTopology();
128
146
  topology.rebuild(projection.slotsSnapshot());
129
147
  const planes = frustum.fromViewProjection(frustum.create(), mat4.identity(mat4.create()));
@@ -152,16 +170,13 @@ describe('GPU-driven batch topology and CPU oracle', () => {
152
170
  expect(first).toBeDefined();
153
171
  if (first === undefined) return;
154
172
  projection.apply([
155
- {
156
- kind: 'create',
157
- snapshot: {
158
- ...source,
159
- gpuDrivenDraws: [
160
- { ...first, kind: 'non-indexed', first: 0, count: 3 },
161
- { ...first, kind: 'non-indexed', first: 3, count: 6 },
162
- ],
163
- },
164
- },
173
+ updateSnapshot({
174
+ ...source,
175
+ gpuDrivenDraws: [
176
+ { ...first, kind: 'non-indexed', first: 0, count: 3 },
177
+ { ...first, kind: 'non-indexed', first: 3, count: 6 },
178
+ ],
179
+ }),
165
180
  ]);
166
181
  const topology = new BatchTopology();
167
182
  topology.rebuild(projection.slotsSnapshot());
@@ -180,6 +195,105 @@ describe('GPU-driven batch topology and CPU oracle', () => {
180
195
  expect(secondArgs.getUint32(12, true)).toBe(0);
181
196
  });
182
197
 
198
+ it('retains source draw identity when an earlier compact draw is ineligible', () => {
199
+ const source = snapshot(1, 0);
200
+ const first = source.gpuDrivenDraws?.[0];
201
+ expect(first).toBeDefined();
202
+ if (first === undefined) return;
203
+ const projection = new RenderScene();
204
+ projection.apply([
205
+ updateSnapshot({
206
+ ...source,
207
+ gpuDrivenDraws: [
208
+ {
209
+ ...first,
210
+ drawItemIndex: 10,
211
+ prepared: {
212
+ identity: { material: 'custom', geometry: 'triangle', deformation: 'rigid' },
213
+ } as never,
214
+ },
215
+ { ...first, drawItemIndex: 20, first: 9, count: 12 },
216
+ ],
217
+ }),
218
+ ]);
219
+ const topology = new BatchTopology();
220
+ topology.rebuild(projection.slotsSnapshot());
221
+ const candidates = topology.plan().batches.flatMap((batch) => batch.candidates);
222
+ expect(candidates).toHaveLength(1);
223
+ expect(candidates[0]?.drawItemIndex).toBe(20);
224
+ expect(topology.plan().batches[0]?.key).toMatchObject({ first: 9, count: 12 });
225
+ });
226
+
227
+ it('patches a same-key eligibility swap using the retained draw identity', () => {
228
+ const source = snapshot(1, 0);
229
+ const first = source.gpuDrivenDraws?.[0];
230
+ expect(first).toBeDefined();
231
+ if (first === undefined) return;
232
+ const ineligible = {
233
+ ...first,
234
+ drawItemIndex: 10,
235
+ prepared: {
236
+ identity: { material: 'custom', geometry: 'triangle', deformation: 'rigid' },
237
+ } as never,
238
+ };
239
+ const eligible = { ...first, drawItemIndex: 20, first: 9, count: 12 };
240
+ const eligibleAt10 = { ...eligible, drawItemIndex: 10 };
241
+ const ineligibleAt20 = { ...ineligible, drawItemIndex: 20 };
242
+ const projection = new RenderScene();
243
+ projection.apply([updateSnapshot({ ...source, gpuDrivenDraws: [ineligible, eligible] })]);
244
+ const topology = new BatchTopology();
245
+ topology.rebuild(projection.slotsSnapshot());
246
+ const swapped = projection.apply([
247
+ updateSnapshot({ ...source, gpuDrivenDraws: [eligibleAt10, ineligibleAt20] }),
248
+ ]);
249
+ expect(topology.apply(swapped)).toBe(true);
250
+ expect(topology.inspect().patches).toBe(1);
251
+ expect(topology.plan().batches.flatMap((batch) => batch.candidates)[0]?.drawItemIndex).toBe(10);
252
+ });
253
+
254
+ it('keeps prepared material and range identity after reversing submesh order', () => {
255
+ const source = snapshot(1, 0);
256
+ const first = source.gpuDrivenDraws?.[0];
257
+ expect(first).toBeDefined();
258
+ if (first === undefined) return;
259
+ const materialA = { ...material, materialHandle: 11 } as MaterialSnapshot;
260
+ const materialB = { ...material, materialHandle: 12 } as MaterialSnapshot;
261
+ const orderedDraws = [
262
+ { ...first, drawItemIndex: 4, materialSlot: 0, first: 0, count: 3 },
263
+ { ...first, drawItemIndex: 9, materialSlot: 1, first: 3, count: 6 },
264
+ ];
265
+ const [orderedFirst, orderedSecond] = orderedDraws;
266
+ if (orderedFirst === undefined || orderedSecond === undefined) return;
267
+ const ordered = {
268
+ ...source,
269
+ materials: [materialA, materialB],
270
+ material: materialA,
271
+ gpuDrivenDraws: orderedDraws,
272
+ };
273
+ const reversed = {
274
+ ...ordered,
275
+ gpuDrivenDraws: [orderedSecond, orderedFirst],
276
+ };
277
+ const orderedTopology = new BatchTopology();
278
+ const reversedTopology = new BatchTopology();
279
+ const orderedScene = new RenderScene();
280
+ const reversedScene = new RenderScene();
281
+ orderedScene.apply([updateSnapshot(ordered)]);
282
+ reversedScene.apply([updateSnapshot(reversed)]);
283
+ orderedTopology.rebuild(orderedScene.slotsSnapshot());
284
+ reversedTopology.rebuild(reversedScene.slotsSnapshot());
285
+ const describe = (topology: BatchTopology) =>
286
+ topology
287
+ .plan()
288
+ .batches.map((batch) => [
289
+ batch.key.materialSlot,
290
+ batch.key.first,
291
+ batch.key.count,
292
+ batch.candidates[0]?.drawItemIndex,
293
+ ]);
294
+ expect(describe(reversedTopology).sort()).toEqual(describe(orderedTopology).sort());
295
+ });
296
+
183
297
  it('culls ordinary instance-local transforms and emits instance identities', () => {
184
298
  const source = snapshot(1, 0);
185
299
  const identity = mat4.identity(mat4.create());
@@ -187,18 +301,15 @@ describe('GPU-driven batch topology and CPU oracle', () => {
187
301
  outside[12] = 10;
188
302
  const projection = new RenderScene();
189
303
  projection.apply([
190
- {
191
- kind: 'create',
192
- snapshot: {
193
- ...source,
194
- instances: {
195
- transforms: new Float32Array([...identity, ...outside]),
196
- instanceCount: 2,
197
- cacheKey: 1,
198
- archVersion: 1,
199
- },
304
+ updateSnapshot({
305
+ ...source,
306
+ instances: {
307
+ transforms: new Float32Array([...identity, ...outside]),
308
+ instanceCount: 2,
309
+ cacheKey: 1,
310
+ archVersion: 1,
200
311
  },
201
- },
312
+ }),
202
313
  ]);
203
314
  const topology = new BatchTopology();
204
315
  topology.rebuild(projection.slotsSnapshot());
@@ -215,10 +326,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
215
326
 
216
327
  it('reports overflow instead of silently accepting a truncated batch', () => {
217
328
  const projection = new RenderScene();
218
- projection.apply([
219
- { kind: 'create', snapshot: snapshot(1, 0) },
220
- { kind: 'create', snapshot: snapshot(2, 0.5) },
221
- ]);
329
+ projection.apply([updateSnapshot(snapshot(1, 0)), updateSnapshot(snapshot(2, 0.5))]);
222
330
  const topology = new BatchTopology();
223
331
  topology.rebuild(projection.slotsSnapshot());
224
332
  const plan = topology.plan();
@@ -239,7 +347,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
239
347
  const projection = new RenderScene();
240
348
  const { localAabb: _localAabb, ...withoutBounds } = snapshot(1, 0);
241
349
  const topology = new BatchTopology();
242
- topology.rebuild(projection.apply([{ kind: 'create', snapshot: withoutBounds }]).createdSlots);
350
+ topology.rebuild(projection.apply([updateSnapshot(withoutBounds)]).createdSlots);
243
351
  expect(topology.inspect().ineligible).toBe(1);
244
352
 
245
353
  const removed = projection.apply([{ kind: 'remove', worldId: 0, entityKey: 1 }]);
@@ -104,6 +104,21 @@ function drawTimingFrame(fixture: BrowserTimingFixture): {
104
104
  };
105
105
  }
106
106
 
107
+ export async function observeBrowserGpuPassTimingDisabled() {
108
+ const fixture = await createBrowserTimingFixture(false);
109
+ try {
110
+ const { receipt } = drawTimingFrame(fixture);
111
+ const requested = await fixture.renderer.observe(receipt, { include: ['timings'] });
112
+ const omitted = await fixture.renderer.observe(receipt, { include: ['draws'] });
113
+ if (!requested.ok) throw requested.error;
114
+ if (!omitted.ok) throw omitted.error;
115
+ return { requested: requested.value, omitted: omitted.value };
116
+ } finally {
117
+ await fixture.renderer.dispose();
118
+ fixture.canvas.remove();
119
+ }
120
+ }
121
+
107
122
  function adapterString(value: unknown): string | undefined {
108
123
  return typeof value === 'string' && value.length > 0 ? value : undefined;
109
124
  }
@@ -1,10 +1,28 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { runBrowserGpuPassTiming } from './gpu-pass-timing-browser-runner.js';
2
+ import {
3
+ observeBrowserGpuPassTimingDisabled,
4
+ runBrowserGpuPassTiming,
5
+ } from './gpu-pass-timing-browser-runner.js';
3
6
 
4
7
  const browserReady = typeof navigator !== 'undefined' && navigator.gpu !== undefined;
5
8
 
6
9
  describe.skipIf(!browserReady)('GPU pass timing Browser dev-server runner', () => {
7
- it('keeps receipt facts and unsupported timing structured without stopping draw', async () => {
10
+ it('returns the standard unavailable observation when GPU timing is disabled', async () => {
11
+ const { requested, omitted } = await observeBrowserGpuPassTimingDisabled();
12
+ expect(requested.timings).toMatchObject({
13
+ status: 'unavailable',
14
+ reason: { code: 'gpu-timing-not-enabled' },
15
+ });
16
+ expect(requested.timings).not.toHaveProperty('frame');
17
+ expect(omitted.timings).toBeUndefined();
18
+ });
19
+
20
+ // The first live lavapipe renderer pair can exceed Vitest's 15s default while
21
+ // the shader manifest and timestamp-query path are cold; keep this bound
22
+ // local to the real WebGPU owner instead of weakening the global timeout.
23
+ it('keeps receipt facts and unsupported timing structured without stopping draw', {
24
+ timeout: 30_000,
25
+ }, async () => {
8
26
  const result = await runBrowserGpuPassTiming();
9
27
  expect(result.frames).toBe(3);
10
28
  if (result.supported) {
@@ -0,0 +1,71 @@
1
+ import { err, ok, type RhiDevice, RhiError } from '@forgeax/engine-rhi';
2
+ import { rhi } from '@forgeax/engine-rhi-null';
3
+ import { expect, it, vi } from 'vitest';
4
+ import { DeviceScope } from '../device/device-scope';
5
+ import { GpuBuffer, GpuTexture } from '../gpu-resource';
6
+
7
+ it.each([
8
+ 'buffer',
9
+ 'texture',
10
+ ] as const)('keeps %s ownership on failed destruction and releases it after successful retry', async (kind) => {
11
+ const device = (await (await rhi.requestAdapter()).unwrap().requestDevice()).unwrap();
12
+ const scope = DeviceScope.create(1, 'gpu-resource');
13
+ const method = kind === 'buffer' ? 'destroyBuffer' : 'destroyTexture';
14
+ const original = device[method].bind(device);
15
+ const spy = vi
16
+ .spyOn(device, method)
17
+ .mockReturnValueOnce(
18
+ err(
19
+ new RhiError({ code: 'webgpu-runtime-error', expected: 'injected failure', hint: 'retry' }),
20
+ ),
21
+ );
22
+ const resource =
23
+ kind === 'buffer'
24
+ ? new GpuBuffer(device, device.createBuffer({ size: 64, usage: 8 }).unwrap(), scope)
25
+ : new GpuTexture(
26
+ device,
27
+ device
28
+ .createTexture({
29
+ size: [1, 1, 1],
30
+ format: 'rgba8unorm',
31
+ usage: 4,
32
+ textureBindingViewDimension: '2d',
33
+ })
34
+ .unwrap(),
35
+ scope,
36
+ );
37
+ expect(scope.resourceDelta()).toBe(1);
38
+ expect(resource.destroy().ok).toBe(false);
39
+ expect(resource.isDestroyed).toBe(false);
40
+ expect(scope.resourceDelta()).toBe(1);
41
+ spy.mockImplementation(original as RhiDevice[typeof method]);
42
+ expect(resource.destroy().ok).toBe(true);
43
+ expect(resource.isDestroyed).toBe(true);
44
+ expect(scope.resourceDelta()).toBe(0);
45
+ scope.retire();
46
+ expect(spy).toHaveBeenCalledTimes(2);
47
+ expect(resource.destroy().ok).toBe(false);
48
+ expect(scope.resourceDelta()).toBe(0);
49
+ });
50
+
51
+ it('cleans remaining resources in reverse order after an earlier resource was released', async () => {
52
+ const device = (await (await rhi.requestAdapter()).unwrap().requestDevice()).unwrap();
53
+ const scope = DeviceScope.create(1, 'gpu-resource-order');
54
+ const resources = Array.from(
55
+ { length: 3 },
56
+ () => new GpuBuffer(device, device.createBuffer({ size: 64, usage: 8 }).unwrap(), scope),
57
+ );
58
+ const handles: unknown[] = [];
59
+ vi.spyOn(device, 'destroyBuffer').mockImplementation((handle) => {
60
+ handles.push(handle);
61
+ return ok(undefined);
62
+ });
63
+ const [first, second, third] = resources;
64
+ if (first === undefined || second === undefined || third === undefined)
65
+ throw new Error('missing fixture resource');
66
+ second.destroy().unwrap();
67
+ scope.retire();
68
+ scope.dispose();
69
+ expect(handles).toEqual([second.handle, third.handle, first.handle]);
70
+ expect(scope.resourceDelta()).toBe(0);
71
+ });