@forgeax/engine-render 0.1.33 → 0.1.35

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 +1062 -127
  2. package/dist/assembly/backend-contract.d.ts +2 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  5. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  6. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  7. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  8. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  9. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  10. package/dist/assembly/device-feature-admission.d.ts +2 -2
  11. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  12. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  13. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  14. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  15. package/dist/assembly/factory.d.ts +1 -1
  16. package/dist/assembly/factory.d.ts.map +1 -1
  17. package/dist/assembly/host-contract.d.ts +6 -5
  18. package/dist/assembly/host-contract.d.ts.map +1 -1
  19. package/dist/assembly/material/assembly.d.ts.map +1 -1
  20. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  21. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  22. package/dist/assembly/material-shader-policy.d.ts +16 -2
  23. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  24. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  25. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  26. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  27. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  28. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  29. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  30. package/dist/assembly/render-target-host.d.ts +5 -0
  31. package/dist/assembly/render-target-host.d.ts.map +1 -1
  32. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  33. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  34. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  35. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  36. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  37. package/dist/assembly/renderer-inspection.d.ts +11 -0
  38. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  39. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  40. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  41. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  42. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  43. package/dist/assembly/webgpu-ready.d.ts +1 -1
  44. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  45. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  46. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  47. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  48. package/dist/assembly/webgpu-renderer.d.ts +2 -1
  49. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  50. package/dist/authoring.mjs +2 -4
  51. package/dist/authoring.mjs.map +1 -1
  52. package/dist/barrel-distortion.d.ts +47 -0
  53. package/dist/barrel-distortion.d.ts.map +1 -0
  54. package/dist/chunk-3XUBWRY2.mjs +1842 -0
  55. package/dist/chunk-3XUBWRY2.mjs.map +1 -0
  56. package/dist/{chunk-OO3DRYK7.mjs → chunk-G6HDNGY7.mjs} +2400 -1767
  57. package/dist/chunk-G6HDNGY7.mjs.map +1 -0
  58. package/dist/{chunk-ZDQWGQW7.mjs → chunk-LM5IE7GF.mjs} +4 -4
  59. package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
  60. package/dist/{chunk-VOZWDM3L.mjs → chunk-LNIUIKQ7.mjs} +1514 -498
  61. package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
  62. package/dist/chunk-MXTWKZO4.mjs +3268 -0
  63. package/dist/chunk-MXTWKZO4.mjs.map +1 -0
  64. package/dist/chunk-MZ4C7EHF.mjs +6942 -0
  65. package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
  66. package/dist/chunk-RIPAEGI6.mjs +48 -0
  67. package/dist/chunk-RIPAEGI6.mjs.map +1 -0
  68. package/dist/{chunk-LEAXOMYJ.mjs → chunk-SGPUJW3F.mjs} +117 -5
  69. package/dist/chunk-SGPUJW3F.mjs.map +1 -0
  70. package/dist/{chunk-PA5DRJNI.mjs → chunk-X2KA6WHM.mjs} +29 -4
  71. package/dist/chunk-X2KA6WHM.mjs.map +1 -0
  72. package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
  73. package/dist/chunk-XSFB7XXQ.mjs.map +1 -0
  74. package/dist/cloud/density.d.ts +55 -0
  75. package/dist/cloud/density.d.ts.map +1 -0
  76. package/dist/cloud/extract.d.ts +25 -0
  77. package/dist/cloud/extract.d.ts.map +1 -0
  78. package/dist/cloud/feature.d.ts +57 -0
  79. package/dist/cloud/feature.d.ts.map +1 -0
  80. package/dist/cloud/frame-context.d.ts +8 -0
  81. package/dist/cloud/frame-context.d.ts.map +1 -0
  82. package/dist/cloud/inspection.d.ts +59 -0
  83. package/dist/cloud/inspection.d.ts.map +1 -0
  84. package/dist/cloud/optics.d.ts +56 -0
  85. package/dist/cloud/optics.d.ts.map +1 -0
  86. package/dist/cloud/parameters.d.ts +73 -0
  87. package/dist/cloud/parameters.d.ts.map +1 -0
  88. package/dist/cloud/resources.d.ts +60 -0
  89. package/dist/cloud/resources.d.ts.map +1 -0
  90. package/dist/cloud/shadow.d.ts +42 -0
  91. package/dist/cloud/shadow.d.ts.map +1 -0
  92. package/dist/cloud/temporal.d.ts +74 -0
  93. package/dist/cloud/temporal.d.ts.map +1 -0
  94. package/dist/components/barrel-distortion.d.ts +13 -0
  95. package/dist/components/barrel-distortion.d.ts.map +1 -0
  96. package/dist/components/cloud-layer.d.ts +29 -0
  97. package/dist/components/cloud-layer.d.ts.map +1 -0
  98. package/dist/components/index.d.ts +2 -0
  99. package/dist/components/index.d.ts.map +1 -1
  100. package/dist/components/instances.d.ts +20 -6
  101. package/dist/components/instances.d.ts.map +1 -1
  102. package/dist/construct-renderer.d.ts +1 -1
  103. package/dist/construct-renderer.d.ts.map +1 -1
  104. package/dist/construct-renderer.mjs +8406 -5785
  105. package/dist/construct-renderer.mjs.map +1 -1
  106. package/dist/device/gpu-residency.d.ts +19 -19
  107. package/dist/device/gpu-residency.d.ts.map +1 -1
  108. package/dist/dynamic-geometry.d.ts +5 -1
  109. package/dist/dynamic-geometry.d.ts.map +1 -1
  110. package/dist/errors/cloud.d.ts +59 -0
  111. package/dist/errors/cloud.d.ts.map +1 -0
  112. package/dist/errors/render.d.ts +20 -5
  113. package/dist/errors/render.d.ts.map +1 -1
  114. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  115. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  116. package/dist/extract/camera.d.ts.map +1 -1
  117. package/dist/extract/contracts.d.ts +5 -1
  118. package/dist/extract/contracts.d.ts.map +1 -1
  119. package/dist/extract/material-context.d.ts +7 -0
  120. package/dist/extract/material-context.d.ts.map +1 -0
  121. package/dist/features/barrel-distortion.d.ts +29 -0
  122. package/dist/features/barrel-distortion.d.ts.map +1 -0
  123. package/dist/features/error-reporting.d.ts +6 -2
  124. package/dist/features/error-reporting.d.ts.map +1 -1
  125. package/dist/features/host.d.ts +15 -0
  126. package/dist/features/host.d.ts.map +1 -1
  127. package/dist/features/plan.d.ts +10 -0
  128. package/dist/features/plan.d.ts.map +1 -1
  129. package/dist/features/render-graph-contribution.d.ts +5 -0
  130. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  131. package/dist/features/render-graph-raster.d.ts +1 -0
  132. package/dist/features/render-graph-raster.d.ts.map +1 -1
  133. package/dist/features/targets.d.ts +2 -0
  134. package/dist/features/targets.d.ts.map +1 -1
  135. package/dist/features/types.d.ts +48 -0
  136. package/dist/features/types.d.ts.map +1 -1
  137. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  138. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  139. package/dist/glyph-text-layout-system.d.ts +1 -1
  140. package/dist/glyph-text-layout-system.d.ts.map +1 -1
  141. package/dist/gpu-dirty-ranges.d.ts +11 -0
  142. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  143. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  144. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  145. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  146. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  147. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  148. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  149. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  150. package/dist/gpu-driven/production-raster.d.ts +47 -3
  151. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  152. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  153. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  154. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  155. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  156. package/dist/gpu-driven/view-gpu.d.ts +26 -2
  157. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  158. package/dist/gpu-scene.d.ts +5 -0
  159. package/dist/gpu-scene.d.ts.map +1 -1
  160. package/dist/hdrp-buffers.d.ts +2 -2
  161. package/dist/hdrp-buffers.d.ts.map +1 -1
  162. package/dist/ibl/frame-resources.d.ts.map +1 -1
  163. package/dist/ibl/skylight-bind-group.d.ts +14 -5
  164. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  165. package/dist/index.d.ts +30 -7
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.mjs +780 -9
  168. package/dist/index.mjs.map +1 -1
  169. package/dist/inspection-types.d.ts +135 -1
  170. package/dist/inspection-types.d.ts.map +1 -1
  171. package/dist/instance-buffer-cache.d.ts +4 -4
  172. package/dist/instance-buffer-cache.d.ts.map +1 -1
  173. package/dist/instances.d.ts +47 -100
  174. package/dist/instances.d.ts.map +1 -1
  175. package/dist/internal.mjs +7 -8
  176. package/dist/internal.mjs.map +1 -1
  177. package/dist/pbr-pipeline.d.ts +22 -4
  178. package/dist/pbr-pipeline.d.ts.map +1 -1
  179. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  180. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  181. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  182. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  183. package/dist/pipeline/standard-output/lut-gpu.d.ts +2 -2
  184. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
  185. package/dist/pipeline/standard-output/resources.d.ts +2 -2
  186. package/dist/pipeline/standard-output/resources.d.ts.map +1 -1
  187. package/dist/pipeline/standard-output/types.d.ts +4 -2
  188. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  189. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  190. package/dist/pipeline/standard-post.d.ts.map +1 -1
  191. package/dist/pipeline-builder.d.ts +1 -1
  192. package/dist/pipeline-builder.d.ts.map +1 -1
  193. package/dist/plugin.d.ts.map +1 -1
  194. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  195. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  196. package/dist/publication/contract.d.ts +77 -0
  197. package/dist/publication/contract.d.ts.map +1 -0
  198. package/dist/publication/dependencies.d.ts +7 -0
  199. package/dist/publication/dependencies.d.ts.map +1 -0
  200. package/dist/publication/prepare-geometry.d.ts +9 -0
  201. package/dist/publication/prepare-geometry.d.ts.map +1 -0
  202. package/dist/publication/programs.d.ts +5 -0
  203. package/dist/publication/programs.d.ts.map +1 -0
  204. package/dist/publication/publisher.d.ts +33 -0
  205. package/dist/publication/publisher.d.ts.map +1 -0
  206. package/dist/publication/receiver.d.ts +29 -0
  207. package/dist/publication/receiver.d.ts.map +1 -0
  208. package/dist/publication/resource-scope.d.ts +18 -0
  209. package/dist/publication/resource-scope.d.ts.map +1 -0
  210. package/dist/publication/targets.d.ts +33 -0
  211. package/dist/publication/targets.d.ts.map +1 -0
  212. package/dist/publication/video.d.ts +5 -0
  213. package/dist/publication/video.d.ts.map +1 -0
  214. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  215. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  216. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  217. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  218. package/dist/record/fold-buckets.d.ts +95 -0
  219. package/dist/record/fold-buckets.d.ts.map +1 -0
  220. package/dist/record/fold-instance-buffer.d.ts +6 -0
  221. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  222. package/dist/record/frame-lighting.d.ts +1 -0
  223. package/dist/record/frame-lighting.d.ts.map +1 -1
  224. package/dist/record/frame-snapshot.d.ts +43 -9
  225. package/dist/record/frame-snapshot.d.ts.map +1 -1
  226. package/dist/record/frame.d.ts +15 -65
  227. package/dist/record/frame.d.ts.map +1 -1
  228. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  229. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  230. package/dist/record/gpu-timing.d.ts +8 -0
  231. package/dist/record/gpu-timing.d.ts.map +1 -1
  232. package/dist/record/helpers.d.ts +2 -2
  233. package/dist/record/helpers.d.ts.map +1 -1
  234. package/dist/record/main-pass-geometry.d.ts +22 -6
  235. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  236. package/dist/record/main-pass-material.d.ts +14 -10
  237. package/dist/record/main-pass-material.d.ts.map +1 -1
  238. package/dist/record/main-pass-sprite-draws.d.ts +3 -16
  239. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  240. package/dist/record/main-pass.d.ts +13 -2
  241. package/dist/record/main-pass.d.ts.map +1 -1
  242. package/dist/record/motion-blur-receipt.d.ts +11 -0
  243. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  244. package/dist/record/prepared-material-bindings.d.ts +3 -3
  245. package/dist/record/prepared-material-bindings.d.ts.map +1 -1
  246. package/dist/record/probe-blend-buffer.d.ts +16 -0
  247. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  248. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  249. package/dist/record/render-context.d.ts +24 -5
  250. package/dist/record/render-context.d.ts.map +1 -1
  251. package/dist/record/shadow-pass.d.ts +2 -0
  252. package/dist/record/shadow-pass.d.ts.map +1 -1
  253. package/dist/record/skybox-post-pass.d.ts +1 -1
  254. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  255. package/dist/record/sprite-instance-buffer.d.ts +31 -0
  256. package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
  257. package/dist/record/target-capture-graph.d.ts +19 -0
  258. package/dist/record/target-capture-graph.d.ts.map +1 -0
  259. package/dist/record/typed-frame-graph.d.ts +24 -15
  260. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  261. package/dist/record/view-ubo.d.ts +11 -3
  262. package/dist/record/view-ubo.d.ts.map +1 -1
  263. package/dist/record/volume-params.d.ts +9 -0
  264. package/dist/record/volume-params.d.ts.map +1 -0
  265. package/dist/recovery/render-system-candidate.d.ts +14 -4
  266. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  267. package/dist/reflection/record-owner.d.ts.map +1 -1
  268. package/dist/render-contract.d.ts +46 -5
  269. package/dist/render-contract.d.ts.map +1 -1
  270. package/dist/render-graph-primitives.d.ts.map +1 -1
  271. package/dist/render-pipeline.d.ts +103 -2
  272. package/dist/render-pipeline.d.ts.map +1 -1
  273. package/dist/render-system-extract-tail.d.ts +3 -2
  274. package/dist/render-system-extract-tail.d.ts.map +1 -1
  275. package/dist/render-system-extract.d.ts +18 -9
  276. package/dist/render-system-extract.d.ts.map +1 -1
  277. package/dist/render-system-presentation.d.ts +23 -0
  278. package/dist/render-system-presentation.d.ts.map +1 -0
  279. package/dist/render-system-producer-roots.d.ts +10 -0
  280. package/dist/render-system-producer-roots.d.ts.map +1 -0
  281. package/dist/render-system-projections.d.ts +3 -2
  282. package/dist/render-system-projections.d.ts.map +1 -1
  283. package/dist/render-system-residency.d.ts +12 -0
  284. package/dist/render-system-residency.d.ts.map +1 -0
  285. package/dist/render-system.d.ts +22 -21
  286. package/dist/render-system.d.ts.map +1 -1
  287. package/dist/scene/probe-blend.d.ts +27 -0
  288. package/dist/scene/probe-blend.d.ts.map +1 -1
  289. package/dist/scene/render-scene.d.ts +18 -7
  290. package/dist/scene/render-scene.d.ts.map +1 -1
  291. package/dist/scene/render-source.d.ts +42 -0
  292. package/dist/scene/render-source.d.ts.map +1 -0
  293. package/dist/scene/source-systems.d.ts +6 -0
  294. package/dist/scene/source-systems.d.ts.map +1 -0
  295. package/dist/ssao-buffers.d.ts +9 -0
  296. package/dist/ssao-buffers.d.ts.map +1 -1
  297. package/dist/surface/dynamic-input.d.ts +133 -0
  298. package/dist/surface/dynamic-input.d.ts.map +1 -0
  299. package/dist/surface/gpu-driven.d.ts +41 -0
  300. package/dist/surface/gpu-driven.d.ts.map +1 -0
  301. package/dist/surface/submission-observation.d.ts +136 -0
  302. package/dist/surface/submission-observation.d.ts.map +1 -0
  303. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  304. package/dist/systems/skin-palette-types.d.ts +10 -0
  305. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  306. package/dist/systems/transparent-dispatch.d.ts +2 -2
  307. package/dist/systems/transparent-dispatch.d.ts.map +1 -1
  308. package/dist/systems/transparent-sort-config.d.ts +2 -1
  309. package/dist/systems/transparent-sort-config.d.ts.map +1 -1
  310. package/dist/temporal/gpu.d.ts +13 -1
  311. package/dist/temporal/gpu.d.ts.map +1 -1
  312. package/dist/temporal/index.mjs +6 -7
  313. package/dist/temporal/inspection.d.ts.map +1 -1
  314. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  315. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  316. package/dist/transmission/single-layer-medium.d.ts +89 -0
  317. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  318. package/dist/typed-render-graph-primitives.d.ts +14 -2
  319. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  320. package/dist/volume/component.d.ts +9 -4
  321. package/dist/volume/component.d.ts.map +1 -1
  322. package/dist/volume/extract.d.ts +1 -1
  323. package/dist/volume/extract.d.ts.map +1 -1
  324. package/dist/volume/inspection.d.ts +2 -0
  325. package/dist/volume/inspection.d.ts.map +1 -1
  326. package/dist/volume/passes.d.ts +4 -1
  327. package/dist/volume/passes.d.ts.map +1 -1
  328. package/dist/volume/resources.d.ts.map +1 -1
  329. package/package.json +22 -21
  330. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  331. package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
  332. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  333. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  334. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  335. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  336. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  337. package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
  338. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  339. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  340. package/src/__tests__/factory-contract.integration.test.ts +295 -45
  341. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  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-material-artifacts.unit.test.ts +143 -0
  347. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +5 -6
  348. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  349. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
  350. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
  351. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  352. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  353. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  354. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  355. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  356. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  357. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  358. package/src/__tests__/gpu-scene.unit.test.ts +119 -9
  359. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  360. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  361. package/src/__tests__/instances-store.unit.test.ts +97 -305
  362. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  363. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
  364. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +145 -0
  365. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  366. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  367. package/src/__tests__/materials-standard-contract.unit.test.ts +0 -1
  368. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  369. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  370. package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
  371. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  372. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  373. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  374. package/src/__tests__/physical-clearcoat.integration.test.ts +66 -8
  375. package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
  376. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  377. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  378. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  379. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  380. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  381. package/src/__tests__/render-error-code-owner.test-d.ts +8 -0
  382. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  383. package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
  384. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  385. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  386. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  387. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  388. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
  389. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  390. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  391. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  392. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +42 -8
  393. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  394. package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
  395. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  396. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  397. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  398. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  399. package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
  400. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  401. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  402. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  403. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  404. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  405. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  406. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  407. package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
  408. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  409. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  410. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  411. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  412. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  413. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  414. package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
  415. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
  416. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  417. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  418. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  419. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
  420. package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
  421. package/src/assembly/backend-contract.ts +30 -0
  422. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  423. package/src/assembly/canvas-draw-guard.ts +11 -0
  424. package/src/assembly/cloud-shadow-entry.ts +22 -0
  425. package/src/assembly/device-feature-admission.ts +2 -2
  426. package/src/assembly/dynamic-geometry-host.ts +65 -37
  427. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  428. package/src/assembly/factory.ts +2 -30
  429. package/src/assembly/host-contract.ts +8 -5
  430. package/src/assembly/material/assembly.ts +25 -13
  431. package/src/assembly/material/pipeline-helpers.ts +53 -12
  432. package/src/assembly/material-shader-policy.ts +55 -0
  433. package/src/assembly/material-shader-prewarm.ts +21 -10
  434. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  435. package/src/assembly/recovery/renderer-recover.ts +50 -18
  436. package/src/assembly/render-feature-post-processes.ts +54 -0
  437. package/src/assembly/render-target-host.ts +57 -47
  438. package/src/assembly/renderer-facade.ts +7 -2
  439. package/src/assembly/renderer-feature-inspection.ts +8 -2
  440. package/src/assembly/renderer-frame-transaction.ts +23 -0
  441. package/src/assembly/renderer-inspection.ts +28 -0
  442. package/src/assembly/skin-palette-owner.ts +1 -1
  443. package/src/assembly/temporal-post-process-prewarm.ts +3 -3
  444. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  445. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  446. package/src/assembly/webgpu-ready.ts +116 -62
  447. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  448. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  449. package/src/assembly/webgpu-renderer.ts +303 -313
  450. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  451. package/src/barrel-distortion.ts +247 -0
  452. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  453. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  454. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  455. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  456. package/src/cloud/density.ts +600 -0
  457. package/src/cloud/extract.ts +110 -0
  458. package/src/cloud/feature.ts +1810 -0
  459. package/src/cloud/frame-context.ts +42 -0
  460. package/src/cloud/inspection.ts +130 -0
  461. package/src/cloud/optics.ts +285 -0
  462. package/src/cloud/parameters.ts +255 -0
  463. package/src/cloud/resources.ts +122 -0
  464. package/src/cloud/shadow.ts +167 -0
  465. package/src/cloud/temporal.ts +226 -0
  466. package/src/components/barrel-distortion.ts +46 -0
  467. package/src/components/cloud-layer.ts +47 -0
  468. package/src/components/index.ts +2 -0
  469. package/src/components/instances.ts +18 -45
  470. package/src/components/sprite-instances.ts +1 -1
  471. package/src/construct-renderer.ts +1 -1
  472. package/src/device/gpu-residency.ts +26 -25
  473. package/src/dynamic-geometry.ts +12 -1
  474. package/src/errors/cloud.ts +103 -0
  475. package/src/errors/render.ts +47 -8
  476. package/src/examples/single-layer-medium-surface.ts +59 -0
  477. package/src/extract/camera.ts +15 -1
  478. package/src/extract/contracts.ts +5 -0
  479. package/src/extract/material-context.ts +21 -0
  480. package/src/features/barrel-distortion.ts +172 -0
  481. package/src/features/error-reporting.ts +26 -6
  482. package/src/features/host.ts +128 -19
  483. package/src/features/plan.ts +10 -0
  484. package/src/features/render-graph-contribution.ts +9 -0
  485. package/src/features/render-graph-raster.ts +45 -3
  486. package/src/features/targets.ts +66 -0
  487. package/src/features/types.ts +51 -0
  488. package/src/fullscreen-post-process-pass.ts +41 -9
  489. package/src/glyph-text-layout-system.ts +2 -2
  490. package/src/gpu-dirty-ranges.ts +48 -0
  491. package/src/gpu-driven/batch-topology.ts +53 -0
  492. package/src/gpu-driven/material-artifacts.ts +33 -25
  493. package/src/gpu-driven/prepared-draw.ts +12 -4
  494. package/src/gpu-driven/production-raster-material.ts +1894 -0
  495. package/src/gpu-driven/production-raster.ts +825 -784
  496. package/src/gpu-driven/resource-allocation.ts +142 -0
  497. package/src/gpu-driven/shadow-ownership.ts +71 -0
  498. package/src/gpu-driven/view-gpu.ts +164 -10
  499. package/src/gpu-scene.ts +75 -84
  500. package/src/hdrp-buffers.ts +4 -3
  501. package/src/ibl/frame-resources.ts +0 -1
  502. package/src/ibl/skylight-bind-group.ts +62 -32
  503. package/src/index.ts +205 -9
  504. package/src/inspection-types.ts +162 -0
  505. package/src/instance-buffer-cache.ts +4 -4
  506. package/src/instances.ts +152 -569
  507. package/src/pbr-pipeline.ts +230 -30
  508. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  509. package/src/pipeline/standard-forward-lane.ts +313 -57
  510. package/src/pipeline/standard-output/graph.ts +8 -2
  511. package/src/pipeline/standard-output/lut-gpu.ts +3 -3
  512. package/src/pipeline/standard-output/resources.ts +2 -2
  513. package/src/pipeline/standard-output/types.ts +12 -1
  514. package/src/pipeline/standard-pipeline.ts +291 -18
  515. package/src/pipeline/standard-post.ts +90 -24
  516. package/src/pipeline-builder.ts +1 -1
  517. package/src/plugin.ts +4 -0
  518. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  519. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  520. package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
  521. package/src/publication/__tests__/features.integration.test.ts +122 -0
  522. package/src/publication/__tests__/programs.unit.test.ts +25 -0
  523. package/src/publication/__tests__/publication.integration.test.ts +370 -0
  524. package/src/publication/__tests__/targets.integration.test.ts +120 -0
  525. package/src/publication/__tests__/video.browser.test.ts +50 -0
  526. package/src/publication/contract.ts +104 -0
  527. package/src/publication/dependencies.ts +54 -0
  528. package/src/publication/prepare-geometry.ts +94 -0
  529. package/src/publication/programs.ts +45 -0
  530. package/src/publication/publisher.ts +618 -0
  531. package/src/publication/receiver.ts +297 -0
  532. package/src/publication/resource-scope.ts +31 -0
  533. package/src/publication/targets.ts +182 -0
  534. package/src/publication/video.ts +33 -0
  535. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  536. package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
  537. package/src/record/__tests__/sprite-material-abi.unit.test.ts +9 -11
  538. package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
  539. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  540. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  541. package/src/record/__tests__/video-texture-view.unit.test.ts +9 -9
  542. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  543. package/src/record/barrel-distortion-frame.ts +110 -0
  544. package/src/record/dynamic-geometry-consumption.ts +39 -9
  545. package/src/record/fold-buckets.ts +855 -0
  546. package/src/record/fold-instance-buffer.ts +51 -0
  547. package/src/record/frame-lighting.ts +36 -2
  548. package/src/record/frame-snapshot.ts +45 -9
  549. package/src/record/frame.ts +258 -1105
  550. package/src/record/gpu-draw-receipts.ts +38 -0
  551. package/src/record/gpu-timing.ts +48 -5
  552. package/src/record/helpers.ts +2 -2
  553. package/src/record/main-pass-geometry.ts +272 -84
  554. package/src/record/main-pass-material.ts +102 -36
  555. package/src/record/main-pass-sprite-draws.ts +13 -217
  556. package/src/record/main-pass.ts +164 -27
  557. package/src/record/motion-blur-receipt.ts +91 -0
  558. package/src/record/prepared-material-bindings.ts +11 -6
  559. package/src/record/probe-blend-buffer.ts +180 -0
  560. package/src/record/recovery-pipeline.ts +35 -3
  561. package/src/record/render-context.ts +41 -5
  562. package/src/record/shadow-pass.ts +30 -4
  563. package/src/record/skybox-post-pass.ts +28 -4
  564. package/src/record/sprite-instance-buffer.ts +155 -0
  565. package/src/record/target-capture-graph.ts +258 -0
  566. package/src/record/typed-frame-graph.ts +776 -340
  567. package/src/record/view-ubo.ts +27 -4
  568. package/src/record/volume-params.ts +225 -0
  569. package/src/recovery/render-system-candidate.ts +243 -50
  570. package/src/reflection/record-owner.ts +7 -3
  571. package/src/render-contract.ts +54 -5
  572. package/src/render-graph-primitives.ts +7 -1
  573. package/src/render-pipeline.ts +130 -0
  574. package/src/render-system-extract-tail.ts +90 -78
  575. package/src/render-system-extract.ts +76 -76
  576. package/src/render-system-presentation.ts +56 -0
  577. package/src/render-system-producer-roots.ts +96 -0
  578. package/src/render-system-projections.ts +3 -2
  579. package/src/render-system-residency.ts +159 -0
  580. package/src/render-system.ts +421 -408
  581. package/src/scene/probe-blend.ts +96 -4
  582. package/src/scene/render-scene.ts +416 -337
  583. package/src/scene/render-source.ts +90 -0
  584. package/src/scene/source-systems.ts +33 -0
  585. package/src/ssao-buffers.ts +95 -2
  586. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  587. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  588. package/src/surface/dynamic-input.ts +658 -0
  589. package/src/surface/gpu-driven.ts +147 -0
  590. package/src/surface/submission-observation.ts +517 -0
  591. package/src/systems/skin-palette-allocator.ts +5 -1
  592. package/src/systems/skin-palette-types.ts +11 -0
  593. package/src/systems/transparent-dispatch.ts +2 -2
  594. package/src/systems/transparent-sort-config.ts +3 -1
  595. package/src/temporal/gpu.ts +101 -17
  596. package/src/temporal/inspection.ts +7 -1
  597. package/src/temporal/standard-scene-data.ts +5 -0
  598. package/src/temporal/target-coverage-attachment.ts +4 -0
  599. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  600. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  601. package/src/transmission/single-layer-medium.ts +322 -0
  602. package/src/typed-render-graph-primitives.ts +70 -2
  603. package/src/volume/component.ts +10 -9
  604. package/src/volume/extract.ts +11 -5
  605. package/src/volume/inspection.ts +3 -0
  606. package/src/volume/passes.ts +87 -4
  607. package/src/volume/resources.ts +2 -1
  608. package/dist/chunk-3RTCJTH4.mjs +0 -1610
  609. package/dist/chunk-3RTCJTH4.mjs.map +0 -1
  610. package/dist/chunk-BLXGONR2.mjs.map +0 -1
  611. package/dist/chunk-ILQ5MEZF.mjs +0 -32
  612. package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
  613. package/dist/chunk-LEAXOMYJ.mjs.map +0 -1
  614. package/dist/chunk-NB2S7ZRX.mjs +0 -1783
  615. package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
  616. package/dist/chunk-NNQL7CB3.mjs +0 -1713
  617. package/dist/chunk-NNQL7CB3.mjs.map +0 -1
  618. package/dist/chunk-OO3DRYK7.mjs.map +0 -1
  619. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
  620. package/dist/chunk-PLAXOOX5.mjs +0 -1907
  621. package/dist/chunk-PLAXOOX5.mjs.map +0 -1
  622. package/dist/chunk-RXZ3RGOU.mjs +0 -53
  623. package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
  624. package/dist/chunk-VOZWDM3L.mjs.map +0 -1
@@ -173,7 +173,11 @@ function addRequest(input: {
173
173
  readonly vertexLayoutProjection?: VertexLayoutProjection;
174
174
  readonly vertexEntry?: string;
175
175
  readonly fragmentEntry?: string;
176
- readonly layoutKindOverride?: 'pbr' | 'pbr-skin';
176
+ readonly layoutKindOverride?:
177
+ | 'pbr'
178
+ | 'pbr-skin'
179
+ | 'surface-direct-pbr'
180
+ | 'surface-direct-cluster-pbr';
177
181
  readonly preserveUndefinedVariant?: boolean;
178
182
  readonly variantAlreadyResolved?: boolean;
179
183
  }): void {
@@ -244,7 +248,7 @@ function addRequest(input: {
244
248
  undefined,
245
249
  undefined,
246
250
  projection,
247
- undefined,
251
+ 'immediate',
248
252
  input.layoutKindOverride,
249
253
  undefined,
250
254
  input.additionalColorFormats,
@@ -260,6 +264,7 @@ function addStandardMaterialRequests(input: {
260
264
  readonly internals: RenderSystemInternals;
261
265
  readonly pipelineState: PipelineState;
262
266
  readonly validated: readonly ValidatedRenderable[];
267
+ readonly dispatch: readonly DispatchEntry[];
263
268
  readonly standardLighting: StandardTopologyInputValue | undefined;
264
269
  readonly sampleCount: number;
265
270
  readonly isHdrTarget: boolean;
@@ -267,6 +272,13 @@ function addStandardMaterialRequests(input: {
267
272
  readonly reflectionFallbackAvailable: boolean;
268
273
  }): void {
269
274
  const pointsLinesProjection = deriveVertexLayoutProjection(DEFAULT_VERTEX_ATTRIBUTE_MAP);
275
+ const forwardPrograms = new Map<string, DispatchEntry>();
276
+ for (const candidate of input.dispatch) {
277
+ if (candidate.tags.LightMode !== 'Forward' || candidate.materialShaderId === undefined)
278
+ continue;
279
+ const key = `${candidate.renderableIndex}:${candidate.materialHandle}`;
280
+ if (!forwardPrograms.has(key)) forwardPrograms.set(key, candidate);
281
+ }
270
282
  for (const entry of input.validated) {
271
283
  if (entry.source.pointsLines !== undefined) {
272
284
  const pointsLinesMaterial = entry.source.material;
@@ -312,9 +324,14 @@ function addStandardMaterialRequests(input: {
312
324
  const unlitHasColor = unlitProjection === 'VERTEX_COLOR_AVAILABLE=true';
313
325
  for (const submesh of entry.mesh.submeshes) {
314
326
  const material = entry.source.materials[submesh.materialSlot] ?? entry.source.material;
327
+ const forwardProgram = forwardPrograms.get(
328
+ `${entry.renderableIndex}:${material.materialHandle ?? -1}`,
329
+ );
315
330
  const materialShaderId =
316
331
  entry.source.skin === undefined
317
- ? (material.materialShaderId ?? 'forgeax::default-unlit')
332
+ ? (forwardProgram?.materialShaderId ??
333
+ material.materialShaderId ??
334
+ 'forgeax::default-unlit')
318
335
  : SKIN_MATERIAL_SHADER_ID;
319
336
  const renderState = geometryRenderStateForPass(
320
337
  recoveryRenderState(materialShaderId, material, submesh.topology) as ReturnType<
@@ -370,6 +387,13 @@ function addStandardMaterialRequests(input: {
370
387
  const materialCapabilityVariantSet = isStandardPbrMaterialShader(materialShaderId)
371
388
  ? standardPbrCapabilityVariantSet
372
389
  : capabilityVariantSet;
390
+ const surfaceLayoutKind =
391
+ material.surfaceModel === 'single-layer-medium'
392
+ ? input.standardLighting?.kind === 'clustered' &&
393
+ input.internals.device.caps.storageBuffer
394
+ ? ('surface-direct-cluster-pbr' as const)
395
+ : ('surface-direct-pbr' as const)
396
+ : undefined;
373
397
  const requestedVariant = isSprite
374
398
  ? materialShaderId === 'forgeax::sprite' && entry.source.spriteInstances !== undefined
375
399
  ? SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET
@@ -398,6 +422,12 @@ function addStandardMaterialRequests(input: {
398
422
  indexFormat: entry.mesh.indexFormat,
399
423
  ...optionalVariant(reflectionFallbackVariant),
400
424
  passKind: 'forward',
425
+ ...(forwardProgram?.vertexEntry === undefined
426
+ ? {}
427
+ : { vertexEntry: forwardProgram.vertexEntry }),
428
+ ...(forwardProgram?.fragmentEntry === undefined
429
+ ? {}
430
+ : { fragmentEntry: forwardProgram.fragmentEntry }),
401
431
  sampleCount: input.sampleCount,
402
432
  ...optionalColorFormat(input.colorFormatOverride),
403
433
  ...(input.reflectionFallbackAvailable &&
@@ -405,6 +435,7 @@ function addStandardMaterialRequests(input: {
405
435
  ? { additionalColorFormats: ['rgba16float'] as const }
406
436
  : {}),
407
437
  vertexLayoutProjection: meshProjection,
438
+ ...(surfaceLayoutKind === undefined ? {} : { layoutKindOverride: surfaceLayoutKind }),
408
439
  preserveUndefinedVariant: isSprite && requestedVariant === undefined,
409
440
  variantAlreadyResolved:
410
441
  isSprite ||
@@ -610,6 +641,7 @@ export function prepareRecoveryPipelineReadiness(input: {
610
641
  internals: input.internals,
611
642
  pipelineState: input.pipelineState,
612
643
  validated: input.validated,
644
+ dispatch: input.dispatch,
613
645
  standardLighting: input.standardLighting,
614
646
  sampleCount,
615
647
  isHdrTarget,
@@ -1,5 +1,4 @@
1
1
  import type { AssetRegistry, DynamicTextureStore } from '@forgeax/engine-assets-runtime';
2
- import type { World } from '@forgeax/engine-ecs';
3
2
  import type { VertexLayoutProjection } from '@forgeax/engine-geometry';
4
3
  import type { Profiler } from '@forgeax/engine-profiler';
5
4
  import type { CompiledRenderGraphInfo } from '@forgeax/engine-render-graph';
@@ -58,6 +57,7 @@ import type { StandardProfile } from '../pipeline/standard-profile';
58
57
  import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
59
58
  import type { PointsLinesInspection } from '../points-lines/inspection';
60
59
  import type { PointsLinesRecordPlan } from '../points-lines/record';
60
+ import type { RenderResourceScope } from '../publication/resource-scope';
61
61
  import type { ReflectionProbeTable } from '../reflection/gpu-table';
62
62
  import type { ReflectionProbeSelectionResult } from '../reflection/projection';
63
63
  import type { FrameObservationDomain } from '../render-contract';
@@ -113,6 +113,11 @@ export interface ReflectionProbeRecordState {
113
113
  export interface MaterialShaderPipelineEntry {
114
114
  readonly pipeline: RhiRenderPipeline;
115
115
  readonly group2Contract: PipelineGroup2Contract;
116
+ /** Producer receipt for the exact artifact selected with this pipeline. */
117
+ readonly receipt?: {
118
+ readonly identity: string;
119
+ readonly generation: number;
120
+ };
116
121
  }
117
122
 
118
123
  import type {
@@ -198,6 +203,7 @@ export interface RenderSystemRuntime {
198
203
  | {
199
204
  readonly vertexColorAvailable?: boolean;
200
205
  readonly deformation?: 'rigid' | 'skin';
206
+ readonly variantSet?: string;
201
207
  readonly clustered?: boolean;
202
208
  readonly reflectionFallback?: boolean;
203
209
  readonly pass?: 'forward' | 'shadow' | 'depth';
@@ -221,7 +227,15 @@ export interface RenderSystemRuntime {
221
227
  vertexLayout?: string,
222
228
  vertexLayoutProjection?: VertexLayoutProjection,
223
229
  shaderModuleMode?: RenderFeatureShaderModuleMode,
224
- layoutKindOverride?: 'pbr' | 'pbr-skin' | 'gpu-driven-pbr' | 'gpu-driven-skin',
230
+ layoutKindOverride?:
231
+ | 'pbr'
232
+ | 'pbr-skin'
233
+ | 'gpu-driven-pbr'
234
+ | 'gpu-driven-skin'
235
+ | 'gpu-driven-cluster-pbr'
236
+ | 'gpu-driven-cluster-skin'
237
+ | 'surface-direct-pbr'
238
+ | 'surface-direct-cluster-pbr',
225
239
  /** Optional vertex entry override for receipt-owned scene-index passes. */
226
240
  vertexEntryPoint?: string,
227
241
  additionalColorFormats?: readonly GPUTextureFormat[],
@@ -246,7 +260,15 @@ export interface RenderSystemRuntime {
246
260
  vertexLayout?: string,
247
261
  vertexLayoutProjection?: VertexLayoutProjection,
248
262
  shaderModuleMode?: RenderFeatureShaderModuleMode,
249
- layoutKindOverride?: 'pbr' | 'pbr-skin' | 'gpu-driven-pbr' | 'gpu-driven-skin',
263
+ layoutKindOverride?:
264
+ | 'pbr'
265
+ | 'pbr-skin'
266
+ | 'gpu-driven-pbr'
267
+ | 'gpu-driven-skin'
268
+ | 'gpu-driven-cluster-pbr'
269
+ | 'gpu-driven-cluster-skin'
270
+ | 'surface-direct-pbr'
271
+ | 'surface-direct-cluster-pbr',
250
272
  /** Optional vertex entry override for receipt-owned scene-index passes. */
251
273
  vertexEntryPoint?: string,
252
274
  additionalColorFormats?: readonly GPUTextureFormat[],
@@ -413,6 +435,8 @@ export interface PipelineState {
413
435
  readonly probeInstancesBindGroupLayout?: BindGroupLayout;
414
436
  readonly identityInstanceBuffer: Buffer;
415
437
  readonly defaultSampler: Sampler;
438
+ /** Nearest/clamp sampler required by r32float Surface depth input. */
439
+ readonly surfaceMediumDepthSampler?: Sampler;
416
440
  readonly fallbackTextureView: TextureView;
417
441
  readonly unlitPipeline: RhiRenderPipeline | null;
418
442
  readonly standardPipeline: RhiRenderPipeline | null;
@@ -427,10 +451,16 @@ export interface PipelineState {
427
451
  readonly pbrPipelineLayout: PipelineLayout | null;
428
452
  /** Dedicated slot-3 layout for scene-index GPU-driven Standard PBR draws. */
429
453
  readonly gpuDrivenInstancesBindGroupLayout?: BindGroupLayout | null;
454
+ /** Direct Surface slot-3 ABI: instances + retained medium frame resources. */
455
+ readonly surfaceDirectInstancesBindGroupLayout?: BindGroupLayout | null;
430
456
  readonly gpuDrivenPbrPipelineLayout?: PipelineLayout | null;
431
457
  /** Device-owned shader modules paired with their exact Standard PBR receipts. */
432
458
  readonly gpuDrivenPbrPrograms?: ReadonlyMap<string, GpuDrivenPbrProgram>;
433
459
  readonly gpuDrivenPbrSkinPipelineLayout?: PipelineLayout | null;
460
+ /** Clustered group(2) layouts paired with the scene-index slot(3). */
461
+ readonly gpuDrivenClusterPbrPipelineLayout?: PipelineLayout | null;
462
+ readonly gpuDrivenClusterPbrSkinPipelineLayout?: PipelineLayout | null;
463
+ readonly gpuDrivenClusterMeshBindGroupLayout?: BindGroupLayout | null;
434
464
  readonly pbrProbePipelineLayout?: PipelineLayout | null;
435
465
  readonly hdrpPbrPipelineLayout: PipelineLayout | null;
436
466
  readonly hdrpMeshBindGroupLayout?: BindGroupLayout | null;
@@ -552,7 +582,7 @@ export interface _StandardForwardSceneView {
552
582
  readonly skybox: SkyboxSnapshot | undefined;
553
583
  readonly profilePhase?: <T>(phase: RenderRecordPhase, action: () => T) => T;
554
584
  readonly directionalShadowCacheReuse: boolean;
555
- readonly world: World;
585
+ readonly world: RenderResourceScope;
556
586
  readonly tonemapActive: boolean;
557
587
  readonly geometryColorView: TextureView | null;
558
588
  readonly geometryDepthView: TextureView | null;
@@ -579,6 +609,8 @@ export interface _StandardForwardSceneView {
579
609
  readonly gpuDrivenSceneMaterialBuffer?: Buffer;
580
610
  /** Concrete main-pass draw identities already claimed by the capable GPU lane. */
581
611
  readonly gpuDrivenDrawKeys?: ReadonlySet<string>;
612
+ /** Stable world identities used to construct the claimed draw keys. */
613
+ readonly gpuDrivenWorldKeys?: readonly number[];
582
614
  readonly gpuDrivenShadowViews?: ShadowViewStatePool;
583
615
  readonly gpuDrivenShadowBatchProjections?: ReadonlyMap<
584
616
  string,
@@ -601,7 +633,11 @@ export interface _StandardForwardSceneView {
601
633
  readonly pointsLines: PointsLinesRecordOwner | undefined;
602
634
  readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;
603
635
  /** Record-stage proof callback; invoked only after a real draw command is encoded. */
604
- readonly onRenderableDraw?: (entry: ValidatedRenderable) => void;
636
+ readonly onRenderableDraw?: (
637
+ entry: ValidatedRenderable,
638
+ submeshIndex?: number,
639
+ receipt?: { readonly lane: 'cpu' | 'gpu'; readonly ready: boolean },
640
+ ) => void;
605
641
  readonly reflectionProbes?: ReflectionProbeRecordState;
606
642
  materialUboPayloadCache?: {
607
643
  readonly materialSlots: readonly MaterialSnapshot[];
@@ -82,6 +82,8 @@ export interface GpuDrivenShadowBatch {
82
82
  readonly deformation: 'rigid' | 'skin';
83
83
  /** Complete binding for this batch, including opaque batches after custom casters. */
84
84
  readonly materialGroup: BindGroup;
85
+ /** Receipt-derived material BG for alpha-mask batches; opaque uses the pass singleton. */
86
+ readonly alphaMaskMaterialGroup?: BindGroup | undefined;
85
87
  readonly vertexBuffer: Buffer;
86
88
  readonly indexBuffer?: Buffer | undefined;
87
89
  readonly indexFormat?: 'uint16' | 'uint32' | undefined;
@@ -192,6 +194,7 @@ function ensureTypedShadowViewBg(
192
194
  );
193
195
  }
194
196
  const projectorAvailable = pipelineState.projectorAvailable !== false;
197
+ const lowLimitCloudBindings = !extendedLighting && !projectorAvailable;
195
198
  try {
196
199
  return getOrCreateFromChain(
197
200
  frameState.viewBindGroupCache,
@@ -209,6 +212,9 @@ function ensureTypedShadowViewBg(
209
212
  ? [pipelineState.defaultWhiteTextureView, pipelineState.defaultSampler]
210
213
  : []),
211
214
  pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,
215
+ ...(lowLimitCloudBindings
216
+ ? []
217
+ : [pipelineState.defaultWhiteTextureView, pipelineState.defaultSampler]),
212
218
  ],
213
219
  variant,
214
220
  () => {
@@ -287,6 +293,24 @@ function ensureTypedShadowViewBg(
287
293
  },
288
294
  ]
289
295
  : []),
296
+ ...(lowLimitCloudBindings
297
+ ? []
298
+ : [
299
+ {
300
+ binding: 16,
301
+ resource: {
302
+ kind: 'textureView' as const,
303
+ value: pipelineState.defaultWhiteTextureView,
304
+ },
305
+ },
306
+ {
307
+ binding: 17,
308
+ resource: {
309
+ kind: 'sampler' as const,
310
+ value: pipelineState.defaultSampler,
311
+ },
312
+ },
313
+ ]),
290
314
  ],
291
315
  });
292
316
  if (!created.ok) throw created.error;
@@ -786,6 +810,7 @@ function recordGpuDrivenShadowIfPublished(
786
810
  visibleBindGroup: projection.visibleBindGroup,
787
811
  deformation: projection.deformation,
788
812
  materialGroup,
813
+ ...(batch.key.admission === 'alpha-mask' ? { alphaMaskMaterialGroup: materialGroup } : {}),
789
814
  vertexBuffer: projection.mesh.vertexBuffer.handle,
790
815
  ...(batch.key.drawKind === 'indexed' && projection.mesh.indexBuffer !== null
791
816
  ? {
@@ -1849,7 +1874,6 @@ function ensureSpotShadowMaterialBg(c: _InternalRenderPipelineContext): BindGrou
1849
1874
  prefilterView: fb.prefilterView,
1850
1875
  prefilterSampler: fb.sampler,
1851
1876
  brdfLutView: fb.brdfLutView,
1852
- brdfLutSampler: fb.sampler,
1853
1877
  intensityBuffer: fb.intensityBuffer,
1854
1878
  },
1855
1879
  transmissionBackdropAvailable(runtime.device.limits.maxSampledTexturesPerShaderStage)
@@ -1931,7 +1955,6 @@ function ensureGpuDrivenAlphaMaskMaterialBg(
1931
1955
  prefilterView: fallback.prefilterView,
1932
1956
  prefilterSampler: fallback.sampler,
1933
1957
  brdfLutView: fallback.brdfLutView,
1934
- brdfLutSampler: fallback.sampler,
1935
1958
  intensityBuffer: fallback.intensityBuffer,
1936
1959
  } satisfies import('../ibl/skylight-bind-group').SkylightBindGroupResources;
1937
1960
  const deps: PerSubmeshMaterialBgDeps = {
@@ -1970,7 +1993,11 @@ function ensureGpuDrivenCustomShadowMaterialBg(
1970
1993
  c: _InternalRenderPipelineContext,
1971
1994
  projection: GpuDrivenShadowBatchProjection,
1972
1995
  ): BindGroup {
1973
- const shaderId = projection.shadowArtifact.material;
1996
+ const shaderId =
1997
+ projection.shadowArtifact.specializationKey ?? projection.shadowArtifact.material;
1998
+ const materialKey = `shadow-material-custom:${shaderId}:${projection.materialEntityKey}:${projection.material.materialHandle ?? -1}:${c.store.materialResourceEpoch}`;
1999
+ const cached = c.materialBgAssemblyCache.get(materialKey);
2000
+ if (cached !== undefined) return cached.bindGroup;
1974
2001
  const fallback = c.pipelineState.skylightFallback;
1975
2002
  if (fallback === null) {
1976
2003
  throw new RhiError({
@@ -1993,7 +2020,6 @@ function ensureGpuDrivenCustomShadowMaterialBg(
1993
2020
  prefilterView: fallback.prefilterView,
1994
2021
  prefilterSampler: fallback.sampler,
1995
2022
  brdfLutView: fallback.brdfLutView,
1996
- brdfLutSampler: fallback.sampler,
1997
2023
  intensityBuffer: fallback.intensityBuffer,
1998
2024
  } satisfies import('../ibl/skylight-bind-group').SkylightBindGroupResources;
1999
2025
  const deps: PerSubmeshMaterialBgDeps = {
@@ -498,6 +498,7 @@ export function recordFxaaPass(
498
498
  resolve: ResolveContext,
499
499
  graphPass?: RhiRenderPassEncoder,
500
500
  paramsOverride?: Uint8Array,
501
+ graphOutputFormat?: GPUTextureFormat,
501
502
  ): void {
502
503
  const { runtime, pipelineState, encoder, camera, currentTexture } = c;
503
504
  // FXAA samples the graph-owned LDR target and writes the current surface.
@@ -570,9 +571,17 @@ export function recordFxaaPass(
570
571
  c.bindGroupCounts,
571
572
  );
572
573
 
573
- const fxaaColorFormat = runtime.device.caps.storageBuffer
574
- ? pipelineState.format
575
- : pipelineState.colorAttachmentFormat;
574
+ // Typed graph passes own their attachment format. In particular, the
575
+ // barrel/LUT split keeps FXAA in the graph-owned rgba16float domain before
576
+ // the final output encoding; falling back to the swapchain format here
577
+ // builds a BGRA pipeline against an RGBA16F attachment and invalidates the
578
+ // command buffer on WebGPU.
579
+ const fxaaColorFormat =
580
+ graphPass !== undefined && graphOutputFormat !== undefined
581
+ ? graphOutputFormat
582
+ : runtime.device.caps.storageBuffer
583
+ ? pipelineState.format
584
+ : pipelineState.colorAttachmentFormat;
576
585
  let fxaaPass = graphPass;
577
586
  if (fxaaPass === undefined) {
578
587
  const fxaaOutputView = runtime.device.createTextureView(currentTexture, {
@@ -594,7 +603,22 @@ export function recordFxaaPass(
594
603
  ) as never,
595
604
  );
596
605
  }
597
- fxaaPass.setPipeline(pipelineState.perPassResources.fxaaPipeline);
606
+ let fxaaPipeline = pipelineState.perPassResources.fxaaPipeline;
607
+ if (graphPass !== undefined && graphOutputFormat !== undefined) {
608
+ const entry = runtime.lookupPostProcess?.(FXAA_POST_PROCESS_ID);
609
+ const rebuilt =
610
+ entry === undefined || runtime.getPostProcessPipeline === undefined
611
+ ? null
612
+ : runtime.getPostProcessPipeline(
613
+ FXAA_POST_PROCESS_ID,
614
+ fxaaBglLayout,
615
+ [graphOutputFormat],
616
+ entry,
617
+ );
618
+ if (rebuilt !== null) fxaaPipeline = rebuilt;
619
+ }
620
+ if (fxaaPipeline === null) return;
621
+ fxaaPass.setPipeline(fxaaPipeline);
598
622
  fxaaPass.setBindGroup(0, fxaaBg);
599
623
  fxaaPass.draw(3, 1, 0, 0);
600
624
  if (graphPass === undefined) fxaaPass.end();
@@ -0,0 +1,155 @@
1
+ import { type Buffer, RhiError } from '@forgeax/engine-rhi';
2
+ import { GpuBuffer } from '../gpu-resource';
3
+ import {
4
+ GPU_BUFFER_USAGE_COPY_DST,
5
+ GPU_BUFFER_USAGE_STORAGE,
6
+ GPU_BUFFER_USAGE_UNIFORM,
7
+ } from '../gpu-usage';
8
+ import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
9
+ import type { SpriteInstancesSnapshot } from '../render-system-extract';
10
+ import { worldEntityKey } from './frame-snapshot';
11
+ import type { _InternalRenderPipelineContext } from './render-context';
12
+
13
+ export type { SpriteInstancesSnapshot } from '../render-system-extract';
14
+
15
+ /**
16
+ * Build the interleaved sprite instance payload consumed by this record owner.
17
+ * The extract stage validates the two packed arrays before they reach this
18
+ * function, so the record path has one source of count-mismatch errors.
19
+ */
20
+ export function interleaveSpriteInstanceBuffer(
21
+ transforms: Float32Array,
22
+ regions: Float32Array,
23
+ includePrevious = false,
24
+ ): Float32Array {
25
+ const count = transforms.length / 16;
26
+ const stride = includePrevious ? 36 : 20;
27
+ const regionOffset = includePrevious ? 32 : 16;
28
+ const out = new Float32Array(count * stride);
29
+ for (let i = 0; i < count; i++) {
30
+ const dstBase = i * stride;
31
+ const transformBase = i * 16;
32
+ const regionBase = i * 4;
33
+ for (let k = 0; k < 16; k++) out[dstBase + k] = transforms[transformBase + k] ?? 0;
34
+ if (includePrevious) {
35
+ for (let k = 0; k < 16; k++) {
36
+ out[dstBase + 16 + k] = transforms[transformBase + k] ?? 0;
37
+ }
38
+ }
39
+ for (let k = 0; k < 4; k++) {
40
+ out[dstBase + regionOffset + k] = regions[regionBase + k] ?? 0;
41
+ }
42
+ }
43
+ return out;
44
+ }
45
+
46
+ /**
47
+ * Check whether the existing per-entity sprite buffer still matches the
48
+ * extract snapshot and interleaved byte count.
49
+ */
50
+ export function spriteInstancesCacheHit(
51
+ entry: InstanceBufferCacheEntry | undefined,
52
+ snapshot: SpriteInstancesSnapshot,
53
+ requestedBytes: number,
54
+ ): boolean {
55
+ return (
56
+ entry !== undefined &&
57
+ entry.uploadedArchVersion === snapshot.archVersion &&
58
+ entry.uploadedByteLength === requestedBytes
59
+ );
60
+ }
61
+
62
+ /**
63
+ * feat-20260704 M3/w19: resolve the interleaved SpriteInstances (@group(3))
64
+ * buffer + instanceCount for a sprite entity in the LDR blend sub-pass,
65
+ * extracted verbatim from recordSpriteEntityDraws. Uploads the interleaved
66
+ * mat4 + per-instance UV region transforms (cache-keyed on the snapshot); on
67
+ * over-cap fires the structured limit-exceeded error and leaves the passed-in
68
+ * fallback buffer/count. Returns the resolved (or unchanged) buffer + count.
69
+ *
70
+ * @internal
71
+ */
72
+ export function resolveSpriteInstancesBuffer(
73
+ c: Pick<_InternalRenderPipelineContext, 'runtime' | 'frameState'>,
74
+ spriteEntry: _InternalRenderPipelineContext['validatedOrdered'][number],
75
+ fallbackBuffer: Buffer,
76
+ fallbackCount: number,
77
+ ): { buffer: Buffer; count: number } {
78
+ const { runtime, frameState } = c;
79
+ let buffer = fallbackBuffer;
80
+ let count = fallbackCount;
81
+ const spriteInstancesSnap: SpriteInstancesSnapshot | undefined =
82
+ spriteEntry.source.spriteInstances;
83
+ if (spriteInstancesSnap !== undefined) {
84
+ if (spriteInstancesSnap.instanceCount === 0) return { buffer, count: 0 };
85
+ const uniformFallback = runtime.device.caps.storageBuffer === false;
86
+ const interleaved = interleaveSpriteInstanceBuffer(
87
+ spriteInstancesSnap.transforms,
88
+ spriteInstancesSnap.regions,
89
+ !uniformFallback,
90
+ );
91
+ const requestedBytes = interleaved.byteLength;
92
+ const cap = runtime.device.limits.maxStorageBufferBindingSize;
93
+ if (typeof cap === 'number' && requestedBytes > cap) {
94
+ runtime.errorRegistry.fire(
95
+ new RhiError({
96
+ code: 'limit-exceeded',
97
+ expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,
98
+ hint: 'reduce SpriteInstances instance count to fit within device.limits.maxStorageBufferBindingSize (144 bytes per instance: current mat4 64B + previous mat4 64B + region 16B)',
99
+ detail: {
100
+ maxStorageBufferBindingSize: cap,
101
+ requestedBytes,
102
+ },
103
+ }),
104
+ );
105
+ } else {
106
+ const cachedSpriteInst = frameState.instanceBuffers.get(
107
+ worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),
108
+ );
109
+ let activeSpriteInst: InstanceBufferCacheEntry | null = null;
110
+ if (spriteInstancesCacheHit(cachedSpriteInst, spriteInstancesSnap, requestedBytes)) {
111
+ activeSpriteInst = cachedSpriteInst ?? null;
112
+ } else if (requestedBytes > 0) {
113
+ const bufRes = runtime.device.createBuffer({
114
+ size: requestedBytes,
115
+ usage:
116
+ (uniformFallback ? GPU_BUFFER_USAGE_UNIFORM : GPU_BUFFER_USAGE_STORAGE) |
117
+ GPU_BUFFER_USAGE_COPY_DST,
118
+ mappedAtCreation: false,
119
+ });
120
+ if (!bufRes.ok) {
121
+ runtime.errorRegistry.fire(bufRes.error);
122
+ } else {
123
+ if (cachedSpriteInst !== undefined && !cachedSpriteInst.buffer.isDestroyed) {
124
+ const r = cachedSpriteInst.buffer.destroy();
125
+ if (!r.ok) runtime.errorRegistry.fire(r.error);
126
+ }
127
+ const newBuf = new GpuBuffer(runtime.device, bufRes.value);
128
+ activeSpriteInst = {
129
+ buffer: newBuf,
130
+ uploadedArchVersion: spriteInstancesSnap.archVersion,
131
+ uploadedByteLength: requestedBytes,
132
+ };
133
+ frameState.instanceBuffers.set(
134
+ worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),
135
+ activeSpriteInst,
136
+ );
137
+ }
138
+ }
139
+ if (activeSpriteInst !== null && requestedBytes > 0) {
140
+ const writeRes = runtime.device.queue.writeBuffer(
141
+ activeSpriteInst.buffer.handle,
142
+ 0,
143
+ interleaved,
144
+ );
145
+ if (!writeRes.ok) {
146
+ runtime.errorRegistry.fire(writeRes.error);
147
+ } else {
148
+ buffer = activeSpriteInst.buffer.handle;
149
+ count = spriteInstancesSnap.instanceCount;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ return { buffer, count };
155
+ }