@forgeax/engine-render 0.1.27 → 0.1.29

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 (655) hide show
  1. package/README.md +842 -124
  2. package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
  3. package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
  4. package/dist/assembly/dynamic-geometry-host.d.ts +52 -0
  5. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
  6. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  7. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  8. package/dist/assembly/factory.d.ts +3 -1
  9. package/dist/assembly/factory.d.ts.map +1 -1
  10. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  11. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  12. package/dist/assembly/host-contract.d.ts +19 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +7 -0
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material-shader-policy.d.ts +3 -1
  17. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  18. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  19. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  20. package/dist/assembly/recovery/renderer-recover.d.ts +6 -4
  21. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  22. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  23. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  24. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  25. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  26. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  27. package/dist/assembly/renderer-helpers.d.ts +3 -0
  28. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  29. package/dist/assembly/renderer-inspection.d.ts +4 -0
  30. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  31. package/dist/assembly/shader-prewarm-policy.d.ts +6 -0
  32. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  33. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  34. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  35. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  36. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  37. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  38. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  39. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  40. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  41. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  42. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  43. package/dist/assembly/webgpu-ready.d.ts +7 -3
  44. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  45. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  46. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  47. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  48. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  49. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  50. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  51. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  52. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  53. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  54. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  55. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  56. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  57. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  58. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  59. package/dist/authoring.mjs +3 -3
  60. package/dist/{chunk-ADHHVYLW.mjs → chunk-33XZFTQU.mjs} +245 -39
  61. package/dist/chunk-33XZFTQU.mjs.map +1 -0
  62. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  63. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  64. package/dist/{chunk-KM2NOX2I.mjs → chunk-BQVQOQJH.mjs} +958 -254
  65. package/dist/chunk-BQVQOQJH.mjs.map +1 -0
  66. package/dist/{chunk-HKXTW355.mjs → chunk-BTWH7BP4.mjs} +386 -17
  67. package/dist/chunk-BTWH7BP4.mjs.map +1 -0
  68. package/dist/{chunk-TMIASV2N.mjs → chunk-FUODTTIA.mjs} +3934 -676
  69. package/dist/chunk-FUODTTIA.mjs.map +1 -0
  70. package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
  71. package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
  72. package/dist/{chunk-E34VL5VI.mjs → chunk-JQTSEI3Z.mjs} +3 -3
  73. package/dist/{chunk-E34VL5VI.mjs.map → chunk-JQTSEI3Z.mjs.map} +1 -1
  74. package/dist/{chunk-GE3SDD72.mjs → chunk-NICXSHAT.mjs} +16 -38
  75. package/dist/chunk-NICXSHAT.mjs.map +1 -0
  76. package/dist/{chunk-ZZ4YQ474.mjs → chunk-NRNXBLIJ.mjs} +577 -7
  77. package/dist/chunk-NRNXBLIJ.mjs.map +1 -0
  78. package/dist/{chunk-JDWARUOI.mjs → chunk-PA5DRJNI.mjs} +17 -3
  79. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  80. package/dist/{chunk-XDP6XE5V.mjs → chunk-S4DNKQYQ.mjs} +1118 -446
  81. package/dist/chunk-S4DNKQYQ.mjs.map +1 -0
  82. package/dist/components/camera.d.ts +62 -2
  83. package/dist/components/camera.d.ts.map +1 -1
  84. package/dist/components/index.d.ts +1 -0
  85. package/dist/components/index.d.ts.map +1 -1
  86. package/dist/components/instances.d.ts +6 -20
  87. package/dist/components/instances.d.ts.map +1 -1
  88. package/dist/components/scene-instance.d.ts +2 -1
  89. package/dist/components/scene-instance.d.ts.map +1 -1
  90. package/dist/components/screen-space-reflection.d.ts +14 -0
  91. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  92. package/dist/construct-renderer.mjs +13805 -7186
  93. package/dist/construct-renderer.mjs.map +1 -1
  94. package/dist/device/gpu-residency.d.ts +11 -17
  95. package/dist/device/gpu-residency.d.ts.map +1 -1
  96. package/dist/device/mesh-residency-lifetime.d.ts +21 -0
  97. package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
  98. package/dist/dynamic-geometry.d.ts +125 -0
  99. package/dist/dynamic-geometry.d.ts.map +1 -0
  100. package/dist/environment/background.d.ts +6 -0
  101. package/dist/environment/background.d.ts.map +1 -0
  102. package/dist/errors/gpu-driven.d.ts +6 -3
  103. package/dist/errors/gpu-driven.d.ts.map +1 -1
  104. package/dist/errors/render.d.ts +7 -4
  105. package/dist/errors/render.d.ts.map +1 -1
  106. package/dist/extract/camera.d.ts.map +1 -1
  107. package/dist/extract/gpu-driven.d.ts +33 -3
  108. package/dist/extract/gpu-driven.d.ts.map +1 -1
  109. package/dist/features/host.d.ts +23 -1
  110. package/dist/features/host.d.ts.map +1 -1
  111. package/dist/features/noise-texture.d.ts +17 -0
  112. package/dist/features/noise-texture.d.ts.map +1 -0
  113. package/dist/features/plan.d.ts +83 -2
  114. package/dist/features/plan.d.ts.map +1 -1
  115. package/dist/features/prepared-gpu-work.d.ts +37 -4
  116. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  117. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  118. package/dist/features/prepared-graphics.d.ts +5 -0
  119. package/dist/features/prepared-graphics.d.ts.map +1 -1
  120. package/dist/features/render-graph-compute.d.ts +5 -3
  121. package/dist/features/render-graph-compute.d.ts.map +1 -1
  122. package/dist/features/render-graph-contribution.d.ts +11 -3
  123. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  124. package/dist/features/render-graph-raster.d.ts +19 -3
  125. package/dist/features/render-graph-raster.d.ts.map +1 -1
  126. package/dist/features/types.d.ts +11 -0
  127. package/dist/features/types.d.ts.map +1 -1
  128. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  129. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  130. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  131. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  132. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  133. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  134. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  135. package/dist/gpu-driven/production-raster.d.ts +144 -23
  136. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  137. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  138. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  139. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  140. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  141. package/dist/gpu-scene-schema.d.ts +2 -8
  142. package/dist/gpu-scene-schema.d.ts.map +1 -1
  143. package/dist/gpu-scene.d.ts +14 -0
  144. package/dist/gpu-scene.d.ts.map +1 -1
  145. package/dist/gpu-texture-usage.d.ts +1 -0
  146. package/dist/gpu-texture-usage.d.ts.map +1 -1
  147. package/dist/hdrp-buffers.d.ts +6 -0
  148. package/dist/hdrp-buffers.d.ts.map +1 -1
  149. package/dist/ibl/frame-resources.d.ts +8 -0
  150. package/dist/ibl/frame-resources.d.ts.map +1 -0
  151. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  152. package/dist/index.d.ts +21 -8
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.mjs +8 -7
  155. package/dist/index.mjs.map +1 -1
  156. package/dist/inspection-types.d.ts +164 -0
  157. package/dist/inspection-types.d.ts.map +1 -1
  158. package/dist/instances-derived-bounds.d.ts +11 -0
  159. package/dist/instances-derived-bounds.d.ts.map +1 -1
  160. package/dist/instances.d.ts +89 -44
  161. package/dist/instances.d.ts.map +1 -1
  162. package/dist/internal.d.ts +3 -0
  163. package/dist/internal.d.ts.map +1 -1
  164. package/dist/internal.mjs +118 -10
  165. package/dist/internal.mjs.map +1 -1
  166. package/dist/lifecycle.d.ts +2 -1
  167. package/dist/lifecycle.d.ts.map +1 -1
  168. package/dist/material-row.d.ts +5 -0
  169. package/dist/material-row.d.ts.map +1 -0
  170. package/dist/materials.d.ts +15 -0
  171. package/dist/materials.d.ts.map +1 -1
  172. package/dist/pbr-pipeline.d.ts +21 -5
  173. package/dist/pbr-pipeline.d.ts.map +1 -1
  174. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  175. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  176. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  177. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  178. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  179. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  180. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  181. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  182. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  183. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  184. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  185. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  186. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  187. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  188. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  189. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  190. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  191. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  192. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  193. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  194. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  195. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  196. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  197. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  198. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  199. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  200. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  201. package/dist/pipeline/standard-output/types.d.ts +39 -0
  202. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  203. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/standard-post.d.ts +2 -2
  205. package/dist/pipeline/standard-post.d.ts.map +1 -1
  206. package/dist/pipeline-builder.d.ts +2 -1
  207. package/dist/pipeline-builder.d.ts.map +1 -1
  208. package/dist/pipeline-spec-types.d.ts +4 -0
  209. package/dist/pipeline-spec-types.d.ts.map +1 -1
  210. package/dist/pipeline-spec.d.ts +1 -9
  211. package/dist/pipeline-spec.d.ts.map +1 -1
  212. package/dist/points-lines/standard-owner.d.ts +1 -1
  213. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  214. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  215. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  216. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  217. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  218. package/dist/record/frame-lighting.d.ts +3 -3
  219. package/dist/record/frame-lighting.d.ts.map +1 -1
  220. package/dist/record/frame-snapshot.d.ts +106 -5
  221. package/dist/record/frame-snapshot.d.ts.map +1 -1
  222. package/dist/record/frame-targets.d.ts.map +1 -1
  223. package/dist/record/frame.d.ts +39 -4
  224. package/dist/record/frame.d.ts.map +1 -1
  225. package/dist/record/main-pass-geometry.d.ts +7 -8
  226. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  227. package/dist/record/main-pass-material.d.ts +38 -1
  228. package/dist/record/main-pass-material.d.ts.map +1 -1
  229. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  230. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  231. package/dist/record/main-pass.d.ts +12 -2
  232. package/dist/record/main-pass.d.ts.map +1 -1
  233. package/dist/record/mesh-ssbo.d.ts +15 -6
  234. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  235. package/dist/record/prepared-material-bindings.d.ts +19 -0
  236. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  237. package/dist/record/recovery-pipeline.d.ts +2 -9
  238. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  239. package/dist/record/render-context.d.ts +76 -26
  240. package/dist/record/render-context.d.ts.map +1 -1
  241. package/dist/record/shadow-pass.d.ts +62 -7
  242. package/dist/record/shadow-pass.d.ts.map +1 -1
  243. package/dist/record/skybox-post-pass.d.ts +1 -1
  244. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  245. package/dist/record/typed-frame-graph.d.ts +35 -7
  246. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  247. package/dist/record/view-ubo.d.ts +1 -0
  248. package/dist/record/view-ubo.d.ts.map +1 -1
  249. package/dist/recovery/render-system-candidate.d.ts +10 -2
  250. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  251. package/dist/recovery/render-system-roots.d.ts +11 -0
  252. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  253. package/dist/recovery/types.d.ts +76 -0
  254. package/dist/recovery/types.d.ts.map +1 -0
  255. package/dist/reflection/record-owner.d.ts +0 -2
  256. package/dist/reflection/record-owner.d.ts.map +1 -1
  257. package/dist/render-contract.d.ts +185 -30
  258. package/dist/render-contract.d.ts.map +1 -1
  259. package/dist/render-graph-primitives.d.ts +1 -0
  260. package/dist/render-graph-primitives.d.ts.map +1 -1
  261. package/dist/render-pipeline.d.ts +64 -5
  262. package/dist/render-pipeline.d.ts.map +1 -1
  263. package/dist/render-system-extract-tail.d.ts +7 -5
  264. package/dist/render-system-extract-tail.d.ts.map +1 -1
  265. package/dist/render-system-extract.d.ts +101 -41
  266. package/dist/render-system-extract.d.ts.map +1 -1
  267. package/dist/render-system-projections.d.ts +22 -0
  268. package/dist/render-system-projections.d.ts.map +1 -0
  269. package/dist/render-system.d.ts +34 -77
  270. package/dist/render-system.d.ts.map +1 -1
  271. package/dist/scene/render-scene-types.d.ts +14 -7
  272. package/dist/scene/render-scene-types.d.ts.map +1 -1
  273. package/dist/scene/render-scene.d.ts +29 -11
  274. package/dist/scene/render-scene.d.ts.map +1 -1
  275. package/dist/scene/shadow-visibility.d.ts +5 -0
  276. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  277. package/dist/ssr/admission.d.ts +70 -1
  278. package/dist/ssr/admission.d.ts.map +1 -1
  279. package/dist/ssr/compose.d.ts +13 -0
  280. package/dist/ssr/compose.d.ts.map +1 -0
  281. package/dist/ssr/errors.d.ts +35 -0
  282. package/dist/ssr/errors.d.ts.map +1 -1
  283. package/dist/ssr/graph.d.ts +60 -0
  284. package/dist/ssr/graph.d.ts.map +1 -0
  285. package/dist/ssr/history.d.ts +97 -0
  286. package/dist/ssr/history.d.ts.map +1 -0
  287. package/dist/ssr/hiz.d.ts +37 -0
  288. package/dist/ssr/hiz.d.ts.map +1 -0
  289. package/dist/ssr/inspection.d.ts +42 -0
  290. package/dist/ssr/inspection.d.ts.map +1 -0
  291. package/dist/ssr/resources.d.ts +58 -0
  292. package/dist/ssr/resources.d.ts.map +1 -0
  293. package/dist/ssr/temporal.d.ts +38 -0
  294. package/dist/ssr/temporal.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  296. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  297. package/dist/systems/skin-palette-types.d.ts +15 -0
  298. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  299. package/dist/systems/transparent-dispatch.d.ts +9 -0
  300. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  301. package/dist/targets/material-source.d.ts +7 -0
  302. package/dist/targets/material-source.d.ts.map +1 -1
  303. package/dist/temporal/frame-coordinator.d.ts +7 -0
  304. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  305. package/dist/temporal/gpu.d.ts +8 -0
  306. package/dist/temporal/gpu.d.ts.map +1 -1
  307. package/dist/temporal/history.d.ts.map +1 -1
  308. package/dist/temporal/index.mjs +6 -6
  309. package/dist/temporal/inspection.d.ts.map +1 -1
  310. package/dist/temporal/standard-scene-data.d.ts +2 -1
  311. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  312. package/dist/temporal/temporal-view.d.ts +2 -0
  313. package/dist/temporal/temporal-view.d.ts.map +1 -1
  314. package/dist/typed-render-graph-primitives.d.ts +35 -1
  315. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  316. package/dist/typed-shadow-passes.d.ts +3 -1
  317. package/dist/typed-shadow-passes.d.ts.map +1 -1
  318. package/dist/volume/temporal.d.ts +6 -0
  319. package/dist/volume/temporal.d.ts.map +1 -1
  320. package/package.json +21 -20
  321. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  322. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  323. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  324. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  325. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  326. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  327. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  328. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  329. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  330. package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
  331. package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
  332. package/src/__tests__/factory-contract.integration.test.ts +73 -22
  333. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  334. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  335. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  336. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  337. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  338. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  339. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  340. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  341. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  342. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +287 -6
  343. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  344. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  345. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +264 -0
  346. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +349 -0
  347. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1417 -0
  348. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  349. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  350. package/src/__tests__/gpu-driven-production.integration.test.ts +1075 -93
  351. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  352. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  353. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  354. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  355. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  356. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  357. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  358. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  359. package/src/__tests__/gpu-driven-view.unit.test.ts +159 -52
  360. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -1
  361. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  362. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  363. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  364. package/src/__tests__/gpu-scene.unit.test.ts +559 -33
  365. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  366. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  367. package/src/__tests__/instances-store.unit.test.ts +242 -39
  368. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  369. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  370. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  371. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  372. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  373. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  374. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  375. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  376. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  377. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  378. package/src/__tests__/materials-standard-contract.unit.test.ts +52 -2
  379. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  380. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
  381. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  382. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  383. package/src/__tests__/physical-clearcoat.integration.test.ts +37 -3
  384. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  385. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  386. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  387. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  388. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +35 -4
  389. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  390. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  391. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  392. package/src/__tests__/public-surface.test-d.ts +3 -0
  393. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  394. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +104 -0
  395. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +2 -1
  396. package/src/__tests__/render-error-code-owner.test-d.ts +4 -0
  397. package/src/__tests__/render-error-detail-ssot.test-d.ts +22 -0
  398. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  399. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  400. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  401. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  402. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  403. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  404. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  405. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  406. package/src/__tests__/render-scene-projection.unit.test.ts +914 -23
  407. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  408. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  409. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  410. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  411. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +61 -1
  412. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  413. package/src/__tests__/shader-manifest-fixture.ts +39 -0
  414. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  415. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  416. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  417. package/src/__tests__/skinned-shadow-caster.test.ts +118 -14
  418. package/src/__tests__/specular-environment-scale.dawn.test.ts +156 -0
  419. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  420. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  421. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  422. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  423. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +91 -0
  424. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +112 -0
  425. package/src/__tests__/ssr-gpu-dispatch.ts +946 -0
  426. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  427. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  428. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  429. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  430. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  431. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  432. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  433. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  434. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  435. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  436. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  437. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  438. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  439. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  440. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  441. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  442. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  443. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  444. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  445. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  446. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  447. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  448. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +44 -12
  449. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  450. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  451. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  452. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  453. package/src/__tests__/standard-output.browser.test.ts +15 -0
  454. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  455. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +38 -0
  456. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  457. package/src/__tests__/standard-profile-oracle.unit.test.ts +22 -0
  458. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  459. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  460. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  461. package/src/__tests__/taa-coverage-edge.dawn.test.ts +193 -0
  462. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  463. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +778 -0
  464. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  465. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  466. package/src/__tests__/taa-stability-feedback.ts +341 -0
  467. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  468. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  469. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  470. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  471. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  472. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  473. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  474. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  475. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  476. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  477. package/src/assembly/atmosphere-shader-prewarm.ts +38 -0
  478. package/src/assembly/dynamic-geometry-host.ts +887 -0
  479. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  480. package/src/assembly/factory.ts +4 -0
  481. package/src/assembly/gpu-driven-owner.ts +29 -0
  482. package/src/assembly/host-contract.ts +36 -0
  483. package/src/assembly/material/assembly.ts +38 -0
  484. package/src/assembly/material-shader-policy.ts +71 -28
  485. package/src/assembly/recovery/failure-location.ts +62 -0
  486. package/src/assembly/recovery/renderer-recover.ts +19 -17
  487. package/src/assembly/renderer-facade.ts +29 -0
  488. package/src/assembly/renderer-feature-inspection.ts +13 -0
  489. package/src/assembly/renderer-frame-transaction.ts +63 -0
  490. package/src/assembly/renderer-helpers.ts +26 -0
  491. package/src/assembly/renderer-inspection.ts +6 -0
  492. package/src/assembly/shader-prewarm-policy.ts +32 -0
  493. package/src/assembly/skin-palette-owner.ts +21 -0
  494. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  495. package/src/assembly/webgpu-device-loss.ts +75 -0
  496. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  497. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  498. package/src/assembly/webgpu-ready.ts +142 -121
  499. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  500. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  501. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  502. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  503. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  504. package/src/assembly/webgpu-renderer.ts +675 -614
  505. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  506. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  507. package/src/components/camera.ts +287 -7
  508. package/src/components/index.ts +1 -0
  509. package/src/components/instances.ts +45 -18
  510. package/src/components/scene-instance.ts +2 -1
  511. package/src/components/screen-space-reflection.ts +21 -0
  512. package/src/components/sprite-animation.ts +3 -3
  513. package/src/components/sprite-instances.ts +1 -1
  514. package/src/device/gpu-residency.ts +96 -93
  515. package/src/device/mesh-residency-lifetime.ts +73 -0
  516. package/src/dynamic-geometry.ts +736 -0
  517. package/src/environment/background.ts +263 -0
  518. package/src/errors/gpu-driven.ts +39 -5
  519. package/src/errors/render.ts +27 -3
  520. package/src/extract/camera.ts +26 -1
  521. package/src/extract/gpu-driven.ts +185 -10
  522. package/src/features/host.ts +237 -19
  523. package/src/features/noise-texture.ts +91 -0
  524. package/src/features/plan.ts +553 -24
  525. package/src/features/prepared-gpu-work.ts +631 -49
  526. package/src/features/prepared-graphics-store.ts +31 -0
  527. package/src/features/prepared-graphics.ts +5 -0
  528. package/src/features/render-graph-compute.ts +41 -8
  529. package/src/features/render-graph-contribution.ts +141 -3
  530. package/src/features/render-graph-raster.ts +143 -30
  531. package/src/features/types.ts +11 -0
  532. package/src/fullscreen-post-process-pass.ts +3 -0
  533. package/src/gpu-driven/batch-topology.ts +424 -102
  534. package/src/gpu-driven/pbr-program.ts +31 -0
  535. package/src/gpu-driven/prepared-draw.ts +29 -4
  536. package/src/gpu-driven/production-raster.ts +2267 -694
  537. package/src/gpu-driven/shadow-views.ts +539 -0
  538. package/src/gpu-driven/view-gpu.ts +188 -41
  539. package/src/gpu-scene-schema.ts +52 -11
  540. package/src/gpu-scene.ts +186 -99
  541. package/src/gpu-texture-usage.ts +1 -0
  542. package/src/hdrp-buffers.ts +72 -36
  543. package/src/ibl/frame-resources.ts +38 -0
  544. package/src/ibl/skylight-bind-group.ts +5 -4
  545. package/src/index.ts +125 -1
  546. package/src/inspection-types.ts +191 -0
  547. package/src/instances-derived-bounds.ts +258 -34
  548. package/src/instances.ts +459 -150
  549. package/src/internal.ts +22 -0
  550. package/src/lifecycle.ts +2 -0
  551. package/src/material-row.ts +145 -0
  552. package/src/materials.ts +44 -8
  553. package/src/pbr-pipeline.ts +159 -17
  554. package/src/pipeline/standard-forward-lane.ts +52 -24
  555. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  556. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  557. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  558. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  559. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  560. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  561. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  562. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  563. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  564. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  565. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  566. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  567. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  568. package/src/pipeline/standard-output/color-transform.ts +124 -0
  569. package/src/pipeline/standard-output/graph.ts +139 -0
  570. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  571. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  572. package/src/pipeline/standard-output/lut-state.ts +176 -0
  573. package/src/pipeline/standard-output/resources.ts +121 -0
  574. package/src/pipeline/standard-output/types.ts +58 -0
  575. package/src/pipeline/standard-pipeline.ts +192 -59
  576. package/src/pipeline/standard-post.ts +186 -27
  577. package/src/pipeline-builder.ts +16 -6
  578. package/src/pipeline-spec-types.ts +4 -0
  579. package/src/pipeline-spec.ts +37 -29
  580. package/src/points-lines/standard-owner.ts +6 -14
  581. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  582. package/src/record/__tests__/material-slot-plan.unit.test.ts +48 -0
  583. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  584. package/src/record/__tests__/recovery-pipeline.unit.test.ts +2 -29
  585. package/src/record/__tests__/sprite-material-abi.unit.test.ts +36 -5
  586. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  587. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  588. package/src/record/dynamic-geometry-consumption.ts +59 -0
  589. package/src/record/frame-lighting.ts +12 -11
  590. package/src/record/frame-snapshot.ts +133 -23
  591. package/src/record/frame-targets.ts +9 -0
  592. package/src/record/frame.ts +727 -133
  593. package/src/record/main-pass-geometry.ts +162 -98
  594. package/src/record/main-pass-material.ts +115 -26
  595. package/src/record/main-pass-sprite-draws.ts +18 -107
  596. package/src/record/main-pass.ts +78 -8
  597. package/src/record/material-uniforms.ts +1 -1
  598. package/src/record/mesh-ssbo.ts +59 -15
  599. package/src/record/prepared-material-bindings.ts +234 -0
  600. package/src/record/recovery-pipeline.ts +59 -136
  601. package/src/record/render-context.ts +92 -22
  602. package/src/record/shadow-pass.ts +1231 -209
  603. package/src/record/skybox-post-pass.ts +14 -3
  604. package/src/record/typed-frame-graph.ts +1006 -53
  605. package/src/record/view-ubo.ts +11 -0
  606. package/src/recovery/render-system-candidate.ts +90 -66
  607. package/src/recovery/render-system-roots.ts +113 -0
  608. package/src/recovery/types.ts +77 -0
  609. package/src/reflection/record-owner.ts +26 -54
  610. package/src/render-contract.ts +219 -25
  611. package/src/render-graph-primitives.ts +6 -2
  612. package/src/render-pipeline.ts +70 -1
  613. package/src/render-system-extract-tail.ts +409 -160
  614. package/src/render-system-extract.ts +376 -102
  615. package/src/render-system-projections.ts +241 -0
  616. package/src/render-system.ts +692 -791
  617. package/src/scene/render-scene-types.ts +13 -4
  618. package/src/scene/render-scene.ts +569 -355
  619. package/src/scene/shadow-visibility.ts +21 -0
  620. package/src/ssr/admission.ts +380 -14
  621. package/src/ssr/compose.ts +144 -0
  622. package/src/ssr/errors.ts +48 -0
  623. package/src/ssr/graph.ts +777 -0
  624. package/src/ssr/history.ts +436 -0
  625. package/src/ssr/hiz.ts +124 -0
  626. package/src/ssr/inspection.ts +124 -0
  627. package/src/ssr/resources.ts +202 -0
  628. package/src/ssr/temporal.ts +164 -0
  629. package/src/systems/skin-palette-allocator.ts +495 -148
  630. package/src/systems/skin-palette-types.ts +17 -0
  631. package/src/systems/transparent-dispatch.ts +90 -0
  632. package/src/targets/material-source.ts +34 -0
  633. package/src/temporal/coverage.ts +1 -1
  634. package/src/temporal/frame-coordinator.ts +23 -2
  635. package/src/temporal/gpu.ts +74 -12
  636. package/src/temporal/history.ts +3 -1
  637. package/src/temporal/inspection.ts +2 -1
  638. package/src/temporal/standard-scene-data.ts +3 -1
  639. package/src/temporal/temporal-view.ts +3 -0
  640. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +204 -139
  641. package/src/typed-render-graph-primitives.ts +266 -74
  642. package/src/typed-shadow-passes.ts +122 -12
  643. package/src/volume/temporal.ts +10 -0
  644. package/dist/chunk-ADHHVYLW.mjs.map +0 -1
  645. package/dist/chunk-FJ6P52EE.mjs.map +0 -1
  646. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  647. package/dist/chunk-GF523LHF.mjs.map +0 -1
  648. package/dist/chunk-HKXTW355.mjs.map +0 -1
  649. package/dist/chunk-JDWARUOI.mjs.map +0 -1
  650. package/dist/chunk-KM2NOX2I.mjs.map +0 -1
  651. package/dist/chunk-TMIASV2N.mjs.map +0 -1
  652. package/dist/chunk-XDP6XE5V.mjs.map +0 -1
  653. package/dist/chunk-ZZ4YQ474.mjs.map +0 -1
  654. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  655. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
@@ -10,7 +10,9 @@ import {
10
10
  RhiError,
11
11
  type RhiRenderPassEncoder,
12
12
  } from '@forgeax/engine-rhi';
13
+ import { STANDARD_TEXTURE_MASK_OVERRIDE } from '@forgeax/engine-shader';
13
14
  import type { ParamSchemaEntry, PassKind, PrimitiveTopology } from '@forgeax/engine-types';
15
+ import { gpuDrivenDrawKey, gpuDrivenSourceDrawItemIndex } from '../extract/gpu-driven';
14
16
  import { GpuBuffer } from '../gpu-resource';
15
17
  import {
16
18
  GPU_BUFFER_USAGE_COPY_DST,
@@ -19,11 +21,7 @@ import {
19
21
  } from '../gpu-usage';
20
22
  import { createHdrpSkinUnifiedBindGroup, getOrCreateHdrpBuffers } from '../hdrp-buffers';
21
23
  import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
22
- import {
23
- type InstanceCollectionFailureCode,
24
- recordInstanceFailure,
25
- recordInstanceResidency,
26
- } from '../instances';
24
+ import { type InstanceCollectionFailureCode, instanceUploadRangesForResident } from '../instances';
27
25
  import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
28
26
  import {
29
27
  createPbrSkinMeshBindGroupEntries,
@@ -127,6 +125,7 @@ type MaterialPipelineLookup = {
127
125
  readonly sampleCount: number;
128
126
  readonly colorFormatOverride: GPUTextureFormat | undefined;
129
127
  readonly additionalColorFormats: readonly GPUTextureFormat[] | undefined;
128
+ readonly textureMask: number | undefined;
130
129
  readonly handle: MaterialShaderPipelineEntry | null;
131
130
  };
132
131
 
@@ -134,6 +133,67 @@ type GeometryRecordProfileSegment = 'material-bind-groups' | 'pipeline-selection
134
133
 
135
134
  type GeometryRenderState = ReturnType<typeof geometryRenderStateForTopology>;
136
135
 
136
+ function gpuDrivenDrawIndicesBySubmesh(
137
+ source: RenderableSnapshot,
138
+ mesh: _InternalRenderPipelineContext['validatedOrdered'][number]['mesh'],
139
+ ): ReadonlyMap<number, number> {
140
+ const draws = source.gpuDrivenDraws;
141
+ if (draws === undefined || draws.length === 0) return new Map();
142
+ const indices = new Map<number, number>();
143
+ let hasStableSourceIdentity = false;
144
+ for (const [compactIndex, draw] of draws.entries()) {
145
+ const drawItemIndex = draw.drawItemIndex;
146
+ if (drawItemIndex === undefined) continue;
147
+ hasStableSourceIdentity = true;
148
+ if (mesh.submeshes[drawItemIndex] !== undefined) indices.set(drawItemIndex, compactIndex);
149
+ }
150
+ if (hasStableSourceIdentity) return indices;
151
+
152
+ // Legacy snapshots predating drawItemIndex are matched by their compact
153
+ // geometry facts. New extracted snapshots never take this path.
154
+ let nonIndexedFirst = 0;
155
+ let drawCursor = 0;
156
+ for (const [submeshIndex, submesh] of mesh.submeshes.entries()) {
157
+ const first = mesh.indexed ? submesh.indexOffset : nonIndexedFirst;
158
+ const count = mesh.indexed ? submesh.indexCount : submesh.vertexCount;
159
+ if (!mesh.indexed) nonIndexedFirst += submesh.vertexCount;
160
+ const draw = draws[drawCursor];
161
+ if (
162
+ draw !== undefined &&
163
+ draw.first === first &&
164
+ draw.count === count &&
165
+ draw.materialSlot === submesh.materialSlot &&
166
+ draw.topology === submesh.topology
167
+ ) {
168
+ indices.set(submeshIndex, drawCursor);
169
+ drawCursor += 1;
170
+ }
171
+ }
172
+ return indices;
173
+ }
174
+
175
+ function isGpuDrivenMainClaimedSubmesh(
176
+ c: _InternalRenderPipelineContext,
177
+ source: RenderableSnapshot,
178
+ submeshIndex: number,
179
+ drawIndices: ReadonlyMap<number, number>,
180
+ ): boolean {
181
+ const drawItemIndex = drawIndices.get(submeshIndex);
182
+ const draw = drawItemIndex === undefined ? undefined : source.gpuDrivenDraws?.[drawItemIndex];
183
+ if (drawItemIndex === undefined || draw === undefined) return false;
184
+ const material = source.materials[draw.materialSlot] ?? source.material;
185
+ const sourceDrawItemIndex = gpuDrivenSourceDrawItemIndex(draw, drawItemIndex);
186
+ return (
187
+ c.gpuDrivenDrawKeys?.has(
188
+ gpuDrivenDrawKey(
189
+ worldEntityKey(source.worldId, source.entityKey),
190
+ material.materialHandle ?? -1,
191
+ sourceDrawItemIndex,
192
+ ),
193
+ ) === true
194
+ );
195
+ }
196
+
137
197
  /**
138
198
  * Select the transmission shader axis from authored material data, not the
139
199
  * canonical boot schema. The latter reserves transmission fields for the
@@ -252,8 +312,8 @@ export function effectiveMaterialLayoutIdentity(
252
312
  /**
253
313
  * Resolve the depth contract for a geometry pass without changing the base
254
314
  * material state. Temporal scene-data shares the main pass depth attachment:
255
- * it is read-only and accepts the equal depth produced by the unjittered
256
- * temporal projection, while still rejecting fragments behind the visible
315
+ * it is read-only and accepts the equal depth produced by the shared raster
316
+ * projection, while motion varyings remain unjittered. It rejects fragments behind the visible
257
317
  * surface.
258
318
  */
259
319
  export function geometryRenderStateForPass(
@@ -297,6 +357,7 @@ function submitSubmeshDraws(
297
357
  indexCount: number,
298
358
  vertexCount: number,
299
359
  indexOffset: number,
360
+ onDraw?: () => void,
300
361
  ): void {
301
362
  if (state.pipeline !== pipeline) {
302
363
  pass.setPipeline(pipeline);
@@ -320,6 +381,7 @@ function submitSubmeshDraws(
320
381
  } else {
321
382
  pass.draw(vertexCount, instanceDraw.instanceCount, 0, 0);
322
383
  }
384
+ onDraw?.();
323
385
  }
324
386
  }
325
387
 
@@ -371,6 +433,7 @@ export function recordGeometryDraws(
371
433
  ) => BindGroup,
372
434
  passKind: PassKind = 'forward',
373
435
  selectedDispatch?: readonly DispatchEntry[],
436
+ colorFormats: readonly GPUTextureFormat[] = [],
374
437
  ): void {
375
438
  const {
376
439
  runtime,
@@ -455,6 +518,7 @@ export function recordGeometryDraws(
455
518
  layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection,
456
519
  vertexEntry?: string,
457
520
  fragmentEntry?: string,
521
+ textureMask?: number,
458
522
  ): MaterialShaderPipelineEntry | null => {
459
523
  // The fallback MRT is an extension of the built-in Standard PBR output
460
524
  // contract only. The render pass may carry a second attachment whenever
@@ -467,7 +531,9 @@ export function recordGeometryDraws(
467
531
  const reflectionFallbackFormats =
468
532
  materialShaderId === 'forgeax::default-standard-pbr' &&
469
533
  c.reflectionFallbackColorFormat !== undefined
470
- ? [c.reflectionFallbackColorFormat]
534
+ ? passKind === 'deferred'
535
+ ? colorFormats.slice(1)
536
+ : [c.reflectionFallbackColorFormat]
471
537
  : undefined;
472
538
  const renderStateKey = renderStateHash(renderState);
473
539
  const shaderLookupCache = materialPipelineLookupCache.get(materialShaderId);
@@ -482,6 +548,7 @@ export function recordGeometryDraws(
482
548
  cached.variantSet === variantSet &&
483
549
  cached.vertexEntry === vertexEntry &&
484
550
  cached.fragmentEntry === fragmentEntry &&
551
+ cached.textureMask === textureMask &&
485
552
  cached.passKind === passKind &&
486
553
  cached.layoutProjection.digest === layoutProjection.digest &&
487
554
  cached.sampleCount === sampleCount &&
@@ -528,9 +595,12 @@ export function recordGeometryDraws(
528
595
  layoutProjection,
529
596
  undefined,
530
597
  undefined,
598
+ undefined,
531
599
  reflectionFallbackFormats,
532
600
  vertexEntry,
533
601
  fragmentEntry,
602
+ undefined,
603
+ textureMask === undefined ? undefined : { [STANDARD_TEXTURE_MASK_OVERRIDE]: textureMask },
534
604
  ) ?? null;
535
605
  const handle =
536
606
  profilePhase === undefined
@@ -558,6 +628,7 @@ export function recordGeometryDraws(
558
628
  sampleCount,
559
629
  colorFormatOverride: colorFormat,
560
630
  additionalColorFormats: reflectionFallbackFormats,
631
+ textureMask,
561
632
  handle,
562
633
  };
563
634
  if (shaderLookupCache === undefined) {
@@ -577,7 +648,6 @@ export function recordGeometryDraws(
577
648
  for (let i = 0; i < validatedOrdered.length; i++) {
578
649
  const entry = validatedOrdered[i];
579
650
  if (entry === undefined) continue;
580
-
581
651
  // Points/Lines share the Standard geometry pass. Their retained source
582
652
  // is prepared once by the renderer owner, while this loop remains the
583
653
  // sole pass/draw submission owner and preserves the authored topology.
@@ -585,18 +655,6 @@ export function recordGeometryDraws(
585
655
  if (entry.source.pointsLines !== undefined && pointsLinesSubmission?.plan.drawCount !== 1)
586
656
  continue;
587
657
 
588
- if (
589
- passKind === 'forward' &&
590
- c.gpuDrivenEntityKeys.has(
591
- worldEntityKey(
592
- c.gpuDrivenWorldKeys?.[entry.source.worldId] ?? entry.source.worldId,
593
- entry.source.entityKey,
594
- ),
595
- )
596
- ) {
597
- continue;
598
- }
599
-
600
658
  // feat-20260609 M2: skip entities that don't match the pass selector.
601
659
  if (matchedMaterials !== null && !matchedMaterials.has(entry.renderableIndex)) continue;
602
660
 
@@ -691,6 +749,7 @@ export function recordGeometryDraws(
691
749
  resolveGeometryInstancesBindGroup(c, identityInstanceBuffer, undefined);
692
750
  pass.setBindGroup(3, pointsLinesInstancesBg);
693
751
  recordOcclusionCandidate(() => recordPointsLinesDraw(pass, pointsLinesSubmission.plan));
752
+ c.onRenderableDraw?.(entry);
694
753
  pass.setBindGroup(0, viewBindGroup as BindGroup, [viewBindGroupDynamicOffset, 0]);
695
754
  continue;
696
755
  }
@@ -984,6 +1043,7 @@ export function recordGeometryDraws(
984
1043
  // — the same placeholders the unlit path already used. The generic
985
1044
  // branch below builds the per-submesh BG.
986
1045
  let perSubmeshBg: BindGroup | null = null;
1046
+ const gpuDrivenDrawIndices = gpuDrivenDrawIndicesBySubmesh(entry.source, entry.mesh);
987
1047
  // feat-20260608 M4 / w16: per-submesh pipeline selection + draw loop.
988
1048
  // Each submesh carries its own topology, so pipeline selection is per-submesh.
989
1049
  // Vertex/index buffers and bind groups are set once (shared across all submeshes).
@@ -1001,12 +1061,22 @@ export function recordGeometryDraws(
1001
1061
  const materialHandle = submeshMaterial.materialHandle ?? 0;
1002
1062
  if (materialHandles === undefined || !materialHandles.has(materialHandle)) continue;
1003
1063
  }
1064
+ if (
1065
+ passKind === 'forward' &&
1066
+ isGpuDrivenMainClaimedSubmesh(c, entry.source, smIdx, gpuDrivenDrawIndices)
1067
+ ) {
1068
+ continue;
1069
+ }
1004
1070
  const draws: readonly (DispatchEntry | undefined)[] =
1005
1071
  selectedDispatch === undefined
1006
1072
  ? [undefined]
1007
1073
  : (materialPasses.get(entry.renderableIndex)?.get(submeshMaterial.materialHandle ?? 0) ??
1008
1074
  []);
1009
1075
  for (const selectedPass of draws) {
1076
+ // Temporal projects the selected material's alpha/motion contract,
1077
+ // not its authored Forward entry points or color outputs.
1078
+ const vertexEntry = passKind === 'temporal' ? undefined : selectedPass?.vertexEntry;
1079
+ const fragmentEntry = passKind === 'temporal' ? undefined : selectedPass?.fragmentEntry;
1010
1080
  const selectedShaderId =
1011
1081
  selectedPass === undefined
1012
1082
  ? submeshMaterial.materialShaderId
@@ -1154,8 +1224,9 @@ export function recordGeometryDraws(
1154
1224
  unlitVariantSet,
1155
1225
  colorFormatOverride,
1156
1226
  entry.mesh.layoutProjection,
1157
- selectedPass?.vertexEntry,
1158
- selectedPass?.fragmentEntry,
1227
+ vertexEntry,
1228
+ fragmentEntry,
1229
+ submeshMaterial.standardTextureMask,
1159
1230
  );
1160
1231
  materialPipelineEntry = unlitRsp;
1161
1232
  smPipelineHandle =
@@ -1195,7 +1266,7 @@ export function recordGeometryDraws(
1195
1266
  const transmissionAvailable = requestsStandardTransmissionVariant(submeshMaterial);
1196
1267
  const materialCapabilityVariantSet =
1197
1268
  transmissionAvailable && !capabilityVariantSet.includes('TRANSMISSION_AVAILABLE=')
1198
- ? `${capabilityVariantSet === '' ? '' : `${capabilityVariantSet}+`}TRANSMISSION_AVAILABLE=true`
1269
+ ? `${capabilityVariantSet}+TRANSMISSION_AVAILABLE=true`
1199
1270
  : capabilityVariantSet;
1200
1271
  // Sprite's base request must retain the boot-selected artifact. Only
1201
1272
  // SpriteInstances uses the explicit empty key for the
@@ -1208,9 +1279,7 @@ export function recordGeometryDraws(
1208
1279
  : undefined
1209
1280
  : entry.variantSet === undefined
1210
1281
  ? materialCapabilityVariantSet
1211
- : capabilityVariantSet === ''
1212
- ? entry.variantSet
1213
- : `${capabilityVariantSet}+${entry.variantSet}`;
1282
+ : `${materialCapabilityVariantSet}+${entry.variantSet}`;
1214
1283
  const cachedPipeline = resolveMaterialPipeline(
1215
1284
  smMaterialShaderId,
1216
1285
  pipelineRenderState,
@@ -1219,8 +1288,9 @@ export function recordGeometryDraws(
1219
1288
  variantSet,
1220
1289
  colorFormatOverride,
1221
1290
  entry.mesh.layoutProjection,
1222
- selectedPass?.vertexEntry,
1223
- selectedPass?.fragmentEntry,
1291
+ vertexEntry,
1292
+ fragmentEntry,
1293
+ submeshMaterial.standardTextureMask,
1224
1294
  );
1225
1295
  // feat-20260615-pipeline-spec-ssot M6-T1: cache miss resolves to
1226
1296
  // null uniformly across URP / HDRP / skin shaders. Charter P3
@@ -1320,6 +1390,7 @@ export function recordGeometryDraws(
1320
1390
  sm.indexCount,
1321
1391
  sm.vertexCount,
1322
1392
  sm.indexOffset,
1393
+ () => c.onRenderableDraw?.(entry),
1323
1394
  ),
1324
1395
  );
1325
1396
  } else {
@@ -1334,6 +1405,7 @@ export function recordGeometryDraws(
1334
1405
  sm.indexCount,
1335
1406
  sm.vertexCount,
1336
1407
  sm.indexOffset,
1408
+ () => c.onRenderableDraw?.(entry),
1337
1409
  ),
1338
1410
  ),
1339
1411
  );
@@ -1352,10 +1424,7 @@ export function recordGeometryDraws(
1352
1424
  * @internal
1353
1425
  */
1354
1426
  function uploadInstanceRanges(
1355
- c: Pick<
1356
- _InternalRenderPipelineContext,
1357
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1358
- >,
1427
+ c: _InternalRenderPipelineContext,
1359
1428
  inst: NonNullable<RenderableSnapshot['instances']>,
1360
1429
  buffer: Buffer,
1361
1430
  ranges: readonly { readonly start: number; readonly end: number }[],
@@ -1387,10 +1456,7 @@ function uploadInstanceRanges(
1387
1456
  }
1388
1457
 
1389
1458
  export function reportInstanceResidency(
1390
- c: Pick<
1391
- _InternalRenderPipelineContext,
1392
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1393
- >,
1459
+ c: _InternalRenderPipelineContext,
1394
1460
  inst: NonNullable<RenderableSnapshot['instances']>,
1395
1461
  input: {
1396
1462
  readonly lane: 'direct-storage' | 'chunked-storage' | 'direct-uniform' | 'chunked-uniform';
@@ -1400,8 +1466,8 @@ export function reportInstanceResidency(
1400
1466
  readonly uploadedBytes: number;
1401
1467
  },
1402
1468
  ): void {
1403
- if (inst.collectionId === undefined || c.frameState.instanceResidency === undefined) return;
1404
- recordInstanceResidency(c.frameState.instanceResidency, {
1469
+ if (inst.collectionId === undefined) return;
1470
+ c.frameState.instanceCollections?._reportResidency({
1405
1471
  collectionId: inst.collectionId,
1406
1472
  frameNumber: c.frameState.frameNumber,
1407
1473
  residentGeneration: c.runtime.deviceScope.generation,
@@ -1415,10 +1481,7 @@ export function reportInstanceResidency(
1415
1481
  }
1416
1482
 
1417
1483
  function reportInstanceFailure(
1418
- c: Pick<
1419
- _InternalRenderPipelineContext,
1420
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1421
- >,
1484
+ c: _InternalRenderPipelineContext,
1422
1485
  inst: NonNullable<RenderableSnapshot['instances']>,
1423
1486
  error: {
1424
1487
  readonly code: InstanceCollectionFailureCode;
@@ -1428,8 +1491,8 @@ function reportInstanceFailure(
1428
1491
  requestedBytes: number,
1429
1492
  supportedBytes: number | undefined,
1430
1493
  ): void {
1431
- if (inst.collectionId === undefined || c.frameState.instanceResidency === undefined) return;
1432
- recordInstanceFailure(c.frameState.instanceResidency, {
1494
+ if (inst.collectionId === undefined) return;
1495
+ c.frameState.instanceCollections?._reportFailure({
1433
1496
  collectionId: inst.collectionId,
1434
1497
  code: error.code,
1435
1498
  expected: error.expected,
@@ -1445,13 +1508,7 @@ function reportInstanceFailure(
1445
1508
  });
1446
1509
  }
1447
1510
 
1448
- function clearInstanceChunksForOwner(
1449
- c: Pick<
1450
- _InternalRenderPipelineContext,
1451
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1452
- >,
1453
- ownerKey: number,
1454
- ): void {
1511
+ function clearInstanceChunksForOwner(c: _InternalRenderPipelineContext, ownerKey: number): void {
1455
1512
  const chunks = c.frameState.instanceBufferChunks;
1456
1513
  if (chunks === undefined) return;
1457
1514
  const prefix = `${ownerKey}:`;
@@ -1466,10 +1523,7 @@ function clearInstanceChunksForOwner(
1466
1523
  }
1467
1524
 
1468
1525
  export function resolveStorageInstanceChunks(
1469
- c: Pick<
1470
- _InternalRenderPipelineContext,
1471
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1472
- >,
1526
+ c: _InternalRenderPipelineContext,
1473
1527
  entry: _InternalRenderPipelineContext['validatedOrdered'][number],
1474
1528
  inst: NonNullable<RenderableSnapshot['instances']>,
1475
1529
  cap: number,
@@ -1507,6 +1561,7 @@ export function resolveStorageInstanceChunks(
1507
1561
  const draws: GeometryInstanceDraw[] = [];
1508
1562
  const uploadedRanges: { start: number; end: number }[] = [];
1509
1563
  let uploadedBytes = 0;
1564
+ const dirtyRanges = inst.dirtyRanges ?? [{ start: 0, end: inst.instanceCount } as const];
1510
1565
  for (let start = 0; start < inst.instanceCount; start += chunkCapacity) {
1511
1566
  const end = Math.min(inst.instanceCount, start + chunkCapacity);
1512
1567
  const count = end - start;
@@ -1548,14 +1603,17 @@ export function resolveStorageInstanceChunks(
1548
1603
  if (chunks === undefined) frameState.transientInstanceBuffers.push(active);
1549
1604
  }
1550
1605
  if (active === undefined) return null;
1551
- const needsUpload =
1552
- activeIsNew || active.uploadedRevision !== (inst.revision ?? inst.archVersion);
1553
- const rangesToUpload = [
1554
- {
1555
- start: 0,
1556
- end: count,
1557
- },
1558
- ];
1606
+ const localRanges = dirtyRanges
1607
+ .map((range) => ({
1608
+ start: Math.max(start, range.start) - start,
1609
+ end: Math.min(end, range.end) - start,
1610
+ }))
1611
+ .filter((range) => range.end > range.start);
1612
+ const needsUpload = activeIsNew || active.uploadedRevision !== inst.revision;
1613
+ const rangesToUpload = instanceUploadRangesForResident(activeIsNew, localRanges, {
1614
+ start: 0,
1615
+ end: count,
1616
+ });
1559
1617
  if (needsUpload && rangesToUpload.length > 0) {
1560
1618
  const upload = uploadInstanceRanges(
1561
1619
  c,
@@ -1575,8 +1633,7 @@ export function resolveStorageInstanceChunks(
1575
1633
  inst,
1576
1634
  {
1577
1635
  code: 'queue-write-buffer-failed',
1578
- expected:
1579
- 'the renderer-owned instance storage buffer accepts the complete instance payload',
1636
+ expected: 'the renderer-owned instance storage buffer accepts the dirty range',
1580
1637
  hint: 'retry after the active device is healthy or recover the renderer',
1581
1638
  },
1582
1639
  inst.instanceCount * strideBytes,
@@ -1586,8 +1643,8 @@ export function resolveStorageInstanceChunks(
1586
1643
  }
1587
1644
  }
1588
1645
  if (needsUpload) {
1589
- {
1590
- const published = { ...active, uploadedRevision: inst.revision ?? inst.archVersion };
1646
+ if (inst.revision !== undefined) {
1647
+ const published = { ...active, uploadedRevision: inst.revision };
1591
1648
  active = published;
1592
1649
  chunks?.set(chunkKey, published);
1593
1650
  }
@@ -1625,11 +1682,8 @@ export function resolveStorageInstanceChunks(
1625
1682
  return draws;
1626
1683
  }
1627
1684
 
1628
- export function resolveGeometryInstanceBuffer(
1629
- c: Pick<
1630
- _InternalRenderPipelineContext,
1631
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1632
- >,
1685
+ function resolveGeometryInstanceBuffer(
1686
+ c: _InternalRenderPipelineContext,
1633
1687
  entry: _InternalRenderPipelineContext['validatedOrdered'][number],
1634
1688
  identityInstanceDraws: readonly GeometryInstanceDraw[],
1635
1689
  useProbeBlend: boolean,
@@ -1665,9 +1719,12 @@ export function resolveGeometryInstanceBuffer(
1665
1719
  // the shared identity buffer, which would silently render one instance.
1666
1720
  if (inst.instanceCount === 0) return [];
1667
1721
  const entityCacheKey = instanceCollectionCacheKey(entry.source.worldId, inst);
1668
- const revision = inst.revision ?? inst.archVersion;
1722
+ const revision = inst.revision;
1723
+ const dirtyRanges = inst.dirtyRanges;
1669
1724
  const sameRevision = (cached: InstanceBufferCacheEntry): boolean =>
1670
- cached.uploadedRevision === revision;
1725
+ revision === undefined
1726
+ ? cached.uploadedRevision === undefined
1727
+ : cached.uploadedRevision === revision;
1671
1728
  const fullRange = [{ start: 0, end: inst.instanceCount }] as const;
1672
1729
  let instanceBuffer: Buffer = pipelineState.identityInstanceBuffer;
1673
1730
  let instanceCount = 1;
@@ -1685,6 +1742,7 @@ export function resolveGeometryInstanceBuffer(
1685
1742
  const activeKeys = new Set<string>();
1686
1743
  const draws: GeometryInstanceDraw[] = [];
1687
1744
  const uniformStrideBytes = 16 * Float32Array.BYTES_PER_ELEMENT;
1745
+ const dirty = inst.dirtyRanges ?? fullRange;
1688
1746
  const uploadedRanges: { start: number; end: number }[] = [];
1689
1747
  let uploadedBytes = 0;
1690
1748
  for (let start = 0; start < inst.instanceCount; start += MAX_UNIFORM_INSTANCES) {
@@ -1730,13 +1788,17 @@ export function resolveGeometryInstanceBuffer(
1730
1788
  chunks?.set(chunkKey, active);
1731
1789
  if (chunks === undefined) frameState.transientInstanceBuffers.push(active);
1732
1790
  }
1791
+ const localRanges = dirty
1792
+ .map((range) => ({
1793
+ start: Math.max(start, range.start) - start,
1794
+ end: Math.min(start + count, range.end) - start,
1795
+ }))
1796
+ .filter((range) => range.end > range.start);
1733
1797
  const needsUpload = activeIsNew || !sameRevision(active);
1734
- const rangesToUpload = [
1735
- {
1736
- start: 0,
1737
- end: count,
1738
- },
1739
- ];
1798
+ const rangesToUpload = instanceUploadRangesForResident(activeIsNew, localRanges, {
1799
+ start: 0,
1800
+ end: count,
1801
+ });
1740
1802
  if (needsUpload && rangesToUpload.length > 0) {
1741
1803
  const upload = uploadInstanceRanges(
1742
1804
  c,
@@ -1756,8 +1818,7 @@ export function resolveGeometryInstanceBuffer(
1756
1818
  inst,
1757
1819
  {
1758
1820
  code: 'queue-write-buffer-failed',
1759
- expected:
1760
- 'the renderer-owned instance uniform buffer accepts the complete instance payload',
1821
+ expected: 'the renderer-owned instance uniform buffer accepts the dirty range',
1761
1822
  hint: 'retry after the active device is healthy or recover the renderer',
1762
1823
  },
1763
1824
  inst.instanceCount * uniformStrideBytes,
@@ -1767,7 +1828,8 @@ export function resolveGeometryInstanceBuffer(
1767
1828
  }
1768
1829
  }
1769
1830
  if (needsUpload) {
1770
- const published = { ...active, uploadedRevision: revision };
1831
+ const published =
1832
+ revision === undefined ? active : { ...active, uploadedRevision: revision };
1771
1833
  active = published;
1772
1834
  chunks?.set(chunkKey, published);
1773
1835
  }
@@ -1848,7 +1910,6 @@ export function resolveGeometryInstanceBuffer(
1848
1910
  if (!bufRes.ok) {
1849
1911
  runtime.errorRegistry.fire(bufRes.error);
1850
1912
  reportInstanceFailure(c, inst, bufRes.error, requestedBytes, cap);
1851
- return null;
1852
1913
  } else {
1853
1914
  // feat-20260619 M4 / F12: destroy the old cached buffer
1854
1915
  // before replacing it with the new one (D-6).
@@ -1871,7 +1932,11 @@ export function resolveGeometryInstanceBuffer(
1871
1932
  }
1872
1933
  if (active !== null) {
1873
1934
  const needsUpload = activeIsNew || !sameRevision(active);
1874
- const ranges = [fullRange[0]];
1935
+ const ranges = instanceUploadRangesForResident(
1936
+ activeIsNew,
1937
+ dirtyRanges ?? fullRange,
1938
+ fullRange[0],
1939
+ );
1875
1940
  let uploadRanges: readonly { readonly start: number; readonly end: number }[] = [];
1876
1941
  let uploadedBytes = 0;
1877
1942
  if (needsUpload && ranges.length > 0) {
@@ -1890,8 +1955,7 @@ export function resolveGeometryInstanceBuffer(
1890
1955
  inst,
1891
1956
  {
1892
1957
  code: 'queue-write-buffer-failed',
1893
- expected:
1894
- 'the renderer-owned instance buffer accepts the complete instance payloads',
1958
+ expected: 'the renderer-owned instance buffer accepts the dirty ranges',
1895
1959
  hint: 'retry after the active device is healthy or recover the renderer',
1896
1960
  },
1897
1961
  requestedBytes,
@@ -1905,7 +1969,8 @@ export function resolveGeometryInstanceBuffer(
1905
1969
  }
1906
1970
  }
1907
1971
  if (needsUpload) {
1908
- const published = { ...active, uploadedRevision: revision };
1972
+ const published =
1973
+ revision === undefined ? active : { ...active, uploadedRevision: revision };
1909
1974
  frameState.instanceBuffers.set(entityCacheKey, published);
1910
1975
  active = published;
1911
1976
  }
@@ -1940,10 +2005,7 @@ export function resolveGeometryInstanceBuffer(
1940
2005
  }
1941
2006
 
1942
2007
  export function resolveProbeBlendBuffer(
1943
- c: Pick<
1944
- _InternalRenderPipelineContext,
1945
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1946
- >,
2008
+ c: _InternalRenderPipelineContext,
1947
2009
  record: import('../scene/probe-blend-record').ProbeBlendRecord | undefined,
1948
2010
  entityKey?: number,
1949
2011
  ): { readonly buffer: Buffer; readonly offset: number } {
@@ -1991,10 +2053,7 @@ export function resolveProbeBlendBuffer(
1991
2053
  }
1992
2054
 
1993
2055
  export function resolveGeometryInstancesBindGroup(
1994
- c: Pick<
1995
- _InternalRenderPipelineContext,
1996
- 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1997
- >,
2056
+ c: _InternalRenderPipelineContext,
1998
2057
  instanceBuffer: Buffer,
1999
2058
  probeBuffer?: Buffer,
2000
2059
  ): BindGroup {
@@ -2004,8 +2063,13 @@ export function resolveGeometryInstancesBindGroup(
2004
2063
  ? pipelineState.instancesBindGroupLayout
2005
2064
  : pipelineState.probeInstancesBindGroupLayout;
2006
2065
  if (layout === undefined) throw new Error('probe instances bind-group layout is unavailable');
2066
+ // A few record-only fixtures construct a minimal frame state and omit the
2067
+ // shared bind-group cache. Production frames always provide it, but keeping
2068
+ // this resolver total lets those fixtures exercise the same binding path
2069
+ // without weakening the production cache contract.
2070
+ const instancesBgShared = frameState.instancesBgShared ?? new WeakMap<object, unknown>();
2007
2071
  return getOrCreateFromChain(
2008
- frameState.instancesBgShared,
2072
+ instancesBgShared,
2009
2073
  probeBuffer === undefined ? [layout, instanceBuffer] : [layout, instanceBuffer, probeBuffer],
2010
2074
  probeBuffer === undefined ? 'instances-no-probe' : 'instances-probe',
2011
2075
  () => {