@forgeax/engine-render 0.1.28 → 0.1.30
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.
- package/README.md +856 -126
- package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
- package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/device-feature-admission.d.ts +4 -3
- package/dist/assembly/device-feature-admission.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-host.d.ts +27 -0
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +3 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/gpu-driven-owner.d.ts +10 -0
- package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +14 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +31 -1
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
- package/dist/assembly/material-shader-policy.d.ts +3 -1
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
- package/dist/assembly/recovery/failure-location.d.ts +12 -0
- package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
- package/dist/assembly/recovery/recovery-attempt.d.ts +1 -6
- package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +7 -4
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
- package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-helpers.d.ts +3 -0
- package/dist/assembly/renderer-helpers.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +4 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +7 -1
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
- package/dist/assembly/skin-palette-owner.d.ts +8 -0
- package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-device-loss.d.ts +15 -0
- package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +7 -3
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +7 -141
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
- package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -2
- package/dist/capture/scene-projection.d.ts +41 -0
- package/dist/capture/scene-projection.d.ts.map +1 -0
- package/dist/{chunk-J52NMQKR.mjs → chunk-7MQ3XBSP.mjs} +1098 -844
- package/dist/chunk-7MQ3XBSP.mjs.map +1 -0
- package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
- package/dist/chunk-BLXGONR2.mjs.map +1 -0
- package/dist/{chunk-VSL23LZE.mjs → chunk-C3DDSXYK.mjs} +1188 -463
- package/dist/chunk-C3DDSXYK.mjs.map +1 -0
- package/dist/{chunk-IQMKJLNU.mjs → chunk-FUUO4UND.mjs} +443 -30
- package/dist/chunk-FUUO4UND.mjs.map +1 -0
- package/dist/{chunk-J6KACNOH.mjs → chunk-JRBDO2KB.mjs} +617 -7
- package/dist/chunk-JRBDO2KB.mjs.map +1 -0
- package/dist/{chunk-GE3SDD72.mjs → chunk-MDQJPY3T.mjs} +20 -40
- package/dist/chunk-MDQJPY3T.mjs.map +1 -0
- package/dist/{chunk-MYJ5RPJO.mjs → chunk-NO4WZCAH.mjs} +3 -3
- package/dist/chunk-NO4WZCAH.mjs.map +1 -0
- package/dist/{chunk-RBDBZ5R7.mjs → chunk-PA5DRJNI.mjs} +2 -2
- package/dist/chunk-PA5DRJNI.mjs.map +1 -0
- package/dist/{chunk-MBU4ZVE7.mjs → chunk-PSEQ6QPH.mjs} +4655 -892
- package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
- package/dist/{chunk-JAASCMXA.mjs → chunk-S5UE2T5P.mjs} +289 -41
- package/dist/chunk-S5UE2T5P.mjs.map +1 -0
- package/dist/components/camera.d.ts +62 -2
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/directional-light.d.ts +2 -2
- package/dist/components/dynamic-resolution.d.ts +15 -0
- package/dist/components/dynamic-resolution.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +6 -20
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/reflection-probe.d.ts +1 -0
- package/dist/components/reflection-probe.d.ts.map +1 -1
- package/dist/components/scene-instance.d.ts +2 -1
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/screen-space-reflection.d.ts +14 -0
- package/dist/components/screen-space-reflection.d.ts.map +1 -0
- package/dist/components/skylight.d.ts +4 -1
- package/dist/components/skylight.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +14809 -7570
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts +2 -0
- package/dist/device/device-scope.d.ts.map +1 -1
- package/dist/device/gpu-residency.d.ts +3 -14
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/environment/background.d.ts +7 -0
- package/dist/environment/background.d.ts.map +1 -0
- package/dist/environment/ibl.d.ts +11 -0
- package/dist/environment/ibl.d.ts.map +1 -0
- package/dist/environment/storage.d.ts +14 -0
- package/dist/environment/storage.d.ts.map +1 -0
- package/dist/errors/gpu-driven.d.ts +6 -3
- package/dist/errors/gpu-driven.d.ts.map +1 -1
- package/dist/errors/render.d.ts +41 -4
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +7 -0
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +50 -3
- package/dist/extract/gpu-driven.d.ts.map +1 -1
- package/dist/features/host.d.ts +23 -1
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/noise-texture.d.ts +17 -0
- package/dist/features/noise-texture.d.ts.map +1 -0
- package/dist/features/plan.d.ts +83 -2
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +37 -4
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/features/prepared-graphics.d.ts +5 -0
- package/dist/features/prepared-graphics.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts +5 -3
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +11 -3
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +19 -3
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/types.d.ts +11 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +2 -0
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts +24 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
- package/dist/gpu-driven/material-bindings.d.ts +7 -0
- package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
- package/dist/gpu-driven/pbr-program.d.ts +10 -0
- package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
- package/dist/gpu-driven/prepared-draw.d.ts +2 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +169 -27
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-views.d.ts +126 -0
- package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +18 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-resource.d.ts +5 -2
- package/dist/gpu-resource.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +2 -8
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +14 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-texture-usage.d.ts +1 -0
- package/dist/gpu-texture-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +9 -0
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +2 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts +8 -0
- package/dist/ibl/frame-resources.d.ts.map +1 -0
- package/dist/ibl/skylight-bind-group.d.ts +3 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +87 -75
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +10 -8
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +180 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +11 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -1
- package/dist/instances.d.ts +89 -44
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +117 -9
- package/dist/internal.mjs.map +1 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/material-row.d.ts +15 -0
- package/dist/material-row.d.ts.map +1 -0
- package/dist/materials.d.ts +15 -0
- package/dist/materials.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +23 -5
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/render-extent.d.ts +51 -0
- package/dist/pipeline/render-extent.d.ts.map +1 -0
- package/dist/pipeline/standard-build-context.d.ts +7 -0
- package/dist/pipeline/standard-build-context.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts +3 -2
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
- package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
- package/dist/pipeline/standard-output/graph.d.ts +15 -0
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
- package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/resources.d.ts +10 -0
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
- package/dist/pipeline/standard-output/types.d.ts +39 -0
- package/dist/pipeline/standard-output/types.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +2 -2
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +2 -1
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +5 -2
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec-types.d.ts +4 -0
- package/dist/pipeline-spec-types.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +1 -9
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/points-lines/standard-owner.d.ts +1 -1
- package/dist/points-lines/standard-owner.d.ts.map +1 -1
- package/dist/post-process-errors.d.ts +9 -2
- package/dist/post-process-errors.d.ts.map +1 -1
- package/dist/prepare/extended-lighting/resources.d.ts +3 -3
- package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +3 -3
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +109 -13
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +41 -5
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +13 -9
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +43 -3
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +2 -10
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +14 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +15 -6
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/prepared-material-bindings.d.ts +19 -0
- package/dist/record/prepared-material-bindings.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts +1 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +101 -22
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +62 -7
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +39 -8
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +1 -0
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +10 -2
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/recovery/render-system-roots.d.ts +11 -0
- package/dist/recovery/render-system-roots.d.ts.map +1 -0
- package/dist/recovery/types.d.ts +76 -0
- package/dist/recovery/types.d.ts.map +1 -0
- package/dist/reflection/background.d.ts +14 -0
- package/dist/reflection/background.d.ts.map +1 -0
- package/dist/reflection/filter.d.ts.map +1 -1
- package/dist/reflection/projection.d.ts +1 -0
- package/dist/reflection/projection.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts +4 -4
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +211 -53
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +81 -6
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +15 -6
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +128 -41
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-projections.d.ts +22 -0
- package/dist/render-system-projections.d.ts.map +1 -0
- package/dist/render-system.d.ts +27 -77
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +14 -7
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +31 -11
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/shadow-visibility.d.ts +5 -0
- package/dist/scene/shadow-visibility.d.ts.map +1 -0
- package/dist/ssao-config.d.ts +8 -6
- package/dist/ssao-config.d.ts.map +1 -1
- package/dist/ssr/admission.d.ts +70 -1
- package/dist/ssr/admission.d.ts.map +1 -1
- package/dist/ssr/compose.d.ts +13 -0
- package/dist/ssr/compose.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +35 -0
- package/dist/ssr/errors.d.ts.map +1 -1
- package/dist/ssr/graph.d.ts +60 -0
- package/dist/ssr/graph.d.ts.map +1 -0
- package/dist/ssr/history.d.ts +97 -0
- package/dist/ssr/history.d.ts.map +1 -0
- package/dist/ssr/hiz.d.ts +37 -0
- package/dist/ssr/hiz.d.ts.map +1 -0
- package/dist/ssr/inspection.d.ts +42 -0
- package/dist/ssr/inspection.d.ts.map +1 -0
- package/dist/ssr/resources.d.ts +58 -0
- package/dist/ssr/resources.d.ts.map +1 -0
- package/dist/ssr/temporal.d.ts +38 -0
- package/dist/ssr/temporal.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +32 -10
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +15 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +9 -0
- package/dist/systems/transparent-dispatch.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +7 -0
- package/dist/targets/material-source.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts +7 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +8 -0
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/history.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -6
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts +4 -2
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts +15 -0
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
- package/dist/temporal/temporal-view.d.ts +6 -0
- package/dist/temporal/temporal-view.d.ts.map +1 -1
- package/dist/temporal/view.d.ts +6 -0
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +41 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +3 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/component.d.ts +1 -0
- package/dist/volume/component.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +6 -0
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
- package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
- package/src/__tests__/auto-exposure.browser.test.ts +33 -0
- package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
- package/src/__tests__/capture-scene-projection.unit.test.ts +24 -0
- package/src/__tests__/detached-inspection.integration.test.ts +5 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
- package/src/__tests__/device-loss-fanout.unit.test.ts +43 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
- package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
- package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
- package/src/__tests__/dynamic-geometry-batch.unit.test.ts +157 -0
- package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
- package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
- package/src/__tests__/factory-contract.integration.test.ts +231 -9
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
- package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
- package/src/__tests__/feature-noise.unit.test.ts +38 -0
- package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
- package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
- package/src/__tests__/frame-observation.contract.test.ts +21 -0
- package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
- package/src/__tests__/frame-targets.unit.test.ts +24 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +307 -7
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
- package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
- package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +261 -0
- package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +346 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1422 -0
- package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +1076 -106
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
- package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
- package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
- package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
- package/src/__tests__/gpu-driven-view.unit.test.ts +160 -52
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +20 -2
- package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
- package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
- package/src/__tests__/gpu-scene.unit.test.ts +613 -33
- package/src/__tests__/instances-culling.integration.test.ts +36 -10
- package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
- package/src/__tests__/instances-store.unit.test.ts +242 -39
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
- package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
- package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
- package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
- package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
- package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
- package/src/__tests__/material-texture-source.unit.test.ts +87 -0
- package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
- package/src/__tests__/materials-standard-contract.unit.test.ts +57 -3
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
- package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -0
- package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
- package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +42 -3
- package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
- package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -5
- package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
- package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +251 -9
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
- package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
- package/src/__tests__/public-surface.test-d.ts +3 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
- package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +171 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
- package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
- package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -14
- package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +27 -1
- package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
- package/src/__tests__/render-extent.unit.test.ts +63 -0
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
- package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
- package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
- package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
- package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
- package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +915 -23
- package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
- package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
- package/src/__tests__/render-target-material-source.test-d.ts +27 -3
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +233 -9
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
- package/src/__tests__/shader-manifest-fixture.ts +45 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
- package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
- package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +125 -14
- package/src/__tests__/specular-environment-scale.dawn.test.ts +158 -0
- package/src/__tests__/ssao-config.unit.test.ts +7 -0
- package/src/__tests__/ssao-surface.dawn.test.ts +252 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
- package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
- package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
- package/src/__tests__/ssr-cube-silhouette.dawn.test.ts +270 -0
- package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +99 -0
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +116 -0
- package/src/__tests__/ssr-gpu-dispatch.ts +951 -0
- package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
- package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
- package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
- package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
- package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
- package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
- package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
- package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
- package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
- package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
- package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
- package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
- package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
- package/src/__tests__/ssr-reprojection-probe.ts +90 -0
- package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
- package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
- package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
- package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
- package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
- package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +84 -12
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
- package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
- package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
- package/src/__tests__/standard-output.browser.test.ts +15 -0
- package/src/__tests__/standard-output.dawn.test.ts +15 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +275 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
- package/src/__tests__/standard-profile-oracle.unit.test.ts +49 -0
- package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
- package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
- package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
- package/src/__tests__/taa-coverage-edge.dawn.test.ts +199 -0
- package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
- package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +782 -0
- package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
- package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
- package/src/__tests__/taa-stability-feedback.ts +342 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
- package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
- package/src/__tests__/temporal-view.unit.test.ts +17 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
- package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
- package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
- package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
- package/src/__tests__/visibility-extract.perf.test.ts +20 -8
- package/src/__tests__/visibility-instances.integration.test.ts +19 -7
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
- package/src/assembly/atmosphere-shader-prewarm.ts +39 -0
- package/src/assembly/device-feature-admission.ts +9 -4
- package/src/assembly/dynamic-geometry-host.ts +284 -163
- package/src/assembly/dynamic-geometry-runtime.ts +71 -0
- package/src/assembly/factory.ts +4 -0
- package/src/assembly/gpu-driven-owner.ts +29 -0
- package/src/assembly/host-contract.ts +19 -0
- package/src/assembly/material/assembly.ts +383 -1
- package/src/assembly/material/pipeline-helpers.ts +100 -0
- package/src/assembly/material-shader-policy.ts +110 -46
- package/src/assembly/recovery/device-loss-fanout.ts +5 -0
- package/src/assembly/recovery/failure-location.ts +62 -0
- package/src/assembly/recovery/recovery-attempt.ts +2 -29
- package/src/assembly/recovery/renderer-recover.ts +16 -17
- package/src/assembly/renderer-facade.ts +34 -1
- package/src/assembly/renderer-feature-inspection.ts +13 -0
- package/src/assembly/renderer-frame-transaction.ts +63 -0
- package/src/assembly/renderer-helpers.ts +26 -0
- package/src/assembly/renderer-inspection.ts +6 -0
- package/src/assembly/shader-prewarm-policy.ts +46 -1
- package/src/assembly/skin-palette-owner.ts +21 -0
- package/src/assembly/ssr-shader-prewarm.ts +41 -0
- package/src/assembly/webgpu-device-loss.ts +75 -0
- package/src/assembly/webgpu-pbr-ready.ts +232 -0
- package/src/assembly/webgpu-ready-mipmap.ts +26 -0
- package/src/assembly/webgpu-ready.ts +161 -131
- package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
- package/src/assembly/webgpu-renderer-contract.ts +69 -0
- package/src/assembly/webgpu-renderer-guards.ts +32 -0
- package/src/assembly/webgpu-renderer-observation.ts +43 -0
- package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
- package/src/assembly/webgpu-renderer.ts +744 -730
- package/src/assembly/webgpu-vertex-layouts.ts +233 -87
- package/src/capture/scene-projection.ts +37 -0
- package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
- package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
- package/src/components/__tests__/light-radius.integration.test.ts +59 -0
- package/src/components/camera.ts +287 -7
- package/src/components/directional-light.ts +3 -3
- package/src/components/dynamic-resolution.ts +67 -0
- package/src/components/index.ts +2 -0
- package/src/components/instances.ts +45 -18
- package/src/components/light-helpers.ts +6 -1
- package/src/components/reflection-probe.ts +1 -0
- package/src/components/scene-instance.ts +2 -1
- package/src/components/screen-space-reflection.ts +21 -0
- package/src/components/skylight.ts +4 -1
- package/src/components/sprite-animation.ts +2 -2
- package/src/components/sprite-instances.ts +1 -1
- package/src/device/device-scope.ts +13 -7
- package/src/device/gpu-residency.ts +45 -42
- package/src/dynamic-geometry.ts +13 -8
- package/src/environment/background.ts +281 -0
- package/src/environment/ibl.ts +211 -0
- package/src/environment/storage.ts +63 -0
- package/src/errors/gpu-driven.ts +49 -8
- package/src/errors/render.ts +91 -3
- package/src/extract/camera.ts +37 -1
- package/src/extract/contracts.ts +10 -0
- package/src/extract/gpu-driven.ts +240 -10
- package/src/features/host.ts +237 -19
- package/src/features/noise-texture.ts +91 -0
- package/src/features/plan.ts +553 -24
- package/src/features/prepared-gpu-work.ts +631 -49
- package/src/features/prepared-graphics-store.ts +31 -0
- package/src/features/prepared-graphics.ts +5 -0
- package/src/features/render-graph-compute.ts +41 -8
- package/src/features/render-graph-contribution.ts +141 -3
- package/src/features/render-graph-raster.ts +143 -30
- package/src/features/types.ts +11 -0
- package/src/fullscreen-post-process-pass.ts +3 -0
- package/src/gpu-driven/batch-topology.ts +452 -108
- package/src/gpu-driven/material-artifacts.ts +179 -0
- package/src/gpu-driven/material-bindings.ts +41 -0
- package/src/gpu-driven/pbr-program.ts +31 -0
- package/src/gpu-driven/prepared-draw.ts +42 -6
- package/src/gpu-driven/production-raster.ts +2806 -716
- package/src/gpu-driven/shadow-views.ts +539 -0
- package/src/gpu-driven/view-gpu.ts +188 -41
- package/src/gpu-resource.ts +21 -2
- package/src/gpu-scene-schema.ts +61 -11
- package/src/gpu-scene.ts +197 -99
- package/src/gpu-texture-usage.ts +1 -0
- package/src/hdrp-buffers.ts +141 -36
- package/src/ibl/IblPipelineCache.ts +5 -0
- package/src/ibl/frame-resources.ts +38 -0
- package/src/ibl/skylight-bind-group.ts +32 -21
- package/src/index.ts +194 -75
- package/src/inspection-types.ts +207 -1
- package/src/instances-derived-bounds.ts +258 -34
- package/src/instances.ts +459 -150
- package/src/internal.ts +22 -0
- package/src/lifecycle.ts +2 -0
- package/src/material-row.ts +194 -0
- package/src/materials.ts +44 -8
- package/src/pbr-pipeline.ts +172 -19
- package/src/pipeline/render-extent.ts +111 -0
- package/src/pipeline/standard-build-context.ts +7 -0
- package/src/pipeline/standard-forward-lane.ts +74 -29
- package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
- package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
- package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
- package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
- package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
- package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
- package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
- package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
- package/src/pipeline/standard-output/color-transform.ts +124 -0
- package/src/pipeline/standard-output/graph.ts +139 -0
- package/src/pipeline/standard-output/lut-admission.ts +121 -0
- package/src/pipeline/standard-output/lut-gpu.ts +399 -0
- package/src/pipeline/standard-output/lut-state.ts +176 -0
- package/src/pipeline/standard-output/resources.ts +121 -0
- package/src/pipeline/standard-output/types.ts +58 -0
- package/src/pipeline/standard-pipeline.ts +232 -70
- package/src/pipeline/standard-post.ts +190 -27
- package/src/pipeline/standard-profile.ts +2 -1
- package/src/pipeline-builder.ts +28 -9
- package/src/pipeline-spec-types.ts +4 -0
- package/src/pipeline-spec.ts +37 -29
- package/src/plugin.ts +4 -0
- package/src/points-lines/standard-owner.ts +6 -14
- package/src/post-process-errors.ts +26 -18
- package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
- package/src/prepare/extended-lighting/resources.ts +3 -3
- package/src/prepare/prepared-graphics-resolver.ts +9 -2
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
- package/src/record/__tests__/material-slot-plan.unit.test.ts +57 -0
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +20 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +41 -6
- package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
- package/src/record/dynamic-geometry-consumption.ts +59 -0
- package/src/record/frame-lighting.ts +15 -12
- package/src/record/frame-snapshot.ts +146 -34
- package/src/record/frame-targets.ts +9 -0
- package/src/record/frame.ts +838 -170
- package/src/record/main-pass-geometry.ts +209 -103
- package/src/record/main-pass-material.ts +157 -40
- package/src/record/main-pass-sprite-draws.ts +16 -107
- package/src/record/main-pass.ts +141 -12
- package/src/record/material-uniforms.ts +1 -1
- package/src/record/mesh-ssbo.ts +59 -15
- package/src/record/prepared-material-bindings.ts +238 -0
- package/src/record/recovery-pipeline.ts +69 -90
- package/src/record/render-context.ts +123 -24
- package/src/record/shadow-pass.ts +1389 -230
- package/src/record/skybox-post-pass.ts +14 -3
- package/src/record/typed-frame-graph.ts +1064 -47
- package/src/record/view-ubo.ts +12 -1
- package/src/recovery/render-system-candidate.ts +135 -68
- package/src/recovery/render-system-roots.ts +113 -0
- package/src/recovery/types.ts +77 -0
- package/src/reflection/background.ts +151 -0
- package/src/reflection/filter.ts +3 -0
- package/src/reflection/projection.ts +16 -6
- package/src/reflection/record-owner.ts +308 -140
- package/src/render-contract.ts +237 -49
- package/src/render-graph-primitives.ts +34 -5
- package/src/render-pipeline.ts +90 -2
- package/src/render-system-extract-tail.ts +431 -162
- package/src/render-system-extract.ts +478 -119
- package/src/render-system-projections.ts +241 -0
- package/src/render-system.ts +715 -828
- package/src/scene/render-scene-types.ts +13 -4
- package/src/scene/render-scene.ts +577 -355
- package/src/scene/shadow-visibility.ts +21 -0
- package/src/ssao-config.ts +25 -8
- package/src/ssr/admission.ts +380 -14
- package/src/ssr/compose.ts +144 -0
- package/src/ssr/errors.ts +48 -0
- package/src/ssr/graph.ts +797 -0
- package/src/ssr/history.ts +436 -0
- package/src/ssr/hiz.ts +124 -0
- package/src/ssr/inspection.ts +124 -0
- package/src/ssr/resources.ts +202 -0
- package/src/ssr/temporal.ts +164 -0
- package/src/systems/skin-palette-allocator.ts +495 -148
- package/src/systems/skin-palette-types.ts +17 -0
- package/src/systems/transparent-dispatch.ts +90 -0
- package/src/targets/material-source.ts +34 -0
- package/src/temporal/coverage.ts +1 -1
- package/src/temporal/frame-coordinator.ts +23 -2
- package/src/temporal/gpu.ts +79 -12
- package/src/temporal/history.ts +3 -1
- package/src/temporal/inspection.ts +2 -1
- package/src/temporal/standard-scene-data.ts +10 -2
- package/src/temporal/target-coverage-attachment.ts +72 -0
- package/src/temporal/temporal-view.ts +11 -2
- package/src/temporal/view.ts +12 -2
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +219 -139
- package/src/typed-render-graph-primitives.ts +304 -74
- package/src/typed-shadow-passes.ts +122 -12
- package/src/volume/component.ts +1 -0
- package/src/volume/passes.ts +3 -3
- package/src/volume/temporal.ts +10 -0
- package/dist/chunk-GE3SDD72.mjs.map +0 -1
- package/dist/chunk-GF523LHF.mjs.map +0 -1
- package/dist/chunk-IQMKJLNU.mjs.map +0 -1
- package/dist/chunk-J52NMQKR.mjs.map +0 -1
- package/dist/chunk-J6KACNOH.mjs.map +0 -1
- package/dist/chunk-JAASCMXA.mjs.map +0 -1
- package/dist/chunk-MBU4ZVE7.mjs.map +0 -1
- package/dist/chunk-MYJ5RPJO.mjs.map +0 -1
- package/dist/chunk-RBDBZ5R7.mjs.map +0 -1
- package/dist/chunk-VSL23LZE.mjs.map +0 -1
- package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
|
@@ -25,10 +25,19 @@ import { executeRendererFrameTransaction } from '../assembly/renderer-frame-tran
|
|
|
25
25
|
import { type RenderError, RenderFeatureStageFailedError } from '../errors/render';
|
|
26
26
|
import {
|
|
27
27
|
getRenderFeaturePlanExecutionProjection,
|
|
28
|
+
hasSubmissionSensitiveFeatures,
|
|
28
29
|
type RenderFeaturePlanExecution,
|
|
29
30
|
} from '../features/host';
|
|
30
|
-
import {
|
|
31
|
-
|
|
31
|
+
import {
|
|
32
|
+
type RenderFeaturePlannedFrame,
|
|
33
|
+
renderFeaturePlanSignature,
|
|
34
|
+
renderFeaturePlanSignatureEvidenceMatches,
|
|
35
|
+
} from '../features/plan';
|
|
36
|
+
import {
|
|
37
|
+
createRenderFeatureProjectionState,
|
|
38
|
+
projectRenderFeaturePlans as projectPlanExecutions,
|
|
39
|
+
projectRenderFeatureShadows,
|
|
40
|
+
} from '../features/render-graph-contribution';
|
|
32
41
|
import type {
|
|
33
42
|
RenderFeatureGraphBindingsResolution,
|
|
34
43
|
RenderFeatureGraphTargetResolver,
|
|
@@ -46,13 +55,29 @@ import {
|
|
|
46
55
|
GPU_TEXTURE_USAGE_COPY_DST,
|
|
47
56
|
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
48
57
|
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,
|
|
58
|
+
GPU_TEXTURE_USAGE_STORAGE_BINDING,
|
|
49
59
|
GPU_TEXTURE_USAGE_TEXTURE_BINDING,
|
|
50
60
|
} from '../gpu-texture-usage';
|
|
61
|
+
import { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';
|
|
62
|
+
import { createStandardSurfaceLightingBindGroup } from '../hdrp-buffers';
|
|
63
|
+
import type { RenderFeatureGraphInspection } from '../inspection-types';
|
|
64
|
+
import type { RenderExtent } from '../pipeline/render-extent';
|
|
51
65
|
import {
|
|
52
66
|
type StandardTopologyInputValue,
|
|
53
67
|
standardLightingTopologySignature,
|
|
54
68
|
} from '../pipeline/standard-lighting/topology';
|
|
69
|
+
import {
|
|
70
|
+
importAutoExposureGraphResources,
|
|
71
|
+
retireAutoExposureGpuResources,
|
|
72
|
+
} from '../pipeline/standard-output/auto-exposure/gpu';
|
|
73
|
+
import { commitAutoExposureSubmission } from '../pipeline/standard-output/auto-exposure/state';
|
|
74
|
+
import { retireStandardLutGpuResources } from '../pipeline/standard-output/lut-gpu';
|
|
75
|
+
import {
|
|
76
|
+
commitStandardLutCandidate,
|
|
77
|
+
resetStandardLutState,
|
|
78
|
+
} from '../pipeline/standard-output/lut-state';
|
|
55
79
|
import { resolveVolumetricFogProfile, STANDARD_PIPELINE_ID } from '../pipeline/standard-profile';
|
|
80
|
+
import { type ProbeBackgroundResources, recordProbeBackground } from '../reflection/background';
|
|
56
81
|
import type { CameraSnapshot } from '../render-contract';
|
|
57
82
|
import type {
|
|
58
83
|
RenderPipelineFeatureTarget,
|
|
@@ -61,7 +86,7 @@ import type {
|
|
|
61
86
|
} from '../render-pipeline';
|
|
62
87
|
import type { ExtractedLights, ExtractedVolumetricFog } from '../render-system-extract';
|
|
63
88
|
import { SHADOW_ATLAS_DEFAULT_FACE_SIZE, SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
|
|
64
|
-
import type { SsrAdmissionResult } from '../ssr/admission';
|
|
89
|
+
import type { SsrAdmissionResult, SsrSpatialAdmission } from '../ssr/admission';
|
|
65
90
|
import type { RenderTarget } from '../targets/contracts';
|
|
66
91
|
import type { RenderTargetPhysical } from '../targets/physical';
|
|
67
92
|
import {
|
|
@@ -71,15 +96,22 @@ import {
|
|
|
71
96
|
hasPendingTemporalGpuSubmit,
|
|
72
97
|
retireTemporalGpuState,
|
|
73
98
|
retireTemporalGpuStateAfterFence,
|
|
99
|
+
TEMPORAL_HISTORY_FORMATS,
|
|
74
100
|
temporalReadIndex,
|
|
75
101
|
temporalWriteIndex,
|
|
76
102
|
} from '../temporal/gpu';
|
|
77
103
|
import { isSceneDataTarget } from '../temporal/scene-data';
|
|
104
|
+
import { createTargetCoverageAttachment } from '../temporal/target-coverage-attachment';
|
|
78
105
|
import type { TransmissionDemand } from '../transmission/projection';
|
|
79
106
|
import { hasVolumetricFogCapability } from '../volume/capability';
|
|
80
107
|
import { deriveVolumetricFogExtent, deriveVolumetricFogResolvedExtent } from '../volume/resources';
|
|
81
108
|
import { buildPerFrameBindGroups } from './frame-lighting';
|
|
82
|
-
import {
|
|
109
|
+
import {
|
|
110
|
+
type GraphTargetPassReplayPrefixReceipt,
|
|
111
|
+
type GraphTargetPassReplayReceipt,
|
|
112
|
+
getTextureIdentity,
|
|
113
|
+
type RenderFrameState,
|
|
114
|
+
} from './frame-snapshot';
|
|
83
115
|
import type { GpuPassTimingPassIdentity } from './gpu-pass-timing/contract.js';
|
|
84
116
|
import type { GpuPassTimingCapture, GpuPassTimingSession } from './gpu-pass-timing/session.js';
|
|
85
117
|
import type { GpuTimingCapture } from './gpu-timing';
|
|
@@ -198,13 +230,14 @@ export function commitReflectionFallbackGraph(
|
|
|
198
230
|
function importTemporalHistoryTarget(
|
|
199
231
|
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
200
232
|
label: string,
|
|
201
|
-
kind: 'color' | 'temporal',
|
|
233
|
+
kind: 'color' | 'temporal' | 'stability',
|
|
202
234
|
role: 'read' | 'write',
|
|
203
235
|
): import('../render-pipeline').RenderPipelineTarget {
|
|
236
|
+
const format = TEMPORAL_HISTORY_FORMATS[kind];
|
|
204
237
|
const texture = graph.importTexture(
|
|
205
238
|
label,
|
|
206
239
|
{
|
|
207
|
-
format
|
|
240
|
+
format,
|
|
208
241
|
size: 'surface',
|
|
209
242
|
usage:
|
|
210
243
|
GPU_TEXTURE_USAGE_COPY_SRC |
|
|
@@ -222,7 +255,7 @@ function importTemporalHistoryTarget(
|
|
|
222
255
|
frame.targetH,
|
|
223
256
|
);
|
|
224
257
|
const index = role === 'read' ? temporalReadIndex(state) : temporalWriteIndex(state);
|
|
225
|
-
return
|
|
258
|
+
return state[kind][index].texture;
|
|
226
259
|
},
|
|
227
260
|
);
|
|
228
261
|
if (!texture.ok) throw texture.error;
|
|
@@ -239,11 +272,11 @@ function importTemporalHistoryTarget(
|
|
|
239
272
|
frame.targetH,
|
|
240
273
|
);
|
|
241
274
|
const index = role === 'read' ? temporalReadIndex(state) : temporalWriteIndex(state);
|
|
242
|
-
return
|
|
275
|
+
return state[kind][index].view;
|
|
243
276
|
},
|
|
244
277
|
);
|
|
245
278
|
if (!view.ok) throw view.error;
|
|
246
|
-
return { texture: texture.value, view: view.value, format
|
|
279
|
+
return { texture: texture.value, view: view.value, format, sampleCount: 1 };
|
|
247
280
|
}
|
|
248
281
|
|
|
249
282
|
function importTemporalHistoryTargets(
|
|
@@ -253,6 +286,18 @@ function importTemporalHistoryTargets(
|
|
|
253
286
|
> {
|
|
254
287
|
return {
|
|
255
288
|
currentColor: importTemporalHistoryTarget(graph, 'taa-history-current-color', 'color', 'write'),
|
|
289
|
+
currentStability: importTemporalHistoryTarget(
|
|
290
|
+
graph,
|
|
291
|
+
'taa-history-current-stability',
|
|
292
|
+
'stability',
|
|
293
|
+
'write',
|
|
294
|
+
),
|
|
295
|
+
previousStability: importTemporalHistoryTarget(
|
|
296
|
+
graph,
|
|
297
|
+
'taa-history-previous-stability',
|
|
298
|
+
'stability',
|
|
299
|
+
'read',
|
|
300
|
+
),
|
|
256
301
|
previousColor: importTemporalHistoryTarget(
|
|
257
302
|
graph,
|
|
258
303
|
'taa-history-previous-color',
|
|
@@ -274,6 +319,110 @@ function importTemporalHistoryTargets(
|
|
|
274
319
|
};
|
|
275
320
|
}
|
|
276
321
|
|
|
322
|
+
function importSsrHistoryTarget(
|
|
323
|
+
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
324
|
+
label: string,
|
|
325
|
+
role: 'read' | 'write',
|
|
326
|
+
surface = false,
|
|
327
|
+
): import('../render-pipeline').RenderPipelineTarget {
|
|
328
|
+
const texture = graph.importTexture(
|
|
329
|
+
label,
|
|
330
|
+
{
|
|
331
|
+
format: surface ? 'rgba8unorm' : 'rgba16float',
|
|
332
|
+
size: 'half-surface',
|
|
333
|
+
usage:
|
|
334
|
+
GPU_TEXTURE_USAGE_COPY_SRC |
|
|
335
|
+
GPU_TEXTURE_USAGE_COPY_DST |
|
|
336
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |
|
|
337
|
+
GPU_TEXTURE_USAGE_STORAGE_BINDING |
|
|
338
|
+
GPU_TEXTURE_USAGE_TEXTURE_BINDING,
|
|
339
|
+
domain: 'linear-hdr',
|
|
340
|
+
},
|
|
341
|
+
(frame) => {
|
|
342
|
+
const internal = frame as import('./render-context')._InternalRenderPipelineContext;
|
|
343
|
+
const owner = internal.frameState.ssrHistoryOwner;
|
|
344
|
+
const candidate = internal.frameState.ssrHistoryCandidate;
|
|
345
|
+
if (owner === undefined || candidate === undefined) {
|
|
346
|
+
throw new RhiError({
|
|
347
|
+
code: 'rhi-not-available',
|
|
348
|
+
expected: 'SSR history candidate to be staged before graph execution',
|
|
349
|
+
hint: 'begin the SSR history candidate before executing the admitted graph',
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
const slot =
|
|
353
|
+
role === 'read'
|
|
354
|
+
? (candidate.readSlot ?? (candidate.writeSlot === 0 ? 1 : 0))
|
|
355
|
+
: candidate.writeSlot;
|
|
356
|
+
return surface
|
|
357
|
+
? owner.resources.slots[slot].surfaceTexture
|
|
358
|
+
: owner.resources.slots[slot].texture;
|
|
359
|
+
},
|
|
360
|
+
);
|
|
361
|
+
if (!texture.ok) throw texture.error;
|
|
362
|
+
const view = graph.importView(
|
|
363
|
+
texture.value,
|
|
364
|
+
{ label: `${label}.view`, dimension: '2d' },
|
|
365
|
+
(frame) => {
|
|
366
|
+
const internal = frame as import('./render-context')._InternalRenderPipelineContext;
|
|
367
|
+
const owner = internal.frameState.ssrHistoryOwner;
|
|
368
|
+
const candidate = internal.frameState.ssrHistoryCandidate;
|
|
369
|
+
if (owner === undefined || candidate === undefined) {
|
|
370
|
+
throw new RhiError({
|
|
371
|
+
code: 'rhi-not-available',
|
|
372
|
+
expected: 'SSR history candidate to be staged before graph execution',
|
|
373
|
+
hint: 'begin the SSR history candidate before executing the admitted graph',
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
const slot =
|
|
377
|
+
role === 'read'
|
|
378
|
+
? (candidate.readSlot ?? (candidate.writeSlot === 0 ? 1 : 0))
|
|
379
|
+
: candidate.writeSlot;
|
|
380
|
+
return surface ? owner.resources.slots[slot].surfaceView : owner.resources.slots[slot].view;
|
|
381
|
+
},
|
|
382
|
+
);
|
|
383
|
+
if (!view.ok) throw view.error;
|
|
384
|
+
return {
|
|
385
|
+
texture: texture.value,
|
|
386
|
+
view: view.value,
|
|
387
|
+
format: surface ? 'rgba8unorm' : 'rgba16float',
|
|
388
|
+
sampleCount: 1,
|
|
389
|
+
domain: 'linear-hdr',
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function importSsrHistoryTargets(
|
|
394
|
+
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
395
|
+
): NonNullable<
|
|
396
|
+
import('../render-pipeline').RenderPipelineBuildContext<RenderPipelineFrame>['ssrHistory']
|
|
397
|
+
> {
|
|
398
|
+
return {
|
|
399
|
+
previous: importSsrHistoryTarget(graph, 'ssr-history-previous', 'read'),
|
|
400
|
+
output: importSsrHistoryTarget(graph, 'ssr-history-output', 'write'),
|
|
401
|
+
previousSurface: importSsrHistoryTarget(graph, 'ssr-history-previous-surface', 'read', true),
|
|
402
|
+
outputSurface: importSsrHistoryTarget(graph, 'ssr-history-output-surface', 'write', true),
|
|
403
|
+
params: (() => {
|
|
404
|
+
const imported = graph.importBuffer(
|
|
405
|
+
'ssr-history-params',
|
|
406
|
+
{ size: 32, usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST },
|
|
407
|
+
(frame) => {
|
|
408
|
+
const internal = frame as import('./render-context')._InternalRenderPipelineContext;
|
|
409
|
+
const owner = internal.frameState.ssrHistoryOwner;
|
|
410
|
+
if (owner === undefined) {
|
|
411
|
+
throw new RhiError({
|
|
412
|
+
code: 'rhi-not-available',
|
|
413
|
+
expected: 'SSR history owner to be staged before graph execution',
|
|
414
|
+
hint: 'create the renderer-owned SSR history before executing the admitted graph',
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
return owner.resources.paramsBuffer;
|
|
418
|
+
},
|
|
419
|
+
);
|
|
420
|
+
if (!imported.ok) throw imported.error;
|
|
421
|
+
return imported.value;
|
|
422
|
+
})(),
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
277
426
|
export function shouldUseTemporalFrameTransaction(
|
|
278
427
|
antialias: CameraSnapshot['antialias'],
|
|
279
428
|
temporalDemand = false,
|
|
@@ -345,6 +494,7 @@ export interface ReflectionProbeFilterGraphState {
|
|
|
345
494
|
}
|
|
346
495
|
|
|
347
496
|
export interface ReflectionProbeGraphWork {
|
|
497
|
+
readonly background?: ProbeBackgroundResources;
|
|
348
498
|
readonly probeIndex: number;
|
|
349
499
|
readonly rawTexture: Texture;
|
|
350
500
|
readonly rawCubeView: TextureView;
|
|
@@ -538,7 +688,6 @@ function addCubeCaptureGraphPasses(
|
|
|
538
688
|
const captureResolveView = captureResolve?.ok ? captureResolve.value : null;
|
|
539
689
|
const captureContext = {
|
|
540
690
|
...internal,
|
|
541
|
-
gpuDrivenEntityKeys: new Set<number>(),
|
|
542
691
|
camera: current().faceCamera,
|
|
543
692
|
// Cube faces are raw scene captures, not display-camera HDR output.
|
|
544
693
|
// Select the PSO against the actual target attachment so an LDR
|
|
@@ -571,6 +720,7 @@ function addCubeCaptureGraphPasses(
|
|
|
571
720
|
export function addReflectionProbeGraphPasses(
|
|
572
721
|
builder: RenderGraphBuilder<RenderPipelineFrame>,
|
|
573
722
|
state: ReflectionProbeGraphState,
|
|
723
|
+
environmentCube?: import('../environment/ibl').GraphEnvironment,
|
|
574
724
|
): Result<readonly import('@forgeax/engine-render-graph').GraphAccess[], RenderGraphError> {
|
|
575
725
|
const accesses: import('@forgeax/engine-render-graph').GraphAccess[] = [];
|
|
576
726
|
for (const work of state.work) {
|
|
@@ -656,6 +806,11 @@ export function addReflectionProbeGraphPasses(
|
|
|
656
806
|
if (!depth.ok) return depth;
|
|
657
807
|
const added = builder.addRasterPass(`reflection-probe.${work.probeIndex}.capture.${face}`, {
|
|
658
808
|
accesses: [
|
|
809
|
+
...(environmentCube === undefined
|
|
810
|
+
? []
|
|
811
|
+
: [environmentCube.sky, environmentCube.irradiance, environmentCube.prefilter].map(
|
|
812
|
+
(resource) => ({ resource, usage: 'sampled-read' as const }),
|
|
813
|
+
)),
|
|
659
814
|
{ resource: view.value, usage: 'color-attachment' },
|
|
660
815
|
{ resource: depth.value, usage: 'depth-stencil-write' },
|
|
661
816
|
],
|
|
@@ -683,9 +838,35 @@ export function addReflectionProbeGraphPasses(
|
|
|
683
838
|
if (!captureColor.ok || !captureDepth.ok) return;
|
|
684
839
|
if (work.faceCamera === undefined || work.viewBindGroupDynamicOffset === undefined)
|
|
685
840
|
return;
|
|
841
|
+
recordProbeBackground(
|
|
842
|
+
work.background,
|
|
843
|
+
internal,
|
|
844
|
+
work.faceCamera,
|
|
845
|
+
pass,
|
|
846
|
+
environmentCube === undefined
|
|
847
|
+
? undefined
|
|
848
|
+
: resources.textureView(environmentCube.sky).unwrap(),
|
|
849
|
+
);
|
|
850
|
+
const captureContext = {
|
|
851
|
+
...internal,
|
|
852
|
+
...(environmentCube === undefined
|
|
853
|
+
? {}
|
|
854
|
+
: {
|
|
855
|
+
environmentIbl: {
|
|
856
|
+
irradiance: resources.textureView(environmentCube.irradiance).unwrap(),
|
|
857
|
+
prefilter: resources.textureView(environmentCube.prefilter).unwrap(),
|
|
858
|
+
},
|
|
859
|
+
}),
|
|
860
|
+
};
|
|
861
|
+
delete captureContext.reflectionProbes;
|
|
862
|
+
delete captureContext.hdrpSsaoBlurredView;
|
|
863
|
+
delete captureContext.gpuDrivenDrawKeys;
|
|
864
|
+
delete captureContext.gpuDrivenStandardPbrFrameResources;
|
|
686
865
|
encodeMainPass(
|
|
687
866
|
{
|
|
688
|
-
...
|
|
867
|
+
...captureContext,
|
|
868
|
+
dispatch: internal.captureDispatch ?? internal.dispatch,
|
|
869
|
+
foldDispatchPlan: null,
|
|
689
870
|
camera: work.faceCamera,
|
|
690
871
|
viewBindGroupDynamicOffset: work.viewBindGroupDynamicOffset,
|
|
691
872
|
geometryColorView: captureColor.value,
|
|
@@ -787,6 +968,57 @@ export interface RenderFeatureGraphRuntimeState {
|
|
|
787
968
|
>;
|
|
788
969
|
}
|
|
789
970
|
|
|
971
|
+
/** The exact fields that define one validated feature-plan collection. */
|
|
972
|
+
export interface RenderFeaturePlanRevisionEntry {
|
|
973
|
+
readonly featureIdentity: string;
|
|
974
|
+
readonly generation: number;
|
|
975
|
+
readonly signature: string;
|
|
976
|
+
readonly order: number;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
/** Compact graph-owner state for a completely validated feature-plan set. */
|
|
980
|
+
export interface RenderFeaturePlanRevisionState {
|
|
981
|
+
readonly revision: number;
|
|
982
|
+
readonly entries: readonly RenderFeaturePlanRevisionEntry[];
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Advance the plan revision only when the complete canonical plan collection
|
|
987
|
+
* changes. Equality is an exact field comparison; the canonical signatures
|
|
988
|
+
* have already been recomputed by validation before this helper is called.
|
|
989
|
+
*/
|
|
990
|
+
export function updateRenderFeaturePlanRevision(
|
|
991
|
+
previous: RenderFeaturePlanRevisionState,
|
|
992
|
+
plans: readonly RenderFeaturePlannedFrame[],
|
|
993
|
+
executions: readonly RenderFeaturePlanExecution[],
|
|
994
|
+
): RenderFeaturePlanRevisionState {
|
|
995
|
+
if (
|
|
996
|
+
plans.length === previous.entries.length &&
|
|
997
|
+
plans.every((planned, index) => {
|
|
998
|
+
const prior = previous.entries[index];
|
|
999
|
+
return (
|
|
1000
|
+
prior !== undefined &&
|
|
1001
|
+
prior.featureIdentity === planned.featureIdentity &&
|
|
1002
|
+
prior.generation === planned.generation &&
|
|
1003
|
+
prior.signature === planned.signature &&
|
|
1004
|
+
prior.order === (executions[index]?.order ?? -1)
|
|
1005
|
+
);
|
|
1006
|
+
})
|
|
1007
|
+
) {
|
|
1008
|
+
return previous;
|
|
1009
|
+
}
|
|
1010
|
+
const entries = plans.map((planned, index) => ({
|
|
1011
|
+
featureIdentity: planned.featureIdentity,
|
|
1012
|
+
generation: planned.generation,
|
|
1013
|
+
signature: planned.signature,
|
|
1014
|
+
order: executions[index]?.order ?? -1,
|
|
1015
|
+
}));
|
|
1016
|
+
return {
|
|
1017
|
+
revision: previous.revision + 1,
|
|
1018
|
+
entries: Object.freeze(entries),
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
|
|
790
1022
|
/** A frame-local graph candidate that is committed only after compilation. */
|
|
791
1023
|
export interface RenderFeatureGraphCandidate {
|
|
792
1024
|
readonly plans: readonly RenderFeaturePlannedFrame[];
|
|
@@ -795,16 +1027,22 @@ export interface RenderFeatureGraphCandidate {
|
|
|
795
1027
|
import('../fullscreen-post-process-pass').PostProcessShaderEntry
|
|
796
1028
|
>;
|
|
797
1029
|
/**
|
|
798
|
-
* Physical
|
|
799
|
-
*
|
|
800
|
-
* signature is unchanged; otherwise queue retirement
|
|
801
|
-
* still referenced by the memoized graph.
|
|
1030
|
+
* Physical transient graphics resources are imported into the compiled
|
|
1031
|
+
* graph. Their lease therefore needs a new graph even when the declarative
|
|
1032
|
+
* plan signature is unchanged; otherwise queue retirement could destroy a
|
|
1033
|
+
* buffer still referenced by the memoized graph. Retired GPU-work leases are
|
|
1034
|
+
* kept in the completion batch but are not imported by this candidate and do
|
|
1035
|
+
* not require a graph revision on their own.
|
|
802
1036
|
*/
|
|
803
1037
|
readonly preparedResourceKey?: string;
|
|
804
1038
|
/** Release candidate-owned prepared resources when graph promotion fails. */
|
|
805
1039
|
readonly onRejected?: () => void;
|
|
806
1040
|
/** Publish candidate-owned runtime declarations only after graph promotion. */
|
|
807
1041
|
readonly onAccepted?: () => void;
|
|
1042
|
+
/** Consume producer frame state only after the command buffer is submitted. */
|
|
1043
|
+
readonly onSubmitted?: () => void;
|
|
1044
|
+
/** Discard producer frame state after graph execution/submission aborts. */
|
|
1045
|
+
readonly onAborted?: () => void;
|
|
808
1046
|
/** Discard candidate-only resources when a base graph is kept as fallback. */
|
|
809
1047
|
readonly onAbandoned?: () => void;
|
|
810
1048
|
}
|
|
@@ -812,6 +1050,139 @@ export interface RenderFeatureGraphCandidate {
|
|
|
812
1050
|
const featureGraphStates = new WeakMap<RenderSystemInternals, RenderFeatureGraphRuntimeState>();
|
|
813
1051
|
const graphDeviceGenerations = new WeakMap<object, number>();
|
|
814
1052
|
|
|
1053
|
+
interface MutableRenderFeatureGraphInspection {
|
|
1054
|
+
planRevisionState: RenderFeaturePlanRevisionState;
|
|
1055
|
+
signatureValidationCalls: number;
|
|
1056
|
+
signatureValidationBytes: number;
|
|
1057
|
+
signatureValidationChars: number;
|
|
1058
|
+
signatureValidationCpuMs: number;
|
|
1059
|
+
signatureValidationCacheHits: number;
|
|
1060
|
+
signatureValidationCacheMisses: number;
|
|
1061
|
+
ensureCalls: number;
|
|
1062
|
+
reuseHits: number;
|
|
1063
|
+
rebuildAttempts: number;
|
|
1064
|
+
compileAttempts: number;
|
|
1065
|
+
compileSuccesses: number;
|
|
1066
|
+
compileFailures: number;
|
|
1067
|
+
validationFailures: number;
|
|
1068
|
+
buildFailures: number;
|
|
1069
|
+
compileCpuMs: number;
|
|
1070
|
+
candidatesWithPreparedBatches: number;
|
|
1071
|
+
preparedKeyChanges: number;
|
|
1072
|
+
accepted: number;
|
|
1073
|
+
rejected: number;
|
|
1074
|
+
abandoned: number;
|
|
1075
|
+
lastPlanSignature: string;
|
|
1076
|
+
lastTopologyKey: string | undefined;
|
|
1077
|
+
lastPreparedResourceKey: string | undefined;
|
|
1078
|
+
preparedKeyObserved: boolean;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
const featureGraphInspections = new WeakMap<
|
|
1082
|
+
RenderSystemInternals,
|
|
1083
|
+
MutableRenderFeatureGraphInspection
|
|
1084
|
+
>();
|
|
1085
|
+
|
|
1086
|
+
function mutableFeatureGraphInspection(
|
|
1087
|
+
internals: RenderSystemInternals,
|
|
1088
|
+
): MutableRenderFeatureGraphInspection {
|
|
1089
|
+
const existing = featureGraphInspections.get(internals);
|
|
1090
|
+
if (existing !== undefined) return existing;
|
|
1091
|
+
const created: MutableRenderFeatureGraphInspection = {
|
|
1092
|
+
planRevisionState: { revision: 0, entries: [] },
|
|
1093
|
+
signatureValidationCalls: 0,
|
|
1094
|
+
signatureValidationBytes: 0,
|
|
1095
|
+
signatureValidationChars: 0,
|
|
1096
|
+
signatureValidationCpuMs: 0,
|
|
1097
|
+
signatureValidationCacheHits: 0,
|
|
1098
|
+
signatureValidationCacheMisses: 0,
|
|
1099
|
+
ensureCalls: 0,
|
|
1100
|
+
reuseHits: 0,
|
|
1101
|
+
rebuildAttempts: 0,
|
|
1102
|
+
compileAttempts: 0,
|
|
1103
|
+
compileSuccesses: 0,
|
|
1104
|
+
compileFailures: 0,
|
|
1105
|
+
validationFailures: 0,
|
|
1106
|
+
buildFailures: 0,
|
|
1107
|
+
compileCpuMs: 0,
|
|
1108
|
+
candidatesWithPreparedBatches: 0,
|
|
1109
|
+
preparedKeyChanges: 0,
|
|
1110
|
+
accepted: 0,
|
|
1111
|
+
rejected: 0,
|
|
1112
|
+
abandoned: 0,
|
|
1113
|
+
lastPlanSignature: '',
|
|
1114
|
+
lastTopologyKey: undefined,
|
|
1115
|
+
lastPreparedResourceKey: undefined,
|
|
1116
|
+
preparedKeyObserved: false,
|
|
1117
|
+
};
|
|
1118
|
+
featureGraphInspections.set(internals, created);
|
|
1119
|
+
return created;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
export function getRenderFeatureGraphInspection(
|
|
1123
|
+
internals: RenderSystemInternals,
|
|
1124
|
+
): RenderFeatureGraphInspection {
|
|
1125
|
+
const metrics = mutableFeatureGraphInspection(internals);
|
|
1126
|
+
return Object.freeze({
|
|
1127
|
+
planRevision: metrics.planRevisionState.revision,
|
|
1128
|
+
signatureValidationCalls: metrics.signatureValidationCalls,
|
|
1129
|
+
signatureValidationBytes: metrics.signatureValidationBytes,
|
|
1130
|
+
signatureValidationChars: metrics.signatureValidationChars,
|
|
1131
|
+
signatureValidationCpuMs: metrics.signatureValidationCpuMs,
|
|
1132
|
+
signatureValidationCacheHits: metrics.signatureValidationCacheHits,
|
|
1133
|
+
signatureValidationCacheMisses: metrics.signatureValidationCacheMisses,
|
|
1134
|
+
ensureCalls: metrics.ensureCalls,
|
|
1135
|
+
reuseHits: metrics.reuseHits,
|
|
1136
|
+
rebuildAttempts: metrics.rebuildAttempts,
|
|
1137
|
+
compileAttempts: metrics.compileAttempts,
|
|
1138
|
+
compileSuccesses: metrics.compileSuccesses,
|
|
1139
|
+
compileFailures: metrics.compileFailures,
|
|
1140
|
+
validationFailures: metrics.validationFailures,
|
|
1141
|
+
buildFailures: metrics.buildFailures,
|
|
1142
|
+
compileCpuMs: metrics.compileCpuMs,
|
|
1143
|
+
candidatesWithPreparedBatches: metrics.candidatesWithPreparedBatches,
|
|
1144
|
+
preparedKeyChanges: metrics.preparedKeyChanges,
|
|
1145
|
+
accepted: metrics.accepted,
|
|
1146
|
+
rejected: metrics.rejected,
|
|
1147
|
+
abandoned: metrics.abandoned,
|
|
1148
|
+
last: Object.freeze({
|
|
1149
|
+
planSignature: metrics.lastPlanSignature,
|
|
1150
|
+
topologyKey: metrics.lastTopologyKey,
|
|
1151
|
+
preparedResourceKey: metrics.lastPreparedResourceKey,
|
|
1152
|
+
}),
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
export function recordRenderFeatureCandidate(
|
|
1157
|
+
internals: RenderSystemInternals,
|
|
1158
|
+
candidate: RenderFeatureGraphCandidate,
|
|
1159
|
+
): void {
|
|
1160
|
+
const metrics = mutableFeatureGraphInspection(internals);
|
|
1161
|
+
if (
|
|
1162
|
+
metrics.preparedKeyObserved &&
|
|
1163
|
+
metrics.lastPreparedResourceKey !== candidate.preparedResourceKey
|
|
1164
|
+
) {
|
|
1165
|
+
metrics.preparedKeyChanges += 1;
|
|
1166
|
+
}
|
|
1167
|
+
metrics.preparedKeyObserved = true;
|
|
1168
|
+
metrics.lastPreparedResourceKey = candidate.preparedResourceKey;
|
|
1169
|
+
if (candidate.preparedResourceKey !== undefined) {
|
|
1170
|
+
metrics.candidatesWithPreparedBatches += 1;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
function recordRenderFeatureCandidateEvent(
|
|
1175
|
+
internals: RenderSystemInternals,
|
|
1176
|
+
candidate: RenderFeatureGraphCandidate,
|
|
1177
|
+
event: 'accepted' | 'rejected' | 'abandoned',
|
|
1178
|
+
): void {
|
|
1179
|
+
const metrics = mutableFeatureGraphInspection(internals);
|
|
1180
|
+
metrics[event] += 1;
|
|
1181
|
+
if (event === 'accepted') candidate.onAccepted?.();
|
|
1182
|
+
else if (event === 'rejected') candidate.onRejected?.();
|
|
1183
|
+
else candidate.onAbandoned?.();
|
|
1184
|
+
}
|
|
1185
|
+
|
|
815
1186
|
interface TimingInstrumentationState {
|
|
816
1187
|
readonly instrumentation: RenderGraphPassInstrumentation<RenderPipelineFrame>;
|
|
817
1188
|
setCapture(capture: GpuPassTimingCapture | undefined): void;
|
|
@@ -830,6 +1201,11 @@ type CompiledGraphTargetAccess = CompiledRenderGraph<RenderPipelineFrame> & {
|
|
|
830
1201
|
readonly getColorTargetTexture: (name: string) => Texture | undefined;
|
|
831
1202
|
};
|
|
832
1203
|
|
|
1204
|
+
type ResolvedDepthPassExecution =
|
|
1205
|
+
import('@forgeax/engine-render-graph').RenderGraphPassExecution & {
|
|
1206
|
+
readonly resolvedDepthStencilAttachmentView?: TextureView;
|
|
1207
|
+
};
|
|
1208
|
+
|
|
833
1209
|
export function getRenderFeatureGraphState(
|
|
834
1210
|
internals: RenderSystemInternals,
|
|
835
1211
|
): RenderFeatureGraphRuntimeState {
|
|
@@ -899,15 +1275,46 @@ export function resolvePostProcessChainAdmission(
|
|
|
899
1275
|
|
|
900
1276
|
function validateRenderFeaturePlans(
|
|
901
1277
|
plans: readonly RenderFeaturePlannedFrame[],
|
|
1278
|
+
metrics?: MutableRenderFeatureGraphInspection,
|
|
902
1279
|
): Result<readonly RenderFeaturePlanExecution[], RenderError> {
|
|
903
1280
|
const identities = new Set<string>();
|
|
904
1281
|
const projected: RenderFeaturePlanExecution[] = [];
|
|
905
1282
|
let previousOrder = -1;
|
|
906
1283
|
for (const [order, planned] of plans.entries()) {
|
|
907
1284
|
const execution = getRenderFeaturePlanExecutionProjection(planned);
|
|
1285
|
+
const signatureMetrics =
|
|
1286
|
+
metrics === undefined ? undefined : { calls: 0, typedArrayBytes: 0, outputChars: 0 };
|
|
1287
|
+
const started =
|
|
1288
|
+
metrics === undefined
|
|
1289
|
+
? 0
|
|
1290
|
+
: typeof performance === 'undefined'
|
|
1291
|
+
? Date.now()
|
|
1292
|
+
: performance.now();
|
|
1293
|
+
// The host records detached structural evidence, but graph admission must
|
|
1294
|
+
// check it again so a mutation between the two synchronous stages cannot
|
|
1295
|
+
// smuggle a stale plan into the compiled graph. Only candidates without
|
|
1296
|
+
// evidence fall back to the canonical serializer.
|
|
1297
|
+
const signatureCacheHit = renderFeaturePlanSignatureEvidenceMatches(
|
|
1298
|
+
planned.plan,
|
|
1299
|
+
planned.signature,
|
|
1300
|
+
);
|
|
1301
|
+
if (metrics !== undefined) {
|
|
1302
|
+
if (signatureCacheHit) metrics.signatureValidationCacheHits += 1;
|
|
1303
|
+
else metrics.signatureValidationCacheMisses += 1;
|
|
1304
|
+
}
|
|
1305
|
+
const recomputedSignature = signatureCacheHit
|
|
1306
|
+
? planned.signature
|
|
1307
|
+
: renderFeaturePlanSignature(planned.plan, signatureMetrics);
|
|
1308
|
+
if (metrics !== undefined) {
|
|
1309
|
+
const now = typeof performance === 'undefined' ? Date.now() : performance.now();
|
|
1310
|
+
metrics.signatureValidationCalls += signatureMetrics?.calls ?? 0;
|
|
1311
|
+
metrics.signatureValidationBytes += signatureMetrics?.typedArrayBytes ?? 0;
|
|
1312
|
+
metrics.signatureValidationChars += signatureMetrics?.outputChars ?? 0;
|
|
1313
|
+
metrics.signatureValidationCpuMs += now - started;
|
|
1314
|
+
}
|
|
908
1315
|
if (
|
|
909
1316
|
identities.has(planned.featureIdentity) ||
|
|
910
|
-
planned.signature !==
|
|
1317
|
+
planned.signature !== recomputedSignature ||
|
|
911
1318
|
execution === undefined ||
|
|
912
1319
|
execution.featureIdentity !== planned.featureIdentity ||
|
|
913
1320
|
execution.order <= previousOrder
|
|
@@ -930,7 +1337,7 @@ function commitFeatureCandidate(
|
|
|
930
1337
|
// Publish renderer-owned declarations only after their device resources have
|
|
931
1338
|
// been admitted. If the acceptance hook throws, the previously accepted
|
|
932
1339
|
// graph/state pair remains visible to the caller.
|
|
933
|
-
candidate
|
|
1340
|
+
recordRenderFeatureCandidateEvent(internals, candidate, 'accepted');
|
|
934
1341
|
const state = getRenderFeatureGraphState(internals);
|
|
935
1342
|
state.plans = candidate.plans;
|
|
936
1343
|
state.fullscreenEffects = candidate.fullscreenEffects;
|
|
@@ -948,10 +1355,13 @@ function topologyOf(
|
|
|
948
1355
|
shadowMapSize: number | undefined,
|
|
949
1356
|
gpuDriven: PreparedGpuDrivenFrame | undefined,
|
|
950
1357
|
featureGraphCandidate: RenderFeatureGraphCandidate | undefined,
|
|
1358
|
+
featurePlanRevision: number,
|
|
951
1359
|
cubeCaptureState: CubeCaptureGraphState | undefined,
|
|
952
1360
|
transmissionDemand: TransmissionDemand | undefined,
|
|
953
1361
|
volumetricFog: ExtractedVolumetricFog | undefined,
|
|
954
1362
|
standardLighting: StandardTopologyInputValue | undefined,
|
|
1363
|
+
ssr: SsrSpatialAdmission | undefined,
|
|
1364
|
+
renderExtent: RenderExtent | undefined,
|
|
955
1365
|
): Result<RenderPipelineTopology, RhiError> {
|
|
956
1366
|
const cascadeCount = Math.max(1, Math.min(4, Math.round(lights.cascadeCount ?? 1))) as
|
|
957
1367
|
| 1
|
|
@@ -1007,12 +1417,16 @@ function topologyOf(
|
|
|
1007
1417
|
: volumetricFog?.lightKind === undefined
|
|
1008
1418
|
? lights.directional
|
|
1009
1419
|
: undefined;
|
|
1420
|
+
const preparedLut =
|
|
1421
|
+
frameState.pendingStandardLutGpuResources ?? frameState.standardLutGpuResources;
|
|
1010
1422
|
return ok({
|
|
1011
1423
|
pipelineId: STANDARD_PIPELINE_ID,
|
|
1012
1424
|
standardProfile: internals.standardProfile,
|
|
1013
1425
|
config,
|
|
1014
1426
|
clearOnly,
|
|
1015
1427
|
reflectionFallback: { enabled: frameState.reflectionFallbackDemand === true },
|
|
1428
|
+
ssr,
|
|
1429
|
+
...(renderExtent === undefined ? {} : { extent: renderExtent }),
|
|
1016
1430
|
surface: {
|
|
1017
1431
|
width,
|
|
1018
1432
|
height,
|
|
@@ -1025,6 +1439,27 @@ function topologyOf(
|
|
|
1025
1439
|
antialias: camera.antialias,
|
|
1026
1440
|
bloom: camera.bloom,
|
|
1027
1441
|
},
|
|
1442
|
+
atmosphere: !clearOnly && frameState.environmentFrame?.source.kind === 'atmosphere',
|
|
1443
|
+
output: {
|
|
1444
|
+
autoExposure:
|
|
1445
|
+
!clearOnly &&
|
|
1446
|
+
camera.output?.exposure.kind === 'auto' &&
|
|
1447
|
+
(frameState.pendingAutoExposureGpuResources ?? frameState.autoExposureGpuResources) !==
|
|
1448
|
+
undefined,
|
|
1449
|
+
whiteBalance:
|
|
1450
|
+
!clearOnly &&
|
|
1451
|
+
camera.output !== undefined &&
|
|
1452
|
+
(camera.output.temperature !== 6504 || camera.output.tint !== 0),
|
|
1453
|
+
temperature: camera.output?.temperature ?? 6504,
|
|
1454
|
+
tint: camera.output?.tint ?? 0,
|
|
1455
|
+
colorLut:
|
|
1456
|
+
!clearOnly &&
|
|
1457
|
+
(camera.output?.colorLutStrength ?? 0) > 0 &&
|
|
1458
|
+
(frameState.pendingStandardLutGpuResources ?? frameState.standardLutGpuResources) !==
|
|
1459
|
+
undefined,
|
|
1460
|
+
colorLutStrength: camera.output?.colorLutStrength ?? 0,
|
|
1461
|
+
...(preparedLut === undefined ? {} : { lutSourceKey: preparedLut.sourceKey }),
|
|
1462
|
+
},
|
|
1028
1463
|
temporal: {
|
|
1029
1464
|
taa: camera.antialias === 'taa',
|
|
1030
1465
|
motionBlur: isMotionBlurTemporalDemand(camera.motionBlur),
|
|
@@ -1092,9 +1527,7 @@ function topologyOf(
|
|
|
1092
1527
|
maxColorAttachments: internals.device.caps.maxColorAttachments,
|
|
1093
1528
|
},
|
|
1094
1529
|
featureTopologySignature: JSON.stringify({
|
|
1095
|
-
|
|
1096
|
-
featureGraphCandidate?.plans ?? getRenderFeatureGraphState(internals).plans,
|
|
1097
|
-
),
|
|
1530
|
+
planRevision: featurePlanRevision,
|
|
1098
1531
|
fullscreenEffects: featurePostEffectDeclarations,
|
|
1099
1532
|
preparedResourceKey: featureGraphCandidate?.preparedResourceKey ?? '',
|
|
1100
1533
|
cubeCaptureSlots: cubeCaptureState?.work.length ?? 0,
|
|
@@ -1263,7 +1696,9 @@ function resolveTargetBindings(
|
|
|
1263
1696
|
frame.runtime as RenderSystemInternals,
|
|
1264
1697
|
frame.frameState,
|
|
1265
1698
|
frame.pipelineState,
|
|
1266
|
-
|
|
1699
|
+
// This callback is reached only for an actual feature draw. A scene
|
|
1700
|
+
// containing only particles still needs the pipeline's View/light ABI.
|
|
1701
|
+
true,
|
|
1267
1702
|
frame.bindGroupCounts,
|
|
1268
1703
|
{
|
|
1269
1704
|
directionalShadow: frame.frameState.currentDirectionalShadowView ?? undefined,
|
|
@@ -1350,23 +1785,42 @@ export function ensureCompiledFrameGraph(
|
|
|
1350
1785
|
volumeTopologyCandidate = false,
|
|
1351
1786
|
standardLighting?: StandardTopologyInputValue,
|
|
1352
1787
|
onRecoveryError?: (error: unknown) => void,
|
|
1788
|
+
ssr?: SsrSpatialAdmission,
|
|
1789
|
+
renderExtent?: RenderExtent,
|
|
1353
1790
|
): CompiledRenderGraph<RenderPipelineFrame> | null {
|
|
1791
|
+
const featureMetrics = mutableFeatureGraphInspection(internals);
|
|
1792
|
+
featureMetrics.ensureCalls += 1;
|
|
1354
1793
|
const requestedStandardLightingSignature = standardLightingTopologySignature(standardLighting);
|
|
1355
1794
|
const lastKnownGood = (): CompiledRenderGraph<RenderPipelineFrame> | null =>
|
|
1356
1795
|
frameState.compiledFrameGraph !== null &&
|
|
1796
|
+
!hasSubmissionSensitiveFeatures(getRenderFeatureGraphState(internals).plans) &&
|
|
1357
1797
|
frameState.standardLightingGraphSignature === requestedStandardLightingSignature
|
|
1358
1798
|
? frameState.compiledFrameGraph
|
|
1359
1799
|
: null;
|
|
1360
1800
|
const surfaceWidth = Math.max(1, width);
|
|
1361
1801
|
const surfaceHeight = Math.max(1, height);
|
|
1362
1802
|
const featurePlans = featureGraphCandidate?.plans ?? getRenderFeatureGraphState(internals).plans;
|
|
1363
|
-
const projectedFeaturePlans = validateRenderFeaturePlans(featurePlans);
|
|
1803
|
+
const projectedFeaturePlans = validateRenderFeaturePlans(featurePlans, featureMetrics);
|
|
1364
1804
|
if (!projectedFeaturePlans.ok) {
|
|
1805
|
+
featureMetrics.validationFailures += 1;
|
|
1365
1806
|
onRecoveryError?.(projectedFeaturePlans.error);
|
|
1366
1807
|
reportRenderFeatureGraphError(internals, projectedFeaturePlans.error);
|
|
1367
|
-
featureGraphCandidate
|
|
1808
|
+
if (featureGraphCandidate !== undefined) {
|
|
1809
|
+
recordRenderFeatureCandidateEvent(internals, featureGraphCandidate, 'rejected');
|
|
1810
|
+
}
|
|
1368
1811
|
return volumeTopologyCandidate ? null : lastKnownGood();
|
|
1369
1812
|
}
|
|
1813
|
+
const nextPlanRevision = updateRenderFeaturePlanRevision(
|
|
1814
|
+
featureMetrics.planRevisionState,
|
|
1815
|
+
featurePlans,
|
|
1816
|
+
projectedFeaturePlans.value,
|
|
1817
|
+
);
|
|
1818
|
+
if (nextPlanRevision !== featureMetrics.planRevisionState) {
|
|
1819
|
+
featureMetrics.lastPlanSignature = nextPlanRevision.entries
|
|
1820
|
+
.map((entry) => `${entry.featureIdentity}:${entry.signature}`)
|
|
1821
|
+
.join('|');
|
|
1822
|
+
featureMetrics.planRevisionState = nextPlanRevision;
|
|
1823
|
+
}
|
|
1370
1824
|
const topologyResult = topologyOf(
|
|
1371
1825
|
internals,
|
|
1372
1826
|
frameState,
|
|
@@ -1379,15 +1833,21 @@ export function ensureCompiledFrameGraph(
|
|
|
1379
1833
|
shadowMapSize,
|
|
1380
1834
|
gpuDriven,
|
|
1381
1835
|
featureGraphCandidate,
|
|
1836
|
+
featureMetrics.planRevisionState.revision,
|
|
1382
1837
|
cubeCaptureState,
|
|
1383
1838
|
transmissionDemand,
|
|
1384
1839
|
volumetricFog,
|
|
1385
1840
|
standardLighting,
|
|
1841
|
+
ssr,
|
|
1842
|
+
renderExtent,
|
|
1386
1843
|
);
|
|
1387
1844
|
if (!topologyResult.ok) {
|
|
1845
|
+
featureMetrics.buildFailures += 1;
|
|
1388
1846
|
onRecoveryError?.(topologyResult.error);
|
|
1389
1847
|
internals.errorRegistry.fire(topologyResult.error);
|
|
1390
|
-
featureGraphCandidate
|
|
1848
|
+
if (featureGraphCandidate !== undefined) {
|
|
1849
|
+
recordRenderFeatureCandidateEvent(internals, featureGraphCandidate, 'rejected');
|
|
1850
|
+
}
|
|
1391
1851
|
return volumeTopologyCandidate ? null : lastKnownGood();
|
|
1392
1852
|
}
|
|
1393
1853
|
const requestedPostEffects = topologyResult.value.config?.postEffects ?? [];
|
|
@@ -1416,7 +1876,7 @@ export function ensureCompiledFrameGraph(
|
|
|
1416
1876
|
getPipeline(
|
|
1417
1877
|
identity,
|
|
1418
1878
|
built.bindGroupLayout,
|
|
1419
|
-
topologyResult.value.surface.storageFormat as GPUTextureFormat,
|
|
1879
|
+
[topologyResult.value.surface.storageFormat as GPUTextureFormat],
|
|
1420
1880
|
entry,
|
|
1421
1881
|
) !== null
|
|
1422
1882
|
);
|
|
@@ -1427,7 +1887,9 @@ export function ensureCompiledFrameGraph(
|
|
|
1427
1887
|
// Do not publish a candidate whose fullscreen chain is only partially
|
|
1428
1888
|
// ready. Keep the accepted graph (including its prior post-effect chain)
|
|
1429
1889
|
// and retry the same feature candidate on the next frame.
|
|
1430
|
-
featureGraphCandidate
|
|
1890
|
+
if (featureGraphCandidate !== undefined) {
|
|
1891
|
+
recordRenderFeatureCandidateEvent(internals, featureGraphCandidate, 'rejected');
|
|
1892
|
+
}
|
|
1431
1893
|
return acceptedLkg;
|
|
1432
1894
|
}
|
|
1433
1895
|
const topology = postProcessAdmission.pending
|
|
@@ -1441,6 +1903,12 @@ export function ensureCompiledFrameGraph(
|
|
|
1441
1903
|
: topologyResult.value;
|
|
1442
1904
|
const key = JSON.stringify({
|
|
1443
1905
|
topology,
|
|
1906
|
+
// Observation domains are an explicit per-frame graph demand. They are
|
|
1907
|
+
// part of the cache identity so a request made after the ordinary graph
|
|
1908
|
+
// was compiled can admit the matching tone/output capture boundaries on
|
|
1909
|
+
// that receipt without forcing every unobserved frame onto the split
|
|
1910
|
+
// output path.
|
|
1911
|
+
observationCaptureDomains: [...(internals.observationCaptureDomains ?? [])].sort(),
|
|
1444
1912
|
// GPU-driven residency can become available after the first record pass
|
|
1445
1913
|
// (custom mesh handles are resolved into the per-frame projection). The
|
|
1446
1914
|
// topology signature alone is intentionally stable across that lifecycle,
|
|
@@ -1461,11 +1929,13 @@ export function ensureCompiledFrameGraph(
|
|
|
1461
1929
|
]),
|
|
1462
1930
|
});
|
|
1463
1931
|
if (frameState.compiledFrameGraph !== null && frameState.compiledFrameGraphTopologyKey === key) {
|
|
1932
|
+
featureMetrics.reuseHits += 1;
|
|
1933
|
+
featureMetrics.lastTopologyKey = key;
|
|
1464
1934
|
frameState.standardLightingGraphSignature = requestedStandardLightingSignature;
|
|
1465
1935
|
if (featureGraphCandidate !== undefined && !postProcessAdmission.pending) {
|
|
1466
1936
|
commitFeatureCandidate(internals, featureGraphCandidate);
|
|
1467
1937
|
} else if (featureGraphCandidate !== undefined) {
|
|
1468
|
-
featureGraphCandidate
|
|
1938
|
+
recordRenderFeatureCandidateEvent(internals, featureGraphCandidate, 'abandoned');
|
|
1469
1939
|
}
|
|
1470
1940
|
// A candidate flag only describes a possible topology replacement. When
|
|
1471
1941
|
// the derived key is unchanged there is no replacement to stage: reuse the
|
|
@@ -1474,17 +1944,120 @@ export function ensureCompiledFrameGraph(
|
|
|
1474
1944
|
return frameState.compiledFrameGraph;
|
|
1475
1945
|
}
|
|
1476
1946
|
|
|
1947
|
+
featureMetrics.rebuildAttempts += 1;
|
|
1948
|
+
featureMetrics.lastTopologyKey = key;
|
|
1949
|
+
const discardPendingStandardOutput = (): void => {
|
|
1950
|
+
if (frameState.pendingAutoExposureGpuResources !== undefined) {
|
|
1951
|
+
retireAutoExposureGpuResources(frameState.pendingAutoExposureGpuResources);
|
|
1952
|
+
frameState.pendingAutoExposureGpuResources = undefined;
|
|
1953
|
+
}
|
|
1954
|
+
if (frameState.pendingStandardLutGpuResources !== undefined) {
|
|
1955
|
+
retireStandardLutGpuResources(frameState.pendingStandardLutGpuResources);
|
|
1956
|
+
frameState.pendingStandardLutGpuResources = undefined;
|
|
1957
|
+
}
|
|
1958
|
+
};
|
|
1477
1959
|
const builder = new RenderGraphBuilder<RenderPipelineFrame>();
|
|
1960
|
+
const autoExposureResources =
|
|
1961
|
+
topology.output?.autoExposure === true ? importAutoExposureGraphResources(builder) : undefined;
|
|
1962
|
+
if (autoExposureResources !== undefined && !autoExposureResources.ok) {
|
|
1963
|
+
internals.errorRegistry.fire(autoExposureResources.error);
|
|
1964
|
+
featureGraphCandidate?.onRejected?.();
|
|
1965
|
+
discardPendingStandardOutput();
|
|
1966
|
+
return lastKnownGood();
|
|
1967
|
+
}
|
|
1968
|
+
const lutResources =
|
|
1969
|
+
topology.output?.colorLut === true
|
|
1970
|
+
? (() => {
|
|
1971
|
+
const prepared =
|
|
1972
|
+
frameState.pendingStandardLutGpuResources ?? frameState.standardLutGpuResources;
|
|
1973
|
+
if (prepared === undefined) return undefined;
|
|
1974
|
+
const texture = builder.importTexture(
|
|
1975
|
+
'standard-color-lut-source',
|
|
1976
|
+
{
|
|
1977
|
+
format: 'rgba16float',
|
|
1978
|
+
size: {
|
|
1979
|
+
width: prepared.size,
|
|
1980
|
+
height: prepared.size,
|
|
1981
|
+
depthOrArrayLayers: prepared.size,
|
|
1982
|
+
},
|
|
1983
|
+
dimension: '3d',
|
|
1984
|
+
usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING,
|
|
1985
|
+
},
|
|
1986
|
+
(frame) =>
|
|
1987
|
+
(
|
|
1988
|
+
(frame as _InternalRenderPipelineContext).frameState
|
|
1989
|
+
.pendingStandardLutGpuResources ??
|
|
1990
|
+
(frame as _InternalRenderPipelineContext).frameState.standardLutGpuResources
|
|
1991
|
+
)?.texture ?? prepared.texture,
|
|
1992
|
+
);
|
|
1993
|
+
if (!texture.ok) return texture;
|
|
1994
|
+
const view = builder.importView(
|
|
1995
|
+
texture.value,
|
|
1996
|
+
{ label: 'standard-color-lut-source.view', dimension: '3d' },
|
|
1997
|
+
(frame) =>
|
|
1998
|
+
(
|
|
1999
|
+
(frame as _InternalRenderPipelineContext).frameState
|
|
2000
|
+
.pendingStandardLutGpuResources ??
|
|
2001
|
+
(frame as _InternalRenderPipelineContext).frameState.standardLutGpuResources
|
|
2002
|
+
)?.view ?? prepared.view,
|
|
2003
|
+
);
|
|
2004
|
+
if (!view.ok) return view;
|
|
2005
|
+
return ok({ texture: texture.value, view: view.value, prepared });
|
|
2006
|
+
})()
|
|
2007
|
+
: undefined;
|
|
2008
|
+
if (lutResources !== undefined && !lutResources.ok) {
|
|
2009
|
+
internals.errorRegistry.fire(lutResources.error);
|
|
2010
|
+
featureGraphCandidate?.onRejected?.();
|
|
2011
|
+
discardPendingStandardOutput();
|
|
2012
|
+
return lastKnownGood();
|
|
2013
|
+
}
|
|
1478
2014
|
const taaHistory = camera.antialias === 'taa' ? importTemporalHistoryTargets(builder) : undefined;
|
|
2015
|
+
const targetCoverage =
|
|
2016
|
+
camera.dynamicResolution === undefined || topology.extent === undefined
|
|
2017
|
+
? undefined
|
|
2018
|
+
: createTargetCoverageAttachment(builder, topology.extent);
|
|
2019
|
+
if (targetCoverage !== undefined && !targetCoverage.ok) {
|
|
2020
|
+
internals.errorRegistry.fire(targetCoverage.error);
|
|
2021
|
+
featureGraphCandidate?.onRejected?.();
|
|
2022
|
+
discardPendingStandardOutput();
|
|
2023
|
+
return lastKnownGood();
|
|
2024
|
+
}
|
|
2025
|
+
const ssrHistory = ssr?.status === 'admitted' ? importSsrHistoryTargets(builder) : undefined;
|
|
1479
2026
|
let projectedFeatures = false;
|
|
2027
|
+
const featureProjection = createRenderFeatureProjectionState();
|
|
2028
|
+
let featureShadows:
|
|
2029
|
+
| ReturnType<typeof projectRenderFeatureShadows<RenderPipelineFrame>>
|
|
2030
|
+
| undefined;
|
|
1480
2031
|
let projectedGpuDriven = false;
|
|
1481
2032
|
const built = frameState.activePipeline.build(
|
|
1482
2033
|
{
|
|
1483
2034
|
graph: builder,
|
|
2035
|
+
observationCaptureDomains: internals.observationCaptureDomains,
|
|
2036
|
+
...(autoExposureResources?.ok === true
|
|
2037
|
+
? { standardOutput: { autoExposure: autoExposureResources.value } }
|
|
2038
|
+
: {}),
|
|
2039
|
+
...(lutResources?.ok === true
|
|
2040
|
+
? {
|
|
2041
|
+
standardOutput: {
|
|
2042
|
+
...(autoExposureResources?.ok === true
|
|
2043
|
+
? { autoExposure: autoExposureResources.value }
|
|
2044
|
+
: {}),
|
|
2045
|
+
colorLut: {
|
|
2046
|
+
view: lutResources.value.view,
|
|
2047
|
+
sampler: lutResources.value.prepared.sampler,
|
|
2048
|
+
strength: lutResources.value.prepared.strength,
|
|
2049
|
+
bindGroupLayout: lutResources.value.prepared.bindGroupLayout,
|
|
2050
|
+
bindGroup: lutResources.value.prepared.bindGroup,
|
|
2051
|
+
},
|
|
2052
|
+
},
|
|
2053
|
+
}
|
|
2054
|
+
: {}),
|
|
1484
2055
|
...(standardLighting === undefined ? {} : { standardLighting }),
|
|
1485
2056
|
capabilities: { rgba16floatRenderable: internals.device.caps.rgba16floatRenderable },
|
|
1486
2057
|
...(occlusion === undefined ? {} : { occlusion }),
|
|
1487
2058
|
...(taaHistory === undefined ? {} : { taaHistory }),
|
|
2059
|
+
...(targetCoverage?.ok === true ? { targetCoverage: targetCoverage.value } : {}),
|
|
2060
|
+
...(ssrHistory === undefined ? {} : { ssrHistory }),
|
|
1488
2061
|
encodeTransmissionMip: ({ pass, resources, source }) => {
|
|
1489
2062
|
const sourceView = resources.textureView(source);
|
|
1490
2063
|
if (!sourceView.ok) throw sourceView.error;
|
|
@@ -1494,24 +2067,69 @@ export function ensureCompiledFrameGraph(
|
|
|
1494
2067
|
projectGpuDriven: (target) => {
|
|
1495
2068
|
if (projectedGpuDriven || gpuDriven === undefined) return ok(undefined);
|
|
1496
2069
|
projectedGpuDriven = true;
|
|
1497
|
-
return gpuDriven.project(
|
|
2070
|
+
return gpuDriven.project(
|
|
2071
|
+
builder,
|
|
2072
|
+
target.format,
|
|
2073
|
+
target.sampleCount,
|
|
2074
|
+
target.additionalColorFormats,
|
|
2075
|
+
);
|
|
1498
2076
|
},
|
|
1499
|
-
|
|
2077
|
+
...(gpuDriven?.projectShadow === undefined
|
|
2078
|
+
? {}
|
|
2079
|
+
: {
|
|
2080
|
+
projectGpuDrivenShadow: (identity) =>
|
|
2081
|
+
gpuDriven.projectShadow?.(builder, identity) ?? ok(undefined),
|
|
2082
|
+
}),
|
|
2083
|
+
contributeShadowFeatures: () =>
|
|
2084
|
+
(featureShadows ??= projectRenderFeatureShadows(
|
|
2085
|
+
builder,
|
|
2086
|
+
projectedFeaturePlans.value,
|
|
2087
|
+
featureProjection,
|
|
2088
|
+
)),
|
|
2089
|
+
contributeFeatures: (
|
|
2090
|
+
targets,
|
|
2091
|
+
semanticTargets = [],
|
|
2092
|
+
namedTargets = {},
|
|
2093
|
+
standardSurfaceAccesses = [],
|
|
2094
|
+
) => {
|
|
1500
2095
|
if (projectedFeatures) return ok(undefined);
|
|
1501
2096
|
projectedFeatures = true;
|
|
1502
2097
|
if (projectedFeaturePlans.value.length === 0) return ok(undefined);
|
|
1503
2098
|
const resolveTarget = targetResolver(targets, semanticTargets, namedTargets);
|
|
1504
2099
|
const projected = projectPlanExecutions(builder, projectedFeaturePlans.value, {
|
|
2100
|
+
state: featureProjection,
|
|
1505
2101
|
resolveTarget,
|
|
2102
|
+
standardSurfaceAccesses,
|
|
1506
2103
|
resolveBindings: (input) => resolveTargetBindings(input, featurePostProcessEntries),
|
|
2104
|
+
resolveStandardLighting: (frame, pipeline) => {
|
|
2105
|
+
const context = frame as import('./render-context')._InternalRenderPipelineContext;
|
|
2106
|
+
if (context.standardLighting?.kind !== 'clustered') return undefined;
|
|
2107
|
+
const layout = (
|
|
2108
|
+
pipeline as RenderPipeline & {
|
|
2109
|
+
getBindGroupLayout?: (index: number) => BindGroupLayout;
|
|
2110
|
+
}
|
|
2111
|
+
).getBindGroupLayout?.(2);
|
|
2112
|
+
if (layout === undefined) return undefined;
|
|
2113
|
+
return (
|
|
2114
|
+
createStandardSurfaceLightingBindGroup(
|
|
2115
|
+
context.runtime,
|
|
2116
|
+
layout,
|
|
2117
|
+
context.standardLighting.prepared.layout.grid,
|
|
2118
|
+
context.hdrpSsaoBlurredView === undefined
|
|
2119
|
+
? { enabled: false }
|
|
2120
|
+
: { enabled: true, ssaoBlurredView: context.hdrpSsaoBlurredView },
|
|
2121
|
+
) ?? undefined
|
|
2122
|
+
);
|
|
2123
|
+
},
|
|
1507
2124
|
reportError: (error) => reportRenderFeatureGraphError(internals, error),
|
|
1508
2125
|
});
|
|
1509
2126
|
return projected.ok ? ok(undefined) : projected;
|
|
1510
2127
|
},
|
|
1511
|
-
contributeCubeCaptures: () => {
|
|
2128
|
+
contributeCubeCaptures: (environmentCube) => {
|
|
1512
2129
|
const reflectionProbes = addReflectionProbeGraphPasses(
|
|
1513
2130
|
builder,
|
|
1514
2131
|
cubeCaptureState?.reflectionProbes ?? { work: [] },
|
|
2132
|
+
environmentCube,
|
|
1515
2133
|
);
|
|
1516
2134
|
if (!reflectionProbes.ok) return reflectionProbes;
|
|
1517
2135
|
return cubeCaptureState === undefined
|
|
@@ -1524,19 +2142,33 @@ export function ensureCompiledFrameGraph(
|
|
|
1524
2142
|
topology,
|
|
1525
2143
|
);
|
|
1526
2144
|
if (!built.ok) {
|
|
2145
|
+
featureMetrics.buildFailures += 1;
|
|
1527
2146
|
onRecoveryError?.(built.error);
|
|
1528
2147
|
internals.errorRegistry.fire(built.error);
|
|
1529
2148
|
featureGraphCandidate?.onRejected?.();
|
|
2149
|
+
discardPendingStandardOutput();
|
|
2150
|
+
if (featureGraphCandidate !== undefined) {
|
|
2151
|
+
recordRenderFeatureCandidateEvent(internals, featureGraphCandidate, 'rejected');
|
|
2152
|
+
}
|
|
1530
2153
|
return volumeTopologyCandidate ? null : lastKnownGood();
|
|
1531
2154
|
}
|
|
2155
|
+
featureMetrics.compileAttempts += 1;
|
|
2156
|
+
const compileStarted = typeof performance === 'undefined' ? Date.now() : performance.now();
|
|
1532
2157
|
const compiled = builder.compile({
|
|
1533
2158
|
device: internals.device,
|
|
1534
2159
|
surfaceSize: { width: surfaceWidth, height: surfaceHeight },
|
|
1535
2160
|
});
|
|
2161
|
+
featureMetrics.compileCpuMs +=
|
|
2162
|
+
(typeof performance === 'undefined' ? Date.now() : performance.now()) - compileStarted;
|
|
1536
2163
|
if (!compiled.ok) {
|
|
2164
|
+
featureMetrics.compileFailures += 1;
|
|
1537
2165
|
onRecoveryError?.(compiled.error);
|
|
1538
2166
|
internals.errorRegistry.fire(compiled.error);
|
|
1539
2167
|
featureGraphCandidate?.onRejected?.();
|
|
2168
|
+
discardPendingStandardOutput();
|
|
2169
|
+
if (featureGraphCandidate !== undefined) {
|
|
2170
|
+
recordRenderFeatureCandidateEvent(internals, featureGraphCandidate, 'rejected');
|
|
2171
|
+
}
|
|
1540
2172
|
return lastKnownGood();
|
|
1541
2173
|
}
|
|
1542
2174
|
const previous = frameState.compiledFrameGraph;
|
|
@@ -1551,21 +2183,31 @@ export function ensureCompiledFrameGraph(
|
|
|
1551
2183
|
frameState.compiledFrameGraphGeneration += 1;
|
|
1552
2184
|
const compiledTargets = compiled.value as CompiledGraphTargetAccess;
|
|
1553
2185
|
frameState.graphGeneration += 1;
|
|
2186
|
+
featureMetrics.compileSuccesses += 1;
|
|
1554
2187
|
frameState.perFrameGraph = {
|
|
1555
2188
|
getColorTargetDescriptor: (name) => compiledTargets.getColorTargetDescriptor(name),
|
|
1556
2189
|
getColorTargetView: (name) => compiledTargets.getColorTargetView(name),
|
|
1557
2190
|
getColorTargetTexture: (name) => compiledTargets.getColorTargetTexture(name),
|
|
1558
2191
|
graphGeneration: frameState.graphGeneration,
|
|
1559
2192
|
};
|
|
2193
|
+
// View buffer replacement is safe to retire once the compiled graph owns
|
|
2194
|
+
// the new imports. Shadow cache publication remains submit-transactional
|
|
2195
|
+
// and is committed only by executeCompiledFrameGraph's onSubmitted hook.
|
|
2196
|
+
if (gpuDriven?._commitGpuResourceReplacement !== undefined) {
|
|
2197
|
+
gpuDriven._commitGpuResourceReplacement();
|
|
2198
|
+
} else {
|
|
2199
|
+
// Synthetic/internal prepared projections predating the split own no
|
|
2200
|
+
// shadow cache; retain their original graph-promotion callback.
|
|
2201
|
+
gpuDriven?._commitResourceReplacement();
|
|
2202
|
+
}
|
|
1560
2203
|
const deviceGeneration = internals.deviceScope?.generation;
|
|
1561
2204
|
if (deviceGeneration !== undefined) {
|
|
1562
2205
|
graphDeviceGenerations.set(compiled.value, deviceGeneration);
|
|
1563
2206
|
}
|
|
1564
|
-
gpuDriven?._commitResourceReplacement();
|
|
1565
2207
|
if (featureGraphCandidate !== undefined && !postProcessAdmission.pending) {
|
|
1566
2208
|
commitFeatureCandidate(internals, featureGraphCandidate);
|
|
1567
2209
|
} else if (featureGraphCandidate !== undefined) {
|
|
1568
|
-
featureGraphCandidate
|
|
2210
|
+
recordRenderFeatureCandidateEvent(internals, featureGraphCandidate, 'abandoned');
|
|
1569
2211
|
}
|
|
1570
2212
|
if (!volumeTopologyCandidate && previous !== null) retire(frameState, previous);
|
|
1571
2213
|
return compiled.value;
|
|
@@ -1577,15 +2219,21 @@ export function executeCompiledFrameGraph(
|
|
|
1577
2219
|
frame: RenderPipelineFrame,
|
|
1578
2220
|
encoder: RhiCommandEncoder,
|
|
1579
2221
|
runPass?: import('@forgeax/engine-render-graph').RenderGraphPassRunner,
|
|
1580
|
-
frameHooks?:
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
2222
|
+
frameHooks?:
|
|
2223
|
+
| {
|
|
2224
|
+
readonly afterGraphExecute?: () => Result<void, RhiError>;
|
|
2225
|
+
readonly onSubmitted?: () => void;
|
|
2226
|
+
readonly onAborted?: () => void;
|
|
2227
|
+
}
|
|
2228
|
+
// Keep the pre-submit-hook shape accepted for internal callers that have
|
|
2229
|
+
// not yet migrated to the typed frame hooks object.
|
|
2230
|
+
| (() => void),
|
|
1585
2231
|
readbackFaces?: readonly number[],
|
|
1586
2232
|
onSubmitted?: (completed: Promise<unknown>) => void,
|
|
1587
2233
|
timingCapture?: GpuTimingCapture,
|
|
1588
2234
|
): boolean {
|
|
2235
|
+
const legacySubmitCommit = typeof frameHooks === 'function' ? frameHooks : undefined;
|
|
2236
|
+
const resolvedFrameHooks = typeof frameHooks === 'function' ? undefined : frameHooks;
|
|
1589
2237
|
const graph = frameState.compiledFrameGraph;
|
|
1590
2238
|
const rejectTemporalFrame = (): void => {
|
|
1591
2239
|
if (frameState.temporalFrameInput === undefined) return;
|
|
@@ -1594,6 +2242,8 @@ export function executeCompiledFrameGraph(
|
|
|
1594
2242
|
};
|
|
1595
2243
|
if (graph === null) {
|
|
1596
2244
|
timingCapture?.discard();
|
|
2245
|
+
frameState.pendingAutoExposureState = undefined;
|
|
2246
|
+
frameState.pendingStandardLutState = undefined;
|
|
1597
2247
|
settleVolumetricFogGraphCandidate(frameState, false);
|
|
1598
2248
|
rejectTemporalFrame();
|
|
1599
2249
|
return false;
|
|
@@ -1664,14 +2314,327 @@ export function executeCompiledFrameGraph(
|
|
|
1664
2314
|
const transaction = executeRendererFrameTransaction<PreparedCommand>({
|
|
1665
2315
|
build: () => ({ ok: true, value: { command: undefined as never } }),
|
|
1666
2316
|
execute: () => {
|
|
1667
|
-
const
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
2317
|
+
const graphCapture = frameState.graphTargetCapture;
|
|
2318
|
+
const replayPassNames = graphCapture?.replayPassNames;
|
|
2319
|
+
const unsupportedCaptureKind =
|
|
2320
|
+
graphCapture !== undefined &&
|
|
2321
|
+
graphCapture.kind !== undefined &&
|
|
2322
|
+
graphCapture.kind !== 'target-copy' &&
|
|
2323
|
+
graphCapture.kind !== 'pass-replay';
|
|
2324
|
+
if (unsupportedCaptureKind || replayPassNames !== undefined) {
|
|
2325
|
+
if (graphCapture === undefined) {
|
|
2326
|
+
return { ok: false, stage: 'execute' };
|
|
2327
|
+
}
|
|
2328
|
+
const passNames = graph.inspect().passes.map((pass) => pass.name);
|
|
2329
|
+
const passNameCounts = new Map<string, number>();
|
|
2330
|
+
for (const passName of passNames) {
|
|
2331
|
+
passNameCounts.set(passName, (passNameCounts.get(passName) ?? 0) + 1);
|
|
2332
|
+
}
|
|
2333
|
+
const passNameSet = new Set(passNames);
|
|
2334
|
+
const selectedReplayPassNames = replayPassNames ?? [];
|
|
2335
|
+
const requestedPassNames = new Set(selectedReplayPassNames);
|
|
2336
|
+
const passReplayCapture = graphCapture.kind === 'pass-replay' ? graphCapture : undefined;
|
|
2337
|
+
const onPassEncoded = passReplayCapture?.onPassEncoded;
|
|
2338
|
+
const onPrefixEncoded = passReplayCapture?.onPrefixEncoded;
|
|
2339
|
+
const depthAttachmentPassName = passReplayCapture?.depthAttachmentPassName;
|
|
2340
|
+
const observeAfterPassName = passReplayCapture?.observeAfterPassName;
|
|
2341
|
+
let replayValidationFailed = false;
|
|
2342
|
+
const duplicatePassName = selectedReplayPassNames.find(
|
|
2343
|
+
(passName, index) => selectedReplayPassNames.indexOf(passName) !== index,
|
|
2344
|
+
);
|
|
2345
|
+
const invalidPassName = selectedReplayPassNames.find(
|
|
2346
|
+
(passName) => !passNameSet.has(passName),
|
|
2347
|
+
);
|
|
2348
|
+
const nonUniquePassName = selectedReplayPassNames.find(
|
|
2349
|
+
(passName) => passNameCounts.get(passName) !== 1,
|
|
2350
|
+
);
|
|
2351
|
+
const replayFailure = (reason: string): void => {
|
|
2352
|
+
replayValidationFailed = true;
|
|
2353
|
+
internals.errorRegistry.fire(
|
|
2354
|
+
new RhiError({
|
|
2355
|
+
code: 'webgpu-runtime-error',
|
|
2356
|
+
expected:
|
|
2357
|
+
'the requested graph target replay pass selection is valid and executes once',
|
|
2358
|
+
hint: 'inspect replayPassNames against the compiled graph pass roster',
|
|
2359
|
+
detail: {
|
|
2360
|
+
error: {
|
|
2361
|
+
code: 'graph-target-capture-failed',
|
|
2362
|
+
message: JSON.stringify({
|
|
2363
|
+
target: graphCapture.kind === 'pass-replay' ? undefined : graphCapture.name,
|
|
2364
|
+
replayPassNames,
|
|
2365
|
+
availablePassNames: passNames,
|
|
2366
|
+
reason,
|
|
2367
|
+
}),
|
|
2368
|
+
},
|
|
2369
|
+
},
|
|
2370
|
+
}),
|
|
2371
|
+
);
|
|
2372
|
+
};
|
|
2373
|
+
if (unsupportedCaptureKind) {
|
|
2374
|
+
replayFailure('capture-kind-unknown');
|
|
2375
|
+
return { ok: false, stage: 'execute' };
|
|
2376
|
+
}
|
|
2377
|
+
if (replayPassNames === undefined) {
|
|
2378
|
+
replayFailure('replay-pass-selection-missing');
|
|
2379
|
+
return { ok: false, stage: 'execute' };
|
|
2380
|
+
}
|
|
2381
|
+
if (replayPassNames.length === 0) {
|
|
2382
|
+
replayFailure('replay-pass-selection-empty');
|
|
2383
|
+
return { ok: false, stage: 'execute' };
|
|
2384
|
+
}
|
|
2385
|
+
if (duplicatePassName !== undefined) {
|
|
2386
|
+
replayFailure(`replay-pass-selection-duplicate:${duplicatePassName}`);
|
|
2387
|
+
return { ok: false, stage: 'execute' };
|
|
2388
|
+
}
|
|
2389
|
+
if (invalidPassName !== undefined) {
|
|
2390
|
+
replayFailure(`replay-pass-selection-unknown:${invalidPassName}`);
|
|
2391
|
+
return { ok: false, stage: 'execute' };
|
|
2392
|
+
}
|
|
2393
|
+
if (nonUniquePassName !== undefined) {
|
|
2394
|
+
replayFailure(`replay-pass-selection-non-unique:${nonUniquePassName}`);
|
|
2395
|
+
return { ok: false, stage: 'execute' };
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
if (onPrefixEncoded !== undefined) {
|
|
2399
|
+
if (onPassEncoded !== undefined) {
|
|
2400
|
+
replayFailure('pass-replay-prefix-callback-conflict');
|
|
2401
|
+
return { ok: false, stage: 'execute' };
|
|
2402
|
+
}
|
|
2403
|
+
if (depthAttachmentPassName === undefined) {
|
|
2404
|
+
replayFailure('pass-replay-depth-attachment-name-missing');
|
|
2405
|
+
return { ok: false, stage: 'execute' };
|
|
2406
|
+
}
|
|
2407
|
+
if (observeAfterPassName === undefined) {
|
|
2408
|
+
replayFailure('pass-replay-observe-boundary-name-missing');
|
|
2409
|
+
return { ok: false, stage: 'execute' };
|
|
2410
|
+
}
|
|
2411
|
+
const firstNonPrefixPass = selectedReplayPassNames.find(
|
|
2412
|
+
(passName, index) => passName !== passNames[index],
|
|
2413
|
+
);
|
|
2414
|
+
if (
|
|
2415
|
+
firstNonPrefixPass !== undefined ||
|
|
2416
|
+
selectedReplayPassNames.length > passNames.length
|
|
2417
|
+
) {
|
|
2418
|
+
replayFailure('pass-replay-selection-not-prefix');
|
|
2419
|
+
return { ok: false, stage: 'execute' };
|
|
2420
|
+
}
|
|
2421
|
+
if (selectedReplayPassNames.at(-1) !== observeAfterPassName) {
|
|
2422
|
+
replayFailure('pass-replay-observe-boundary-not-last');
|
|
2423
|
+
return { ok: false, stage: 'execute' };
|
|
2424
|
+
}
|
|
2425
|
+
const anchorIndex = selectedReplayPassNames.indexOf(depthAttachmentPassName);
|
|
2426
|
+
if (anchorIndex < 0 || anchorIndex > selectedReplayPassNames.length - 1) {
|
|
2427
|
+
replayFailure('pass-replay-depth-attachment-not-in-prefix');
|
|
2428
|
+
return { ok: false, stage: 'execute' };
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
let replayTarget:
|
|
2433
|
+
| {
|
|
2434
|
+
readonly name: string;
|
|
2435
|
+
readonly view: TextureView;
|
|
2436
|
+
readonly texture: Texture;
|
|
2437
|
+
readonly textureIdentity: number;
|
|
2438
|
+
readonly graphGeneration: number;
|
|
2439
|
+
}
|
|
2440
|
+
| undefined;
|
|
2441
|
+
if (onPassEncoded !== undefined || onPrefixEncoded !== undefined) {
|
|
2442
|
+
const targetName = passReplayCapture?.targetName;
|
|
2443
|
+
const graphAccess = frameState.perFrameGraph;
|
|
2444
|
+
const targetView =
|
|
2445
|
+
targetName === undefined ? undefined : graphAccess?.getColorTargetView(targetName);
|
|
2446
|
+
const targetTexture =
|
|
2447
|
+
targetName === undefined ? undefined : graphAccess?.getColorTargetTexture(targetName);
|
|
2448
|
+
const targetDescriptor =
|
|
2449
|
+
targetName === undefined
|
|
2450
|
+
? undefined
|
|
2451
|
+
: graphAccess?.getColorTargetDescriptor(targetName);
|
|
2452
|
+
if (targetName === undefined) {
|
|
2453
|
+
replayFailure('pass-replay-target-name-missing');
|
|
2454
|
+
return { ok: false, stage: 'execute' };
|
|
2455
|
+
}
|
|
2456
|
+
if (graphAccess === undefined || graphAccess === null) {
|
|
2457
|
+
replayFailure(`pass-replay-target-missing:${targetName}`);
|
|
2458
|
+
return { ok: false, stage: 'execute' };
|
|
2459
|
+
}
|
|
2460
|
+
if (targetView === undefined || targetTexture === undefined) {
|
|
2461
|
+
replayFailure(`pass-replay-target-missing:${targetName}`);
|
|
2462
|
+
return { ok: false, stage: 'execute' };
|
|
2463
|
+
}
|
|
2464
|
+
if (targetDescriptor !== undefined && targetDescriptor.texture !== targetTexture) {
|
|
2465
|
+
replayFailure(`pass-replay-target-identity-mismatch:${targetName}`);
|
|
2466
|
+
return { ok: false, stage: 'execute' };
|
|
2467
|
+
}
|
|
2468
|
+
replayTarget = {
|
|
2469
|
+
name: targetName,
|
|
2470
|
+
view: targetView,
|
|
2471
|
+
texture: targetTexture,
|
|
2472
|
+
textureIdentity: getTextureIdentity(targetTexture),
|
|
2473
|
+
graphGeneration: graphAccess.graphGeneration,
|
|
2474
|
+
};
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
const executed = graph.execute(frame, runPass, graphInstrumentation);
|
|
2478
|
+
if (!executed.ok) {
|
|
2479
|
+
passTimingCapture?.abort({ code: executed.error.code });
|
|
2480
|
+
internals.errorRegistry.fire(executed.error);
|
|
2481
|
+
return { ok: false, stage: 'execute' };
|
|
2482
|
+
}
|
|
2483
|
+
const replayedPassNames = new Set<string>();
|
|
2484
|
+
let prefixCallbackCount = 0;
|
|
2485
|
+
let depthAnchorReceipt:
|
|
2486
|
+
| {
|
|
2487
|
+
readonly pass: { name: string; executionIndex: number };
|
|
2488
|
+
readonly view: TextureView;
|
|
2489
|
+
}
|
|
2490
|
+
| undefined;
|
|
2491
|
+
const replayRunPass: import('@forgeax/engine-render-graph').RenderGraphPassRunner = (
|
|
2492
|
+
pass,
|
|
2493
|
+
encode,
|
|
2494
|
+
) => {
|
|
2495
|
+
if (!requestedPassNames.has(pass.name)) return;
|
|
2496
|
+
if (replayedPassNames.has(pass.name)) {
|
|
2497
|
+
replayFailure(`replay-pass-selection-multiple-hit:${pass.name}`);
|
|
2498
|
+
return;
|
|
2499
|
+
}
|
|
2500
|
+
replayedPassNames.add(pass.name);
|
|
2501
|
+
const depthView = (pass as ResolvedDepthPassExecution).resolvedDepthStencilAttachmentView;
|
|
2502
|
+
if (onPrefixEncoded !== undefined) {
|
|
2503
|
+
if (pass.name === depthAttachmentPassName) {
|
|
2504
|
+
if (depthView === undefined) {
|
|
2505
|
+
replayFailure(`pass-replay-depth-attachment-missing:${pass.name}`);
|
|
2506
|
+
return;
|
|
2507
|
+
}
|
|
2508
|
+
const target = replayTarget;
|
|
2509
|
+
if (target === undefined || depthView !== target.view) {
|
|
2510
|
+
replayFailure(`pass-replay-attachment-target-mismatch:${pass.name}`);
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2513
|
+
if (depthAnchorReceipt !== undefined) {
|
|
2514
|
+
replayFailure(`pass-replay-depth-attachment-multiple-hit:${pass.name}`);
|
|
2515
|
+
return;
|
|
2516
|
+
}
|
|
2517
|
+
depthAnchorReceipt = {
|
|
2518
|
+
pass: { name: pass.name, executionIndex: pass.executionIndex },
|
|
2519
|
+
view: depthView,
|
|
2520
|
+
};
|
|
2521
|
+
}
|
|
2522
|
+
let encoded = false;
|
|
2523
|
+
const encodePrefix = () => {
|
|
2524
|
+
if (encoded) {
|
|
2525
|
+
replayFailure(`pass-replay-encode-multiple-hit:${pass.name}`);
|
|
2526
|
+
return;
|
|
2527
|
+
}
|
|
2528
|
+
encode();
|
|
2529
|
+
encoded = true;
|
|
2530
|
+
if (replayValidationFailed || pass.name !== observeAfterPassName) return;
|
|
2531
|
+
const target = replayTarget;
|
|
2532
|
+
const anchor = depthAnchorReceipt;
|
|
2533
|
+
if (target === undefined || anchor === undefined) {
|
|
2534
|
+
replayFailure('pass-replay-depth-attachment-anchor-missing-at-boundary');
|
|
2535
|
+
return;
|
|
2536
|
+
}
|
|
2537
|
+
const receipt: GraphTargetPassReplayPrefixReceipt = {
|
|
2538
|
+
passName: pass.name,
|
|
2539
|
+
executionIndex: pass.executionIndex,
|
|
2540
|
+
resolvedDepthStencilAttachmentView: anchor.view,
|
|
2541
|
+
graphGeneration: target.graphGeneration,
|
|
2542
|
+
targetName: target.name,
|
|
2543
|
+
targetView: target.view,
|
|
2544
|
+
targetTexture: target.texture,
|
|
2545
|
+
targetTextureIdentity: target.textureIdentity,
|
|
2546
|
+
replayPassNames: [...selectedReplayPassNames],
|
|
2547
|
+
depthAttachmentPassName: anchor.pass.name,
|
|
2548
|
+
observeAfterPassName: pass.name,
|
|
2549
|
+
depthAttachmentExecutionIndex: anchor.pass.executionIndex,
|
|
2550
|
+
};
|
|
2551
|
+
try {
|
|
2552
|
+
onPrefixEncoded(receipt);
|
|
2553
|
+
prefixCallbackCount += 1;
|
|
2554
|
+
} catch (cause) {
|
|
2555
|
+
replayFailure(
|
|
2556
|
+
`pass-replay-prefix-callback-threw:${pass.name}:${cause instanceof Error ? cause.message : String(cause)}`,
|
|
2557
|
+
);
|
|
2558
|
+
}
|
|
2559
|
+
};
|
|
2560
|
+
if (runPass === undefined) encodePrefix();
|
|
2561
|
+
else runPass(pass, encodePrefix);
|
|
2562
|
+
if (!encoded && !replayValidationFailed) {
|
|
2563
|
+
replayFailure(`pass-replay-encode-not-called:${pass.name}`);
|
|
2564
|
+
}
|
|
2565
|
+
return;
|
|
2566
|
+
}
|
|
2567
|
+
if (onPassEncoded === undefined) {
|
|
2568
|
+
if (runPass === undefined) encode();
|
|
2569
|
+
else runPass(pass, encode);
|
|
2570
|
+
return;
|
|
2571
|
+
}
|
|
2572
|
+
const target = replayTarget;
|
|
2573
|
+
if (target === undefined || depthView === undefined) {
|
|
2574
|
+
replayFailure(`pass-replay-depth-attachment-missing:${pass.name}`);
|
|
2575
|
+
return;
|
|
2576
|
+
}
|
|
2577
|
+
if (depthView !== target.view) {
|
|
2578
|
+
replayFailure(`pass-replay-attachment-target-mismatch:${pass.name}`);
|
|
2579
|
+
return;
|
|
2580
|
+
}
|
|
2581
|
+
let encoded = false;
|
|
2582
|
+
const encodeAndObserve = () => {
|
|
2583
|
+
if (encoded) {
|
|
2584
|
+
replayFailure(`pass-replay-encode-multiple-hit:${pass.name}`);
|
|
2585
|
+
return;
|
|
2586
|
+
}
|
|
2587
|
+
encode();
|
|
2588
|
+
encoded = true;
|
|
2589
|
+
if (replayValidationFailed) return;
|
|
2590
|
+
const receipt: GraphTargetPassReplayReceipt = {
|
|
2591
|
+
passName: pass.name,
|
|
2592
|
+
executionIndex: pass.executionIndex,
|
|
2593
|
+
resolvedDepthStencilAttachmentView: depthView,
|
|
2594
|
+
graphGeneration: target.graphGeneration,
|
|
2595
|
+
targetName: target.name,
|
|
2596
|
+
targetView: target.view,
|
|
2597
|
+
targetTexture: target.texture,
|
|
2598
|
+
targetTextureIdentity: target.textureIdentity,
|
|
2599
|
+
};
|
|
2600
|
+
try {
|
|
2601
|
+
onPassEncoded(receipt);
|
|
2602
|
+
} catch (cause) {
|
|
2603
|
+
replayFailure(
|
|
2604
|
+
`pass-replay-callback-threw:${pass.name}:${cause instanceof Error ? cause.message : String(cause)}`,
|
|
2605
|
+
);
|
|
2606
|
+
}
|
|
2607
|
+
};
|
|
2608
|
+
if (runPass === undefined) encodeAndObserve();
|
|
2609
|
+
else runPass(pass, encodeAndObserve);
|
|
2610
|
+
if (!encoded && !replayValidationFailed) {
|
|
2611
|
+
replayFailure(`pass-replay-encode-not-called:${pass.name}`);
|
|
2612
|
+
}
|
|
2613
|
+
};
|
|
2614
|
+
const replayed = graph.execute(frame, replayRunPass);
|
|
2615
|
+
if (!replayed.ok) {
|
|
2616
|
+
internals.errorRegistry.fire(replayed.error);
|
|
2617
|
+
return { ok: false, stage: 'execute' };
|
|
2618
|
+
}
|
|
2619
|
+
if (replayValidationFailed) return { ok: false, stage: 'execute' };
|
|
2620
|
+
if (replayedPassNames.size !== requestedPassNames.size) {
|
|
2621
|
+
replayFailure('replay-pass-selection-zero-hit');
|
|
2622
|
+
return { ok: false, stage: 'execute' };
|
|
2623
|
+
}
|
|
2624
|
+
if (onPrefixEncoded !== undefined && prefixCallbackCount !== 1) {
|
|
2625
|
+
replayFailure('pass-replay-prefix-callback-count-invalid');
|
|
2626
|
+
return { ok: false, stage: 'execute' };
|
|
2627
|
+
}
|
|
2628
|
+
} else {
|
|
2629
|
+
const executed = graph.execute(frame, runPass, graphInstrumentation);
|
|
2630
|
+
if (!executed.ok) {
|
|
2631
|
+
passTimingCapture?.abort({ code: executed.error.code });
|
|
2632
|
+
internals.errorRegistry.fire(executed.error);
|
|
2633
|
+
return { ok: false, stage: 'execute' };
|
|
2634
|
+
}
|
|
1673
2635
|
}
|
|
1674
|
-
|
|
2636
|
+
timingInstrumentationState?.setCapture(undefined);
|
|
2637
|
+
const afterGraphExecute = resolvedFrameHooks?.afterGraphExecute;
|
|
1675
2638
|
if (afterGraphExecute !== undefined) {
|
|
1676
2639
|
const recorded = afterGraphExecute();
|
|
1677
2640
|
if (!recorded.ok) {
|
|
@@ -1684,7 +2647,7 @@ export function executeCompiledFrameGraph(
|
|
|
1684
2647
|
finish: () => {
|
|
1685
2648
|
const graphCapture = frameState.graphTargetCapture;
|
|
1686
2649
|
frameState.graphTargetCapture = undefined;
|
|
1687
|
-
if (graphCapture !== undefined) {
|
|
2650
|
+
if (graphCapture !== undefined && graphCapture.kind !== 'pass-replay') {
|
|
1688
2651
|
const graphAccess = frameState.perFrameGraph;
|
|
1689
2652
|
const graphTexture = graphAccess?.getColorTargetTexture(graphCapture.name);
|
|
1690
2653
|
const descriptor = graphAccess?.getColorTargetDescriptor(graphCapture.name);
|
|
@@ -1903,7 +2866,8 @@ export function executeCompiledFrameGraph(
|
|
|
1903
2866
|
},
|
|
1904
2867
|
}),
|
|
1905
2868
|
commit: () => {
|
|
1906
|
-
|
|
2869
|
+
resolvedFrameHooks?.onSubmitted?.();
|
|
2870
|
+
legacySubmitCommit?.();
|
|
1907
2871
|
if (frameState.temporalFrameInput !== undefined) {
|
|
1908
2872
|
const temporal = frameState.temporalFrameTransaction.commit({ accepted: true });
|
|
1909
2873
|
if (temporal.ok) {
|
|
@@ -1931,6 +2895,46 @@ export function executeCompiledFrameGraph(
|
|
|
1931
2895
|
?.perPassResources.commitBloomFrameReceipts?.(frameState.bloomFrameReceipts);
|
|
1932
2896
|
frameState.bloomFrameReceipts = undefined;
|
|
1933
2897
|
}
|
|
2898
|
+
const pendingAuto = frameState.pendingAutoExposureGpuResources;
|
|
2899
|
+
if (pendingAuto !== undefined) {
|
|
2900
|
+
const previousAuto = frameState.autoExposureGpuResources;
|
|
2901
|
+
frameState.autoExposureGpuResources = pendingAuto;
|
|
2902
|
+
frameState.pendingAutoExposureGpuResources = undefined;
|
|
2903
|
+
if (previousAuto !== undefined && previousAuto !== pendingAuto) {
|
|
2904
|
+
internals.device.queue
|
|
2905
|
+
.onSubmittedWorkDone()
|
|
2906
|
+
.then(() => retireAutoExposureGpuResources(previousAuto))
|
|
2907
|
+
.catch(() => undefined);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
const pendingAutoState = frameState.pendingAutoExposureState;
|
|
2911
|
+
if (pendingAutoState !== undefined) {
|
|
2912
|
+
frameState.autoExposureState = commitAutoExposureSubmission(
|
|
2913
|
+
pendingAutoState.state,
|
|
2914
|
+
pendingAutoState,
|
|
2915
|
+
);
|
|
2916
|
+
frameState.pendingAutoExposureState = undefined;
|
|
2917
|
+
}
|
|
2918
|
+
const pendingLut = frameState.pendingStandardLutGpuResources;
|
|
2919
|
+
if (pendingLut !== undefined) {
|
|
2920
|
+
const previousLut = frameState.standardLutGpuResources;
|
|
2921
|
+
frameState.standardLutGpuResources = pendingLut;
|
|
2922
|
+
frameState.pendingStandardLutGpuResources = undefined;
|
|
2923
|
+
if (previousLut !== undefined && previousLut !== pendingLut) {
|
|
2924
|
+
retireStandardLutGpuResources(previousLut);
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
const pendingLutState = frameState.pendingStandardLutState;
|
|
2928
|
+
if (pendingLutState !== undefined) {
|
|
2929
|
+
frameState.standardLutState =
|
|
2930
|
+
pendingLutState.remove || pendingLutState.candidate === undefined
|
|
2931
|
+
? resetStandardLutState(pendingLutState.state, 'resource-removed', {
|
|
2932
|
+
targetGeneration: pendingLutState.targetGeneration,
|
|
2933
|
+
deviceEpoch: pendingLutState.deviceEpoch,
|
|
2934
|
+
})
|
|
2935
|
+
: commitStandardLutCandidate(pendingLutState.state, pendingLutState.candidate);
|
|
2936
|
+
frameState.pendingStandardLutState = undefined;
|
|
2937
|
+
}
|
|
1934
2938
|
const stagedGpuState = frameState.temporalGpuState;
|
|
1935
2939
|
if (stagedGpuState !== undefined) {
|
|
1936
2940
|
if (commitTemporalGpuSubmit(stagedGpuState)) {
|
|
@@ -1993,15 +2997,28 @@ export function executeCompiledFrameGraph(
|
|
|
1993
2997
|
frameState.environmentLifecycle?.publish(frameState.environmentGeneration);
|
|
1994
2998
|
frameState.environmentGeneration = undefined;
|
|
1995
2999
|
}
|
|
3000
|
+
frameState.pendingAtmospherePublish?.();
|
|
3001
|
+
frameState.pendingAtmospherePublish = undefined;
|
|
1996
3002
|
onSubmitted?.(internals.device.queue.onSubmittedWorkDone());
|
|
1997
3003
|
},
|
|
1998
3004
|
abort: (failure) => {
|
|
1999
|
-
|
|
3005
|
+
frameState.pendingAtmospherePublish = undefined;
|
|
3006
|
+
resolvedFrameHooks?.onAborted?.();
|
|
2000
3007
|
passTimingCapture?.abort({ code: failure.stage });
|
|
2001
3008
|
timingHost.gpuPassTimingCapture = undefined;
|
|
2002
3009
|
timingHost.gpuPassTimingSubmittedWork = undefined;
|
|
2003
3010
|
timingCapture?.discard();
|
|
2004
3011
|
frameState.bloomFrameReceipts = undefined;
|
|
3012
|
+
frameState.pendingAutoExposureState = undefined;
|
|
3013
|
+
frameState.pendingStandardLutState = undefined;
|
|
3014
|
+
if (frameState.pendingAutoExposureGpuResources !== undefined) {
|
|
3015
|
+
retireAutoExposureGpuResources(frameState.pendingAutoExposureGpuResources);
|
|
3016
|
+
frameState.pendingAutoExposureGpuResources = undefined;
|
|
3017
|
+
}
|
|
3018
|
+
if (frameState.pendingStandardLutGpuResources !== undefined) {
|
|
3019
|
+
retireStandardLutGpuResources(frameState.pendingStandardLutGpuResources);
|
|
3020
|
+
frameState.pendingStandardLutGpuResources = undefined;
|
|
3021
|
+
}
|
|
2005
3022
|
if (frameState.environmentGeneration !== undefined) {
|
|
2006
3023
|
frameState.environmentLifecycle?.recordStageFailure(
|
|
2007
3024
|
failure.stage,
|