@forgeax/engine-render 0.1.32 → 0.1.34

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 (624) hide show
  1. package/README.md +1374 -142
  2. package/dist/assembly/analytic-fog-registration.d.ts +3 -0
  3. package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
  4. package/dist/assembly/backend-contract.d.ts +2 -0
  5. package/dist/assembly/backend-contract.d.ts.map +1 -1
  6. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  7. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  8. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  9. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  10. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  11. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  12. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  13. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  14. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  15. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  16. package/dist/assembly/factory.d.ts +1 -1
  17. package/dist/assembly/factory.d.ts.map +1 -1
  18. package/dist/assembly/fxaa-registration.d.ts +4 -0
  19. package/dist/assembly/fxaa-registration.d.ts.map +1 -0
  20. package/dist/assembly/host-contract.d.ts +3 -3
  21. package/dist/assembly/host-contract.d.ts.map +1 -1
  22. package/dist/assembly/lod-observation.d.ts +4 -0
  23. package/dist/assembly/lod-observation.d.ts.map +1 -0
  24. package/dist/assembly/material/assembly.d.ts.map +1 -1
  25. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  26. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  27. package/dist/assembly/material-shader-policy.d.ts +16 -2
  28. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  29. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  30. package/dist/assembly/motion-blur-registration.d.ts +3 -0
  31. package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
  32. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  33. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  34. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  35. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  36. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  37. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  38. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  39. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  40. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  41. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  42. package/dist/assembly/renderer-inspection.d.ts +11 -0
  43. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  44. package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
  45. package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  48. package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
  49. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
  50. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  51. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  52. package/dist/assembly/webgpu-ready.d.ts +2 -2
  53. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  54. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  55. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  56. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  57. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  58. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  59. package/dist/authoring.mjs +1 -1
  60. package/dist/barrel-distortion.d.ts +47 -0
  61. package/dist/barrel-distortion.d.ts.map +1 -0
  62. package/dist/bloom-admission.d.ts +13 -0
  63. package/dist/bloom-admission.d.ts.map +1 -0
  64. package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
  65. package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
  66. package/dist/{chunk-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
  67. package/dist/chunk-HEB564WF.mjs.map +1 -0
  68. package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
  69. package/dist/chunk-MKDIT2EM.mjs.map +1 -0
  70. package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
  71. package/dist/{chunk-S665NJNF.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
  72. package/dist/chunk-ODZWR6JQ.mjs +4927 -0
  73. package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
  74. package/dist/{chunk-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
  75. package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
  76. package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
  77. package/dist/chunk-UI5SFODX.mjs.map +1 -0
  78. package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
  79. package/dist/chunk-UINHLCZA.mjs.map +1 -0
  80. package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
  81. package/dist/chunk-WEX45HKH.mjs.map +1 -0
  82. package/dist/cloud/density.d.ts +55 -0
  83. package/dist/cloud/density.d.ts.map +1 -0
  84. package/dist/cloud/extract.d.ts +25 -0
  85. package/dist/cloud/extract.d.ts.map +1 -0
  86. package/dist/cloud/feature.d.ts +57 -0
  87. package/dist/cloud/feature.d.ts.map +1 -0
  88. package/dist/cloud/frame-context.d.ts +8 -0
  89. package/dist/cloud/frame-context.d.ts.map +1 -0
  90. package/dist/cloud/inspection.d.ts +59 -0
  91. package/dist/cloud/inspection.d.ts.map +1 -0
  92. package/dist/cloud/optics.d.ts +56 -0
  93. package/dist/cloud/optics.d.ts.map +1 -0
  94. package/dist/cloud/parameters.d.ts +73 -0
  95. package/dist/cloud/parameters.d.ts.map +1 -0
  96. package/dist/cloud/resources.d.ts +60 -0
  97. package/dist/cloud/resources.d.ts.map +1 -0
  98. package/dist/cloud/shadow.d.ts +42 -0
  99. package/dist/cloud/shadow.d.ts.map +1 -0
  100. package/dist/cloud/temporal.d.ts +74 -0
  101. package/dist/cloud/temporal.d.ts.map +1 -0
  102. package/dist/components/atmosphere.d.ts +2 -0
  103. package/dist/components/atmosphere.d.ts.map +1 -1
  104. package/dist/components/barrel-distortion.d.ts +13 -0
  105. package/dist/components/barrel-distortion.d.ts.map +1 -0
  106. package/dist/components/camera.d.ts +20 -4
  107. package/dist/components/camera.d.ts.map +1 -1
  108. package/dist/components/cloud-layer.d.ts +29 -0
  109. package/dist/components/cloud-layer.d.ts.map +1 -0
  110. package/dist/components/index.d.ts +2 -0
  111. package/dist/components/index.d.ts.map +1 -1
  112. package/dist/components/instances.d.ts +20 -6
  113. package/dist/components/instances.d.ts.map +1 -1
  114. package/dist/components/mesh-filter.d.ts +6 -5
  115. package/dist/components/mesh-filter.d.ts.map +1 -1
  116. package/dist/components/motion-blur.d.ts +1 -0
  117. package/dist/components/motion-blur.d.ts.map +1 -1
  118. package/dist/construct-renderer.d.ts +1 -1
  119. package/dist/construct-renderer.d.ts.map +1 -1
  120. package/dist/construct-renderer.mjs +9751 -3528
  121. package/dist/construct-renderer.mjs.map +1 -1
  122. package/dist/device/gpu-residency.d.ts +6 -0
  123. package/dist/device/gpu-residency.d.ts.map +1 -1
  124. package/dist/dynamic-geometry.d.ts +5 -1
  125. package/dist/dynamic-geometry.d.ts.map +1 -1
  126. package/dist/environment/analytic-fog.d.ts +6 -0
  127. package/dist/environment/analytic-fog.d.ts.map +1 -0
  128. package/dist/errors/cloud.d.ts +59 -0
  129. package/dist/errors/cloud.d.ts.map +1 -0
  130. package/dist/errors/render.d.ts +23 -5
  131. package/dist/errors/render.d.ts.map +1 -1
  132. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  133. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  134. package/dist/extract/camera.d.ts.map +1 -1
  135. package/dist/extract/contracts.d.ts +12 -1
  136. package/dist/extract/contracts.d.ts.map +1 -1
  137. package/dist/extract/environment.d.ts +2 -0
  138. package/dist/extract/environment.d.ts.map +1 -1
  139. package/dist/features/barrel-distortion.d.ts +29 -0
  140. package/dist/features/barrel-distortion.d.ts.map +1 -0
  141. package/dist/features/error-reporting.d.ts +17 -0
  142. package/dist/features/error-reporting.d.ts.map +1 -0
  143. package/dist/features/host.d.ts +15 -0
  144. package/dist/features/host.d.ts.map +1 -1
  145. package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
  146. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
  147. package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
  148. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
  149. package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
  150. package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
  151. package/dist/features/plan.d.ts +15 -4
  152. package/dist/features/plan.d.ts.map +1 -1
  153. package/dist/features/prepared-gpu-work.d.ts +9 -5
  154. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  155. package/dist/features/render-graph-compute.d.ts.map +1 -1
  156. package/dist/features/render-graph-contribution.d.ts +5 -0
  157. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  158. package/dist/features/render-graph-raster.d.ts +1 -0
  159. package/dist/features/render-graph-raster.d.ts.map +1 -1
  160. package/dist/features/targets.d.ts +2 -0
  161. package/dist/features/targets.d.ts.map +1 -1
  162. package/dist/features/types.d.ts +44 -0
  163. package/dist/features/types.d.ts.map +1 -1
  164. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  165. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  166. package/dist/gpu-dirty-ranges.d.ts +11 -0
  167. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  168. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  169. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  170. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  171. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  172. package/dist/gpu-driven/prepared-draw.d.ts +7 -0
  173. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  174. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  175. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  176. package/dist/gpu-driven/production-raster.d.ts +50 -4
  177. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  178. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  179. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  180. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  181. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  182. package/dist/gpu-driven/view-gpu.d.ts +35 -2
  183. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  184. package/dist/gpu-scene.d.ts +11 -1
  185. package/dist/gpu-scene.d.ts.map +1 -1
  186. package/dist/hdrp-buffers.d.ts +2 -2
  187. package/dist/hdrp-buffers.d.ts.map +1 -1
  188. package/dist/ibl/skylight-bind-group.d.ts +10 -1
  189. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  190. package/dist/index.d.ts +31 -8
  191. package/dist/index.d.ts.map +1 -1
  192. package/dist/index.mjs +258 -8
  193. package/dist/index.mjs.map +1 -1
  194. package/dist/inspection-types.d.ts +178 -3
  195. package/dist/inspection-types.d.ts.map +1 -1
  196. package/dist/instance-buffer-cache.d.ts +4 -4
  197. package/dist/instance-buffer-cache.d.ts.map +1 -1
  198. package/dist/instances.d.ts +49 -94
  199. package/dist/instances.d.ts.map +1 -1
  200. package/dist/internal.mjs +7 -7
  201. package/dist/pbr-pipeline.d.ts +19 -1
  202. package/dist/pbr-pipeline.d.ts.map +1 -1
  203. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  204. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  205. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  206. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  207. package/dist/pipeline/standard-output/types.d.ts +4 -2
  208. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  209. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  210. package/dist/pipeline/standard-post.d.ts +28 -19
  211. package/dist/pipeline/standard-post.d.ts.map +1 -1
  212. package/dist/pipeline-builder.d.ts +1 -1
  213. package/dist/pipeline-builder.d.ts.map +1 -1
  214. package/dist/pipeline-spec.d.ts +2 -2
  215. package/dist/plugin.d.ts.map +1 -1
  216. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  217. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  218. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  219. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  220. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  221. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  222. package/dist/record/fold-buckets.d.ts +95 -0
  223. package/dist/record/fold-buckets.d.ts.map +1 -0
  224. package/dist/record/fold-instance-buffer.d.ts +6 -0
  225. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  226. package/dist/record/frame-lighting.d.ts +1 -0
  227. package/dist/record/frame-lighting.d.ts.map +1 -1
  228. package/dist/record/frame-snapshot.d.ts +40 -3
  229. package/dist/record/frame-snapshot.d.ts.map +1 -1
  230. package/dist/record/frame-targets.d.ts.map +1 -1
  231. package/dist/record/frame.d.ts +14 -62
  232. package/dist/record/frame.d.ts.map +1 -1
  233. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  234. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  235. package/dist/record/gpu-timing.d.ts +8 -0
  236. package/dist/record/gpu-timing.d.ts.map +1 -1
  237. package/dist/record/main-pass-geometry.d.ts +21 -5
  238. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  239. package/dist/record/main-pass-material.d.ts +7 -1
  240. package/dist/record/main-pass-material.d.ts.map +1 -1
  241. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  242. package/dist/record/main-pass.d.ts +13 -2
  243. package/dist/record/main-pass.d.ts.map +1 -1
  244. package/dist/record/mesh-ssbo.d.ts +6 -5
  245. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  246. package/dist/record/motion-blur-receipt.d.ts +11 -0
  247. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  248. package/dist/record/probe-blend-buffer.d.ts +16 -0
  249. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  250. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  251. package/dist/record/render-context.d.ts +34 -31
  252. package/dist/record/render-context.d.ts.map +1 -1
  253. package/dist/record/shadow-pass.d.ts +2 -0
  254. package/dist/record/shadow-pass.d.ts.map +1 -1
  255. package/dist/record/skybox-post-pass.d.ts +6 -4
  256. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  257. package/dist/record/typed-frame-graph.d.ts +22 -2
  258. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  259. package/dist/record/view-ubo.d.ts +11 -3
  260. package/dist/record/view-ubo.d.ts.map +1 -1
  261. package/dist/record/volume-params.d.ts +9 -0
  262. package/dist/record/volume-params.d.ts.map +1 -0
  263. package/dist/recovery/render-system-candidate.d.ts +10 -0
  264. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  265. package/dist/reflection/record-owner.d.ts.map +1 -1
  266. package/dist/render-contract.d.ts +66 -8
  267. package/dist/render-contract.d.ts.map +1 -1
  268. package/dist/render-graph-primitives.d.ts.map +1 -1
  269. package/dist/render-pipeline.d.ts +106 -3
  270. package/dist/render-pipeline.d.ts.map +1 -1
  271. package/dist/render-system-extract-tail.d.ts +3 -2
  272. package/dist/render-system-extract-tail.d.ts.map +1 -1
  273. package/dist/render-system-extract.d.ts +24 -10
  274. package/dist/render-system-extract.d.ts.map +1 -1
  275. package/dist/render-system-presentation.d.ts +23 -0
  276. package/dist/render-system-presentation.d.ts.map +1 -0
  277. package/dist/render-system-producer-roots.d.ts +10 -0
  278. package/dist/render-system-producer-roots.d.ts.map +1 -0
  279. package/dist/render-system-residency.d.ts +12 -0
  280. package/dist/render-system-residency.d.ts.map +1 -0
  281. package/dist/render-system.d.ts +26 -15
  282. package/dist/render-system.d.ts.map +1 -1
  283. package/dist/scene/probe-blend.d.ts +27 -0
  284. package/dist/scene/probe-blend.d.ts.map +1 -1
  285. package/dist/scene/render-scene.d.ts +14 -5
  286. package/dist/scene/render-scene.d.ts.map +1 -1
  287. package/dist/ssao-buffers.d.ts +9 -0
  288. package/dist/ssao-buffers.d.ts.map +1 -1
  289. package/dist/surface/dynamic-input.d.ts +133 -0
  290. package/dist/surface/dynamic-input.d.ts.map +1 -0
  291. package/dist/surface/gpu-driven.d.ts +41 -0
  292. package/dist/surface/gpu-driven.d.ts.map +1 -0
  293. package/dist/surface/submission-observation.d.ts +136 -0
  294. package/dist/surface/submission-observation.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  296. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  297. package/dist/temporal/frame.d.ts +7 -0
  298. package/dist/temporal/frame.d.ts.map +1 -1
  299. package/dist/temporal/gpu.d.ts +13 -1
  300. package/dist/temporal/gpu.d.ts.map +1 -1
  301. package/dist/temporal/index.mjs +5 -5
  302. package/dist/temporal/inspection.d.ts.map +1 -1
  303. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  304. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  305. package/dist/temporal/view.d.ts +6 -1
  306. package/dist/temporal/view.d.ts.map +1 -1
  307. package/dist/transmission/single-layer-medium.d.ts +89 -0
  308. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  309. package/dist/typed-render-graph-primitives.d.ts +24 -9
  310. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  311. package/dist/volume/component.d.ts +9 -5
  312. package/dist/volume/component.d.ts.map +1 -1
  313. package/dist/volume/extract.d.ts +1 -1
  314. package/dist/volume/extract.d.ts.map +1 -1
  315. package/dist/volume/inspection.d.ts +2 -0
  316. package/dist/volume/inspection.d.ts.map +1 -1
  317. package/dist/volume/passes.d.ts +4 -1
  318. package/dist/volume/passes.d.ts.map +1 -1
  319. package/dist/volume/resources.d.ts.map +1 -1
  320. package/dist/volume/temporal.d.ts +3 -1
  321. package/dist/volume/temporal.d.ts.map +1 -1
  322. package/package.json +22 -21
  323. package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
  324. package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
  325. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  326. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  327. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  328. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  329. package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
  330. package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
  331. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  332. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  333. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  334. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  335. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
  336. package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
  337. package/src/__tests__/environment-selection.unit.test.ts +12 -0
  338. package/src/__tests__/factory-contract.integration.test.ts +626 -113
  339. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  340. package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
  341. package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
  342. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  343. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  344. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  345. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  346. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
  347. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  348. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
  349. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  350. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +7 -6
  351. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
  352. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
  353. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  354. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  355. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  356. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  357. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  358. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  359. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  360. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
  361. package/src/__tests__/gpu-scene.unit.test.ts +210 -9
  362. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  363. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  364. package/src/__tests__/instances-store.unit.test.ts +105 -238
  365. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  366. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
  367. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  368. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  369. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
  370. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  371. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  372. package/src/__tests__/motion-blur-compute.dawn.test.ts +589 -0
  373. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  374. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  375. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  376. package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
  377. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
  378. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  379. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
  380. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  381. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  382. package/src/__tests__/public-surface.test-d.ts +8 -0
  383. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  384. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  385. package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
  386. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  387. package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
  388. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  389. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  390. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
  391. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  392. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  393. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +37 -6
  394. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  395. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  396. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  397. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
  398. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  399. package/src/__tests__/renderer-frame-transaction.integration.test.ts +33 -11
  400. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  401. package/src/__tests__/shader-manifest-fixture.ts +4 -4
  402. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  403. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  404. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  405. package/src/__tests__/skinned-shadow-caster.test.ts +17 -0
  406. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  407. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  408. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  409. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  410. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  411. package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
  412. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  413. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  414. package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
  415. package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
  416. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  417. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  418. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  419. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  420. package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
  421. package/src/__tests__/temporal-view.unit.test.ts +2 -1
  422. package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
  423. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  424. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  425. package/src/__tests__/volume-optics-oracle.unit.test.ts +7 -3
  426. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
  427. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  428. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  429. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  430. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +558 -68
  431. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
  432. package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
  433. package/src/assembly/analytic-fog-registration.ts +14 -0
  434. package/src/assembly/backend-contract.ts +30 -0
  435. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  436. package/src/assembly/canvas-draw-guard.ts +11 -0
  437. package/src/assembly/cloud-shadow-entry.ts +22 -0
  438. package/src/assembly/dynamic-geometry-host.ts +65 -37
  439. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  440. package/src/assembly/factory.ts +2 -30
  441. package/src/assembly/fxaa-registration.ts +17 -0
  442. package/src/assembly/host-contract.ts +3 -3
  443. package/src/assembly/lod-observation.ts +12 -0
  444. package/src/assembly/material/assembly.ts +25 -13
  445. package/src/assembly/material/pipeline-helpers.ts +53 -12
  446. package/src/assembly/material-shader-policy.ts +55 -0
  447. package/src/assembly/material-shader-prewarm.ts +21 -10
  448. package/src/assembly/motion-blur-registration.ts +17 -0
  449. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  450. package/src/assembly/recovery/renderer-recover.ts +41 -18
  451. package/src/assembly/render-feature-post-processes.ts +54 -0
  452. package/src/assembly/renderer-facade.ts +6 -1
  453. package/src/assembly/renderer-feature-inspection.ts +8 -2
  454. package/src/assembly/renderer-frame-transaction.ts +23 -0
  455. package/src/assembly/renderer-inspection.ts +28 -0
  456. package/src/assembly/skin-palette-owner.ts +1 -1
  457. package/src/assembly/temporal-post-process-prewarm.ts +40 -0
  458. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  459. package/src/assembly/webgpu-ready-contract.ts +8 -3
  460. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  461. package/src/assembly/webgpu-ready.ts +296 -306
  462. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  463. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  464. package/src/assembly/webgpu-renderer.ts +228 -281
  465. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  466. package/src/barrel-distortion.ts +247 -0
  467. package/src/bloom-admission.ts +21 -0
  468. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  469. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  470. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  471. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  472. package/src/cloud/density.ts +600 -0
  473. package/src/cloud/extract.ts +110 -0
  474. package/src/cloud/feature.ts +1810 -0
  475. package/src/cloud/frame-context.ts +42 -0
  476. package/src/cloud/inspection.ts +130 -0
  477. package/src/cloud/optics.ts +285 -0
  478. package/src/cloud/parameters.ts +255 -0
  479. package/src/cloud/resources.ts +122 -0
  480. package/src/cloud/shadow.ts +167 -0
  481. package/src/cloud/temporal.ts +226 -0
  482. package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
  483. package/src/components/atmosphere.ts +4 -0
  484. package/src/components/barrel-distortion.ts +46 -0
  485. package/src/components/camera.ts +66 -10
  486. package/src/components/cloud-layer.ts +47 -0
  487. package/src/components/index.ts +2 -0
  488. package/src/components/instances.ts +18 -45
  489. package/src/components/mesh-filter.ts +11 -9
  490. package/src/components/motion-blur.ts +1 -0
  491. package/src/components/sprite-instances.ts +1 -1
  492. package/src/construct-renderer.ts +1 -1
  493. package/src/device/gpu-residency.ts +56 -12
  494. package/src/dynamic-geometry.ts +12 -1
  495. package/src/environment/analytic-fog.ts +44 -0
  496. package/src/environment/background.ts +2 -2
  497. package/src/errors/cloud.ts +103 -0
  498. package/src/errors/render.ts +58 -8
  499. package/src/examples/single-layer-medium-surface.ts +59 -0
  500. package/src/extract/camera.ts +35 -8
  501. package/src/extract/contracts.ts +12 -0
  502. package/src/extract/environment.ts +4 -0
  503. package/src/features/barrel-distortion.ts +172 -0
  504. package/src/features/error-reporting.ts +98 -0
  505. package/src/features/host.ts +138 -24
  506. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
  507. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
  508. package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
  509. package/src/features/motion-blur/motion-blur-params.ts +70 -2
  510. package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
  511. package/src/features/plan.ts +33 -8
  512. package/src/features/prepared-gpu-work.ts +86 -35
  513. package/src/features/render-graph-compute.ts +13 -5
  514. package/src/features/render-graph-contribution.ts +11 -0
  515. package/src/features/render-graph-raster.ts +45 -3
  516. package/src/features/targets.ts +66 -0
  517. package/src/features/types.ts +47 -0
  518. package/src/fullscreen-post-process-pass.ts +41 -9
  519. package/src/gpu-dirty-ranges.ts +48 -0
  520. package/src/gpu-driven/batch-topology.ts +53 -0
  521. package/src/gpu-driven/material-artifacts.ts +35 -32
  522. package/src/gpu-driven/prepared-draw.ts +27 -14
  523. package/src/gpu-driven/production-raster-material.ts +1894 -0
  524. package/src/gpu-driven/production-raster.ts +904 -787
  525. package/src/gpu-driven/resource-allocation.ts +142 -0
  526. package/src/gpu-driven/shadow-ownership.ts +71 -0
  527. package/src/gpu-driven/view-gpu.ts +181 -10
  528. package/src/gpu-scene.ts +259 -101
  529. package/src/hdrp-buffers.ts +4 -3
  530. package/src/ibl/skylight-bind-group.ts +49 -7
  531. package/src/index.ts +228 -9
  532. package/src/inspection-types.ts +222 -2
  533. package/src/instance-buffer-cache.ts +4 -4
  534. package/src/instances.ts +151 -492
  535. package/src/pbr-pipeline.ts +219 -13
  536. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  537. package/src/pipeline/standard-forward-lane.ts +313 -57
  538. package/src/pipeline/standard-output/graph.ts +8 -2
  539. package/src/pipeline/standard-output/types.ts +12 -1
  540. package/src/pipeline/standard-pipeline.ts +291 -18
  541. package/src/pipeline/standard-post.ts +397 -102
  542. package/src/pipeline-builder.ts +1 -1
  543. package/src/pipeline-spec.ts +5 -5
  544. package/src/plugin.ts +4 -0
  545. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  546. package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
  547. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  548. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  549. package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
  550. package/src/record/__tests__/temporal-payload.unit.test.ts +3 -2
  551. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  552. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  553. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  554. package/src/record/barrel-distortion-frame.ts +110 -0
  555. package/src/record/dynamic-geometry-consumption.ts +39 -9
  556. package/src/record/fold-buckets.ts +852 -0
  557. package/src/record/fold-instance-buffer.ts +51 -0
  558. package/src/record/frame-lighting.ts +36 -2
  559. package/src/record/frame-snapshot.ts +44 -4
  560. package/src/record/frame-targets.ts +10 -6
  561. package/src/record/frame.ts +373 -1099
  562. package/src/record/gpu-draw-receipts.ts +38 -0
  563. package/src/record/gpu-timing.ts +48 -5
  564. package/src/record/main-pass-geometry.ts +281 -83
  565. package/src/record/main-pass-material.ts +66 -4
  566. package/src/record/main-pass-sprite-draws.ts +13 -66
  567. package/src/record/main-pass.ts +156 -20
  568. package/src/record/mesh-ssbo.ts +43 -6
  569. package/src/record/motion-blur-receipt.ts +91 -0
  570. package/src/record/probe-blend-buffer.ts +180 -0
  571. package/src/record/recovery-pipeline.ts +35 -3
  572. package/src/record/render-context.ts +51 -31
  573. package/src/record/shadow-pass.ts +36 -2
  574. package/src/record/skybox-post-pass.ts +150 -200
  575. package/src/record/typed-frame-graph.ts +824 -44
  576. package/src/record/view-ubo.ts +26 -3
  577. package/src/record/volume-params.ts +225 -0
  578. package/src/recovery/render-system-candidate.ts +257 -52
  579. package/src/reflection/record-owner.ts +7 -3
  580. package/src/render-contract.ts +71 -8
  581. package/src/render-graph-primitives.ts +7 -1
  582. package/src/render-pipeline.ts +136 -1
  583. package/src/render-system-extract-tail.ts +72 -60
  584. package/src/render-system-extract.ts +117 -87
  585. package/src/render-system-presentation.ts +56 -0
  586. package/src/render-system-producer-roots.ts +96 -0
  587. package/src/render-system-residency.ts +159 -0
  588. package/src/render-system.ts +601 -482
  589. package/src/scene/probe-blend.ts +96 -4
  590. package/src/scene/render-scene.ts +431 -281
  591. package/src/ssao-buffers.ts +95 -2
  592. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  593. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  594. package/src/surface/dynamic-input.ts +658 -0
  595. package/src/surface/gpu-driven.ts +147 -0
  596. package/src/surface/submission-observation.ts +517 -0
  597. package/src/systems/skin-palette-allocator.ts +4 -1
  598. package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
  599. package/src/temporal/frame-coordinator.ts +8 -1
  600. package/src/temporal/frame.ts +20 -0
  601. package/src/temporal/gpu.ts +101 -17
  602. package/src/temporal/inspection.ts +7 -1
  603. package/src/temporal/standard-scene-data.ts +5 -0
  604. package/src/temporal/target-coverage-attachment.ts +4 -0
  605. package/src/temporal/view.ts +13 -2
  606. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  607. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  608. package/src/transmission/single-layer-medium.ts +322 -0
  609. package/src/typed-render-graph-primitives.ts +191 -50
  610. package/src/volume/component.ts +10 -10
  611. package/src/volume/extract.ts +11 -5
  612. package/src/volume/inspection.ts +3 -0
  613. package/src/volume/passes.ts +95 -8
  614. package/src/volume/resources.ts +2 -1
  615. package/src/volume/temporal.ts +11 -0
  616. package/dist/chunk-4NNZQCL3.mjs.map +0 -1
  617. package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
  618. package/dist/chunk-DRR7D3KX.mjs.map +0 -1
  619. package/dist/chunk-GWCEMDVR.mjs.map +0 -1
  620. package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
  621. package/dist/chunk-JRIPCMYC.mjs.map +0 -1
  622. package/dist/chunk-LULCA3OF.mjs +0 -1713
  623. package/dist/chunk-LULCA3OF.mjs.map +0 -1
  624. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
@@ -0,0 +1,142 @@
1
+ import type { GpuResourceAllocationInspection } from '../inspection-types';
2
+
3
+ export interface GpuResourceAllocationToken {
4
+ readonly id: number;
5
+ readonly bytes: number;
6
+ }
7
+
8
+ /**
9
+ * Tracks logical Engine allocation ownership independently of physical GPU
10
+ * residency. A replacement is live and pending at the same time until the
11
+ * queue fence releases the old generation.
12
+ */
13
+ export class GpuResourceAllocationLedger {
14
+ private nextId = 1;
15
+ private readonly live = new Map<number, number>();
16
+ private readonly pending = new Map<number, number>();
17
+ private liveBytes = 0;
18
+ private pendingBytes = 0;
19
+ private peakBytes = 0;
20
+ private successfulAllocationCount = 0;
21
+ private successfulAllocationBytes = 0;
22
+ private retiredBytes = 0;
23
+ private failedAllocationRollbacks = 0;
24
+ private failedAllocationRollbackBytes = 0;
25
+
26
+ allocate(bytes: number): GpuResourceAllocationToken {
27
+ if (!Number.isFinite(bytes) || bytes < 0) {
28
+ throw new RangeError(`GPU allocation bytes must be finite and non-negative (got ${bytes})`);
29
+ }
30
+ const token = { id: this.nextId++, bytes };
31
+ this.live.set(token.id, token.bytes);
32
+ this.liveBytes += token.bytes;
33
+ this.successfulAllocationCount += 1;
34
+ this.successfulAllocationBytes += token.bytes;
35
+ this.updatePeak();
36
+ return token;
37
+ }
38
+
39
+ retire(token: GpuResourceAllocationToken): void {
40
+ const bytes = this.live.get(token.id);
41
+ if (bytes === undefined) return;
42
+ this.live.delete(token.id);
43
+ this.liveBytes -= bytes;
44
+ this.pending.set(token.id, bytes);
45
+ this.pendingBytes += bytes;
46
+ this.updatePeak();
47
+ }
48
+
49
+ release(token: GpuResourceAllocationToken): void {
50
+ const pendingBytes = this.pending.get(token.id);
51
+ if (pendingBytes !== undefined) {
52
+ this.pending.delete(token.id);
53
+ this.pendingBytes -= pendingBytes;
54
+ this.retiredBytes += pendingBytes;
55
+ return;
56
+ }
57
+ const liveBytes = this.live.get(token.id);
58
+ if (liveBytes !== undefined) {
59
+ this.live.delete(token.id);
60
+ this.liveBytes -= liveBytes;
61
+ this.retiredBytes += liveBytes;
62
+ }
63
+ }
64
+
65
+ rollback(token: GpuResourceAllocationToken): void {
66
+ const bytes = this.live.get(token.id);
67
+ if (bytes === undefined) return;
68
+ this.live.delete(token.id);
69
+ this.liveBytes -= bytes;
70
+ this.failedAllocationRollbacks += 1;
71
+ this.failedAllocationRollbackBytes += bytes;
72
+ }
73
+
74
+ inspect(): GpuResourceAllocationInspection {
75
+ return {
76
+ unit: 'engine-allocation-bytes',
77
+ physicalResidency: 'unknown',
78
+ liveBytes: this.liveBytes,
79
+ pendingRetirementBytes: this.pendingBytes,
80
+ peakBytes: this.peakBytes,
81
+ successfulAllocationCount: this.successfulAllocationCount,
82
+ successfulAllocationBytes: this.successfulAllocationBytes,
83
+ pendingRetirementCount: this.pending.size,
84
+ retiredBytes: this.retiredBytes,
85
+ failedAllocationRollbacks: this.failedAllocationRollbacks,
86
+ failedAllocationRollbackBytes: this.failedAllocationRollbackBytes,
87
+ };
88
+ }
89
+
90
+ private updatePeak(): void {
91
+ this.peakBytes = Math.max(this.peakBytes, this.liveBytes + this.pendingBytes);
92
+ }
93
+ }
94
+
95
+ export function combineGpuResourceAllocationInspections(
96
+ inspections: readonly GpuResourceAllocationInspection[],
97
+ ): GpuResourceAllocationInspection | undefined {
98
+ if (inspections.length === 0) return undefined;
99
+ const liveBytes = inspections.reduce((sum, value) => sum + value.liveBytes, 0);
100
+ const pendingRetirementBytes = inspections.reduce(
101
+ (sum, value) => sum + value.pendingRetirementBytes,
102
+ 0,
103
+ );
104
+ // Each owner reports its own historical high-water mark. Adding those
105
+ // marks invents overlap between replacements that happened at different
106
+ // times. The aggregate can prove the current simultaneous occupancy, or
107
+ // retain the largest owner-local mark as a conservative lower-bound fact
108
+ // when all resources have since retired; it cannot claim their historical
109
+ // sum without an event-time aggregate owner.
110
+ const peakBytes = Math.max(
111
+ liveBytes + pendingRetirementBytes,
112
+ ...inspections.map((value) => value.peakBytes),
113
+ );
114
+ return {
115
+ unit: 'engine-allocation-bytes',
116
+ physicalResidency: 'unknown',
117
+ liveBytes,
118
+ pendingRetirementBytes,
119
+ peakBytes,
120
+ successfulAllocationCount: inspections.reduce(
121
+ (sum, value) => sum + value.successfulAllocationCount,
122
+ 0,
123
+ ),
124
+ successfulAllocationBytes: inspections.reduce(
125
+ (sum, value) => sum + value.successfulAllocationBytes,
126
+ 0,
127
+ ),
128
+ pendingRetirementCount: inspections.reduce(
129
+ (sum, value) => sum + value.pendingRetirementCount,
130
+ 0,
131
+ ),
132
+ retiredBytes: inspections.reduce((sum, value) => sum + value.retiredBytes, 0),
133
+ failedAllocationRollbacks: inspections.reduce(
134
+ (sum, value) => sum + value.failedAllocationRollbacks,
135
+ 0,
136
+ ),
137
+ failedAllocationRollbackBytes: inspections.reduce(
138
+ (sum, value) => sum + value.failedAllocationRollbackBytes,
139
+ 0,
140
+ ),
141
+ };
142
+ }
@@ -0,0 +1,71 @@
1
+ import type { World } from '@forgeax/engine-ecs';
2
+ import { gpuDrivenShadowDrawKey } from '../extract/gpu-driven';
3
+ import { worldEntityKey } from '../record/frame-snapshot';
4
+ import type { ShadowCasterMembership } from '../render-system-extract';
5
+
6
+ const WORLD_ENTITY_KEY_STRIDE = 4294967296;
7
+
8
+ /**
9
+ * Extract emits world/entity keys in the transient `worlds[]` index domain,
10
+ * while PersistentRenderScene owns stable renderer-local World keys for the
11
+ * retained GPU scene. Rebase ShadowCaster ownership at this orchestration
12
+ * boundary before both GPU projection and CPU residual recording consume it.
13
+ */
14
+ export function rebaseShadowCasterOwnership(
15
+ worlds: readonly World[],
16
+ stableWorldKeys: readonly number[],
17
+ entityKeys: ReadonlySet<number>,
18
+ drawKeys: ReadonlySet<string>,
19
+ membership: readonly ShadowCasterMembership[] | undefined,
20
+ ): {
21
+ readonly entityKeys: ReadonlySet<number>;
22
+ readonly drawKeys: ReadonlySet<string>;
23
+ readonly membership: readonly ShadowCasterMembership[] | undefined;
24
+ } {
25
+ const rebaseWorldEntity = (composite: number): number => {
26
+ const transientWorldId = Math.floor(composite / WORLD_ENTITY_KEY_STRIDE);
27
+ if (
28
+ !Number.isInteger(transientWorldId) ||
29
+ transientWorldId < 0 ||
30
+ transientWorldId >= worlds.length
31
+ ) {
32
+ return composite;
33
+ }
34
+ const entityKey = composite - transientWorldId * WORLD_ENTITY_KEY_STRIDE;
35
+ return worldEntityKey(stableWorldKeys[transientWorldId] ?? transientWorldId, entityKey);
36
+ };
37
+
38
+ const stableMembership =
39
+ membership === undefined
40
+ ? undefined
41
+ : membership.map((entry) => ({
42
+ ...entry,
43
+ worldEntity: rebaseWorldEntity(entry.worldEntity),
44
+ }));
45
+ const stableDrawKeys =
46
+ stableMembership === undefined
47
+ ? new Set(
48
+ [...drawKeys].map((key) => {
49
+ const parts = key.split(':');
50
+ if (parts.length !== 4) return key;
51
+ const transientWorldEntity = Number(parts[0]);
52
+ if (!Number.isFinite(transientWorldEntity)) return key;
53
+ return `${rebaseWorldEntity(transientWorldEntity)}:${parts[1]}:${parts[2]}:${parts[3]}`;
54
+ }),
55
+ )
56
+ : new Set(
57
+ stableMembership.map((entry) =>
58
+ gpuDrivenShadowDrawKey(
59
+ entry.worldEntity,
60
+ entry.materialHandle,
61
+ entry.drawItemIndex,
62
+ entry.passIndex,
63
+ ),
64
+ ),
65
+ );
66
+ return {
67
+ entityKeys: new Set([...entityKeys].map(rebaseWorldEntity)),
68
+ drawKeys: stableDrawKeys,
69
+ membership: stableMembership,
70
+ };
71
+ }
@@ -25,8 +25,20 @@ import {
25
25
  GPU_BUFFER_USAGE_UNIFORM,
26
26
  } from '../gpu-usage';
27
27
  import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
28
+ import { getOpaqueResourceIdentity } from '../record/frame-snapshot';
29
+ import type {
30
+ SurfaceGpuIndirectParameters,
31
+ SurfaceGpuIndirectReadbackError,
32
+ SurfaceGpuReadbackSnapshot,
33
+ SurfaceSubmissionCandidate,
34
+ } from '../surface/submission-observation';
35
+ import { decodeSurfaceIndirectParameters } from '../surface/submission-observation';
28
36
  import type { GpuDrivenCandidate, SubmissionPlan } from './batch-topology';
29
37
  import { GPU_DRIVEN_SKIN_FLAG } from './batch-topology';
38
+ import {
39
+ GpuResourceAllocationLedger,
40
+ type GpuResourceAllocationToken,
41
+ } from './resource-allocation';
30
42
 
31
43
  const COMPUTE_STAGE = 0x4;
32
44
  const WORKGROUP_SIZE = 64;
@@ -43,6 +55,7 @@ const COUNTER_WORDS = 2 + LOD_ROW_CAPACITY + 2;
43
55
  const GEOMETRY_WORK_COUNTER_OFFSET = 2 + LOD_ROW_CAPACITY;
44
56
  const ROOT_GEOMETRY_WORK_COUNTER_OFFSET = GEOMETRY_WORK_COUNTER_OFFSET + 1;
45
57
  const COUNTER_STRIDE = COUNTER_WORDS * 4;
58
+ const INDIRECT_COMMAND_BYTES = 20;
46
59
  type GpuDrivenAdmissionCandidate = GpuDrivenCandidate & {
47
60
  readonly submitAdmission?: boolean;
48
61
  };
@@ -168,7 +181,7 @@ fn selectLodLevel(
168
181
  @group(0) @binding(4) var<storage, read> batches: array<BatchRecord>;
169
182
  @group(0) @binding(5) var<uniform> view: ViewConstants;
170
183
  @group(0) @binding(6) var<storage, read_write> counters: array<atomic<u32>>;
171
- @group(0) @binding(7) var<storage, read_write> visibleIndices: array<vec2<u32>>;
184
+ @group(0) @binding(7) var<storage, read_write> visibleIndices: array<vec4<u32>>;
172
185
  @group(0) @binding(8) var<storage, read_write> indirectArgs: array<u32>;
173
186
 
174
187
  fn counterIndex(batchIndex: u32) -> u32 { return batchIndex * ${COUNTER_WORDS}u; }
@@ -253,9 +266,11 @@ fn cullView(@builtin(global_invocation_id) id: vec3<u32>) {
253
266
  if ((candidate.materialSlot & 0x80000000u) != 0u) {
254
267
  materialOrPalette = instance.customDataStart;
255
268
  }
256
- visibleIndices[candidate.visibleBase + localVisible] = vec2<u32>(
269
+ visibleIndices[candidate.visibleBase + localVisible] = vec4<u32>(
257
270
  candidate.submitAdmission >> 1u,
258
271
  materialOrPalette,
272
+ candidate.primitiveIndex + 1u,
273
+ candidate.generation,
259
274
  );
260
275
  }
261
276
 
@@ -278,10 +293,22 @@ fn finalizeView(@builtin(global_invocation_id) id: vec3<u32>) {
278
293
  let candidate = candidates[batch.candidateBase];
279
294
  let selectedLod = selectLodLevel(candidate.projectedHeight, candidate.previousLevel, candidate.historyValid != 0u, candidate.lodRows, candidate.lodCount);
280
295
  let lod = candidate.lodRows[selectedLod];
281
- indirectArgs[args] = select(batch.count, lod.indexCount, candidate.lodCount > 0u);
296
+ var drawCount = batch.count;
297
+ var drawFirst = batch.first;
298
+ var drawBaseVertex: i32 = 0;
299
+ if (candidate.lodCount > 0u) {
300
+ drawCount = lod.indexCount;
301
+ if (batch.indexed != 0u) {
302
+ drawFirst = lod.firstIndex;
303
+ drawBaseVertex = lod.baseVertex;
304
+ }
305
+ } else if (batch.indexed != 0u) {
306
+ drawBaseVertex = batch.baseVertex;
307
+ }
308
+ indirectArgs[args] = drawCount;
282
309
  indirectArgs[args + 1u] = visibleCount;
283
- indirectArgs[args + 2u] = select(batch.first, lod.firstIndex, candidate.lodCount > 0u && batch.indexed != 0u);
284
- indirectArgs[args + 3u] = select(0u, bitcast<u32>(lod.baseVertex), candidate.lodCount > 0u && batch.indexed != 0u);
310
+ indirectArgs[args + 2u] = drawFirst;
311
+ indirectArgs[args + 3u] = bitcast<u32>(drawBaseVertex);
285
312
  indirectArgs[args + 4u] = 0u;
286
313
  }
287
314
  `;
@@ -302,8 +329,17 @@ type LodTelemetryCopy = {
302
329
  readonly buffers: ViewBuffers;
303
330
  readonly plan: SubmissionPlan;
304
331
  readonly resourceGeneration: number;
332
+ readonly indirectBufferIdentity: number;
333
+ readonly indirectReadbackOffset: number;
334
+ readonly surfaceReadbackSnapshot?: () => SurfaceGpuReadbackSnapshot | undefined;
335
+ readonly submit?: GpuDrivenLodSubmitIdentity;
305
336
  };
306
337
 
338
+ export interface GpuDrivenLodSubmitIdentity {
339
+ readonly frameId: number;
340
+ readonly deviceGeneration: number;
341
+ }
342
+
307
343
  export interface GpuDrivenViewGraphResources {
308
344
  readonly primitive: GraphBuffer;
309
345
  readonly instance: GraphBuffer;
@@ -332,6 +368,8 @@ export interface GpuDrivenViewInspection {
332
368
  readonly bindGroupCreates: number;
333
369
  readonly bufferRebuilds: number;
334
370
  readonly resourceGeneration: number;
371
+ /** Logical Engine allocation facts; physical VRAM residency is unknown. */
372
+ readonly resourceAllocation: import('../inspection-types').GpuResourceAllocationInspection;
335
373
  }
336
374
 
337
375
  export interface GpuDrivenViewBufferCapacities {
@@ -342,6 +380,8 @@ export interface GpuDrivenViewBufferCapacities {
342
380
  }
343
381
 
344
382
  export interface GpuDrivenLodSelectionInspection {
383
+ /** Exact resource generation whose selector rows were copied. */
384
+ readonly resourceGeneration?: number;
345
385
  readonly candidateCount: number;
346
386
  readonly batchCount: number;
347
387
  readonly indirectDrawCount: number;
@@ -369,6 +409,24 @@ export interface GpuDrivenLodSelectionInspection {
369
409
  }[];
370
410
  readonly geometryWork: number;
371
411
  readonly rootGeometryWork: number;
412
+ /** Actual visible rows copied from the submitted GPU selector. */
413
+ readonly actualMembers: readonly {
414
+ readonly batchId: number;
415
+ readonly primitiveIndex: number;
416
+ readonly generation: number;
417
+ readonly drawItemIndex: number;
418
+ readonly instanceOrdinal: number;
419
+ }[];
420
+ /** Surface subset projected by the material producer after readback. */
421
+ readonly surfaceActualMemberIds?: readonly string[];
422
+ /** Decoded indexed/non-indexed command words for the exact Surface copy. */
423
+ readonly surfaceIndirectParameters?: readonly SurfaceGpuIndirectParameters[];
424
+ /** Fail-closed readback reason when the copied command range is unusable. */
425
+ readonly surfaceIndirectReadbackError?: SurfaceGpuIndirectReadbackError;
426
+ /** Exact Surface recording whose selector bytes were copied. */
427
+ readonly surfaceReadback?: SurfaceGpuReadbackSnapshot;
428
+ /** Public receipt identity captured when the telemetry copy was encoded. */
429
+ readonly submit?: GpuDrivenLodSubmitIdentity;
372
430
  }
373
431
 
374
432
  function nextCapacity(required: number): number {
@@ -429,8 +487,12 @@ export class GpuDrivenView {
429
487
  private bindGroupCreates = 0;
430
488
  private bufferRebuilds = 0;
431
489
  private resourceGeneration = 0;
490
+ private readonly allocationLedger = new GpuResourceAllocationLedger();
491
+ private readonly allocationTokens = new WeakMap<Buffer, GpuResourceAllocationToken>();
432
492
  /** The last readback copy that was actually encoded and is not consumed. */
433
493
  private telemetryPending: LodTelemetryCopy | undefined;
494
+ /** Receipt identity for the copy pass encoded by the current frame. */
495
+ private telemetrySubmit: GpuDrivenLodSubmitIdentity | undefined;
434
496
  /** Coalesce observers while the readback buffer is map-pending. */
435
497
  private lodSelectionReadback:
436
498
  | {
@@ -449,6 +511,10 @@ export class GpuDrivenView {
449
511
  private readonly labelPrefix: string,
450
512
  ) {}
451
513
 
514
+ setTelemetrySubmit(identity: GpuDrivenLodSubmitIdentity | undefined): void {
515
+ this.telemetrySubmit = identity;
516
+ }
517
+
452
518
  static create(input: {
453
519
  readonly device: RhiDevice;
454
520
  readonly shaderModuleFactory: PipelineBuilderShaderModuleFactory;
@@ -706,6 +772,7 @@ export class GpuDrivenView {
706
772
  bindGroupCreates: this.bindGroupCreates,
707
773
  bufferRebuilds: this.bufferRebuilds,
708
774
  resourceGeneration: this.resourceGeneration,
775
+ resourceAllocation: this.allocationLedger.inspect(),
709
776
  };
710
777
  }
711
778
 
@@ -770,6 +837,13 @@ export class GpuDrivenView {
770
837
  let overflow = false;
771
838
  let geometryWork = 0;
772
839
  let rootGeometryWork = 0;
840
+ const actualMembers: Array<{
841
+ readonly batchId: number;
842
+ readonly primitiveIndex: number;
843
+ readonly generation: number;
844
+ readonly drawItemIndex: number;
845
+ readonly instanceOrdinal: number;
846
+ }> = [];
773
847
  const histogram = new Map<number, number>();
774
848
  for (let batchIndex = 0; batchIndex < plan.batches.length; batchIndex += 1) {
775
849
  const offset = batchIndex * COUNTER_STRIDE;
@@ -780,6 +854,33 @@ export class GpuDrivenView {
780
854
  values.getUint32(offset, true),
781
855
  plan.batches[batchIndex]?.visibleCapacity ?? 0,
782
856
  );
857
+ const batch = plan.batches[batchIndex];
858
+ const admitted =
859
+ batch?.candidates.filter(
860
+ (candidate) => (candidate as GpuDrivenAdmissionCandidate).submitAdmission !== false,
861
+ ) ?? [];
862
+ for (let visibleIndex = 0; visibleIndex < batchVisible; visibleIndex += 1) {
863
+ const visibleOffset =
864
+ this.batchCapacity * COUNTER_STRIDE + ((batch?.visibleBase ?? 0) + visibleIndex) * 16;
865
+ const projectionIndex = values.getUint32(visibleOffset, true);
866
+ const primitiveIndex = values.getUint32(visibleOffset + 8, true) - 1;
867
+ const generation = values.getUint32(visibleOffset + 12, true);
868
+ const candidate = admitted[projectionIndex];
869
+ if (
870
+ batch !== undefined &&
871
+ candidate !== undefined &&
872
+ candidate.primitiveIndex === primitiveIndex &&
873
+ candidate.generation === generation
874
+ ) {
875
+ actualMembers.push({
876
+ batchId: batch.batchId,
877
+ primitiveIndex,
878
+ generation,
879
+ drawItemIndex: candidate.drawItemIndex,
880
+ instanceOrdinal: candidate.instanceOrdinal,
881
+ });
882
+ }
883
+ }
783
884
  visible += batchVisible;
784
885
  overflow ||= batchOverflow;
785
886
  geometryWork += values.getUint32(offset + GEOMETRY_WORK_COUNTER_OFFSET * 4, true);
@@ -800,7 +901,19 @@ export class GpuDrivenView {
800
901
  return undefined;
801
902
  }
802
903
  const candidateCount = plan.candidateCount;
904
+ const surfaceReadback = copy.surfaceReadbackSnapshot?.();
905
+ const surfaceIndirectReadback =
906
+ surfaceReadback === undefined
907
+ ? undefined
908
+ : decodeSurfaceIndirectParameters({
909
+ bytes: range.value,
910
+ byteOffset: copy.indirectReadbackOffset,
911
+ byteLength: this.indirectCapacity * INDIRECT_COMMAND_BYTES,
912
+ indirectBufferIdentity: copy.indirectBufferIdentity,
913
+ recording: surfaceReadback,
914
+ });
803
915
  this.lodSelection = Object.freeze({
916
+ resourceGeneration: copy.resourceGeneration,
804
917
  candidateCount,
805
918
  batchCount: plan.batches.length,
806
919
  // Selector-only batches remain in the plan/readback but the production
@@ -848,6 +961,14 @@ export class GpuDrivenView {
848
961
  ),
849
962
  geometryWork,
850
963
  rootGeometryWork,
964
+ actualMembers: Object.freeze(actualMembers),
965
+ ...(surfaceReadback === undefined ? {} : { surfaceReadback }),
966
+ ...(surfaceIndirectReadback === undefined
967
+ ? {}
968
+ : surfaceIndirectReadback.ok
969
+ ? { surfaceIndirectParameters: surfaceIndirectReadback.value }
970
+ : { surfaceIndirectReadbackError: surfaceIndirectReadback.error }),
971
+ ...(copy.submit === undefined ? {} : { submit: copy.submit }),
851
972
  });
852
973
  this.telemetryPending = undefined;
853
974
  return this.lodSelection;
@@ -860,6 +981,7 @@ export class GpuDrivenView {
860
981
  builder: RenderGraphBuilder<FrameCtx>,
861
982
  labelPrefix = 'gpu-driven',
862
983
  includeCompute = true,
984
+ surfaceSubmissionObservation?: () => SurfaceSubmissionCandidate | undefined,
863
985
  ): Result<GpuDrivenViewGraphResources, RenderGraphError> {
864
986
  const buffers = this.buffers;
865
987
  const bindGroup = this.bindGroup;
@@ -941,14 +1063,16 @@ export class GpuDrivenView {
941
1063
  const lodReadback = importBuffer(
942
1064
  `${labelPrefix}.lod-selection-readback`,
943
1065
  buffers.lodReadback,
944
- this.batchCapacity * COUNTER_STRIDE,
1066
+ this.batchCapacity * COUNTER_STRIDE +
1067
+ this.visibleBufferCapacity * 16 +
1068
+ this.indirectCapacity * INDIRECT_COMMAND_BYTES,
945
1069
  GPU_BUFFER_USAGE_MAP_READ | GPU_BUFFER_USAGE_COPY_DST,
946
1070
  );
947
1071
  if (!lodReadback.ok) return lodReadback;
948
1072
  const visible = importBuffer(
949
1073
  `${labelPrefix}.visible`,
950
1074
  buffers.visible,
951
- this.visibleBufferCapacity * 8,
1075
+ this.visibleBufferCapacity * 16,
952
1076
  GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_SRC,
953
1077
  );
954
1078
  if (!visible.ok) return visible;
@@ -1014,9 +1138,14 @@ export class GpuDrivenView {
1014
1138
  });
1015
1139
  if (!finalize.ok) return finalize;
1016
1140
  const graphResourceGeneration = this.resourceGeneration;
1141
+ const indirectReadbackOffset =
1142
+ this.batchCapacity * COUNTER_STRIDE + this.visibleBufferCapacity * 16;
1143
+ const indirectBufferIdentity = getOpaqueResourceIdentity(buffers.indirect as object);
1017
1144
  const readback = builder.addCopyPass(`${labelPrefix}.lod-selection-readback`, {
1018
1145
  accesses: [
1019
1146
  { resource: counters.value, usage: 'copy-src' },
1147
+ { resource: visible.value, usage: 'copy-src' },
1148
+ { resource: indirect.value, usage: 'copy-src' },
1020
1149
  { resource: lodReadback.value, usage: 'copy-dst' },
1021
1150
  ],
1022
1151
  encode: ({ encoder, resources }) => {
@@ -1032,6 +1161,20 @@ export class GpuDrivenView {
1032
1161
  resources.buffer(lodReadback.value).unwrap(),
1033
1162
  this.batchCapacity * COUNTER_STRIDE,
1034
1163
  );
1164
+ encoder.copyBufferToBuffer(
1165
+ resources.buffer(visible.value).unwrap(),
1166
+ 0,
1167
+ resources.buffer(lodReadback.value).unwrap(),
1168
+ this.batchCapacity * COUNTER_STRIDE,
1169
+ this.visibleBufferCapacity * 16,
1170
+ );
1171
+ encoder.copyBufferToBuffer(
1172
+ resources.buffer(indirect.value).unwrap(),
1173
+ 0,
1174
+ resources.buffer(lodReadback.value).unwrap(),
1175
+ indirectReadbackOffset,
1176
+ this.indirectCapacity * INDIRECT_COMMAND_BYTES,
1177
+ );
1035
1178
  // The render graph is cached across camera-only LOD projection
1036
1179
  // changes. The pass closure therefore retains the graph-generation
1037
1180
  // plan while `this.plan` carries the plan uploaded for the frame that
@@ -1044,10 +1187,19 @@ export class GpuDrivenView {
1044
1187
  submittedPlan !== undefined &&
1045
1188
  this.resourceGeneration === graphResourceGeneration
1046
1189
  ) {
1190
+ const submittedObservation = surfaceSubmissionObservation?.();
1047
1191
  this.telemetryPending = {
1048
1192
  buffers,
1049
1193
  plan: submittedPlan,
1050
1194
  resourceGeneration: graphResourceGeneration,
1195
+ indirectBufferIdentity,
1196
+ indirectReadbackOffset,
1197
+ ...(submittedObservation === undefined
1198
+ ? {}
1199
+ : {
1200
+ surfaceReadbackSnapshot: () => submittedObservation.gpuReadbackSnapshot(),
1201
+ }),
1202
+ ...(this.telemetrySubmit === undefined ? {} : { submit: this.telemetrySubmit }),
1051
1203
  };
1052
1204
  }
1053
1205
  },
@@ -1080,8 +1232,10 @@ export class GpuDrivenView {
1080
1232
  this.sceneMaterial = undefined;
1081
1233
  this.sceneCapacity = 0;
1082
1234
  this.telemetryPending = undefined;
1235
+ this.telemetrySubmit = undefined;
1083
1236
  this.lodSelectionReadback = undefined;
1084
1237
  this.lodSelection = undefined;
1238
+ for (const generation of buffers) this.retireGeneration(generation);
1085
1239
  this.destroyAfterSubmittedWork(buffers);
1086
1240
  void this.pipelineLayout;
1087
1241
  }
@@ -1126,6 +1280,7 @@ export class GpuDrivenView {
1126
1280
  const nextBatch = nextCapacity(batchCapacity);
1127
1281
  const nextIndirect = nextCapacity(indirectCapacity);
1128
1282
  const created: Partial<MutableViewBuffers> = {};
1283
+ const createdTokens: GpuResourceAllocationToken[] = [];
1129
1284
  const allocate = (
1130
1285
  name: keyof ViewBuffers,
1131
1286
  size: number,
@@ -1139,6 +1294,9 @@ export class GpuDrivenView {
1139
1294
  });
1140
1295
  if (!buffer.ok) return buffer;
1141
1296
  created[name] = buffer.value;
1297
+ const token = this.allocationLedger.allocate(size);
1298
+ this.allocationTokens.set(buffer.value, token);
1299
+ createdTokens.push(token);
1142
1300
  return ok(undefined);
1143
1301
  };
1144
1302
  const storage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_SRC;
@@ -1167,7 +1325,7 @@ export class GpuDrivenView {
1167
1325
  storage: false,
1168
1326
  },
1169
1327
  { name: 'counters', size: nextBatch * COUNTER_STRIDE, usage: storage, storage: true },
1170
- { name: 'visible', size: nextVisible * 8, usage: storage, storage: true },
1328
+ { name: 'visible', size: nextVisible * 16, usage: storage, storage: true },
1171
1329
  {
1172
1330
  name: 'indirect',
1173
1331
  size: nextIndirect * 20,
@@ -1176,7 +1334,7 @@ export class GpuDrivenView {
1176
1334
  },
1177
1335
  {
1178
1336
  name: 'lodReadback',
1179
- size: nextBatch * COUNTER_STRIDE,
1337
+ size: nextBatch * COUNTER_STRIDE + nextVisible * 16 + nextIndirect * INDIRECT_COMMAND_BYTES,
1180
1338
  usage: GPU_BUFFER_USAGE_MAP_READ | GPU_BUFFER_USAGE_COPY_DST,
1181
1339
  storage: false,
1182
1340
  },
@@ -1202,10 +1360,14 @@ export class GpuDrivenView {
1202
1360
  const result = allocate(request.name, request.size, request.usage);
1203
1361
  if (!result.ok) {
1204
1362
  for (const buffer of Object.values(created)) this.device.destroyBuffer(buffer);
1363
+ for (const token of createdTokens) this.allocationLedger.rollback(token);
1205
1364
  return result;
1206
1365
  }
1207
1366
  }
1208
- if (this.buffers !== undefined) this.supersededBuffers.push(this.buffers);
1367
+ if (this.buffers !== undefined) {
1368
+ this.supersededBuffers.push(this.buffers);
1369
+ this.retireGeneration(this.buffers);
1370
+ }
1209
1371
  this.buffers = created as ViewBuffers;
1210
1372
  this.candidateCapacity = nextCandidate;
1211
1373
  this.visibleBufferCapacity = nextVisible;
@@ -1223,10 +1385,19 @@ export class GpuDrivenView {
1223
1385
  for (const buffers of generations) {
1224
1386
  for (const buffer of Object.values(buffers)) {
1225
1387
  this.device.destroyBuffer(buffer);
1388
+ const token = this.allocationTokens.get(buffer);
1389
+ if (token !== undefined) this.allocationLedger.release(token);
1226
1390
  }
1227
1391
  }
1228
1392
  };
1229
1393
  void this.device.queue.onSubmittedWorkDone().then(release, release);
1230
1394
  }
1395
+
1396
+ private retireGeneration(generation: ViewBuffers): void {
1397
+ for (const buffer of Object.values(generation)) {
1398
+ const token = this.allocationTokens.get(buffer);
1399
+ if (token !== undefined) this.allocationLedger.retire(token);
1400
+ }
1401
+ }
1231
1402
  }
1232
1403
  export { decideVisibility } from '../scene/visibility/occlusion-confidence';