@forgeax/engine-render 0.1.32 → 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 +1374 -142
- package/dist/assembly/analytic-fog-registration.d.ts +3 -0
- package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
- 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/fxaa-registration.d.ts +4 -0
- package/dist/assembly/fxaa-registration.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +3 -3
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/lod-observation.d.ts +4 -0
- package/dist/assembly/lod-observation.d.ts.map +1 -0
- 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/motion-blur-registration.d.ts +3 -0
- package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
- 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/temporal-post-process-prewarm.d.ts +13 -0
- package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
- 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-contract.d.ts +4 -3
- package/dist/assembly/webgpu-ready-contract.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 +2 -2
- 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/bloom-admission.d.ts +13 -0
- package/dist/bloom-admission.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-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
- package/dist/chunk-HEB564WF.mjs.map +1 -0
- package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
- package/dist/chunk-MKDIT2EM.mjs.map +1 -0
- package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
- package/dist/{chunk-S665NJNF.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-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
- package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
- package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
- package/dist/chunk-UI5SFODX.mjs.map +1 -0
- package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
- package/dist/chunk-UINHLCZA.mjs.map +1 -0
- package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
- 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/atmosphere.d.ts +2 -0
- package/dist/components/atmosphere.d.ts.map +1 -1
- package/dist/components/barrel-distortion.d.ts +13 -0
- package/dist/components/barrel-distortion.d.ts.map +1 -0
- package/dist/components/camera.d.ts +20 -4
- package/dist/components/camera.d.ts.map +1 -1
- 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/components/mesh-filter.d.ts +6 -5
- package/dist/components/mesh-filter.d.ts.map +1 -1
- package/dist/components/motion-blur.d.ts +1 -0
- package/dist/components/motion-blur.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 +9751 -3528
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +6 -0
- 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/environment/analytic-fog.d.ts +6 -0
- package/dist/environment/analytic-fog.d.ts.map +1 -0
- package/dist/errors/cloud.d.ts +59 -0
- package/dist/errors/cloud.d.ts.map +1 -0
- package/dist/errors/render.d.ts +23 -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 +12 -1
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/environment.d.ts +2 -0
- package/dist/extract/environment.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 +17 -0
- package/dist/features/error-reporting.d.ts.map +1 -0
- package/dist/features/host.d.ts +15 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
- package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
- package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
- package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
- package/dist/features/plan.d.ts +15 -4
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +9 -5
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/render-graph-compute.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 +7 -0
- 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 +50 -4
- 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 +35 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +11 -1
- 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 +31 -8
- 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 +178 -3
- 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 +49 -94
- 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 +28 -19
- 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/pipeline-spec.d.ts +2 -2
- 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 +40 -3
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +14 -62
- 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/mesh-ssbo.d.ts +6 -5
- package/dist/record/mesh-ssbo.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 +34 -31
- 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 +6 -4
- 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 +66 -8
- 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 +106 -3
- 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 +24 -10
- 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 +26 -15
- 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 +14 -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/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +7 -0
- package/dist/temporal/frame.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/temporal/view.d.ts +6 -1
- package/dist/temporal/view.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 +24 -9
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +9 -5
- 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/dist/volume/temporal.d.ts +3 -1
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +22 -21
- package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
- package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
- 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__/bloom-exact-zero.unit.test.ts +112 -18
- package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
- 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__/dynamic-resolution-plugin.integration.test.ts +20 -0
- package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
- package/src/__tests__/environment-selection.unit.test.ts +12 -0
- package/src/__tests__/factory-contract.integration.test.ts +626 -113
- package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
- package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
- package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
- 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-indirect-raster-evidence.ts +2 -1
- 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 +7 -6
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
- 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-resource-store-stride.unit.test.ts +12 -0
- package/src/__tests__/gpu-scene.unit.test.ts +210 -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 +105 -238
- 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__/mesh-submission-lifetime.unit.test.ts +31 -0
- 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 +589 -0
- 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-gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
- package/src/__tests__/probe-bindings.unit.test.ts +582 -1
- package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
- package/src/__tests__/public-surface.test-d.ts +8 -0
- 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 +9 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
- 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-feature-stage-fault-recovery.unit.test.ts +23 -0
- 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 +37 -6
- 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 +33 -11
- package/src/__tests__/resource-allocation.unit.test.ts +123 -0
- package/src/__tests__/shader-manifest-fixture.ts +4 -4
- 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 +17 -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-lighting-write.unit.test.ts +2 -1
- 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.dawn.test.ts +1 -1
- package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
- 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__/temporal-reset-matrix.unit.test.ts +10 -0
- package/src/__tests__/temporal-view.unit.test.ts +2 -1
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
- 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 +7 -3
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
- 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 +558 -68
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
- package/src/assembly/analytic-fog-registration.ts +14 -0
- 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/fxaa-registration.ts +17 -0
- package/src/assembly/host-contract.ts +3 -3
- package/src/assembly/lod-observation.ts +12 -0
- 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/motion-blur-registration.ts +17 -0
- 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 +6 -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 +40 -0
- package/src/assembly/webgpu-pbr-ready.ts +9 -1
- package/src/assembly/webgpu-ready-contract.ts +8 -3
- package/src/assembly/webgpu-ready-per-pass.ts +104 -0
- package/src/assembly/webgpu-ready.ts +296 -306
- 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 +228 -281
- package/src/assembly/webgpu-vertex-layouts.ts +1 -1
- package/src/barrel-distortion.ts +247 -0
- package/src/bloom-admission.ts +21 -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/__tests__/motion-blur.unit.test.ts +1 -0
- package/src/components/atmosphere.ts +4 -0
- package/src/components/barrel-distortion.ts +46 -0
- package/src/components/camera.ts +66 -10
- 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/mesh-filter.ts +11 -9
- package/src/components/motion-blur.ts +1 -0
- package/src/components/sprite-instances.ts +1 -1
- package/src/construct-renderer.ts +1 -1
- package/src/device/gpu-residency.ts +56 -12
- package/src/dynamic-geometry.ts +12 -1
- package/src/environment/analytic-fog.ts +44 -0
- package/src/environment/background.ts +2 -2
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +58 -8
- package/src/examples/single-layer-medium-surface.ts +59 -0
- package/src/extract/camera.ts +35 -8
- package/src/extract/contracts.ts +12 -0
- package/src/extract/environment.ts +4 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +98 -0
- package/src/features/host.ts +138 -24
- package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
- package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
- package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
- package/src/features/motion-blur/motion-blur-params.ts +70 -2
- package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
- package/src/features/plan.ts +33 -8
- package/src/features/prepared-gpu-work.ts +86 -35
- package/src/features/render-graph-compute.ts +13 -5
- package/src/features/render-graph-contribution.ts +11 -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 +35 -32
- package/src/gpu-driven/prepared-draw.ts +27 -14
- package/src/gpu-driven/production-raster-material.ts +1894 -0
- package/src/gpu-driven/production-raster.ts +904 -787
- 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 +181 -10
- package/src/gpu-scene.ts +259 -101
- package/src/hdrp-buffers.ts +4 -3
- package/src/ibl/skylight-bind-group.ts +49 -7
- package/src/index.ts +228 -9
- package/src/inspection-types.ts +222 -2
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +151 -492
- 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 +397 -102
- package/src/pipeline-builder.ts +1 -1
- package/src/pipeline-spec.ts +5 -5
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
- 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 +3 -2
- 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 +44 -4
- package/src/record/frame-targets.ts +10 -6
- package/src/record/frame.ts +373 -1099
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/main-pass-geometry.ts +281 -83
- package/src/record/main-pass-material.ts +66 -4
- package/src/record/main-pass-sprite-draws.ts +13 -66
- package/src/record/main-pass.ts +156 -20
- package/src/record/mesh-ssbo.ts +43 -6
- 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 +51 -31
- package/src/record/shadow-pass.ts +36 -2
- package/src/record/skybox-post-pass.ts +150 -200
- package/src/record/typed-frame-graph.ts +824 -44
- package/src/record/view-ubo.ts +26 -3
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +257 -52
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +71 -8
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +136 -1
- package/src/render-system-extract-tail.ts +72 -60
- package/src/render-system-extract.ts +117 -87
- 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 +601 -482
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +431 -281
- 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/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
- package/src/temporal/frame-coordinator.ts +8 -1
- package/src/temporal/frame.ts +20 -0
- 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/temporal/view.ts +13 -2
- 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 +191 -50
- package/src/volume/component.ts +10 -10
- package/src/volume/extract.ts +11 -5
- package/src/volume/inspection.ts +3 -0
- package/src/volume/passes.ts +95 -8
- package/src/volume/resources.ts +2 -1
- package/src/volume/temporal.ts +11 -0
- package/dist/chunk-4NNZQCL3.mjs.map +0 -1
- package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
- package/dist/chunk-DRR7D3KX.mjs.map +0 -1
- package/dist/chunk-GWCEMDVR.mjs.map +0 -1
- package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
- package/dist/chunk-JRIPCMYC.mjs.map +0 -1
- package/dist/chunk-LULCA3OF.mjs +0 -1713
- package/dist/chunk-LULCA3OF.mjs.map +0 -1
- package/dist/chunk-PA5DRJNI.mjs.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RuntimeMeshVertices } from '@forgeax/engine-assets-runtime';
|
|
1
2
|
import { World } from '@forgeax/engine-ecs';
|
|
2
3
|
import { createRenderReadLease } from '@forgeax/engine-ecs/projection';
|
|
3
4
|
import { vec3 } from '@forgeax/engine-math';
|
|
@@ -16,7 +17,7 @@ import {
|
|
|
16
17
|
PointLightShadow,
|
|
17
18
|
SpotLight,
|
|
18
19
|
} from '../components';
|
|
19
|
-
import {
|
|
20
|
+
import { InstanceProjectionStore } from '../instances';
|
|
20
21
|
import { makeZeroCameraFallbackSnapshot } from '../record/frame-snapshot';
|
|
21
22
|
import type {
|
|
22
23
|
DispatchEntry,
|
|
@@ -302,13 +303,12 @@ describe('RenderScene canonical owner', () => {
|
|
|
302
303
|
|
|
303
304
|
it('classifies an Instances-only collection revision without widening the content update', () => {
|
|
304
305
|
const world = new World();
|
|
305
|
-
const instanceCollections = new
|
|
306
|
+
const instanceCollections = new InstanceProjectionStore();
|
|
306
307
|
const initialTransforms = new Float32Array(16);
|
|
307
308
|
initialTransforms[0] = 1;
|
|
308
309
|
initialTransforms[5] = 1;
|
|
309
310
|
initialTransforms[10] = 1;
|
|
310
311
|
initialTransforms[15] = 1;
|
|
311
|
-
const collection = instanceCollections.create({ transforms: initialTransforms }).unwrap();
|
|
312
312
|
const entity = world
|
|
313
313
|
.spawn(
|
|
314
314
|
{
|
|
@@ -317,14 +317,18 @@ describe('RenderScene canonical owner', () => {
|
|
|
317
317
|
},
|
|
318
318
|
{ component: MeshFilter, data: { assetHandle: 1 as never } },
|
|
319
319
|
{ component: MeshRenderer, data: { materials: [] } },
|
|
320
|
-
{ component: Instances, data: {
|
|
320
|
+
{ component: Instances, data: { transforms: initialTransforms } },
|
|
321
321
|
)
|
|
322
322
|
.unwrap();
|
|
323
323
|
const lease = createRenderReadLease(world);
|
|
324
324
|
const requests: PersistentRenderCandidateRequest[] = [];
|
|
325
325
|
const build = (request: PersistentRenderCandidateRequest): ExtractedFrame => {
|
|
326
326
|
requests.push(request);
|
|
327
|
-
const detached = instanceCollections.
|
|
327
|
+
const detached = instanceCollections.project(
|
|
328
|
+
world,
|
|
329
|
+
entity,
|
|
330
|
+
world.get(entity, Instances).unwrap().transforms,
|
|
331
|
+
);
|
|
328
332
|
return {
|
|
329
333
|
cameras: [{ ...makeZeroCameraFallbackSnapshot(), worldId: 0, entityKey: 1 }],
|
|
330
334
|
renderables: [
|
|
@@ -349,7 +353,7 @@ describe('RenderScene canonical owner', () => {
|
|
|
349
353
|
]);
|
|
350
354
|
const nextTransforms = new Float32Array(initialTransforms);
|
|
351
355
|
nextTransforms[12] = 4;
|
|
352
|
-
|
|
356
|
+
world.set(entity, Instances, { transforms: nextTransforms }).unwrap();
|
|
353
357
|
persistent.extractComposition([world], { cameraOwner: 0, resourceOwner: 0 }, 0, build, [
|
|
354
358
|
lease,
|
|
355
359
|
]);
|
|
@@ -734,8 +738,8 @@ describe('RenderScene canonical owner', () => {
|
|
|
734
738
|
const world = new World();
|
|
735
739
|
const lease = createRenderReadLease(world);
|
|
736
740
|
const handle = world.allocSharedRef('MeshAsset', { kind: 'mesh' });
|
|
737
|
-
const
|
|
738
|
-
const persistent = new PersistentRenderScene({
|
|
741
|
+
const onRuntimeAssetChange = vi.fn();
|
|
742
|
+
const persistent = new PersistentRenderScene({ onRuntimeAssetChange });
|
|
739
743
|
const frame = {
|
|
740
744
|
cameras: [],
|
|
741
745
|
renderables: [],
|
|
@@ -746,12 +750,12 @@ describe('RenderScene canonical owner', () => {
|
|
|
746
750
|
persistent.extractComposition([world], { cameraOwner: 0, resourceOwner: 0 }, 0, () => frame, [
|
|
747
751
|
lease,
|
|
748
752
|
]);
|
|
749
|
-
world.
|
|
753
|
+
world.spawn({ component: RuntimeMeshVertices, data: { asset: handle, vertices: [] } }).unwrap();
|
|
750
754
|
persistent.extractComposition([world], { cameraOwner: 0, resourceOwner: 0 }, 0, () => frame, [
|
|
751
755
|
lease,
|
|
752
756
|
]);
|
|
753
757
|
|
|
754
|
-
expect(
|
|
758
|
+
expect(onRuntimeAssetChange).toHaveBeenCalledWith(0, handle);
|
|
755
759
|
lease.dispose();
|
|
756
760
|
persistent.dispose();
|
|
757
761
|
});
|
|
@@ -974,6 +978,7 @@ describe('RenderScene canonical owner', () => {
|
|
|
974
978
|
expect(projected.renderables).toEqual(cameraMoved.renderables);
|
|
975
979
|
expect(projected.dispatch).toEqual(cameraMoved.dispatch);
|
|
976
980
|
expect(initial.renderables).toHaveLength(1);
|
|
981
|
+
// Transform spans update poses without a second source-identity scan.
|
|
977
982
|
expect(persistent.inspect()).toMatchObject({ fullRebuilds: 1, worldEntitiesScanned: 0 });
|
|
978
983
|
} finally {
|
|
979
984
|
lease.dispose();
|
|
@@ -1373,7 +1378,7 @@ describe('RenderScene', () => {
|
|
|
1373
1378
|
} as unknown as ExtractedFrame;
|
|
1374
1379
|
|
|
1375
1380
|
const projected = scene.extractComposition(
|
|
1376
|
-
[
|
|
1381
|
+
[new World()],
|
|
1377
1382
|
{ cameraOwner: 0, resourceOwner: 0 },
|
|
1378
1383
|
0,
|
|
1379
1384
|
() => frame,
|
|
@@ -1515,3 +1520,23 @@ describe('projected bounds query', () => {
|
|
|
1515
1520
|
scene.dispose();
|
|
1516
1521
|
});
|
|
1517
1522
|
});
|
|
1523
|
+
|
|
1524
|
+
it('does not publish an earlier transform when later CPU candidate preparation fails', () => {
|
|
1525
|
+
const scene = new RenderScene();
|
|
1526
|
+
scene.apply([updateSnapshot(snapshot(1, 0)), updateSnapshot(snapshot(2, 0))]);
|
|
1527
|
+
const changed = snapshot(1, 7).transform.world;
|
|
1528
|
+
const malformed = snapshot(2, 9);
|
|
1529
|
+
Object.defineProperty(malformed, 'transform', {
|
|
1530
|
+
get() {
|
|
1531
|
+
throw new Error('candidate copy failure');
|
|
1532
|
+
},
|
|
1533
|
+
});
|
|
1534
|
+
expect(() =>
|
|
1535
|
+
scene.apply([
|
|
1536
|
+
{ kind: 'update', worldId: 0, entityKey: 1, world: changed },
|
|
1537
|
+
updateSnapshot(malformed),
|
|
1538
|
+
]),
|
|
1539
|
+
).toThrow('candidate copy failure');
|
|
1540
|
+
expect(scene.slot(0, 1)?.snapshot.transform.world[12]).toBe(0);
|
|
1541
|
+
expect(scene.slot(0, 2)?.snapshot.transform.world[12]).toBe(0);
|
|
1542
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { World } from '@forgeax/engine-ecs';
|
|
1
2
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { type InstanceCollectionSnapshot,
|
|
3
|
+
import { type InstanceCollectionSnapshot, InstanceProjectionStore } from '../instances';
|
|
3
4
|
import type { MaterialSnapshot, RenderableSnapshot } from '../render-system-extract';
|
|
4
5
|
import { RenderScene } from '../scene/render-scene';
|
|
5
6
|
|
|
@@ -93,11 +94,11 @@ describe('RenderScene temporal retry boundary', () => {
|
|
|
93
94
|
});
|
|
94
95
|
|
|
95
96
|
it('keeps last committed root and Instances data across a failed mixed frame and retry', () => {
|
|
96
|
-
const instanceCollections = new
|
|
97
|
-
const
|
|
98
|
-
const initialInstances = instanceCollections.
|
|
99
|
-
instanceCollections.
|
|
100
|
-
const nextInstances = instanceCollections.
|
|
97
|
+
const instanceCollections = new InstanceProjectionStore();
|
|
98
|
+
const source = new World();
|
|
99
|
+
const initialInstances = instanceCollections.project(source, 7, matrices(2, 1));
|
|
100
|
+
instanceCollections.accept(source, 7, initialInstances);
|
|
101
|
+
const nextInstances = instanceCollections.project(source, 7, matrices(3, 9));
|
|
101
102
|
const scene = new RenderScene();
|
|
102
103
|
scene.setTemporalTracking(true);
|
|
103
104
|
try {
|
|
@@ -130,4 +131,34 @@ describe('RenderScene temporal retry boundary', () => {
|
|
|
130
131
|
instanceCollections.dispose();
|
|
131
132
|
}
|
|
132
133
|
});
|
|
134
|
+
|
|
135
|
+
it('keeps instance motion valid when stable generations reorder', () => {
|
|
136
|
+
const instanceCollections = new InstanceProjectionStore();
|
|
137
|
+
const source = new World();
|
|
138
|
+
const initialInstances = instanceCollections.project(source, 7, matrices(2, 1));
|
|
139
|
+
instanceCollections.accept(source, 7, initialInstances);
|
|
140
|
+
// Exercise the temporal consumer's identity remapping directly. World
|
|
141
|
+
// authoring uses ordinal identity; this consumer also accepts reordered projections.
|
|
142
|
+
const reorderedInstances = {
|
|
143
|
+
...instanceCollections.project(source, 7, matrices(2, 9)),
|
|
144
|
+
generations: new Uint32Array([
|
|
145
|
+
initialInstances.generations[1] ?? 0,
|
|
146
|
+
initialInstances.generations[0] ?? 0,
|
|
147
|
+
]),
|
|
148
|
+
};
|
|
149
|
+
const scene = new RenderScene();
|
|
150
|
+
scene.setTemporalTracking(true);
|
|
151
|
+
try {
|
|
152
|
+
scene.apply([updateSnapshot(snapshot(7, 1, initialInstances))]);
|
|
153
|
+
submit(scene, 7);
|
|
154
|
+
scene.apply([updateInstances(snapshot(7, 1, reorderedInstances))]);
|
|
155
|
+
|
|
156
|
+
const temporal = scene.temporalSnapshotBySlot(0);
|
|
157
|
+
expect(temporal?.motionValid).toBe(true);
|
|
158
|
+
expect(temporal?.previousInstances?.generations).toEqual(initialInstances.generations);
|
|
159
|
+
expect(temporal?.previousInstances?.transforms).toEqual(initialInstances.transforms);
|
|
160
|
+
} finally {
|
|
161
|
+
instanceCollections.dispose();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
133
164
|
});
|
|
@@ -4,10 +4,10 @@ import { boundedReflectionProbeFilterWork } from '../record/typed-frame-graph';
|
|
|
4
4
|
import { advanceProbeFilter, createProbeFilterState } from '../reflection/filter';
|
|
5
5
|
import type { RenderTarget } from '../targets/contracts';
|
|
6
6
|
|
|
7
|
-
const FRAME_COUNT =
|
|
7
|
+
const FRAME_COUNT = 60;
|
|
8
8
|
const target = {} as RenderTarget;
|
|
9
9
|
|
|
10
|
-
describe('RenderTarget and ReflectionProbe
|
|
10
|
+
describe('RenderTarget and ReflectionProbe 60-frame soak contract', () => {
|
|
11
11
|
it('keeps off and settled steady-state work exactly zero', () => {
|
|
12
12
|
const scheduler = createCubeCaptureScheduler({ maxFacesPerFrame: 1 });
|
|
13
13
|
const initialFilter = createProbeFilterState({ probeIndex: 0, faceCount: 6, mipCount: 5 });
|
|
@@ -3,18 +3,18 @@ import { describe, expect, it } from 'vitest';
|
|
|
3
3
|
const scenarios = ['none', 'fxaa', 'taa', 'recovery'] as const;
|
|
4
4
|
|
|
5
5
|
describe('temporal Environment consumer browser contract', () => {
|
|
6
|
-
it('requires every mode to carry a
|
|
6
|
+
it('requires every mode to carry a 60-frame identity', () => {
|
|
7
7
|
const records = scenarios.map((scenario) => ({
|
|
8
8
|
scenario,
|
|
9
9
|
backend: 'browser-webgpu',
|
|
10
|
-
frames:
|
|
10
|
+
frames: 60,
|
|
11
11
|
status: 'pass',
|
|
12
12
|
}));
|
|
13
13
|
expect(records).toHaveLength(4);
|
|
14
14
|
expect(
|
|
15
15
|
records.every(
|
|
16
16
|
(record) =>
|
|
17
|
-
record.backend === 'browser-webgpu' && record.frames >=
|
|
17
|
+
record.backend === 'browser-webgpu' && record.frames >= 60 && record.status === 'pass',
|
|
18
18
|
),
|
|
19
19
|
).toBe(true);
|
|
20
20
|
});
|
|
@@ -6,11 +6,14 @@ describe('temporal Environment consumer Dawn contract', () => {
|
|
|
6
6
|
backend: 'dawn-node',
|
|
7
7
|
runner: 'dawn.node',
|
|
8
8
|
scenarios: 4,
|
|
9
|
-
framesPerScenario:
|
|
9
|
+
framesPerScenario: 60,
|
|
10
10
|
};
|
|
11
11
|
expect(record.backend).toBe('dawn-node');
|
|
12
12
|
expect(record.runner).toBe('dawn.node');
|
|
13
|
-
expect(
|
|
13
|
+
expect(
|
|
14
|
+
record.scenarios * record.framesPerScenario,
|
|
15
|
+
'four temporal scenarios must account for 60 frames each',
|
|
16
|
+
).toBe(240);
|
|
14
17
|
});
|
|
15
18
|
|
|
16
19
|
it('keeps adapter refusal explicit', () => {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
selectNoColorPbrVariant,
|
|
21
21
|
selectPipelineLayoutForVariant,
|
|
22
22
|
shouldDeferMissingPreparedMaterialShader,
|
|
23
|
+
stripCloudShadowBindingsForLowLimit,
|
|
23
24
|
} from '../assembly/factory';
|
|
24
25
|
import { prepareMaterialShaders } from '../assembly/material-shader-policy';
|
|
25
26
|
import {
|
|
@@ -61,6 +62,22 @@ function noColorManifest() {
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
describe('material shader variant identity', () => {
|
|
65
|
+
it('lowers the optional cloud shadow bindings on cooked single-source materials', () => {
|
|
66
|
+
const source = `
|
|
67
|
+
@group(0) @binding(16) var cloudShadowMapX: texture_2d<f32>;
|
|
68
|
+
@group(0) @binding(17) var cloudShadowSamplerX: sampler;
|
|
69
|
+
fn cloud_direct_solar_factorX() -> f32 {
|
|
70
|
+
let sampled = textureSampleLevel(cloudShadowMapX, cloudShadowSamplerX, vec2<f32>(0.5), 0.0).x;
|
|
71
|
+
return sampled;
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
const lowered = stripCloudShadowBindingsForLowLimit(source);
|
|
75
|
+
expect(lowered).not.toMatch(/@group\(0\)\s*@binding\((?:16|17)\)/u);
|
|
76
|
+
expect(lowered).not.toContain('cloudShadowMapX');
|
|
77
|
+
expect(lowered).not.toContain('cloudShadowSamplerX');
|
|
78
|
+
expect(lowered).toContain('vec4<f32>(1.0).x');
|
|
79
|
+
});
|
|
80
|
+
|
|
64
81
|
it('defaults a declared coverage-only axis to the opaque boot variant', async () => {
|
|
65
82
|
const entry: MaterialShaderManifestEntry = {
|
|
66
83
|
identifier: 'forgeax::default-standard-pbr',
|
|
@@ -264,6 +281,23 @@ describe('material shader variant identity', () => {
|
|
|
264
281
|
).toBeNull();
|
|
265
282
|
});
|
|
266
283
|
|
|
284
|
+
it('selects the producer-owned clustered layouts for scene-index batches', () => {
|
|
285
|
+
const state = {
|
|
286
|
+
pbrPipelineLayout: 'urp' as never,
|
|
287
|
+
hdrpPbrPipelineLayout: 'hdrp' as never,
|
|
288
|
+
pbrSkinPipelineLayout: 'skin-urp' as never,
|
|
289
|
+
gpuDrivenPbrPipelineLayout: 'gpu-urp' as never,
|
|
290
|
+
gpuDrivenPbrSkinPipelineLayout: 'gpu-skin-urp' as never,
|
|
291
|
+
gpuDrivenClusterPbrPipelineLayout: 'gpu-cluster' as never,
|
|
292
|
+
gpuDrivenClusterPbrSkinPipelineLayout: 'gpu-skin-cluster' as never,
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
expect(selectPipelineLayoutForVariant(state, '', 'gpu-driven-cluster-pbr')).toBe('gpu-cluster');
|
|
296
|
+
expect(selectPipelineLayoutForVariant(state, '', 'gpu-driven-cluster-skin')).toBe(
|
|
297
|
+
'gpu-skin-cluster',
|
|
298
|
+
);
|
|
299
|
+
});
|
|
300
|
+
|
|
267
301
|
it('does not promote an omitted semantic axis to true', () => {
|
|
268
302
|
const resolved = resolveMaterialShaderVariantSet(
|
|
269
303
|
'VERTEX_COLOR_AVAILABLE=true',
|
|
@@ -946,9 +980,9 @@ describe('material shader color-domain contract', () => {
|
|
|
946
980
|
resolve(import.meta.dirname, '../assembly/webgpu-renderer.ts'),
|
|
947
981
|
'utf8',
|
|
948
982
|
);
|
|
949
|
-
expect(source).
|
|
950
|
-
|
|
951
|
-
);
|
|
983
|
+
expect(source).toContain('!singleLayerMedium');
|
|
984
|
+
expect(source).toContain('!clustered');
|
|
985
|
+
expect(source).toContain('isSharedMaterialUserRegionCompatible');
|
|
952
986
|
});
|
|
953
987
|
|
|
954
988
|
it('keeps the fixed standard texture ABI before authored clearcoat slots', () => {
|
|
@@ -960,7 +994,7 @@ describe('material shader color-domain contract', () => {
|
|
|
960
994
|
expect(pipelineSource).toContain(
|
|
961
995
|
'const physicalFields = physicalTextureFields(effectiveSchema)',
|
|
962
996
|
);
|
|
963
|
-
expect(pipelineSource).toContain('appendTextureInjection(
|
|
997
|
+
expect(pipelineSource).toContain('appendTextureInjection(afterSurfaceMedium, physicalFields)');
|
|
964
998
|
expect(recordSource).toContain('BUILTIN_USER_REGION_TEXTURE_FIELDS');
|
|
965
999
|
});
|
|
966
1000
|
|
|
@@ -969,12 +1003,12 @@ describe('material shader color-domain contract', () => {
|
|
|
969
1003
|
resolve(import.meta.dirname, '../assembly/material/pipeline-helpers.ts'),
|
|
970
1004
|
'utf8',
|
|
971
1005
|
);
|
|
972
|
-
expect(source).
|
|
973
|
-
|
|
1006
|
+
expect(source).toMatch(
|
|
1007
|
+
/const sceneIndex =\s+[\s\S]*layoutKind === 'gpu-driven-pbr'[\s\S]*layoutKind === 'gpu-driven-skin'[\s\S]*layoutKind === 'gpu-driven-cluster-pbr'[\s\S]*layoutKind === 'gpu-driven-cluster-skin'/u,
|
|
974
1008
|
);
|
|
975
1009
|
expect(source).toContain('? (vertexEntryPoint ?? authoredVertexEntry)');
|
|
976
1010
|
expect(source).toMatch(
|
|
977
|
-
/const instancesLayout =\s+layoutKind === 'gpu-driven-pbr'
|
|
1011
|
+
/const instancesLayout =\s+[\s\S]*layoutKind === 'gpu-driven-pbr'[\s\S]*layoutKind === 'gpu-driven-skin'[\s\S]*layoutKind === 'gpu-driven-cluster-pbr'[\s\S]*layoutKind === 'gpu-driven-cluster-skin'[\s\S]*state\.gpuDrivenInstancesBindGroupLayout/u,
|
|
978
1012
|
);
|
|
979
1013
|
});
|
|
980
1014
|
});
|
|
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
|
|
|
2
2
|
import {
|
|
3
3
|
createContinuationTerminator,
|
|
4
4
|
executeRendererFrameTransaction,
|
|
5
|
+
guardFrameCompletion,
|
|
5
6
|
} from '../assembly/renderer-frame-transaction';
|
|
6
7
|
|
|
7
8
|
describe('renderer frame generation fence', () => {
|
|
@@ -44,4 +45,19 @@ describe('renderer frame generation fence', () => {
|
|
|
44
45
|
expect(terminator.guard('mapAsync')).toBe(false);
|
|
45
46
|
expect(terminator.guard('queue-completion')).toBe(false);
|
|
46
47
|
});
|
|
48
|
+
|
|
49
|
+
it('preserves a producer Result error carried by a fulfilled completion Promise', async () => {
|
|
50
|
+
const error = { code: 'queue-rejected' } as const;
|
|
51
|
+
const result = await guardFrameCompletion<
|
|
52
|
+
void,
|
|
53
|
+
{ code: 'queue-rejected' | 'stale' | 'rejected' }
|
|
54
|
+
>(
|
|
55
|
+
Promise.resolve({ ok: false as const, error }),
|
|
56
|
+
() => true,
|
|
57
|
+
() => ({ code: 'stale' as const }),
|
|
58
|
+
() => ({ code: 'rejected' as const }),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
expect(result).toEqual({ ok: false, error });
|
|
62
|
+
});
|
|
47
63
|
});
|
|
@@ -87,7 +87,8 @@ function temporalResolveFrame(
|
|
|
87
87
|
bloom: 'off',
|
|
88
88
|
bloomThreshold: 1,
|
|
89
89
|
bloomIntensity: 1,
|
|
90
|
-
|
|
90
|
+
bloomSoftKnee: 0.5,
|
|
91
|
+
bloomScatter: 0.7,
|
|
91
92
|
clearColor: [0, 0, 0, 1],
|
|
92
93
|
temporal: frameState.lastSuccessfulTemporalView,
|
|
93
94
|
},
|
|
@@ -258,6 +259,7 @@ function executeReplayCapture(
|
|
|
258
259
|
};
|
|
259
260
|
const frameState = {
|
|
260
261
|
compiledFrameGraph: graph,
|
|
262
|
+
compiledFrameGraphTopologyKey: 'synthetic-capture',
|
|
261
263
|
frameNumber: 13,
|
|
262
264
|
graphTargetCapture:
|
|
263
265
|
captureKind === 'pass-replay'
|
|
@@ -373,7 +375,7 @@ function executeReplayCapture(
|
|
|
373
375
|
describe('renderer successful-submit transaction', () => {
|
|
374
376
|
it('publishes the renderer-created receipt object only after submit', async () => {
|
|
375
377
|
const rendererHost = await constructRenderer(
|
|
376
|
-
{ getContext: () => null },
|
|
378
|
+
{ width: 64, height: 64, getContext: () => null },
|
|
377
379
|
{ rhi },
|
|
378
380
|
{
|
|
379
381
|
shaderManifestUrl: `data:application/json,${encodeURIComponent(
|
|
@@ -381,6 +383,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
381
383
|
)}`,
|
|
382
384
|
},
|
|
383
385
|
);
|
|
386
|
+
expect((await rendererHost.initialization).ok).toBe(true);
|
|
384
387
|
const renderer = exposeRenderer(rendererHost);
|
|
385
388
|
const events: Array<
|
|
386
389
|
Extract<import('../render-contract').RendererEvent, { kind: 'frame-submitted' }>
|
|
@@ -397,7 +400,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
397
400
|
camera: { lease: attached.value },
|
|
398
401
|
environment: { lease: attached.value },
|
|
399
402
|
});
|
|
400
|
-
expect(frame.ok).toBe(true);
|
|
403
|
+
expect(frame.ok, frame.ok ? '' : JSON.stringify(frame.error)).toBe(true);
|
|
401
404
|
if (!frame.ok) return;
|
|
402
405
|
expect(events).toHaveLength(1);
|
|
403
406
|
expect(events[0]?.receipt).toBe(frame.value);
|
|
@@ -415,7 +418,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
415
418
|
|
|
416
419
|
it('fail-closes an all-domain request without an admitted LUT producer', async () => {
|
|
417
420
|
const renderer = await constructRenderer(
|
|
418
|
-
{ getContext: () => null },
|
|
421
|
+
{ width: 64, height: 64, getContext: () => null },
|
|
419
422
|
{ rhi },
|
|
420
423
|
{
|
|
421
424
|
shaderManifestUrl: `data:application/json,${encodeURIComponent(
|
|
@@ -423,6 +426,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
423
426
|
)}`,
|
|
424
427
|
},
|
|
425
428
|
);
|
|
429
|
+
expect((await renderer.initialization).ok).toBe(true);
|
|
426
430
|
const world = new World();
|
|
427
431
|
const attached = renderer.attach(world);
|
|
428
432
|
expect(attached.ok).toBe(true);
|
|
@@ -432,7 +436,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
432
436
|
camera: { lease: attached.value },
|
|
433
437
|
environment: { lease: attached.value },
|
|
434
438
|
});
|
|
435
|
-
expect(frame.ok).toBe(true);
|
|
439
|
+
expect(frame.ok, frame.ok ? '' : JSON.stringify(frame.error)).toBe(true);
|
|
436
440
|
if (!frame.ok || frame.value === undefined) return;
|
|
437
441
|
expect(frame.value.graphGeneration).toBeTypeOf('number');
|
|
438
442
|
expect(frame.value.backendId).toBe('null');
|
|
@@ -476,8 +480,18 @@ describe('renderer successful-submit transaction', () => {
|
|
|
476
480
|
JSON.stringify({ schemaVersion: '1.0.0', entries: [] }),
|
|
477
481
|
)}`,
|
|
478
482
|
};
|
|
479
|
-
const firstRenderer = await constructRenderer(
|
|
480
|
-
|
|
483
|
+
const firstRenderer = await constructRenderer(
|
|
484
|
+
{ width: 64, height: 64, getContext: () => null },
|
|
485
|
+
{ rhi },
|
|
486
|
+
options,
|
|
487
|
+
);
|
|
488
|
+
const secondRenderer = await constructRenderer(
|
|
489
|
+
{ width: 64, height: 64, getContext: () => null },
|
|
490
|
+
{ rhi },
|
|
491
|
+
options,
|
|
492
|
+
);
|
|
493
|
+
expect((await firstRenderer.initialization).ok).toBe(true);
|
|
494
|
+
expect((await secondRenderer.initialization).ok).toBe(true);
|
|
481
495
|
const world = new World();
|
|
482
496
|
const attached = firstRenderer.attach(world);
|
|
483
497
|
expect(attached.ok).toBe(true);
|
|
@@ -487,7 +501,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
487
501
|
camera: { lease: attached.value },
|
|
488
502
|
environment: { lease: attached.value },
|
|
489
503
|
});
|
|
490
|
-
expect(frame.ok).toBe(true);
|
|
504
|
+
expect(frame.ok, frame.ok ? '' : JSON.stringify(frame.error)).toBe(true);
|
|
491
505
|
if (!frame.ok || frame.value === undefined) return;
|
|
492
506
|
expect(frame.value.backendId).toBe('null');
|
|
493
507
|
const crossRenderer = await secondRenderer.observe(frame.value, { include: ['timings'] });
|
|
@@ -572,7 +586,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
572
586
|
|
|
573
587
|
it('keeps real Renderer observation requests isolated across receipts', async () => {
|
|
574
588
|
const renderer = await constructRenderer(
|
|
575
|
-
{ getContext: () => null },
|
|
589
|
+
{ width: 64, height: 64, getContext: () => null },
|
|
576
590
|
{ rhi },
|
|
577
591
|
{
|
|
578
592
|
shaderManifestUrl: `data:application/json,${encodeURIComponent(
|
|
@@ -580,6 +594,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
580
594
|
)}`,
|
|
581
595
|
},
|
|
582
596
|
);
|
|
597
|
+
expect((await renderer.initialization).ok).toBe(true);
|
|
583
598
|
const world = new World();
|
|
584
599
|
const attached = renderer.attach(world);
|
|
585
600
|
expect(attached.ok).toBe(true);
|
|
@@ -594,8 +609,8 @@ describe('renderer successful-submit transaction', () => {
|
|
|
594
609
|
camera: { lease: attached.value },
|
|
595
610
|
environment: { lease: attached.value },
|
|
596
611
|
});
|
|
597
|
-
expect(first.ok).toBe(true);
|
|
598
|
-
expect(second.ok).toBe(true);
|
|
612
|
+
expect(first.ok, first.ok ? '' : JSON.stringify(first.error)).toBe(true);
|
|
613
|
+
expect(second.ok, second.ok ? '' : JSON.stringify(second.error)).toBe(true);
|
|
599
614
|
if (!first.ok || !second.ok || first.value === undefined || second.value === undefined) return;
|
|
600
615
|
const firstPending = renderer.observe(first.value, {
|
|
601
616
|
include: ['timings', 'linear-hdr', 'linear-ldr', 'final-srgb'],
|
|
@@ -1109,6 +1124,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
1109
1124
|
expect(compiled.ok).toBe(true);
|
|
1110
1125
|
if (!compiled.ok) return;
|
|
1111
1126
|
frameState.compiledFrameGraph = compiled.value;
|
|
1127
|
+
frameState.compiledFrameGraphTopologyKey = 'temporal-readiness-probe';
|
|
1112
1128
|
const submits = vi.spyOn(device.queue, 'submit');
|
|
1113
1129
|
const errors = new RhiErrorListenerRegistry();
|
|
1114
1130
|
const result = executeCompiledFrameGraph(
|
|
@@ -1147,6 +1163,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
1147
1163
|
height: 4,
|
|
1148
1164
|
frameIndex: 6,
|
|
1149
1165
|
historyValid: true,
|
|
1166
|
+
sampleTimeSeconds: 1,
|
|
1150
1167
|
});
|
|
1151
1168
|
const frameState = {
|
|
1152
1169
|
temporalGpuState: undefined,
|
|
@@ -1160,6 +1177,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
1160
1177
|
height: 4,
|
|
1161
1178
|
frameIndex: 6,
|
|
1162
1179
|
historyValid: true,
|
|
1180
|
+
sampleTimeSeconds: 1.016,
|
|
1163
1181
|
}),
|
|
1164
1182
|
},
|
|
1165
1183
|
environmentGeneration,
|
|
@@ -1180,6 +1198,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
1180
1198
|
getTemporalParamsBuffer(candidate);
|
|
1181
1199
|
const graph = await buildTemporalResolveGraph(device);
|
|
1182
1200
|
frameState.compiledFrameGraph = graph;
|
|
1201
|
+
frameState.compiledFrameGraphTopologyKey = 'temporal-resolve';
|
|
1183
1202
|
|
|
1184
1203
|
const failure = new RhiError({
|
|
1185
1204
|
code: 'webgpu-runtime-error',
|
|
@@ -1244,6 +1263,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
1244
1263
|
expect(active.valid).toBe(true);
|
|
1245
1264
|
expect(active.readIndex).toBe(1);
|
|
1246
1265
|
expect(frameState.lastSuccessfulTemporalView).toBe(lastSuccessfulTemporalView);
|
|
1266
|
+
expect(frameState.lastSuccessfulTemporalView.sampleTimeSeconds).toBe(1);
|
|
1247
1267
|
expect(environmentLifecycle.inspect().activeSignature).toBe(activeEnvironment.signature);
|
|
1248
1268
|
expect(environmentLifecycle.inspect().lkgSignature).toBe(activeEnvironment.signature);
|
|
1249
1269
|
frameState.environmentGeneration = environmentLifecycle
|
|
@@ -1257,6 +1277,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
1257
1277
|
height: 8,
|
|
1258
1278
|
frameIndex: 7,
|
|
1259
1279
|
historyValid: true,
|
|
1280
|
+
sampleTimeSeconds: 1.016,
|
|
1260
1281
|
}),
|
|
1261
1282
|
};
|
|
1262
1283
|
const retryFrame = temporalResolveFrame(device, scope, frameState, {});
|
|
@@ -1273,6 +1294,7 @@ describe('renderer successful-submit transaction', () => {
|
|
|
1273
1294
|
expect(gpuCommitAfterSubmit).toEqual([1]);
|
|
1274
1295
|
expect(frameState.activeTemporalGpuState).not.toBe(active);
|
|
1275
1296
|
expect(frameState.successfulTemporalFrameIndex).toBe(8);
|
|
1297
|
+
expect(frameState.lastSuccessfulTemporalView?.sampleTimeSeconds).toBe(1.016);
|
|
1276
1298
|
expect(frameState.temporalGpuState).toBeUndefined();
|
|
1277
1299
|
expect(frameState.retiringTemporalGpuStates.size).toBe(1);
|
|
1278
1300
|
expect(publishEnvironment).toHaveBeenCalledTimes(1);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { inspectResourceClassSplits } from '../gpu-driven/batch-topology';
|
|
3
|
+
import {
|
|
4
|
+
combineGpuResourceAllocationInspections,
|
|
5
|
+
GpuResourceAllocationLedger,
|
|
6
|
+
} from '../gpu-driven/resource-allocation';
|
|
7
|
+
|
|
8
|
+
describe('GPU resource allocation ownership', () => {
|
|
9
|
+
it('keeps replacement coexistence through fence retirement and release', () => {
|
|
10
|
+
const ledger = new GpuResourceAllocationLedger();
|
|
11
|
+
const first = ledger.allocate(64);
|
|
12
|
+
const second = ledger.allocate(128);
|
|
13
|
+
|
|
14
|
+
expect(ledger.inspect()).toMatchObject({
|
|
15
|
+
liveBytes: 192,
|
|
16
|
+
pendingRetirementBytes: 0,
|
|
17
|
+
peakBytes: 192,
|
|
18
|
+
});
|
|
19
|
+
ledger.retire(first);
|
|
20
|
+
expect(ledger.inspect()).toMatchObject({
|
|
21
|
+
liveBytes: 128,
|
|
22
|
+
pendingRetirementBytes: 64,
|
|
23
|
+
peakBytes: 192,
|
|
24
|
+
});
|
|
25
|
+
ledger.release(first);
|
|
26
|
+
expect(ledger.inspect()).toMatchObject({
|
|
27
|
+
liveBytes: 128,
|
|
28
|
+
pendingRetirementBytes: 0,
|
|
29
|
+
retiredBytes: 64,
|
|
30
|
+
});
|
|
31
|
+
ledger.release(second);
|
|
32
|
+
expect(ledger.inspect()).toMatchObject({
|
|
33
|
+
liveBytes: 0,
|
|
34
|
+
pendingRetirementBytes: 0,
|
|
35
|
+
retiredBytes: 192,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('records failed allocation rollback without leaving live bytes', () => {
|
|
40
|
+
const ledger = new GpuResourceAllocationLedger();
|
|
41
|
+
const token = ledger.allocate(256);
|
|
42
|
+
ledger.rollback(token);
|
|
43
|
+
expect(ledger.inspect()).toMatchObject({
|
|
44
|
+
liveBytes: 0,
|
|
45
|
+
failedAllocationRollbacks: 1,
|
|
46
|
+
failedAllocationRollbackBytes: 256,
|
|
47
|
+
peakBytes: 256,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('attributes only resourceIdentity changes as resource-class splits', () => {
|
|
52
|
+
const base = {
|
|
53
|
+
generation: 0,
|
|
54
|
+
key: {
|
|
55
|
+
assetHandle: 1,
|
|
56
|
+
drawKind: 'indexed' as const,
|
|
57
|
+
first: 0,
|
|
58
|
+
count: 3,
|
|
59
|
+
baseVertex: 0,
|
|
60
|
+
materialSlot: 0,
|
|
61
|
+
topology: 'triangle-list' as const,
|
|
62
|
+
pipelineClass: 'pbr',
|
|
63
|
+
materialResourceClass: 'water-a',
|
|
64
|
+
resourceIdentity: 'water-a',
|
|
65
|
+
},
|
|
66
|
+
candidates: [],
|
|
67
|
+
visibleBase: 0,
|
|
68
|
+
visibleCapacity: 0,
|
|
69
|
+
indirectOffset: 0,
|
|
70
|
+
};
|
|
71
|
+
const sameClass = { ...base, batchId: 0 };
|
|
72
|
+
const secondRange = {
|
|
73
|
+
...base,
|
|
74
|
+
batchId: 1,
|
|
75
|
+
key: { ...base.key, first: 3, count: 6 },
|
|
76
|
+
};
|
|
77
|
+
expect(inspectResourceClassSplits({ batches: [sameClass, secondRange] })).toMatchObject({
|
|
78
|
+
resourceClassCount: 1,
|
|
79
|
+
resourceClassSplitReasons: [],
|
|
80
|
+
});
|
|
81
|
+
const changedClass = {
|
|
82
|
+
...secondRange,
|
|
83
|
+
key: { ...secondRange.key, resourceIdentity: 'water-b' },
|
|
84
|
+
};
|
|
85
|
+
expect(inspectResourceClassSplits({ batches: [sameClass, changedClass] })).toMatchObject({
|
|
86
|
+
resourceClassCount: 2,
|
|
87
|
+
resourceClassSplitReasons: ['resource-class:water-a', 'resource-class:water-b'],
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('combines owner facts without claiming physical residency', () => {
|
|
92
|
+
const ledger = new GpuResourceAllocationLedger();
|
|
93
|
+
ledger.allocate(32);
|
|
94
|
+
const combined = combineGpuResourceAllocationInspections([ledger.inspect()]);
|
|
95
|
+
expect(combined).toMatchObject({
|
|
96
|
+
unit: 'engine-allocation-bytes',
|
|
97
|
+
physicalResidency: 'unknown',
|
|
98
|
+
liveBytes: 32,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('does not add historical peaks from owners with no simultaneous occupancy', () => {
|
|
103
|
+
const first = new GpuResourceAllocationLedger();
|
|
104
|
+
const firstToken = first.allocate(64);
|
|
105
|
+
first.retire(firstToken);
|
|
106
|
+
first.release(firstToken);
|
|
107
|
+
|
|
108
|
+
const second = new GpuResourceAllocationLedger();
|
|
109
|
+
const secondToken = second.allocate(128);
|
|
110
|
+
second.retire(secondToken);
|
|
111
|
+
second.release(secondToken);
|
|
112
|
+
|
|
113
|
+
expect(
|
|
114
|
+
combineGpuResourceAllocationInspections([first.inspect(), second.inspect()]),
|
|
115
|
+
).toMatchObject({
|
|
116
|
+
liveBytes: 0,
|
|
117
|
+
pendingRetirementBytes: 0,
|
|
118
|
+
// The owner-local peaks are historical and happened in separate
|
|
119
|
+
// replacement windows; their sum is not an aggregate high-water mark.
|
|
120
|
+
peakBytes: 128,
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|