@forgeax/engine-render 0.1.33 → 0.1.35
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 +1062 -127
- 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/device-feature-admission.d.ts +2 -2
- 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 +6 -5
- 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/render-target-host.d.ts +5 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -1
- 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 +2 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -4
- package/dist/authoring.mjs.map +1 -1
- package/dist/barrel-distortion.d.ts +47 -0
- package/dist/barrel-distortion.d.ts.map +1 -0
- package/dist/chunk-3XUBWRY2.mjs +1842 -0
- package/dist/chunk-3XUBWRY2.mjs.map +1 -0
- package/dist/{chunk-OO3DRYK7.mjs → chunk-G6HDNGY7.mjs} +2400 -1767
- package/dist/chunk-G6HDNGY7.mjs.map +1 -0
- package/dist/{chunk-ZDQWGQW7.mjs → chunk-LM5IE7GF.mjs} +4 -4
- package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
- package/dist/{chunk-VOZWDM3L.mjs → chunk-LNIUIKQ7.mjs} +1514 -498
- package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
- package/dist/chunk-MXTWKZO4.mjs +3268 -0
- package/dist/chunk-MXTWKZO4.mjs.map +1 -0
- package/dist/chunk-MZ4C7EHF.mjs +6942 -0
- package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
- package/dist/chunk-RIPAEGI6.mjs +48 -0
- package/dist/chunk-RIPAEGI6.mjs.map +1 -0
- package/dist/{chunk-LEAXOMYJ.mjs → chunk-SGPUJW3F.mjs} +117 -5
- package/dist/chunk-SGPUJW3F.mjs.map +1 -0
- package/dist/{chunk-PA5DRJNI.mjs → chunk-X2KA6WHM.mjs} +29 -4
- package/dist/chunk-X2KA6WHM.mjs.map +1 -0
- package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
- package/dist/chunk-XSFB7XXQ.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 +8406 -5785
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -19
- package/dist/device/gpu-residency.d.ts.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 +20 -5
- 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/extract/material-context.d.ts +7 -0
- package/dist/extract/material-context.d.ts.map +1 -0
- 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 +15 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/plan.d.ts +10 -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 +48 -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/glyph-text-layout-system.d.ts +1 -1
- package/dist/glyph-text-layout-system.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/frame-resources.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +14 -5
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +30 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +780 -9
- 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 +47 -100
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -8
- package/dist/internal.mjs.map +1 -1
- package/dist/pbr-pipeline.d.ts +22 -4
- 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/lut-gpu.d.ts +2 -2
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
- package/dist/pipeline/standard-output/resources.d.ts +2 -2
- package/dist/pipeline/standard-output/resources.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/publication/contract.d.ts +77 -0
- package/dist/publication/contract.d.ts.map +1 -0
- package/dist/publication/dependencies.d.ts +7 -0
- package/dist/publication/dependencies.d.ts.map +1 -0
- package/dist/publication/prepare-geometry.d.ts +9 -0
- package/dist/publication/prepare-geometry.d.ts.map +1 -0
- package/dist/publication/programs.d.ts +5 -0
- package/dist/publication/programs.d.ts.map +1 -0
- package/dist/publication/publisher.d.ts +33 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/receiver.d.ts +29 -0
- package/dist/publication/receiver.d.ts.map +1 -0
- package/dist/publication/resource-scope.d.ts +18 -0
- package/dist/publication/resource-scope.d.ts.map +1 -0
- package/dist/publication/targets.d.ts +33 -0
- package/dist/publication/targets.d.ts.map +1 -0
- package/dist/publication/video.d.ts +5 -0
- package/dist/publication/video.d.ts.map +1 -0
- 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 +43 -9
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +15 -65
- 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/helpers.d.ts +2 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +22 -6
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +14 -10
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +3 -16
- 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/prepared-material-bindings.d.ts +3 -3
- package/dist/record/prepared-material-bindings.d.ts.map +1 -1
- 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 +24 -5
- 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/sprite-instance-buffer.d.ts +31 -0
- package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
- package/dist/record/target-capture-graph.d.ts +19 -0
- package/dist/record/target-capture-graph.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +24 -15
- 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 +14 -4
- 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 +46 -5
- 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 +18 -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-projections.d.ts +3 -2
- package/dist/render-system-projections.d.ts.map +1 -1
- 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 +22 -21
- 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 +18 -7
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/render-source.d.ts +42 -0
- package/dist/scene/render-source.d.ts.map +1 -0
- package/dist/scene/source-systems.d.ts +6 -0
- package/dist/scene/source-systems.d.ts.map +1 -0
- 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/systems/skin-palette-types.d.ts +10 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +2 -2
- package/dist/systems/transparent-dispatch.d.ts.map +1 -1
- package/dist/systems/transparent-sort-config.d.ts +2 -1
- package/dist/systems/transparent-sort-config.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 +6 -7
- 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__/auto-exposure-transaction.integration.test.ts +4 -9
- 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-feature-admission.unit.test.ts +3 -2
- 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 +5 -6
- 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__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +145 -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__/materials-standard-contract.unit.test.ts +0 -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 +66 -8
- package/src/__tests__/physical-material-budget.unit.test.ts +40 -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 +8 -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 +42 -8
- 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/device-feature-admission.ts +2 -2
- 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 +8 -5
- 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 +50 -18
- package/src/assembly/render-feature-post-processes.ts +54 -0
- package/src/assembly/render-target-host.ts +57 -47
- package/src/assembly/renderer-facade.ts +7 -2
- 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 +116 -62
- 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 +303 -313
- 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/device/gpu-residency.ts +26 -25
- package/src/dynamic-geometry.ts +12 -1
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +47 -8
- 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/extract/material-context.ts +21 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +26 -6
- package/src/features/host.ts +128 -19
- package/src/features/plan.ts +10 -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 +51 -0
- package/src/fullscreen-post-process-pass.ts +41 -9
- package/src/glyph-text-layout-system.ts +2 -2
- 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/frame-resources.ts +0 -1
- package/src/ibl/skylight-bind-group.ts +62 -32
- package/src/index.ts +205 -9
- package/src/inspection-types.ts +162 -0
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +152 -569
- package/src/pbr-pipeline.ts +230 -30
- 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/lut-gpu.ts +3 -3
- package/src/pipeline/standard-output/resources.ts +2 -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/publication/__tests__/derived-geometry.integration.test.ts +177 -0
- package/src/publication/__tests__/features.integration.test.ts +122 -0
- package/src/publication/__tests__/programs.unit.test.ts +25 -0
- package/src/publication/__tests__/publication.integration.test.ts +370 -0
- package/src/publication/__tests__/targets.integration.test.ts +120 -0
- package/src/publication/__tests__/video.browser.test.ts +50 -0
- package/src/publication/contract.ts +104 -0
- package/src/publication/dependencies.ts +54 -0
- package/src/publication/prepare-geometry.ts +94 -0
- package/src/publication/programs.ts +45 -0
- package/src/publication/publisher.ts +618 -0
- package/src/publication/receiver.ts +297 -0
- package/src/publication/resource-scope.ts +31 -0
- package/src/publication/targets.ts +182 -0
- package/src/publication/video.ts +33 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +9 -11
- 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__/video-texture-view.unit.test.ts +9 -9
- 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 +855 -0
- package/src/record/fold-instance-buffer.ts +51 -0
- package/src/record/frame-lighting.ts +36 -2
- package/src/record/frame-snapshot.ts +45 -9
- package/src/record/frame.ts +258 -1105
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/helpers.ts +2 -2
- package/src/record/main-pass-geometry.ts +272 -84
- package/src/record/main-pass-material.ts +102 -36
- package/src/record/main-pass-sprite-draws.ts +13 -217
- package/src/record/main-pass.ts +164 -27
- package/src/record/motion-blur-receipt.ts +91 -0
- package/src/record/prepared-material-bindings.ts +11 -6
- package/src/record/probe-blend-buffer.ts +180 -0
- package/src/record/recovery-pipeline.ts +35 -3
- package/src/record/render-context.ts +41 -5
- package/src/record/shadow-pass.ts +30 -4
- package/src/record/skybox-post-pass.ts +28 -4
- package/src/record/sprite-instance-buffer.ts +155 -0
- package/src/record/target-capture-graph.ts +258 -0
- package/src/record/typed-frame-graph.ts +776 -340
- package/src/record/view-ubo.ts +27 -4
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +243 -50
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +54 -5
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +130 -0
- package/src/render-system-extract-tail.ts +90 -78
- package/src/render-system-extract.ts +76 -76
- package/src/render-system-presentation.ts +56 -0
- package/src/render-system-producer-roots.ts +96 -0
- package/src/render-system-projections.ts +3 -2
- package/src/render-system-residency.ts +159 -0
- package/src/render-system.ts +421 -408
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +416 -337
- package/src/scene/render-source.ts +90 -0
- package/src/scene/source-systems.ts +33 -0
- 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 +5 -1
- package/src/systems/skin-palette-types.ts +11 -0
- package/src/systems/transparent-dispatch.ts +2 -2
- package/src/systems/transparent-sort-config.ts +3 -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 +0 -1610
- package/dist/chunk-3RTCJTH4.mjs.map +0 -1
- package/dist/chunk-BLXGONR2.mjs.map +0 -1
- package/dist/chunk-ILQ5MEZF.mjs +0 -32
- package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
- package/dist/chunk-LEAXOMYJ.mjs.map +0 -1
- package/dist/chunk-NB2S7ZRX.mjs +0 -1783
- 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 +0 -1907
- package/dist/chunk-PLAXOOX5.mjs.map +0 -1
- package/dist/chunk-RXZ3RGOU.mjs +0 -53
- package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
- package/dist/chunk-VOZWDM3L.mjs.map +0 -1
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
DynamicTextureStore,
|
|
7
7
|
} from '@forgeax/engine-assets-runtime';
|
|
8
8
|
import { audioLoader } from '@forgeax/engine-audio-webaudio';
|
|
9
|
-
import {
|
|
9
|
+
import type { World } from '@forgeax/engine-ecs';
|
|
10
10
|
import { createRenderReadLease, type RenderReadLease } from '@forgeax/engine-ecs/projection';
|
|
11
11
|
import {
|
|
12
12
|
DEFAULT_VERTEX_ATTRIBUTE_MAP,
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
} from '@forgeax/engine-geometry';
|
|
15
15
|
import type {
|
|
16
16
|
BindGroupLayout,
|
|
17
|
-
Buffer,
|
|
18
17
|
PipelineLayout,
|
|
19
18
|
RenderPipeline,
|
|
20
19
|
Result,
|
|
@@ -22,12 +21,14 @@ import type {
|
|
|
22
21
|
RhiDevice,
|
|
23
22
|
} from '@forgeax/engine-rhi';
|
|
24
23
|
import { err, ok, RhiError, validateDrawArgs } from '@forgeax/engine-rhi';
|
|
25
|
-
import { registerPropagateTransforms } from '@forgeax/engine-scene';
|
|
26
24
|
import {
|
|
27
25
|
findVariantByKey,
|
|
28
26
|
type MaterialShaderEntry,
|
|
29
27
|
type MaterialShaderManifestEntry,
|
|
30
28
|
ShaderCatalog,
|
|
29
|
+
SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
|
|
30
|
+
SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
|
|
31
|
+
SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
|
|
31
32
|
standardPhysicalTextureFields,
|
|
32
33
|
} from '@forgeax/engine-shader';
|
|
33
34
|
import type {
|
|
@@ -37,6 +38,11 @@ import type {
|
|
|
37
38
|
PrimitiveTopology,
|
|
38
39
|
VertexAttributeMap,
|
|
39
40
|
} from '@forgeax/engine-types';
|
|
41
|
+
import { type PublishedRenderFrameInput, RenderPublicationError } from '../publication/contract';
|
|
42
|
+
import { installPublicationPrograms } from '../publication/programs';
|
|
43
|
+
import { type PreparedRenderPublication, RenderPublicationReceiver } from '../publication/receiver';
|
|
44
|
+
import { RenderPublicationTargetReceiver } from '../publication/targets';
|
|
45
|
+
import { registerRenderSourceSystems } from '../scene/source-systems';
|
|
40
46
|
import { transmissionBackdropAvailable } from './device-feature-admission';
|
|
41
47
|
|
|
42
48
|
export type { MaterialShaderManifestEntry } from '@forgeax/engine-shader';
|
|
@@ -53,6 +59,10 @@ import {
|
|
|
53
59
|
RenderFeatureCapabilityMissingError,
|
|
54
60
|
RenderFeatureStageFailedError,
|
|
55
61
|
} from '../errors/render';
|
|
62
|
+
import {
|
|
63
|
+
BARREL_DISTORTION_FEATURE_IDENTITY,
|
|
64
|
+
createBarrelDistortionRenderFeature,
|
|
65
|
+
} from '../features/barrel-distortion';
|
|
56
66
|
import {
|
|
57
67
|
dofInspection,
|
|
58
68
|
registerDepthOfFieldBuiltins,
|
|
@@ -65,7 +75,6 @@ import {
|
|
|
65
75
|
type PostProcessShaderEntry,
|
|
66
76
|
postProcessShaderModuleLabel,
|
|
67
77
|
} from '../fullscreen-post-process-pass';
|
|
68
|
-
import { glyphTextLayoutSystem } from '../glyph-text-layout-system';
|
|
69
78
|
import { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from '../gpu-stage';
|
|
70
79
|
import { type BloomInspection, emptyBloomInspection } from '../inspection-types';
|
|
71
80
|
import { DeviceScope } from '../lifecycle';
|
|
@@ -74,9 +83,13 @@ import {
|
|
|
74
83
|
isCanonicalStandardPbrMaterialShader,
|
|
75
84
|
isStandardPbrMaterialShader,
|
|
76
85
|
type PipelineGroup2Contract,
|
|
77
|
-
resolvePipelineGroup2Contract,
|
|
78
86
|
SKIN_MATERIAL_SHADER_ID,
|
|
79
87
|
} from '../pbr-pipeline';
|
|
88
|
+
import {
|
|
89
|
+
SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID,
|
|
90
|
+
SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID,
|
|
91
|
+
SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID,
|
|
92
|
+
} from '../pipeline/single-layer-medium-passes';
|
|
80
93
|
import { standardPipeline } from '../pipeline/standard-pipeline';
|
|
81
94
|
import { DEFAULT_STANDARD_PROFILE } from '../pipeline/standard-profile';
|
|
82
95
|
import { buildPipelineForMaterialShader } from '../pipeline-builder';
|
|
@@ -132,7 +145,7 @@ import type {
|
|
|
132
145
|
SsrShaderSources,
|
|
133
146
|
VolumetricFogShaderSources,
|
|
134
147
|
} from '../render-contract';
|
|
135
|
-
import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from '../render-contract';
|
|
148
|
+
import { FXAA_POST_PROCESS_ID, STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from '../render-contract';
|
|
136
149
|
import {
|
|
137
150
|
attachGpuPassTimingSession,
|
|
138
151
|
createRenderSystem,
|
|
@@ -145,11 +158,12 @@ import {
|
|
|
145
158
|
import { createGpuPassTimingObservationStore, observeGpuPassTimingDisabled } from '../renderer.js';
|
|
146
159
|
import { postSpawnResolveJoints } from '../scene-instances/post-spawn-resolve-joints';
|
|
147
160
|
import type { RenderTarget } from '../targets/contracts';
|
|
148
|
-
import { tilemapChunkExtractSystem } from '../tilemap-chunk-extract-system';
|
|
149
161
|
import type { TypedFrameObservationCapture } from '../typed-render-graph-primitives';
|
|
150
162
|
import { registerAnalyticFogPostProcess } from './analytic-fog-registration';
|
|
151
163
|
import type { RhiBackendPack } from './backend-contract';
|
|
164
|
+
import { inspectBarrelDistortion } from './barrel-distortion-inspection';
|
|
152
165
|
import type { BundlerOptions } from './bundler-contract';
|
|
166
|
+
import { rejectZeroCanvasSize } from './canvas-draw-guard';
|
|
153
167
|
import { createRendererDynamicGeometryController } from './dynamic-geometry-host';
|
|
154
168
|
import { registerFxaaPostProcess } from './fxaa-registration';
|
|
155
169
|
import type { RendererAssemblyImplementation } from './host-contract';
|
|
@@ -157,6 +171,7 @@ import { observeLodOcclusionForReceipt } from './lod-observation';
|
|
|
157
171
|
import {
|
|
158
172
|
isEngineOwnedMaterialShader,
|
|
159
173
|
resolveMaterialPipelineBindGroups,
|
|
174
|
+
resolveMaterialPipelineGroup2Contract,
|
|
160
175
|
resolveMaterialPipelineShaderId,
|
|
161
176
|
resolveMaterialPipelineVertexEntry,
|
|
162
177
|
resolveRendererMaterialShaderArtifact,
|
|
@@ -169,6 +184,7 @@ import {
|
|
|
169
184
|
type MaterialShaderBindingContract,
|
|
170
185
|
makeShaderDeviceAdapter,
|
|
171
186
|
normalizeMaterialShaderVariantSet,
|
|
187
|
+
prepareLowLimitMaterialShaderEntry,
|
|
172
188
|
prepareMaterialShaders,
|
|
173
189
|
resolveMaterialShaderBackendArtifactKey,
|
|
174
190
|
resolveMaterialShaderBindingContract,
|
|
@@ -188,6 +204,7 @@ import {
|
|
|
188
204
|
publishGeneration,
|
|
189
205
|
} from './recovery/generation';
|
|
190
206
|
import { createRendererRecovery, type RendererRecovery } from './recovery/renderer-recover';
|
|
207
|
+
import { collectRequiredFullscreenPostProcesses } from './render-feature-post-processes';
|
|
191
208
|
import { createRenderTargetHost } from './render-target-host';
|
|
192
209
|
import {
|
|
193
210
|
freezeRenderProfile,
|
|
@@ -198,6 +215,7 @@ import { projectRendererFeatureInspection } from './renderer-feature-inspection'
|
|
|
198
215
|
import {
|
|
199
216
|
type ContinuationTerminator,
|
|
200
217
|
createContinuationTerminator,
|
|
218
|
+
guardFrameCompletion,
|
|
201
219
|
} from './renderer-frame-transaction';
|
|
202
220
|
import {
|
|
203
221
|
ensureContextConfigured,
|
|
@@ -205,7 +223,7 @@ import {
|
|
|
205
223
|
rendererInitializationPipelineError,
|
|
206
224
|
wrapDisposeError,
|
|
207
225
|
} from './renderer-helpers';
|
|
208
|
-
import {
|
|
226
|
+
import { projectRendererOutputInspectionFromSurface } from './renderer-inspection';
|
|
209
227
|
import {
|
|
210
228
|
createRecoveryContinuation,
|
|
211
229
|
createRecoveryDeadline,
|
|
@@ -229,7 +247,10 @@ import {
|
|
|
229
247
|
type WebGPURendererInternals,
|
|
230
248
|
} from './webgpu-renderer-bootstrap';
|
|
231
249
|
import type { WebGPUOutcome } from './webgpu-renderer-contract';
|
|
232
|
-
import {
|
|
250
|
+
import {
|
|
251
|
+
createRendererObservationCaptureOwner,
|
|
252
|
+
type ObservationCaptureRead,
|
|
253
|
+
} from './webgpu-renderer-observation-owner';
|
|
233
254
|
import {
|
|
234
255
|
isPreparedMaterialVertexLayout,
|
|
235
256
|
PREPARED_INSTANCE_VERTEX_ATTRS,
|
|
@@ -257,6 +278,7 @@ export {
|
|
|
257
278
|
selectNoColorPbrVariant,
|
|
258
279
|
selectPipelineLayoutForVariant,
|
|
259
280
|
shouldDeferMissingPreparedMaterialShader,
|
|
281
|
+
stripCloudShadowBindingsForLowLimit,
|
|
260
282
|
} from './material-shader-policy';
|
|
261
283
|
export {
|
|
262
284
|
createMeshSsboGrowController,
|
|
@@ -283,7 +305,6 @@ export type { WebGPUOutcome, WebGPURendererInternals } from './webgpu-renderer-c
|
|
|
283
305
|
export { disposeObservationCaptureSet } from './webgpu-renderer-observation';
|
|
284
306
|
|
|
285
307
|
/** Bundler injection and the WebGPU renderer construction entry points. */
|
|
286
|
-
let nextDerivedSystemId = 0;
|
|
287
308
|
export async function tryCreateWebGPURenderer(
|
|
288
309
|
canvas: HTMLCanvasElement | OffscreenCanvas,
|
|
289
310
|
options: RendererOptions | undefined,
|
|
@@ -295,7 +316,12 @@ export async function tryCreateWebGPURenderer(
|
|
|
295
316
|
async function makeWebGPURenderer(
|
|
296
317
|
internals: WebGPURendererInternals,
|
|
297
318
|
): Promise<RendererAssemblyImplementation> {
|
|
319
|
+
let publicationTargets: RenderPublicationTargetReceiver | undefined;
|
|
298
320
|
let disposed = false;
|
|
321
|
+
const publicationReceiver =
|
|
322
|
+
internals.options?.publicationSource === undefined
|
|
323
|
+
? undefined
|
|
324
|
+
: new RenderPublicationReceiver(internals.options.publicationSource);
|
|
299
325
|
const observeTiming = observeGpuPassTimingDisabled;
|
|
300
326
|
const frameContinuations = new Set<ContinuationTerminator>();
|
|
301
327
|
type RecoveryInspection = RenderInspection['recovery'];
|
|
@@ -333,7 +359,13 @@ async function makeWebGPURenderer(
|
|
|
333
359
|
let renderTargetDevice = internals.device;
|
|
334
360
|
let renderTargetGeneration = 0;
|
|
335
361
|
let renderSystemForTargetPromotion: RenderSystem | undefined;
|
|
336
|
-
const
|
|
362
|
+
const requestedFeatures = internals.options?.features ?? [];
|
|
363
|
+
const featureHostFeatures = requestedFeatures.some(
|
|
364
|
+
(f) => f.identity === BARREL_DISTORTION_FEATURE_IDENTITY,
|
|
365
|
+
)
|
|
366
|
+
? requestedFeatures
|
|
367
|
+
: [...requestedFeatures, createBarrelDistortionRenderFeature()];
|
|
368
|
+
const featureHostResult = createRenderFeatureHost(featureHostFeatures);
|
|
337
369
|
if (!featureHostResult.ok) throw featureHostResult.error;
|
|
338
370
|
internals.featureHost = featureHostResult.value;
|
|
339
371
|
let rendererRecovery: RendererRecovery | undefined;
|
|
@@ -466,27 +498,8 @@ async function makeWebGPURenderer(
|
|
|
466
498
|
featureHostResult.value.features.flatMap((feature) => feature.requiredMaterialShaders ?? []),
|
|
467
499
|
);
|
|
468
500
|
let requiredMaterialShaders = Object.freeze([...requiredMaterialShaderSet]);
|
|
469
|
-
|
|
470
|
-
features
|
|
471
|
-
): readonly { readonly identity: string; readonly source: string }[] => {
|
|
472
|
-
const entries = new Map<string, { readonly identity: string; readonly source: string }>();
|
|
473
|
-
for (const feature of features) {
|
|
474
|
-
for (const entry of feature.requiredFullscreenPostProcesses ?? []) {
|
|
475
|
-
const existing = entries.get(entry.identity);
|
|
476
|
-
if (existing !== undefined && existing.source !== entry.source) {
|
|
477
|
-
throw new RhiError({
|
|
478
|
-
code: 'internal-error',
|
|
479
|
-
expected: `fullscreen identity '${entry.identity}' has one source across render features`,
|
|
480
|
-
hint: 'rename the conflicting fullscreen identity or make its WGSL source identical',
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
entries.set(entry.identity, entry);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
return Object.freeze([...entries.values()]);
|
|
487
|
-
};
|
|
488
|
-
let requiredFullscreenPostProcesses = collectRequiredFullscreenPostProcesses(
|
|
489
|
-
featureHostResult.value.features,
|
|
501
|
+
let requiredFullscreenPostProcesses = Object.freeze(
|
|
502
|
+
collectRequiredFullscreenPostProcesses(featureHostResult.value.features),
|
|
490
503
|
);
|
|
491
504
|
// Lazy ShaderCatalog instance (plan-strategy section S-10 / D-R10 / OQ-5
|
|
492
505
|
// close): constructed on first access; subsequent accesses return the
|
|
@@ -536,7 +549,7 @@ async function makeWebGPURenderer(
|
|
|
536
549
|
feature: RenderFeature<unknown>,
|
|
537
550
|
): Promise<Result<void, RhiError>> => {
|
|
538
551
|
for (const postProcess of feature.requiredFullscreenPostProcesses ?? []) {
|
|
539
|
-
const label = postProcessShaderModuleLabel(postProcess.
|
|
552
|
+
const label = postProcessShaderModuleLabel(postProcess.source);
|
|
540
553
|
const shaderResult = internals.pack.createShaderModule
|
|
541
554
|
? await internals.pack.createShaderModule(internals.device, {
|
|
542
555
|
code: postProcess.source,
|
|
@@ -577,27 +590,7 @@ async function makeWebGPURenderer(
|
|
|
577
590
|
}
|
|
578
591
|
return state.shaderInstance;
|
|
579
592
|
};
|
|
580
|
-
// D-S9: AssetRegistry instance shared with RenderSystem. RenderSystem
|
|
581
|
-
// looks up MeshFilter.assetHandle here per frame; buildReadyWebGPU step 3
|
|
582
|
-
// uploads the registry's builtin mesh geometry to GPU buffers so the
|
|
583
|
-
// RenderSystem can route MeshFilter.assetHandle to a real (vbo, ibo) pair.
|
|
584
|
-
// feat-20260527 M1 / w1: ShaderCatalog is now eager-constructed and
|
|
585
|
-
// constructor-injected into AssetRegistry (plan-strategy D-1). The
|
|
586
|
-
// ShaderCatalogDevice adapter (shared between the catalog and per-MaterialShader
|
|
587
|
-
// pipeline cache) is already available at this point.
|
|
588
593
|
const shaderCatalog = getShader();
|
|
589
|
-
// bug-20260601-hello-tonemap-material-register M1 (plan-strategy D-1):
|
|
590
|
-
// All material-shader entries are now registered from the manifest
|
|
591
|
-
// BEFORE the renderer is returned, so `register<MaterialAsset>` referencing
|
|
592
|
-
// an engine shader succeeds without waiting for `renderer.initialization`.
|
|
593
|
-
// Host-injected ImportTransport remains a constructor-only dependency.
|
|
594
|
-
// feat-20260705-runtime-tier2-decomposition M1 / w10 (D-1 / D-2): the sole
|
|
595
|
-
// production assembly point injects (a) the post-spawn hook
|
|
596
|
-
// `postSpawnResolveJoints` (auto-wire Skin.joints; D-1) and the audio
|
|
597
|
-
// catalog-entry loader. The latter stays at this assembly boundary so
|
|
598
|
-
// assets-runtime remains independent of the concrete Web Audio backend.
|
|
599
|
-
// videoLoader is wired internally from graphics-extras; the full registry has
|
|
600
|
-
// 11 engine kinds. This is the only `new AssetRegistry(...)` call in the repo.
|
|
601
594
|
const assets = new AssetRegistry(
|
|
602
595
|
shaderCatalog,
|
|
603
596
|
internals.importTransport,
|
|
@@ -728,7 +721,9 @@ async function makeWebGPURenderer(
|
|
|
728
721
|
gpuStore.configureGpuDevice(
|
|
729
722
|
internals.device,
|
|
730
723
|
packShaderFactory,
|
|
731
|
-
(world, pod) => {
|
|
724
|
+
(world, pod, source) => {
|
|
725
|
+
// The accepted equirect identity already owns this renderer-local GPU projection.
|
|
726
|
+
if ('resolveAsset' in world) return ok(source);
|
|
732
727
|
const handle = world.allocSharedRef('EquirectAsset', pod);
|
|
733
728
|
return ok(handle);
|
|
734
729
|
},
|
|
@@ -1137,6 +1132,9 @@ async function makeWebGPURenderer(
|
|
|
1137
1132
|
const lookup = getShader().findMaterialArtifact(materialShaderId);
|
|
1138
1133
|
const source = lookup.ok ? lookup.value.source : '';
|
|
1139
1134
|
const paramSchema = lookup.ok ? lookup.value.paramSchema : explicitParamSchema;
|
|
1135
|
+
const singleLayerMedium =
|
|
1136
|
+
materialShaderId === 'forgeax::single-layer-medium' ||
|
|
1137
|
+
(lookup.ok && lookup.value.receipt?.surface?.model === 'single-layer-medium');
|
|
1140
1138
|
if (paramSchema === undefined) return null;
|
|
1141
1139
|
const cacheKey = `${materialShaderId}:${layoutKind}:${clustered}`;
|
|
1142
1140
|
const cached = cacheState.perShaderMaterialLayoutCache.get(cacheKey);
|
|
@@ -1155,7 +1153,12 @@ async function makeWebGPURenderer(
|
|
|
1155
1153
|
isStandardPbrMaterialShader(materialShaderId) ||
|
|
1156
1154
|
standardPhysicalTextureFields(paramSchema).length > 0;
|
|
1157
1155
|
const isStandardMapLayout = requiresStandardMapLayout;
|
|
1158
|
-
if (
|
|
1156
|
+
if (
|
|
1157
|
+
!clustered &&
|
|
1158
|
+
!singleLayerMedium &&
|
|
1159
|
+
!isStandardMapLayout &&
|
|
1160
|
+
isSharedMaterialUserRegionCompatible(paramSchema)
|
|
1161
|
+
) {
|
|
1159
1162
|
cacheState.perShaderMaterialLayoutCache.set(cacheKey, {
|
|
1160
1163
|
source,
|
|
1161
1164
|
paramSchema,
|
|
@@ -1165,7 +1168,11 @@ async function makeWebGPURenderer(
|
|
|
1165
1168
|
return null;
|
|
1166
1169
|
}
|
|
1167
1170
|
const spec: PipelineSpec = {
|
|
1168
|
-
shader: {
|
|
1171
|
+
shader: {
|
|
1172
|
+
id: singleLayerMedium ? 'forgeax::single-layer-medium' : materialShaderId,
|
|
1173
|
+
passKind: 'forward',
|
|
1174
|
+
variantSet: undefined,
|
|
1175
|
+
},
|
|
1169
1176
|
attachments: { colorFormats: [], depthFormat: undefined, sampleCount: 1 },
|
|
1170
1177
|
geometry: { topology: 'triangle-list', vertexLayout: {} },
|
|
1171
1178
|
renderState: undefined,
|
|
@@ -1552,7 +1559,11 @@ async function makeWebGPURenderer(
|
|
|
1552
1559
|
: getShaderModuleAdapter(),
|
|
1553
1560
|
pipelineLayout,
|
|
1554
1561
|
vertexBuffers,
|
|
1555
|
-
...(layoutKind === 'pbr-skin' ||
|
|
1562
|
+
...(layoutKind === 'pbr-skin' ||
|
|
1563
|
+
layoutKind === 'gpu-driven-skin' ||
|
|
1564
|
+
layoutKind === 'gpu-driven-cluster-skin'
|
|
1565
|
+
? { layoutKind }
|
|
1566
|
+
: {}),
|
|
1556
1567
|
};
|
|
1557
1568
|
};
|
|
1558
1569
|
/**
|
|
@@ -1619,7 +1630,10 @@ async function makeWebGPURenderer(
|
|
|
1619
1630
|
particleInputLanes?: number,
|
|
1620
1631
|
coverageOnly = false,
|
|
1621
1632
|
): RenderPipeline | null => {
|
|
1622
|
-
const declaredGroup2Contract =
|
|
1633
|
+
const declaredGroup2Contract = resolveMaterialPipelineGroup2Contract(
|
|
1634
|
+
entry.source,
|
|
1635
|
+
layoutKindOverride,
|
|
1636
|
+
);
|
|
1623
1637
|
const group2Contract =
|
|
1624
1638
|
declaredGroup2Contract === 'mesh' &&
|
|
1625
1639
|
(materialShaderId === 'forgeax::vfx-render.particles.mesh' ||
|
|
@@ -2048,6 +2062,10 @@ async function makeWebGPURenderer(
|
|
|
2048
2062
|
}
|
|
2049
2063
|
}
|
|
2050
2064
|
}
|
|
2065
|
+
shaderEntry = prepareLowLimitMaterialShaderEntry(
|
|
2066
|
+
shaderEntry,
|
|
2067
|
+
currentBuildDevice().limits.maxSampledTexturesPerShaderStage,
|
|
2068
|
+
);
|
|
2051
2069
|
// feat-20260609 M4 / R3-fixup: append `-${passKind}` to the PSO label so
|
|
2052
2070
|
// GPU debug captures (and the shadow-caster branch in the builder)
|
|
2053
2071
|
// make the cache variant visible. The fallback path above keeps the
|
|
@@ -2115,10 +2133,50 @@ async function makeWebGPURenderer(
|
|
|
2115
2133
|
) => {
|
|
2116
2134
|
const pipeline = getMaterialShaderPipeline(...args);
|
|
2117
2135
|
if (pipeline === null) return null;
|
|
2136
|
+
const materialShaderId = args[0];
|
|
2137
|
+
const variantSet = args[5];
|
|
2138
|
+
const passKind = args[6] ?? 'forward';
|
|
2139
|
+
const vertexLayoutProjection = args[13];
|
|
2140
|
+
const layoutKind = args[15];
|
|
2141
|
+
const sceneIndexAddress =
|
|
2142
|
+
layoutKind === 'gpu-driven-pbr' ||
|
|
2143
|
+
layoutKind === 'gpu-driven-skin' ||
|
|
2144
|
+
layoutKind === 'gpu-driven-cluster-pbr' ||
|
|
2145
|
+
layoutKind === 'gpu-driven-cluster-skin';
|
|
2146
|
+
const artifact = resolveRendererMaterialShaderArtifact(
|
|
2147
|
+
materialShaderId,
|
|
2148
|
+
getShader(),
|
|
2149
|
+
pipelineState?.gpuDrivenPbrPrograms,
|
|
2150
|
+
{
|
|
2151
|
+
...(vertexLayoutProjection === undefined
|
|
2152
|
+
? {}
|
|
2153
|
+
: {
|
|
2154
|
+
vertexColorAvailable: vertexLayoutProjection.attributes.some(
|
|
2155
|
+
(attribute) => attribute.key === 'color',
|
|
2156
|
+
),
|
|
2157
|
+
}),
|
|
2158
|
+
...(layoutKind === 'pbr-skin' ||
|
|
2159
|
+
layoutKind === 'gpu-driven-skin' ||
|
|
2160
|
+
layoutKind === 'gpu-driven-cluster-skin'
|
|
2161
|
+
? { deformation: 'skin' as const }
|
|
2162
|
+
: {}),
|
|
2163
|
+
...(variantSet === undefined ? {} : { variantSet }),
|
|
2164
|
+
address: sceneIndexAddress ? 'scene-index' : 'direct',
|
|
2165
|
+
pass: passKind === 'shadow-caster' ? 'shadow' : 'forward',
|
|
2166
|
+
},
|
|
2167
|
+
);
|
|
2118
2168
|
return {
|
|
2119
2169
|
pipeline,
|
|
2120
2170
|
group2Contract:
|
|
2121
2171
|
materialShaderPipelineGroup2Contracts.get(pipeline as object) ?? ('mesh' as const),
|
|
2172
|
+
...(artifact?.receipt === undefined
|
|
2173
|
+
? {}
|
|
2174
|
+
: {
|
|
2175
|
+
receipt: {
|
|
2176
|
+
identity: artifact.receipt.receiptIdentity,
|
|
2177
|
+
generation: artifact.receipt.generation,
|
|
2178
|
+
},
|
|
2179
|
+
}),
|
|
2122
2180
|
};
|
|
2123
2181
|
};
|
|
2124
2182
|
const getParamSchema = (materialShaderId: string) => {
|
|
@@ -2172,10 +2230,11 @@ async function makeWebGPURenderer(
|
|
|
2172
2230
|
colorFormats: readonly GPUTextureFormat[],
|
|
2173
2231
|
label: string,
|
|
2174
2232
|
): RenderPipeline | null => {
|
|
2233
|
+
const isFxaaPipeline = label.startsWith(`post-process-${FXAA_POST_PROCESS_ID}-pso-`);
|
|
2175
2234
|
const moduleFactory = getShaderModuleAdapter();
|
|
2176
2235
|
const moduleResult = moduleFactory.createShaderModule({
|
|
2177
2236
|
code: entry.source,
|
|
2178
|
-
label:
|
|
2237
|
+
label: postProcessShaderModuleLabel(entry.source),
|
|
2179
2238
|
});
|
|
2180
2239
|
if (!moduleResult.ok) {
|
|
2181
2240
|
// 'rhi-not-available' = async compile in flight: caller falls back one frame.
|
|
@@ -2186,7 +2245,7 @@ async function makeWebGPURenderer(
|
|
|
2186
2245
|
}
|
|
2187
2246
|
return null;
|
|
2188
2247
|
}
|
|
2189
|
-
if (currentEmptyPostProcessBgl() === null) {
|
|
2248
|
+
if (!isFxaaPipeline && entry.usesView !== true && currentEmptyPostProcessBgl() === null) {
|
|
2190
2249
|
const bglRes = currentBuildDevice().createBindGroupLayout({ entries: [] });
|
|
2191
2250
|
if (!bglRes.ok) {
|
|
2192
2251
|
internals.errorRegistry.fire(bglRes.error);
|
|
@@ -2199,9 +2258,18 @@ async function makeWebGPURenderer(
|
|
|
2199
2258
|
emptyPostProcessBgl = bglRes.value;
|
|
2200
2259
|
}
|
|
2201
2260
|
}
|
|
2261
|
+
const viewLayout =
|
|
2262
|
+
entry.usesView === true ? currentPipelineState()?.viewBindGroupLayout : undefined;
|
|
2263
|
+
const group0Layout = viewLayout ?? currentEmptyPostProcessBgl();
|
|
2264
|
+
if (group0Layout === null || group0Layout === undefined) {
|
|
2265
|
+
internals.errorRegistry.fire(
|
|
2266
|
+
new Error('fullscreen post-process View layout is unavailable') as never,
|
|
2267
|
+
);
|
|
2268
|
+
return null;
|
|
2269
|
+
}
|
|
2202
2270
|
const layoutRes = currentBuildDevice().createPipelineLayout({
|
|
2203
2271
|
label: `${label}-layout`,
|
|
2204
|
-
bindGroupLayouts: [
|
|
2272
|
+
bindGroupLayouts: isFxaaPipeline ? [bgl] : [group0Layout as BindGroupLayout, bgl],
|
|
2205
2273
|
});
|
|
2206
2274
|
if (!layoutRes.ok) {
|
|
2207
2275
|
internals.errorRegistry.fire(layoutRes.error);
|
|
@@ -2439,6 +2507,22 @@ async function makeWebGPURenderer(
|
|
|
2439
2507
|
});
|
|
2440
2508
|
attachGpuPassTimingSession(internals, gpuPassTimingSession);
|
|
2441
2509
|
renderSystemForTargetPromotion = renderSystem;
|
|
2510
|
+
renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID, {
|
|
2511
|
+
source: SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
|
|
2512
|
+
reads: ['input', { key: 'scene-depth', sampleType: 'depth' }],
|
|
2513
|
+
});
|
|
2514
|
+
const pairedMsaaReads = [
|
|
2515
|
+
{ key: 'input', sampleType: 'multisampled-float' as const },
|
|
2516
|
+
{ key: 'scene-depth', sampleType: 'depth' as const },
|
|
2517
|
+
];
|
|
2518
|
+
renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID, {
|
|
2519
|
+
source: SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
|
|
2520
|
+
reads: pairedMsaaReads,
|
|
2521
|
+
});
|
|
2522
|
+
renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID, {
|
|
2523
|
+
source: SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
|
|
2524
|
+
reads: pairedMsaaReads,
|
|
2525
|
+
});
|
|
2442
2526
|
if (
|
|
2443
2527
|
internals.device.caps.backendKind === 'null' &&
|
|
2444
2528
|
Array.from(getShader().entries()).length === 0
|
|
@@ -2466,7 +2550,6 @@ async function makeWebGPURenderer(
|
|
|
2466
2550
|
currentGeneration: () => activeDeviceScope.generation,
|
|
2467
2551
|
renderSystem,
|
|
2468
2552
|
});
|
|
2469
|
-
const derivedSystemNames = new Map<World, string>();
|
|
2470
2553
|
const transformReleases = new Map<World, () => void>();
|
|
2471
2554
|
const attachmentOwner = {};
|
|
2472
2555
|
let frameId = 0;
|
|
@@ -2475,184 +2558,41 @@ async function makeWebGPURenderer(
|
|
|
2475
2558
|
const receiptTimings = new WeakMap<FrameReceipt, Promise<VolumeTimingObservation>>();
|
|
2476
2559
|
let latestReceipt: FrameReceipt | undefined;
|
|
2477
2560
|
let pendingObservationDomains: readonly FrameObservationDomain[] | undefined;
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
observationLiveCount += 1;
|
|
2493
|
-
observationPeakLiveCount = Math.max(observationPeakLiveCount, observationLiveCount);
|
|
2494
|
-
observationLiveByteLength += capture.bytesPerRow * capture.height;
|
|
2495
|
-
},
|
|
2496
|
-
consume(frameNumber: number): readonly TypedFrameObservationCapture[] {
|
|
2497
|
-
const captures = capturesByFrame.get(frameNumber) ?? [];
|
|
2498
|
-
capturesByFrame.delete(frameNumber);
|
|
2499
|
-
return Object.freeze(captures);
|
|
2500
|
-
},
|
|
2501
|
-
drain(): readonly TypedFrameObservationCapture[] {
|
|
2502
|
-
const captures = [...capturesByFrame.values()].flat();
|
|
2503
|
-
capturesByFrame.clear();
|
|
2504
|
-
return Object.freeze(captures);
|
|
2505
|
-
},
|
|
2506
|
-
};
|
|
2507
|
-
})();
|
|
2561
|
+
const observationOwner = createRendererObservationCaptureOwner((error) => {
|
|
2562
|
+
internals.errorRegistry.fire(error);
|
|
2563
|
+
});
|
|
2564
|
+
const {
|
|
2565
|
+
observationCaptureOwner,
|
|
2566
|
+
stats: observationStats,
|
|
2567
|
+
receiptObservationCaptures,
|
|
2568
|
+
receiptObservationBuffers,
|
|
2569
|
+
destroyedObservationBuffers,
|
|
2570
|
+
disposeObservationCaptures,
|
|
2571
|
+
disposeOwnedObservationCaptures,
|
|
2572
|
+
readObservationCapture,
|
|
2573
|
+
disposeReceiptObservationCaptures,
|
|
2574
|
+
} = observationOwner;
|
|
2508
2575
|
Object.assign(internals, { observationCaptureOwner });
|
|
2509
|
-
let expectedObservationGraphGeneration: number | undefined;
|
|
2510
2576
|
Object.defineProperty(internals, 'observationGraphGeneration', {
|
|
2511
2577
|
configurable: true,
|
|
2512
|
-
get: () =>
|
|
2578
|
+
get: () => observationOwner.expectedGraphGeneration,
|
|
2513
2579
|
set: (generation: number | undefined) => {
|
|
2514
|
-
|
|
2580
|
+
observationOwner.expectedGraphGeneration = generation;
|
|
2515
2581
|
},
|
|
2516
2582
|
});
|
|
2517
|
-
type ObservationCaptureRead = () => Promise<
|
|
2518
|
-
RenderResult<
|
|
2519
|
-
readonly {
|
|
2520
|
-
readonly capture: TypedFrameObservationCapture;
|
|
2521
|
-
readonly bytes: Uint8Array;
|
|
2522
|
-
}[],
|
|
2523
|
-
RenderError
|
|
2524
|
-
>
|
|
2525
|
-
>;
|
|
2526
|
-
const receiptObservationCaptures = new Map<FrameReceipt, ObservationCaptureRead>();
|
|
2527
|
-
const receiptObservationBuffers = new Map<
|
|
2528
|
-
FrameReceipt,
|
|
2529
|
-
readonly TypedFrameObservationCapture[]
|
|
2530
|
-
>();
|
|
2531
|
-
const destroyedObservationBuffers = new WeakSet<Buffer>();
|
|
2532
|
-
const observationBufferCleanupFailures = new WeakMap<Buffer, RendererContractFailureError>();
|
|
2533
|
-
const failedObservationCaptures = new Map<Buffer, TypedFrameObservationCapture>();
|
|
2534
|
-
const disposeObservationCaptures = (
|
|
2535
|
-
captures: readonly TypedFrameObservationCapture[],
|
|
2536
|
-
): RendererContractFailureError | undefined => {
|
|
2537
|
-
const wasDestroyed = new Set(
|
|
2538
|
-
captures
|
|
2539
|
-
.filter((capture) => destroyedObservationBuffers.has(capture.buffer))
|
|
2540
|
-
.map((capture) => capture.buffer),
|
|
2541
|
-
);
|
|
2542
|
-
const result = disposeObservationCaptureSet(
|
|
2543
|
-
captures,
|
|
2544
|
-
destroyedObservationBuffers,
|
|
2545
|
-
observationBufferCleanupFailures,
|
|
2546
|
-
(failure) => internals.errorRegistry.fire(failure),
|
|
2547
|
-
);
|
|
2548
|
-
for (const capture of captures) {
|
|
2549
|
-
if (!wasDestroyed.has(capture.buffer) && destroyedObservationBuffers.has(capture.buffer)) {
|
|
2550
|
-
observationLiveCount = Math.max(0, observationLiveCount - 1);
|
|
2551
|
-
observationLiveByteLength = Math.max(
|
|
2552
|
-
0,
|
|
2553
|
-
observationLiveByteLength - capture.bytesPerRow * capture.height,
|
|
2554
|
-
);
|
|
2555
|
-
}
|
|
2556
|
-
}
|
|
2557
|
-
return result;
|
|
2558
|
-
};
|
|
2559
|
-
const disposeOwnedObservationCaptures = (
|
|
2560
|
-
captures: readonly TypedFrameObservationCapture[],
|
|
2561
|
-
): RendererContractFailureError | undefined => {
|
|
2562
|
-
const failure = disposeObservationCaptures(captures);
|
|
2563
|
-
if (failure !== undefined) {
|
|
2564
|
-
for (const capture of captures) {
|
|
2565
|
-
if (!destroyedObservationBuffers.has(capture.buffer)) {
|
|
2566
|
-
failedObservationCaptures.set(capture.buffer, capture);
|
|
2567
|
-
}
|
|
2568
|
-
}
|
|
2569
|
-
}
|
|
2570
|
-
return failure;
|
|
2571
|
-
};
|
|
2572
|
-
const readObservationCapture = async (
|
|
2573
|
-
capture: TypedFrameObservationCapture,
|
|
2574
|
-
): Promise<RenderResult<Uint8Array, RenderError>> => {
|
|
2575
|
-
try {
|
|
2576
|
-
if (typeof capture.buffer.mapAsync !== 'function') {
|
|
2577
|
-
const cleanupFailure = disposeObservationCaptures([capture]);
|
|
2578
|
-
return err(
|
|
2579
|
-
cleanupFailure ??
|
|
2580
|
-
new RendererContractFailureError(
|
|
2581
|
-
'observe',
|
|
2582
|
-
`the ${capture.domain} receipt-bound readback backend has no mapAsync capability`,
|
|
2583
|
-
),
|
|
2584
|
-
);
|
|
2585
|
-
}
|
|
2586
|
-
observationMapCount += 1;
|
|
2587
|
-
const mapped = await capture.buffer.mapAsync(1);
|
|
2588
|
-
if (!mapped.ok) {
|
|
2589
|
-
const cleanupFailure = disposeObservationCaptures([capture]);
|
|
2590
|
-
return err(
|
|
2591
|
-
cleanupFailure ??
|
|
2592
|
-
new RendererContractFailureError(
|
|
2593
|
-
'observe',
|
|
2594
|
-
`mapping ${capture.domain} receipt-bound readback failed: ${mapped.error.code}`,
|
|
2595
|
-
),
|
|
2596
|
-
);
|
|
2597
|
-
}
|
|
2598
|
-
const range = mapped.value.getMappedRange();
|
|
2599
|
-
if (!range.ok) {
|
|
2600
|
-
mapped.value.unmap();
|
|
2601
|
-
const cleanupFailure = disposeObservationCaptures([capture]);
|
|
2602
|
-
return err(
|
|
2603
|
-
cleanupFailure ??
|
|
2604
|
-
new RendererContractFailureError(
|
|
2605
|
-
'observe',
|
|
2606
|
-
`reading ${capture.domain} receipt-bound readback failed: ${range.error.code}`,
|
|
2607
|
-
),
|
|
2608
|
-
);
|
|
2609
|
-
}
|
|
2610
|
-
const bytes = new Uint8Array(range.value.slice(0));
|
|
2611
|
-
mapped.value.unmap();
|
|
2612
|
-
observationReadbackCount += 1;
|
|
2613
|
-
const cleanupFailure = disposeObservationCaptures([capture]);
|
|
2614
|
-
if (cleanupFailure !== undefined) return err(cleanupFailure);
|
|
2615
|
-
return ok(bytes);
|
|
2616
|
-
} catch (cause) {
|
|
2617
|
-
const cleanupFailure = disposeObservationCaptures([capture]);
|
|
2618
|
-
return err(
|
|
2619
|
-
cleanupFailure ??
|
|
2620
|
-
new RendererContractFailureError(
|
|
2621
|
-
'observe',
|
|
2622
|
-
`reading ${capture.domain} receipt-bound readback threw: ${
|
|
2623
|
-
cause instanceof Error ? cause.message : String(cause)
|
|
2624
|
-
}`,
|
|
2625
|
-
),
|
|
2626
|
-
);
|
|
2627
|
-
}
|
|
2628
|
-
};
|
|
2629
|
-
|
|
2630
|
-
const disposeReceiptObservationCaptures = (): RendererContractFailureError | undefined => {
|
|
2631
|
-
let firstFailure: RendererContractFailureError | undefined;
|
|
2632
|
-
for (const [receipt, captures] of receiptObservationBuffers) {
|
|
2633
|
-
const failure = disposeObservationCaptures(captures);
|
|
2634
|
-
firstFailure ??= failure;
|
|
2635
|
-
if (captures.every((capture) => destroyedObservationBuffers.has(capture.buffer))) {
|
|
2636
|
-
receiptObservationBuffers.delete(receipt);
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
receiptObservationCaptures.clear();
|
|
2640
|
-
const retryCaptures = [...failedObservationCaptures.values()];
|
|
2641
|
-
const retryFailure = disposeObservationCaptures(retryCaptures);
|
|
2642
|
-
firstFailure ??= retryFailure;
|
|
2643
|
-
for (const capture of retryCaptures) {
|
|
2644
|
-
if (destroyedObservationBuffers.has(capture.buffer)) {
|
|
2645
|
-
failedObservationCaptures.delete(capture.buffer);
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2648
|
-
const ownedFailure = disposeOwnedObservationCaptures(observationCaptureOwner.drain());
|
|
2649
|
-
firstFailure ??= ownedFailure;
|
|
2650
|
-
return firstFailure;
|
|
2651
|
-
};
|
|
2652
2583
|
let surfaceReleased = false;
|
|
2653
2584
|
const renderer: RendererAssemblyImplementation = {
|
|
2654
|
-
|
|
2585
|
+
setSurfaceDynamicInput(frame) {
|
|
2586
|
+
renderSystem.setSurfaceDynamicInput(frame);
|
|
2587
|
+
},
|
|
2655
2588
|
attach(world: World): RenderResult<RenderWorldLease, RenderError> {
|
|
2589
|
+
if (publicationReceiver !== undefined)
|
|
2590
|
+
return err(
|
|
2591
|
+
new RenderPublicationError({
|
|
2592
|
+
reason: 'identity',
|
|
2593
|
+
subject: 'publication Renderer has no World attachment',
|
|
2594
|
+
}),
|
|
2595
|
+
);
|
|
2656
2596
|
const attached = this.attachScene(world);
|
|
2657
2597
|
if (!attached.ok) {
|
|
2658
2598
|
return err(new RendererContractFailureError('attach', attached.error.hint));
|
|
@@ -2714,25 +2654,29 @@ async function makeWebGPURenderer(
|
|
|
2714
2654
|
? 'faulted'
|
|
2715
2655
|
: 'alive';
|
|
2716
2656
|
const graph = deviceLost ? undefined : renderSystem.perFrameGraphInfo;
|
|
2657
|
+
const graphResourceAllocation = graph?.resourceAllocation;
|
|
2658
|
+
const graphGenerationAllocation = deviceLost
|
|
2659
|
+
? undefined
|
|
2660
|
+
: renderSystem.renderGraphGenerationAllocation;
|
|
2717
2661
|
const standardLighting = deviceLost ? undefined : renderSystem.standardLightingInspection;
|
|
2662
|
+
const barrelDistortion = inspectBarrelDistortion(
|
|
2663
|
+
disposed,
|
|
2664
|
+
deviceLost,
|
|
2665
|
+
surfaceReleased,
|
|
2666
|
+
frameId,
|
|
2667
|
+
activeDeviceScope.generation,
|
|
2668
|
+
renderSystem.barrelDistortionInspection,
|
|
2669
|
+
);
|
|
2718
2670
|
const bloom: BloomInspection = deviceLost ? emptyBloomInspection() : renderSystem.bloom;
|
|
2719
|
-
const surfaceStorage = pipelineState?.format ?? 'rgba8unorm';
|
|
2720
|
-
const surfaceDisplay = pipelineState?.colorAttachmentFormat ?? 'rgba8unorm';
|
|
2721
2671
|
const observationId = `${STANDARD_OUTPUT_TRANSFORM_FEATURE_ID}:frame-${frameId}`;
|
|
2722
|
-
const outputInspection =
|
|
2672
|
+
const outputInspection = projectRendererOutputInspectionFromSurface({
|
|
2723
2673
|
graph,
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
surfaceDisplay,
|
|
2727
|
-
...(pipelineState?.surfaceProfile === undefined
|
|
2728
|
-
? {}
|
|
2729
|
-
: { surfaceProfile: pipelineState.surfaceProfile }),
|
|
2674
|
+
surfaceReleased,
|
|
2675
|
+
pipelineState,
|
|
2730
2676
|
rgba16floatRenderable: internals.device.caps.rgba16floatRenderable,
|
|
2731
2677
|
autoExposure: renderSystem.autoExposure,
|
|
2732
2678
|
standardLut: renderSystem.standardLut,
|
|
2733
|
-
|
|
2734
|
-
? {}
|
|
2735
|
-
: { presentationProof: internals.context.presentationProof }),
|
|
2679
|
+
presentationProof: internals.context?.presentationProof,
|
|
2736
2680
|
});
|
|
2737
2681
|
const volumetricFog = renderSystem.volumetricFog;
|
|
2738
2682
|
const directionalShadow = renderSystem.directionalShadow;
|
|
@@ -2747,6 +2691,7 @@ async function makeWebGPURenderer(
|
|
|
2747
2691
|
frameId,
|
|
2748
2692
|
deviceGeneration: activeDeviceScope.generation,
|
|
2749
2693
|
}),
|
|
2694
|
+
barrelDistortion,
|
|
2750
2695
|
...projectRendererFeatureInspection(internals.featureHost),
|
|
2751
2696
|
featureGraph: renderSystem.featureGraphInspection,
|
|
2752
2697
|
materialTextureSources: renderSystem.materialTextureSources,
|
|
@@ -2756,9 +2701,6 @@ async function makeWebGPURenderer(
|
|
|
2756
2701
|
renderSystem.instanceCollectionsInspection.map((collection) =>
|
|
2757
2702
|
Object.freeze({
|
|
2758
2703
|
...collection,
|
|
2759
|
-
dirtyRanges: Object.freeze(
|
|
2760
|
-
collection.dirtyRanges.map((range) => Object.freeze({ ...range })),
|
|
2761
|
-
),
|
|
2762
2704
|
uploadRanges: Object.freeze(
|
|
2763
2705
|
collection.uploadRanges.map((range) => Object.freeze({ ...range })),
|
|
2764
2706
|
),
|
|
@@ -2775,6 +2717,12 @@ async function makeWebGPURenderer(
|
|
|
2775
2717
|
),
|
|
2776
2718
|
dynamicGeometry: dynamicGeometry.inspect(),
|
|
2777
2719
|
renderScene: renderSystem.renderScene,
|
|
2720
|
+
...(graphResourceAllocation === undefined
|
|
2721
|
+
? {}
|
|
2722
|
+
: { renderGraphResourceAllocation: graphResourceAllocation }),
|
|
2723
|
+
...(graphGenerationAllocation === undefined
|
|
2724
|
+
? {}
|
|
2725
|
+
: { renderGraphGenerationAllocation: graphGenerationAllocation }),
|
|
2778
2726
|
...(renderSystem.iblBinding === undefined ? {} : { iblBinding: renderSystem.iblBinding }),
|
|
2779
2727
|
reflectionProbes: renderSystem.reflectionProbes,
|
|
2780
2728
|
ssrDependencies: renderSystem.ssrDependencies,
|
|
@@ -2855,12 +2803,12 @@ async function makeWebGPURenderer(
|
|
|
2855
2803
|
? {}
|
|
2856
2804
|
: { standardOutputColor: Object.freeze({ ...outputInspection.standardOutputColor }) }),
|
|
2857
2805
|
resourceStats: Object.freeze({
|
|
2858
|
-
allocationCount:
|
|
2859
|
-
liveCount:
|
|
2860
|
-
peakLiveCount:
|
|
2861
|
-
mapCount:
|
|
2862
|
-
readbackCount:
|
|
2863
|
-
liveByteLength:
|
|
2806
|
+
allocationCount: observationStats.allocationCount,
|
|
2807
|
+
liveCount: observationStats.liveCount,
|
|
2808
|
+
peakLiveCount: observationStats.peakLiveCount,
|
|
2809
|
+
mapCount: observationStats.mapCount,
|
|
2810
|
+
readbackCount: observationStats.readbackCount,
|
|
2811
|
+
liveByteLength: observationStats.liveByteLength,
|
|
2864
2812
|
}),
|
|
2865
2813
|
}),
|
|
2866
2814
|
});
|
|
@@ -2896,23 +2844,7 @@ async function makeWebGPURenderer(
|
|
|
2896
2844
|
}
|
|
2897
2845
|
if (attachedWorlds.has(world)) return ok(undefined);
|
|
2898
2846
|
try {
|
|
2899
|
-
|
|
2900
|
-
const derivedSystemName = `renderDerived:${++nextDerivedSystemId}`;
|
|
2901
|
-
const derived = world.addSystem(Update, {
|
|
2902
|
-
name: derivedSystemName,
|
|
2903
|
-
queries: [],
|
|
2904
|
-
fn: (world) => {
|
|
2905
|
-
tilemapChunkExtractSystem(world, (guid) => assets.lookup(guid));
|
|
2906
|
-
const glyphResult = glyphTextLayoutSystem(world, gpuStore);
|
|
2907
|
-
if (!glyphResult.ok) throw glyphResult.error;
|
|
2908
|
-
},
|
|
2909
|
-
});
|
|
2910
|
-
if (!derived.ok) {
|
|
2911
|
-
releaseTransforms();
|
|
2912
|
-
throw new Error(`failed to register ${derivedSystemName}: ${derived.error.code}`);
|
|
2913
|
-
}
|
|
2914
|
-
transformReleases.set(world, releaseTransforms);
|
|
2915
|
-
derivedSystemNames.set(world, derivedSystemName);
|
|
2847
|
+
transformReleases.set(world, registerRenderSourceSystems(world, assets, gpuStore));
|
|
2916
2848
|
attachedWorlds.add(world);
|
|
2917
2849
|
return ok(undefined);
|
|
2918
2850
|
} catch (cause) {
|
|
@@ -2943,11 +2875,6 @@ async function makeWebGPURenderer(
|
|
|
2943
2875
|
}
|
|
2944
2876
|
}
|
|
2945
2877
|
renderSystem.detachScene(world);
|
|
2946
|
-
const derivedSystemName = derivedSystemNames.get(world);
|
|
2947
|
-
if (derivedSystemName !== undefined) {
|
|
2948
|
-
world.removeSystem(Update, derivedSystemName);
|
|
2949
|
-
derivedSystemNames.delete(world);
|
|
2950
|
-
}
|
|
2951
2878
|
transformReleases.get(world)?.();
|
|
2952
2879
|
transformReleases.delete(world);
|
|
2953
2880
|
},
|
|
@@ -3151,17 +3078,43 @@ async function makeWebGPURenderer(
|
|
|
3151
3078
|
: ok(result.value);
|
|
3152
3079
|
},
|
|
3153
3080
|
draw(
|
|
3154
|
-
worldsOrRequest: readonly World[] | RenderFrameInput,
|
|
3081
|
+
worldsOrRequest: readonly World[] | RenderFrameInput | PublishedRenderFrameInput,
|
|
3155
3082
|
options?: DrawOwnerOptions,
|
|
3156
3083
|
): Result<void | FrameReceipt, RhiError | RenderError> {
|
|
3157
3084
|
const isFrameRequest = !Array.isArray(worldsOrRequest);
|
|
3158
|
-
const
|
|
3085
|
+
const publicationRequest =
|
|
3086
|
+
isFrameRequest && 'publication' in worldsOrRequest
|
|
3087
|
+
? (worldsOrRequest as PublishedRenderFrameInput)
|
|
3088
|
+
: undefined;
|
|
3089
|
+
const frameRequest =
|
|
3090
|
+
isFrameRequest && publicationRequest === undefined
|
|
3091
|
+
? (worldsOrRequest as RenderFrameInput)
|
|
3092
|
+
: undefined;
|
|
3093
|
+
let publication: PreparedRenderPublication | undefined;
|
|
3094
|
+
if (publicationRequest !== undefined) {
|
|
3095
|
+
if (publicationReceiver === undefined)
|
|
3096
|
+
return err(
|
|
3097
|
+
new RenderPublicationError({
|
|
3098
|
+
reason: 'identity',
|
|
3099
|
+
subject: 'RendererOptions.publicationSource',
|
|
3100
|
+
}),
|
|
3101
|
+
);
|
|
3102
|
+
} else if (publicationReceiver !== undefined) {
|
|
3103
|
+
return err(
|
|
3104
|
+
new RenderPublicationError({
|
|
3105
|
+
reason: 'identity',
|
|
3106
|
+
subject: 'a publication-bound renderer cannot consume local World leases',
|
|
3107
|
+
}),
|
|
3108
|
+
);
|
|
3109
|
+
}
|
|
3159
3110
|
const worlds: readonly World[] =
|
|
3160
3111
|
frameRequest !== undefined
|
|
3161
3112
|
? frameRequest.leases
|
|
3162
3113
|
.map((lease) => attachedLeases.get(lease))
|
|
3163
3114
|
.filter((world): world is World => world !== undefined)
|
|
3164
|
-
:
|
|
3115
|
+
: publicationRequest === undefined
|
|
3116
|
+
? (worldsOrRequest as readonly World[])
|
|
3117
|
+
: [];
|
|
3165
3118
|
const readLeases: readonly RenderReadLease[] | undefined =
|
|
3166
3119
|
frameRequest !== undefined
|
|
3167
3120
|
? frameRequest.leases
|
|
@@ -3212,8 +3165,18 @@ async function makeWebGPURenderer(
|
|
|
3212
3165
|
...(frameRequest.profileFrame === undefined
|
|
3213
3166
|
? {}
|
|
3214
3167
|
: { profileFrame: frameRequest.profileFrame }),
|
|
3168
|
+
...(frameRequest.geometryLane === undefined
|
|
3169
|
+
? {}
|
|
3170
|
+
: { geometryLane: frameRequest.geometryLane }),
|
|
3215
3171
|
}
|
|
3216
|
-
:
|
|
3172
|
+
: publicationRequest === undefined
|
|
3173
|
+
? (options ?? { cameraOwner: 0, resourceOwner: 0 })
|
|
3174
|
+
: {
|
|
3175
|
+
cameraOwner: 0,
|
|
3176
|
+
resourceOwner: 0,
|
|
3177
|
+
sampleTimeSeconds: publicationRequest.publication.sampleTimeSeconds,
|
|
3178
|
+
temporalReset: publicationRequest.publication.temporalReset,
|
|
3179
|
+
};
|
|
3217
3180
|
// feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M5 / w21
|
|
3218
3181
|
// (plan-strategy D-1, D-8): post-dispose the renderer is dead. AI
|
|
3219
3182
|
// users observing `result.ok === false && err.code === 'rhi-not-
|
|
@@ -3239,6 +3202,8 @@ async function makeWebGPURenderer(
|
|
|
3239
3202
|
}),
|
|
3240
3203
|
);
|
|
3241
3204
|
}
|
|
3205
|
+
const canvasSizeError = rejectZeroCanvasSize(internals.canvas.width, internals.canvas.height);
|
|
3206
|
+
if (canvasSizeError !== undefined) return err(canvasSizeError);
|
|
3242
3207
|
// M2 / w9 (A-IN-5): device-lost guard — draw() silently returns err
|
|
3243
3208
|
// without firing onError each frame. The device-lost channel fires once
|
|
3244
3209
|
// through the dual-channel fan-out (:750-797); draw() does not repeat it
|
|
@@ -3287,7 +3252,8 @@ async function makeWebGPURenderer(
|
|
|
3287
3252
|
// are non-exclusive: an empty array short-circuits to empty-worlds. The
|
|
3288
3253
|
// check is defensive against JS callers passing a non-array despite the
|
|
3289
3254
|
// compile-time World[] type (red-window migration safety).
|
|
3290
|
-
const worldCount =
|
|
3255
|
+
const worldCount =
|
|
3256
|
+
publicationRequest === undefined ? (Array.isArray(worlds) ? worlds.length : 0) : 1;
|
|
3291
3257
|
if (worldCount === 0 && internals.device.caps.backendKind === 'null') {
|
|
3292
3258
|
return ok(undefined);
|
|
3293
3259
|
}
|
|
@@ -3309,12 +3275,27 @@ async function makeWebGPURenderer(
|
|
|
3309
3275
|
internals.errorRegistry,
|
|
3310
3276
|
);
|
|
3311
3277
|
if (!contextConfigured.ok) return contextConfigured;
|
|
3312
|
-
renderTargetHost.beginFrame();
|
|
3313
3278
|
// w24 — facade-level try/catch produces Result.err on unexpected throw
|
|
3314
3279
|
// (D-P6 dual-channel preserved: per-stage RhiError continues to fan out
|
|
3315
3280
|
// through onError separately; the facade Result is the synchronous
|
|
3316
3281
|
// summary AI users can ignore or branch on).
|
|
3317
3282
|
try {
|
|
3283
|
+
if (publicationRequest !== undefined && publicationReceiver !== undefined) {
|
|
3284
|
+
const accepted = publicationReceiver.accept(publicationRequest.publication);
|
|
3285
|
+
if (!accepted.ok) return accepted;
|
|
3286
|
+
publicationTargets ??= new RenderPublicationTargetReceiver(renderTargetHost);
|
|
3287
|
+
publication = {
|
|
3288
|
+
...publicationTargets.apply(accepted.value),
|
|
3289
|
+
...(publicationRequest.onFeatureSourceSubmitted === undefined
|
|
3290
|
+
? {}
|
|
3291
|
+
: {
|
|
3292
|
+
onFeatureSourceSubmitted: publicationRequest.onFeatureSourceSubmitted,
|
|
3293
|
+
}),
|
|
3294
|
+
};
|
|
3295
|
+
installPublicationPrograms(assets, publicationRequest.publication.programs);
|
|
3296
|
+
}
|
|
3297
|
+
renderTargetHost.beginFrame();
|
|
3298
|
+
|
|
3318
3299
|
const timingHost = internals as WebGPURendererInternals & {
|
|
3319
3300
|
gpuPassTimingFrameIdentity?:
|
|
3320
3301
|
| {
|
|
@@ -3352,7 +3333,13 @@ async function makeWebGPURenderer(
|
|
|
3352
3333
|
graphGeneration: 0,
|
|
3353
3334
|
};
|
|
3354
3335
|
}
|
|
3355
|
-
const submitted = renderSystem.draw(
|
|
3336
|
+
const submitted = renderSystem.draw(
|
|
3337
|
+
worlds,
|
|
3338
|
+
drawOptions,
|
|
3339
|
+
readLeases,
|
|
3340
|
+
volumeTimingCapture,
|
|
3341
|
+
publication,
|
|
3342
|
+
);
|
|
3356
3343
|
timingHost.observationFrameId = undefined;
|
|
3357
3344
|
timingHost.observationCaptureDomains = undefined;
|
|
3358
3345
|
timingHost.gpuPassTimingFrameIdentity = undefined;
|
|
@@ -3400,34 +3387,30 @@ async function makeWebGPURenderer(
|
|
|
3400
3387
|
);
|
|
3401
3388
|
const continuation = createContinuationTerminator();
|
|
3402
3389
|
frameContinuations.add(continuation);
|
|
3403
|
-
const guardedCompletion =
|
|
3390
|
+
const guardedCompletion = guardFrameCompletion(
|
|
3391
|
+
completion,
|
|
3392
|
+
() => continuation.guard('queue-completion'),
|
|
3404
3393
|
() =>
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
:
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
'complete-frame',
|
|
3419
|
-
),
|
|
3420
|
-
}),
|
|
3421
|
-
),
|
|
3394
|
+
new RendererOperationError('device-operation-failed', {
|
|
3395
|
+
operation: 'complete-frame',
|
|
3396
|
+
frameId: receiptFrameId,
|
|
3397
|
+
deviceGeneration: receiptGeneration,
|
|
3398
|
+
cause: structuredRendererCause(
|
|
3399
|
+
{
|
|
3400
|
+
code: 'stale-generation',
|
|
3401
|
+
expected: 'frame completion belongs to its device generation',
|
|
3402
|
+
hint: 'discard the stale receipt',
|
|
3403
|
+
},
|
|
3404
|
+
'complete-frame',
|
|
3405
|
+
),
|
|
3406
|
+
}),
|
|
3422
3407
|
(cause: unknown) =>
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
}),
|
|
3430
|
-
),
|
|
3408
|
+
new RendererOperationError('device-operation-failed', {
|
|
3409
|
+
operation: 'complete-frame',
|
|
3410
|
+
frameId: receiptFrameId,
|
|
3411
|
+
deviceGeneration: receiptGeneration,
|
|
3412
|
+
cause: structuredRendererCause(cause, 'complete-frame'),
|
|
3413
|
+
}),
|
|
3431
3414
|
);
|
|
3432
3415
|
const terminated = continuation.promise().then((reason) =>
|
|
3433
3416
|
err(
|
|
@@ -3455,12 +3438,17 @@ async function makeWebGPURenderer(
|
|
|
3455
3438
|
});
|
|
3456
3439
|
const captures = observationCaptureOwner.consume(receiptFrameId);
|
|
3457
3440
|
pendingObservationDomains = undefined;
|
|
3458
|
-
const receiptGraphGeneration =
|
|
3441
|
+
const receiptGraphGeneration =
|
|
3442
|
+
timingHost.observationGraphGeneration ?? renderSystem.perFrameGraphInfo?.generation ?? 0;
|
|
3459
3443
|
const receipt = Object.freeze({
|
|
3460
3444
|
frameId: receiptFrameId,
|
|
3461
3445
|
deviceGeneration: receiptGeneration,
|
|
3446
|
+
presentation: renderSystem.presentation,
|
|
3462
3447
|
backendId: internals.device.caps.backendKind,
|
|
3463
3448
|
graphGeneration: receiptGraphGeneration,
|
|
3449
|
+
...(renderSystem.lastSuccessfulBarrelDistortion === undefined
|
|
3450
|
+
? {}
|
|
3451
|
+
: { barrelDistortion: renderSystem.lastSuccessfulBarrelDistortion }),
|
|
3464
3452
|
completed,
|
|
3465
3453
|
});
|
|
3466
3454
|
renderTargetHost.onFrameSubmitted(completed);
|
|
@@ -3550,6 +3538,10 @@ async function makeWebGPURenderer(
|
|
|
3550
3538
|
});
|
|
3551
3539
|
internals.errorRegistry.fire(e);
|
|
3552
3540
|
return err(e);
|
|
3541
|
+
} finally {
|
|
3542
|
+
// Native video pixels have been consumed by synchronous queue copy calls.
|
|
3543
|
+
// Release them on every success/failure path, including direct publication users.
|
|
3544
|
+
publicationReceiver?.releaseVideoFrames();
|
|
3553
3545
|
}
|
|
3554
3546
|
},
|
|
3555
3547
|
async observe(
|
|
@@ -3792,6 +3784,7 @@ async function makeWebGPURenderer(
|
|
|
3792
3784
|
disposed = true;
|
|
3793
3785
|
for (const world of attachedWorlds) dynamicGeometryHost.invalidateDynamicGeometryWorld(world);
|
|
3794
3786
|
dynamicGeometry.dispose();
|
|
3787
|
+
publicationReceiver?.dispose();
|
|
3795
3788
|
for (const continuation of frameContinuations) {
|
|
3796
3789
|
continuation.terminate({ code: 'disposed' });
|
|
3797
3790
|
}
|
|
@@ -3802,11 +3795,6 @@ async function makeWebGPURenderer(
|
|
|
3802
3795
|
}
|
|
3803
3796
|
for (const world of attachedWorlds) {
|
|
3804
3797
|
try {
|
|
3805
|
-
const derivedSystemName = derivedSystemNames.get(world);
|
|
3806
|
-
if (derivedSystemName !== undefined) {
|
|
3807
|
-
world.removeSystem(Update, derivedSystemName);
|
|
3808
|
-
derivedSystemNames.delete(world);
|
|
3809
|
-
}
|
|
3810
3798
|
transformReleases.get(world)?.();
|
|
3811
3799
|
transformReleases.delete(world);
|
|
3812
3800
|
} catch (cause) {
|
|
@@ -4055,6 +4043,8 @@ async function makeWebGPURenderer(
|
|
|
4055
4043
|
setCandidateEmptyPostProcessBgl(layout) {
|
|
4056
4044
|
candidateEmptyPostProcessBgl = layout;
|
|
4057
4045
|
},
|
|
4046
|
+
getShaderModuleAdapter,
|
|
4047
|
+
getImmediateShaderModuleAdapter,
|
|
4058
4048
|
getShader,
|
|
4059
4049
|
assets,
|
|
4060
4050
|
adaptMipmapShaderModuleFactory,
|