@forgeax/engine-render 0.1.27 → 0.1.29
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 +842 -124
- package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
- package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +52 -0
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +3 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/gpu-driven-owner.d.ts +10 -0
- package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +19 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +7 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +3 -1
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/recovery/failure-location.d.ts +12 -0
- package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
- package/dist/assembly/recovery/renderer-recover.d.ts +6 -4
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
- package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-helpers.d.ts +3 -0
- package/dist/assembly/renderer-helpers.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +4 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +6 -0
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
- package/dist/assembly/skin-palette-owner.d.ts +8 -0
- package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-device-loss.d.ts +15 -0
- package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +7 -3
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +7 -141
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
- package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
- package/dist/authoring.mjs +3 -3
- package/dist/{chunk-ADHHVYLW.mjs → chunk-33XZFTQU.mjs} +245 -39
- package/dist/chunk-33XZFTQU.mjs.map +1 -0
- package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
- package/dist/chunk-BLXGONR2.mjs.map +1 -0
- package/dist/{chunk-KM2NOX2I.mjs → chunk-BQVQOQJH.mjs} +958 -254
- package/dist/chunk-BQVQOQJH.mjs.map +1 -0
- package/dist/{chunk-HKXTW355.mjs → chunk-BTWH7BP4.mjs} +386 -17
- package/dist/chunk-BTWH7BP4.mjs.map +1 -0
- package/dist/{chunk-TMIASV2N.mjs → chunk-FUODTTIA.mjs} +3934 -676
- package/dist/chunk-FUODTTIA.mjs.map +1 -0
- package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
- package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
- package/dist/{chunk-E34VL5VI.mjs → chunk-JQTSEI3Z.mjs} +3 -3
- package/dist/{chunk-E34VL5VI.mjs.map → chunk-JQTSEI3Z.mjs.map} +1 -1
- package/dist/{chunk-GE3SDD72.mjs → chunk-NICXSHAT.mjs} +16 -38
- package/dist/chunk-NICXSHAT.mjs.map +1 -0
- package/dist/{chunk-ZZ4YQ474.mjs → chunk-NRNXBLIJ.mjs} +577 -7
- package/dist/chunk-NRNXBLIJ.mjs.map +1 -0
- package/dist/{chunk-JDWARUOI.mjs → chunk-PA5DRJNI.mjs} +17 -3
- package/dist/chunk-PA5DRJNI.mjs.map +1 -0
- package/dist/{chunk-XDP6XE5V.mjs → chunk-S4DNKQYQ.mjs} +1118 -446
- package/dist/chunk-S4DNKQYQ.mjs.map +1 -0
- package/dist/components/camera.d.ts +62 -2
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +6 -20
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/scene-instance.d.ts +2 -1
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/screen-space-reflection.d.ts +14 -0
- package/dist/components/screen-space-reflection.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +13805 -7186
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +11 -17
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/mesh-residency-lifetime.d.ts +21 -0
- package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
- package/dist/dynamic-geometry.d.ts +125 -0
- package/dist/dynamic-geometry.d.ts.map +1 -0
- package/dist/environment/background.d.ts +6 -0
- package/dist/environment/background.d.ts.map +1 -0
- package/dist/errors/gpu-driven.d.ts +6 -3
- package/dist/errors/gpu-driven.d.ts.map +1 -1
- package/dist/errors/render.d.ts +7 -4
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +33 -3
- package/dist/extract/gpu-driven.d.ts.map +1 -1
- package/dist/features/host.d.ts +23 -1
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/noise-texture.d.ts +17 -0
- package/dist/features/noise-texture.d.ts.map +1 -0
- package/dist/features/plan.d.ts +83 -2
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +37 -4
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/features/prepared-graphics.d.ts +5 -0
- package/dist/features/prepared-graphics.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts +5 -3
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +11 -3
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +19 -3
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/types.d.ts +11 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +2 -0
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/pbr-program.d.ts +10 -0
- package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +144 -23
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-views.d.ts +126 -0
- package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +18 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +2 -8
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +14 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-texture-usage.d.ts +1 -0
- package/dist/gpu-texture-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +6 -0
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts +8 -0
- package/dist/ibl/frame-resources.d.ts.map +1 -0
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +21 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +8 -7
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +164 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +11 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -1
- package/dist/instances.d.ts +89 -44
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +118 -10
- package/dist/internal.mjs.map +1 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/material-row.d.ts +5 -0
- package/dist/material-row.d.ts.map +1 -0
- package/dist/materials.d.ts +15 -0
- package/dist/materials.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +21 -5
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
- package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
- package/dist/pipeline/standard-output/graph.d.ts +15 -0
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
- package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/resources.d.ts +10 -0
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
- package/dist/pipeline/standard-output/types.d.ts +39 -0
- package/dist/pipeline/standard-output/types.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +2 -2
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec-types.d.ts +4 -0
- package/dist/pipeline-spec-types.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +1 -9
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/points-lines/standard-owner.d.ts +1 -1
- package/dist/points-lines/standard-owner.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +3 -3
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +106 -5
- 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 +39 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +7 -8
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +38 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +2 -10
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +12 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +15 -6
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/prepared-material-bindings.d.ts +19 -0
- package/dist/record/prepared-material-bindings.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts +2 -9
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +76 -26
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +62 -7
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +35 -7
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +1 -0
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +10 -2
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/recovery/render-system-roots.d.ts +11 -0
- package/dist/recovery/render-system-roots.d.ts.map +1 -0
- package/dist/recovery/types.d.ts +76 -0
- package/dist/recovery/types.d.ts.map +1 -0
- package/dist/reflection/record-owner.d.ts +0 -2
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +185 -30
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +64 -5
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +7 -5
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +101 -41
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-projections.d.ts +22 -0
- package/dist/render-system-projections.d.ts.map +1 -0
- package/dist/render-system.d.ts +34 -77
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +14 -7
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +29 -11
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/shadow-visibility.d.ts +5 -0
- package/dist/scene/shadow-visibility.d.ts.map +1 -0
- package/dist/ssr/admission.d.ts +70 -1
- package/dist/ssr/admission.d.ts.map +1 -1
- package/dist/ssr/compose.d.ts +13 -0
- package/dist/ssr/compose.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +35 -0
- package/dist/ssr/errors.d.ts.map +1 -1
- package/dist/ssr/graph.d.ts +60 -0
- package/dist/ssr/graph.d.ts.map +1 -0
- package/dist/ssr/history.d.ts +97 -0
- package/dist/ssr/history.d.ts.map +1 -0
- package/dist/ssr/hiz.d.ts +37 -0
- package/dist/ssr/hiz.d.ts.map +1 -0
- package/dist/ssr/inspection.d.ts +42 -0
- package/dist/ssr/inspection.d.ts.map +1 -0
- package/dist/ssr/resources.d.ts +58 -0
- package/dist/ssr/resources.d.ts.map +1 -0
- package/dist/ssr/temporal.d.ts +38 -0
- package/dist/ssr/temporal.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +32 -10
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +15 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +9 -0
- package/dist/systems/transparent-dispatch.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +7 -0
- package/dist/targets/material-source.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts +7 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +8 -0
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/history.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -6
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts +2 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/temporal-view.d.ts +2 -0
- package/dist/temporal/temporal-view.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +35 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +3 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +6 -0
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
- package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
- package/src/__tests__/auto-exposure.browser.test.ts +33 -0
- package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
- package/src/__tests__/detached-inspection.integration.test.ts +5 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
- package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
- package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
- package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
- package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
- package/src/__tests__/factory-contract.integration.test.ts +73 -22
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
- package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
- package/src/__tests__/feature-noise.unit.test.ts +38 -0
- package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
- package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
- package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
- package/src/__tests__/frame-targets.unit.test.ts +24 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +287 -6
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
- package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
- package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +264 -0
- package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +349 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1417 -0
- package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +1075 -93
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
- package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
- package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
- package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
- package/src/__tests__/gpu-driven-view.unit.test.ts +159 -52
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -1
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
- package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
- package/src/__tests__/gpu-scene.unit.test.ts +559 -33
- package/src/__tests__/instances-culling.integration.test.ts +36 -10
- package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
- package/src/__tests__/instances-store.unit.test.ts +242 -39
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
- package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
- package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
- package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
- package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
- package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
- package/src/__tests__/material-texture-source.unit.test.ts +87 -0
- package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
- package/src/__tests__/materials-standard-contract.unit.test.ts +52 -2
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
- package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
- package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +37 -3
- package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
- package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
- package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +35 -4
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
- package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
- package/src/__tests__/public-surface.test-d.ts +3 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
- package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +104 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +2 -1
- package/src/__tests__/render-error-code-owner.test-d.ts +4 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +22 -0
- package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
- package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
- package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
- package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
- package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
- package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +914 -23
- package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
- package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
- package/src/__tests__/render-target-material-source.test-d.ts +27 -3
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +61 -1
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
- package/src/__tests__/shader-manifest-fixture.ts +39 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
- package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
- package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +118 -14
- package/src/__tests__/specular-environment-scale.dawn.test.ts +156 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
- package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
- package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
- package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +91 -0
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +112 -0
- package/src/__tests__/ssr-gpu-dispatch.ts +946 -0
- package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
- package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
- package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
- package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
- package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
- package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
- package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
- package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
- package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
- package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
- package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
- package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
- package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
- package/src/__tests__/ssr-reprojection-probe.ts +90 -0
- package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
- package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
- package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
- package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
- package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
- package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +44 -12
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
- package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
- package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
- package/src/__tests__/standard-output.browser.test.ts +15 -0
- package/src/__tests__/standard-output.dawn.test.ts +15 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +38 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
- package/src/__tests__/standard-profile-oracle.unit.test.ts +22 -0
- package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
- package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
- package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
- package/src/__tests__/taa-coverage-edge.dawn.test.ts +193 -0
- package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
- package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +778 -0
- package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
- package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
- package/src/__tests__/taa-stability-feedback.ts +341 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
- package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
- package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
- package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
- package/src/__tests__/visibility-extract.perf.test.ts +20 -8
- package/src/__tests__/visibility-instances.integration.test.ts +19 -7
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
- package/src/assembly/atmosphere-shader-prewarm.ts +38 -0
- package/src/assembly/dynamic-geometry-host.ts +887 -0
- package/src/assembly/dynamic-geometry-runtime.ts +71 -0
- package/src/assembly/factory.ts +4 -0
- package/src/assembly/gpu-driven-owner.ts +29 -0
- package/src/assembly/host-contract.ts +36 -0
- package/src/assembly/material/assembly.ts +38 -0
- package/src/assembly/material-shader-policy.ts +71 -28
- package/src/assembly/recovery/failure-location.ts +62 -0
- package/src/assembly/recovery/renderer-recover.ts +19 -17
- package/src/assembly/renderer-facade.ts +29 -0
- package/src/assembly/renderer-feature-inspection.ts +13 -0
- package/src/assembly/renderer-frame-transaction.ts +63 -0
- package/src/assembly/renderer-helpers.ts +26 -0
- package/src/assembly/renderer-inspection.ts +6 -0
- package/src/assembly/shader-prewarm-policy.ts +32 -0
- package/src/assembly/skin-palette-owner.ts +21 -0
- package/src/assembly/ssr-shader-prewarm.ts +41 -0
- package/src/assembly/webgpu-device-loss.ts +75 -0
- package/src/assembly/webgpu-pbr-ready.ts +232 -0
- package/src/assembly/webgpu-ready-mipmap.ts +26 -0
- package/src/assembly/webgpu-ready.ts +142 -121
- package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
- package/src/assembly/webgpu-renderer-contract.ts +69 -0
- package/src/assembly/webgpu-renderer-guards.ts +32 -0
- package/src/assembly/webgpu-renderer-observation.ts +43 -0
- package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
- package/src/assembly/webgpu-renderer.ts +675 -614
- package/src/assembly/webgpu-vertex-layouts.ts +233 -87
- package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
- package/src/components/camera.ts +287 -7
- package/src/components/index.ts +1 -0
- package/src/components/instances.ts +45 -18
- package/src/components/scene-instance.ts +2 -1
- package/src/components/screen-space-reflection.ts +21 -0
- package/src/components/sprite-animation.ts +3 -3
- package/src/components/sprite-instances.ts +1 -1
- package/src/device/gpu-residency.ts +96 -93
- package/src/device/mesh-residency-lifetime.ts +73 -0
- package/src/dynamic-geometry.ts +736 -0
- package/src/environment/background.ts +263 -0
- package/src/errors/gpu-driven.ts +39 -5
- package/src/errors/render.ts +27 -3
- package/src/extract/camera.ts +26 -1
- package/src/extract/gpu-driven.ts +185 -10
- package/src/features/host.ts +237 -19
- package/src/features/noise-texture.ts +91 -0
- package/src/features/plan.ts +553 -24
- package/src/features/prepared-gpu-work.ts +631 -49
- package/src/features/prepared-graphics-store.ts +31 -0
- package/src/features/prepared-graphics.ts +5 -0
- package/src/features/render-graph-compute.ts +41 -8
- package/src/features/render-graph-contribution.ts +141 -3
- package/src/features/render-graph-raster.ts +143 -30
- package/src/features/types.ts +11 -0
- package/src/fullscreen-post-process-pass.ts +3 -0
- package/src/gpu-driven/batch-topology.ts +424 -102
- package/src/gpu-driven/pbr-program.ts +31 -0
- package/src/gpu-driven/prepared-draw.ts +29 -4
- package/src/gpu-driven/production-raster.ts +2267 -694
- package/src/gpu-driven/shadow-views.ts +539 -0
- package/src/gpu-driven/view-gpu.ts +188 -41
- package/src/gpu-scene-schema.ts +52 -11
- package/src/gpu-scene.ts +186 -99
- package/src/gpu-texture-usage.ts +1 -0
- package/src/hdrp-buffers.ts +72 -36
- package/src/ibl/frame-resources.ts +38 -0
- package/src/ibl/skylight-bind-group.ts +5 -4
- package/src/index.ts +125 -1
- package/src/inspection-types.ts +191 -0
- package/src/instances-derived-bounds.ts +258 -34
- package/src/instances.ts +459 -150
- package/src/internal.ts +22 -0
- package/src/lifecycle.ts +2 -0
- package/src/material-row.ts +145 -0
- package/src/materials.ts +44 -8
- package/src/pbr-pipeline.ts +159 -17
- package/src/pipeline/standard-forward-lane.ts +52 -24
- package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
- package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
- package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
- package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
- package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
- package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
- package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
- package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
- package/src/pipeline/standard-output/color-transform.ts +124 -0
- package/src/pipeline/standard-output/graph.ts +139 -0
- package/src/pipeline/standard-output/lut-admission.ts +121 -0
- package/src/pipeline/standard-output/lut-gpu.ts +399 -0
- package/src/pipeline/standard-output/lut-state.ts +176 -0
- package/src/pipeline/standard-output/resources.ts +121 -0
- package/src/pipeline/standard-output/types.ts +58 -0
- package/src/pipeline/standard-pipeline.ts +192 -59
- package/src/pipeline/standard-post.ts +186 -27
- package/src/pipeline-builder.ts +16 -6
- package/src/pipeline-spec-types.ts +4 -0
- package/src/pipeline-spec.ts +37 -29
- package/src/points-lines/standard-owner.ts +6 -14
- package/src/prepare/prepared-graphics-resolver.ts +9 -2
- package/src/record/__tests__/material-slot-plan.unit.test.ts +48 -0
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +2 -29
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +36 -5
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
- package/src/record/dynamic-geometry-consumption.ts +59 -0
- package/src/record/frame-lighting.ts +12 -11
- package/src/record/frame-snapshot.ts +133 -23
- package/src/record/frame-targets.ts +9 -0
- package/src/record/frame.ts +727 -133
- package/src/record/main-pass-geometry.ts +162 -98
- package/src/record/main-pass-material.ts +115 -26
- package/src/record/main-pass-sprite-draws.ts +18 -107
- package/src/record/main-pass.ts +78 -8
- package/src/record/material-uniforms.ts +1 -1
- package/src/record/mesh-ssbo.ts +59 -15
- package/src/record/prepared-material-bindings.ts +234 -0
- package/src/record/recovery-pipeline.ts +59 -136
- package/src/record/render-context.ts +92 -22
- package/src/record/shadow-pass.ts +1231 -209
- package/src/record/skybox-post-pass.ts +14 -3
- package/src/record/typed-frame-graph.ts +1006 -53
- package/src/record/view-ubo.ts +11 -0
- package/src/recovery/render-system-candidate.ts +90 -66
- package/src/recovery/render-system-roots.ts +113 -0
- package/src/recovery/types.ts +77 -0
- package/src/reflection/record-owner.ts +26 -54
- package/src/render-contract.ts +219 -25
- package/src/render-graph-primitives.ts +6 -2
- package/src/render-pipeline.ts +70 -1
- package/src/render-system-extract-tail.ts +409 -160
- package/src/render-system-extract.ts +376 -102
- package/src/render-system-projections.ts +241 -0
- package/src/render-system.ts +692 -791
- package/src/scene/render-scene-types.ts +13 -4
- package/src/scene/render-scene.ts +569 -355
- package/src/scene/shadow-visibility.ts +21 -0
- package/src/ssr/admission.ts +380 -14
- package/src/ssr/compose.ts +144 -0
- package/src/ssr/errors.ts +48 -0
- package/src/ssr/graph.ts +777 -0
- package/src/ssr/history.ts +436 -0
- package/src/ssr/hiz.ts +124 -0
- package/src/ssr/inspection.ts +124 -0
- package/src/ssr/resources.ts +202 -0
- package/src/ssr/temporal.ts +164 -0
- package/src/systems/skin-palette-allocator.ts +495 -148
- package/src/systems/skin-palette-types.ts +17 -0
- package/src/systems/transparent-dispatch.ts +90 -0
- package/src/targets/material-source.ts +34 -0
- package/src/temporal/coverage.ts +1 -1
- package/src/temporal/frame-coordinator.ts +23 -2
- package/src/temporal/gpu.ts +74 -12
- package/src/temporal/history.ts +3 -1
- package/src/temporal/inspection.ts +2 -1
- package/src/temporal/standard-scene-data.ts +3 -1
- package/src/temporal/temporal-view.ts +3 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +204 -139
- package/src/typed-render-graph-primitives.ts +266 -74
- package/src/typed-shadow-passes.ts +122 -12
- package/src/volume/temporal.ts +10 -0
- package/dist/chunk-ADHHVYLW.mjs.map +0 -1
- package/dist/chunk-FJ6P52EE.mjs.map +0 -1
- package/dist/chunk-GE3SDD72.mjs.map +0 -1
- package/dist/chunk-GF523LHF.mjs.map +0 -1
- package/dist/chunk-HKXTW355.mjs.map +0 -1
- package/dist/chunk-JDWARUOI.mjs.map +0 -1
- package/dist/chunk-KM2NOX2I.mjs.map +0 -1
- package/dist/chunk-TMIASV2N.mjs.map +0 -1
- package/dist/chunk-XDP6XE5V.mjs.map +0 -1
- package/dist/chunk-ZZ4YQ474.mjs.map +0 -1
- package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PrimitiveTopology } from '@forgeax/engine-types';
|
|
2
|
+
import { gpuDrivenSourceDrawItemIndex } from '../extract/gpu-driven';
|
|
2
3
|
import type { BatchTopologyInspection } from '../inspection-types';
|
|
3
4
|
import type { CameraSnapshot } from '../render-contract';
|
|
4
5
|
import type { RenderSceneApplyResult, RenderSceneSlot } from '../scene/render-scene-types';
|
|
@@ -8,6 +9,9 @@ import type { PreparedGpuDrivenDraw } from './prepared-draw';
|
|
|
8
9
|
|
|
9
10
|
export type { BatchTopologyInspection } from '../inspection-types';
|
|
10
11
|
|
|
12
|
+
/** High bit in the compact candidate material lane marks a skin palette row. */
|
|
13
|
+
export const GPU_DRIVEN_SKIN_FLAG = 0x80000000;
|
|
14
|
+
|
|
11
15
|
export interface GpuDrivenBatchKey {
|
|
12
16
|
readonly assetHandle: number;
|
|
13
17
|
readonly drawKind: 'indexed' | 'non-indexed';
|
|
@@ -31,6 +35,7 @@ export interface GpuDrivenCandidate {
|
|
|
31
35
|
readonly generation: number;
|
|
32
36
|
readonly drawItemIndex: number;
|
|
33
37
|
readonly instanceOrdinal: number;
|
|
38
|
+
readonly prepared?: PreparedGpuDrivenDraw;
|
|
34
39
|
/** Absolute coverage rows uploaded to the GPU selector; root is implicit. */
|
|
35
40
|
readonly lodCoverages?: readonly number[];
|
|
36
41
|
readonly lodHysteresis?: number;
|
|
@@ -40,7 +45,6 @@ export interface GpuDrivenCandidate {
|
|
|
40
45
|
readonly count: number;
|
|
41
46
|
readonly baseVertex: number;
|
|
42
47
|
}[];
|
|
43
|
-
readonly prepared?: PreparedGpuDrivenDraw;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
export interface GpuDrivenBatch {
|
|
@@ -55,6 +59,8 @@ export interface GpuDrivenBatch {
|
|
|
55
59
|
|
|
56
60
|
export interface SubmissionPlan {
|
|
57
61
|
readonly revision: number;
|
|
62
|
+
/** Payload-only updates keep topology revision stable but still invalidate the plan snapshot. */
|
|
63
|
+
readonly payloadRevision: number;
|
|
58
64
|
readonly batches: readonly GpuDrivenBatch[];
|
|
59
65
|
readonly candidateCount: number;
|
|
60
66
|
readonly visibleCapacity: number;
|
|
@@ -86,6 +92,88 @@ export function compactGpuLodCandidates(
|
|
|
86
92
|
);
|
|
87
93
|
}
|
|
88
94
|
|
|
95
|
+
export interface SubmissionCandidateMembershipEntry {
|
|
96
|
+
readonly batchId: number;
|
|
97
|
+
readonly candidate: GpuDrivenCandidate;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Immutable reverse membership for one submission topology.
|
|
102
|
+
*
|
|
103
|
+
* Shadow views query the same candidate domain as the main view. Keeping the
|
|
104
|
+
* primitive-to-batch join beside the immutable plan makes that lookup once per
|
|
105
|
+
* topology instead of rescanning every batch for every view.
|
|
106
|
+
*/
|
|
107
|
+
export interface SubmissionCandidateMembership {
|
|
108
|
+
readonly source: SubmissionPlan;
|
|
109
|
+
readonly byPrimitiveIndex: ReadonlyMap<number, readonly SubmissionCandidateMembershipEntry[]>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const submissionCandidateMembershipCache = new WeakMap<
|
|
113
|
+
SubmissionPlan,
|
|
114
|
+
SubmissionCandidateMembership
|
|
115
|
+
>();
|
|
116
|
+
|
|
117
|
+
export function buildSubmissionCandidateMembership(
|
|
118
|
+
source: SubmissionPlan,
|
|
119
|
+
): SubmissionCandidateMembership {
|
|
120
|
+
const cached = submissionCandidateMembershipCache.get(source);
|
|
121
|
+
if (cached !== undefined) return cached;
|
|
122
|
+
|
|
123
|
+
const mutable = new Map<number, SubmissionCandidateMembershipEntry[]>();
|
|
124
|
+
for (const batch of source.batches) {
|
|
125
|
+
for (const candidate of batch.candidates) {
|
|
126
|
+
const entries = mutable.get(candidate.primitiveIndex) ?? [];
|
|
127
|
+
entries.push({ batchId: batch.batchId, candidate });
|
|
128
|
+
mutable.set(candidate.primitiveIndex, entries);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const byPrimitiveIndex = new Map<number, readonly SubmissionCandidateMembershipEntry[]>();
|
|
132
|
+
for (const [primitiveIndex, entries] of mutable) {
|
|
133
|
+
byPrimitiveIndex.set(primitiveIndex, Object.freeze(entries));
|
|
134
|
+
}
|
|
135
|
+
const membership: SubmissionCandidateMembership = {
|
|
136
|
+
source,
|
|
137
|
+
byPrimitiveIndex,
|
|
138
|
+
};
|
|
139
|
+
submissionCandidateMembershipCache.set(source, membership);
|
|
140
|
+
return membership;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Re-project one source topology for a view without changing batch identity.
|
|
145
|
+
* The returned plan only changes candidate windows and keeps batch ids,
|
|
146
|
+
* generations, draw ranges, and indirect offsets from the source plan.
|
|
147
|
+
*/
|
|
148
|
+
export function buildBatchAlignedSubmission(
|
|
149
|
+
source: SubmissionPlan,
|
|
150
|
+
candidatesByBatch: ReadonlyMap<number, readonly GpuDrivenCandidate[]>,
|
|
151
|
+
): SubmissionPlan {
|
|
152
|
+
let visibleBase = 0;
|
|
153
|
+
const batches: GpuDrivenBatch[] = [];
|
|
154
|
+
for (const sourceBatch of source.batches) {
|
|
155
|
+
const candidates = candidatesByBatch.get(sourceBatch.batchId) ?? [];
|
|
156
|
+
if (candidates.length === 0) continue;
|
|
157
|
+
visibleBase = alignInstanceBase(visibleBase);
|
|
158
|
+
batches.push(
|
|
159
|
+
Object.freeze({
|
|
160
|
+
...sourceBatch,
|
|
161
|
+
candidates: Object.freeze([...candidates]),
|
|
162
|
+
visibleBase,
|
|
163
|
+
visibleCapacity: candidates.length,
|
|
164
|
+
}),
|
|
165
|
+
);
|
|
166
|
+
visibleBase += candidates.length;
|
|
167
|
+
}
|
|
168
|
+
return Object.freeze({
|
|
169
|
+
revision: source.revision,
|
|
170
|
+
payloadRevision: source.payloadRevision,
|
|
171
|
+
batches: Object.freeze(batches),
|
|
172
|
+
candidateCount: batches.reduce((total, batch) => total + batch.candidates.length, 0),
|
|
173
|
+
visibleCapacity: visibleBase,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
89
177
|
interface MutableBatch {
|
|
90
178
|
readonly batchId: number;
|
|
91
179
|
readonly generation: number;
|
|
@@ -93,7 +181,37 @@ interface MutableBatch {
|
|
|
93
181
|
readonly candidates: Map<string, GpuDrivenCandidate>;
|
|
94
182
|
}
|
|
95
183
|
|
|
96
|
-
|
|
184
|
+
interface EligibleGpuDrivenDraw {
|
|
185
|
+
readonly sourceDrawIndex: number;
|
|
186
|
+
readonly key: GpuDrivenBatchKey;
|
|
187
|
+
readonly prepared?: PreparedGpuDrivenDraw;
|
|
188
|
+
readonly projectedHeight?: number;
|
|
189
|
+
readonly lodCoverages?: readonly number[];
|
|
190
|
+
readonly lodHysteresis?: number;
|
|
191
|
+
readonly lodRanges?: readonly {
|
|
192
|
+
readonly first: number;
|
|
193
|
+
readonly count: number;
|
|
194
|
+
readonly baseVertex: number;
|
|
195
|
+
}[];
|
|
196
|
+
/** Candidate data that does not change batch compatibility. */
|
|
197
|
+
readonly payloadRevision: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
interface MembershipDraw {
|
|
201
|
+
readonly sourceDrawIndex: number;
|
|
202
|
+
readonly key: GpuDrivenBatchKey;
|
|
203
|
+
readonly batchText: string;
|
|
204
|
+
readonly candidateKeyPrefix: string;
|
|
205
|
+
readonly payloadRevision: string;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
interface MembershipProjection {
|
|
209
|
+
readonly instanceCount: number;
|
|
210
|
+
readonly hasLod: boolean;
|
|
211
|
+
readonly draws: readonly MembershipDraw[];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function eligibleDraws(slot: RenderSceneSlot): readonly EligibleGpuDrivenDraw[] {
|
|
97
215
|
const snapshot = slot.snapshot;
|
|
98
216
|
const draws = snapshot.gpuDrivenDraws;
|
|
99
217
|
if (
|
|
@@ -101,29 +219,51 @@ function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
|
|
|
101
219
|
draws.length === 0 ||
|
|
102
220
|
snapshot.instances?.instanceCount === 0 ||
|
|
103
221
|
snapshot.localAabb === undefined ||
|
|
104
|
-
snapshot.skin !== undefined ||
|
|
105
222
|
snapshot.morph !== undefined ||
|
|
106
223
|
snapshot.spriteInstances !== undefined
|
|
107
224
|
) {
|
|
108
225
|
return [];
|
|
109
226
|
}
|
|
110
|
-
|
|
227
|
+
const result: EligibleGpuDrivenDraw[] = [];
|
|
228
|
+
for (let compactIndex = 0; compactIndex < draws.length; compactIndex += 1) {
|
|
229
|
+
const draw = draws[compactIndex];
|
|
230
|
+
if (draw === undefined) continue;
|
|
231
|
+
const drawItemIndex = gpuDrivenSourceDrawItemIndex(draw, compactIndex);
|
|
111
232
|
const prepared = draw.prepared;
|
|
112
233
|
const material = snapshot.materials[draw.materialSlot] ?? snapshot.material;
|
|
113
234
|
if (prepared !== undefined) {
|
|
114
235
|
const isStandardPbr =
|
|
115
236
|
(material.materialShaderId === 'forgeax::default-standard-pbr' &&
|
|
116
237
|
prepared.identity.material === 'forgeax::default-standard-pbr') ||
|
|
117
|
-
(material.materialShaderId === 'forgeax::
|
|
118
|
-
|
|
238
|
+
((material.materialShaderId === 'forgeax::pbr-skin' ||
|
|
239
|
+
material.materialShaderId === 'forgeax::default-standard-pbr-skin') &&
|
|
240
|
+
(prepared.identity.material === 'forgeax::pbr-skin' ||
|
|
241
|
+
prepared.identity.material === 'forgeax::default-standard-pbr-skin'));
|
|
119
242
|
const isAlphaBlend =
|
|
120
243
|
material.transparent === true || material.renderState?.blend !== undefined;
|
|
121
|
-
|
|
244
|
+
const cpuOnlyMaterialResources =
|
|
245
|
+
(material.textureSources?.size ?? 0) > 0 || (material.videoTextureFields?.size ?? 0) > 0;
|
|
246
|
+
const skinReady =
|
|
247
|
+
prepared.identity.deformation !== 'skin' ||
|
|
248
|
+
(snapshot.skin?.storageOrUniform === 'storage' &&
|
|
249
|
+
snapshot.skin.customDataStart >= 0 &&
|
|
250
|
+
Number.isInteger(snapshot.skin.customDataStart) &&
|
|
251
|
+
hasFiniteOrderedBounds(snapshot.skin.bounds) &&
|
|
252
|
+
prepared.skinPaletteAddress !== undefined);
|
|
253
|
+
if (
|
|
254
|
+
!isStandardPbr ||
|
|
255
|
+
isAlphaBlend ||
|
|
256
|
+
cpuOnlyMaterialResources ||
|
|
257
|
+
(prepared.identity.deformation !== 'rigid' && prepared.identity.deformation !== 'skin') ||
|
|
258
|
+
!skinReady
|
|
259
|
+
)
|
|
260
|
+
continue;
|
|
122
261
|
const preparedIdentity = `${prepared.identity.material}|${prepared.identity.geometry}|${prepared.identity.deformation}`;
|
|
123
262
|
const admission =
|
|
124
263
|
typeof material.paramSnapshot?.alphaCutoff === 'number' ? 'alpha-mask' : 'opaque';
|
|
125
|
-
|
|
126
|
-
|
|
264
|
+
result.push({
|
|
265
|
+
sourceDrawIndex: drawItemIndex,
|
|
266
|
+
key: {
|
|
127
267
|
assetHandle: snapshot.assetHandle,
|
|
128
268
|
drawKind: draw.kind,
|
|
129
269
|
first: prepared.first,
|
|
@@ -137,10 +277,14 @@ function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
|
|
|
137
277
|
resourceIdentity: draw.materialResourceClass,
|
|
138
278
|
admission,
|
|
139
279
|
},
|
|
140
|
-
|
|
280
|
+
prepared,
|
|
281
|
+
...candidatePayload(draw, snapshot),
|
|
282
|
+
});
|
|
283
|
+
continue;
|
|
141
284
|
}
|
|
142
|
-
|
|
143
|
-
|
|
285
|
+
result.push({
|
|
286
|
+
sourceDrawIndex: drawItemIndex,
|
|
287
|
+
key: {
|
|
144
288
|
assetHandle: snapshot.assetHandle,
|
|
145
289
|
drawKind: draw.kind,
|
|
146
290
|
first: draw.first,
|
|
@@ -151,8 +295,66 @@ function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
|
|
|
151
295
|
pipelineClass: draw.pipelineClass,
|
|
152
296
|
materialResourceClass: draw.materialResourceClass,
|
|
153
297
|
},
|
|
154
|
-
|
|
298
|
+
...candidatePayload(draw, snapshot),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function candidatePayload(
|
|
305
|
+
draw: NonNullable<RenderSceneSlot['snapshot']['gpuDrivenDraws']>[number],
|
|
306
|
+
snapshot: RenderSceneSlot['snapshot'],
|
|
307
|
+
): Pick<
|
|
308
|
+
EligibleGpuDrivenDraw,
|
|
309
|
+
'lodCoverages' | 'lodHysteresis' | 'lodRanges' | 'payloadRevision' | 'projectedHeight'
|
|
310
|
+
> {
|
|
311
|
+
const lodCoverages =
|
|
312
|
+
snapshot.lods === undefined
|
|
313
|
+
? undefined
|
|
314
|
+
: [1, ...snapshot.lods.map((lod) => lod.screenCoverage)];
|
|
315
|
+
const lodRanges = draw.lodRanges as EligibleGpuDrivenDraw['lodRanges'];
|
|
316
|
+
const lodHysteresis = snapshot.lodHysteresis;
|
|
317
|
+
const payloadRevision = JSON.stringify({
|
|
318
|
+
projectedHeight: draw.projectedHeight,
|
|
319
|
+
lodCoverages,
|
|
320
|
+
lodHysteresis,
|
|
321
|
+
lodRanges,
|
|
322
|
+
prepared: draw.prepared,
|
|
155
323
|
});
|
|
324
|
+
return {
|
|
325
|
+
...(draw.projectedHeight === undefined ? {} : { projectedHeight: draw.projectedHeight }),
|
|
326
|
+
...(lodCoverages === undefined ? {} : { lodCoverages }),
|
|
327
|
+
...(lodHysteresis === undefined ? {} : { lodHysteresis }),
|
|
328
|
+
...(lodRanges === undefined ? {} : { lodRanges }),
|
|
329
|
+
payloadRevision,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function hasFiniteOrderedBounds(bounds: Float32Array | undefined): boolean {
|
|
334
|
+
if (bounds === undefined || bounds.length < 6) return false;
|
|
335
|
+
const minX = bounds[0];
|
|
336
|
+
const minY = bounds[1];
|
|
337
|
+
const minZ = bounds[2];
|
|
338
|
+
const maxX = bounds[3];
|
|
339
|
+
const maxY = bounds[4];
|
|
340
|
+
const maxZ = bounds[5];
|
|
341
|
+
return (
|
|
342
|
+
minX !== undefined &&
|
|
343
|
+
minY !== undefined &&
|
|
344
|
+
minZ !== undefined &&
|
|
345
|
+
maxX !== undefined &&
|
|
346
|
+
maxY !== undefined &&
|
|
347
|
+
maxZ !== undefined &&
|
|
348
|
+
Number.isFinite(minX) &&
|
|
349
|
+
Number.isFinite(minY) &&
|
|
350
|
+
Number.isFinite(minZ) &&
|
|
351
|
+
Number.isFinite(maxX) &&
|
|
352
|
+
Number.isFinite(maxY) &&
|
|
353
|
+
Number.isFinite(maxZ) &&
|
|
354
|
+
minX <= maxX &&
|
|
355
|
+
minY <= maxY &&
|
|
356
|
+
minZ <= maxZ
|
|
357
|
+
);
|
|
156
358
|
}
|
|
157
359
|
|
|
158
360
|
function keyText(key: GpuDrivenBatchKey): string {
|
|
@@ -160,11 +362,9 @@ function keyText(key: GpuDrivenBatchKey): string {
|
|
|
160
362
|
}
|
|
161
363
|
|
|
162
364
|
/**
|
|
163
|
-
* A GPU indirect draw has one index/vertex range for the whole batch.
|
|
365
|
+
* A GPU indirect draw has one index/vertex range for the whole batch. LOD
|
|
164
366
|
* selection is per candidate, so sharing a batch between LOD candidates would
|
|
165
|
-
* let
|
|
166
|
-
* instance. Keep LOD candidates in single-candidate batches; ordinary meshes
|
|
167
|
-
* retain the existing compatibility batching path.
|
|
367
|
+
* let the first candidate's range serve every visible instance.
|
|
168
368
|
*/
|
|
169
369
|
function candidateBatchText(
|
|
170
370
|
key: GpuDrivenBatchKey,
|
|
@@ -178,19 +378,32 @@ function candidateBatchText(
|
|
|
178
378
|
: keyText(key);
|
|
179
379
|
}
|
|
180
380
|
|
|
181
|
-
function
|
|
182
|
-
|
|
381
|
+
function drawBatchText(
|
|
382
|
+
key: GpuDrivenBatchKey,
|
|
383
|
+
primitiveIndex: number,
|
|
384
|
+
drawItemIndex: number,
|
|
385
|
+
hasLod: boolean,
|
|
386
|
+
): string {
|
|
387
|
+
return hasLod ? `${keyText(key)}|lod:${primitiveIndex}:${drawItemIndex}` : keyText(key);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function membershipProjection(
|
|
391
|
+
slot: RenderSceneSlot,
|
|
392
|
+
draws = eligibleDraws(slot),
|
|
393
|
+
): MembershipProjection {
|
|
183
394
|
const instanceCount = slot.snapshot.instances?.instanceCount ?? 1;
|
|
184
395
|
const hasLod = (slot.snapshot.lods?.length ?? 0) > 0;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
396
|
+
return {
|
|
397
|
+
instanceCount,
|
|
398
|
+
hasLod,
|
|
399
|
+
draws: draws.map((draw) => ({
|
|
400
|
+
sourceDrawIndex: draw.sourceDrawIndex,
|
|
401
|
+
key: draw.key,
|
|
402
|
+
batchText: drawBatchText(draw.key, slot.slot, draw.sourceDrawIndex, hasLod),
|
|
403
|
+
candidateKeyPrefix: `${slot.slot}:${draw.sourceDrawIndex}:`,
|
|
404
|
+
payloadRevision: draw.payloadRevision,
|
|
405
|
+
})),
|
|
406
|
+
};
|
|
194
407
|
}
|
|
195
408
|
|
|
196
409
|
function alignInstanceBase(value: number): number {
|
|
@@ -209,10 +422,6 @@ export function projectedHeightForCandidate(slot: RenderSceneSlot, camera: Camer
|
|
|
209
422
|
const halfY = Math.abs((aabb[4] ?? 0) - (aabb[1] ?? 0)) * 0.5;
|
|
210
423
|
const halfZ = Math.abs((aabb[5] ?? 0) - (aabb[2] ?? 0)) * 0.5;
|
|
211
424
|
const world = slot.snapshot.transform.world;
|
|
212
|
-
// Transform the local AABB's half extents through the absolute value of the
|
|
213
|
-
// world 3x3. This is the conservative world-space sphere bound for every
|
|
214
|
-
// rotation and signed/non-uniform scale, and keeps CPU projection aligned
|
|
215
|
-
// with the world transform uploaded to the GPU selector.
|
|
216
425
|
const worldHalfX =
|
|
217
426
|
Math.abs(world[0] ?? 0) * halfX +
|
|
218
427
|
Math.abs(world[4] ?? 0) * halfY +
|
|
@@ -241,16 +450,19 @@ export function projectedHeightForCandidate(slot: RenderSceneSlot, camera: Camer
|
|
|
241
450
|
/** Stable compatibility grouping; per-view visibility never mutates this owner. */
|
|
242
451
|
export class BatchTopology {
|
|
243
452
|
private readonly batches = new Map<string, MutableBatch>();
|
|
244
|
-
private readonly membershipByPrimitive = new Map<
|
|
245
|
-
number,
|
|
246
|
-
readonly { readonly batchText: string; readonly candidateKey: string }[]
|
|
247
|
-
>();
|
|
453
|
+
private readonly membershipByPrimitive = new Map<number, MembershipProjection>();
|
|
248
454
|
private readonly ineligiblePrimitives = new Set<number>();
|
|
249
455
|
private readonly generationByBatchId: number[] = [];
|
|
250
456
|
private readonly freeBatchIds: number[] = [];
|
|
251
457
|
private revision = 0;
|
|
458
|
+
private payloadRevision = 0;
|
|
252
459
|
private rebuilds = 0;
|
|
253
460
|
private patches = 0;
|
|
461
|
+
private payloadPatches = 0;
|
|
462
|
+
private membershipChecks = 0;
|
|
463
|
+
private membershipAllocations = 0;
|
|
464
|
+
private candidateAdds = 0;
|
|
465
|
+
private candidateRemoves = 0;
|
|
254
466
|
private cachedPlan: SubmissionPlan | undefined;
|
|
255
467
|
|
|
256
468
|
rebuild(slots: readonly RenderSceneSlot[]): void {
|
|
@@ -261,37 +473,125 @@ export class BatchTopology {
|
|
|
261
473
|
this.freeBatchIds.length = 0;
|
|
262
474
|
for (const slot of slots) this.add(slot);
|
|
263
475
|
this.revision += 1;
|
|
476
|
+
this.payloadRevision += 1;
|
|
264
477
|
this.rebuilds += 1;
|
|
265
478
|
this.cachedPlan = undefined;
|
|
266
479
|
}
|
|
267
480
|
|
|
268
481
|
apply(delta: RenderSceneApplyResult): boolean {
|
|
269
482
|
let changed = false;
|
|
270
|
-
|
|
483
|
+
let topologyChanged = false;
|
|
484
|
+
for (const removed of delta.removedSlots) {
|
|
485
|
+
const removedChanged = this.remove(removed.slot);
|
|
486
|
+
changed = removedChanged || changed;
|
|
487
|
+
topologyChanged = removedChanged || topologyChanged;
|
|
488
|
+
}
|
|
271
489
|
for (const slot of delta.recreatedSlots) {
|
|
272
|
-
|
|
273
|
-
|
|
490
|
+
const removedChanged = this.remove(slot.slot);
|
|
491
|
+
const addedChanged = this.add(slot);
|
|
492
|
+
changed = removedChanged || addedChanged || changed;
|
|
493
|
+
topologyChanged = removedChanged || addedChanged || topologyChanged;
|
|
274
494
|
}
|
|
275
|
-
//
|
|
276
|
-
//
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
for (const slot of
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
495
|
+
// Membership depends on source descriptors and instance cardinality.
|
|
496
|
+
// Root matrices feed visibility without changing this dependency.
|
|
497
|
+
const contentUpdatedSlots = delta.contentUpdatedSlots;
|
|
498
|
+
const instanceUpdatedSlots = delta.instanceUpdatedSlots;
|
|
499
|
+
const membershipUpdates = new Map<number, { slot: RenderSceneSlot; content: boolean }>();
|
|
500
|
+
for (const slot of contentUpdatedSlots) {
|
|
501
|
+
membershipUpdates.set(slot.slot, { slot, content: true });
|
|
502
|
+
}
|
|
503
|
+
// Instance cardinality is a membership input, including in mixed updates.
|
|
504
|
+
for (const slot of instanceUpdatedSlots) {
|
|
505
|
+
if (!membershipUpdates.has(slot.slot)) {
|
|
506
|
+
membershipUpdates.set(slot.slot, { slot, content: false });
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
for (const update of membershipUpdates.values()) {
|
|
510
|
+
const { slot, content } = update;
|
|
511
|
+
const eligible = eligibleDraws(slot);
|
|
512
|
+
const next = membershipProjection(slot, eligible);
|
|
513
|
+
// The projection is one descriptor per eligible source draw; candidate
|
|
514
|
+
// identities are derived from the stable ordinal and are not stored as
|
|
515
|
+
// N per-instance comparison records.
|
|
516
|
+
this.membershipAllocations += next.draws.length;
|
|
517
|
+
const previous = this.membershipByPrimitive.get(slot.slot);
|
|
518
|
+
this.membershipChecks += 1;
|
|
519
|
+
const topologyStable =
|
|
520
|
+
previous !== undefined &&
|
|
521
|
+
previous.instanceCount === next.instanceCount &&
|
|
522
|
+
previous.hasLod === next.hasLod &&
|
|
523
|
+
previous.draws.length === next.draws.length &&
|
|
524
|
+
previous.draws.every((membership, index) => {
|
|
525
|
+
const candidate = next.draws[index];
|
|
526
|
+
return (
|
|
527
|
+
candidate !== undefined &&
|
|
528
|
+
membership.sourceDrawIndex === candidate.sourceDrawIndex &&
|
|
529
|
+
membership.batchText === candidate.batchText
|
|
530
|
+
);
|
|
531
|
+
});
|
|
532
|
+
if (!topologyStable) {
|
|
533
|
+
const removedChanged = this.remove(slot.slot);
|
|
534
|
+
const addedChanged = this.add(slot);
|
|
535
|
+
changed = removedChanged || addedChanged || changed;
|
|
536
|
+
topologyChanged = removedChanged || addedChanged || topologyChanged;
|
|
287
537
|
continue;
|
|
288
538
|
}
|
|
289
|
-
|
|
290
|
-
|
|
539
|
+
if (!content) {
|
|
540
|
+
this.membershipByPrimitive.set(slot.slot, next);
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
let payloadChanged = false;
|
|
544
|
+
let topologyFallback = false;
|
|
545
|
+
for (let index = 0; index < next.draws.length; index += 1) {
|
|
546
|
+
const oldMembership = previous.draws[index];
|
|
547
|
+
const newMembership = next.draws[index];
|
|
548
|
+
const draw = eligible[index];
|
|
549
|
+
if (oldMembership === undefined || newMembership === undefined || draw === undefined) {
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
if (oldMembership.payloadRevision === newMembership.payloadRevision) continue;
|
|
553
|
+
for (let instanceOrdinal = 0; instanceOrdinal < next.instanceCount; instanceOrdinal += 1) {
|
|
554
|
+
const batchText = candidateBatchText(
|
|
555
|
+
draw.key,
|
|
556
|
+
slot.slot,
|
|
557
|
+
draw.sourceDrawIndex,
|
|
558
|
+
instanceOrdinal,
|
|
559
|
+
next.hasLod,
|
|
560
|
+
);
|
|
561
|
+
const batch = this.batches.get(batchText);
|
|
562
|
+
const candidateKey = `${newMembership.candidateKeyPrefix}${instanceOrdinal}`;
|
|
563
|
+
if (batch === undefined || !batch.candidates.has(candidateKey)) {
|
|
564
|
+
const removedChanged = this.remove(slot.slot);
|
|
565
|
+
const addedChanged = this.add(slot);
|
|
566
|
+
changed = removedChanged || addedChanged || changed;
|
|
567
|
+
topologyChanged = removedChanged || addedChanged || topologyChanged;
|
|
568
|
+
topologyFallback = true;
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
batch.candidates.set(
|
|
572
|
+
candidateKey,
|
|
573
|
+
this.candidateFromEligible(slot, instanceOrdinal, draw),
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
if (topologyFallback) break;
|
|
577
|
+
payloadChanged = true;
|
|
578
|
+
}
|
|
579
|
+
this.membershipByPrimitive.set(slot.slot, next);
|
|
580
|
+
if (payloadChanged) {
|
|
581
|
+
changed = true;
|
|
582
|
+
this.payloadRevision += 1;
|
|
583
|
+
this.payloadPatches += 1;
|
|
584
|
+
this.cachedPlan = undefined;
|
|
585
|
+
}
|
|
291
586
|
}
|
|
292
|
-
for (const slot of delta.createdSlots)
|
|
293
|
-
|
|
587
|
+
for (const slot of delta.createdSlots) {
|
|
588
|
+
const addedChanged = this.add(slot);
|
|
589
|
+
changed = addedChanged || changed;
|
|
590
|
+
topologyChanged = addedChanged || topologyChanged;
|
|
591
|
+
}
|
|
592
|
+
if (topologyChanged) {
|
|
294
593
|
this.revision += 1;
|
|
594
|
+
this.payloadRevision += 1;
|
|
295
595
|
this.patches += 1;
|
|
296
596
|
this.cachedPlan = undefined;
|
|
297
597
|
}
|
|
@@ -324,6 +624,7 @@ export class BatchTopology {
|
|
|
324
624
|
});
|
|
325
625
|
this.cachedPlan = Object.freeze({
|
|
326
626
|
revision: this.revision,
|
|
627
|
+
payloadRevision: this.payloadRevision,
|
|
327
628
|
batches: Object.freeze(batches),
|
|
328
629
|
candidateCount: batches.reduce((total, batch) => total + batch.candidates.length, 0),
|
|
329
630
|
visibleCapacity: visibleBase,
|
|
@@ -341,24 +642,34 @@ export class BatchTopology {
|
|
|
341
642
|
rebuilds: this.rebuilds,
|
|
342
643
|
patches: this.patches,
|
|
343
644
|
ineligible: this.ineligiblePrimitives.size,
|
|
645
|
+
payloadPatches: this.payloadPatches,
|
|
646
|
+
membershipChecks: this.membershipChecks,
|
|
647
|
+
membershipAllocations: this.membershipAllocations,
|
|
648
|
+
candidateAdds: this.candidateAdds,
|
|
649
|
+
candidateRemoves: this.candidateRemoves,
|
|
344
650
|
};
|
|
345
651
|
}
|
|
346
652
|
|
|
347
653
|
private add(slot: RenderSceneSlot): boolean {
|
|
348
|
-
const
|
|
349
|
-
if (
|
|
654
|
+
const draws = eligibleDraws(slot);
|
|
655
|
+
if (draws.length === 0) {
|
|
350
656
|
this.ineligiblePrimitives.add(slot.slot);
|
|
351
657
|
return false;
|
|
352
658
|
}
|
|
353
659
|
this.ineligiblePrimitives.delete(slot.slot);
|
|
354
|
-
const memberships
|
|
355
|
-
const instanceCount =
|
|
356
|
-
const hasLod =
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
if (key === undefined) continue;
|
|
660
|
+
const memberships = membershipProjection(slot, draws);
|
|
661
|
+
const instanceCount = memberships.instanceCount;
|
|
662
|
+
const hasLod = memberships.hasLod;
|
|
663
|
+
this.membershipAllocations += memberships.draws.length;
|
|
664
|
+
for (const draw of draws) {
|
|
360
665
|
for (let instanceOrdinal = 0; instanceOrdinal < instanceCount; instanceOrdinal += 1) {
|
|
361
|
-
const text = candidateBatchText(
|
|
666
|
+
const text = candidateBatchText(
|
|
667
|
+
draw.key,
|
|
668
|
+
slot.slot,
|
|
669
|
+
draw.sourceDrawIndex,
|
|
670
|
+
instanceOrdinal,
|
|
671
|
+
hasLod,
|
|
672
|
+
);
|
|
362
673
|
let batch = this.batches.get(text);
|
|
363
674
|
if (batch === undefined) {
|
|
364
675
|
const reused = this.freeBatchIds.pop();
|
|
@@ -366,39 +677,12 @@ export class BatchTopology {
|
|
|
366
677
|
const generation =
|
|
367
678
|
reused === undefined ? 0 : (this.generationByBatchId[batchId] ?? -1) + 1;
|
|
368
679
|
this.generationByBatchId[batchId] = generation;
|
|
369
|
-
batch = { batchId, generation, key, candidates: new Map() };
|
|
680
|
+
batch = { batchId, generation, key: draw.key, candidates: new Map() };
|
|
370
681
|
this.batches.set(text, batch);
|
|
371
682
|
}
|
|
372
|
-
const candidateKey = `${slot.slot}:${
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
batch.candidates.set(candidateKey, {
|
|
376
|
-
primitiveIndex: slot.slot,
|
|
377
|
-
generation: slot.generation,
|
|
378
|
-
drawItemIndex,
|
|
379
|
-
instanceOrdinal,
|
|
380
|
-
...(draw?.projectedHeight === undefined ? {} : { projectedHeight: draw.projectedHeight }),
|
|
381
|
-
...(slot.snapshot.lods === undefined
|
|
382
|
-
? {}
|
|
383
|
-
: {
|
|
384
|
-
lodCoverages: [1, ...slot.snapshot.lods.map((lod) => lod.screenCoverage)],
|
|
385
|
-
...(slot.snapshot.gpuDrivenDraws?.[drawItemIndex]?.lodRanges === undefined
|
|
386
|
-
? {}
|
|
387
|
-
: {
|
|
388
|
-
lodRanges: slot.snapshot.gpuDrivenDraws[drawItemIndex]
|
|
389
|
-
?.lodRanges as readonly {
|
|
390
|
-
readonly first: number;
|
|
391
|
-
readonly count: number;
|
|
392
|
-
readonly baseVertex: number;
|
|
393
|
-
}[],
|
|
394
|
-
}),
|
|
395
|
-
...(slot.snapshot.lodHysteresis === undefined
|
|
396
|
-
? {}
|
|
397
|
-
: { lodHysteresis: slot.snapshot.lodHysteresis }),
|
|
398
|
-
}),
|
|
399
|
-
...(prepared === undefined ? {} : { prepared }),
|
|
400
|
-
});
|
|
401
|
-
memberships.push({ batchText: text, candidateKey });
|
|
683
|
+
const candidateKey = `${slot.slot}:${draw.sourceDrawIndex}:${instanceOrdinal}`;
|
|
684
|
+
batch.candidates.set(candidateKey, this.candidateFromEligible(slot, instanceOrdinal, draw));
|
|
685
|
+
this.candidateAdds += 1;
|
|
402
686
|
}
|
|
403
687
|
}
|
|
404
688
|
this.membershipByPrimitive.set(slot.slot, memberships);
|
|
@@ -410,15 +694,53 @@ export class BatchTopology {
|
|
|
410
694
|
const memberships = this.membershipByPrimitive.get(primitiveIndex);
|
|
411
695
|
this.membershipByPrimitive.delete(primitiveIndex);
|
|
412
696
|
if (memberships === undefined) return false;
|
|
413
|
-
for (const membership of memberships) {
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
697
|
+
for (const membership of memberships.draws) {
|
|
698
|
+
const batchTexts = new Set<string>();
|
|
699
|
+
for (
|
|
700
|
+
let instanceOrdinal = 0;
|
|
701
|
+
instanceOrdinal < memberships.instanceCount;
|
|
702
|
+
instanceOrdinal += 1
|
|
703
|
+
) {
|
|
704
|
+
const batchText = candidateBatchText(
|
|
705
|
+
membership.key,
|
|
706
|
+
primitiveIndex,
|
|
707
|
+
membership.sourceDrawIndex,
|
|
708
|
+
instanceOrdinal,
|
|
709
|
+
memberships.hasLod,
|
|
710
|
+
);
|
|
711
|
+
batchTexts.add(batchText);
|
|
712
|
+
const batch = this.batches.get(batchText);
|
|
713
|
+
if (batch === undefined) continue;
|
|
714
|
+
const candidateKey = `${membership.candidateKeyPrefix}${instanceOrdinal}`;
|
|
715
|
+
if (!batch.candidates.delete(candidateKey)) continue;
|
|
716
|
+
this.candidateRemoves += 1;
|
|
717
|
+
}
|
|
718
|
+
for (const batchText of batchTexts) {
|
|
719
|
+
const batch = this.batches.get(batchText);
|
|
720
|
+
if (batch !== undefined && batch.candidates.size === 0) {
|
|
721
|
+
this.batches.delete(batchText);
|
|
722
|
+
this.freeBatchIds.push(batch.batchId);
|
|
723
|
+
}
|
|
420
724
|
}
|
|
421
725
|
}
|
|
422
726
|
return true;
|
|
423
727
|
}
|
|
728
|
+
|
|
729
|
+
private candidateFromEligible(
|
|
730
|
+
slot: RenderSceneSlot,
|
|
731
|
+
instanceOrdinal: number,
|
|
732
|
+
draw: EligibleGpuDrivenDraw,
|
|
733
|
+
): GpuDrivenCandidate {
|
|
734
|
+
return {
|
|
735
|
+
primitiveIndex: slot.slot,
|
|
736
|
+
generation: slot.generation,
|
|
737
|
+
drawItemIndex: draw.sourceDrawIndex,
|
|
738
|
+
instanceOrdinal,
|
|
739
|
+
...(draw.projectedHeight === undefined ? {} : { projectedHeight: draw.projectedHeight }),
|
|
740
|
+
...(draw.lodCoverages === undefined ? {} : { lodCoverages: draw.lodCoverages }),
|
|
741
|
+
...(draw.lodRanges === undefined ? {} : { lodRanges: draw.lodRanges }),
|
|
742
|
+
...(draw.lodHysteresis === undefined ? {} : { lodHysteresis: draw.lodHysteresis }),
|
|
743
|
+
...(draw.prepared === undefined ? {} : { prepared: draw.prepared }),
|
|
744
|
+
};
|
|
745
|
+
}
|
|
424
746
|
}
|