@forgeax/engine-render 0.1.4 → 0.1.7

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 (979) hide show
  1. package/README.md +268 -640
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts +2 -0
  4. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts.map +1 -0
  5. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts +2 -0
  6. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts.map +1 -0
  7. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts +2 -0
  8. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts.map +1 -0
  9. package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -1
  10. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +6 -0
  11. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -1
  12. package/dist/{gpu-driven/view-reference.d.ts → __tests__/gpu-driven-view-reference.d.ts} +4 -4
  13. package/dist/__tests__/gpu-driven-view-reference.d.ts.map +1 -0
  14. package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -1
  15. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts +2 -0
  16. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts.map +1 -0
  17. package/dist/__tests__/morph-feature-plan.unit.test.d.ts +2 -0
  18. package/dist/__tests__/morph-feature-plan.unit.test.d.ts.map +1 -0
  19. package/dist/__tests__/render-feature-plan.test-d.d.ts +2 -0
  20. package/dist/__tests__/render-feature-plan.test-d.d.ts.map +1 -0
  21. package/dist/__tests__/render-feature-plan.unit.test.d.ts +2 -0
  22. package/dist/__tests__/render-feature-plan.unit.test.d.ts.map +1 -0
  23. package/dist/__tests__/ssao-config.unit.test.d.ts +2 -0
  24. package/dist/__tests__/ssao-config.unit.test.d.ts.map +1 -0
  25. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts +2 -0
  26. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts.map +1 -0
  27. package/dist/__tests__/standard-descriptors.test-d.d.ts +2 -0
  28. package/dist/__tests__/standard-descriptors.test-d.d.ts.map +1 -0
  29. package/dist/__tests__/standard-pipeline.dawn.test.d.ts +2 -0
  30. package/dist/__tests__/standard-pipeline.dawn.test.d.ts.map +1 -0
  31. package/dist/__tests__/standard-pipeline.integration.test.d.ts +2 -0
  32. package/dist/__tests__/standard-pipeline.integration.test.d.ts.map +1 -0
  33. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts +2 -0
  34. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts.map +1 -0
  35. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts +2 -0
  36. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts.map +1 -0
  37. package/dist/{renderer/backend-selection.d.ts → assembly/backend-contract.d.ts} +15 -4
  38. package/dist/assembly/backend-contract.d.ts.map +1 -0
  39. package/dist/assembly/factory.d.ts +214 -0
  40. package/dist/assembly/factory.d.ts.map +1 -0
  41. package/dist/assembly/host-contract.d.ts +84 -0
  42. package/dist/assembly/host-contract.d.ts.map +1 -0
  43. package/dist/{renderer → assembly}/material/assembly.d.ts +0 -1
  44. package/dist/{renderer → assembly}/material/assembly.d.ts.map +1 -1
  45. package/dist/assembly/material/pipeline-projection.d.ts +30 -0
  46. package/dist/assembly/material/pipeline-projection.d.ts.map +1 -0
  47. package/dist/authoring.d.ts +11 -11
  48. package/dist/authoring.d.ts.map +1 -1
  49. package/dist/authoring.mjs +25 -3
  50. package/dist/authoring.mjs.map +1 -1
  51. package/dist/chunk-CQXZC5XI.mjs +182 -0
  52. package/dist/chunk-CQXZC5XI.mjs.map +1 -0
  53. package/dist/chunk-HCOGPHKS.mjs +93 -0
  54. package/dist/chunk-HCOGPHKS.mjs.map +1 -0
  55. package/dist/chunk-YEJIUW7D.mjs +1152 -0
  56. package/dist/chunk-YEJIUW7D.mjs.map +1 -0
  57. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +2 -0
  58. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +1 -0
  59. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +2 -0
  60. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.map +1 -0
  61. package/dist/components/__tests__/schema-contract.unit.test.d.ts +2 -0
  62. package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +1 -0
  63. package/dist/components/glyph-text.d.ts +1 -1
  64. package/dist/components/glyph-text.d.ts.map +1 -1
  65. package/dist/components/index.d.ts +4 -2
  66. package/dist/components/index.d.ts.map +1 -1
  67. package/dist/components/instances.d.ts +1 -1
  68. package/dist/components/instances.d.ts.map +1 -1
  69. package/dist/components/light-helpers.d.ts +1 -1
  70. package/dist/components/light-helpers.d.ts.map +1 -1
  71. package/dist/components/lines.d.ts +5 -0
  72. package/dist/components/lines.d.ts.map +1 -0
  73. package/dist/components/mesh-filter.d.ts +7 -7
  74. package/dist/components/mesh-filter.d.ts.map +1 -1
  75. package/dist/components/points.d.ts +15 -0
  76. package/dist/components/points.d.ts.map +1 -0
  77. package/dist/components/scene-instance.d.ts +11 -11
  78. package/dist/components/skybox-background.d.ts +56 -0
  79. package/dist/components/skybox-background.d.ts.map +1 -0
  80. package/dist/components/skylight.d.ts +55 -0
  81. package/dist/components/skylight.d.ts.map +1 -0
  82. package/dist/components/sprite-animation.d.ts +2 -3
  83. package/dist/components/sprite-animation.d.ts.map +1 -1
  84. package/dist/components/sprite-instances.d.ts +1 -1
  85. package/dist/components/sprite-playback-mode.d.ts +6 -1
  86. package/dist/components/sprite-playback-mode.d.ts.map +1 -1
  87. package/dist/components/sprite-region-override.d.ts +2 -3
  88. package/dist/components/sprite-region-override.d.ts.map +1 -1
  89. package/dist/components/tile-layer.d.ts +5 -0
  90. package/dist/components/tile-layer.d.ts.map +1 -1
  91. package/dist/construct-renderer.d.ts +18 -1
  92. package/dist/construct-renderer.d.ts.map +1 -1
  93. package/dist/construct-renderer.mjs +27463 -4
  94. package/dist/construct-renderer.mjs.map +1 -1
  95. package/dist/debug-draw-glue.d.ts +2 -53
  96. package/dist/debug-draw-glue.d.ts.map +1 -1
  97. package/dist/device/device-scope.d.ts +83 -0
  98. package/dist/device/device-scope.d.ts.map +1 -0
  99. package/dist/{gpu-resource-store.d.ts → device/gpu-residency.d.ts} +91 -48
  100. package/dist/device/gpu-residency.d.ts.map +1 -0
  101. package/dist/device/resource-types.d.ts +8 -0
  102. package/dist/device/resource-types.d.ts.map +1 -0
  103. package/dist/engine-metrics.d.ts +2 -2
  104. package/dist/engine-metrics.d.ts.map +1 -1
  105. package/dist/errors/recover.d.ts +28 -1
  106. package/dist/errors/recover.d.ts.map +1 -1
  107. package/dist/errors/render.d.ts +320 -248
  108. package/dist/errors/render.d.ts.map +1 -1
  109. package/dist/features/fullscreen.d.ts +19 -0
  110. package/dist/features/fullscreen.d.ts.map +1 -0
  111. package/dist/features/host.d.ts +32 -26
  112. package/dist/features/host.d.ts.map +1 -1
  113. package/dist/features/morph/morph-feature.d.ts +39 -5
  114. package/dist/features/morph/morph-feature.d.ts.map +1 -1
  115. package/dist/features/plan.d.ts +182 -0
  116. package/dist/features/plan.d.ts.map +1 -0
  117. package/dist/features/prepared-gpu-work.d.ts +21 -17
  118. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  119. package/dist/features/prepared-graphics-store.d.ts +2 -1
  120. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  121. package/dist/features/prepared-graphics.d.ts +11 -21
  122. package/dist/features/prepared-graphics.d.ts.map +1 -1
  123. package/dist/features/render-graph-compute.d.ts +2 -2
  124. package/dist/features/render-graph-compute.d.ts.map +1 -1
  125. package/dist/features/render-graph-contribution.d.ts +4 -7
  126. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  127. package/dist/features/render-graph-raster.d.ts +7 -3
  128. package/dist/features/render-graph-raster.d.ts.map +1 -1
  129. package/dist/features/render-graph-resources.d.ts +6 -6
  130. package/dist/features/render-graph-resources.d.ts.map +1 -1
  131. package/dist/features/targets.d.ts +5 -5
  132. package/dist/features/targets.d.ts.map +1 -1
  133. package/dist/features/types.d.ts +11 -190
  134. package/dist/features/types.d.ts.map +1 -1
  135. package/dist/features/vocabulary.d.ts +14 -0
  136. package/dist/features/vocabulary.d.ts.map +1 -0
  137. package/dist/fullscreen-post-process-pass.d.ts +4 -25
  138. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  139. package/dist/glyph-text-layout-system.d.ts +3 -2
  140. package/dist/glyph-text-layout-system.d.ts.map +1 -1
  141. package/dist/gpu-driven/batch-topology.d.ts +6 -75
  142. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  143. package/dist/gpu-driven/production-raster.d.ts +13 -112
  144. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  145. package/dist/gpu-driven/view-gpu.d.ts +10 -66
  146. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  147. package/dist/gpu-resource.d.ts +3 -3
  148. package/dist/gpu-scene-schema.d.ts +1 -94
  149. package/dist/gpu-scene-schema.d.ts.map +1 -1
  150. package/dist/gpu-scene.d.ts +7 -33
  151. package/dist/gpu-scene.d.ts.map +1 -1
  152. package/dist/hdrp-buffers.d.ts +3 -53
  153. package/dist/hdrp-buffers.d.ts.map +1 -1
  154. package/dist/ibl/IblPipelineCache.d.ts +74 -180
  155. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  156. package/dist/ibl/skylight-bind-group.d.ts +1 -1
  157. package/dist/index.d.ts +17 -43
  158. package/dist/index.d.ts.map +1 -1
  159. package/dist/index.mjs +167 -3
  160. package/dist/index.mjs.map +1 -1
  161. package/dist/inspection-types.d.ts +72 -0
  162. package/dist/inspection-types.d.ts.map +1 -0
  163. package/dist/instance-buffer-cache.d.ts +1 -4
  164. package/dist/instance-buffer-cache.d.ts.map +1 -1
  165. package/dist/internal.d.ts +1 -73
  166. package/dist/internal.d.ts.map +1 -1
  167. package/dist/internal.mjs +1 -43
  168. package/dist/internal.mjs.map +1 -1
  169. package/dist/lifecycle.d.ts +36 -2
  170. package/dist/lifecycle.d.ts.map +1 -1
  171. package/dist/materials.d.ts +0 -3
  172. package/dist/materials.d.ts.map +1 -1
  173. package/dist/mesh-material-bindings.d.ts +0 -1
  174. package/dist/mesh-material-bindings.d.ts.map +1 -1
  175. package/dist/pbr-pipeline.d.ts +77 -29
  176. package/dist/pbr-pipeline.d.ts.map +1 -1
  177. package/dist/pipeline/standard-forward-lane.d.ts +5 -0
  178. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -0
  179. package/dist/pipeline/standard-pipeline.d.ts +31 -0
  180. package/dist/pipeline/standard-pipeline.d.ts.map +1 -0
  181. package/dist/pipeline/standard-profile.d.ts +40 -0
  182. package/dist/pipeline/standard-profile.d.ts.map +1 -0
  183. package/dist/pipeline-builder.d.ts +3 -3
  184. package/dist/pipeline-builder.d.ts.map +1 -1
  185. package/dist/pipeline-spec-types.d.ts +24 -0
  186. package/dist/pipeline-spec-types.d.ts.map +1 -0
  187. package/dist/pipeline-spec.d.ts +16 -155
  188. package/dist/pipeline-spec.d.ts.map +1 -1
  189. package/dist/plugin.d.ts +1 -14
  190. package/dist/plugin.d.ts.map +1 -1
  191. package/dist/points-lines/__tests__/bounds.unit.test.d.ts +2 -0
  192. package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +1 -0
  193. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +2 -0
  194. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +1 -0
  195. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +2 -0
  196. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +1 -0
  197. package/dist/points-lines/__tests__/inspection.unit.test.d.ts +2 -0
  198. package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +1 -0
  199. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +2 -0
  200. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +1 -0
  201. package/dist/points-lines/__tests__/points-lines.bench.d.ts +2 -0
  202. package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +1 -0
  203. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +2 -0
  204. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +1 -0
  205. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +2 -0
  206. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +1 -0
  207. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +2 -0
  208. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +1 -0
  209. package/dist/points-lines/admission.d.ts +36 -0
  210. package/dist/points-lines/admission.d.ts.map +1 -0
  211. package/dist/points-lines/bounds.d.ts +8 -0
  212. package/dist/points-lines/bounds.d.ts.map +1 -0
  213. package/dist/points-lines/expansion-cache.d.ts +28 -0
  214. package/dist/points-lines/expansion-cache.d.ts.map +1 -0
  215. package/dist/points-lines/inspection.d.ts +53 -0
  216. package/dist/points-lines/inspection.d.ts.map +1 -0
  217. package/dist/points-lines/prepare.d.ts +67 -0
  218. package/dist/points-lines/prepare.d.ts.map +1 -0
  219. package/dist/points-lines/record.d.ts +60 -0
  220. package/dist/points-lines/record.d.ts.map +1 -0
  221. package/dist/points-lines/snapshot.d.ts +49 -0
  222. package/dist/points-lines/snapshot.d.ts.map +1 -0
  223. package/dist/post-process-errors.d.ts +18 -18
  224. package/dist/post-process-errors.d.ts.map +1 -1
  225. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -5
  226. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  227. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +2 -0
  228. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +1 -0
  229. package/dist/record/frame-lighting.d.ts +7 -73
  230. package/dist/record/frame-lighting.d.ts.map +1 -1
  231. package/dist/record/frame-snapshot.d.ts +44 -44
  232. package/dist/record/frame-snapshot.d.ts.map +1 -1
  233. package/dist/record/frame-targets.d.ts +5 -38
  234. package/dist/record/frame-targets.d.ts.map +1 -1
  235. package/dist/record/frame.d.ts +64 -52
  236. package/dist/record/frame.d.ts.map +1 -1
  237. package/dist/record/helpers.d.ts +3 -2
  238. package/dist/record/helpers.d.ts.map +1 -1
  239. package/dist/record/main-pass-geometry.d.ts +12 -4
  240. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  241. package/dist/record/main-pass-material.d.ts +90 -59
  242. package/dist/record/main-pass-material.d.ts.map +1 -1
  243. package/dist/record/main-pass-sprite-draws.d.ts +28 -3
  244. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  245. package/dist/record/main-pass.d.ts +1 -1
  246. package/dist/record/main-pass.d.ts.map +1 -1
  247. package/dist/record/mesh-ssbo.d.ts +276 -3
  248. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  249. package/dist/record/render-context.d.ts +252 -0
  250. package/dist/record/render-context.d.ts.map +1 -0
  251. package/dist/record/shadow-pass.d.ts +15 -88
  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/typed-frame-graph.d.ts +29 -7
  256. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  257. package/dist/record/view-ubo.d.ts +9 -3
  258. package/dist/record/view-ubo.d.ts.map +1 -1
  259. package/dist/render-contract.d.ts +424 -0
  260. package/dist/render-contract.d.ts.map +1 -0
  261. package/dist/render-data.d.ts.map +1 -1
  262. package/dist/render-graph-primitives.d.ts +14 -362
  263. package/dist/render-graph-primitives.d.ts.map +1 -1
  264. package/dist/render-pipeline.d.ts +25 -64
  265. package/dist/render-pipeline.d.ts.map +1 -1
  266. package/dist/render-system-extract.d.ts +110 -338
  267. package/dist/render-system-extract.d.ts.map +1 -1
  268. package/dist/render-system.d.ts +24 -713
  269. package/dist/render-system.d.ts.map +1 -1
  270. package/dist/scene/render-scene-types.d.ts +61 -0
  271. package/dist/scene/render-scene-types.d.ts.map +1 -0
  272. package/dist/scene/render-scene.d.ts +112 -0
  273. package/dist/scene/render-scene.d.ts.map +1 -0
  274. package/dist/scene-instances/post-spawn-resolve-joints.d.ts +2 -5
  275. package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -1
  276. package/dist/ssao-buffers.d.ts +22 -3
  277. package/dist/ssao-buffers.d.ts.map +1 -1
  278. package/dist/systems/skin-palette-allocator.d.ts +2 -4
  279. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  280. package/dist/systems/skin-palette-types.d.ts +14 -0
  281. package/dist/systems/skin-palette-types.d.ts.map +1 -0
  282. package/dist/systems/transparent-sort-config.d.ts +23 -2
  283. package/dist/systems/transparent-sort-config.d.ts.map +1 -1
  284. package/dist/tilemap-chunk-extract-system.d.ts +4 -3
  285. package/dist/tilemap-chunk-extract-system.d.ts.map +1 -1
  286. package/dist/typed-render-graph-primitives.d.ts +2 -4
  287. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  288. package/dist/typed-shadow-passes.d.ts +3 -3
  289. package/dist/typed-shadow-passes.d.ts.map +1 -1
  290. package/package.json +23 -23
  291. package/src/__tests__/authoring-path.unit.test.ts +9 -0
  292. package/src/__tests__/backend-selection-rhi-capture.test-d.ts +1 -1
  293. package/src/__tests__/callback-inference.test-d.ts +6 -3
  294. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -4
  295. package/src/__tests__/construct-renderer-identity.unit.test.ts +15 -2
  296. package/src/__tests__/device-scope-lifecycle.unit.test.ts +151 -0
  297. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +42 -0
  298. package/src/__tests__/direct-extract-consumer-contract.test-d.ts +8 -19
  299. package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -13
  300. package/src/__tests__/factory-contract.integration.test.ts +158 -209
  301. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +1 -4
  302. package/src/__tests__/frame-observation.contract.test.ts +17 -8
  303. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
  304. package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +6 -11
  305. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +21 -18
  306. package/src/__tests__/gpu-driven-production.integration.test.ts +32 -205
  307. package/src/__tests__/gpu-driven-scaling.unit.test.ts +4 -7
  308. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +87 -8
  309. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +170 -8
  310. package/src/{gpu-driven/view-reference.ts → __tests__/gpu-driven-view-reference.ts} +4 -3
  311. package/src/__tests__/gpu-driven-view.browser.test.ts +12 -1
  312. package/src/__tests__/gpu-driven-view.dawn.test.ts +12 -1
  313. package/src/__tests__/gpu-driven-view.unit.test.ts +11 -267
  314. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +3 -3
  315. package/src/__tests__/gpu-scene-render-graph-gpu.ts +2 -3
  316. package/src/__tests__/gpu-scene.dawn.test.ts +2 -6
  317. package/src/__tests__/gpu-scene.unit.test.ts +10 -24
  318. package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
  319. package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +34 -66
  320. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -5
  321. package/src/__tests__/light-buffer-layout.unit.test.ts +4 -49
  322. package/src/__tests__/material-cooked-projection.unit.test.ts +31 -58
  323. package/src/__tests__/material-snapshot-mutation.integration.test.ts +10 -15
  324. package/src/__tests__/material-static-dynamic-route.unit.test.ts +31 -50
  325. package/src/__tests__/material-stride-surface.unit.test.ts +2 -2
  326. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +7 -8
  327. package/src/__tests__/morph-culling-reentry.dawn.test.ts +29 -38
  328. package/src/__tests__/morph-feature-gpu-work.integration.test.ts +45 -43
  329. package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
  330. package/src/__tests__/morph-visual-evidence.integration.test.ts +47 -33
  331. package/src/__tests__/nineslice-handle-surface.unit.test.ts +11 -6
  332. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -13
  333. package/src/__tests__/prepared-graphics-capability.unit.test.ts +6 -81
  334. package/src/__tests__/prepared-graphics-generation.unit.test.ts +3 -17
  335. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +6 -74
  336. package/src/__tests__/prepared-graphics-resolver.unit.test.ts +1 -3
  337. package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +2 -2
  338. package/src/__tests__/profiler-default-off.test.ts +1 -1
  339. package/src/__tests__/profiler-phase-catalog.test.ts +2 -2
  340. package/src/__tests__/profiler-phase-integration.test.ts +5 -13
  341. package/src/__tests__/profiler-phase-token.test.ts +3 -8
  342. package/src/__tests__/public-surface.test-d.ts +65 -3
  343. package/src/__tests__/recover-error-policy-owner.unit.test.ts +1 -21
  344. package/src/__tests__/render-error-code-owner.test-d.ts +24 -23
  345. package/src/__tests__/render-error-detail-ssot.test-d.ts +0 -95
  346. package/src/__tests__/render-error-exhaustive.test-d.ts +27 -1
  347. package/src/__tests__/render-feature-assembly.test-d.ts +8 -16
  348. package/src/__tests__/render-feature-context.test-d.ts +16 -40
  349. package/src/__tests__/render-feature-contract.test-d.ts +9 -18
  350. package/src/__tests__/render-feature-diagnostics.unit.test.ts +6 -8
  351. package/src/__tests__/render-feature-docs.unit.test.ts +8 -7
  352. package/src/__tests__/render-feature-gpu-work.integration.test.ts +14 -75
  353. package/src/__tests__/render-feature-plan.test-d.ts +161 -0
  354. package/src/__tests__/render-feature-plan.unit.test.ts +170 -0
  355. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +8 -19
  356. package/src/__tests__/render-feature-prepared-errors.test-d.ts +3 -6
  357. package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +10 -71
  358. package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +11 -61
  359. package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +20 -43
  360. package/src/__tests__/render-feature-prepared-graphics.test-d.ts +56 -78
  361. package/src/__tests__/render-feature-public-surface.test-d.ts +6 -24
  362. package/src/__tests__/render-feature-retry.unit.test.ts +7 -48
  363. package/src/__tests__/render-feature-scheduling.unit.test.ts +15 -27
  364. package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +0 -9
  365. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +19 -109
  366. package/src/__tests__/render-feature-visibility-context.test-d.ts +1 -6
  367. package/src/__tests__/render-feature-visibility-context.unit.test.ts +1 -2
  368. package/src/__tests__/render-feature-zero-work.unit.test.ts +14 -20
  369. package/src/__tests__/render-scene-projection.unit.test.ts +73 -111
  370. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +82 -95
  371. package/src/__tests__/renderer-lifecycle.integration.test.ts +49 -1
  372. package/src/__tests__/shader-stage-surface.unit.test.ts +14 -9
  373. package/src/__tests__/ssao-config.unit.test.ts +36 -0
  374. package/src/__tests__/ssao-kernel-surface.unit.test.ts +4 -5
  375. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +28 -0
  376. package/src/__tests__/standard-descriptors.test-d.ts +22 -0
  377. package/src/__tests__/standard-pipeline.dawn.test.ts +61 -0
  378. package/src/__tests__/standard-pipeline.integration.test.ts +124 -0
  379. package/src/__tests__/standard-profile-oracle.unit.test.ts +62 -0
  380. package/src/__tests__/surface-configuration.unit.test.ts +1 -2
  381. package/src/__tests__/texture-usage-surface.unit.test.ts +3 -6
  382. package/src/__tests__/typed-pipeline-topology.unit.test.ts +40 -206
  383. package/src/__tests__/urp-pipeline-targets.unit.test.ts +1 -11
  384. package/src/__tests__/urp-pipeline.unit.test.ts +2 -2
  385. package/src/__tests__/vertex-color-pipeline.unit.test.ts +10 -2
  386. package/src/__tests__/vertex-layout-consumer.unit.test.ts +1 -1
  387. package/src/__tests__/visibility-diagnostics.integration.test.ts +7 -11
  388. package/src/__tests__/visibility-extract.integration.test.ts +20 -11
  389. package/src/__tests__/visibility-extract.perf.test.ts +66 -32
  390. package/src/__tests__/visibility-feature-dedup.integration.test.ts +2 -4
  391. package/src/__tests__/visibility-hidden-report.unit.test.ts +1 -2
  392. package/src/__tests__/visibility-instances.integration.test.ts +7 -11
  393. package/src/__tests__/visibility-multi-world.integration.test.ts +38 -6
  394. package/src/__tests__/visibility-producer-matrix.integration.test.ts +18 -41
  395. package/src/__tests__/visibility-public-surface.test-d.ts +10 -9
  396. package/src/__tests__/visibility-resolver.unit.test.ts +2 -1
  397. package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
  398. package/src/__tests__/visibility-snapshot-contract.unit.test.ts +2 -1
  399. package/src/__tests__/vocabulary.unit.test.ts +1 -1
  400. package/src/assembly/backend-contract.ts +57 -0
  401. package/src/{renderer/renderer-factory.ts → assembly/factory.ts} +1741 -2699
  402. package/src/assembly/host-contract.ts +101 -0
  403. package/src/{renderer → assembly}/material/assembly.ts +2 -7
  404. package/src/assembly/material/pipeline-projection.ts +63 -0
  405. package/src/authoring.ts +15 -22
  406. package/src/components/__tests__/points-lines-admission.unit.test.ts +219 -0
  407. package/src/components/__tests__/points-lines-schema.unit.test.ts +56 -0
  408. package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
  409. package/src/components/glyph-text.ts +3 -2
  410. package/src/components/index.ts +14 -9
  411. package/src/components/instances.ts +4 -5
  412. package/src/components/light-helpers.ts +1 -1
  413. package/src/components/lines.ts +18 -0
  414. package/src/components/mesh-filter.ts +11 -10
  415. package/src/components/points.ts +40 -0
  416. package/src/components/post-process-params.ts +3 -3
  417. package/src/components/scene-instance.ts +12 -12
  418. package/src/components/skybox-background.ts +103 -0
  419. package/src/components/{environment.ts → skylight.ts} +2 -110
  420. package/src/components/sprite-animation.ts +3 -4
  421. package/src/components/sprite-instances.ts +2 -2
  422. package/src/components/sprite-playback-mode.ts +7 -1
  423. package/src/components/sprite-region-override.ts +2 -3
  424. package/src/components/tile-layer.ts +8 -2
  425. package/src/construct-renderer.ts +67 -4
  426. package/src/debug-draw-glue.ts +8 -129
  427. package/src/device/device-scope.ts +306 -0
  428. package/src/{gpu-resource-store.ts → device/gpu-residency.ts} +540 -639
  429. package/src/device/resource-types.ts +20 -0
  430. package/src/engine-metrics.ts +12 -19
  431. package/src/errors/recover.ts +45 -3
  432. package/src/errors/render.ts +469 -429
  433. package/src/features/fullscreen.ts +46 -0
  434. package/src/features/host.ts +575 -309
  435. package/src/features/morph/morph-feature.ts +195 -105
  436. package/src/features/plan.ts +447 -0
  437. package/src/features/prepared-gpu-work.ts +72 -15
  438. package/src/features/prepared-graphics-store.ts +20 -6
  439. package/src/features/prepared-graphics.ts +12 -71
  440. package/src/features/render-graph-compute.ts +14 -5
  441. package/src/features/render-graph-contribution.ts +43 -63
  442. package/src/features/render-graph-raster.ts +32 -8
  443. package/src/features/render-graph-resources.ts +25 -23
  444. package/src/features/targets.ts +8 -21
  445. package/src/features/types.ts +39 -227
  446. package/src/features/vocabulary.ts +24 -0
  447. package/src/fullscreen-post-process-pass.ts +14 -57
  448. package/src/glyph-text-layout-system.ts +70 -96
  449. package/src/gpu-driven/batch-topology.ts +24 -202
  450. package/src/gpu-driven/production-raster.ts +99 -1109
  451. package/src/gpu-driven/view-gpu.ts +46 -192
  452. package/src/gpu-resource.ts +4 -4
  453. package/src/gpu-scene-schema.ts +11 -99
  454. package/src/gpu-scene.ts +231 -364
  455. package/src/hdrp-buffers.ts +12 -221
  456. package/src/ibl/IblPipelineCache.ts +471 -711
  457. package/src/ibl/skylight-bind-group.ts +4 -4
  458. package/src/index.ts +75 -217
  459. package/src/inspection-types.ts +80 -0
  460. package/src/instance-buffer-cache.ts +1 -29
  461. package/src/internal.ts +6 -85
  462. package/src/lifecycle.ts +64 -19
  463. package/src/materials.ts +7 -29
  464. package/src/mesh-material-bindings.ts +0 -1
  465. package/src/pbr-pipeline.ts +441 -53
  466. package/src/{urp-pipeline.ts → pipeline/standard-forward-lane.ts} +38 -149
  467. package/src/{hdrp-pipeline.ts → pipeline/standard-pipeline.ts} +221 -191
  468. package/src/pipeline/standard-profile.ts +65 -0
  469. package/src/pipeline-builder.ts +60 -64
  470. package/src/pipeline-spec-types.ts +28 -0
  471. package/src/pipeline-spec.ts +72 -609
  472. package/src/plugin.ts +7 -75
  473. package/src/points-lines/__tests__/bounds.unit.test.ts +21 -0
  474. package/src/points-lines/__tests__/cache-recovery.unit.test.ts +157 -0
  475. package/src/points-lines/__tests__/inspection-lanes.integration.test.ts +146 -0
  476. package/src/points-lines/__tests__/inspection.unit.test.ts +173 -0
  477. package/src/points-lines/__tests__/lane-structural.integration.test.ts +122 -0
  478. package/src/points-lines/__tests__/points-lines.bench.ts +400 -0
  479. package/src/points-lines/__tests__/raster-lane.integration.test.ts +44 -0
  480. package/src/points-lines/__tests__/snapshot.unit.test.ts +101 -0
  481. package/src/points-lines/__tests__/view-ubo.unit.test.ts +73 -0
  482. package/src/points-lines/admission.ts +238 -0
  483. package/src/points-lines/bounds.ts +23 -0
  484. package/src/points-lines/expansion-cache.ts +215 -0
  485. package/src/points-lines/inspection.ts +97 -0
  486. package/src/points-lines/prepare.ts +177 -0
  487. package/src/points-lines/record.ts +125 -0
  488. package/src/points-lines/snapshot.ts +130 -0
  489. package/src/post-process-errors.ts +31 -33
  490. package/src/prepare/prepared-graphics-resolver.ts +5 -4
  491. package/src/record/__tests__/material-slot-plan.unit.test.ts +1 -33
  492. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
  493. package/src/record/__tests__/video-texture-view.unit.test.ts +1 -1
  494. package/src/record/frame-lighting.ts +88 -197
  495. package/src/record/frame-snapshot.ts +45 -60
  496. package/src/record/frame-targets.ts +8 -243
  497. package/src/record/frame.ts +521 -797
  498. package/src/record/helpers.ts +6 -11
  499. package/src/record/main-pass-geometry.ts +198 -147
  500. package/src/record/main-pass-material.ts +517 -190
  501. package/src/record/main-pass-sprite-draws.ts +199 -118
  502. package/src/record/main-pass.ts +166 -144
  503. package/src/record/mesh-ssbo.ts +517 -38
  504. package/src/record/render-context.ts +384 -0
  505. package/src/record/shadow-pass.ts +154 -1843
  506. package/src/record/skybox-post-pass.ts +14 -15
  507. package/src/record/typed-frame-graph.ts +224 -262
  508. package/src/record/view-ubo.ts +53 -37
  509. package/src/render-contract.ts +582 -0
  510. package/src/render-data.ts +3 -3
  511. package/src/render-graph-primitives.ts +76 -851
  512. package/src/render-pipeline.ts +104 -188
  513. package/src/render-system-extract.ts +1114 -1732
  514. package/src/render-system.ts +614 -1939
  515. package/src/scene/render-scene-types.ts +67 -0
  516. package/src/scene/render-scene.ts +1087 -0
  517. package/src/scene-instances/post-spawn-resolve-joints.ts +4 -7
  518. package/src/ssao-buffers.ts +167 -8
  519. package/src/systems/skin-palette-allocator.ts +21 -64
  520. package/src/systems/skin-palette-types.ts +14 -0
  521. package/src/systems/transparent-sort-config.ts +25 -3
  522. package/src/tilemap-chunk-extract-system.ts +53 -70
  523. package/src/typed-render-graph-primitives.ts +35 -24
  524. package/src/typed-shadow-passes.ts +26 -56
  525. package/dist/__tests__/analytic-sky-contract.test.d.ts +0 -2
  526. package/dist/__tests__/analytic-sky-contract.test.d.ts.map +0 -1
  527. package/dist/__tests__/analytic-sky-falsify.test.d.ts +0 -2
  528. package/dist/__tests__/analytic-sky-falsify.test.d.ts.map +0 -1
  529. package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts +0 -2
  530. package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts.map +0 -1
  531. package/dist/__tests__/backend-selection.integration.test.d.ts +0 -2
  532. package/dist/__tests__/backend-selection.integration.test.d.ts.map +0 -1
  533. package/dist/__tests__/camera-temporal.test-d.d.ts +0 -2
  534. package/dist/__tests__/camera-temporal.test-d.d.ts.map +0 -1
  535. package/dist/__tests__/camera-temporal.test.d.ts +0 -2
  536. package/dist/__tests__/camera-temporal.test.d.ts.map +0 -1
  537. package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts +0 -2
  538. package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts.map +0 -1
  539. package/dist/__tests__/environment-inspection.test.d.ts +0 -2
  540. package/dist/__tests__/environment-inspection.test.d.ts.map +0 -1
  541. package/dist/__tests__/fog-ai-user.fixture.d.ts +0 -2
  542. package/dist/__tests__/fog-ai-user.fixture.d.ts.map +0 -1
  543. package/dist/__tests__/fog-custom-render-feature.fixture.d.ts +0 -16
  544. package/dist/__tests__/fog-custom-render-feature.fixture.d.ts.map +0 -1
  545. package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts +0 -2
  546. package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts.map +0 -1
  547. package/dist/__tests__/fog-inspection.integration.test.d.ts +0 -2
  548. package/dist/__tests__/fog-inspection.integration.test.d.ts.map +0 -1
  549. package/dist/__tests__/fog-owner-state.integration.test.d.ts +0 -2
  550. package/dist/__tests__/fog-owner-state.integration.test.d.ts.map +0 -1
  551. package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts +0 -2
  552. package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts.map +0 -1
  553. package/dist/__tests__/fog-public-surface.integration.test.d.ts +0 -2
  554. package/dist/__tests__/fog-public-surface.integration.test.d.ts.map +0 -1
  555. package/dist/__tests__/fog-ray-contract.integration.test.d.ts +0 -2
  556. package/dist/__tests__/fog-ray-contract.integration.test.d.ts.map +0 -1
  557. package/dist/__tests__/fog-source-absence.integration.test.d.ts +0 -2
  558. package/dist/__tests__/fog-source-absence.integration.test.d.ts.map +0 -1
  559. package/dist/__tests__/fog-temporal.integration.test.d.ts +0 -2
  560. package/dist/__tests__/fog-temporal.integration.test.d.ts.map +0 -1
  561. package/dist/__tests__/frame-chain.unit.test.d.ts +0 -2
  562. package/dist/__tests__/frame-chain.unit.test.d.ts.map +0 -1
  563. package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts +0 -2
  564. package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts.map +0 -1
  565. package/dist/__tests__/hdrp-pipeline.unit.test.d.ts +0 -2
  566. package/dist/__tests__/hdrp-pipeline.unit.test.d.ts.map +0 -1
  567. package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts +0 -2
  568. package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts.map +0 -1
  569. package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts +0 -2
  570. package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts.map +0 -1
  571. package/dist/__tests__/material-derived-payload.integration.test.d.ts +0 -2
  572. package/dist/__tests__/material-derived-payload.integration.test.d.ts.map +0 -1
  573. package/dist/__tests__/materials.unit.test.d.ts +0 -2
  574. package/dist/__tests__/materials.unit.test.d.ts.map +0 -1
  575. package/dist/__tests__/param-schema-projection-census.unit.test.d.ts +0 -2
  576. package/dist/__tests__/param-schema-projection-census.unit.test.d.ts.map +0 -1
  577. package/dist/__tests__/persistent-render-scene.unit.test.d.ts +0 -2
  578. package/dist/__tests__/persistent-render-scene.unit.test.d.ts.map +0 -1
  579. package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts +0 -2
  580. package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts.map +0 -1
  581. package/dist/__tests__/pipeline-pass-trace.test.d.ts +0 -2
  582. package/dist/__tests__/pipeline-pass-trace.test.d.ts.map +0 -1
  583. package/dist/__tests__/pipeline-stage-owner.test-d.d.ts +0 -2
  584. package/dist/__tests__/pipeline-stage-owner.test-d.d.ts.map +0 -1
  585. package/dist/__tests__/plugin.test.d.ts +0 -2
  586. package/dist/__tests__/plugin.test.d.ts.map +0 -1
  587. package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts +0 -2
  588. package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts.map +0 -1
  589. package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts +0 -2
  590. package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts.map +0 -1
  591. package/dist/__tests__/public-pipeline-id.test-d.d.ts +0 -2
  592. package/dist/__tests__/public-pipeline-id.test-d.d.ts.map +0 -1
  593. package/dist/__tests__/render-dispatch-membership.unit.test.d.ts +0 -2
  594. package/dist/__tests__/render-dispatch-membership.unit.test.d.ts.map +0 -1
  595. package/dist/__tests__/render-feature-construction.unit.test.d.ts +0 -2
  596. package/dist/__tests__/render-feature-construction.unit.test.d.ts.map +0 -1
  597. package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts +0 -2
  598. package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts.map +0 -1
  599. package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts +0 -2
  600. package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts.map +0 -1
  601. package/dist/__tests__/render-feature-graph.integration.test.d.ts +0 -2
  602. package/dist/__tests__/render-feature-graph.integration.test.d.ts.map +0 -1
  603. package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts +0 -2
  604. package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts.map +0 -1
  605. package/dist/__tests__/render-feature-order.unit.test.d.ts +0 -2
  606. package/dist/__tests__/render-feature-order.unit.test.d.ts.map +0 -1
  607. package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts +0 -2
  608. package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts.map +0 -1
  609. package/dist/__tests__/render-feature-staging.unit.test.d.ts +0 -2
  610. package/dist/__tests__/render-feature-staging.unit.test.d.ts.map +0 -1
  611. package/dist/__tests__/renderer-render-scene-public.test-d.d.ts +0 -2
  612. package/dist/__tests__/renderer-render-scene-public.test-d.d.ts.map +0 -1
  613. package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts +0 -2
  614. package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts.map +0 -1
  615. package/dist/__tests__/sun-snapshot-consumers.test.d.ts +0 -2
  616. package/dist/__tests__/sun-snapshot-consumers.test.d.ts.map +0 -1
  617. package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts +0 -2
  618. package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts.map +0 -1
  619. package/dist/__tests__/taa-history-store.unit.test.d.ts +0 -2
  620. package/dist/__tests__/taa-history-store.unit.test.d.ts.map +0 -1
  621. package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts +0 -2
  622. package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts.map +0 -1
  623. package/dist/__tests__/temporal-inspection.unit.test.d.ts +0 -2
  624. package/dist/__tests__/temporal-inspection.unit.test.d.ts.map +0 -1
  625. package/dist/assets/__tests__/asset-decoders.unit.test.d.ts +0 -2
  626. package/dist/assets/__tests__/asset-decoders.unit.test.d.ts.map +0 -1
  627. package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts +0 -2
  628. package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts.map +0 -1
  629. package/dist/assets/__tests__/render-asset-port.unit.test.d.ts +0 -2
  630. package/dist/assets/__tests__/render-asset-port.unit.test.d.ts.map +0 -1
  631. package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts +0 -2
  632. package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts.map +0 -1
  633. package/dist/chunk-DJIMFYX6.mjs +0 -1439
  634. package/dist/chunk-DJIMFYX6.mjs.map +0 -1
  635. package/dist/chunk-F2SIOCRM.mjs +0 -7423
  636. package/dist/chunk-F2SIOCRM.mjs.map +0 -1
  637. package/dist/chunk-JMSB7AR4.mjs +0 -3
  638. package/dist/chunk-JMSB7AR4.mjs.map +0 -1
  639. package/dist/chunk-KHI6K4C6.mjs +0 -659
  640. package/dist/chunk-KHI6K4C6.mjs.map +0 -1
  641. package/dist/chunk-PORZOL2V.mjs +0 -569
  642. package/dist/chunk-PORZOL2V.mjs.map +0 -1
  643. package/dist/chunk-UOJGMDGP.mjs +0 -29913
  644. package/dist/chunk-UOJGMDGP.mjs.map +0 -1
  645. package/dist/components/__tests__/atmosphere-red.test.d.ts +0 -2
  646. package/dist/components/__tests__/atmosphere-red.test.d.ts.map +0 -1
  647. package/dist/components/__tests__/atmosphere.test.d.ts +0 -2
  648. package/dist/components/__tests__/atmosphere.test.d.ts.map +0 -1
  649. package/dist/components/__tests__/fog.test-d.d.ts +0 -2
  650. package/dist/components/__tests__/fog.test-d.d.ts.map +0 -1
  651. package/dist/components/__tests__/fog.test.d.ts +0 -2
  652. package/dist/components/__tests__/fog.test.d.ts.map +0 -1
  653. package/dist/components/atmosphere.d.ts +0 -18
  654. package/dist/components/atmosphere.d.ts.map +0 -1
  655. package/dist/components/environment.d.ts +0 -115
  656. package/dist/components/environment.d.ts.map +0 -1
  657. package/dist/deferred-lighting.d.ts +0 -13
  658. package/dist/deferred-lighting.d.ts.map +0 -1
  659. package/dist/dynamic-texture-store.d.ts +0 -42
  660. package/dist/dynamic-texture-store.d.ts.map +0 -1
  661. package/dist/environment/__tests__/failure-injection.test.d.ts +0 -2
  662. package/dist/environment/__tests__/failure-injection.test.d.ts.map +0 -1
  663. package/dist/environment/__tests__/generation-red.test.d.ts +0 -2
  664. package/dist/environment/__tests__/generation-red.test.d.ts.map +0 -1
  665. package/dist/environment/__tests__/generation.test.d.ts +0 -2
  666. package/dist/environment/__tests__/generation.test.d.ts.map +0 -1
  667. package/dist/environment/__tests__/graph-transaction.test.d.ts +0 -2
  668. package/dist/environment/__tests__/graph-transaction.test.d.ts.map +0 -1
  669. package/dist/environment/__tests__/inspection-red.test.d.ts +0 -2
  670. package/dist/environment/__tests__/inspection-red.test.d.ts.map +0 -1
  671. package/dist/environment/__tests__/lifecycle-evidence.test.d.ts +0 -2
  672. package/dist/environment/__tests__/lifecycle-evidence.test.d.ts.map +0 -1
  673. package/dist/environment/__tests__/pipeline-topology.test.d.ts +0 -2
  674. package/dist/environment/__tests__/pipeline-topology.test.d.ts.map +0 -1
  675. package/dist/environment/__tests__/readiness.test.d.ts +0 -2
  676. package/dist/environment/__tests__/readiness.test.d.ts.map +0 -1
  677. package/dist/environment/__tests__/recovery.test.d.ts +0 -2
  678. package/dist/environment/__tests__/recovery.test.d.ts.map +0 -1
  679. package/dist/environment/__tests__/resize-dispose.test.d.ts +0 -2
  680. package/dist/environment/__tests__/resize-dispose.test.d.ts.map +0 -1
  681. package/dist/environment/__tests__/signature-red.test.d.ts +0 -2
  682. package/dist/environment/__tests__/signature-red.test.d.ts.map +0 -1
  683. package/dist/environment/__tests__/signature.test.d.ts +0 -2
  684. package/dist/environment/__tests__/signature.test.d.ts.map +0 -1
  685. package/dist/environment/descriptors.d.ts +0 -2
  686. package/dist/environment/descriptors.d.ts.map +0 -1
  687. package/dist/environment/extracted-environment.d.ts +0 -53
  688. package/dist/environment/extracted-environment.d.ts.map +0 -1
  689. package/dist/environment/generation.d.ts +0 -62
  690. package/dist/environment/generation.d.ts.map +0 -1
  691. package/dist/environment/gpu-bundle.d.ts +0 -23
  692. package/dist/environment/gpu-bundle.d.ts.map +0 -1
  693. package/dist/environment/graph.d.ts +0 -108
  694. package/dist/environment/graph.d.ts.map +0 -1
  695. package/dist/environment/inspection.d.ts +0 -48
  696. package/dist/environment/inspection.d.ts.map +0 -1
  697. package/dist/environment/lifecycle.d.ts +0 -22
  698. package/dist/environment/lifecycle.d.ts.map +0 -1
  699. package/dist/environment/readiness.d.ts +0 -29
  700. package/dist/environment/readiness.d.ts.map +0 -1
  701. package/dist/environment/signature.d.ts +0 -70
  702. package/dist/environment/signature.d.ts.map +0 -1
  703. package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts +0 -2
  704. package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts.map +0 -1
  705. package/dist/extract/__tests__/environment-source.test.d.ts +0 -2
  706. package/dist/extract/__tests__/environment-source.test.d.ts.map +0 -1
  707. package/dist/extract/__tests__/schema-readers.unit.test.d.ts +0 -2
  708. package/dist/extract/__tests__/schema-readers.unit.test.d.ts.map +0 -1
  709. package/dist/extract/directional-csm.d.ts +0 -129
  710. package/dist/extract/directional-csm.d.ts.map +0 -1
  711. package/dist/extract/index.d.ts +0 -5
  712. package/dist/extract/index.d.ts.map +0 -1
  713. package/dist/extract/material-interface.d.ts +0 -56
  714. package/dist/extract/material-interface.d.ts.map +0 -1
  715. package/dist/extract/schema-readers.d.ts +0 -20
  716. package/dist/extract/schema-readers.d.ts.map +0 -1
  717. package/dist/features/graph-contribution.d.ts +0 -64
  718. package/dist/features/graph-contribution.d.ts.map +0 -1
  719. package/dist/features/index.d.ts +0 -21
  720. package/dist/features/index.d.ts.map +0 -1
  721. package/dist/features/morph/index.d.ts +0 -3
  722. package/dist/features/morph/index.d.ts.map +0 -1
  723. package/dist/features/morph/morph-bounds.d.ts +0 -42
  724. package/dist/features/morph/morph-bounds.d.ts.map +0 -1
  725. package/dist/features/scene-temporal.d.ts +0 -45
  726. package/dist/features/scene-temporal.d.ts.map +0 -1
  727. package/dist/features/taa-resolve.d.ts +0 -21
  728. package/dist/features/taa-resolve.d.ts.map +0 -1
  729. package/dist/frame-chain.d.ts +0 -14
  730. package/dist/frame-chain.d.ts.map +0 -1
  731. package/dist/gpu-driven/view-reference.d.ts.map +0 -1
  732. package/dist/gpu-resource-store.d.ts.map +0 -1
  733. package/dist/hdrp-cluster-membership.d.ts +0 -2
  734. package/dist/hdrp-cluster-membership.d.ts.map +0 -1
  735. package/dist/hdrp-pipeline.d.ts +0 -36
  736. package/dist/hdrp-pipeline.d.ts.map +0 -1
  737. package/dist/ibl/cubemap-projection.d.ts +0 -23
  738. package/dist/ibl/cubemap-projection.d.ts.map +0 -1
  739. package/dist/ibl/face-uniforms.d.ts +0 -65
  740. package/dist/ibl/face-uniforms.d.ts.map +0 -1
  741. package/dist/mesh-update-errors.d.ts +0 -71
  742. package/dist/mesh-update-errors.d.ts.map +0 -1
  743. package/dist/mipmap-generator.d.ts +0 -39
  744. package/dist/mipmap-generator.d.ts.map +0 -1
  745. package/dist/param-schema-projection-census.d.ts +0 -18
  746. package/dist/param-schema-projection-census.d.ts.map +0 -1
  747. package/dist/persistent-render-scene.d.ts +0 -158
  748. package/dist/persistent-render-scene.d.ts.map +0 -1
  749. package/dist/pipeline/index.d.ts +0 -11
  750. package/dist/pipeline/index.d.ts.map +0 -1
  751. package/dist/pipeline-errors.d.ts +0 -110
  752. package/dist/pipeline-errors.d.ts.map +0 -1
  753. package/dist/prepare/__tests__/schema-readers.unit.test.d.ts +0 -2
  754. package/dist/prepare/__tests__/schema-readers.unit.test.d.ts.map +0 -1
  755. package/dist/prepare/index.d.ts +0 -4
  756. package/dist/prepare/index.d.ts.map +0 -1
  757. package/dist/prepare/schema-readers.d.ts +0 -11
  758. package/dist/prepare/schema-readers.d.ts.map +0 -1
  759. package/dist/record/__tests__/environment-record.test.d.ts +0 -2
  760. package/dist/record/__tests__/environment-record.test.d.ts.map +0 -1
  761. package/dist/record/__tests__/frame-targets.unit.test.d.ts +0 -2
  762. package/dist/record/__tests__/frame-targets.unit.test.d.ts.map +0 -1
  763. package/dist/record/__tests__/membership-timing.unit.test.d.ts +0 -2
  764. package/dist/record/__tests__/membership-timing.unit.test.d.ts.map +0 -1
  765. package/dist/record/__tests__/render-submission.integration.test.d.ts +0 -2
  766. package/dist/record/__tests__/render-submission.integration.test.d.ts.map +0 -1
  767. package/dist/record/__tests__/render-submission.perf.test.d.ts +0 -2
  768. package/dist/record/__tests__/render-submission.perf.test.d.ts.map +0 -1
  769. package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts +0 -2
  770. package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts.map +0 -1
  771. package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts +0 -2
  772. package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts.map +0 -1
  773. package/dist/record/frame-observation.d.ts +0 -38
  774. package/dist/record/frame-observation.d.ts.map +0 -1
  775. package/dist/record/index.d.ts +0 -15
  776. package/dist/record/index.d.ts.map +0 -1
  777. package/dist/record/main-pass-skin.d.ts +0 -46
  778. package/dist/record/main-pass-skin.d.ts.map +0 -1
  779. package/dist/record/main-pass-sprite.d.ts +0 -69
  780. package/dist/record/main-pass-sprite.d.ts.map +0 -1
  781. package/dist/record/material-payload.d.ts +0 -43
  782. package/dist/record/material-payload.d.ts.map +0 -1
  783. package/dist/record/material-slot-plan.d.ts +0 -26
  784. package/dist/record/material-slot-plan.d.ts.map +0 -1
  785. package/dist/record/membership-timing.d.ts +0 -232
  786. package/dist/record/membership-timing.d.ts.map +0 -1
  787. package/dist/record/shadow-caster-uniform.d.ts +0 -8
  788. package/dist/record/shadow-caster-uniform.d.ts.map +0 -1
  789. package/dist/record/shadow-submit-mode.d.ts +0 -66
  790. package/dist/record/shadow-submit-mode.d.ts.map +0 -1
  791. package/dist/render-dispatch-membership.d.ts +0 -47
  792. package/dist/render-dispatch-membership.d.ts.map +0 -1
  793. package/dist/render-pipeline-context.d.ts +0 -289
  794. package/dist/render-pipeline-context.d.ts.map +0 -1
  795. package/dist/render-pipeline-target.d.ts +0 -16
  796. package/dist/render-pipeline-target.d.ts.map +0 -1
  797. package/dist/render-scene-projection.d.ts +0 -174
  798. package/dist/render-scene-projection.d.ts.map +0 -1
  799. package/dist/render-system-fold.d.ts +0 -266
  800. package/dist/render-system-fold.d.ts.map +0 -1
  801. package/dist/renderer/asset-service.d.ts +0 -10
  802. package/dist/renderer/asset-service.d.ts.map +0 -1
  803. package/dist/renderer/backend-selection.d.ts.map +0 -1
  804. package/dist/renderer/environment-classify.d.ts +0 -6
  805. package/dist/renderer/environment-classify.d.ts.map +0 -1
  806. package/dist/renderer/environment-error.d.ts +0 -13
  807. package/dist/renderer/environment-error.d.ts.map +0 -1
  808. package/dist/renderer/material/pipeline-projection.d.ts +0 -91
  809. package/dist/renderer/material/pipeline-projection.d.ts.map +0 -1
  810. package/dist/renderer/renderer-factory.d.ts +0 -289
  811. package/dist/renderer/renderer-factory.d.ts.map +0 -1
  812. package/dist/renderer.d.ts +0 -771
  813. package/dist/renderer.d.ts.map +0 -1
  814. package/dist/scene-utils/collect-subtree.d.ts +0 -11
  815. package/dist/scene-utils/collect-subtree.d.ts.map +0 -1
  816. package/dist/ssao-data.d.ts +0 -34
  817. package/dist/ssao-data.d.ts.map +0 -1
  818. package/dist/surface-format.d.ts +0 -10
  819. package/dist/surface-format.d.ts.map +0 -1
  820. package/dist/taa-history-store.d.ts +0 -88
  821. package/dist/taa-history-store.d.ts.map +0 -1
  822. package/dist/temporal-coverage.d.ts +0 -35
  823. package/dist/temporal-coverage.d.ts.map +0 -1
  824. package/dist/temporal-frame-transaction.d.ts +0 -92
  825. package/dist/temporal-frame-transaction.d.ts.map +0 -1
  826. package/dist/temporal-inspection.d.ts +0 -57
  827. package/dist/temporal-inspection.d.ts.map +0 -1
  828. package/dist/temporal-view.d.ts +0 -43
  829. package/dist/temporal-view.d.ts.map +0 -1
  830. package/dist/tilemap/resolve-tileset-runtime.d.ts +0 -23
  831. package/dist/tilemap/resolve-tileset-runtime.d.ts.map +0 -1
  832. package/dist/urp-pipeline.d.ts +0 -4
  833. package/dist/urp-pipeline.d.ts.map +0 -1
  834. package/src/__tests__/analytic-sky-contract.test.ts +0 -27
  835. package/src/__tests__/analytic-sky-falsify-carriers.mjs +0 -43
  836. package/src/__tests__/analytic-sky-falsify.test.ts +0 -94
  837. package/src/__tests__/assets-runtime-handoff.integration.test.ts +0 -36
  838. package/src/__tests__/backend-selection.integration.test.ts +0 -11
  839. package/src/__tests__/camera-temporal.test-d.ts +0 -8
  840. package/src/__tests__/camera-temporal.test.ts +0 -188
  841. package/src/__tests__/directional-shadow-probe-atlas-layout.unit.test.ts +0 -18
  842. package/src/__tests__/environment-inspection.test.ts +0 -45
  843. package/src/__tests__/fog-ai-user.fixture.ts +0 -350
  844. package/src/__tests__/fog-custom-render-feature.fixture.ts +0 -33
  845. package/src/__tests__/fog-custom-render-feature.integration.test.ts +0 -76
  846. package/src/__tests__/fog-inspection.integration.test.ts +0 -127
  847. package/src/__tests__/fog-owner-state.integration.test.ts +0 -112
  848. package/src/__tests__/fog-pipeline-topology.integration.test.ts +0 -93
  849. package/src/__tests__/fog-public-surface.integration.test.ts +0 -60
  850. package/src/__tests__/fog-ray-contract.integration.test.ts +0 -73
  851. package/src/__tests__/fog-source-absence.integration.test.ts +0 -51
  852. package/src/__tests__/fog-temporal.integration.test.ts +0 -115
  853. package/src/__tests__/frame-chain.unit.test.ts +0 -26
  854. package/src/__tests__/gpu-scene-field-type-owner.test-d.ts +0 -27
  855. package/src/__tests__/hdrp-pipeline.unit.test.ts +0 -100
  856. package/src/__tests__/ibl/ibl-fallback.unit.test.ts +0 -23
  857. package/src/__tests__/material-derived-error-stop-draw.integration.test.ts +0 -69
  858. package/src/__tests__/material-derived-payload.integration.test.ts +0 -164
  859. package/src/__tests__/materials.unit.test.ts +0 -25
  860. package/src/__tests__/param-schema-projection-census.unit.test.ts +0 -40
  861. package/src/__tests__/persistent-render-scene.unit.test.ts +0 -1311
  862. package/src/__tests__/pipeline-error-policy-owner.unit.test.ts +0 -167
  863. package/src/__tests__/pipeline-pass-trace.test.ts +0 -92
  864. package/src/__tests__/pipeline-stage-owner.test-d.ts +0 -13
  865. package/src/__tests__/plugin.test.ts +0 -25
  866. package/src/__tests__/prepared-graphics-backend-matrix.unit.test.ts +0 -129
  867. package/src/__tests__/prepared-graphics-resolver-recording.unit.test.ts +0 -180
  868. package/src/__tests__/public-pipeline-id.test-d.ts +0 -6
  869. package/src/__tests__/render-dispatch-membership.unit.test.ts +0 -117
  870. package/src/__tests__/render-feature-construction.unit.test.ts +0 -124
  871. package/src/__tests__/render-feature-error-code-owner.test-d.ts +0 -27
  872. package/src/__tests__/render-feature-gpu-buffer-usage-owner.test-d.ts +0 -46
  873. package/src/__tests__/render-feature-graph.integration.test.ts +0 -205
  874. package/src/__tests__/render-feature-graphics-staging.unit.test.ts +0 -200
  875. package/src/__tests__/render-feature-order.unit.test.ts +0 -66
  876. package/src/__tests__/render-feature-prepared-graphics-recording.unit.test.ts +0 -107
  877. package/src/__tests__/render-feature-staging.unit.test.ts +0 -94
  878. package/src/__tests__/renderer-render-scene-public.test-d.ts +0 -27
  879. package/src/__tests__/scene-temporal-coverage.unit.test.ts +0 -259
  880. package/src/__tests__/sun-snapshot-consumers.test.ts +0 -35
  881. package/src/__tests__/surface-backend-kind-owner.test-d.ts +0 -42
  882. package/src/__tests__/taa-history-store.unit.test.ts +0 -196
  883. package/src/__tests__/temporal-frame-transaction.integration.test.ts +0 -537
  884. package/src/__tests__/temporal-inspection.unit.test.ts +0 -138
  885. package/src/assets/__tests__/asset-decoders.unit.test.ts +0 -92
  886. package/src/assets/__tests__/mipmap-generator.unit.test.ts +0 -52
  887. package/src/assets/__tests__/render-asset-port.unit.test.ts +0 -54
  888. package/src/assets/__tests__/resolve-render-asset.unit.test.ts +0 -47
  889. package/src/components/__tests__/atmosphere-red.test.ts +0 -51
  890. package/src/components/__tests__/atmosphere.test.ts +0 -79
  891. package/src/components/__tests__/fog.test-d.ts +0 -49
  892. package/src/components/__tests__/fog.test.ts +0 -60
  893. package/src/components/atmosphere.ts +0 -64
  894. package/src/deferred-lighting.ts +0 -92
  895. package/src/dynamic-texture-store.ts +0 -111
  896. package/src/environment/README.md +0 -76
  897. package/src/environment/__tests__/failure-injection.test.ts +0 -50
  898. package/src/environment/__tests__/generation-red.test.ts +0 -64
  899. package/src/environment/__tests__/generation.test.ts +0 -37
  900. package/src/environment/__tests__/graph-transaction.test.ts +0 -85
  901. package/src/environment/__tests__/inspection-red.test.ts +0 -53
  902. package/src/environment/__tests__/lifecycle-evidence.test.ts +0 -40
  903. package/src/environment/__tests__/pipeline-topology.test.ts +0 -33
  904. package/src/environment/__tests__/readiness.test.ts +0 -42
  905. package/src/environment/__tests__/recovery.test.ts +0 -62
  906. package/src/environment/__tests__/resize-dispose.test.ts +0 -30
  907. package/src/environment/__tests__/signature-red.test.ts +0 -45
  908. package/src/environment/__tests__/signature.test.ts +0 -60
  909. package/src/environment/descriptors.ts +0 -7
  910. package/src/environment/extracted-environment.ts +0 -239
  911. package/src/environment/generation.ts +0 -158
  912. package/src/environment/gpu-bundle.ts +0 -144
  913. package/src/environment/graph.ts +0 -588
  914. package/src/environment/inspection.ts +0 -107
  915. package/src/environment/lifecycle.ts +0 -124
  916. package/src/environment/readiness.ts +0 -76
  917. package/src/environment/signature.ts +0 -185
  918. package/src/extract/__tests__/directional-csm-domain.unit.test.ts +0 -391
  919. package/src/extract/__tests__/environment-source.test.ts +0 -105
  920. package/src/extract/__tests__/schema-readers.unit.test.ts +0 -16
  921. package/src/extract/directional-csm.ts +0 -959
  922. package/src/extract/index.ts +0 -10
  923. package/src/extract/material-interface.ts +0 -604
  924. package/src/extract/schema-readers.ts +0 -27
  925. package/src/features/graph-contribution.ts +0 -577
  926. package/src/features/index.ts +0 -100
  927. package/src/features/morph/index.ts +0 -24
  928. package/src/features/morph/morph-bounds.ts +0 -123
  929. package/src/features/scene-temporal.ts +0 -274
  930. package/src/features/taa-resolve.ts +0 -244
  931. package/src/frame-chain.ts +0 -21
  932. package/src/hdrp-cluster-membership.ts +0 -70
  933. package/src/ibl/cubemap-projection.ts +0 -60
  934. package/src/ibl/face-uniforms.ts +0 -150
  935. package/src/mesh-update-errors.ts +0 -113
  936. package/src/mipmap-generator.ts +0 -244
  937. package/src/param-schema-projection-census.ts +0 -73
  938. package/src/persistent-render-scene.ts +0 -1752
  939. package/src/pipeline/index.ts +0 -40
  940. package/src/pipeline-errors.ts +0 -172
  941. package/src/prepare/__tests__/schema-readers.unit.test.ts +0 -16
  942. package/src/prepare/index.ts +0 -8
  943. package/src/prepare/schema-readers.ts +0 -20
  944. package/src/record/__tests__/environment-record.test.ts +0 -35
  945. package/src/record/__tests__/frame-targets.unit.test.ts +0 -54
  946. package/src/record/__tests__/membership-timing.unit.test.ts +0 -524
  947. package/src/record/__tests__/render-submission.integration.test.ts +0 -76
  948. package/src/record/__tests__/render-submission.perf.test.ts +0 -141
  949. package/src/record/__tests__/shadow-submit-mode.unit.test.ts +0 -88
  950. package/src/record/__tests__/view-ubo-layout.unit.test.ts +0 -101
  951. package/src/record/frame-observation.ts +0 -122
  952. package/src/record/index.ts +0 -15
  953. package/src/record/main-pass-skin.ts +0 -51
  954. package/src/record/main-pass-sprite.ts +0 -166
  955. package/src/record/material-payload.ts +0 -292
  956. package/src/record/material-slot-plan.ts +0 -68
  957. package/src/record/membership-timing.ts +0 -1012
  958. package/src/record/shadow-caster-uniform.ts +0 -37
  959. package/src/record/shadow-submit-mode.ts +0 -277
  960. package/src/render-dispatch-membership.ts +0 -155
  961. package/src/render-pipeline-context.ts +0 -332
  962. package/src/render-pipeline-target.ts +0 -96
  963. package/src/render-scene-projection.ts +0 -1738
  964. package/src/render-system-fold.ts +0 -531
  965. package/src/renderer/asset-service.ts +0 -32
  966. package/src/renderer/backend-selection.ts +0 -121
  967. package/src/renderer/environment-classify.ts +0 -30
  968. package/src/renderer/environment-error.ts +0 -19
  969. package/src/renderer/material/pipeline-projection.ts +0 -140
  970. package/src/renderer.ts +0 -940
  971. package/src/scene-utils/collect-subtree.ts +0 -40
  972. package/src/ssao-data.ts +0 -106
  973. package/src/surface-format.ts +0 -37
  974. package/src/taa-history-store.ts +0 -429
  975. package/src/temporal-coverage.ts +0 -106
  976. package/src/temporal-frame-transaction.ts +0 -301
  977. package/src/temporal-inspection.ts +0 -194
  978. package/src/temporal-view.ts +0 -174
  979. package/src/tilemap/resolve-tileset-runtime.ts +0 -72
@@ -1,19 +1,19 @@
1
- // IblPipelineCache.ts -- Per-device WeakMap pipeline cache for IBL precompute.
1
+ // IblPipelineCache.ts -- DeviceScope-generation cache for IBL precompute.
2
2
  //
3
3
  // Plan-strategy D-1/D-7: cache for 4 GPU passes (equirect->cube /
4
4
  // irradiance / prefilter / BRDF LUT). M2 provides the cache skeleton;
5
5
  // M3 (t18/t20) wires real shader math from ibl.wgsl.
6
6
  //
7
- // Structure mirrors mipmap-generator.ts per-device WeakMap pattern:
8
- // WeakMap<device, IblPipelineCachePerDevice>
7
+ // The cache is keyed by the renderer-owned DeviceScope generation. Raw device
8
+ // handles are inputs to pipeline creation, never cache or lifecycle owners.
9
9
  //
10
10
  // Public surface (M3):
11
- // - getOrCreateIblCache(device): get or initialize per-device cache
11
+ // - getOrCreateIblCache(scope): get or initialize the generation cache
12
12
  // - iblCacheSize(): introspection hook
13
- // - hasIblCache(device): introspection hook
13
+ // - hasIblCache(scope): introspection hook
14
14
  // - setIblWgslSource(source): set the ibl.wgsl WGSL source string
15
15
  // - createIblShaderModules(device, factory): create shader modules from ibl.wgsl
16
- // - createIblPipelines(device, factory, modules): create 4 render pipelines
16
+ // - createIblPipelines(scope, device, factory, modules): create 4 render pipelines
17
17
  // - runIblPrecompute(opts): execute 4 GPU precompute passes (M3 t20)
18
18
  //
19
19
  // M3 t20: pipeline slots are filled with real render pipelines loaded from
@@ -21,86 +21,111 @@
21
21
  // executed in the standard order (equirect->cube -> irradiance -> prefilter
22
22
  // -> BRDF LUT), with counters set post-execution per AC-04/05/06.
23
23
 
24
- // ─── Device shim shapes ──────────────────────────────────────────────────────
24
+ // ─── RHI-owned handles ───────────────────────────────────────────────────────
25
25
 
26
+ import {
27
+ type BindGroup,
28
+ type BindGroupLayout,
29
+ type Buffer,
30
+ type CommandBuffer,
31
+ err,
32
+ ok,
33
+ type RenderPipeline,
34
+ type Result,
35
+ type RhiCommandEncoder,
36
+ type RhiDevice,
37
+ type RhiError,
38
+ type RhiRenderPassEncoder,
39
+ type Sampler,
40
+ type ShaderModule,
41
+ type Texture,
42
+ type TextureFormat,
43
+ type TextureView,
44
+ } from '@forgeax/engine-rhi';
45
+ import type { DeviceScope } from '../device/device-scope';
26
46
  import { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from '../gpu-stage';
27
47
  import {
28
48
  GPU_TEXTURE_USAGE_COPY_DST,
29
49
  GPU_TEXTURE_USAGE_COPY_SRC,
30
50
  GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING,
31
51
  } from '../gpu-texture-usage';
32
- import { cubemapCaptureProjection } from './cubemap-projection';
33
52
 
34
53
  /**
35
54
  * Shader module factory (async, injected via configureGpuDevice).
36
55
  * Mirrors `MipmapShaderModuleFactory` from mipmap-generator.
37
56
  */
57
+ /**
58
+ * IBL is assembled by the renderer's device owner, so it consumes the full
59
+ * opaque RHI device rather than a structurally-compatible raw/shim split.
60
+ * Keeping the owner as RhiDevice makes the backend boundary explicit: raw
61
+ * GPU handles can only exist inside an RHI implementation or a test readback.
62
+ */
63
+ export type IblRhiOwner = RhiDevice;
64
+
38
65
  export type IblShaderModuleFactory = (
39
- device: object,
66
+ device: IblRhiOwner,
40
67
  desc: { code: string; label?: string },
41
- ) => Promise<{ ok: boolean; value?: unknown; error?: { code: string; message: string } }>;
68
+ ) => Promise<Result<ShaderModule, RhiError>>;
69
+
70
+ export interface IblPipelineSet {
71
+ readonly equirectToCubePipeline: RenderPipeline;
72
+ readonly irradiancePipeline: RenderPipeline;
73
+ readonly prefilterPipeline: RenderPipeline;
74
+ readonly brdfLutPipeline: RenderPipeline;
75
+ }
76
+
77
+ export interface IblPipelineError {
78
+ readonly code: 'ibl-pipeline-create-failed' | 'ibl-shader-module-missing';
79
+ readonly expected: string;
80
+ readonly hint: string;
81
+ readonly detail: { readonly stage: string; readonly rhiCode?: RhiError['code'] };
82
+ }
42
83
 
43
84
  /**
44
- * Per-device IBL pipeline cache instance.
85
+ * Per-DeviceScope-generation IBL pipeline cache instance.
45
86
  *
46
87
  * M3.5 (round-2 t52): the 4 pipeline slots are mutable so createIblPipelines
47
88
  * can fill them after construction. The 4 textures + their views are also
48
89
  * cached here so runIblPrecompute targets are stable across calls
49
90
  * (idempotent).
50
91
  */
51
- export interface IblPipelineCachePerDevice {
92
+ export interface IblPipelineCache {
52
93
  /** Color format shared by all precompute outputs for this device. */
53
- outputFormat?: string;
94
+ outputFormat?: TextureFormat;
54
95
  /** Equirectangular-to-cubemap pipeline. */
55
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipeline handle
56
- equirectToCubePipeline?: any;
96
+ equirectToCubePipeline?: RenderPipeline;
57
97
  /** Diffuse irradiance convolution pipeline. */
58
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipeline handle
59
- irradiancePipeline?: any;
98
+ irradiancePipeline?: RenderPipeline;
60
99
  /** Specular prefilter pipeline. */
61
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipeline handle
62
- prefilterPipeline?: any;
100
+ prefilterPipeline?: RenderPipeline;
63
101
  /** BRDF integration LUT pipeline. */
64
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipeline handle
65
- brdfLutPipeline?: any;
102
+ brdfLutPipeline?: RenderPipeline;
66
103
 
67
104
  /** Face uniforms BGL (shared across equirect/irradiance/prefilter, D-9). */
68
- // biome-ignore lint/suspicious/noExplicitAny: opaque BGL
69
- faceUniformsBgl?: any;
105
+ faceUniformsBgl?: BindGroupLayout;
70
106
  /** group(1) BGL for the equirect-to-cube pass (texture_2d + sampler). */
71
- // biome-ignore lint/suspicious/noExplicitAny: opaque BGL
72
- equirectGroup1Bgl?: any;
107
+ equirectGroup1Bgl?: BindGroupLayout;
73
108
  /** group(1) BGL for irradiance + prefilter (texture_cube + sampler). */
74
- // biome-ignore lint/suspicious/noExplicitAny: opaque BGL
75
- cubeGroup1Bgl?: any;
109
+ cubeGroup1Bgl?: BindGroupLayout;
76
110
  /** group(0) BGL for prefilter (face + prefilter uniforms). */
77
- // biome-ignore lint/suspicious/noExplicitAny: opaque BGL
78
- prefilterGroup0Bgl?: any;
111
+ prefilterGroup0Bgl?: BindGroupLayout;
79
112
 
80
113
  /** Irradiance cubemap texture (32x32; outputFormat, cube). */
81
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture
82
- irradianceTexture?: any;
114
+ irradianceTexture?: Texture;
83
115
  /** Irradiance cubemap view (dimension:cube). */
84
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture view
85
- irradianceView?: any;
116
+ irradianceView?: TextureView;
86
117
  /** Per-face 2D views for irradiance (render-attachment use). */
87
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture views
88
- irradianceFaceViews?: ReadonlyArray<any>;
118
+ irradianceFaceViews?: ReadonlyArray<TextureView>;
89
119
  /** Specular prefilter cubemap (128x128, 5 mip levels). */
90
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture
91
- prefilterTexture?: any;
120
+ prefilterTexture?: Texture;
92
121
  /** Prefilter cubemap view (dimension:cube, all mips). */
93
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture view
94
- prefilterView?: any;
122
+ prefilterView?: TextureView;
95
123
  /** Per-face 2D views per mip for prefilter (5 mips x 6 faces). */
96
- // biome-ignore lint/suspicious/noExplicitAny: nested mip x face views
97
- prefilterFaceViewsByMip?: ReadonlyArray<ReadonlyArray<any>>;
124
+ prefilterFaceViewsByMip?: ReadonlyArray<ReadonlyArray<TextureView>>;
98
125
  /** BRDF LUT (256x256; outputFormat). */
99
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture
100
- brdfLutTexture?: any;
126
+ brdfLutTexture?: Texture;
101
127
  /** BRDF LUT view. */
102
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture view
103
- brdfLutView?: any;
128
+ brdfLutView?: TextureView;
104
129
 
105
130
  /** Counter: times irradiance pass has executed. AC-04: == 1 after first cook. */
106
131
  irradianceBakeCount: number;
@@ -111,101 +136,41 @@ export interface IblPipelineCachePerDevice {
111
136
  }
112
137
 
113
138
  /**
114
- * Per-device cache map. The WeakMap key is the opaque device object;
115
- * destroying the device naturally clears its cache entry.
139
+ * Cache ownership follows the renderer's DeviceScope generation. A cache is
140
+ * never recovered by looking up an opaque device handle, so every pipeline and
141
+ * side texture is born under the same lifecycle owner as the rest of the
142
+ * renderer resources.
116
143
  */
117
- const deviceCache: WeakMap<object, IblPipelineCachePerDevice> = new WeakMap();
144
+ const scopeCaches: WeakMap<DeviceScope, IblPipelineCache> = new WeakMap();
118
145
 
119
146
  /**
120
- * Get or create the per-device IBL pipeline cache.
147
+ * Get or create the current-generation IBL pipeline cache.
121
148
  */
122
- export function getOrCreateIblCache(device: object): IblPipelineCachePerDevice {
123
- const existing = deviceCache.get(device);
149
+ export function getOrCreateIblCache(scope: DeviceScope): IblPipelineCache {
150
+ const existing = scopeCaches.get(scope);
124
151
  if (existing !== undefined) return existing;
125
152
 
126
- const cache: IblPipelineCachePerDevice = {
153
+ const cache: IblPipelineCache = {
127
154
  irradianceBakeCount: 0,
128
155
  prefilterBakeCount: 0,
129
156
  brdfLutBakeCount: 0,
130
157
  };
131
- deviceCache.set(device, cache);
158
+ scopeCaches.set(scope, cache);
132
159
  return cache;
133
160
  }
134
161
 
135
162
  /**
136
- * Number of cached per-device instances (introspection hook for tests).
137
- */
138
- export function iblCacheSize(): number {
139
- // WeakMap doesn't expose size; approximate by iteration.
140
- let count = 0;
141
- try {
142
- // biome-ignore lint/suspicious/noExplicitAny: WeakMap iteration hack
143
- for (const _ of deviceCache as any) {
144
- count++;
145
- }
146
- } catch {
147
- // WeakMap is not iterable; this is expected.
148
- }
149
- return count;
150
- }
151
-
152
- /**
153
- * Check whether a device has an active cache entry (introspection for tests).
154
- */
155
- export function hasIblCache(device: object): boolean {
156
- return deviceCache.has(device);
157
- }
158
-
159
- /**
160
- * Clear the per-device cache entry for the given device, if any.
161
- *
162
- * feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M5: called from
163
- * `Renderer.dispose()` step 4 (plan-strategy D-2 6-step walk) so the IBL
164
- * pipelines / textures attached to a torn-down device do not survive in the
165
- * runtime cache. The underlying GPU pipeline / texture handles are not
166
- * separately destroyed here -- they were created on the same RhiDevice the
167
- * dispose chain is about to release at step 5 (`context.unconfigure`); the
168
- * spec contract is that releasing the device tears down its child pipelines
169
- * implicitly. Clearing the WeakMap entry simply lets GC reclaim the JS-side
170
- * cache record.
171
- *
172
- * Idempotent (architecture-principles §6): a second call after the entry
173
- * was deleted is a no-op.
174
- */
175
- export function clearIblCacheForDevice(device: object): void {
176
- deviceCache.delete(device);
177
- }
178
-
179
- // ─── IBL WGSL source management ──────────────────────────────────────────────
180
-
181
- let iblWgslSourceCache: string | undefined;
182
-
183
- /**
184
- * Set the ibl.wgsl source string. Called once by the consumer
185
- * (e.g., AssetRegistry) when the shader module source is loaded.
163
+ * Check whether a DeviceScope generation has an active cache entry.
186
164
  */
187
- export function setIblWgslSource(source: string): void {
188
- iblWgslSourceCache = source;
189
- }
190
-
191
- /**
192
- * Get the cached ibl.wgsl source string.
193
- * Throws if not yet loaded.
194
- */
195
- export function getIblWgslSource(): string {
196
- if (iblWgslSourceCache === undefined) {
197
- throw new Error(
198
- 'ibl.wgsl source not loaded -- call setIblWgslSource before using IBL pipelines',
199
- );
200
- }
201
- return iblWgslSourceCache;
165
+ export function hasIblCache(scope: DeviceScope): boolean {
166
+ return scopeCaches.has(scope);
202
167
  }
203
168
 
204
169
  // ─── M3.5 composed ibl-* shader source registry ─────────────────────────────
205
170
  //
206
171
  // 4 composed WGSL strings -- one per render pipeline. Each string is the
207
172
  // output of @forgeax/engine-naga composeShader after merging ibl_shared +
208
- // the per-pass module. Built by ShaderRegistry / vite-plugin-shader at
173
+ // the per-pass module. Built by ShaderCatalog / vite-plugin-shader at
209
174
  // build-time so the runtime cache never reaches into engine-naga
210
175
  // (AGENTS.md grep gate forbids).
211
176
 
@@ -225,22 +190,12 @@ let iblComposedShadersCache: IblComposedShaders | undefined;
225
190
  /**
226
191
  * Inject the composed ibl-* shader sources used by createIblPipelines.
227
192
  * Called once by the engine bootstrap (createRenderer step "shader-load")
228
- * with the 4 composed entries from ShaderRegistry.
193
+ * with the 4 composed entries from ShaderCatalog.
229
194
  */
230
195
  export function setIblComposedShaders(sources: IblComposedShaders): void {
231
196
  iblComposedShadersCache = sources;
232
197
  }
233
198
 
234
- /**
235
- * Retrieve the cached composed shader bundle.
236
- * Returns undefined when the runtime is operating without a real shader
237
- * source (mock device unit tests that exercise pipeline dispatch surface
238
- * only).
239
- */
240
- export function getIblComposedShaders(): IblComposedShaders | undefined {
241
- return iblComposedShadersCache;
242
- }
243
-
244
199
  // ─── Standard cube vertices for cubemap face rendering ───────────────────────
245
200
  // 36 vertices (6 faces * 2 triangles * 3 vertices), vec3<f32> format.
246
201
  // Unit cube [-1, 1]^3 centered at origin.
@@ -296,6 +251,18 @@ function buildCaptureViewProjs(): Float32Array[] {
296
251
  });
297
252
  }
298
253
 
254
+ function cubemapCaptureProjection(fovy: number, near: number, far: number): Float32Array {
255
+ const f = 1.0 / Math.tan(fovy / 2);
256
+ const nf = 1.0 / (near - far);
257
+ // biome-ignore format: manual column-major mat4
258
+ return new Float32Array([
259
+ f, 0, 0, 0,
260
+ 0, -f, 0, 0,
261
+ 0, 0, (far + near) * nf, -1,
262
+ 0, 0, 2 * far * near * nf, 0,
263
+ ]);
264
+ }
265
+
299
266
  function lookAtMatrix(
300
267
  eye: readonly number[],
301
268
  target: readonly number[],
@@ -379,43 +346,6 @@ export const PREFILTER_SIZE = 128;
379
346
  export const PREFILTER_MIP_LEVELS = 5;
380
347
  export const BRDF_LUT_SIZE = 256;
381
348
 
382
- /**
383
- * Minimal device shape used by createIblPipelines + runIblPrecompute. The
384
- * surface is intentionally narrow so unit-level mock devices can exercise
385
- * the dispatch path without standing up the full RHI shim.
386
- */
387
- export interface IblPipelineDevice {
388
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
389
- createBindGroupLayout(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
390
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
391
- createPipelineLayout(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
392
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
393
- createRenderPipeline(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
394
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
395
- createBuffer(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
396
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
397
- createTexture(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
398
- createTextureView(
399
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture
400
- texture: any,
401
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
402
- desc: any,
403
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
404
- ): { ok: true; value: any } | { ok: false; error: unknown };
405
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
406
- createSampler(desc?: any): { ok: true; value: any } | { ok: false; error: unknown };
407
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
408
- createBindGroup(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
409
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
410
- createCommandEncoder(desc?: any): { ok: true; value: any } | { ok: false; error: unknown };
411
- readonly queue: {
412
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
413
- submit(buffers: ReadonlyArray<any>): unknown;
414
- // biome-ignore lint/suspicious/noExplicitAny: shim shapes
415
- writeBuffer?: (...args: any[]) => unknown;
416
- };
417
- }
418
-
419
349
  /**
420
350
  * Create 4 independent GPURenderPipelines + their shared / per-pass bind
421
351
  * group layouts. Pipeline slots are stored on the per-device cache and
@@ -427,37 +357,24 @@ export interface IblPipelineDevice {
427
357
  * irradiance + prefilter, none for brdf-lut.
428
358
  */
429
359
  export async function createIblPipelines(
430
- device: IblPipelineDevice,
360
+ scope: DeviceScope,
361
+ device: IblRhiOwner,
431
362
  factory: IblShaderModuleFactory,
432
- // biome-ignore lint/suspicious/noExplicitAny: cubemap output format opaque
433
- cubeOutputFormat: any = 'rgba16float',
434
- ): Promise<
435
- | {
436
- ok: true;
437
- value: {
438
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipelines
439
- equirectToCubePipeline: any;
440
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipelines
441
- irradiancePipeline: any;
442
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipelines
443
- prefilterPipeline: any;
444
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU pipelines
445
- brdfLutPipeline: any;
446
- };
447
- }
448
- | { ok: false; error: unknown }
449
- > {
450
- const cache = getOrCreateIblCache(device);
451
- if (cache.equirectToCubePipeline !== undefined) {
452
- return {
453
- ok: true,
454
- value: {
455
- equirectToCubePipeline: cache.equirectToCubePipeline,
456
- irradiancePipeline: cache.irradiancePipeline,
457
- prefilterPipeline: cache.prefilterPipeline,
458
- brdfLutPipeline: cache.brdfLutPipeline,
459
- },
460
- };
363
+ cubeOutputFormat: TextureFormat = 'rgba16float',
364
+ ): Promise<Result<IblPipelineSet, RhiError | IblPipelineError>> {
365
+ const cache = getOrCreateIblCache(scope);
366
+ if (
367
+ cache.equirectToCubePipeline !== undefined &&
368
+ cache.irradiancePipeline !== undefined &&
369
+ cache.prefilterPipeline !== undefined &&
370
+ cache.brdfLutPipeline !== undefined
371
+ ) {
372
+ return ok({
373
+ equirectToCubePipeline: cache.equirectToCubePipeline,
374
+ irradiancePipeline: cache.irradiancePipeline,
375
+ prefilterPipeline: cache.prefilterPipeline,
376
+ brdfLutPipeline: cache.brdfLutPipeline,
377
+ });
461
378
  }
462
379
  // Keep the output format on the per-device cache so the four pipelines and
463
380
  // their lazily-created side textures cannot drift. WebGL2 may need the
@@ -476,16 +393,6 @@ export async function createIblPipelines(
476
393
  brdfLut: fallbackCode,
477
394
  };
478
395
 
479
- // M5-amend Bug 1: normalise shim/raw return shapes. See runIblPrecompute
480
- // for full rationale -- same helper applied across both functions so
481
- // dawn-node (raw GPUDevice) + browser (rhi-shim) both succeed.
482
- // biome-ignore lint/suspicious/noExplicitAny: union of shim/raw return shapes
483
- const unwrap = (r: any): any => {
484
- if (r === null || r === undefined) return undefined;
485
- if (typeof r === 'object' && 'ok' in r) return r.ok ? r.value : undefined;
486
- return r;
487
- };
488
-
489
396
  const modules = await Promise.all([
490
397
  factory(device, { code: src.equirectToCube, label: 'ibl-equirect-to-cube' }),
491
398
  factory(device, { code: src.irradiance, label: 'ibl-irradiance' }),
@@ -493,183 +400,175 @@ export async function createIblPipelines(
493
400
  factory(device, { code: src.brdfLut, label: 'ibl-brdf-lut' }),
494
401
  ]);
495
402
  for (const m of modules) {
496
- if (!m.ok) return { ok: false, error: m.error };
403
+ if (!m.ok) return err(m.error);
404
+ }
405
+ const shaderModules = modules.flatMap((module) => (module.ok ? [module.value] : []));
406
+ if (shaderModules.length !== 4) {
407
+ return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));
408
+ }
409
+ const [mEq, mIr, mPr, mBr] = shaderModules;
410
+ if (mEq === undefined || mIr === undefined || mPr === undefined || mBr === undefined) {
411
+ return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));
497
412
  }
498
- // biome-ignore lint/style/noNonNullAssertion: checked above
499
- const [mEq, mIr, mPr, mBr] = modules.map((m) => m.value!) as [unknown, unknown, unknown, unknown];
500
413
 
501
414
  // D-9: faceUniforms BGL shared across 3 pipelines (equirect / irradiance /
502
415
  // prefilter). The prefilter additionally needs binding(1) for prefUniforms;
503
416
  // we keep a separate BGL for the prefilter group(0) to honour the WGSL
504
417
  // declaration in ibl-prefilter.wgsl.
505
- const faceBgl = unwrap(
506
- device.createBindGroupLayout({
507
- label: 'ibl-face-uniforms-bgl',
508
- entries: [{ binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } }],
509
- }),
510
- );
511
- if (faceBgl === undefined) return { ok: false, error: 'ibl-face-uniforms-bgl' };
512
- cache.faceUniformsBgl = faceBgl;
513
-
514
- const prefilterGroup0 = unwrap(
515
- device.createBindGroupLayout({
516
- label: 'ibl-prefilter-group0-bgl',
517
- entries: [
518
- { binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } },
519
- { binding: 1, visibility: GPU_SHADER_STAGE_FRAGMENT, buffer: { type: 'uniform' } },
520
- ],
521
- }),
522
- );
523
- if (prefilterGroup0 === undefined) return { ok: false, error: 'ibl-prefilter-group0-bgl' };
524
- cache.prefilterGroup0Bgl = prefilterGroup0;
525
-
526
- const equirectGroup1 = unwrap(
527
- device.createBindGroupLayout({
528
- label: 'ibl-equirect-group1-bgl',
529
- entries: [
530
- {
531
- binding: 0,
532
- visibility: GPU_SHADER_STAGE_FRAGMENT,
533
- texture: { sampleType: 'float', viewDimension: '2d' },
534
- },
535
- {
536
- binding: 1,
537
- visibility: GPU_SHADER_STAGE_FRAGMENT,
538
- sampler: { type: 'filtering' },
539
- },
540
- ],
541
- }),
542
- );
543
- if (equirectGroup1 === undefined) return { ok: false, error: 'ibl-equirect-group1-bgl' };
544
- cache.equirectGroup1Bgl = equirectGroup1;
545
-
546
- const cubeGroup1 = unwrap(
547
- device.createBindGroupLayout({
548
- label: 'ibl-cube-group1-bgl',
549
- entries: [
550
- {
551
- binding: 0,
552
- visibility: GPU_SHADER_STAGE_FRAGMENT,
553
- texture: { sampleType: 'float', viewDimension: 'cube' },
554
- },
555
- {
556
- binding: 1,
557
- visibility: GPU_SHADER_STAGE_FRAGMENT,
558
- sampler: { type: 'filtering' },
559
- },
560
- ],
561
- }),
562
- );
563
- if (cubeGroup1 === undefined) return { ok: false, error: 'ibl-cube-group1-bgl' };
564
- cache.cubeGroup1Bgl = cubeGroup1;
418
+ const faceBgl = device.createBindGroupLayout({
419
+ label: 'ibl-face-uniforms-bgl',
420
+ entries: [{ binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } }],
421
+ });
422
+ if (!faceBgl.ok) return err(faceBgl.error);
423
+ cache.faceUniformsBgl = faceBgl.value;
424
+
425
+ const prefilterGroup0 = device.createBindGroupLayout({
426
+ label: 'ibl-prefilter-group0-bgl',
427
+ entries: [
428
+ { binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } },
429
+ { binding: 1, visibility: GPU_SHADER_STAGE_FRAGMENT, buffer: { type: 'uniform' } },
430
+ ],
431
+ });
432
+ if (!prefilterGroup0.ok) return err(prefilterGroup0.error);
433
+ cache.prefilterGroup0Bgl = prefilterGroup0.value;
434
+
435
+ const equirectGroup1 = device.createBindGroupLayout({
436
+ label: 'ibl-equirect-group1-bgl',
437
+ entries: [
438
+ {
439
+ binding: 0,
440
+ visibility: GPU_SHADER_STAGE_FRAGMENT,
441
+ texture: { sampleType: 'float', viewDimension: '2d' },
442
+ },
443
+ {
444
+ binding: 1,
445
+ visibility: GPU_SHADER_STAGE_FRAGMENT,
446
+ sampler: { type: 'filtering' },
447
+ },
448
+ ],
449
+ });
450
+ if (!equirectGroup1.ok) return err(equirectGroup1.error);
451
+ cache.equirectGroup1Bgl = equirectGroup1.value;
452
+
453
+ const cubeGroup1 = device.createBindGroupLayout({
454
+ label: 'ibl-cube-group1-bgl',
455
+ entries: [
456
+ {
457
+ binding: 0,
458
+ visibility: GPU_SHADER_STAGE_FRAGMENT,
459
+ texture: { sampleType: 'float', viewDimension: 'cube' },
460
+ },
461
+ {
462
+ binding: 1,
463
+ visibility: GPU_SHADER_STAGE_FRAGMENT,
464
+ sampler: { type: 'filtering' },
465
+ },
466
+ ],
467
+ });
468
+ if (!cubeGroup1.ok) return err(cubeGroup1.error);
469
+ cache.cubeGroup1Bgl = cubeGroup1.value;
565
470
 
566
471
  // Pipeline layouts.
567
- const equirectLayout = unwrap(
568
- device.createPipelineLayout({
569
- label: 'ibl-equirect-pipeline-layout',
570
- bindGroupLayouts: [cache.faceUniformsBgl, cache.equirectGroup1Bgl],
571
- }),
572
- );
573
- if (equirectLayout === undefined) return { ok: false, error: 'ibl-equirect-pipeline-layout' };
574
- const irradianceLayout = unwrap(
575
- device.createPipelineLayout({
576
- label: 'ibl-irradiance-pipeline-layout',
577
- bindGroupLayouts: [cache.faceUniformsBgl, cache.cubeGroup1Bgl],
578
- }),
579
- );
580
- if (irradianceLayout === undefined) return { ok: false, error: 'ibl-irradiance-pipeline-layout' };
581
- const prefilterLayout = unwrap(
582
- device.createPipelineLayout({
583
- label: 'ibl-prefilter-pipeline-layout',
584
- bindGroupLayouts: [prefilterGroup0, cache.cubeGroup1Bgl],
585
- }),
586
- );
587
- if (prefilterLayout === undefined) return { ok: false, error: 'ibl-prefilter-pipeline-layout' };
588
- const brdfLutLayout = unwrap(
589
- device.createPipelineLayout({
590
- label: 'ibl-brdf-lut-pipeline-layout',
591
- bindGroupLayouts: [],
592
- }),
593
- );
594
- if (brdfLutLayout === undefined) return { ok: false, error: 'ibl-brdf-lut-pipeline-layout' };
472
+ const equirectLayout = device.createPipelineLayout({
473
+ label: 'ibl-equirect-pipeline-layout',
474
+ bindGroupLayouts: [faceBgl.value, equirectGroup1.value],
475
+ });
476
+ if (!equirectLayout.ok) return err(equirectLayout.error);
477
+ const irradianceLayout = device.createPipelineLayout({
478
+ label: 'ibl-irradiance-pipeline-layout',
479
+ bindGroupLayouts: [faceBgl.value, cubeGroup1.value],
480
+ });
481
+ if (!irradianceLayout.ok) return err(irradianceLayout.error);
482
+ const prefilterLayout = device.createPipelineLayout({
483
+ label: 'ibl-prefilter-pipeline-layout',
484
+ bindGroupLayouts: [prefilterGroup0.value, cubeGroup1.value],
485
+ });
486
+ if (!prefilterLayout.ok) return err(prefilterLayout.error);
487
+ const brdfLutLayout = device.createPipelineLayout({
488
+ label: 'ibl-brdf-lut-pipeline-layout',
489
+ bindGroupLayouts: [],
490
+ });
491
+ if (!brdfLutLayout.ok) return err(brdfLutLayout.error);
595
492
 
596
493
  const vertexLayout3F = {
597
494
  arrayStride: 12,
598
495
  attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' as const }],
599
496
  };
600
497
 
601
- const pipeEquirect = unwrap(
602
- device.createRenderPipeline({
603
- label: 'ibl-equirect-to-cube-pipeline',
604
- layout: equirectLayout,
605
- vertex: { module: mEq, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
606
- fragment: {
607
- module: mEq,
608
- entryPoint: 'equirectToCube_fs',
609
- targets: [{ format: cubeOutputFormat }],
610
- },
611
- primitive: { topology: 'triangle-list', cullMode: 'none' },
612
- }),
613
- );
614
- if (pipeEquirect === undefined) return { ok: false, error: 'ibl-equirect-to-cube-pipeline' };
615
- cache.equirectToCubePipeline = pipeEquirect;
616
-
617
- const pipeIrradiance = unwrap(
618
- device.createRenderPipeline({
619
- label: 'ibl-irradiance-pipeline',
620
- layout: irradianceLayout,
621
- vertex: { module: mIr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
622
- fragment: {
623
- module: mIr,
624
- entryPoint: 'irradianceConvolve_fs',
625
- targets: [{ format: cubeOutputFormat }],
626
- },
627
- primitive: { topology: 'triangle-list', cullMode: 'none' },
628
- }),
629
- );
630
- if (pipeIrradiance === undefined) return { ok: false, error: 'ibl-irradiance-pipeline' };
631
- cache.irradiancePipeline = pipeIrradiance;
632
-
633
- const pipePrefilter = unwrap(
634
- device.createRenderPipeline({
635
- label: 'ibl-prefilter-pipeline',
636
- layout: prefilterLayout,
637
- vertex: { module: mPr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
638
- fragment: {
639
- module: mPr,
640
- entryPoint: 'prefilterEnv_fs',
641
- targets: [{ format: cubeOutputFormat }],
642
- },
643
- primitive: { topology: 'triangle-list', cullMode: 'none' },
644
- }),
645
- );
646
- if (pipePrefilter === undefined) return { ok: false, error: 'ibl-prefilter-pipeline' };
647
- cache.prefilterPipeline = pipePrefilter;
648
-
649
- const pipeBrdfLut = unwrap(
650
- device.createRenderPipeline({
651
- label: 'ibl-brdf-lut-pipeline',
652
- layout: brdfLutLayout,
653
- vertex: { module: mBr, entryPoint: 'fullscreen_vs', buffers: [] },
654
- fragment: {
655
- module: mBr,
656
- entryPoint: 'brdfLutBake_fs',
657
- targets: [{ format: cubeOutputFormat }],
658
- },
659
- primitive: { topology: 'triangle-list', cullMode: 'none' },
660
- }),
661
- );
662
- if (pipeBrdfLut === undefined) return { ok: false, error: 'ibl-brdf-lut-pipeline' };
663
- cache.brdfLutPipeline = pipeBrdfLut;
498
+ const pipeEquirect = device.createRenderPipeline({
499
+ label: 'ibl-equirect-to-cube-pipeline',
500
+ layout: equirectLayout.value,
501
+ vertex: { module: mEq, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
502
+ fragment: {
503
+ module: mEq,
504
+ entryPoint: 'equirectToCube_fs',
505
+ targets: [{ format: cubeOutputFormat }],
506
+ },
507
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
508
+ });
509
+ if (!pipeEquirect.ok) return err(pipeEquirect.error);
510
+ cache.equirectToCubePipeline = pipeEquirect.value;
511
+
512
+ const pipeIrradiance = device.createRenderPipeline({
513
+ label: 'ibl-irradiance-pipeline',
514
+ layout: irradianceLayout.value,
515
+ vertex: { module: mIr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
516
+ fragment: {
517
+ module: mIr,
518
+ entryPoint: 'irradianceConvolve_fs',
519
+ targets: [{ format: cubeOutputFormat }],
520
+ },
521
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
522
+ });
523
+ if (!pipeIrradiance.ok) return err(pipeIrradiance.error);
524
+ cache.irradiancePipeline = pipeIrradiance.value;
525
+
526
+ const pipePrefilter = device.createRenderPipeline({
527
+ label: 'ibl-prefilter-pipeline',
528
+ layout: prefilterLayout.value,
529
+ vertex: { module: mPr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
530
+ fragment: {
531
+ module: mPr,
532
+ entryPoint: 'prefilterEnv_fs',
533
+ targets: [{ format: cubeOutputFormat }],
534
+ },
535
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
536
+ });
537
+ if (!pipePrefilter.ok) return err(pipePrefilter.error);
538
+ cache.prefilterPipeline = pipePrefilter.value;
539
+
540
+ const pipeBrdfLut = device.createRenderPipeline({
541
+ label: 'ibl-brdf-lut-pipeline',
542
+ layout: brdfLutLayout.value,
543
+ vertex: { module: mBr, entryPoint: 'fullscreen_vs', buffers: [] },
544
+ fragment: {
545
+ module: mBr,
546
+ entryPoint: 'brdfLutBake_fs',
547
+ targets: [{ format: cubeOutputFormat }],
548
+ },
549
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
550
+ });
551
+ if (!pipeBrdfLut.ok) return err(pipeBrdfLut.error);
552
+ cache.brdfLutPipeline = pipeBrdfLut.value;
553
+
554
+ return ok({
555
+ equirectToCubePipeline: pipeEquirect.value,
556
+ irradiancePipeline: pipeIrradiance.value,
557
+ prefilterPipeline: pipePrefilter.value,
558
+ brdfLutPipeline: pipeBrdfLut.value,
559
+ });
560
+ }
664
561
 
562
+ function iblPipelineError(
563
+ stage: string,
564
+ code: IblPipelineError['code'],
565
+ cause?: RhiError,
566
+ ): IblPipelineError {
665
567
  return {
666
- ok: true,
667
- value: {
668
- equirectToCubePipeline: cache.equirectToCubePipeline,
669
- irradiancePipeline: cache.irradiancePipeline,
670
- prefilterPipeline: cache.prefilterPipeline,
671
- brdfLutPipeline: cache.brdfLutPipeline,
672
- },
568
+ code,
569
+ expected: `${stage} completed through the RHI Result contract`,
570
+ hint: `inspect the ${stage} RHI error before retrying IBL pipeline creation`,
571
+ detail: { stage, ...(cause === undefined ? {} : { rhiCode: cause.code }) },
673
572
  };
674
573
  }
675
574
 
@@ -677,28 +576,28 @@ export async function createIblPipelines(
677
576
 
678
577
  /**
679
578
  * Options consumed by runIblPrecompute. The caller (the internal
680
- * GpuResourceStore equirect-to-cubemap projection) provides the equirect input
579
+ * GpuResidencyCache equirect-to-cubemap projection) provides the equirect input
681
580
  * + cubemap target GPU resources; the face-uniform / prefilter-uniform buffers
682
581
  * come from the t55 helpers.
683
582
  */
684
583
  export interface RunIblPrecomputeOptions {
685
- readonly device: IblPipelineDevice;
686
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture (input equirect)
687
- readonly equirectGpuTex: any;
688
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture view (input equirect 2D view)
689
- readonly equirectView: any;
690
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture (output cube)
691
- readonly cubeGpuTex: any;
692
- // biome-ignore lint/suspicious/noExplicitAny: opaque cube view (for sampling)
693
- readonly cubeView: any;
694
- // biome-ignore lint/suspicious/noExplicitAny: per-face 2D views (6) for render attachments
695
- readonly cubeFaceViews: ReadonlyArray<any>;
696
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU buffer (6 x 256-byte face uniforms)
697
- readonly faceUniformsBuffer: any;
698
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU buffer (30 x 256-byte prefilter uniforms)
699
- readonly prefilterUniformsBuffer: any;
700
- // biome-ignore lint/suspicious/noExplicitAny: opaque vertex buffer (36 cube verts)
701
- readonly cubeVertexBuffer: any;
584
+ readonly scope: DeviceScope;
585
+ readonly device: IblRhiOwner;
586
+ readonly equirectGpuTex: Texture;
587
+ readonly equirectView: TextureView;
588
+ readonly cubeGpuTex: Texture;
589
+ readonly cubeView: TextureView;
590
+ readonly cubeFaceViews: ReadonlyArray<TextureView>;
591
+ readonly faceUniformsBuffer: Buffer;
592
+ readonly prefilterUniformsBuffer: Buffer;
593
+ readonly cubeVertexBuffer: Buffer;
594
+ }
595
+
596
+ export interface IblPrecomputeError {
597
+ readonly code: 'ibl-precompute-not-dispatched';
598
+ readonly expected: string;
599
+ readonly hint: string;
600
+ readonly detail?: { readonly stage: string; readonly rhiCode?: RhiError['code'] };
702
601
  }
703
602
 
704
603
  /**
@@ -712,107 +611,28 @@ export interface RunIblPrecomputeOptions {
712
611
  * round-1 "counter += 1 as dispatch proxy" anti-pattern.
713
612
  *
714
613
  * Returns Result.err with code='ibl-precompute-not-dispatched' when the
715
- * underlying device lacks queue.submit or any of the 4 pipelines was not
614
+ * underlying device lacks queue.submit or one of the 4 pipelines was not
716
615
  * created (createIblPipelines must run first).
717
616
  */
718
617
  export function runIblPrecompute(
719
618
  opts: RunIblPrecomputeOptions,
720
- ):
721
- | { ok: true; value: { submitted: boolean } }
722
- | { ok: false; error: { code: string; expected: string; hint: string } } {
723
- const { device } = opts;
724
- const cache = getOrCreateIblCache(device);
619
+ ): Result<{ submitted: boolean }, IblPrecomputeError> {
620
+ const { device, scope } = opts;
621
+ const cache = getOrCreateIblCache(scope);
725
622
  const outputFormat = cache.outputFormat ?? 'rgba16float';
726
623
 
727
- // M5-amend Bug 1: support both rhi-shim path (Result<T, RhiError>) and raw
728
- // GPUDevice path (returns value directly). The shim returns
729
- // `{ok, value}`; raw devices return the GPU resource handle directly.
730
- // Same root cause + remedy as the mesh-upload raw-device fix at
731
- // uploadMeshById. Without this normalisation, every `device.createXxx(...)`
732
- // call inside this function bails on `!res.ok` (== !undefined == true)
733
- // when invoked from dawn-node / native bindings, silently skipping the
734
- // entire dispatch chain.
735
- // biome-ignore lint/suspicious/noExplicitAny: union of shim/raw return shapes
736
- const unwrap = (r: any): any => {
737
- if (r === null || r === undefined) return undefined;
738
- if (typeof r === 'object' && 'ok' in r) return r.ok ? r.value : undefined;
739
- return r;
740
- };
741
-
742
- // M5-amend Bug 1: detect raw GPUDevice vs rhi-shim. The shim's
743
- // `createBindGroup` accepts the forgeax tagged-union resource shape
744
- // (`{kind: 'buffer', value: {buffer, offset, size}}` etc.); raw
745
- // GPUDevice strictly requires WebGPU spec shape (`{buffer, offset,
746
- // size}` directly as `resource` for buffer bindings, raw view/sampler
747
- // handles directly for the other kinds). Probe by creating a no-op
748
- // empty BGL: shim wraps in `{ok, value}`; raw returns the BGL handle
749
- // directly. We discard the probe result; the cache already has BGLs.
750
- // biome-ignore lint/suspicious/noExplicitAny: probe call
751
- const probe: any = device.createBindGroupLayout({
752
- label: 'ibl-shape-probe',
753
- entries: [],
754
- });
755
- const isRawDevice =
756
- probe === null || probe === undefined || typeof probe !== 'object' || !('ok' in probe);
757
-
758
- // biome-ignore lint/suspicious/noExplicitAny: spec buffer-binding shape
759
- type SpecBgEntry = { binding: number; resource: any };
760
- // biome-ignore lint/suspicious/noExplicitAny: forgeax tagged-union resource
761
- const toSpecResource = (r: any): any => {
762
- if (r === null || r === undefined) return r;
763
- if (typeof r !== 'object' || !('kind' in r)) return r;
764
- if (r.kind === 'sampler') return r.value;
765
- if (r.kind === 'textureView') return r.value;
766
- if (r.kind === 'externalTexture') return r.value;
767
- if (r.kind === 'buffer') {
768
- const v = r.value;
769
- if (v !== null && typeof v === 'object' && 'buffer' in v) return v;
770
- // legacy shape -- shouldn't occur after Bug 1 fix but tolerate
771
- return { buffer: v };
772
- }
773
- return r;
774
- };
775
- // biome-ignore lint/suspicious/noExplicitAny: descriptor builder
776
- const buildBgDesc = (desc: any): any => {
777
- if (!isRawDevice) return desc;
778
- const entries: SpecBgEntry[] = (
779
- desc.entries as ReadonlyArray<{ binding: number; resource: unknown }>
780
- ).map((e) => ({
781
- binding: e.binding,
782
- resource: toSpecResource(e.resource),
783
- }));
784
- const out: { label?: string; layout: unknown; entries: SpecBgEntry[] } = {
785
- layout: desc.layout,
786
- entries,
787
- };
788
- if ('label' in desc && desc.label !== undefined) out.label = desc.label;
789
- return out;
790
- };
791
-
792
624
  if (
793
625
  cache.equirectToCubePipeline === undefined ||
794
626
  cache.irradiancePipeline === undefined ||
795
627
  cache.prefilterPipeline === undefined ||
796
628
  cache.brdfLutPipeline === undefined
797
629
  ) {
798
- return {
799
- ok: false,
800
- error: {
801
- code: 'ibl-precompute-not-dispatched',
802
- expected: '4 IBL pipelines created via createIblPipelines',
803
- hint: 'check IblPipelineCache.createIblPipelines was called before runIblPrecompute; counters must not increment before queue.submit',
804
- },
805
- };
806
- }
807
- if (typeof device.queue?.submit !== 'function') {
808
- return {
809
- ok: false,
810
- error: {
811
- code: 'ibl-precompute-not-dispatched',
812
- expected: 'device.queue.submit callable',
813
- hint: 'check IblPipelineCache.runIblPrecompute is called inside the GpuResourceStore equirect-to-cubemap projection; counters must not increment before queue.submit',
814
- },
815
- };
630
+ return err({
631
+ code: 'ibl-precompute-not-dispatched',
632
+ expected: '4 IBL pipelines created via createIblPipelines',
633
+ hint: 'check IblPipelineCache.createIblPipelines was called before runIblPrecompute; counters must not increment before queue.submit',
634
+ detail: { stage: 'pipeline-cache' },
635
+ });
816
636
  }
817
637
 
818
638
  // Allocate side textures (irradiance / prefilter / brdf-lut) lazily.
@@ -821,31 +641,8 @@ export function runIblPrecompute(
821
641
  // requires the TextureUsage::CopySrc bit on the source. Without it
822
642
  // Dawn fails-fast "usage doesn't include CopySrc".
823
643
 
824
- // M5-amend Bug 1: helper that normalises shim/raw texture-view creation.
825
- // Raw GPUDevice exposes `gpuTexture.createView(desc)` on the texture
826
- // object itself; the rhi-shim exposes `device.createTextureView(tex, desc)`
827
- // and returns Result<T>.
828
- // biome-ignore lint/suspicious/noExplicitAny: shim/raw device split
829
- const makeView = (texture: any, desc: any): any => {
830
- // biome-ignore lint/suspicious/noExplicitAny: device shim shape
831
- const dev = device as any;
832
- if (typeof dev.createTextureView === 'function') {
833
- const r = dev.createTextureView(texture, desc);
834
- const u = unwrap(r);
835
- if (u !== undefined) return u;
836
- }
837
- if (texture !== null && texture !== undefined && typeof texture.createView === 'function') {
838
- try {
839
- return texture.createView(desc);
840
- } catch {
841
- return undefined;
842
- }
843
- }
844
- return undefined;
845
- };
846
-
847
644
  if (cache.irradianceTexture === undefined) {
848
- const tRaw = device.createTexture({
645
+ const textureResult = device.createTexture({
849
646
  label: 'ibl-irradiance-cube',
850
647
  size: { width: IRRADIANCE_SIZE, height: IRRADIANCE_SIZE, depthOrArrayLayers: 6 },
851
648
  mipLevelCount: 1,
@@ -857,34 +654,33 @@ export function runIblPrecompute(
857
654
  GPU_TEXTURE_USAGE_COPY_DST |
858
655
  GPU_TEXTURE_USAGE_COPY_SRC,
859
656
  viewFormats: [],
657
+ textureBindingViewDimension: undefined,
860
658
  });
861
- const tVal = unwrap(tRaw);
862
- if (tVal === undefined) return { ok: false, error: badAlloc('irradiance-texture') };
863
- cache.irradianceTexture = tVal;
864
- const cubeView = makeView(tVal, {
659
+ if (!textureResult.ok) return err(badAlloc('irradiance-texture', textureResult.error));
660
+ cache.irradianceTexture = textureResult.value;
661
+ const cubeViewResult = device.createTextureView(textureResult.value, {
865
662
  label: 'ibl-irradiance-cube-view',
866
663
  dimension: 'cube',
867
664
  arrayLayerCount: 6,
868
665
  });
869
- if (cubeView === undefined) return { ok: false, error: badAlloc('irradiance-view') };
870
- cache.irradianceView = cubeView;
871
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU views
872
- const faceViews: any[] = [];
666
+ if (!cubeViewResult.ok) return err(badAlloc('irradiance-view', cubeViewResult.error));
667
+ cache.irradianceView = cubeViewResult.value;
668
+ const faceViews: TextureView[] = [];
873
669
  for (let f = 0; f < 6; f++) {
874
- const v = makeView(tVal, {
670
+ const viewResult = device.createTextureView(textureResult.value, {
875
671
  label: `ibl-irradiance-face-${f}`,
876
672
  dimension: '2d',
877
673
  baseArrayLayer: f,
878
674
  arrayLayerCount: 1,
879
675
  });
880
- if (v === undefined) return { ok: false, error: badAlloc('irradiance-face-view') };
881
- faceViews.push(v);
676
+ if (!viewResult.ok) return err(badAlloc('irradiance-face-view', viewResult.error));
677
+ faceViews.push(viewResult.value);
882
678
  }
883
679
  cache.irradianceFaceViews = faceViews;
884
680
  }
885
681
 
886
682
  if (cache.prefilterTexture === undefined) {
887
- const tRaw = device.createTexture({
683
+ const textureResult = device.createTexture({
888
684
  label: 'ibl-prefilter-cube',
889
685
  size: { width: PREFILTER_SIZE, height: PREFILTER_SIZE, depthOrArrayLayers: 6 },
890
686
  mipLevelCount: PREFILTER_MIP_LEVELS,
@@ -896,26 +692,24 @@ export function runIblPrecompute(
896
692
  GPU_TEXTURE_USAGE_COPY_DST |
897
693
  GPU_TEXTURE_USAGE_COPY_SRC,
898
694
  viewFormats: [],
695
+ textureBindingViewDimension: undefined,
899
696
  });
900
- const tVal = unwrap(tRaw);
901
- if (tVal === undefined) return { ok: false, error: badAlloc('prefilter-texture') };
902
- cache.prefilterTexture = tVal;
903
- const cubeView = makeView(tVal, {
697
+ if (!textureResult.ok) return err(badAlloc('prefilter-texture', textureResult.error));
698
+ cache.prefilterTexture = textureResult.value;
699
+ const cubeViewResult = device.createTextureView(textureResult.value, {
904
700
  label: 'ibl-prefilter-cube-view',
905
701
  dimension: 'cube',
906
702
  arrayLayerCount: 6,
907
703
  baseMipLevel: 0,
908
704
  mipLevelCount: PREFILTER_MIP_LEVELS,
909
705
  });
910
- if (cubeView === undefined) return { ok: false, error: badAlloc('prefilter-view') };
911
- cache.prefilterView = cubeView;
912
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU views
913
- const mipViews: any[][] = [];
706
+ if (!cubeViewResult.ok) return err(badAlloc('prefilter-view', cubeViewResult.error));
707
+ cache.prefilterView = cubeViewResult.value;
708
+ const mipViews: TextureView[][] = [];
914
709
  for (let m = 0; m < PREFILTER_MIP_LEVELS; m++) {
915
- // biome-ignore lint/suspicious/noExplicitAny: opaque GPU views
916
- const faces: any[] = [];
710
+ const faces: TextureView[] = [];
917
711
  for (let f = 0; f < 6; f++) {
918
- const v = makeView(tVal, {
712
+ const viewResult = device.createTextureView(textureResult.value, {
919
713
  label: `ibl-prefilter-mip${m}-face${f}`,
920
714
  dimension: '2d',
921
715
  baseMipLevel: m,
@@ -923,8 +717,8 @@ export function runIblPrecompute(
923
717
  baseArrayLayer: f,
924
718
  arrayLayerCount: 1,
925
719
  });
926
- if (v === undefined) return { ok: false, error: badAlloc('prefilter-face-view') };
927
- faces.push(v);
720
+ if (!viewResult.ok) return err(badAlloc('prefilter-face-view', viewResult.error));
721
+ faces.push(viewResult.value);
928
722
  }
929
723
  mipViews.push(faces);
930
724
  }
@@ -932,7 +726,7 @@ export function runIblPrecompute(
932
726
  }
933
727
 
934
728
  if (cache.brdfLutTexture === undefined) {
935
- const tRaw = device.createTexture({
729
+ const textureResult = device.createTexture({
936
730
  label: 'ibl-brdf-lut',
937
731
  size: { width: BRDF_LUT_SIZE, height: BRDF_LUT_SIZE, depthOrArrayLayers: 1 },
938
732
  mipLevelCount: 1,
@@ -944,22 +738,22 @@ export function runIblPrecompute(
944
738
  GPU_TEXTURE_USAGE_COPY_DST |
945
739
  GPU_TEXTURE_USAGE_COPY_SRC,
946
740
  viewFormats: [],
741
+ textureBindingViewDimension: undefined,
947
742
  });
948
- const tVal = unwrap(tRaw);
949
- if (tVal === undefined) return { ok: false, error: badAlloc('brdf-lut-texture') };
950
- cache.brdfLutTexture = tVal;
951
- const v = makeView(tVal, {
743
+ if (!textureResult.ok) return err(badAlloc('brdf-lut-texture', textureResult.error));
744
+ cache.brdfLutTexture = textureResult.value;
745
+ const viewResult = device.createTextureView(textureResult.value, {
952
746
  label: 'ibl-brdf-lut-view',
953
747
  dimension: '2d',
954
748
  });
955
- if (v === undefined) return { ok: false, error: badAlloc('brdf-lut-view') };
956
- cache.brdfLutView = v;
749
+ if (!viewResult.ok) return err(badAlloc('brdf-lut-view', viewResult.error));
750
+ cache.brdfLutView = viewResult.value;
957
751
  }
958
752
 
959
753
  // Shared sampler (filtering, linear-linear).
960
754
  // U=repeat because equirect wraps horizontally (atan2 seam at ±π);
961
755
  // V=clamp because equirect poles are clamped vertically.
962
- const samplerRaw = device.createSampler({
756
+ const samplerResult = device.createSampler({
963
757
  label: 'ibl-precompute-sampler',
964
758
  magFilter: 'linear',
965
759
  minFilter: 'linear',
@@ -968,51 +762,74 @@ export function runIblPrecompute(
968
762
  addressModeV: 'clamp-to-edge',
969
763
  addressModeW: 'clamp-to-edge',
970
764
  });
971
- const sampler = unwrap(samplerRaw);
972
- if (sampler === undefined) return { ok: false, error: badAlloc('sampler') };
973
-
974
- const encoderRaw = device.createCommandEncoder({ label: 'ibl-precompute-encoder' });
975
- const encoder = unwrap(encoderRaw);
976
- if (encoder === undefined) return { ok: false, error: badAlloc('encoder') };
765
+ if (!samplerResult.ok) return err(badAlloc('sampler', samplerResult.error));
766
+ const sampler: Sampler = samplerResult.value;
767
+
768
+ const encoderResult = device.createCommandEncoder({ label: 'ibl-precompute-encoder' });
769
+ if (!encoderResult.ok) return err(badAlloc('encoder', encoderResult.error));
770
+ const encoder: RhiCommandEncoder = encoderResult.value;
771
+
772
+ const faceUniformsBgl = cache.faceUniformsBgl;
773
+ const equirectGroup1Bgl = cache.equirectGroup1Bgl;
774
+ const cubeGroup1Bgl = cache.cubeGroup1Bgl;
775
+ const prefilterGroup0Bgl = cache.prefilterGroup0Bgl;
776
+ const equirectPipeline = cache.equirectToCubePipeline;
777
+ const irradiancePipeline = cache.irradiancePipeline;
778
+ const prefilterPipeline = cache.prefilterPipeline;
779
+ const brdfLutPipeline = cache.brdfLutPipeline;
780
+ const irrFaceViews = cache.irradianceFaceViews;
781
+ const prefMipViews = cache.prefilterFaceViewsByMip;
782
+ const brdfLutView = cache.brdfLutView;
783
+ if (
784
+ faceUniformsBgl === undefined ||
785
+ equirectGroup1Bgl === undefined ||
786
+ cubeGroup1Bgl === undefined ||
787
+ prefilterGroup0Bgl === undefined ||
788
+ equirectPipeline === undefined ||
789
+ irradiancePipeline === undefined ||
790
+ prefilterPipeline === undefined ||
791
+ brdfLutPipeline === undefined ||
792
+ irrFaceViews === undefined ||
793
+ prefMipViews === undefined ||
794
+ brdfLutView === undefined
795
+ ) {
796
+ return err(badAlloc('ibl-cache-resources'));
797
+ }
977
798
 
978
799
  // Bind group: equirect group(1).
979
- const equirectBg = unwrap(
980
- device.createBindGroup(
981
- buildBgDesc({
982
- label: 'ibl-equirect-bg',
983
- layout: cache.equirectGroup1Bgl,
984
- entries: [
985
- { binding: 0, resource: { kind: 'textureView', value: opts.equirectView } },
986
- { binding: 1, resource: { kind: 'sampler', value: sampler } },
987
- ],
988
- }),
989
- ),
990
- );
991
- if (equirectBg === undefined) return { ok: false, error: badAlloc('equirect-bg') };
800
+ const equirectBgResult = device.createBindGroup({
801
+ label: 'ibl-equirect-bg',
802
+ layout: equirectGroup1Bgl,
803
+ entries: [
804
+ { binding: 0, resource: { kind: 'textureView', value: opts.equirectView } },
805
+ { binding: 1, resource: { kind: 'sampler', value: sampler } },
806
+ ],
807
+ });
808
+ if (!equirectBgResult.ok) return err(badAlloc('equirect-bg', equirectBgResult.error));
809
+ const equirectBg: BindGroup = equirectBgResult.value;
992
810
 
993
811
  // Bind group: cube group(1) for irradiance + prefilter.
994
- const cubeBg = unwrap(
995
- device.createBindGroup(
996
- buildBgDesc({
997
- label: 'ibl-cube-bg',
998
- layout: cache.cubeGroup1Bgl,
999
- entries: [
1000
- { binding: 0, resource: { kind: 'textureView', value: opts.cubeView } },
1001
- { binding: 1, resource: { kind: 'sampler', value: sampler } },
1002
- ],
1003
- }),
1004
- ),
1005
- );
1006
- if (cubeBg === undefined) return { ok: false, error: badAlloc('cube-bg') };
812
+ const cubeBgResult = device.createBindGroup({
813
+ label: 'ibl-cube-bg',
814
+ layout: cubeGroup1Bgl,
815
+ entries: [
816
+ { binding: 0, resource: { kind: 'textureView', value: opts.cubeView } },
817
+ { binding: 1, resource: { kind: 'sampler', value: sampler } },
818
+ ],
819
+ });
820
+ if (!cubeBgResult.ok) return err(badAlloc('cube-bg', cubeBgResult.error));
821
+ const cubeBg: BindGroup = cubeBgResult.value;
1007
822
 
1008
823
  // (a) equirect-to-cube: 6 face draws.
1009
824
  const cubeFaceViews = opts.cubeFaceViews;
1010
825
  for (let face = 0; face < 6; face++) {
1011
- const pass = encoder.beginRenderPass({
826
+ const cubeFaceView = cubeFaceViews[face];
827
+ if (cubeFaceView === undefined) return err(badAlloc('cube-face-view'));
828
+ const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
1012
829
  label: 'ibl-equirect-to-cube',
1013
830
  colorAttachments: [
1014
831
  {
1015
- view: cubeFaceViews[face],
832
+ view: cubeFaceView,
1016
833
  clearValue: { r: 0, g: 0, b: 0, a: 1 },
1017
834
  loadOp: 'clear',
1018
835
  storeOp: 'store',
@@ -1020,30 +837,26 @@ export function runIblPrecompute(
1020
837
  ],
1021
838
  });
1022
839
  // Face uniform: dynamic offset = face * 256.
1023
- const faceBg = unwrap(
1024
- device.createBindGroup(
1025
- buildBgDesc({
1026
- label: `ibl-face-bg-${face}`,
1027
- layout: cache.faceUniformsBgl,
1028
- entries: [
1029
- {
1030
- binding: 0,
1031
- resource: {
1032
- kind: 'buffer',
1033
- value: {
1034
- buffer: opts.faceUniformsBuffer,
1035
- offset: face * 256,
1036
- size: 64,
1037
- },
1038
- },
840
+ const faceBgResult = device.createBindGroup({
841
+ label: `ibl-face-bg-${face}`,
842
+ layout: faceUniformsBgl,
843
+ entries: [
844
+ {
845
+ binding: 0,
846
+ resource: {
847
+ kind: 'buffer',
848
+ value: {
849
+ buffer: opts.faceUniformsBuffer,
850
+ offset: face * 256,
851
+ size: 64,
1039
852
  },
1040
- ],
1041
- }),
1042
- ),
1043
- );
1044
- if (faceBg === undefined) return { ok: false, error: badAlloc('face-bg') };
1045
- pass.setPipeline(cache.equirectToCubePipeline);
1046
- pass.setBindGroup(0, faceBg);
853
+ },
854
+ },
855
+ ],
856
+ });
857
+ if (!faceBgResult.ok) return err(badAlloc('face-bg', faceBgResult.error));
858
+ pass.setPipeline(equirectPipeline);
859
+ pass.setBindGroup(0, faceBgResult.value);
1047
860
  pass.setBindGroup(1, equirectBg);
1048
861
  pass.setVertexBuffer(0, opts.cubeVertexBuffer);
1049
862
  pass.draw(6, 1, face * 6, 0);
@@ -1051,43 +864,40 @@ export function runIblPrecompute(
1051
864
  }
1052
865
 
1053
866
  // (b) irradiance convolve: 6 face draws.
1054
- const irrFaceViews = cache.irradianceFaceViews ?? [];
1055
867
  for (let face = 0; face < 6; face++) {
1056
- const pass = encoder.beginRenderPass({
868
+ const irrFaceView = irrFaceViews[face];
869
+ if (irrFaceView === undefined) return err(badAlloc('irradiance-face-view'));
870
+ const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
1057
871
  label: 'ibl-irradiance',
1058
872
  colorAttachments: [
1059
873
  {
1060
- view: irrFaceViews[face],
874
+ view: irrFaceView,
1061
875
  clearValue: { r: 0, g: 0, b: 0, a: 1 },
1062
876
  loadOp: 'clear',
1063
877
  storeOp: 'store',
1064
878
  },
1065
879
  ],
1066
880
  });
1067
- const faceBg = unwrap(
1068
- device.createBindGroup(
1069
- buildBgDesc({
1070
- label: `ibl-irr-face-bg-${face}`,
1071
- layout: cache.faceUniformsBgl,
1072
- entries: [
1073
- {
1074
- binding: 0,
1075
- resource: {
1076
- kind: 'buffer',
1077
- value: {
1078
- buffer: opts.faceUniformsBuffer,
1079
- offset: face * 256,
1080
- size: 64,
1081
- },
1082
- },
881
+ const faceBgResult = device.createBindGroup({
882
+ label: `ibl-irr-face-bg-${face}`,
883
+ layout: faceUniformsBgl,
884
+ entries: [
885
+ {
886
+ binding: 0,
887
+ resource: {
888
+ kind: 'buffer',
889
+ value: {
890
+ buffer: opts.faceUniformsBuffer,
891
+ offset: face * 256,
892
+ size: 64,
1083
893
  },
1084
- ],
1085
- }),
1086
- ),
1087
- );
1088
- if (faceBg === undefined) return { ok: false, error: badAlloc('irr-face-bg') };
1089
- pass.setPipeline(cache.irradiancePipeline);
1090
- pass.setBindGroup(0, faceBg);
894
+ },
895
+ },
896
+ ],
897
+ });
898
+ if (!faceBgResult.ok) return err(badAlloc('irr-face-bg', faceBgResult.error));
899
+ pass.setPipeline(irradiancePipeline);
900
+ pass.setBindGroup(0, faceBgResult.value);
1091
901
  pass.setBindGroup(1, cubeBg);
1092
902
  pass.setVertexBuffer(0, opts.cubeVertexBuffer);
1093
903
  pass.draw(6, 1, face * 6, 0);
@@ -1095,57 +905,55 @@ export function runIblPrecompute(
1095
905
  }
1096
906
 
1097
907
  // (c) prefilter env: 5 mips x 6 faces = 30 sub-passes.
1098
- const prefMipViews = cache.prefilterFaceViewsByMip ?? [];
1099
908
  for (let mip = 0; mip < PREFILTER_MIP_LEVELS; mip++) {
1100
- const mipFaceViews = prefMipViews[mip] ?? [];
909
+ const mipFaceViews = prefMipViews[mip];
910
+ if (mipFaceViews === undefined) return err(badAlloc('prefilter-mip-views'));
1101
911
  for (let face = 0; face < 6; face++) {
1102
912
  const subIdx = mip * 6 + face;
1103
- const pass = encoder.beginRenderPass({
913
+ const mipFaceView = mipFaceViews[face];
914
+ if (mipFaceView === undefined) return err(badAlloc('prefilter-face-view'));
915
+ const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
1104
916
  label: 'ibl-prefilter',
1105
917
  colorAttachments: [
1106
918
  {
1107
- view: mipFaceViews[face],
919
+ view: mipFaceView,
1108
920
  clearValue: { r: 0, g: 0, b: 0, a: 1 },
1109
921
  loadOp: 'clear',
1110
922
  storeOp: 'store',
1111
923
  },
1112
924
  ],
1113
925
  });
1114
- const bg = unwrap(
1115
- device.createBindGroup(
1116
- buildBgDesc({
1117
- label: `ibl-pref-bg-${subIdx}`,
1118
- layout: prefilterGroup0LayoutOf(cache),
1119
- entries: [
1120
- {
1121
- binding: 0,
1122
- resource: {
1123
- kind: 'buffer',
1124
- value: {
1125
- buffer: opts.faceUniformsBuffer,
1126
- offset: face * 256,
1127
- size: 64,
1128
- },
1129
- },
926
+ const bgResult = device.createBindGroup({
927
+ label: `ibl-pref-bg-${subIdx}`,
928
+ layout: prefilterGroup0Bgl,
929
+ entries: [
930
+ {
931
+ binding: 0,
932
+ resource: {
933
+ kind: 'buffer',
934
+ value: {
935
+ buffer: opts.faceUniformsBuffer,
936
+ offset: face * 256,
937
+ size: 64,
1130
938
  },
1131
- {
1132
- binding: 1,
1133
- resource: {
1134
- kind: 'buffer',
1135
- value: {
1136
- buffer: opts.prefilterUniformsBuffer,
1137
- offset: subIdx * 256,
1138
- size: 16,
1139
- },
1140
- },
939
+ },
940
+ },
941
+ {
942
+ binding: 1,
943
+ resource: {
944
+ kind: 'buffer',
945
+ value: {
946
+ buffer: opts.prefilterUniformsBuffer,
947
+ offset: subIdx * 256,
948
+ size: 16,
1141
949
  },
1142
- ],
1143
- }),
1144
- ),
1145
- );
1146
- if (bg === undefined) return { ok: false, error: badAlloc('pref-bg') };
1147
- pass.setPipeline(cache.prefilterPipeline);
1148
- pass.setBindGroup(0, bg);
950
+ },
951
+ },
952
+ ],
953
+ });
954
+ if (!bgResult.ok) return err(badAlloc('pref-bg', bgResult.error));
955
+ pass.setPipeline(prefilterPipeline);
956
+ pass.setBindGroup(0, bgResult.value);
1149
957
  pass.setBindGroup(1, cubeBg);
1150
958
  pass.setVertexBuffer(0, opts.cubeVertexBuffer);
1151
959
  pass.draw(6, 1, face * 6, 0);
@@ -1155,18 +963,18 @@ export function runIblPrecompute(
1155
963
 
1156
964
  // (d) brdf-lut: fullscreen triangle.
1157
965
  {
1158
- const pass = encoder.beginRenderPass({
966
+ const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
1159
967
  label: 'ibl-brdf-lut',
1160
968
  colorAttachments: [
1161
969
  {
1162
- view: cache.brdfLutView,
970
+ view: brdfLutView,
1163
971
  clearValue: { r: 0, g: 0, b: 0, a: 1 },
1164
972
  loadOp: 'clear',
1165
973
  storeOp: 'store',
1166
974
  },
1167
975
  ],
1168
976
  });
1169
- pass.setPipeline(cache.brdfLutPipeline);
977
+ pass.setPipeline(brdfLutPipeline);
1170
978
  pass.draw(3, 1, 0, 0);
1171
979
  pass.end();
1172
980
  }
@@ -1174,73 +982,25 @@ export function runIblPrecompute(
1174
982
  // Finish + submit. Counter increments are STRICTLY after submit; if
1175
983
  // submit throws or fails, counters stay at 0 (AC-20 critical invariant).
1176
984
  const finishRes = encoder.finish();
1177
- // biome-ignore lint/suspicious/noExplicitAny: command buffer opaque
1178
- let cmdBuffer: any;
1179
- if (
1180
- finishRes !== null &&
1181
- finishRes !== undefined &&
1182
- typeof finishRes === 'object' &&
1183
- 'ok' in finishRes
1184
- ) {
1185
- if (!finishRes.ok) return { ok: false, error: badAlloc('finish') };
1186
- cmdBuffer = finishRes.value;
1187
- } else {
1188
- cmdBuffer = finishRes;
1189
- }
1190
-
1191
- // Submit -- may throw on mock devices in failure-injection tests, or
1192
- // return a structured Result.err on the rhi shim path. AC-20 critical:
1193
- // counters are incremented ONLY if submit returns cleanly (no throw +
1194
- // no .ok === false).
1195
- let submitOk = true;
1196
- let submitError: unknown;
1197
- try {
1198
- // biome-ignore lint/suspicious/noExplicitAny: submit returns Result|undefined
1199
- const submitRes = device.queue.submit([cmdBuffer]) as any;
1200
- if (
1201
- submitRes !== null &&
1202
- submitRes !== undefined &&
1203
- typeof submitRes === 'object' &&
1204
- 'ok' in submitRes &&
1205
- submitRes.ok === false
1206
- ) {
1207
- submitOk = false;
1208
- submitError = submitRes.error;
1209
- }
1210
- } catch (e) {
1211
- submitOk = false;
1212
- submitError = e;
1213
- }
1214
-
1215
- if (!submitOk) {
1216
- return {
1217
- ok: false,
1218
- error: {
1219
- code: 'ibl-precompute-not-dispatched',
1220
- expected: 'device.queue.submit returned successfully',
1221
- hint: `queue.submit failed: ${String(submitError)}; counters must not increment before queue.submit`,
1222
- },
1223
- };
1224
- }
985
+ if (!finishRes.ok) return err(badAlloc('finish', finishRes.error));
986
+ const cmdBuffer: CommandBuffer = finishRes.value;
987
+ const submitRes = device.queue.submit([cmdBuffer]);
988
+ if (!submitRes.ok) return err(badAlloc('queue.submit', submitRes.error));
1225
989
 
1226
990
  // POST-SUBMIT counter increments (AC-20).
1227
991
  cache.irradianceBakeCount += 1;
1228
992
  cache.prefilterBakeCount += 1;
1229
993
  cache.brdfLutBakeCount += 1;
1230
994
 
1231
- return { ok: true, value: { submitted: true } };
995
+ return ok({ submitted: true });
1232
996
  }
1233
997
 
1234
998
  // Local helper -- structured error payload shared across allocation paths.
1235
- function badAlloc(stage: string): { code: string; expected: string; hint: string } {
999
+ function badAlloc(stage: string, cause?: RhiError): IblPrecomputeError {
1236
1000
  return {
1237
1001
  code: 'ibl-precompute-not-dispatched',
1238
1002
  expected: `${stage} allocated successfully`,
1239
- hint: `check queue.submit path is reachable and ${stage} GPU resource creation did not fail; counters must not increment before queue.submit`,
1003
+ hint: `check the RHI Result for ${stage}; counters must not increment before queue.submit`,
1004
+ ...(cause === undefined ? {} : { detail: { stage, rhiCode: cause.code } }),
1240
1005
  };
1241
1006
  }
1242
-
1243
- // biome-ignore lint/suspicious/noExplicitAny: opaque BGL return
1244
- function prefilterGroup0LayoutOf(cache: IblPipelineCachePerDevice): any {
1245
- return cache.prefilterGroup0Bgl;
1246
- }