@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,142 @@
|
|
|
1
|
+
import type { GpuResourceAllocationInspection } from '../inspection-types';
|
|
2
|
+
|
|
3
|
+
export interface GpuResourceAllocationToken {
|
|
4
|
+
readonly id: number;
|
|
5
|
+
readonly bytes: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Tracks logical Engine allocation ownership independently of physical GPU
|
|
10
|
+
* residency. A replacement is live and pending at the same time until the
|
|
11
|
+
* queue fence releases the old generation.
|
|
12
|
+
*/
|
|
13
|
+
export class GpuResourceAllocationLedger {
|
|
14
|
+
private nextId = 1;
|
|
15
|
+
private readonly live = new Map<number, number>();
|
|
16
|
+
private readonly pending = new Map<number, number>();
|
|
17
|
+
private liveBytes = 0;
|
|
18
|
+
private pendingBytes = 0;
|
|
19
|
+
private peakBytes = 0;
|
|
20
|
+
private successfulAllocationCount = 0;
|
|
21
|
+
private successfulAllocationBytes = 0;
|
|
22
|
+
private retiredBytes = 0;
|
|
23
|
+
private failedAllocationRollbacks = 0;
|
|
24
|
+
private failedAllocationRollbackBytes = 0;
|
|
25
|
+
|
|
26
|
+
allocate(bytes: number): GpuResourceAllocationToken {
|
|
27
|
+
if (!Number.isFinite(bytes) || bytes < 0) {
|
|
28
|
+
throw new RangeError(`GPU allocation bytes must be finite and non-negative (got ${bytes})`);
|
|
29
|
+
}
|
|
30
|
+
const token = { id: this.nextId++, bytes };
|
|
31
|
+
this.live.set(token.id, token.bytes);
|
|
32
|
+
this.liveBytes += token.bytes;
|
|
33
|
+
this.successfulAllocationCount += 1;
|
|
34
|
+
this.successfulAllocationBytes += token.bytes;
|
|
35
|
+
this.updatePeak();
|
|
36
|
+
return token;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
retire(token: GpuResourceAllocationToken): void {
|
|
40
|
+
const bytes = this.live.get(token.id);
|
|
41
|
+
if (bytes === undefined) return;
|
|
42
|
+
this.live.delete(token.id);
|
|
43
|
+
this.liveBytes -= bytes;
|
|
44
|
+
this.pending.set(token.id, bytes);
|
|
45
|
+
this.pendingBytes += bytes;
|
|
46
|
+
this.updatePeak();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
release(token: GpuResourceAllocationToken): void {
|
|
50
|
+
const pendingBytes = this.pending.get(token.id);
|
|
51
|
+
if (pendingBytes !== undefined) {
|
|
52
|
+
this.pending.delete(token.id);
|
|
53
|
+
this.pendingBytes -= pendingBytes;
|
|
54
|
+
this.retiredBytes += pendingBytes;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const liveBytes = this.live.get(token.id);
|
|
58
|
+
if (liveBytes !== undefined) {
|
|
59
|
+
this.live.delete(token.id);
|
|
60
|
+
this.liveBytes -= liveBytes;
|
|
61
|
+
this.retiredBytes += liveBytes;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
rollback(token: GpuResourceAllocationToken): void {
|
|
66
|
+
const bytes = this.live.get(token.id);
|
|
67
|
+
if (bytes === undefined) return;
|
|
68
|
+
this.live.delete(token.id);
|
|
69
|
+
this.liveBytes -= bytes;
|
|
70
|
+
this.failedAllocationRollbacks += 1;
|
|
71
|
+
this.failedAllocationRollbackBytes += bytes;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
inspect(): GpuResourceAllocationInspection {
|
|
75
|
+
return {
|
|
76
|
+
unit: 'engine-allocation-bytes',
|
|
77
|
+
physicalResidency: 'unknown',
|
|
78
|
+
liveBytes: this.liveBytes,
|
|
79
|
+
pendingRetirementBytes: this.pendingBytes,
|
|
80
|
+
peakBytes: this.peakBytes,
|
|
81
|
+
successfulAllocationCount: this.successfulAllocationCount,
|
|
82
|
+
successfulAllocationBytes: this.successfulAllocationBytes,
|
|
83
|
+
pendingRetirementCount: this.pending.size,
|
|
84
|
+
retiredBytes: this.retiredBytes,
|
|
85
|
+
failedAllocationRollbacks: this.failedAllocationRollbacks,
|
|
86
|
+
failedAllocationRollbackBytes: this.failedAllocationRollbackBytes,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private updatePeak(): void {
|
|
91
|
+
this.peakBytes = Math.max(this.peakBytes, this.liveBytes + this.pendingBytes);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function combineGpuResourceAllocationInspections(
|
|
96
|
+
inspections: readonly GpuResourceAllocationInspection[],
|
|
97
|
+
): GpuResourceAllocationInspection | undefined {
|
|
98
|
+
if (inspections.length === 0) return undefined;
|
|
99
|
+
const liveBytes = inspections.reduce((sum, value) => sum + value.liveBytes, 0);
|
|
100
|
+
const pendingRetirementBytes = inspections.reduce(
|
|
101
|
+
(sum, value) => sum + value.pendingRetirementBytes,
|
|
102
|
+
0,
|
|
103
|
+
);
|
|
104
|
+
// Each owner reports its own historical high-water mark. Adding those
|
|
105
|
+
// marks invents overlap between replacements that happened at different
|
|
106
|
+
// times. The aggregate can prove the current simultaneous occupancy, or
|
|
107
|
+
// retain the largest owner-local mark as a conservative lower-bound fact
|
|
108
|
+
// when all resources have since retired; it cannot claim their historical
|
|
109
|
+
// sum without an event-time aggregate owner.
|
|
110
|
+
const peakBytes = Math.max(
|
|
111
|
+
liveBytes + pendingRetirementBytes,
|
|
112
|
+
...inspections.map((value) => value.peakBytes),
|
|
113
|
+
);
|
|
114
|
+
return {
|
|
115
|
+
unit: 'engine-allocation-bytes',
|
|
116
|
+
physicalResidency: 'unknown',
|
|
117
|
+
liveBytes,
|
|
118
|
+
pendingRetirementBytes,
|
|
119
|
+
peakBytes,
|
|
120
|
+
successfulAllocationCount: inspections.reduce(
|
|
121
|
+
(sum, value) => sum + value.successfulAllocationCount,
|
|
122
|
+
0,
|
|
123
|
+
),
|
|
124
|
+
successfulAllocationBytes: inspections.reduce(
|
|
125
|
+
(sum, value) => sum + value.successfulAllocationBytes,
|
|
126
|
+
0,
|
|
127
|
+
),
|
|
128
|
+
pendingRetirementCount: inspections.reduce(
|
|
129
|
+
(sum, value) => sum + value.pendingRetirementCount,
|
|
130
|
+
0,
|
|
131
|
+
),
|
|
132
|
+
retiredBytes: inspections.reduce((sum, value) => sum + value.retiredBytes, 0),
|
|
133
|
+
failedAllocationRollbacks: inspections.reduce(
|
|
134
|
+
(sum, value) => sum + value.failedAllocationRollbacks,
|
|
135
|
+
0,
|
|
136
|
+
),
|
|
137
|
+
failedAllocationRollbackBytes: inspections.reduce(
|
|
138
|
+
(sum, value) => sum + value.failedAllocationRollbackBytes,
|
|
139
|
+
0,
|
|
140
|
+
),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { World } from '@forgeax/engine-ecs';
|
|
2
|
+
import { gpuDrivenShadowDrawKey } from '../extract/gpu-driven';
|
|
3
|
+
import { worldEntityKey } from '../record/frame-snapshot';
|
|
4
|
+
import type { ShadowCasterMembership } from '../render-system-extract';
|
|
5
|
+
|
|
6
|
+
const WORLD_ENTITY_KEY_STRIDE = 4294967296;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extract emits world/entity keys in the transient `worlds[]` index domain,
|
|
10
|
+
* while PersistentRenderScene owns stable renderer-local World keys for the
|
|
11
|
+
* retained GPU scene. Rebase ShadowCaster ownership at this orchestration
|
|
12
|
+
* boundary before both GPU projection and CPU residual recording consume it.
|
|
13
|
+
*/
|
|
14
|
+
export function rebaseShadowCasterOwnership(
|
|
15
|
+
worlds: readonly World[],
|
|
16
|
+
stableWorldKeys: readonly number[],
|
|
17
|
+
entityKeys: ReadonlySet<number>,
|
|
18
|
+
drawKeys: ReadonlySet<string>,
|
|
19
|
+
membership: readonly ShadowCasterMembership[] | undefined,
|
|
20
|
+
): {
|
|
21
|
+
readonly entityKeys: ReadonlySet<number>;
|
|
22
|
+
readonly drawKeys: ReadonlySet<string>;
|
|
23
|
+
readonly membership: readonly ShadowCasterMembership[] | undefined;
|
|
24
|
+
} {
|
|
25
|
+
const rebaseWorldEntity = (composite: number): number => {
|
|
26
|
+
const transientWorldId = Math.floor(composite / WORLD_ENTITY_KEY_STRIDE);
|
|
27
|
+
if (
|
|
28
|
+
!Number.isInteger(transientWorldId) ||
|
|
29
|
+
transientWorldId < 0 ||
|
|
30
|
+
transientWorldId >= worlds.length
|
|
31
|
+
) {
|
|
32
|
+
return composite;
|
|
33
|
+
}
|
|
34
|
+
const entityKey = composite - transientWorldId * WORLD_ENTITY_KEY_STRIDE;
|
|
35
|
+
return worldEntityKey(stableWorldKeys[transientWorldId] ?? transientWorldId, entityKey);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const stableMembership =
|
|
39
|
+
membership === undefined
|
|
40
|
+
? undefined
|
|
41
|
+
: membership.map((entry) => ({
|
|
42
|
+
...entry,
|
|
43
|
+
worldEntity: rebaseWorldEntity(entry.worldEntity),
|
|
44
|
+
}));
|
|
45
|
+
const stableDrawKeys =
|
|
46
|
+
stableMembership === undefined
|
|
47
|
+
? new Set(
|
|
48
|
+
[...drawKeys].map((key) => {
|
|
49
|
+
const parts = key.split(':');
|
|
50
|
+
if (parts.length !== 4) return key;
|
|
51
|
+
const transientWorldEntity = Number(parts[0]);
|
|
52
|
+
if (!Number.isFinite(transientWorldEntity)) return key;
|
|
53
|
+
return `${rebaseWorldEntity(transientWorldEntity)}:${parts[1]}:${parts[2]}:${parts[3]}`;
|
|
54
|
+
}),
|
|
55
|
+
)
|
|
56
|
+
: new Set(
|
|
57
|
+
stableMembership.map((entry) =>
|
|
58
|
+
gpuDrivenShadowDrawKey(
|
|
59
|
+
entry.worldEntity,
|
|
60
|
+
entry.materialHandle,
|
|
61
|
+
entry.drawItemIndex,
|
|
62
|
+
entry.passIndex,
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
return {
|
|
67
|
+
entityKeys: new Set([...entityKeys].map(rebaseWorldEntity)),
|
|
68
|
+
drawKeys: stableDrawKeys,
|
|
69
|
+
membership: stableMembership,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -25,8 +25,20 @@ import {
|
|
|
25
25
|
GPU_BUFFER_USAGE_UNIFORM,
|
|
26
26
|
} from '../gpu-usage';
|
|
27
27
|
import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
|
|
28
|
+
import { getOpaqueResourceIdentity } from '../record/frame-snapshot';
|
|
29
|
+
import type {
|
|
30
|
+
SurfaceGpuIndirectParameters,
|
|
31
|
+
SurfaceGpuIndirectReadbackError,
|
|
32
|
+
SurfaceGpuReadbackSnapshot,
|
|
33
|
+
SurfaceSubmissionCandidate,
|
|
34
|
+
} from '../surface/submission-observation';
|
|
35
|
+
import { decodeSurfaceIndirectParameters } from '../surface/submission-observation';
|
|
28
36
|
import type { GpuDrivenCandidate, SubmissionPlan } from './batch-topology';
|
|
29
37
|
import { GPU_DRIVEN_SKIN_FLAG } from './batch-topology';
|
|
38
|
+
import {
|
|
39
|
+
GpuResourceAllocationLedger,
|
|
40
|
+
type GpuResourceAllocationToken,
|
|
41
|
+
} from './resource-allocation';
|
|
30
42
|
|
|
31
43
|
const COMPUTE_STAGE = 0x4;
|
|
32
44
|
const WORKGROUP_SIZE = 64;
|
|
@@ -43,6 +55,7 @@ const COUNTER_WORDS = 2 + LOD_ROW_CAPACITY + 2;
|
|
|
43
55
|
const GEOMETRY_WORK_COUNTER_OFFSET = 2 + LOD_ROW_CAPACITY;
|
|
44
56
|
const ROOT_GEOMETRY_WORK_COUNTER_OFFSET = GEOMETRY_WORK_COUNTER_OFFSET + 1;
|
|
45
57
|
const COUNTER_STRIDE = COUNTER_WORDS * 4;
|
|
58
|
+
const INDIRECT_COMMAND_BYTES = 20;
|
|
46
59
|
type GpuDrivenAdmissionCandidate = GpuDrivenCandidate & {
|
|
47
60
|
readonly submitAdmission?: boolean;
|
|
48
61
|
};
|
|
@@ -168,7 +181,7 @@ fn selectLodLevel(
|
|
|
168
181
|
@group(0) @binding(4) var<storage, read> batches: array<BatchRecord>;
|
|
169
182
|
@group(0) @binding(5) var<uniform> view: ViewConstants;
|
|
170
183
|
@group(0) @binding(6) var<storage, read_write> counters: array<atomic<u32>>;
|
|
171
|
-
@group(0) @binding(7) var<storage, read_write> visibleIndices: array<
|
|
184
|
+
@group(0) @binding(7) var<storage, read_write> visibleIndices: array<vec4<u32>>;
|
|
172
185
|
@group(0) @binding(8) var<storage, read_write> indirectArgs: array<u32>;
|
|
173
186
|
|
|
174
187
|
fn counterIndex(batchIndex: u32) -> u32 { return batchIndex * ${COUNTER_WORDS}u; }
|
|
@@ -253,9 +266,11 @@ fn cullView(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
253
266
|
if ((candidate.materialSlot & 0x80000000u) != 0u) {
|
|
254
267
|
materialOrPalette = instance.customDataStart;
|
|
255
268
|
}
|
|
256
|
-
visibleIndices[candidate.visibleBase + localVisible] =
|
|
269
|
+
visibleIndices[candidate.visibleBase + localVisible] = vec4<u32>(
|
|
257
270
|
candidate.submitAdmission >> 1u,
|
|
258
271
|
materialOrPalette,
|
|
272
|
+
candidate.primitiveIndex + 1u,
|
|
273
|
+
candidate.generation,
|
|
259
274
|
);
|
|
260
275
|
}
|
|
261
276
|
|
|
@@ -278,10 +293,22 @@ fn finalizeView(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
278
293
|
let candidate = candidates[batch.candidateBase];
|
|
279
294
|
let selectedLod = selectLodLevel(candidate.projectedHeight, candidate.previousLevel, candidate.historyValid != 0u, candidate.lodRows, candidate.lodCount);
|
|
280
295
|
let lod = candidate.lodRows[selectedLod];
|
|
281
|
-
|
|
296
|
+
var drawCount = batch.count;
|
|
297
|
+
var drawFirst = batch.first;
|
|
298
|
+
var drawBaseVertex: i32 = 0;
|
|
299
|
+
if (candidate.lodCount > 0u) {
|
|
300
|
+
drawCount = lod.indexCount;
|
|
301
|
+
if (batch.indexed != 0u) {
|
|
302
|
+
drawFirst = lod.firstIndex;
|
|
303
|
+
drawBaseVertex = lod.baseVertex;
|
|
304
|
+
}
|
|
305
|
+
} else if (batch.indexed != 0u) {
|
|
306
|
+
drawBaseVertex = batch.baseVertex;
|
|
307
|
+
}
|
|
308
|
+
indirectArgs[args] = drawCount;
|
|
282
309
|
indirectArgs[args + 1u] = visibleCount;
|
|
283
|
-
indirectArgs[args + 2u] =
|
|
284
|
-
indirectArgs[args + 3u] =
|
|
310
|
+
indirectArgs[args + 2u] = drawFirst;
|
|
311
|
+
indirectArgs[args + 3u] = bitcast<u32>(drawBaseVertex);
|
|
285
312
|
indirectArgs[args + 4u] = 0u;
|
|
286
313
|
}
|
|
287
314
|
`;
|
|
@@ -302,6 +329,9 @@ type LodTelemetryCopy = {
|
|
|
302
329
|
readonly buffers: ViewBuffers;
|
|
303
330
|
readonly plan: SubmissionPlan;
|
|
304
331
|
readonly resourceGeneration: number;
|
|
332
|
+
readonly indirectBufferIdentity: number;
|
|
333
|
+
readonly indirectReadbackOffset: number;
|
|
334
|
+
readonly surfaceReadbackSnapshot?: () => SurfaceGpuReadbackSnapshot | undefined;
|
|
305
335
|
readonly submit?: GpuDrivenLodSubmitIdentity;
|
|
306
336
|
};
|
|
307
337
|
|
|
@@ -338,6 +368,8 @@ export interface GpuDrivenViewInspection {
|
|
|
338
368
|
readonly bindGroupCreates: number;
|
|
339
369
|
readonly bufferRebuilds: number;
|
|
340
370
|
readonly resourceGeneration: number;
|
|
371
|
+
/** Logical Engine allocation facts; physical VRAM residency is unknown. */
|
|
372
|
+
readonly resourceAllocation: import('../inspection-types').GpuResourceAllocationInspection;
|
|
341
373
|
}
|
|
342
374
|
|
|
343
375
|
export interface GpuDrivenViewBufferCapacities {
|
|
@@ -348,6 +380,8 @@ export interface GpuDrivenViewBufferCapacities {
|
|
|
348
380
|
}
|
|
349
381
|
|
|
350
382
|
export interface GpuDrivenLodSelectionInspection {
|
|
383
|
+
/** Exact resource generation whose selector rows were copied. */
|
|
384
|
+
readonly resourceGeneration?: number;
|
|
351
385
|
readonly candidateCount: number;
|
|
352
386
|
readonly batchCount: number;
|
|
353
387
|
readonly indirectDrawCount: number;
|
|
@@ -375,6 +409,22 @@ export interface GpuDrivenLodSelectionInspection {
|
|
|
375
409
|
}[];
|
|
376
410
|
readonly geometryWork: number;
|
|
377
411
|
readonly rootGeometryWork: number;
|
|
412
|
+
/** Actual visible rows copied from the submitted GPU selector. */
|
|
413
|
+
readonly actualMembers: readonly {
|
|
414
|
+
readonly batchId: number;
|
|
415
|
+
readonly primitiveIndex: number;
|
|
416
|
+
readonly generation: number;
|
|
417
|
+
readonly drawItemIndex: number;
|
|
418
|
+
readonly instanceOrdinal: number;
|
|
419
|
+
}[];
|
|
420
|
+
/** Surface subset projected by the material producer after readback. */
|
|
421
|
+
readonly surfaceActualMemberIds?: readonly string[];
|
|
422
|
+
/** Decoded indexed/non-indexed command words for the exact Surface copy. */
|
|
423
|
+
readonly surfaceIndirectParameters?: readonly SurfaceGpuIndirectParameters[];
|
|
424
|
+
/** Fail-closed readback reason when the copied command range is unusable. */
|
|
425
|
+
readonly surfaceIndirectReadbackError?: SurfaceGpuIndirectReadbackError;
|
|
426
|
+
/** Exact Surface recording whose selector bytes were copied. */
|
|
427
|
+
readonly surfaceReadback?: SurfaceGpuReadbackSnapshot;
|
|
378
428
|
/** Public receipt identity captured when the telemetry copy was encoded. */
|
|
379
429
|
readonly submit?: GpuDrivenLodSubmitIdentity;
|
|
380
430
|
}
|
|
@@ -437,6 +487,8 @@ export class GpuDrivenView {
|
|
|
437
487
|
private bindGroupCreates = 0;
|
|
438
488
|
private bufferRebuilds = 0;
|
|
439
489
|
private resourceGeneration = 0;
|
|
490
|
+
private readonly allocationLedger = new GpuResourceAllocationLedger();
|
|
491
|
+
private readonly allocationTokens = new WeakMap<Buffer, GpuResourceAllocationToken>();
|
|
440
492
|
/** The last readback copy that was actually encoded and is not consumed. */
|
|
441
493
|
private telemetryPending: LodTelemetryCopy | undefined;
|
|
442
494
|
/** Receipt identity for the copy pass encoded by the current frame. */
|
|
@@ -720,6 +772,7 @@ export class GpuDrivenView {
|
|
|
720
772
|
bindGroupCreates: this.bindGroupCreates,
|
|
721
773
|
bufferRebuilds: this.bufferRebuilds,
|
|
722
774
|
resourceGeneration: this.resourceGeneration,
|
|
775
|
+
resourceAllocation: this.allocationLedger.inspect(),
|
|
723
776
|
};
|
|
724
777
|
}
|
|
725
778
|
|
|
@@ -784,6 +837,13 @@ export class GpuDrivenView {
|
|
|
784
837
|
let overflow = false;
|
|
785
838
|
let geometryWork = 0;
|
|
786
839
|
let rootGeometryWork = 0;
|
|
840
|
+
const actualMembers: Array<{
|
|
841
|
+
readonly batchId: number;
|
|
842
|
+
readonly primitiveIndex: number;
|
|
843
|
+
readonly generation: number;
|
|
844
|
+
readonly drawItemIndex: number;
|
|
845
|
+
readonly instanceOrdinal: number;
|
|
846
|
+
}> = [];
|
|
787
847
|
const histogram = new Map<number, number>();
|
|
788
848
|
for (let batchIndex = 0; batchIndex < plan.batches.length; batchIndex += 1) {
|
|
789
849
|
const offset = batchIndex * COUNTER_STRIDE;
|
|
@@ -794,6 +854,33 @@ export class GpuDrivenView {
|
|
|
794
854
|
values.getUint32(offset, true),
|
|
795
855
|
plan.batches[batchIndex]?.visibleCapacity ?? 0,
|
|
796
856
|
);
|
|
857
|
+
const batch = plan.batches[batchIndex];
|
|
858
|
+
const admitted =
|
|
859
|
+
batch?.candidates.filter(
|
|
860
|
+
(candidate) => (candidate as GpuDrivenAdmissionCandidate).submitAdmission !== false,
|
|
861
|
+
) ?? [];
|
|
862
|
+
for (let visibleIndex = 0; visibleIndex < batchVisible; visibleIndex += 1) {
|
|
863
|
+
const visibleOffset =
|
|
864
|
+
this.batchCapacity * COUNTER_STRIDE + ((batch?.visibleBase ?? 0) + visibleIndex) * 16;
|
|
865
|
+
const projectionIndex = values.getUint32(visibleOffset, true);
|
|
866
|
+
const primitiveIndex = values.getUint32(visibleOffset + 8, true) - 1;
|
|
867
|
+
const generation = values.getUint32(visibleOffset + 12, true);
|
|
868
|
+
const candidate = admitted[projectionIndex];
|
|
869
|
+
if (
|
|
870
|
+
batch !== undefined &&
|
|
871
|
+
candidate !== undefined &&
|
|
872
|
+
candidate.primitiveIndex === primitiveIndex &&
|
|
873
|
+
candidate.generation === generation
|
|
874
|
+
) {
|
|
875
|
+
actualMembers.push({
|
|
876
|
+
batchId: batch.batchId,
|
|
877
|
+
primitiveIndex,
|
|
878
|
+
generation,
|
|
879
|
+
drawItemIndex: candidate.drawItemIndex,
|
|
880
|
+
instanceOrdinal: candidate.instanceOrdinal,
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
}
|
|
797
884
|
visible += batchVisible;
|
|
798
885
|
overflow ||= batchOverflow;
|
|
799
886
|
geometryWork += values.getUint32(offset + GEOMETRY_WORK_COUNTER_OFFSET * 4, true);
|
|
@@ -814,7 +901,19 @@ export class GpuDrivenView {
|
|
|
814
901
|
return undefined;
|
|
815
902
|
}
|
|
816
903
|
const candidateCount = plan.candidateCount;
|
|
904
|
+
const surfaceReadback = copy.surfaceReadbackSnapshot?.();
|
|
905
|
+
const surfaceIndirectReadback =
|
|
906
|
+
surfaceReadback === undefined
|
|
907
|
+
? undefined
|
|
908
|
+
: decodeSurfaceIndirectParameters({
|
|
909
|
+
bytes: range.value,
|
|
910
|
+
byteOffset: copy.indirectReadbackOffset,
|
|
911
|
+
byteLength: this.indirectCapacity * INDIRECT_COMMAND_BYTES,
|
|
912
|
+
indirectBufferIdentity: copy.indirectBufferIdentity,
|
|
913
|
+
recording: surfaceReadback,
|
|
914
|
+
});
|
|
817
915
|
this.lodSelection = Object.freeze({
|
|
916
|
+
resourceGeneration: copy.resourceGeneration,
|
|
818
917
|
candidateCount,
|
|
819
918
|
batchCount: plan.batches.length,
|
|
820
919
|
// Selector-only batches remain in the plan/readback but the production
|
|
@@ -862,6 +961,13 @@ export class GpuDrivenView {
|
|
|
862
961
|
),
|
|
863
962
|
geometryWork,
|
|
864
963
|
rootGeometryWork,
|
|
964
|
+
actualMembers: Object.freeze(actualMembers),
|
|
965
|
+
...(surfaceReadback === undefined ? {} : { surfaceReadback }),
|
|
966
|
+
...(surfaceIndirectReadback === undefined
|
|
967
|
+
? {}
|
|
968
|
+
: surfaceIndirectReadback.ok
|
|
969
|
+
? { surfaceIndirectParameters: surfaceIndirectReadback.value }
|
|
970
|
+
: { surfaceIndirectReadbackError: surfaceIndirectReadback.error }),
|
|
865
971
|
...(copy.submit === undefined ? {} : { submit: copy.submit }),
|
|
866
972
|
});
|
|
867
973
|
this.telemetryPending = undefined;
|
|
@@ -875,6 +981,7 @@ export class GpuDrivenView {
|
|
|
875
981
|
builder: RenderGraphBuilder<FrameCtx>,
|
|
876
982
|
labelPrefix = 'gpu-driven',
|
|
877
983
|
includeCompute = true,
|
|
984
|
+
surfaceSubmissionObservation?: () => SurfaceSubmissionCandidate | undefined,
|
|
878
985
|
): Result<GpuDrivenViewGraphResources, RenderGraphError> {
|
|
879
986
|
const buffers = this.buffers;
|
|
880
987
|
const bindGroup = this.bindGroup;
|
|
@@ -956,14 +1063,16 @@ export class GpuDrivenView {
|
|
|
956
1063
|
const lodReadback = importBuffer(
|
|
957
1064
|
`${labelPrefix}.lod-selection-readback`,
|
|
958
1065
|
buffers.lodReadback,
|
|
959
|
-
this.batchCapacity * COUNTER_STRIDE
|
|
1066
|
+
this.batchCapacity * COUNTER_STRIDE +
|
|
1067
|
+
this.visibleBufferCapacity * 16 +
|
|
1068
|
+
this.indirectCapacity * INDIRECT_COMMAND_BYTES,
|
|
960
1069
|
GPU_BUFFER_USAGE_MAP_READ | GPU_BUFFER_USAGE_COPY_DST,
|
|
961
1070
|
);
|
|
962
1071
|
if (!lodReadback.ok) return lodReadback;
|
|
963
1072
|
const visible = importBuffer(
|
|
964
1073
|
`${labelPrefix}.visible`,
|
|
965
1074
|
buffers.visible,
|
|
966
|
-
this.visibleBufferCapacity *
|
|
1075
|
+
this.visibleBufferCapacity * 16,
|
|
967
1076
|
GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_SRC,
|
|
968
1077
|
);
|
|
969
1078
|
if (!visible.ok) return visible;
|
|
@@ -1029,9 +1138,14 @@ export class GpuDrivenView {
|
|
|
1029
1138
|
});
|
|
1030
1139
|
if (!finalize.ok) return finalize;
|
|
1031
1140
|
const graphResourceGeneration = this.resourceGeneration;
|
|
1141
|
+
const indirectReadbackOffset =
|
|
1142
|
+
this.batchCapacity * COUNTER_STRIDE + this.visibleBufferCapacity * 16;
|
|
1143
|
+
const indirectBufferIdentity = getOpaqueResourceIdentity(buffers.indirect as object);
|
|
1032
1144
|
const readback = builder.addCopyPass(`${labelPrefix}.lod-selection-readback`, {
|
|
1033
1145
|
accesses: [
|
|
1034
1146
|
{ resource: counters.value, usage: 'copy-src' },
|
|
1147
|
+
{ resource: visible.value, usage: 'copy-src' },
|
|
1148
|
+
{ resource: indirect.value, usage: 'copy-src' },
|
|
1035
1149
|
{ resource: lodReadback.value, usage: 'copy-dst' },
|
|
1036
1150
|
],
|
|
1037
1151
|
encode: ({ encoder, resources }) => {
|
|
@@ -1047,6 +1161,20 @@ export class GpuDrivenView {
|
|
|
1047
1161
|
resources.buffer(lodReadback.value).unwrap(),
|
|
1048
1162
|
this.batchCapacity * COUNTER_STRIDE,
|
|
1049
1163
|
);
|
|
1164
|
+
encoder.copyBufferToBuffer(
|
|
1165
|
+
resources.buffer(visible.value).unwrap(),
|
|
1166
|
+
0,
|
|
1167
|
+
resources.buffer(lodReadback.value).unwrap(),
|
|
1168
|
+
this.batchCapacity * COUNTER_STRIDE,
|
|
1169
|
+
this.visibleBufferCapacity * 16,
|
|
1170
|
+
);
|
|
1171
|
+
encoder.copyBufferToBuffer(
|
|
1172
|
+
resources.buffer(indirect.value).unwrap(),
|
|
1173
|
+
0,
|
|
1174
|
+
resources.buffer(lodReadback.value).unwrap(),
|
|
1175
|
+
indirectReadbackOffset,
|
|
1176
|
+
this.indirectCapacity * INDIRECT_COMMAND_BYTES,
|
|
1177
|
+
);
|
|
1050
1178
|
// The render graph is cached across camera-only LOD projection
|
|
1051
1179
|
// changes. The pass closure therefore retains the graph-generation
|
|
1052
1180
|
// plan while `this.plan` carries the plan uploaded for the frame that
|
|
@@ -1059,10 +1187,18 @@ export class GpuDrivenView {
|
|
|
1059
1187
|
submittedPlan !== undefined &&
|
|
1060
1188
|
this.resourceGeneration === graphResourceGeneration
|
|
1061
1189
|
) {
|
|
1190
|
+
const submittedObservation = surfaceSubmissionObservation?.();
|
|
1062
1191
|
this.telemetryPending = {
|
|
1063
1192
|
buffers,
|
|
1064
1193
|
plan: submittedPlan,
|
|
1065
1194
|
resourceGeneration: graphResourceGeneration,
|
|
1195
|
+
indirectBufferIdentity,
|
|
1196
|
+
indirectReadbackOffset,
|
|
1197
|
+
...(submittedObservation === undefined
|
|
1198
|
+
? {}
|
|
1199
|
+
: {
|
|
1200
|
+
surfaceReadbackSnapshot: () => submittedObservation.gpuReadbackSnapshot(),
|
|
1201
|
+
}),
|
|
1066
1202
|
...(this.telemetrySubmit === undefined ? {} : { submit: this.telemetrySubmit }),
|
|
1067
1203
|
};
|
|
1068
1204
|
}
|
|
@@ -1099,6 +1235,7 @@ export class GpuDrivenView {
|
|
|
1099
1235
|
this.telemetrySubmit = undefined;
|
|
1100
1236
|
this.lodSelectionReadback = undefined;
|
|
1101
1237
|
this.lodSelection = undefined;
|
|
1238
|
+
for (const generation of buffers) this.retireGeneration(generation);
|
|
1102
1239
|
this.destroyAfterSubmittedWork(buffers);
|
|
1103
1240
|
void this.pipelineLayout;
|
|
1104
1241
|
}
|
|
@@ -1143,6 +1280,7 @@ export class GpuDrivenView {
|
|
|
1143
1280
|
const nextBatch = nextCapacity(batchCapacity);
|
|
1144
1281
|
const nextIndirect = nextCapacity(indirectCapacity);
|
|
1145
1282
|
const created: Partial<MutableViewBuffers> = {};
|
|
1283
|
+
const createdTokens: GpuResourceAllocationToken[] = [];
|
|
1146
1284
|
const allocate = (
|
|
1147
1285
|
name: keyof ViewBuffers,
|
|
1148
1286
|
size: number,
|
|
@@ -1156,6 +1294,9 @@ export class GpuDrivenView {
|
|
|
1156
1294
|
});
|
|
1157
1295
|
if (!buffer.ok) return buffer;
|
|
1158
1296
|
created[name] = buffer.value;
|
|
1297
|
+
const token = this.allocationLedger.allocate(size);
|
|
1298
|
+
this.allocationTokens.set(buffer.value, token);
|
|
1299
|
+
createdTokens.push(token);
|
|
1159
1300
|
return ok(undefined);
|
|
1160
1301
|
};
|
|
1161
1302
|
const storage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_SRC;
|
|
@@ -1184,7 +1325,7 @@ export class GpuDrivenView {
|
|
|
1184
1325
|
storage: false,
|
|
1185
1326
|
},
|
|
1186
1327
|
{ name: 'counters', size: nextBatch * COUNTER_STRIDE, usage: storage, storage: true },
|
|
1187
|
-
{ name: 'visible', size: nextVisible *
|
|
1328
|
+
{ name: 'visible', size: nextVisible * 16, usage: storage, storage: true },
|
|
1188
1329
|
{
|
|
1189
1330
|
name: 'indirect',
|
|
1190
1331
|
size: nextIndirect * 20,
|
|
@@ -1193,7 +1334,7 @@ export class GpuDrivenView {
|
|
|
1193
1334
|
},
|
|
1194
1335
|
{
|
|
1195
1336
|
name: 'lodReadback',
|
|
1196
|
-
size: nextBatch * COUNTER_STRIDE,
|
|
1337
|
+
size: nextBatch * COUNTER_STRIDE + nextVisible * 16 + nextIndirect * INDIRECT_COMMAND_BYTES,
|
|
1197
1338
|
usage: GPU_BUFFER_USAGE_MAP_READ | GPU_BUFFER_USAGE_COPY_DST,
|
|
1198
1339
|
storage: false,
|
|
1199
1340
|
},
|
|
@@ -1219,10 +1360,14 @@ export class GpuDrivenView {
|
|
|
1219
1360
|
const result = allocate(request.name, request.size, request.usage);
|
|
1220
1361
|
if (!result.ok) {
|
|
1221
1362
|
for (const buffer of Object.values(created)) this.device.destroyBuffer(buffer);
|
|
1363
|
+
for (const token of createdTokens) this.allocationLedger.rollback(token);
|
|
1222
1364
|
return result;
|
|
1223
1365
|
}
|
|
1224
1366
|
}
|
|
1225
|
-
if (this.buffers !== undefined)
|
|
1367
|
+
if (this.buffers !== undefined) {
|
|
1368
|
+
this.supersededBuffers.push(this.buffers);
|
|
1369
|
+
this.retireGeneration(this.buffers);
|
|
1370
|
+
}
|
|
1226
1371
|
this.buffers = created as ViewBuffers;
|
|
1227
1372
|
this.candidateCapacity = nextCandidate;
|
|
1228
1373
|
this.visibleBufferCapacity = nextVisible;
|
|
@@ -1240,10 +1385,19 @@ export class GpuDrivenView {
|
|
|
1240
1385
|
for (const buffers of generations) {
|
|
1241
1386
|
for (const buffer of Object.values(buffers)) {
|
|
1242
1387
|
this.device.destroyBuffer(buffer);
|
|
1388
|
+
const token = this.allocationTokens.get(buffer);
|
|
1389
|
+
if (token !== undefined) this.allocationLedger.release(token);
|
|
1243
1390
|
}
|
|
1244
1391
|
}
|
|
1245
1392
|
};
|
|
1246
1393
|
void this.device.queue.onSubmittedWorkDone().then(release, release);
|
|
1247
1394
|
}
|
|
1395
|
+
|
|
1396
|
+
private retireGeneration(generation: ViewBuffers): void {
|
|
1397
|
+
for (const buffer of Object.values(generation)) {
|
|
1398
|
+
const token = this.allocationTokens.get(buffer);
|
|
1399
|
+
if (token !== undefined) this.allocationLedger.retire(token);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1248
1402
|
}
|
|
1249
1403
|
export { decideVisibility } from '../scene/visibility/occlusion-confidence';
|