@forgeax/engine-render 0.1.33 → 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 (518) hide show
  1. package/README.md +1010 -124
  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/dynamic-geometry-host.d.ts +4 -1
  11. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  12. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  13. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  14. package/dist/assembly/factory.d.ts +1 -1
  15. package/dist/assembly/factory.d.ts.map +1 -1
  16. package/dist/assembly/host-contract.d.ts +3 -3
  17. package/dist/assembly/host-contract.d.ts.map +1 -1
  18. package/dist/assembly/material/assembly.d.ts.map +1 -1
  19. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  20. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  21. package/dist/assembly/material-shader-policy.d.ts +16 -2
  22. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  23. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  24. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  25. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  26. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  27. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  28. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  29. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  30. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  31. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  32. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  33. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  34. package/dist/assembly/renderer-inspection.d.ts +11 -0
  35. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  36. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  37. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  38. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  39. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  40. package/dist/assembly/webgpu-ready.d.ts +1 -1
  41. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  42. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  43. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  44. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  45. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  46. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  47. package/dist/authoring.mjs +1 -1
  48. package/dist/barrel-distortion.d.ts +47 -0
  49. package/dist/barrel-distortion.d.ts.map +1 -0
  50. package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
  51. package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
  52. package/dist/{chunk-ZDQWGQW7.mjs → chunk-HEB564WF.mjs} +4 -4
  53. package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-HEB564WF.mjs.map} +1 -1
  54. package/dist/{chunk-VOZWDM3L.mjs → chunk-MKDIT2EM.mjs} +1307 -188
  55. package/dist/chunk-MKDIT2EM.mjs.map +1 -0
  56. package/dist/{chunk-LEAXOMYJ.mjs → chunk-OCDLEI6I.mjs} +3 -3
  57. package/dist/{chunk-LEAXOMYJ.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
  58. package/dist/chunk-ODZWR6JQ.mjs +4927 -0
  59. package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
  60. package/dist/{chunk-3RTCJTH4.mjs → chunk-SHFUFJ5N.mjs} +184 -13
  61. package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
  62. package/dist/{chunk-OO3DRYK7.mjs → chunk-UI5SFODX.mjs} +176 -96
  63. package/dist/chunk-UI5SFODX.mjs.map +1 -0
  64. package/dist/{chunk-PLAXOOX5.mjs → chunk-UINHLCZA.mjs} +561 -79
  65. package/dist/chunk-UINHLCZA.mjs.map +1 -0
  66. package/dist/{chunk-NB2S7ZRX.mjs → chunk-WEX45HKH.mjs} +127 -386
  67. package/dist/chunk-WEX45HKH.mjs.map +1 -0
  68. package/dist/cloud/density.d.ts +55 -0
  69. package/dist/cloud/density.d.ts.map +1 -0
  70. package/dist/cloud/extract.d.ts +25 -0
  71. package/dist/cloud/extract.d.ts.map +1 -0
  72. package/dist/cloud/feature.d.ts +57 -0
  73. package/dist/cloud/feature.d.ts.map +1 -0
  74. package/dist/cloud/frame-context.d.ts +8 -0
  75. package/dist/cloud/frame-context.d.ts.map +1 -0
  76. package/dist/cloud/inspection.d.ts +59 -0
  77. package/dist/cloud/inspection.d.ts.map +1 -0
  78. package/dist/cloud/optics.d.ts +56 -0
  79. package/dist/cloud/optics.d.ts.map +1 -0
  80. package/dist/cloud/parameters.d.ts +73 -0
  81. package/dist/cloud/parameters.d.ts.map +1 -0
  82. package/dist/cloud/resources.d.ts +60 -0
  83. package/dist/cloud/resources.d.ts.map +1 -0
  84. package/dist/cloud/shadow.d.ts +42 -0
  85. package/dist/cloud/shadow.d.ts.map +1 -0
  86. package/dist/cloud/temporal.d.ts +74 -0
  87. package/dist/cloud/temporal.d.ts.map +1 -0
  88. package/dist/components/barrel-distortion.d.ts +13 -0
  89. package/dist/components/barrel-distortion.d.ts.map +1 -0
  90. package/dist/components/cloud-layer.d.ts +29 -0
  91. package/dist/components/cloud-layer.d.ts.map +1 -0
  92. package/dist/components/index.d.ts +2 -0
  93. package/dist/components/index.d.ts.map +1 -1
  94. package/dist/components/instances.d.ts +20 -6
  95. package/dist/components/instances.d.ts.map +1 -1
  96. package/dist/construct-renderer.d.ts +1 -1
  97. package/dist/construct-renderer.d.ts.map +1 -1
  98. package/dist/construct-renderer.mjs +6759 -2875
  99. package/dist/construct-renderer.mjs.map +1 -1
  100. package/dist/dynamic-geometry.d.ts +5 -1
  101. package/dist/dynamic-geometry.d.ts.map +1 -1
  102. package/dist/errors/cloud.d.ts +59 -0
  103. package/dist/errors/cloud.d.ts.map +1 -0
  104. package/dist/errors/render.d.ts +18 -4
  105. package/dist/errors/render.d.ts.map +1 -1
  106. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  107. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  108. package/dist/extract/camera.d.ts.map +1 -1
  109. package/dist/extract/contracts.d.ts +5 -1
  110. package/dist/extract/contracts.d.ts.map +1 -1
  111. package/dist/features/barrel-distortion.d.ts +29 -0
  112. package/dist/features/barrel-distortion.d.ts.map +1 -0
  113. package/dist/features/error-reporting.d.ts +6 -2
  114. package/dist/features/error-reporting.d.ts.map +1 -1
  115. package/dist/features/host.d.ts +10 -0
  116. package/dist/features/host.d.ts.map +1 -1
  117. package/dist/features/plan.d.ts +8 -0
  118. package/dist/features/plan.d.ts.map +1 -1
  119. package/dist/features/render-graph-contribution.d.ts +5 -0
  120. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  121. package/dist/features/render-graph-raster.d.ts +1 -0
  122. package/dist/features/render-graph-raster.d.ts.map +1 -1
  123. package/dist/features/targets.d.ts +2 -0
  124. package/dist/features/targets.d.ts.map +1 -1
  125. package/dist/features/types.d.ts +44 -0
  126. package/dist/features/types.d.ts.map +1 -1
  127. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  128. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  129. package/dist/gpu-dirty-ranges.d.ts +11 -0
  130. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  131. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  132. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  133. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  134. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  135. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  136. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  137. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  138. package/dist/gpu-driven/production-raster.d.ts +47 -3
  139. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  140. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  141. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  142. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  143. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  144. package/dist/gpu-driven/view-gpu.d.ts +26 -2
  145. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  146. package/dist/gpu-scene.d.ts +5 -0
  147. package/dist/gpu-scene.d.ts.map +1 -1
  148. package/dist/hdrp-buffers.d.ts +2 -2
  149. package/dist/hdrp-buffers.d.ts.map +1 -1
  150. package/dist/ibl/skylight-bind-group.d.ts +10 -1
  151. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  152. package/dist/index.d.ts +27 -7
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.mjs +258 -8
  155. package/dist/index.mjs.map +1 -1
  156. package/dist/inspection-types.d.ts +135 -1
  157. package/dist/inspection-types.d.ts.map +1 -1
  158. package/dist/instance-buffer-cache.d.ts +4 -4
  159. package/dist/instance-buffer-cache.d.ts.map +1 -1
  160. package/dist/instances.d.ts +48 -100
  161. package/dist/instances.d.ts.map +1 -1
  162. package/dist/internal.mjs +7 -7
  163. package/dist/pbr-pipeline.d.ts +19 -1
  164. package/dist/pbr-pipeline.d.ts.map +1 -1
  165. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  166. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  167. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  168. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  169. package/dist/pipeline/standard-output/types.d.ts +4 -2
  170. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  171. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  172. package/dist/pipeline/standard-post.d.ts.map +1 -1
  173. package/dist/pipeline-builder.d.ts +1 -1
  174. package/dist/pipeline-builder.d.ts.map +1 -1
  175. package/dist/plugin.d.ts.map +1 -1
  176. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  177. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  178. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  179. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  180. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  181. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  182. package/dist/record/fold-buckets.d.ts +95 -0
  183. package/dist/record/fold-buckets.d.ts.map +1 -0
  184. package/dist/record/fold-instance-buffer.d.ts +6 -0
  185. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  186. package/dist/record/frame-lighting.d.ts +1 -0
  187. package/dist/record/frame-lighting.d.ts.map +1 -1
  188. package/dist/record/frame-snapshot.d.ts +37 -3
  189. package/dist/record/frame-snapshot.d.ts.map +1 -1
  190. package/dist/record/frame.d.ts +10 -61
  191. package/dist/record/frame.d.ts.map +1 -1
  192. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  193. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  194. package/dist/record/gpu-timing.d.ts +8 -0
  195. package/dist/record/gpu-timing.d.ts.map +1 -1
  196. package/dist/record/main-pass-geometry.d.ts +21 -5
  197. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  198. package/dist/record/main-pass-material.d.ts +7 -1
  199. package/dist/record/main-pass-material.d.ts.map +1 -1
  200. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  201. package/dist/record/main-pass.d.ts +13 -2
  202. package/dist/record/main-pass.d.ts.map +1 -1
  203. package/dist/record/motion-blur-receipt.d.ts +11 -0
  204. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  205. package/dist/record/probe-blend-buffer.d.ts +16 -0
  206. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  207. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  208. package/dist/record/render-context.d.ts +22 -3
  209. package/dist/record/render-context.d.ts.map +1 -1
  210. package/dist/record/shadow-pass.d.ts +2 -0
  211. package/dist/record/shadow-pass.d.ts.map +1 -1
  212. package/dist/record/skybox-post-pass.d.ts +1 -1
  213. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  214. package/dist/record/typed-frame-graph.d.ts +22 -2
  215. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  216. package/dist/record/view-ubo.d.ts +11 -3
  217. package/dist/record/view-ubo.d.ts.map +1 -1
  218. package/dist/record/volume-params.d.ts +9 -0
  219. package/dist/record/volume-params.d.ts.map +1 -0
  220. package/dist/recovery/render-system-candidate.d.ts +10 -0
  221. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  222. package/dist/reflection/record-owner.d.ts.map +1 -1
  223. package/dist/render-contract.d.ts +42 -4
  224. package/dist/render-contract.d.ts.map +1 -1
  225. package/dist/render-graph-primitives.d.ts.map +1 -1
  226. package/dist/render-pipeline.d.ts +103 -2
  227. package/dist/render-pipeline.d.ts.map +1 -1
  228. package/dist/render-system-extract-tail.d.ts +3 -2
  229. package/dist/render-system-extract-tail.d.ts.map +1 -1
  230. package/dist/render-system-extract.d.ts +16 -9
  231. package/dist/render-system-extract.d.ts.map +1 -1
  232. package/dist/render-system-presentation.d.ts +23 -0
  233. package/dist/render-system-presentation.d.ts.map +1 -0
  234. package/dist/render-system-producer-roots.d.ts +10 -0
  235. package/dist/render-system-producer-roots.d.ts.map +1 -0
  236. package/dist/render-system-residency.d.ts +12 -0
  237. package/dist/render-system-residency.d.ts.map +1 -0
  238. package/dist/render-system.d.ts +19 -14
  239. package/dist/render-system.d.ts.map +1 -1
  240. package/dist/scene/probe-blend.d.ts +27 -0
  241. package/dist/scene/probe-blend.d.ts.map +1 -1
  242. package/dist/scene/render-scene.d.ts +12 -5
  243. package/dist/scene/render-scene.d.ts.map +1 -1
  244. package/dist/ssao-buffers.d.ts +9 -0
  245. package/dist/ssao-buffers.d.ts.map +1 -1
  246. package/dist/surface/dynamic-input.d.ts +133 -0
  247. package/dist/surface/dynamic-input.d.ts.map +1 -0
  248. package/dist/surface/gpu-driven.d.ts +41 -0
  249. package/dist/surface/gpu-driven.d.ts.map +1 -0
  250. package/dist/surface/submission-observation.d.ts +136 -0
  251. package/dist/surface/submission-observation.d.ts.map +1 -0
  252. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  253. package/dist/temporal/gpu.d.ts +13 -1
  254. package/dist/temporal/gpu.d.ts.map +1 -1
  255. package/dist/temporal/index.mjs +5 -5
  256. package/dist/temporal/inspection.d.ts.map +1 -1
  257. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  258. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  259. package/dist/transmission/single-layer-medium.d.ts +89 -0
  260. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  261. package/dist/typed-render-graph-primitives.d.ts +14 -2
  262. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  263. package/dist/volume/component.d.ts +9 -4
  264. package/dist/volume/component.d.ts.map +1 -1
  265. package/dist/volume/extract.d.ts +1 -1
  266. package/dist/volume/extract.d.ts.map +1 -1
  267. package/dist/volume/inspection.d.ts +2 -0
  268. package/dist/volume/inspection.d.ts.map +1 -1
  269. package/dist/volume/passes.d.ts +4 -1
  270. package/dist/volume/passes.d.ts.map +1 -1
  271. package/dist/volume/resources.d.ts.map +1 -1
  272. package/package.json +22 -21
  273. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  274. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  275. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  276. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  277. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  278. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  279. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  280. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  281. package/src/__tests__/factory-contract.integration.test.ts +295 -45
  282. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  283. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  284. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  285. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  286. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  287. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  288. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
  289. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  290. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
  291. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
  292. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  293. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  294. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  295. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  296. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  297. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  298. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  299. package/src/__tests__/gpu-scene.unit.test.ts +119 -9
  300. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  301. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  302. package/src/__tests__/instances-store.unit.test.ts +97 -305
  303. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  304. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
  305. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  306. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  307. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  308. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  309. package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
  310. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  311. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  312. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  313. package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
  314. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  315. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  316. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  317. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  318. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  319. package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
  320. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  321. package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
  322. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  323. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  324. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  325. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  326. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
  327. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  328. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  329. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  330. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
  331. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  332. package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
  333. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  334. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  335. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  336. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  337. package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
  338. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  339. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  340. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  341. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  342. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  343. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  344. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  345. package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
  346. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  347. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  348. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  349. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  350. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  351. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  352. package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
  353. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
  354. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  355. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  356. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  357. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
  358. package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
  359. package/src/assembly/backend-contract.ts +30 -0
  360. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  361. package/src/assembly/canvas-draw-guard.ts +11 -0
  362. package/src/assembly/cloud-shadow-entry.ts +22 -0
  363. package/src/assembly/dynamic-geometry-host.ts +65 -37
  364. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  365. package/src/assembly/factory.ts +2 -30
  366. package/src/assembly/host-contract.ts +3 -3
  367. package/src/assembly/material/assembly.ts +25 -13
  368. package/src/assembly/material/pipeline-helpers.ts +53 -12
  369. package/src/assembly/material-shader-policy.ts +55 -0
  370. package/src/assembly/material-shader-prewarm.ts +21 -10
  371. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  372. package/src/assembly/recovery/renderer-recover.ts +41 -18
  373. package/src/assembly/render-feature-post-processes.ts +54 -0
  374. package/src/assembly/renderer-facade.ts +4 -1
  375. package/src/assembly/renderer-feature-inspection.ts +8 -2
  376. package/src/assembly/renderer-frame-transaction.ts +23 -0
  377. package/src/assembly/renderer-inspection.ts +28 -0
  378. package/src/assembly/skin-palette-owner.ts +1 -1
  379. package/src/assembly/temporal-post-process-prewarm.ts +3 -3
  380. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  381. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  382. package/src/assembly/webgpu-ready.ts +115 -61
  383. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  384. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  385. package/src/assembly/webgpu-renderer.ts +214 -252
  386. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  387. package/src/barrel-distortion.ts +247 -0
  388. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  389. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  390. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  391. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  392. package/src/cloud/density.ts +600 -0
  393. package/src/cloud/extract.ts +110 -0
  394. package/src/cloud/feature.ts +1810 -0
  395. package/src/cloud/frame-context.ts +42 -0
  396. package/src/cloud/inspection.ts +130 -0
  397. package/src/cloud/optics.ts +285 -0
  398. package/src/cloud/parameters.ts +255 -0
  399. package/src/cloud/resources.ts +122 -0
  400. package/src/cloud/shadow.ts +167 -0
  401. package/src/cloud/temporal.ts +226 -0
  402. package/src/components/barrel-distortion.ts +46 -0
  403. package/src/components/cloud-layer.ts +47 -0
  404. package/src/components/index.ts +2 -0
  405. package/src/components/instances.ts +18 -45
  406. package/src/components/sprite-instances.ts +1 -1
  407. package/src/construct-renderer.ts +1 -1
  408. package/src/dynamic-geometry.ts +12 -1
  409. package/src/errors/cloud.ts +103 -0
  410. package/src/errors/render.ts +44 -7
  411. package/src/examples/single-layer-medium-surface.ts +59 -0
  412. package/src/extract/camera.ts +15 -1
  413. package/src/extract/contracts.ts +5 -0
  414. package/src/features/barrel-distortion.ts +172 -0
  415. package/src/features/error-reporting.ts +26 -6
  416. package/src/features/host.ts +115 -14
  417. package/src/features/plan.ts +8 -0
  418. package/src/features/render-graph-contribution.ts +9 -0
  419. package/src/features/render-graph-raster.ts +45 -3
  420. package/src/features/targets.ts +66 -0
  421. package/src/features/types.ts +47 -0
  422. package/src/fullscreen-post-process-pass.ts +41 -9
  423. package/src/gpu-dirty-ranges.ts +48 -0
  424. package/src/gpu-driven/batch-topology.ts +53 -0
  425. package/src/gpu-driven/material-artifacts.ts +33 -25
  426. package/src/gpu-driven/prepared-draw.ts +12 -4
  427. package/src/gpu-driven/production-raster-material.ts +1894 -0
  428. package/src/gpu-driven/production-raster.ts +825 -784
  429. package/src/gpu-driven/resource-allocation.ts +142 -0
  430. package/src/gpu-driven/shadow-ownership.ts +71 -0
  431. package/src/gpu-driven/view-gpu.ts +164 -10
  432. package/src/gpu-scene.ts +75 -84
  433. package/src/hdrp-buffers.ts +4 -3
  434. package/src/ibl/skylight-bind-group.ts +49 -7
  435. package/src/index.ts +196 -9
  436. package/src/inspection-types.ts +162 -0
  437. package/src/instance-buffer-cache.ts +4 -4
  438. package/src/instances.ts +149 -569
  439. package/src/pbr-pipeline.ts +219 -13
  440. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  441. package/src/pipeline/standard-forward-lane.ts +313 -57
  442. package/src/pipeline/standard-output/graph.ts +8 -2
  443. package/src/pipeline/standard-output/types.ts +12 -1
  444. package/src/pipeline/standard-pipeline.ts +291 -18
  445. package/src/pipeline/standard-post.ts +90 -24
  446. package/src/pipeline-builder.ts +1 -1
  447. package/src/plugin.ts +4 -0
  448. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  449. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  450. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  451. package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
  452. package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
  453. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  454. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  455. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  456. package/src/record/barrel-distortion-frame.ts +110 -0
  457. package/src/record/dynamic-geometry-consumption.ts +39 -9
  458. package/src/record/fold-buckets.ts +852 -0
  459. package/src/record/fold-instance-buffer.ts +51 -0
  460. package/src/record/frame-lighting.ts +36 -2
  461. package/src/record/frame-snapshot.ts +39 -3
  462. package/src/record/frame.ts +217 -1084
  463. package/src/record/gpu-draw-receipts.ts +38 -0
  464. package/src/record/gpu-timing.ts +48 -5
  465. package/src/record/main-pass-geometry.ts +251 -82
  466. package/src/record/main-pass-material.ts +66 -4
  467. package/src/record/main-pass-sprite-draws.ts +7 -65
  468. package/src/record/main-pass.ts +156 -20
  469. package/src/record/motion-blur-receipt.ts +91 -0
  470. package/src/record/probe-blend-buffer.ts +180 -0
  471. package/src/record/recovery-pipeline.ts +35 -3
  472. package/src/record/render-context.ts +39 -3
  473. package/src/record/shadow-pass.ts +30 -1
  474. package/src/record/skybox-post-pass.ts +28 -4
  475. package/src/record/typed-frame-graph.ts +770 -134
  476. package/src/record/view-ubo.ts +26 -3
  477. package/src/record/volume-params.ts +225 -0
  478. package/src/recovery/render-system-candidate.ts +235 -42
  479. package/src/reflection/record-owner.ts +7 -3
  480. package/src/render-contract.ts +48 -4
  481. package/src/render-graph-primitives.ts +7 -1
  482. package/src/render-pipeline.ts +130 -0
  483. package/src/render-system-extract-tail.ts +57 -61
  484. package/src/render-system-extract.ts +74 -76
  485. package/src/render-system-presentation.ts +56 -0
  486. package/src/render-system-producer-roots.ts +96 -0
  487. package/src/render-system-residency.ts +159 -0
  488. package/src/render-system.ts +347 -363
  489. package/src/scene/probe-blend.ts +96 -4
  490. package/src/scene/render-scene.ts +349 -280
  491. package/src/ssao-buffers.ts +95 -2
  492. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  493. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  494. package/src/surface/dynamic-input.ts +658 -0
  495. package/src/surface/gpu-driven.ts +147 -0
  496. package/src/surface/submission-observation.ts +517 -0
  497. package/src/systems/skin-palette-allocator.ts +4 -1
  498. package/src/temporal/gpu.ts +101 -17
  499. package/src/temporal/inspection.ts +7 -1
  500. package/src/temporal/standard-scene-data.ts +5 -0
  501. package/src/temporal/target-coverage-attachment.ts +4 -0
  502. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  503. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  504. package/src/transmission/single-layer-medium.ts +322 -0
  505. package/src/typed-render-graph-primitives.ts +70 -2
  506. package/src/volume/component.ts +10 -9
  507. package/src/volume/extract.ts +11 -5
  508. package/src/volume/inspection.ts +3 -0
  509. package/src/volume/passes.ts +87 -4
  510. package/src/volume/resources.ts +2 -1
  511. package/dist/chunk-3RTCJTH4.mjs.map +0 -1
  512. package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
  513. package/dist/chunk-NNQL7CB3.mjs +0 -1713
  514. package/dist/chunk-NNQL7CB3.mjs.map +0 -1
  515. package/dist/chunk-OO3DRYK7.mjs.map +0 -1
  516. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
  517. package/dist/chunk-PLAXOOX5.mjs.map +0 -1
  518. package/dist/chunk-VOZWDM3L.mjs.map +0 -1
@@ -14,7 +14,6 @@ import {
14
14
  } from '@forgeax/engine-geometry';
15
15
  import type {
16
16
  BindGroupLayout,
17
- Buffer,
18
17
  PipelineLayout,
19
18
  RenderPipeline,
20
19
  Result,
@@ -28,6 +27,9 @@ import {
28
27
  type MaterialShaderEntry,
29
28
  type MaterialShaderManifestEntry,
30
29
  ShaderCatalog,
30
+ SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
31
+ SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
32
+ SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
31
33
  standardPhysicalTextureFields,
32
34
  } from '@forgeax/engine-shader';
33
35
  import type {
@@ -53,6 +55,10 @@ import {
53
55
  RenderFeatureCapabilityMissingError,
54
56
  RenderFeatureStageFailedError,
55
57
  } from '../errors/render';
58
+ import {
59
+ BARREL_DISTORTION_FEATURE_IDENTITY,
60
+ createBarrelDistortionRenderFeature,
61
+ } from '../features/barrel-distortion';
56
62
  import {
57
63
  dofInspection,
58
64
  registerDepthOfFieldBuiltins,
@@ -74,9 +80,13 @@ import {
74
80
  isCanonicalStandardPbrMaterialShader,
75
81
  isStandardPbrMaterialShader,
76
82
  type PipelineGroup2Contract,
77
- resolvePipelineGroup2Contract,
78
83
  SKIN_MATERIAL_SHADER_ID,
79
84
  } from '../pbr-pipeline';
85
+ import {
86
+ SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID,
87
+ SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID,
88
+ SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID,
89
+ } from '../pipeline/single-layer-medium-passes';
80
90
  import { standardPipeline } from '../pipeline/standard-pipeline';
81
91
  import { DEFAULT_STANDARD_PROFILE } from '../pipeline/standard-profile';
82
92
  import { buildPipelineForMaterialShader } from '../pipeline-builder';
@@ -132,7 +142,7 @@ import type {
132
142
  SsrShaderSources,
133
143
  VolumetricFogShaderSources,
134
144
  } from '../render-contract';
135
- import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from '../render-contract';
145
+ import { FXAA_POST_PROCESS_ID, STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from '../render-contract';
136
146
  import {
137
147
  attachGpuPassTimingSession,
138
148
  createRenderSystem,
@@ -149,7 +159,9 @@ import { tilemapChunkExtractSystem } from '../tilemap-chunk-extract-system';
149
159
  import type { TypedFrameObservationCapture } from '../typed-render-graph-primitives';
150
160
  import { registerAnalyticFogPostProcess } from './analytic-fog-registration';
151
161
  import type { RhiBackendPack } from './backend-contract';
162
+ import { inspectBarrelDistortion } from './barrel-distortion-inspection';
152
163
  import type { BundlerOptions } from './bundler-contract';
164
+ import { rejectZeroCanvasSize } from './canvas-draw-guard';
153
165
  import { createRendererDynamicGeometryController } from './dynamic-geometry-host';
154
166
  import { registerFxaaPostProcess } from './fxaa-registration';
155
167
  import type { RendererAssemblyImplementation } from './host-contract';
@@ -157,6 +169,7 @@ import { observeLodOcclusionForReceipt } from './lod-observation';
157
169
  import {
158
170
  isEngineOwnedMaterialShader,
159
171
  resolveMaterialPipelineBindGroups,
172
+ resolveMaterialPipelineGroup2Contract,
160
173
  resolveMaterialPipelineShaderId,
161
174
  resolveMaterialPipelineVertexEntry,
162
175
  resolveRendererMaterialShaderArtifact,
@@ -169,6 +182,7 @@ import {
169
182
  type MaterialShaderBindingContract,
170
183
  makeShaderDeviceAdapter,
171
184
  normalizeMaterialShaderVariantSet,
185
+ prepareLowLimitMaterialShaderEntry,
172
186
  prepareMaterialShaders,
173
187
  resolveMaterialShaderBackendArtifactKey,
174
188
  resolveMaterialShaderBindingContract,
@@ -188,6 +202,7 @@ import {
188
202
  publishGeneration,
189
203
  } from './recovery/generation';
190
204
  import { createRendererRecovery, type RendererRecovery } from './recovery/renderer-recover';
205
+ import { collectRequiredFullscreenPostProcesses } from './render-feature-post-processes';
191
206
  import { createRenderTargetHost } from './render-target-host';
192
207
  import {
193
208
  freezeRenderProfile,
@@ -198,6 +213,7 @@ import { projectRendererFeatureInspection } from './renderer-feature-inspection'
198
213
  import {
199
214
  type ContinuationTerminator,
200
215
  createContinuationTerminator,
216
+ guardFrameCompletion,
201
217
  } from './renderer-frame-transaction';
202
218
  import {
203
219
  ensureContextConfigured,
@@ -205,7 +221,7 @@ import {
205
221
  rendererInitializationPipelineError,
206
222
  wrapDisposeError,
207
223
  } from './renderer-helpers';
208
- import { projectRendererOutputInspection } from './renderer-inspection';
224
+ import { projectRendererOutputInspectionFromSurface } from './renderer-inspection';
209
225
  import {
210
226
  createRecoveryContinuation,
211
227
  createRecoveryDeadline,
@@ -229,7 +245,10 @@ import {
229
245
  type WebGPURendererInternals,
230
246
  } from './webgpu-renderer-bootstrap';
231
247
  import type { WebGPUOutcome } from './webgpu-renderer-contract';
232
- import { disposeObservationCaptureSet } from './webgpu-renderer-observation';
248
+ import {
249
+ createRendererObservationCaptureOwner,
250
+ type ObservationCaptureRead,
251
+ } from './webgpu-renderer-observation-owner';
233
252
  import {
234
253
  isPreparedMaterialVertexLayout,
235
254
  PREPARED_INSTANCE_VERTEX_ATTRS,
@@ -257,6 +276,7 @@ export {
257
276
  selectNoColorPbrVariant,
258
277
  selectPipelineLayoutForVariant,
259
278
  shouldDeferMissingPreparedMaterialShader,
279
+ stripCloudShadowBindingsForLowLimit,
260
280
  } from './material-shader-policy';
261
281
  export {
262
282
  createMeshSsboGrowController,
@@ -333,7 +353,13 @@ async function makeWebGPURenderer(
333
353
  let renderTargetDevice = internals.device;
334
354
  let renderTargetGeneration = 0;
335
355
  let renderSystemForTargetPromotion: RenderSystem | undefined;
336
- const featureHostResult = createRenderFeatureHost(internals.options?.features ?? []);
356
+ const requestedFeatures = internals.options?.features ?? [];
357
+ const featureHostFeatures = requestedFeatures.some(
358
+ (f) => f.identity === BARREL_DISTORTION_FEATURE_IDENTITY,
359
+ )
360
+ ? requestedFeatures
361
+ : [...requestedFeatures, createBarrelDistortionRenderFeature()];
362
+ const featureHostResult = createRenderFeatureHost(featureHostFeatures);
337
363
  if (!featureHostResult.ok) throw featureHostResult.error;
338
364
  internals.featureHost = featureHostResult.value;
339
365
  let rendererRecovery: RendererRecovery | undefined;
@@ -466,27 +492,8 @@ async function makeWebGPURenderer(
466
492
  featureHostResult.value.features.flatMap((feature) => feature.requiredMaterialShaders ?? []),
467
493
  );
468
494
  let requiredMaterialShaders = Object.freeze([...requiredMaterialShaderSet]);
469
- const collectRequiredFullscreenPostProcesses = (
470
- features: readonly RenderFeature<unknown>[],
471
- ): readonly { readonly identity: string; readonly source: string }[] => {
472
- const entries = new Map<string, { readonly identity: string; readonly source: string }>();
473
- for (const feature of features) {
474
- for (const entry of feature.requiredFullscreenPostProcesses ?? []) {
475
- const existing = entries.get(entry.identity);
476
- if (existing !== undefined && existing.source !== entry.source) {
477
- throw new RhiError({
478
- code: 'internal-error',
479
- expected: `fullscreen identity '${entry.identity}' has one source across render features`,
480
- hint: 'rename the conflicting fullscreen identity or make its WGSL source identical',
481
- });
482
- }
483
- entries.set(entry.identity, entry);
484
- }
485
- }
486
- return Object.freeze([...entries.values()]);
487
- };
488
- let requiredFullscreenPostProcesses = collectRequiredFullscreenPostProcesses(
489
- featureHostResult.value.features,
495
+ let requiredFullscreenPostProcesses = Object.freeze(
496
+ collectRequiredFullscreenPostProcesses(featureHostResult.value.features),
490
497
  );
491
498
  // Lazy ShaderCatalog instance (plan-strategy section S-10 / D-R10 / OQ-5
492
499
  // close): constructed on first access; subsequent accesses return the
@@ -536,7 +543,7 @@ async function makeWebGPURenderer(
536
543
  feature: RenderFeature<unknown>,
537
544
  ): Promise<Result<void, RhiError>> => {
538
545
  for (const postProcess of feature.requiredFullscreenPostProcesses ?? []) {
539
- const label = postProcessShaderModuleLabel(postProcess.identity, postProcess.source);
546
+ const label = postProcessShaderModuleLabel(postProcess.source);
540
547
  const shaderResult = internals.pack.createShaderModule
541
548
  ? await internals.pack.createShaderModule(internals.device, {
542
549
  code: postProcess.source,
@@ -1137,6 +1144,9 @@ async function makeWebGPURenderer(
1137
1144
  const lookup = getShader().findMaterialArtifact(materialShaderId);
1138
1145
  const source = lookup.ok ? lookup.value.source : '';
1139
1146
  const paramSchema = lookup.ok ? lookup.value.paramSchema : explicitParamSchema;
1147
+ const singleLayerMedium =
1148
+ materialShaderId === 'forgeax::single-layer-medium' ||
1149
+ (lookup.ok && lookup.value.receipt?.surface?.model === 'single-layer-medium');
1140
1150
  if (paramSchema === undefined) return null;
1141
1151
  const cacheKey = `${materialShaderId}:${layoutKind}:${clustered}`;
1142
1152
  const cached = cacheState.perShaderMaterialLayoutCache.get(cacheKey);
@@ -1155,7 +1165,12 @@ async function makeWebGPURenderer(
1155
1165
  isStandardPbrMaterialShader(materialShaderId) ||
1156
1166
  standardPhysicalTextureFields(paramSchema).length > 0;
1157
1167
  const isStandardMapLayout = requiresStandardMapLayout;
1158
- if (!clustered && !isStandardMapLayout && isSharedMaterialUserRegionCompatible(paramSchema)) {
1168
+ if (
1169
+ !clustered &&
1170
+ !singleLayerMedium &&
1171
+ !isStandardMapLayout &&
1172
+ isSharedMaterialUserRegionCompatible(paramSchema)
1173
+ ) {
1159
1174
  cacheState.perShaderMaterialLayoutCache.set(cacheKey, {
1160
1175
  source,
1161
1176
  paramSchema,
@@ -1165,7 +1180,11 @@ async function makeWebGPURenderer(
1165
1180
  return null;
1166
1181
  }
1167
1182
  const spec: PipelineSpec = {
1168
- shader: { id: materialShaderId, passKind: 'forward', variantSet: undefined },
1183
+ shader: {
1184
+ id: singleLayerMedium ? 'forgeax::single-layer-medium' : materialShaderId,
1185
+ passKind: 'forward',
1186
+ variantSet: undefined,
1187
+ },
1169
1188
  attachments: { colorFormats: [], depthFormat: undefined, sampleCount: 1 },
1170
1189
  geometry: { topology: 'triangle-list', vertexLayout: {} },
1171
1190
  renderState: undefined,
@@ -1552,7 +1571,11 @@ async function makeWebGPURenderer(
1552
1571
  : getShaderModuleAdapter(),
1553
1572
  pipelineLayout,
1554
1573
  vertexBuffers,
1555
- ...(layoutKind === 'pbr-skin' || layoutKind === 'gpu-driven-skin' ? { layoutKind } : {}),
1574
+ ...(layoutKind === 'pbr-skin' ||
1575
+ layoutKind === 'gpu-driven-skin' ||
1576
+ layoutKind === 'gpu-driven-cluster-skin'
1577
+ ? { layoutKind }
1578
+ : {}),
1556
1579
  };
1557
1580
  };
1558
1581
  /**
@@ -1619,7 +1642,10 @@ async function makeWebGPURenderer(
1619
1642
  particleInputLanes?: number,
1620
1643
  coverageOnly = false,
1621
1644
  ): RenderPipeline | null => {
1622
- const declaredGroup2Contract = resolvePipelineGroup2Contract(entry.source);
1645
+ const declaredGroup2Contract = resolveMaterialPipelineGroup2Contract(
1646
+ entry.source,
1647
+ layoutKindOverride,
1648
+ );
1623
1649
  const group2Contract =
1624
1650
  declaredGroup2Contract === 'mesh' &&
1625
1651
  (materialShaderId === 'forgeax::vfx-render.particles.mesh' ||
@@ -2048,6 +2074,10 @@ async function makeWebGPURenderer(
2048
2074
  }
2049
2075
  }
2050
2076
  }
2077
+ shaderEntry = prepareLowLimitMaterialShaderEntry(
2078
+ shaderEntry,
2079
+ currentBuildDevice().limits.maxSampledTexturesPerShaderStage,
2080
+ );
2051
2081
  // feat-20260609 M4 / R3-fixup: append `-${passKind}` to the PSO label so
2052
2082
  // GPU debug captures (and the shadow-caster branch in the builder)
2053
2083
  // make the cache variant visible. The fallback path above keeps the
@@ -2115,10 +2145,50 @@ async function makeWebGPURenderer(
2115
2145
  ) => {
2116
2146
  const pipeline = getMaterialShaderPipeline(...args);
2117
2147
  if (pipeline === null) return null;
2148
+ const materialShaderId = args[0];
2149
+ const variantSet = args[5];
2150
+ const passKind = args[6] ?? 'forward';
2151
+ const vertexLayoutProjection = args[13];
2152
+ const layoutKind = args[15];
2153
+ const sceneIndexAddress =
2154
+ layoutKind === 'gpu-driven-pbr' ||
2155
+ layoutKind === 'gpu-driven-skin' ||
2156
+ layoutKind === 'gpu-driven-cluster-pbr' ||
2157
+ layoutKind === 'gpu-driven-cluster-skin';
2158
+ const artifact = resolveRendererMaterialShaderArtifact(
2159
+ materialShaderId,
2160
+ getShader(),
2161
+ pipelineState?.gpuDrivenPbrPrograms,
2162
+ {
2163
+ ...(vertexLayoutProjection === undefined
2164
+ ? {}
2165
+ : {
2166
+ vertexColorAvailable: vertexLayoutProjection.attributes.some(
2167
+ (attribute) => attribute.key === 'color',
2168
+ ),
2169
+ }),
2170
+ ...(layoutKind === 'pbr-skin' ||
2171
+ layoutKind === 'gpu-driven-skin' ||
2172
+ layoutKind === 'gpu-driven-cluster-skin'
2173
+ ? { deformation: 'skin' as const }
2174
+ : {}),
2175
+ ...(variantSet === undefined ? {} : { variantSet }),
2176
+ address: sceneIndexAddress ? 'scene-index' : 'direct',
2177
+ pass: passKind === 'shadow-caster' ? 'shadow' : 'forward',
2178
+ },
2179
+ );
2118
2180
  return {
2119
2181
  pipeline,
2120
2182
  group2Contract:
2121
2183
  materialShaderPipelineGroup2Contracts.get(pipeline as object) ?? ('mesh' as const),
2184
+ ...(artifact?.receipt === undefined
2185
+ ? {}
2186
+ : {
2187
+ receipt: {
2188
+ identity: artifact.receipt.receiptIdentity,
2189
+ generation: artifact.receipt.generation,
2190
+ },
2191
+ }),
2122
2192
  };
2123
2193
  };
2124
2194
  const getParamSchema = (materialShaderId: string) => {
@@ -2172,10 +2242,11 @@ async function makeWebGPURenderer(
2172
2242
  colorFormats: readonly GPUTextureFormat[],
2173
2243
  label: string,
2174
2244
  ): RenderPipeline | null => {
2245
+ const isFxaaPipeline = label.startsWith(`post-process-${FXAA_POST_PROCESS_ID}-pso-`);
2175
2246
  const moduleFactory = getShaderModuleAdapter();
2176
2247
  const moduleResult = moduleFactory.createShaderModule({
2177
2248
  code: entry.source,
2178
- label: `${label}-module`,
2249
+ label: postProcessShaderModuleLabel(entry.source),
2179
2250
  });
2180
2251
  if (!moduleResult.ok) {
2181
2252
  // 'rhi-not-available' = async compile in flight: caller falls back one frame.
@@ -2186,7 +2257,7 @@ async function makeWebGPURenderer(
2186
2257
  }
2187
2258
  return null;
2188
2259
  }
2189
- if (currentEmptyPostProcessBgl() === null) {
2260
+ if (!isFxaaPipeline && entry.usesView !== true && currentEmptyPostProcessBgl() === null) {
2190
2261
  const bglRes = currentBuildDevice().createBindGroupLayout({ entries: [] });
2191
2262
  if (!bglRes.ok) {
2192
2263
  internals.errorRegistry.fire(bglRes.error);
@@ -2199,9 +2270,18 @@ async function makeWebGPURenderer(
2199
2270
  emptyPostProcessBgl = bglRes.value;
2200
2271
  }
2201
2272
  }
2273
+ const viewLayout =
2274
+ entry.usesView === true ? currentPipelineState()?.viewBindGroupLayout : undefined;
2275
+ const group0Layout = viewLayout ?? currentEmptyPostProcessBgl();
2276
+ if (group0Layout === null || group0Layout === undefined) {
2277
+ internals.errorRegistry.fire(
2278
+ new Error('fullscreen post-process View layout is unavailable') as never,
2279
+ );
2280
+ return null;
2281
+ }
2202
2282
  const layoutRes = currentBuildDevice().createPipelineLayout({
2203
2283
  label: `${label}-layout`,
2204
- bindGroupLayouts: [currentEmptyPostProcessBgl() as BindGroupLayout, bgl],
2284
+ bindGroupLayouts: isFxaaPipeline ? [bgl] : [group0Layout as BindGroupLayout, bgl],
2205
2285
  });
2206
2286
  if (!layoutRes.ok) {
2207
2287
  internals.errorRegistry.fire(layoutRes.error);
@@ -2439,6 +2519,22 @@ async function makeWebGPURenderer(
2439
2519
  });
2440
2520
  attachGpuPassTimingSession(internals, gpuPassTimingSession);
2441
2521
  renderSystemForTargetPromotion = renderSystem;
2522
+ renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID, {
2523
+ source: SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
2524
+ reads: ['input', { key: 'scene-depth', sampleType: 'depth' }],
2525
+ });
2526
+ const pairedMsaaReads = [
2527
+ { key: 'input', sampleType: 'multisampled-float' as const },
2528
+ { key: 'scene-depth', sampleType: 'depth' as const },
2529
+ ];
2530
+ renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID, {
2531
+ source: SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
2532
+ reads: pairedMsaaReads,
2533
+ });
2534
+ renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID, {
2535
+ source: SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
2536
+ reads: pairedMsaaReads,
2537
+ });
2442
2538
  if (
2443
2539
  internals.device.caps.backendKind === 'null' &&
2444
2540
  Array.from(getShader().entries()).length === 0
@@ -2475,183 +2571,33 @@ async function makeWebGPURenderer(
2475
2571
  const receiptTimings = new WeakMap<FrameReceipt, Promise<VolumeTimingObservation>>();
2476
2572
  let latestReceipt: FrameReceipt | undefined;
2477
2573
  let pendingObservationDomains: readonly FrameObservationDomain[] | undefined;
2478
- let observationAllocationCount = 0;
2479
- let observationLiveCount = 0;
2480
- let observationPeakLiveCount = 0;
2481
- let observationMapCount = 0;
2482
- let observationReadbackCount = 0;
2483
- let observationLiveByteLength = 0;
2484
- const observationCaptureOwner = (() => {
2485
- const capturesByFrame = new Map<number, TypedFrameObservationCapture[]>();
2486
- return {
2487
- register(capture: TypedFrameObservationCapture): void {
2488
- const captures = capturesByFrame.get(capture.frameNumber) ?? [];
2489
- captures.push(capture);
2490
- capturesByFrame.set(capture.frameNumber, captures);
2491
- observationAllocationCount += 1;
2492
- observationLiveCount += 1;
2493
- observationPeakLiveCount = Math.max(observationPeakLiveCount, observationLiveCount);
2494
- observationLiveByteLength += capture.bytesPerRow * capture.height;
2495
- },
2496
- consume(frameNumber: number): readonly TypedFrameObservationCapture[] {
2497
- const captures = capturesByFrame.get(frameNumber) ?? [];
2498
- capturesByFrame.delete(frameNumber);
2499
- return Object.freeze(captures);
2500
- },
2501
- drain(): readonly TypedFrameObservationCapture[] {
2502
- const captures = [...capturesByFrame.values()].flat();
2503
- capturesByFrame.clear();
2504
- return Object.freeze(captures);
2505
- },
2506
- };
2507
- })();
2574
+ const observationOwner = createRendererObservationCaptureOwner((error) => {
2575
+ internals.errorRegistry.fire(error);
2576
+ });
2577
+ const {
2578
+ observationCaptureOwner,
2579
+ stats: observationStats,
2580
+ receiptObservationCaptures,
2581
+ receiptObservationBuffers,
2582
+ destroyedObservationBuffers,
2583
+ disposeObservationCaptures,
2584
+ disposeOwnedObservationCaptures,
2585
+ readObservationCapture,
2586
+ disposeReceiptObservationCaptures,
2587
+ } = observationOwner;
2508
2588
  Object.assign(internals, { observationCaptureOwner });
2509
- let expectedObservationGraphGeneration: number | undefined;
2510
2589
  Object.defineProperty(internals, 'observationGraphGeneration', {
2511
2590
  configurable: true,
2512
- get: () => expectedObservationGraphGeneration,
2591
+ get: () => observationOwner.expectedGraphGeneration,
2513
2592
  set: (generation: number | undefined) => {
2514
- expectedObservationGraphGeneration = generation;
2593
+ observationOwner.expectedGraphGeneration = generation;
2515
2594
  },
2516
2595
  });
2517
- type ObservationCaptureRead = () => Promise<
2518
- RenderResult<
2519
- readonly {
2520
- readonly capture: TypedFrameObservationCapture;
2521
- readonly bytes: Uint8Array;
2522
- }[],
2523
- RenderError
2524
- >
2525
- >;
2526
- const receiptObservationCaptures = new Map<FrameReceipt, ObservationCaptureRead>();
2527
- const receiptObservationBuffers = new Map<
2528
- FrameReceipt,
2529
- readonly TypedFrameObservationCapture[]
2530
- >();
2531
- const destroyedObservationBuffers = new WeakSet<Buffer>();
2532
- const observationBufferCleanupFailures = new WeakMap<Buffer, RendererContractFailureError>();
2533
- const failedObservationCaptures = new Map<Buffer, TypedFrameObservationCapture>();
2534
- const disposeObservationCaptures = (
2535
- captures: readonly TypedFrameObservationCapture[],
2536
- ): RendererContractFailureError | undefined => {
2537
- const wasDestroyed = new Set(
2538
- captures
2539
- .filter((capture) => destroyedObservationBuffers.has(capture.buffer))
2540
- .map((capture) => capture.buffer),
2541
- );
2542
- const result = disposeObservationCaptureSet(
2543
- captures,
2544
- destroyedObservationBuffers,
2545
- observationBufferCleanupFailures,
2546
- (failure) => internals.errorRegistry.fire(failure),
2547
- );
2548
- for (const capture of captures) {
2549
- if (!wasDestroyed.has(capture.buffer) && destroyedObservationBuffers.has(capture.buffer)) {
2550
- observationLiveCount = Math.max(0, observationLiveCount - 1);
2551
- observationLiveByteLength = Math.max(
2552
- 0,
2553
- observationLiveByteLength - capture.bytesPerRow * capture.height,
2554
- );
2555
- }
2556
- }
2557
- return result;
2558
- };
2559
- const disposeOwnedObservationCaptures = (
2560
- captures: readonly TypedFrameObservationCapture[],
2561
- ): RendererContractFailureError | undefined => {
2562
- const failure = disposeObservationCaptures(captures);
2563
- if (failure !== undefined) {
2564
- for (const capture of captures) {
2565
- if (!destroyedObservationBuffers.has(capture.buffer)) {
2566
- failedObservationCaptures.set(capture.buffer, capture);
2567
- }
2568
- }
2569
- }
2570
- return failure;
2571
- };
2572
- const readObservationCapture = async (
2573
- capture: TypedFrameObservationCapture,
2574
- ): Promise<RenderResult<Uint8Array, RenderError>> => {
2575
- try {
2576
- if (typeof capture.buffer.mapAsync !== 'function') {
2577
- const cleanupFailure = disposeObservationCaptures([capture]);
2578
- return err(
2579
- cleanupFailure ??
2580
- new RendererContractFailureError(
2581
- 'observe',
2582
- `the ${capture.domain} receipt-bound readback backend has no mapAsync capability`,
2583
- ),
2584
- );
2585
- }
2586
- observationMapCount += 1;
2587
- const mapped = await capture.buffer.mapAsync(1);
2588
- if (!mapped.ok) {
2589
- const cleanupFailure = disposeObservationCaptures([capture]);
2590
- return err(
2591
- cleanupFailure ??
2592
- new RendererContractFailureError(
2593
- 'observe',
2594
- `mapping ${capture.domain} receipt-bound readback failed: ${mapped.error.code}`,
2595
- ),
2596
- );
2597
- }
2598
- const range = mapped.value.getMappedRange();
2599
- if (!range.ok) {
2600
- mapped.value.unmap();
2601
- const cleanupFailure = disposeObservationCaptures([capture]);
2602
- return err(
2603
- cleanupFailure ??
2604
- new RendererContractFailureError(
2605
- 'observe',
2606
- `reading ${capture.domain} receipt-bound readback failed: ${range.error.code}`,
2607
- ),
2608
- );
2609
- }
2610
- const bytes = new Uint8Array(range.value.slice(0));
2611
- mapped.value.unmap();
2612
- observationReadbackCount += 1;
2613
- const cleanupFailure = disposeObservationCaptures([capture]);
2614
- if (cleanupFailure !== undefined) return err(cleanupFailure);
2615
- return ok(bytes);
2616
- } catch (cause) {
2617
- const cleanupFailure = disposeObservationCaptures([capture]);
2618
- return err(
2619
- cleanupFailure ??
2620
- new RendererContractFailureError(
2621
- 'observe',
2622
- `reading ${capture.domain} receipt-bound readback threw: ${
2623
- cause instanceof Error ? cause.message : String(cause)
2624
- }`,
2625
- ),
2626
- );
2627
- }
2628
- };
2629
-
2630
- const disposeReceiptObservationCaptures = (): RendererContractFailureError | undefined => {
2631
- let firstFailure: RendererContractFailureError | undefined;
2632
- for (const [receipt, captures] of receiptObservationBuffers) {
2633
- const failure = disposeObservationCaptures(captures);
2634
- firstFailure ??= failure;
2635
- if (captures.every((capture) => destroyedObservationBuffers.has(capture.buffer))) {
2636
- receiptObservationBuffers.delete(receipt);
2637
- }
2638
- }
2639
- receiptObservationCaptures.clear();
2640
- const retryCaptures = [...failedObservationCaptures.values()];
2641
- const retryFailure = disposeObservationCaptures(retryCaptures);
2642
- firstFailure ??= retryFailure;
2643
- for (const capture of retryCaptures) {
2644
- if (destroyedObservationBuffers.has(capture.buffer)) {
2645
- failedObservationCaptures.delete(capture.buffer);
2646
- }
2647
- }
2648
- const ownedFailure = disposeOwnedObservationCaptures(observationCaptureOwner.drain());
2649
- firstFailure ??= ownedFailure;
2650
- return firstFailure;
2651
- };
2652
2596
  let surfaceReleased = false;
2653
2597
  const renderer: RendererAssemblyImplementation = {
2654
- instances: renderSystem.instances,
2598
+ setSurfaceDynamicInput(frame) {
2599
+ renderSystem.setSurfaceDynamicInput(frame);
2600
+ },
2655
2601
  attach(world: World): RenderResult<RenderWorldLease, RenderError> {
2656
2602
  const attached = this.attachScene(world);
2657
2603
  if (!attached.ok) {
@@ -2714,25 +2660,29 @@ async function makeWebGPURenderer(
2714
2660
  ? 'faulted'
2715
2661
  : 'alive';
2716
2662
  const graph = deviceLost ? undefined : renderSystem.perFrameGraphInfo;
2663
+ const graphResourceAllocation = graph?.resourceAllocation;
2664
+ const graphGenerationAllocation = deviceLost
2665
+ ? undefined
2666
+ : renderSystem.renderGraphGenerationAllocation;
2717
2667
  const standardLighting = deviceLost ? undefined : renderSystem.standardLightingInspection;
2668
+ const barrelDistortion = inspectBarrelDistortion(
2669
+ disposed,
2670
+ deviceLost,
2671
+ surfaceReleased,
2672
+ frameId,
2673
+ activeDeviceScope.generation,
2674
+ renderSystem.barrelDistortionInspection,
2675
+ );
2718
2676
  const bloom: BloomInspection = deviceLost ? emptyBloomInspection() : renderSystem.bloom;
2719
- const surfaceStorage = pipelineState?.format ?? 'rgba8unorm';
2720
- const surfaceDisplay = pipelineState?.colorAttachmentFormat ?? 'rgba8unorm';
2721
2677
  const observationId = `${STANDARD_OUTPUT_TRANSFORM_FEATURE_ID}:frame-${frameId}`;
2722
- const outputInspection = projectRendererOutputInspection({
2678
+ const outputInspection = projectRendererOutputInspectionFromSurface({
2723
2679
  graph,
2724
- surfaceAvailable: !surfaceReleased && pipelineState !== null,
2725
- surfaceStorage,
2726
- surfaceDisplay,
2727
- ...(pipelineState?.surfaceProfile === undefined
2728
- ? {}
2729
- : { surfaceProfile: pipelineState.surfaceProfile }),
2680
+ surfaceReleased,
2681
+ pipelineState,
2730
2682
  rgba16floatRenderable: internals.device.caps.rgba16floatRenderable,
2731
2683
  autoExposure: renderSystem.autoExposure,
2732
2684
  standardLut: renderSystem.standardLut,
2733
- ...(internals.context?.presentationProof === undefined
2734
- ? {}
2735
- : { presentationProof: internals.context.presentationProof }),
2685
+ presentationProof: internals.context?.presentationProof,
2736
2686
  });
2737
2687
  const volumetricFog = renderSystem.volumetricFog;
2738
2688
  const directionalShadow = renderSystem.directionalShadow;
@@ -2747,6 +2697,7 @@ async function makeWebGPURenderer(
2747
2697
  frameId,
2748
2698
  deviceGeneration: activeDeviceScope.generation,
2749
2699
  }),
2700
+ barrelDistortion,
2750
2701
  ...projectRendererFeatureInspection(internals.featureHost),
2751
2702
  featureGraph: renderSystem.featureGraphInspection,
2752
2703
  materialTextureSources: renderSystem.materialTextureSources,
@@ -2756,9 +2707,6 @@ async function makeWebGPURenderer(
2756
2707
  renderSystem.instanceCollectionsInspection.map((collection) =>
2757
2708
  Object.freeze({
2758
2709
  ...collection,
2759
- dirtyRanges: Object.freeze(
2760
- collection.dirtyRanges.map((range) => Object.freeze({ ...range })),
2761
- ),
2762
2710
  uploadRanges: Object.freeze(
2763
2711
  collection.uploadRanges.map((range) => Object.freeze({ ...range })),
2764
2712
  ),
@@ -2775,6 +2723,12 @@ async function makeWebGPURenderer(
2775
2723
  ),
2776
2724
  dynamicGeometry: dynamicGeometry.inspect(),
2777
2725
  renderScene: renderSystem.renderScene,
2726
+ ...(graphResourceAllocation === undefined
2727
+ ? {}
2728
+ : { renderGraphResourceAllocation: graphResourceAllocation }),
2729
+ ...(graphGenerationAllocation === undefined
2730
+ ? {}
2731
+ : { renderGraphGenerationAllocation: graphGenerationAllocation }),
2778
2732
  ...(renderSystem.iblBinding === undefined ? {} : { iblBinding: renderSystem.iblBinding }),
2779
2733
  reflectionProbes: renderSystem.reflectionProbes,
2780
2734
  ssrDependencies: renderSystem.ssrDependencies,
@@ -2855,12 +2809,12 @@ async function makeWebGPURenderer(
2855
2809
  ? {}
2856
2810
  : { standardOutputColor: Object.freeze({ ...outputInspection.standardOutputColor }) }),
2857
2811
  resourceStats: Object.freeze({
2858
- allocationCount: observationAllocationCount,
2859
- liveCount: observationLiveCount,
2860
- peakLiveCount: observationPeakLiveCount,
2861
- mapCount: observationMapCount,
2862
- readbackCount: observationReadbackCount,
2863
- liveByteLength: observationLiveByteLength,
2812
+ allocationCount: observationStats.allocationCount,
2813
+ liveCount: observationStats.liveCount,
2814
+ peakLiveCount: observationStats.peakLiveCount,
2815
+ mapCount: observationStats.mapCount,
2816
+ readbackCount: observationStats.readbackCount,
2817
+ liveByteLength: observationStats.liveByteLength,
2864
2818
  }),
2865
2819
  }),
2866
2820
  });
@@ -3212,6 +3166,9 @@ async function makeWebGPURenderer(
3212
3166
  ...(frameRequest.profileFrame === undefined
3213
3167
  ? {}
3214
3168
  : { profileFrame: frameRequest.profileFrame }),
3169
+ ...(frameRequest.geometryLane === undefined
3170
+ ? {}
3171
+ : { geometryLane: frameRequest.geometryLane }),
3215
3172
  }
3216
3173
  : (options ?? { cameraOwner: 0, resourceOwner: 0 });
3217
3174
  // feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M5 / w21
@@ -3239,6 +3196,8 @@ async function makeWebGPURenderer(
3239
3196
  }),
3240
3197
  );
3241
3198
  }
3199
+ const canvasSizeError = rejectZeroCanvasSize(internals.canvas.width, internals.canvas.height);
3200
+ if (canvasSizeError !== undefined) return err(canvasSizeError);
3242
3201
  // M2 / w9 (A-IN-5): device-lost guard — draw() silently returns err
3243
3202
  // without firing onError each frame. The device-lost channel fires once
3244
3203
  // through the dual-channel fan-out (:750-797); draw() does not repeat it
@@ -3400,34 +3359,30 @@ async function makeWebGPURenderer(
3400
3359
  );
3401
3360
  const continuation = createContinuationTerminator();
3402
3361
  frameContinuations.add(continuation);
3403
- const guardedCompletion = completion.then(
3362
+ const guardedCompletion = guardFrameCompletion(
3363
+ completion,
3364
+ () => continuation.guard('queue-completion'),
3404
3365
  () =>
3405
- continuation.guard('queue-completion')
3406
- ? ok(undefined)
3407
- : err(
3408
- new RendererOperationError('device-operation-failed', {
3409
- operation: 'complete-frame',
3410
- frameId: receiptFrameId,
3411
- deviceGeneration: receiptGeneration,
3412
- cause: structuredRendererCause(
3413
- {
3414
- code: 'stale-generation',
3415
- expected: 'frame completion belongs to its device generation',
3416
- hint: 'discard the stale receipt',
3417
- },
3418
- 'complete-frame',
3419
- ),
3420
- }),
3421
- ),
3366
+ new RendererOperationError('device-operation-failed', {
3367
+ operation: 'complete-frame',
3368
+ frameId: receiptFrameId,
3369
+ deviceGeneration: receiptGeneration,
3370
+ cause: structuredRendererCause(
3371
+ {
3372
+ code: 'stale-generation',
3373
+ expected: 'frame completion belongs to its device generation',
3374
+ hint: 'discard the stale receipt',
3375
+ },
3376
+ 'complete-frame',
3377
+ ),
3378
+ }),
3422
3379
  (cause: unknown) =>
3423
- err(
3424
- new RendererOperationError('device-operation-failed', {
3425
- operation: 'complete-frame',
3426
- frameId: receiptFrameId,
3427
- deviceGeneration: receiptGeneration,
3428
- cause: structuredRendererCause(cause, 'complete-frame'),
3429
- }),
3430
- ),
3380
+ new RendererOperationError('device-operation-failed', {
3381
+ operation: 'complete-frame',
3382
+ frameId: receiptFrameId,
3383
+ deviceGeneration: receiptGeneration,
3384
+ cause: structuredRendererCause(cause, 'complete-frame'),
3385
+ }),
3431
3386
  );
3432
3387
  const terminated = continuation.promise().then((reason) =>
3433
3388
  err(
@@ -3455,12 +3410,17 @@ async function makeWebGPURenderer(
3455
3410
  });
3456
3411
  const captures = observationCaptureOwner.consume(receiptFrameId);
3457
3412
  pendingObservationDomains = undefined;
3458
- const receiptGraphGeneration = timingHost.observationGraphGeneration ?? 0;
3413
+ const receiptGraphGeneration =
3414
+ timingHost.observationGraphGeneration ?? renderSystem.perFrameGraphInfo?.generation ?? 0;
3459
3415
  const receipt = Object.freeze({
3460
3416
  frameId: receiptFrameId,
3461
3417
  deviceGeneration: receiptGeneration,
3418
+ presentation: renderSystem.presentation,
3462
3419
  backendId: internals.device.caps.backendKind,
3463
3420
  graphGeneration: receiptGraphGeneration,
3421
+ ...(renderSystem.lastSuccessfulBarrelDistortion === undefined
3422
+ ? {}
3423
+ : { barrelDistortion: renderSystem.lastSuccessfulBarrelDistortion }),
3464
3424
  completed,
3465
3425
  });
3466
3426
  renderTargetHost.onFrameSubmitted(completed);
@@ -4055,6 +4015,8 @@ async function makeWebGPURenderer(
4055
4015
  setCandidateEmptyPostProcessBgl(layout) {
4056
4016
  candidateEmptyPostProcessBgl = layout;
4057
4017
  },
4018
+ getShaderModuleAdapter,
4019
+ getImmediateShaderModuleAdapter,
4058
4020
  getShader,
4059
4021
  assets,
4060
4022
  adaptMipmapShaderModuleFactory,