@forgeax/engine-render 0.1.33 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1010 -124
- package/dist/assembly/backend-contract.d.ts +2 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
- package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
- package/dist/assembly/canvas-draw-guard.d.ts +3 -0
- package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
- package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
- package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
- package/dist/assembly/factory.d.ts +1 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +3 -3
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +16 -2
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-feature-post-processes.d.ts +6 -0
- package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
- package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +11 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
- package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +1 -1
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- package/dist/barrel-distortion.d.ts +47 -0
- package/dist/barrel-distortion.d.ts.map +1 -0
- package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
- package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
- package/dist/{chunk-ZDQWGQW7.mjs → chunk-HEB564WF.mjs} +4 -4
- package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-HEB564WF.mjs.map} +1 -1
- package/dist/{chunk-VOZWDM3L.mjs → chunk-MKDIT2EM.mjs} +1307 -188
- package/dist/chunk-MKDIT2EM.mjs.map +1 -0
- package/dist/{chunk-LEAXOMYJ.mjs → chunk-OCDLEI6I.mjs} +3 -3
- package/dist/{chunk-LEAXOMYJ.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
- package/dist/chunk-ODZWR6JQ.mjs +4927 -0
- package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
- package/dist/{chunk-3RTCJTH4.mjs → chunk-SHFUFJ5N.mjs} +184 -13
- package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
- package/dist/{chunk-OO3DRYK7.mjs → chunk-UI5SFODX.mjs} +176 -96
- package/dist/chunk-UI5SFODX.mjs.map +1 -0
- package/dist/{chunk-PLAXOOX5.mjs → chunk-UINHLCZA.mjs} +561 -79
- package/dist/chunk-UINHLCZA.mjs.map +1 -0
- package/dist/{chunk-NB2S7ZRX.mjs → chunk-WEX45HKH.mjs} +127 -386
- package/dist/chunk-WEX45HKH.mjs.map +1 -0
- package/dist/cloud/density.d.ts +55 -0
- package/dist/cloud/density.d.ts.map +1 -0
- package/dist/cloud/extract.d.ts +25 -0
- package/dist/cloud/extract.d.ts.map +1 -0
- package/dist/cloud/feature.d.ts +57 -0
- package/dist/cloud/feature.d.ts.map +1 -0
- package/dist/cloud/frame-context.d.ts +8 -0
- package/dist/cloud/frame-context.d.ts.map +1 -0
- package/dist/cloud/inspection.d.ts +59 -0
- package/dist/cloud/inspection.d.ts.map +1 -0
- package/dist/cloud/optics.d.ts +56 -0
- package/dist/cloud/optics.d.ts.map +1 -0
- package/dist/cloud/parameters.d.ts +73 -0
- package/dist/cloud/parameters.d.ts.map +1 -0
- package/dist/cloud/resources.d.ts +60 -0
- package/dist/cloud/resources.d.ts.map +1 -0
- package/dist/cloud/shadow.d.ts +42 -0
- package/dist/cloud/shadow.d.ts.map +1 -0
- package/dist/cloud/temporal.d.ts +74 -0
- package/dist/cloud/temporal.d.ts.map +1 -0
- package/dist/components/barrel-distortion.d.ts +13 -0
- package/dist/components/barrel-distortion.d.ts.map +1 -0
- package/dist/components/cloud-layer.d.ts +29 -0
- package/dist/components/cloud-layer.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 +20 -6
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/construct-renderer.d.ts +1 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +6759 -2875
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/dynamic-geometry.d.ts +5 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/errors/cloud.d.ts +59 -0
- package/dist/errors/cloud.d.ts.map +1 -0
- package/dist/errors/render.d.ts +18 -4
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/examples/single-layer-medium-surface.d.ts +47 -0
- package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +5 -1
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/features/barrel-distortion.d.ts +29 -0
- package/dist/features/barrel-distortion.d.ts.map +1 -0
- package/dist/features/error-reporting.d.ts +6 -2
- package/dist/features/error-reporting.d.ts.map +1 -1
- package/dist/features/host.d.ts +10 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/plan.d.ts +8 -0
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +5 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +1 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/targets.d.ts +2 -0
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +44 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +15 -7
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-dirty-ranges.d.ts +11 -0
- package/dist/gpu-dirty-ranges.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +17 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts +6 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster-material.d.ts +178 -0
- package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +47 -3
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/resource-allocation.d.ts +31 -0
- package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
- package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +26 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +5 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +2 -2
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +10 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +27 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +258 -8
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +135 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instance-buffer-cache.d.ts +4 -4
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/instances.d.ts +48 -100
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -7
- package/dist/pbr-pipeline.d.ts +19 -1
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
- package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-output/types.d.ts +4 -2
- package/dist/pipeline/standard-output/types.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +1 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/barrel-distortion-frame.d.ts +15 -0
- package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
- package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
- package/dist/record/fold-buckets.d.ts +95 -0
- package/dist/record/fold-buckets.d.ts.map +1 -0
- package/dist/record/fold-instance-buffer.d.ts +6 -0
- package/dist/record/fold-instance-buffer.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +1 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +37 -3
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +10 -61
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-draw-receipts.d.ts +11 -0
- package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +8 -0
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +21 -5
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +13 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/motion-blur-receipt.d.ts +11 -0
- package/dist/record/motion-blur-receipt.d.ts.map +1 -0
- package/dist/record/probe-blend-buffer.d.ts +16 -0
- package/dist/record/probe-blend-buffer.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +22 -3
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -0
- 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 +22 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +11 -3
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +9 -0
- package/dist/record/volume-params.d.ts.map +1 -0
- package/dist/recovery/render-system-candidate.d.ts +10 -0
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +42 -4
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +103 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +3 -2
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +16 -9
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +23 -0
- package/dist/render-system-presentation.d.ts.map +1 -0
- package/dist/render-system-producer-roots.d.ts +10 -0
- package/dist/render-system-producer-roots.d.ts.map +1 -0
- package/dist/render-system-residency.d.ts +12 -0
- package/dist/render-system-residency.d.ts.map +1 -0
- package/dist/render-system.d.ts +19 -14
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/probe-blend.d.ts +27 -0
- package/dist/scene/probe-blend.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +12 -5
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +9 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/surface/dynamic-input.d.ts +133 -0
- package/dist/surface/dynamic-input.d.ts.map +1 -0
- package/dist/surface/gpu-driven.d.ts +41 -0
- package/dist/surface/gpu-driven.d.ts.map +1 -0
- package/dist/surface/submission-observation.d.ts +136 -0
- package/dist/surface/submission-observation.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +13 -1
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
- package/dist/transmission/single-layer-medium.d.ts +89 -0
- package/dist/transmission/single-layer-medium.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +14 -2
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +9 -4
- package/dist/volume/component.d.ts.map +1 -1
- package/dist/volume/extract.d.ts +1 -1
- package/dist/volume/extract.d.ts.map +1 -1
- package/dist/volume/inspection.d.ts +2 -0
- package/dist/volume/inspection.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +4 -1
- package/dist/volume/passes.d.ts.map +1 -1
- package/dist/volume/resources.d.ts.map +1 -1
- package/package.json +22 -21
- package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
- package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
- package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
- package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
- package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
- package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
- package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
- package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
- package/src/__tests__/factory-contract.integration.test.ts +295 -45
- package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
- package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
- package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
- package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
- package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
- package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
- package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
- package/src/__tests__/gpu-scene.unit.test.ts +119 -9
- package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
- package/src/__tests__/instances-culling.integration.test.ts +10 -36
- package/src/__tests__/instances-store.unit.test.ts +97 -305
- package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
- package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
- package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
- package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
- package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
- package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
- package/src/__tests__/probe-bindings.unit.test.ts +582 -1
- package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
- package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
- package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
- package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
- package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
- package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
- package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
- package/src/__tests__/resource-allocation.unit.test.ts +123 -0
- package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
- package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
- package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
- package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
- package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
- package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
- package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
- package/src/__tests__/temporal-performance.integration.test.ts +3 -3
- package/src/__tests__/visibility-instances.integration.test.ts +7 -19
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
- package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
- package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
- package/src/assembly/backend-contract.ts +30 -0
- package/src/assembly/barrel-distortion-inspection.ts +22 -0
- package/src/assembly/canvas-draw-guard.ts +11 -0
- package/src/assembly/cloud-shadow-entry.ts +22 -0
- package/src/assembly/dynamic-geometry-host.ts +65 -37
- package/src/assembly/dynamic-geometry-runtime.ts +7 -1
- package/src/assembly/factory.ts +2 -30
- package/src/assembly/host-contract.ts +3 -3
- package/src/assembly/material/assembly.ts +25 -13
- package/src/assembly/material/pipeline-helpers.ts +53 -12
- package/src/assembly/material-shader-policy.ts +55 -0
- package/src/assembly/material-shader-prewarm.ts +21 -10
- package/src/assembly/recovery/device-loss-fanout.ts +13 -0
- package/src/assembly/recovery/renderer-recover.ts +41 -18
- package/src/assembly/render-feature-post-processes.ts +54 -0
- package/src/assembly/renderer-facade.ts +4 -1
- package/src/assembly/renderer-feature-inspection.ts +8 -2
- package/src/assembly/renderer-frame-transaction.ts +23 -0
- package/src/assembly/renderer-inspection.ts +28 -0
- package/src/assembly/skin-palette-owner.ts +1 -1
- package/src/assembly/temporal-post-process-prewarm.ts +3 -3
- package/src/assembly/webgpu-pbr-ready.ts +9 -1
- package/src/assembly/webgpu-ready-per-pass.ts +104 -0
- package/src/assembly/webgpu-ready.ts +115 -61
- package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
- package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
- package/src/assembly/webgpu-renderer.ts +214 -252
- package/src/assembly/webgpu-vertex-layouts.ts +1 -1
- package/src/barrel-distortion.ts +247 -0
- package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
- package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
- package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
- package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
- package/src/cloud/density.ts +600 -0
- package/src/cloud/extract.ts +110 -0
- package/src/cloud/feature.ts +1810 -0
- package/src/cloud/frame-context.ts +42 -0
- package/src/cloud/inspection.ts +130 -0
- package/src/cloud/optics.ts +285 -0
- package/src/cloud/parameters.ts +255 -0
- package/src/cloud/resources.ts +122 -0
- package/src/cloud/shadow.ts +167 -0
- package/src/cloud/temporal.ts +226 -0
- package/src/components/barrel-distortion.ts +46 -0
- package/src/components/cloud-layer.ts +47 -0
- package/src/components/index.ts +2 -0
- package/src/components/instances.ts +18 -45
- package/src/components/sprite-instances.ts +1 -1
- package/src/construct-renderer.ts +1 -1
- package/src/dynamic-geometry.ts +12 -1
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +44 -7
- package/src/examples/single-layer-medium-surface.ts +59 -0
- package/src/extract/camera.ts +15 -1
- package/src/extract/contracts.ts +5 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +26 -6
- package/src/features/host.ts +115 -14
- package/src/features/plan.ts +8 -0
- package/src/features/render-graph-contribution.ts +9 -0
- package/src/features/render-graph-raster.ts +45 -3
- package/src/features/targets.ts +66 -0
- package/src/features/types.ts +47 -0
- package/src/fullscreen-post-process-pass.ts +41 -9
- package/src/gpu-dirty-ranges.ts +48 -0
- package/src/gpu-driven/batch-topology.ts +53 -0
- package/src/gpu-driven/material-artifacts.ts +33 -25
- package/src/gpu-driven/prepared-draw.ts +12 -4
- package/src/gpu-driven/production-raster-material.ts +1894 -0
- package/src/gpu-driven/production-raster.ts +825 -784
- package/src/gpu-driven/resource-allocation.ts +142 -0
- package/src/gpu-driven/shadow-ownership.ts +71 -0
- package/src/gpu-driven/view-gpu.ts +164 -10
- package/src/gpu-scene.ts +75 -84
- package/src/hdrp-buffers.ts +4 -3
- package/src/ibl/skylight-bind-group.ts +49 -7
- package/src/index.ts +196 -9
- package/src/inspection-types.ts +162 -0
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +149 -569
- package/src/pbr-pipeline.ts +219 -13
- package/src/pipeline/single-layer-medium-passes.ts +267 -0
- package/src/pipeline/standard-forward-lane.ts +313 -57
- package/src/pipeline/standard-output/graph.ts +8 -2
- package/src/pipeline/standard-output/types.ts +12 -1
- package/src/pipeline/standard-pipeline.ts +291 -18
- package/src/pipeline/standard-post.ts +90 -24
- package/src/pipeline-builder.ts +1 -1
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
- package/src/prepare/prepared-graphics-resolver.ts +2 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
- package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
- package/src/record/barrel-distortion-frame.ts +110 -0
- package/src/record/dynamic-geometry-consumption.ts +39 -9
- package/src/record/fold-buckets.ts +852 -0
- package/src/record/fold-instance-buffer.ts +51 -0
- package/src/record/frame-lighting.ts +36 -2
- package/src/record/frame-snapshot.ts +39 -3
- package/src/record/frame.ts +217 -1084
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/main-pass-geometry.ts +251 -82
- package/src/record/main-pass-material.ts +66 -4
- package/src/record/main-pass-sprite-draws.ts +7 -65
- package/src/record/main-pass.ts +156 -20
- package/src/record/motion-blur-receipt.ts +91 -0
- package/src/record/probe-blend-buffer.ts +180 -0
- package/src/record/recovery-pipeline.ts +35 -3
- package/src/record/render-context.ts +39 -3
- package/src/record/shadow-pass.ts +30 -1
- package/src/record/skybox-post-pass.ts +28 -4
- package/src/record/typed-frame-graph.ts +770 -134
- package/src/record/view-ubo.ts +26 -3
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +235 -42
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +48 -4
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +130 -0
- package/src/render-system-extract-tail.ts +57 -61
- package/src/render-system-extract.ts +74 -76
- package/src/render-system-presentation.ts +56 -0
- package/src/render-system-producer-roots.ts +96 -0
- package/src/render-system-residency.ts +159 -0
- package/src/render-system.ts +347 -363
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +349 -280
- package/src/ssao-buffers.ts +95 -2
- package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
- package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
- package/src/surface/dynamic-input.ts +658 -0
- package/src/surface/gpu-driven.ts +147 -0
- package/src/surface/submission-observation.ts +517 -0
- package/src/systems/skin-palette-allocator.ts +4 -1
- package/src/temporal/gpu.ts +101 -17
- package/src/temporal/inspection.ts +7 -1
- package/src/temporal/standard-scene-data.ts +5 -0
- package/src/temporal/target-coverage-attachment.ts +4 -0
- package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
- package/src/transmission/single-layer-medium.ts +322 -0
- package/src/typed-render-graph-primitives.ts +70 -2
- package/src/volume/component.ts +10 -9
- package/src/volume/extract.ts +11 -5
- package/src/volume/inspection.ts +3 -0
- package/src/volume/passes.ts +87 -4
- package/src/volume/resources.ts +2 -1
- package/dist/chunk-3RTCJTH4.mjs.map +0 -1
- package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
- package/dist/chunk-NNQL7CB3.mjs +0 -1713
- package/dist/chunk-NNQL7CB3.mjs.map +0 -1
- package/dist/chunk-OO3DRYK7.mjs.map +0 -1
- package/dist/chunk-PA5DRJNI.mjs.map +0 -1
- package/dist/chunk-PLAXOOX5.mjs.map +0 -1
- package/dist/chunk-VOZWDM3L.mjs.map +0 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { MaterialRootAsset } from '@forgeax/engine-types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A public root asset showing the model declaration and its bounded input.
|
|
5
|
+
* The page is shared by every material instance; Render supplies the page
|
|
6
|
+
* bytes and each instance publishes its own range.
|
|
7
|
+
*/
|
|
8
|
+
export const SINGLE_LAYER_MEDIUM_SURFACE_EXAMPLE = {
|
|
9
|
+
kind: 'material',
|
|
10
|
+
surface: {
|
|
11
|
+
model: 'single-layer-medium',
|
|
12
|
+
module: 'game::water_surface_a',
|
|
13
|
+
dynamicInput: {
|
|
14
|
+
name: 'waterEvents',
|
|
15
|
+
fields: [
|
|
16
|
+
{ name: 'position', type: 'vec3<f32>' },
|
|
17
|
+
{ name: 'time', type: 'f32' },
|
|
18
|
+
{ name: 'eventId', type: 'u32' },
|
|
19
|
+
],
|
|
20
|
+
maxRecords: 64,
|
|
21
|
+
maxDomains: 8,
|
|
22
|
+
maxPageBytes: 2048,
|
|
23
|
+
maxBindings: 1,
|
|
24
|
+
maxEventsPerSample: 8,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
passes: [
|
|
28
|
+
{
|
|
29
|
+
name: 'color',
|
|
30
|
+
program: { module: 'forgeax::single-layer-medium' },
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
parameters: [],
|
|
34
|
+
values: {},
|
|
35
|
+
} as const satisfies MaterialRootAsset;
|
|
36
|
+
|
|
37
|
+
/** Two different imported Surface implementations consuming one model ABI. */
|
|
38
|
+
export const SINGLE_LAYER_MEDIUM_SURFACE_EXAMPLES = [
|
|
39
|
+
{
|
|
40
|
+
module: 'game::water_surface_a',
|
|
41
|
+
source: `#define_import_path game::water_surface_a
|
|
42
|
+
#import forgeax_material::single_layer_medium_surface_v1::{SingleLayerMediumSurfaceInput, SingleLayerMediumSurfaceData}
|
|
43
|
+
fn evaluate_surface(input : SingleLayerMediumSurfaceInput) -> SingleLayerMediumSurfaceData {
|
|
44
|
+
let event = read_waterEvents(input.eventRangeStart);
|
|
45
|
+
let normal = normalize(input.geometricNormalWS + vec3<f32>(0.0, 0.0, event.time * 0.02));
|
|
46
|
+
return SingleLayerMediumSurfaceData(normal, 0.18, 1.0, 0.0, vec3<f32>(0.18, 0.06, 0.02), vec3<f32>(0.02, 0.04, 0.08), 1.333, 0.2, 1000.0);
|
|
47
|
+
}`,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
module: 'game::water_surface_b',
|
|
51
|
+
source: `#define_import_path game::water_surface_b
|
|
52
|
+
#import forgeax_material::single_layer_medium_surface_v1::{SingleLayerMediumSurfaceInput, SingleLayerMediumSurfaceData}
|
|
53
|
+
fn evaluate_surface(input : SingleLayerMediumSurfaceInput) -> SingleLayerMediumSurfaceData {
|
|
54
|
+
let event = read_waterEvents(input.eventRangeStart);
|
|
55
|
+
let normal = normalize(input.geometricNormalWS + vec3<f32>(event.position.xy * 0.01, 0.0));
|
|
56
|
+
return SingleLayerMediumSurfaceData(normal, 0.32, 1.0, clamp(event.time * 0.1, 0.0, 1.0), vec3<f32>(0.04, 0.02, 0.01), vec3<f32>(0.08, 0.05, 0.02), 1.333, -0.1, 800.0);
|
|
57
|
+
}`,
|
|
58
|
+
},
|
|
59
|
+
] as const;
|
package/src/extract/camera.ts
CHANGED
|
@@ -2,6 +2,10 @@ import type { EntityHandle, World } from '@forgeax/engine-ecs';
|
|
|
2
2
|
import { readRenderArrayView } from '@forgeax/engine-ecs/projection';
|
|
3
3
|
import { mat4, vec3 } from '@forgeax/engine-math';
|
|
4
4
|
import { GlobalTransform } from '@forgeax/engine-scene';
|
|
5
|
+
import {
|
|
6
|
+
BarrelDistortion,
|
|
7
|
+
validateBarrelDistortionParameters,
|
|
8
|
+
} from '../components/barrel-distortion';
|
|
5
9
|
import {
|
|
6
10
|
antialiasFromF32,
|
|
7
11
|
Camera,
|
|
@@ -38,13 +42,20 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
|
|
|
38
42
|
const cameraQuery = world
|
|
39
43
|
.query({
|
|
40
44
|
read: [Camera],
|
|
41
|
-
optional: [
|
|
45
|
+
optional: [
|
|
46
|
+
MotionBlur,
|
|
47
|
+
DynamicResolution,
|
|
48
|
+
ScreenSpaceReflection,
|
|
49
|
+
DepthOfField,
|
|
50
|
+
BarrelDistortion,
|
|
51
|
+
],
|
|
42
52
|
with: [GlobalTransform],
|
|
43
53
|
})
|
|
44
54
|
.unwrap();
|
|
45
55
|
for (const row of cameraQuery) {
|
|
46
56
|
const cam = row.get(Camera);
|
|
47
57
|
const motionBlur = row.get(MotionBlur);
|
|
58
|
+
const barrelDistortion = row.get(BarrelDistortion);
|
|
48
59
|
const motionBlurResult = resolveMotionBlurParams(motionBlur);
|
|
49
60
|
if (!motionBlurResult.ok) throw motionBlurResult.error;
|
|
50
61
|
const motionBlurParams = motionBlurResult.value;
|
|
@@ -75,6 +86,8 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
|
|
|
75
86
|
const antialias = antialiasFromF32(cam.antialias);
|
|
76
87
|
const dynamicResolutionResult = validateDynamicResolutionCamera(dynamicResolution, antialias);
|
|
77
88
|
if (!dynamicResolutionResult.ok) throw dynamicResolutionResult.error;
|
|
89
|
+
const barrelDistortionResult = validateBarrelDistortionParameters(barrelDistortion);
|
|
90
|
+
if (!barrelDistortionResult.ok) throw barrelDistortionResult.error;
|
|
78
91
|
cameras.push({
|
|
79
92
|
entityKey: entity as number,
|
|
80
93
|
historyVersion: cam.historyVersion,
|
|
@@ -128,6 +141,7 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
|
|
|
128
141
|
targetFps: motionBlurParams.targetFps,
|
|
129
142
|
},
|
|
130
143
|
}),
|
|
144
|
+
...(barrelDistortion === undefined ? {} : { barrelDistortion: barrelDistortionResult.value }),
|
|
131
145
|
...(screenSpaceReflection === undefined
|
|
132
146
|
? {}
|
|
133
147
|
: {
|
package/src/extract/contracts.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
MaterialAsset,
|
|
14
14
|
MaterialPass,
|
|
15
15
|
MaterialRenderState,
|
|
16
|
+
MaterialSurfaceModel,
|
|
16
17
|
MaterialTextureCoordinates,
|
|
17
18
|
MeshLodLevel,
|
|
18
19
|
ParamSchemaEntry,
|
|
@@ -652,6 +653,10 @@ export interface MaterialSnapshot {
|
|
|
652
653
|
readonly baseColor: Vec3;
|
|
653
654
|
readonly metallic: number;
|
|
654
655
|
readonly roughness: number;
|
|
656
|
+
/** Root-owned Surface model used only for typed pass routing. */
|
|
657
|
+
readonly surfaceModel?: MaterialSurfaceModel | undefined;
|
|
658
|
+
/** Whether this material publishes a Deferred pass consumed before the forward-only lane. */
|
|
659
|
+
readonly deferredPass?: boolean | undefined;
|
|
655
660
|
readonly clearcoat?: number | undefined;
|
|
656
661
|
readonly clearcoatRoughness?: number | undefined;
|
|
657
662
|
/** Authored Standard PBR specular tint in linear runtime color space. */
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/** One graph-valid identity for the barrel stage, feature and shader prewarm. */
|
|
2
|
+
export const BARREL_DISTORTION_POST_PROCESS_ID = 'fullscreen.forgeax.barrel-distortion';
|
|
3
|
+
export const BARREL_DISTORTION_FEATURE_IDENTITY = BARREL_DISTORTION_POST_PROCESS_ID;
|
|
4
|
+
|
|
5
|
+
import { ok, type Result } from '@forgeax/engine-types';
|
|
6
|
+
import type { RenderError } from '../errors/render';
|
|
7
|
+
import type { RenderFeaturePlan } from './plan';
|
|
8
|
+
import type { RenderFeature, RenderFeatureExtractContext, RenderFeaturePlanContext } from './types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The coordinate function is exported beside the production shader so a real
|
|
12
|
+
* f32 device probe can compile exactly the same implementation. Keeping the
|
|
13
|
+
* probe source here avoids a second test-only equation that could drift from
|
|
14
|
+
* the Standard pass.
|
|
15
|
+
*/
|
|
16
|
+
export const BARREL_DISTORTION_WGSL_COORDINATE = /* wgsl */ `
|
|
17
|
+
struct BarrelDistortionParams {
|
|
18
|
+
strength : f32,
|
|
19
|
+
centerX : f32,
|
|
20
|
+
centerY : f32,
|
|
21
|
+
radiusSquared : f32,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
fn barrel_distortion_display_to_scene_uv(
|
|
25
|
+
inputUv : vec2<f32>,
|
|
26
|
+
params : BarrelDistortionParams,
|
|
27
|
+
dimensions : vec2<f32>,
|
|
28
|
+
) -> vec2<f32> {
|
|
29
|
+
let aspect = dimensions.x / max(dimensions.y, 1.0);
|
|
30
|
+
let p = vec2<f32>(
|
|
31
|
+
2.0 * aspect * (inputUv.x - params.centerX),
|
|
32
|
+
2.0 * (inputUv.y - params.centerY),
|
|
33
|
+
);
|
|
34
|
+
let t = dot(p, p) / max(params.radiusSquared, 1e-6);
|
|
35
|
+
let scale = (1.0 - params.strength) / (1.0 - params.strength * t);
|
|
36
|
+
return clamp(
|
|
37
|
+
vec2<f32>(
|
|
38
|
+
params.centerX + (inputUv.x - params.centerX) * scale,
|
|
39
|
+
params.centerY + (inputUv.y - params.centerY) * scale,
|
|
40
|
+
),
|
|
41
|
+
vec2<f32>(0.0),
|
|
42
|
+
vec2<f32>(1.0),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Manifest-equivalent WGSL for the bounded analytic model. The Standard
|
|
49
|
+
* owner registers this source once and keeps the graph, encoder, and submit
|
|
50
|
+
* lifecycle shared with every other fullscreen stage.
|
|
51
|
+
*/
|
|
52
|
+
export const BARREL_DISTORTION_WGSL = /* wgsl */ `${BARREL_DISTORTION_WGSL_COORDINATE}
|
|
53
|
+
struct FullscreenOutput {
|
|
54
|
+
@builtin(position) position : vec4<f32>,
|
|
55
|
+
@location(0) uv : vec2<f32>,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
fn fullscreen_triangle(vertex_index : u32) -> FullscreenOutput {
|
|
59
|
+
var x : f32 = -1.0;
|
|
60
|
+
var y : f32 = -1.0;
|
|
61
|
+
if (vertex_index == 1u) { x = 3.0; }
|
|
62
|
+
if (vertex_index == 2u) { y = 3.0; }
|
|
63
|
+
let u : f32 = (x + 1.0) * 0.5;
|
|
64
|
+
let v : f32 = 1.0 - (y + 1.0) * 0.5;
|
|
65
|
+
var out : FullscreenOutput;
|
|
66
|
+
out.position = vec4<f32>(x, y, 0.0, 1.0);
|
|
67
|
+
out.uv = vec2<f32>(u, v);
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@group(1) @binding(0) var sceneColor : texture_2d<f32>;
|
|
72
|
+
@group(1) @binding(1) var sceneSampler : sampler;
|
|
73
|
+
|
|
74
|
+
@group(1) @binding(2) var<uniform> params : BarrelDistortionParams;
|
|
75
|
+
|
|
76
|
+
@vertex
|
|
77
|
+
fn vs_main(@builtin(vertex_index) vertex_index : u32) -> FullscreenOutput {
|
|
78
|
+
return fullscreen_triangle(vertex_index);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@fragment
|
|
82
|
+
fn fs_main(input : FullscreenOutput) -> @location(0) vec4<f32> {
|
|
83
|
+
let dimensions = vec2<f32>(textureDimensions(sceneColor));
|
|
84
|
+
let sampleUv = barrel_distortion_display_to_scene_uv(input.uv, params, dimensions);
|
|
85
|
+
return textureSampleLevel(sceneColor, sceneSampler, sampleUv, 0.0);
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Ordinary feature registration for the Standard linear-LDR stage.
|
|
91
|
+
* Standard still allocates the stage targets and chooses its position in the
|
|
92
|
+
* post chain; this feature owns the executable fullscreen declaration that is
|
|
93
|
+
* projected into that slot by the existing graph/encoder/submit path.
|
|
94
|
+
*/
|
|
95
|
+
export interface BarrelDistortionFeatureFrame {
|
|
96
|
+
/** True only when the extracted camera requires a spatial warp this frame. */
|
|
97
|
+
readonly active: boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function createBarrelDistortionRenderFeature(): RenderFeature<BarrelDistortionFeatureFrame> {
|
|
101
|
+
return Object.freeze({
|
|
102
|
+
identity: BARREL_DISTORTION_FEATURE_IDENTITY,
|
|
103
|
+
requiredCapabilities: ['rgba16floatRenderable'] as const,
|
|
104
|
+
requiredFullscreenPostProcesses: [
|
|
105
|
+
{ identity: BARREL_DISTORTION_POST_PROCESS_ID, source: BARREL_DISTORTION_WGSL },
|
|
106
|
+
],
|
|
107
|
+
extract: (
|
|
108
|
+
context: RenderFeatureExtractContext,
|
|
109
|
+
): Result<BarrelDistortionFeatureFrame, RenderError> =>
|
|
110
|
+
ok({ active: (context.selectedCamera?.barrelDistortion?.strength ?? 0) > 0 }),
|
|
111
|
+
plan: (
|
|
112
|
+
data: BarrelDistortionFeatureFrame,
|
|
113
|
+
_context: RenderFeaturePlanContext,
|
|
114
|
+
): Result<RenderFeaturePlan, RenderError> =>
|
|
115
|
+
ok({
|
|
116
|
+
resources: data.active
|
|
117
|
+
? [
|
|
118
|
+
{
|
|
119
|
+
kind: 'fullscreen-program' as const,
|
|
120
|
+
name: BARREL_DISTORTION_POST_PROCESS_ID,
|
|
121
|
+
source: BARREL_DISTORTION_WGSL,
|
|
122
|
+
reads: ['ldrColor'],
|
|
123
|
+
params: { byteSize: 16, defaultValue: new Uint8Array(16) },
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
kind: 'graphics-program' as const,
|
|
127
|
+
name: 'barrel-distortion-pipeline',
|
|
128
|
+
program: {
|
|
129
|
+
shader: BARREL_DISTORTION_POST_PROCESS_ID,
|
|
130
|
+
vertexLayout: 'none',
|
|
131
|
+
colorFormats: ['rgba16float'],
|
|
132
|
+
sampleCount: 1,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
kind: 'graphics-bindings' as const,
|
|
137
|
+
name: 'barrel-distortion-bindings',
|
|
138
|
+
program: 'barrel-distortion-pipeline',
|
|
139
|
+
values: {
|
|
140
|
+
group: 1,
|
|
141
|
+
fullscreen: true,
|
|
142
|
+
shader: BARREL_DISTORTION_POST_PROCESS_ID,
|
|
143
|
+
input: 'barrel-input',
|
|
144
|
+
},
|
|
145
|
+
logicalTargets: { input: 'barrel-input' },
|
|
146
|
+
},
|
|
147
|
+
]
|
|
148
|
+
: [],
|
|
149
|
+
passes: data.active
|
|
150
|
+
? [
|
|
151
|
+
{
|
|
152
|
+
kind: 'raster' as const,
|
|
153
|
+
name: 'barrel-distortion',
|
|
154
|
+
colorAttachments: [
|
|
155
|
+
{ target: 'barrel-output', loadOp: 'clear' as const, storeOp: 'store' as const },
|
|
156
|
+
],
|
|
157
|
+
sampledTargets: ['barrel-input'],
|
|
158
|
+
draws: [
|
|
159
|
+
{
|
|
160
|
+
program: 'barrel-distortion-pipeline',
|
|
161
|
+
bindings: ['barrel-distortion-bindings'],
|
|
162
|
+
vertexData: [],
|
|
163
|
+
vertexLayout: 'none' as const,
|
|
164
|
+
draw: { kind: 'draw' as const, vertexCount: 3, instanceCount: 1 },
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
]
|
|
169
|
+
: [],
|
|
170
|
+
}),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
@@ -8,22 +8,33 @@ import type { RenderError } from '../errors/render';
|
|
|
8
8
|
*/
|
|
9
9
|
export const PENDING_RENDER_FEATURE_ERROR_REPORT_INTERVAL_FRAMES = 60;
|
|
10
10
|
|
|
11
|
+
export interface PendingRenderFeatureErrorReport {
|
|
12
|
+
readonly frame: number;
|
|
13
|
+
readonly fingerprint: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
export function shouldReportPendingRenderFeatureError(
|
|
12
|
-
lastReportedFrame: Map<string,
|
|
17
|
+
lastReportedFrame: Map<string, PendingRenderFeatureErrorReport>,
|
|
13
18
|
key: string,
|
|
14
19
|
frameNumber: number,
|
|
20
|
+
fingerprint = '',
|
|
15
21
|
intervalFrames = PENDING_RENDER_FEATURE_ERROR_REPORT_INTERVAL_FRAMES,
|
|
16
22
|
): boolean {
|
|
17
23
|
const lastReported = lastReportedFrame.get(key);
|
|
18
|
-
if (
|
|
19
|
-
|
|
24
|
+
if (
|
|
25
|
+
lastReported !== undefined &&
|
|
26
|
+
lastReported.fingerprint === fingerprint &&
|
|
27
|
+
frameNumber - lastReported.frame < intervalFrames
|
|
28
|
+
)
|
|
29
|
+
return false;
|
|
30
|
+
lastReportedFrame.set(key, { frame: frameNumber, fingerprint });
|
|
20
31
|
return true;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
export function reportPendingRenderFeatureErrors(
|
|
24
35
|
errors: readonly RenderError[],
|
|
25
36
|
frameNumber: number,
|
|
26
|
-
lastReportedFrame: Map<string,
|
|
37
|
+
lastReportedFrame: Map<string, PendingRenderFeatureErrorReport>,
|
|
27
38
|
errorRegistry: { fire(error: RenderError): void },
|
|
28
39
|
): void {
|
|
29
40
|
for (const error of errors) {
|
|
@@ -36,7 +47,16 @@ export function reportPendingRenderFeatureErrors(
|
|
|
36
47
|
// failures still receive first/periodic reporting.
|
|
37
48
|
if (isSilentRenderFeatureWarmup(error)) continue;
|
|
38
49
|
const key = pendingRenderFeatureErrorKey(error);
|
|
39
|
-
|
|
50
|
+
const cause = error.code === 'render-feature-stage-failed' ? error.detail.cause : undefined;
|
|
51
|
+
const causeText =
|
|
52
|
+
cause instanceof Error
|
|
53
|
+
? `${cause.name}\0${cause.message}`
|
|
54
|
+
: typeof cause === 'string'
|
|
55
|
+
? cause
|
|
56
|
+
: '';
|
|
57
|
+
const fingerprint = `${error.expected}\0${error.hint}\0${causeText}`;
|
|
58
|
+
// Retain one record per owner, not one record per changing cause string.
|
|
59
|
+
if (shouldReportPendingRenderFeatureError(lastReportedFrame, key, frameNumber, fingerprint)) {
|
|
40
60
|
errorRegistry.fire(error);
|
|
41
61
|
}
|
|
42
62
|
}
|
|
@@ -74,5 +94,5 @@ function pendingRenderFeatureErrorKey(error: RenderError): string {
|
|
|
74
94
|
detail !== undefined && 'order' in detail && typeof detail.order === 'number'
|
|
75
95
|
? detail.order
|
|
76
96
|
: -1;
|
|
77
|
-
return `${error.code}\0${featureIdentity}\0${order}
|
|
97
|
+
return `${error.code}\0${featureIdentity}\0${order}`;
|
|
78
98
|
}
|
package/src/features/host.ts
CHANGED
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
PreparedGraphicsResolver,
|
|
18
18
|
PreparedGraphicsResourceLease,
|
|
19
19
|
} from '../prepare/prepared-graphics-resolver';
|
|
20
|
+
import type { CameraSnapshot } from '../render-contract';
|
|
20
21
|
import { isSceneDataTarget, type SceneDataTarget } from '../temporal/scene-data';
|
|
21
22
|
import { createSceneDataCatalog, type SceneDataCatalog } from '../temporal/scene-data-catalog';
|
|
22
23
|
import {
|
|
@@ -114,6 +115,7 @@ export interface RenderFeaturePlanExecutionPass {
|
|
|
114
115
|
export interface RenderFeaturePlanExecution {
|
|
115
116
|
readonly featureIdentity: string;
|
|
116
117
|
readonly order: number;
|
|
118
|
+
readonly placement?: import('./types').RenderFeaturePlacement;
|
|
117
119
|
readonly passes: readonly RenderFeaturePlanExecutionPass[];
|
|
118
120
|
}
|
|
119
121
|
|
|
@@ -134,6 +136,8 @@ export interface RenderFeatureFrameInput {
|
|
|
134
136
|
readonly worlds: readonly import('@forgeax/engine-ecs').World[];
|
|
135
137
|
readonly owner: number;
|
|
136
138
|
readonly frameNumber: number;
|
|
139
|
+
/** Renderer-selected display camera forwarded to feature extraction. */
|
|
140
|
+
readonly selectedCamera?: CameraSnapshot;
|
|
137
141
|
/** Physical render extent for bounded feature dispatch sizing. */
|
|
138
142
|
readonly frameSize?: { readonly width: number; readonly height: number };
|
|
139
143
|
readonly visibilitySnapshots?: readonly RenderFeatureWorldVisibilitySnapshot[];
|
|
@@ -144,6 +148,8 @@ export interface RenderFeatureFrameInput {
|
|
|
144
148
|
readonly sceneData?: SceneDataCatalog;
|
|
145
149
|
readonly generation?: number;
|
|
146
150
|
readonly caps: Readonly<RhiCaps>;
|
|
151
|
+
/** Normal frame-owner facts shared with producer extraction. */
|
|
152
|
+
readonly frame?: import('./types').RenderFeatureFrameContext;
|
|
147
153
|
/** Renderer-owned material binding contract projection for producer plans. */
|
|
148
154
|
readonly materialShaderBindingContract?: (
|
|
149
155
|
materialShaderId: string,
|
|
@@ -175,6 +181,8 @@ export interface RenderFeatureFrameResult {
|
|
|
175
181
|
readonly errors: readonly RenderError[];
|
|
176
182
|
readonly plans: readonly RenderFeaturePlannedFrame[];
|
|
177
183
|
readonly fullscreenEffects: ReadonlyMap<string, PostProcessShaderEntry>;
|
|
184
|
+
/** Public Standard post-effect identities; graph-local fullscreen resources are not included. */
|
|
185
|
+
readonly postProcessIdentities: readonly string[];
|
|
178
186
|
readonly preparedResourceBatches: readonly RenderFeaturePreparedResourceBatch[];
|
|
179
187
|
/**
|
|
180
188
|
* True only when the current graph resolves a transient graphics lease.
|
|
@@ -223,6 +231,8 @@ export interface RenderFeatureHost {
|
|
|
223
231
|
recover(input: RenderFeatureRecoverInput): Result<void, RenderError>;
|
|
224
232
|
createRecoveryRoot(scope: DeviceScope): LifecycleResourceSpec<unknown>;
|
|
225
233
|
diagnostics(): readonly RenderFeatureDiagnostics[];
|
|
234
|
+
/** Retain an explicitly producer-published detached inspection value. */
|
|
235
|
+
setInspection(identity: string, inspection: unknown): void;
|
|
226
236
|
/** Subscribe to lifecycle projection changes; unchanged active frames are silent. */
|
|
227
237
|
subscribeDiagnostics(listener: () => void): () => void;
|
|
228
238
|
/** Detached signature and prepared-resource accounting for diagnostics. */
|
|
@@ -269,6 +279,7 @@ interface FeatureSlot {
|
|
|
269
279
|
readonly preparedStore: PreparedGraphicsStore;
|
|
270
280
|
status: RenderFeatureStatus;
|
|
271
281
|
latestError: RenderFeatureErrorDescriptor | undefined;
|
|
282
|
+
latestInspection?: unknown;
|
|
272
283
|
}
|
|
273
284
|
|
|
274
285
|
function freezeError(error: RenderFeatureErrorDescriptor): RenderFeatureErrorDescriptor {
|
|
@@ -291,6 +302,7 @@ function freezeDiagnostics(slot: FeatureSlot): RenderFeatureDiagnostics {
|
|
|
291
302
|
order: slot.order,
|
|
292
303
|
status: slot.status,
|
|
293
304
|
latestError: slot.latestError === undefined ? undefined : freezeError(slot.latestError),
|
|
305
|
+
...(slot.latestInspection === undefined ? {} : { inspection: slot.latestInspection }),
|
|
294
306
|
});
|
|
295
307
|
}
|
|
296
308
|
|
|
@@ -320,6 +332,16 @@ function missingCapability(
|
|
|
320
332
|
return feature.requiredCapabilities?.find((capability) => caps[capability] !== true);
|
|
321
333
|
}
|
|
322
334
|
|
|
335
|
+
/**
|
|
336
|
+
* Capability declarations gate work that the current plan actually admits.
|
|
337
|
+
* A producer is still allowed to extract and return an empty plan when its
|
|
338
|
+
* authored feature is disabled; that path must remain allocation-free on a
|
|
339
|
+
* backend which cannot support the optional feature.
|
|
340
|
+
*/
|
|
341
|
+
function hasActivePlan(plan: RenderFeaturePlan): boolean {
|
|
342
|
+
return plan.resources.length > 0 || plan.passes.length > 0;
|
|
343
|
+
}
|
|
344
|
+
|
|
323
345
|
function createPreparedGraphicsPrepare(
|
|
324
346
|
transaction: PreparedGraphicsTransaction,
|
|
325
347
|
): RenderFeatureGraphicsPrepare {
|
|
@@ -346,6 +368,9 @@ function resolveGraphicsSnapshot(
|
|
|
346
368
|
resolver: PreparedGraphicsResolver,
|
|
347
369
|
descriptor: import('./prepared-graphics').RenderFeatureGraphicsPassDescriptor,
|
|
348
370
|
generation: number,
|
|
371
|
+
resolveGpuResource?: (
|
|
372
|
+
name: string,
|
|
373
|
+
) => import('./prepared-gpu-work').RenderFeatureResolvedGpuBuffer | undefined,
|
|
349
374
|
): Result<PreparedGraphicsResolvedSnapshot, RenderError> {
|
|
350
375
|
const resources = new Map<
|
|
351
376
|
object,
|
|
@@ -364,6 +389,7 @@ function resolveGraphicsSnapshot(
|
|
|
364
389
|
...(resolver.resolveGpuBuffer === undefined
|
|
365
390
|
? {}
|
|
366
391
|
: { resolveGpuBuffer: resolver.resolveGpuBuffer }),
|
|
392
|
+
...(resolveGpuResource === undefined ? {} : { resolveGpuResource }),
|
|
367
393
|
});
|
|
368
394
|
}
|
|
369
395
|
|
|
@@ -971,6 +997,7 @@ function projectPlanPasses(
|
|
|
971
997
|
return ok({
|
|
972
998
|
featureIdentity: slot.feature.identity,
|
|
973
999
|
order: slot.order,
|
|
1000
|
+
...(slot.feature.placement === undefined ? {} : { placement: slot.feature.placement }),
|
|
974
1001
|
passes: Object.freeze(projected),
|
|
975
1002
|
});
|
|
976
1003
|
}
|
|
@@ -1330,6 +1357,13 @@ class FeatureHostImpl implements RenderFeatureHost {
|
|
|
1330
1357
|
return Object.freeze(this.slots.map(freezeDiagnostics));
|
|
1331
1358
|
}
|
|
1332
1359
|
|
|
1360
|
+
/** Retain only an explicitly producer-published detached inspection value. */
|
|
1361
|
+
setInspection(identity: string, inspection: unknown): void {
|
|
1362
|
+
const slot = findSlot(this.slots, identity);
|
|
1363
|
+
if (slot === undefined || slot.status === 'disposed') return;
|
|
1364
|
+
slot.latestInspection = inspection;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1333
1367
|
subscribeDiagnostics(listener: () => void): () => void {
|
|
1334
1368
|
this.diagnosticsListeners.add(listener);
|
|
1335
1369
|
return () => this.diagnosticsListeners.delete(listener);
|
|
@@ -1360,6 +1394,7 @@ export function runRenderFeatureFrame(
|
|
|
1360
1394
|
const errors: RenderError[] = [];
|
|
1361
1395
|
const plans: RenderFeaturePlannedFrame[] = [];
|
|
1362
1396
|
const fullscreenEffects = new Map<string, PostProcessShaderEntry>();
|
|
1397
|
+
const postProcessIdentities = new Set<string>();
|
|
1363
1398
|
const preparedResourceBatches: RenderFeaturePreparedResourceBatch[] = [];
|
|
1364
1399
|
let requiresPreparedResourceKey = false;
|
|
1365
1400
|
const hiddenEntityReports: RenderFeatureHiddenEntityReport[] = [
|
|
@@ -1370,17 +1405,18 @@ export function runRenderFeatureFrame(
|
|
|
1370
1405
|
const diagnostics = host.diagnostics();
|
|
1371
1406
|
for (const [order, feature] of host.features.entries()) {
|
|
1372
1407
|
const diagnostic = diagnostics[order];
|
|
1373
|
-
if (diagnostic?.status === '
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1408
|
+
if (diagnostic?.status === 'disposed') continue;
|
|
1409
|
+
// Preserve the existing recovery contract for a capability-disabled
|
|
1410
|
+
// feature once the device becomes capable: an explicit host.recover()
|
|
1411
|
+
// still re-admits it. While the capability is absent, however, rerun the
|
|
1412
|
+
// producer so a camera/world can disable its authored plan and recover to
|
|
1413
|
+
// an empty, zero-resource frame without a second manager.
|
|
1414
|
+
if (diagnostic?.status === 'disabled') {
|
|
1415
|
+
const diagnosticError = diagnostic.latestError;
|
|
1416
|
+
const missing = missingCapability(feature, input.caps);
|
|
1417
|
+
if (diagnosticError?.code !== 'render-feature-capability-missing' || missing === undefined) {
|
|
1418
|
+
continue;
|
|
1419
|
+
}
|
|
1384
1420
|
}
|
|
1385
1421
|
const slot: FeatureSlot = {
|
|
1386
1422
|
feature,
|
|
@@ -1391,6 +1427,9 @@ export function runRenderFeatureFrame(
|
|
|
1391
1427
|
latestError: undefined,
|
|
1392
1428
|
};
|
|
1393
1429
|
const identity = slot.feature.identity;
|
|
1430
|
+
for (const postProcess of feature.requiredFullscreenPostProcesses ?? []) {
|
|
1431
|
+
postProcessIdentities.add(postProcess.identity);
|
|
1432
|
+
}
|
|
1394
1433
|
const transaction = host.beginPreparedFrame(identity, input.generation ?? 0);
|
|
1395
1434
|
if (transaction === undefined) continue;
|
|
1396
1435
|
const graphics = createPreparedGraphicsPrepare(transaction);
|
|
@@ -1404,6 +1443,9 @@ export function runRenderFeatureFrame(
|
|
|
1404
1443
|
worlds: input.worlds,
|
|
1405
1444
|
owner: input.owner,
|
|
1406
1445
|
frameNumber: input.frameNumber,
|
|
1446
|
+
...(input.selectedCamera === undefined ? {} : { selectedCamera: input.selectedCamera }),
|
|
1447
|
+
caps: input.caps,
|
|
1448
|
+
...(input.frame === undefined ? {} : { frame: input.frame }),
|
|
1407
1449
|
reportHiddenEntity: (report) => featureHiddenEntityReports.push(report),
|
|
1408
1450
|
...(input.visibilitySnapshots === undefined
|
|
1409
1451
|
? {}
|
|
@@ -1421,6 +1463,16 @@ export function runRenderFeatureFrame(
|
|
|
1421
1463
|
host.setStatus(identity, 'failed', slot.latestError);
|
|
1422
1464
|
continue;
|
|
1423
1465
|
}
|
|
1466
|
+
if (
|
|
1467
|
+
typeof extracted.value === 'object' &&
|
|
1468
|
+
extracted.value !== null &&
|
|
1469
|
+
'inspection' in extracted.value
|
|
1470
|
+
) {
|
|
1471
|
+
host.setInspection(
|
|
1472
|
+
identity,
|
|
1473
|
+
(extracted.value as { readonly inspection?: unknown }).inspection,
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1424
1476
|
|
|
1425
1477
|
const targets = logicalTargets(input.targets ?? []);
|
|
1426
1478
|
const sceneData =
|
|
@@ -1466,21 +1518,43 @@ export function runRenderFeatureFrame(
|
|
|
1466
1518
|
host.setStatus(identity, 'failed', slot.latestError);
|
|
1467
1519
|
continue;
|
|
1468
1520
|
}
|
|
1521
|
+
const missing = missingCapability(feature, input.caps);
|
|
1522
|
+
if (missing !== undefined && hasActivePlan(frozen.value)) {
|
|
1523
|
+
const capabilityError = new RenderFeatureCapabilityMissingError(identity, order, missing);
|
|
1524
|
+
errors.push(capabilityError);
|
|
1525
|
+
transaction.abort();
|
|
1526
|
+
host.setStatus(identity, 'disabled', errorDescriptor(capabilityError));
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1469
1529
|
const plannedFrame: RenderFeaturePlannedFrame = Object.freeze({
|
|
1470
1530
|
featureIdentity: identity,
|
|
1471
1531
|
generation: transaction.generation,
|
|
1472
1532
|
signature:
|
|
1473
1533
|
host.recordPlanSignature?.(identity, frozen.value) ??
|
|
1474
1534
|
renderFeaturePlanSignature(frozen.value),
|
|
1535
|
+
...(feature.placement === undefined ? {} : { placement: feature.placement }),
|
|
1475
1536
|
plan: frozen.value,
|
|
1476
1537
|
});
|
|
1477
1538
|
for (const resource of frozen.value.resources) {
|
|
1478
1539
|
if (resource.kind !== 'fullscreen-program') continue;
|
|
1479
|
-
|
|
1540
|
+
const entry = {
|
|
1480
1541
|
source: resource.source,
|
|
1542
|
+
...(resource.fragmentEntryPoint === undefined
|
|
1543
|
+
? {}
|
|
1544
|
+
: { fragmentEntryPoint: resource.fragmentEntryPoint }),
|
|
1481
1545
|
...(resource.reads === undefined ? {} : { reads: resource.reads }),
|
|
1546
|
+
...(resource.usesView === undefined ? {} : { usesView: resource.usesView }),
|
|
1547
|
+
...(resource.storageBindings === undefined
|
|
1548
|
+
? {}
|
|
1549
|
+
: { storageBindings: resource.storageBindings }),
|
|
1482
1550
|
...(resource.params === undefined ? {} : { params: resource.params }),
|
|
1483
|
-
}
|
|
1551
|
+
} satisfies PostProcessShaderEntry;
|
|
1552
|
+
// A feature may expose more than one graph-local fullscreen producer
|
|
1553
|
+
// (the cloud display composite and its shadow map). Keep each resource
|
|
1554
|
+
// addressable by its declared name and retain the feature identity alias
|
|
1555
|
+
// for the original public post-process route.
|
|
1556
|
+
fullscreenEffects.set(resource.name, entry);
|
|
1557
|
+
if (!fullscreenEffects.has(identity)) fullscreenEffects.set(identity, entry);
|
|
1484
1558
|
}
|
|
1485
1559
|
const prepared = preparePlanResources(slot, frozen.value, graphics, gpu, input.targets ?? []);
|
|
1486
1560
|
if (!prepared.ok) {
|
|
@@ -1512,7 +1586,33 @@ export function runRenderFeatureFrame(
|
|
|
1512
1586
|
: (descriptor: import('./prepared-graphics').RenderFeatureGraphicsPassDescriptor) => {
|
|
1513
1587
|
// A pending pass can be skipped while earlier passes remain usable.
|
|
1514
1588
|
// Keep their shared resolver leases alive until submission retires them.
|
|
1515
|
-
|
|
1589
|
+
const resolveGpuResource = (name: string) => {
|
|
1590
|
+
const owned = prepared.value.buffers.get(name);
|
|
1591
|
+
const borrowed = prepared.value.preparedGpuResources.get(name);
|
|
1592
|
+
const reference =
|
|
1593
|
+
owned ?? (borrowed?.kind === 'buffer' ? borrowed.reference : undefined);
|
|
1594
|
+
return reference === undefined ? undefined : gpu?.resolveBuffer(reference);
|
|
1595
|
+
};
|
|
1596
|
+
const resolved = resolveGraphicsSnapshot(
|
|
1597
|
+
resolver,
|
|
1598
|
+
descriptor,
|
|
1599
|
+
transaction.generation,
|
|
1600
|
+
resolveGpuResource,
|
|
1601
|
+
);
|
|
1602
|
+
// A pending pipeline is a retryable partial frame. The resolver
|
|
1603
|
+
// leases cover resources used by earlier ready passes and must
|
|
1604
|
+
// stay retained until the submitted batch retires; only terminal
|
|
1605
|
+
// resolution failures release them here.
|
|
1606
|
+
if (
|
|
1607
|
+
!resolved.ok &&
|
|
1608
|
+
!(
|
|
1609
|
+
resolved.error instanceof RenderFeaturePreparationFailedError &&
|
|
1610
|
+
resolved.error.detail.reason === 'pipeline-pending'
|
|
1611
|
+
)
|
|
1612
|
+
) {
|
|
1613
|
+
resolver.release();
|
|
1614
|
+
}
|
|
1615
|
+
return resolved;
|
|
1516
1616
|
};
|
|
1517
1617
|
const releaseResolver = (): void => {
|
|
1518
1618
|
if (resolver !== undefined) resolver.release();
|
|
@@ -1577,6 +1677,7 @@ export function runRenderFeatureFrame(
|
|
|
1577
1677
|
errors,
|
|
1578
1678
|
plans,
|
|
1579
1679
|
fullscreenEffects,
|
|
1680
|
+
postProcessIdentities: Object.freeze([...postProcessIdentities]),
|
|
1580
1681
|
preparedResourceBatches,
|
|
1581
1682
|
requiresPreparedResourceKey,
|
|
1582
1683
|
hiddenEntityReports: mergeHiddenEntityReports(hiddenEntityReports),
|
package/src/features/plan.ts
CHANGED
|
@@ -51,7 +51,13 @@ export interface RenderFeatureFullscreenProgramDeclaration {
|
|
|
51
51
|
readonly kind: 'fullscreen-program';
|
|
52
52
|
readonly name: string;
|
|
53
53
|
readonly source: string;
|
|
54
|
+
/** Optional fragment entry point when one WGSL module owns multiple passes. */
|
|
55
|
+
readonly fragmentEntryPoint?: string;
|
|
54
56
|
readonly reads?: readonly RenderFeatureFullscreenRead[];
|
|
57
|
+
/** Bind the renderer-owned View group at group(0) for camera reconstruction. */
|
|
58
|
+
readonly usesView?: boolean;
|
|
59
|
+
/** Read-only storage buffers appended after the regular color/depth reads. */
|
|
60
|
+
readonly storageBindings?: readonly number[];
|
|
55
61
|
readonly params?: {
|
|
56
62
|
readonly byteSize: number;
|
|
57
63
|
readonly defaultValue: Uint8Array;
|
|
@@ -275,6 +281,8 @@ export interface RenderFeaturePlannedFrame {
|
|
|
275
281
|
readonly generation: number;
|
|
276
282
|
readonly signature: string;
|
|
277
283
|
readonly plan: RenderFeaturePlan;
|
|
284
|
+
/** Placement selected by the installed feature; omitted means the legacy post stage. */
|
|
285
|
+
readonly placement?: import('./types').RenderFeaturePlacement;
|
|
278
286
|
}
|
|
279
287
|
|
|
280
288
|
export interface RenderFeatureDerivedAccess {
|