@forgeax/engine-render 0.1.21 → 0.1.24
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 +281 -38
- package/dist/assembly/backend-contract.d.ts +13 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/bundler-contract.d.ts +9 -0
- package/dist/assembly/bundler-contract.d.ts.map +1 -0
- package/dist/assembly/device-feature-admission.d.ts +8 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -1
- package/dist/assembly/extended-lighting-fallback.d.ts +13 -0
- package/dist/assembly/extended-lighting-fallback.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +7 -235
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +10 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +3 -2
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/standard-layer-projection.d.ts +10 -0
- package/dist/assembly/material/standard-layer-projection.d.ts.map +1 -0
- package/dist/assembly/material-shader-policy.d.ts +168 -0
- package/dist/assembly/material-shader-policy.d.ts.map +1 -0
- package/dist/assembly/material-shader-prewarm.d.ts +21 -0
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/mesh-ssbo-grow.d.ts +88 -0
- package/dist/assembly/mesh-ssbo-grow.d.ts.map +1 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts +14 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -0
- package/dist/assembly/recovery/generation.d.ts +46 -0
- package/dist/assembly/recovery/generation.d.ts.map +1 -0
- package/dist/assembly/recovery/recovery-attempt.d.ts +63 -0
- package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -0
- package/dist/assembly/recovery/renderer-recover.d.ts +115 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts +10 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -0
- package/dist/assembly/renderer-frame-transaction.d.ts +17 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-helpers.d.ts +19 -0
- package/dist/assembly/renderer-helpers.d.ts.map +1 -0
- package/dist/assembly/renderer-lifecycle.d.ts +34 -0
- package/dist/assembly/renderer-lifecycle.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +15 -0
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-contract.d.ts +9 -0
- package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +55 -0
- package/dist/assembly/webgpu-ready.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +152 -0
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -0
- package/dist/authoring.mjs +1 -1
- package/dist/{chunk-PCHBPYML.mjs → chunk-GE3SDD72.mjs} +37 -5
- package/dist/chunk-GE3SDD72.mjs.map +1 -0
- package/dist/chunk-KZFTK6DO.mjs +1191 -0
- package/dist/chunk-KZFTK6DO.mjs.map +1 -0
- package/dist/{chunk-FS2KNUQH.mjs → chunk-Q752SHI5.mjs} +332 -568
- package/dist/chunk-Q752SHI5.mjs.map +1 -0
- package/dist/{chunk-6OPXDQ2E.mjs → chunk-RR5L4SRS.mjs} +33 -294
- package/dist/chunk-RR5L4SRS.mjs.map +1 -0
- package/dist/chunk-TFH5I7JJ.mjs +296 -0
- package/dist/chunk-TFH5I7JJ.mjs.map +1 -0
- package/dist/chunk-UQYS7FRM.mjs +1003 -0
- package/dist/chunk-UQYS7FRM.mjs.map +1 -0
- package/dist/chunk-YKB5DQV7.mjs +345 -0
- package/dist/chunk-YKB5DQV7.mjs.map +1 -0
- package/dist/{chunk-5YADUCA7.mjs → chunk-YRUYGA4A.mjs} +1189 -1217
- package/dist/chunk-YRUYGA4A.mjs.map +1 -0
- package/dist/chunk-Z3YYH2MB.mjs +5082 -0
- package/dist/chunk-Z3YYH2MB.mjs.map +1 -0
- package/dist/cluster-binner.d.ts +5 -0
- package/dist/cluster-binner.d.ts.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts +4 -0
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/light-probe.d.ts +9 -0
- package/dist/components/light-probe.d.ts.map +1 -0
- package/dist/components/rect-area-light.d.ts +12 -0
- package/dist/components/rect-area-light.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +4 -0
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/spot-light.d.ts +3 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +27276 -23232
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts +2 -0
- package/dist/device/device-scope.d.ts.map +1 -1
- package/dist/device/gpu-residency.d.ts +32 -5
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/lifecycle-transaction.d.ts +2 -0
- package/dist/device/lifecycle-transaction.d.ts.map +1 -0
- package/dist/environment/frame.d.ts +5 -0
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/inspection.d.ts +7 -0
- package/dist/environment/inspection.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +20 -2
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/gpu-driven.d.ts +26 -0
- package/dist/errors/gpu-driven.d.ts.map +1 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/recover.d.ts +67 -3
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +39 -1
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +899 -0
- package/dist/extract/contracts.d.ts.map +1 -0
- package/dist/extract/gpu-driven.d.ts +50 -0
- package/dist/extract/gpu-driven.d.ts.map +1 -0
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/features/host.d.ts +2 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +3 -0
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts +2 -0
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +63 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +126 -2
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +64 -1
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +14 -0
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +9 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +0 -1
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +3 -3
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +7 -6
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +7 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +90 -5
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +163 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/internal.d.ts +9 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +23 -2
- package/dist/internal.mjs.map +1 -1
- package/dist/light-buffer-layout.d.ts +60 -148
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts +34 -10
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +56 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/occlusion-proxy.d.ts +4 -0
- package/dist/occlusion-proxy.d.ts.map +1 -0
- package/dist/pbr-pipeline.d.ts +58 -21
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/light-frame.d.ts +3 -3
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/topology.d.ts +1 -1
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -0
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +1 -1
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/points-lines/prepare.d.ts +3 -0
- package/dist/points-lines/prepare.d.ts.map +1 -1
- package/dist/points-lines/standard-owner.d.ts +33 -0
- package/dist/points-lines/standard-owner.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
- package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/resources.d.ts +72 -0
- package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/state.d.ts +24 -0
- package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +8 -6
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +55 -10
- 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 +21 -5
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-timing.d.ts +19 -7
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +0 -20
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +20 -2
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +10 -18
- 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.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +11 -3
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/recovery-pipeline.d.ts +30 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -0
- package/dist/record/render-context.d.ts +82 -9
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +49 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +1 -2
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +65 -0
- package/dist/recovery/render-system-candidate.d.ts.map +1 -0
- package/dist/reflection/inspection.d.ts +10 -0
- package/dist/reflection/inspection.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +49 -0
- package/dist/reflection/projection.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts +60 -0
- package/dist/reflection/record-owner.d.ts.map +1 -0
- package/dist/render-contract.d.ts +78 -15
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +7 -0
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +12 -0
- package/dist/render-system-extract-tail.d.ts.map +1 -0
- package/dist/render-system-extract.d.ts +252 -30
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +140 -5
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/probe-blend-record.d.ts +22 -0
- package/dist/scene/probe-blend-record.d.ts.map +1 -0
- package/dist/scene/probe-blend.d.ts +142 -0
- package/dist/scene/probe-blend.d.ts.map +1 -0
- package/dist/scene/render-scene-types.d.ts +0 -6
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +122 -9
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/visibility/bounds.d.ts +20 -0
- package/dist/scene/visibility/bounds.d.ts.map +1 -0
- package/dist/scene/visibility/budget.d.ts +16 -0
- package/dist/scene/visibility/budget.d.ts.map +1 -0
- package/dist/scene/visibility/facet.d.ts +73 -0
- package/dist/scene/visibility/facet.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-lod.d.ts +46 -0
- package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
- package/dist/scene/visibility/inspection.d.ts +132 -0
- package/dist/scene/visibility/inspection.d.ts.map +1 -0
- package/dist/scene/visibility/lod-selector.d.ts +25 -0
- package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
- package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
- package/dist/scene/visibility/types.d.ts +34 -0
- package/dist/scene/visibility/types.d.ts.map +1 -0
- package/dist/ssr/admission.d.ts +122 -0
- package/dist/ssr/admission.d.ts.map +1 -0
- package/dist/ssr/composition.d.ts +32 -0
- package/dist/ssr/composition.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +39 -0
- package/dist/ssr/errors.d.ts.map +1 -0
- package/dist/ssr/identity.d.ts +13 -0
- package/dist/ssr/identity.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +1 -1
- package/dist/temporal/frame-coordinator.d.ts +13 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +2 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -5
- package/dist/temporal/taa-history-store.d.ts +15 -1
- package/dist/temporal/taa-history-store.d.ts.map +1 -1
- package/dist/temporal/transaction.d.ts +5 -0
- package/dist/temporal/transaction.d.ts.map +1 -1
- package/dist/temporal/view.d.ts +7 -0
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/tilemap-chunk-extract-system.d.ts +1 -1
- package/dist/typed-render-graph-primitives.d.ts +4 -0
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +8 -4
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +5 -0
- package/src/__tests__/detached-inspection.integration.test.ts +6 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +19 -1
- package/src/__tests__/device-loss-fanout.unit.test.ts +107 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +21 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
- package/src/__tests__/environment-generation.integration.test.ts +39 -0
- package/src/__tests__/evidence-identity.ts +13 -0
- package/src/__tests__/evidence-identity.unit.test.ts +24 -0
- package/src/__tests__/expose-renderer-errors.unit.test.ts +34 -0
- package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
- package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
- package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
- package/src/__tests__/factory-contract.integration.test.ts +154 -6
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +4 -1
- package/src/__tests__/frame-observation.contract.test.ts +15 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +1 -0
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +1 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +572 -9
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +89 -2
- package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
- package/src/__tests__/gpu-lod-evidence.ts +188 -0
- package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
- package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
- package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
- package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
- package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
- package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
- package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
- package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
- package/src/__tests__/gpu-scene.unit.test.ts +49 -3
- package/src/__tests__/ibl/face-uniforms.unit.test.ts +2 -0
- package/src/__tests__/ibl-residency-publication.unit.test.ts +113 -0
- package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
- package/src/__tests__/light-inspection.unit.test.ts +55 -0
- package/src/__tests__/light-resource-error.unit.test.ts +43 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
- package/src/__tests__/lod-bounds.unit.test.ts +42 -0
- package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
- package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
- package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
- package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
- package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
- package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
- package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
- package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
- package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
- package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
- package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
- package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
- package/src/__tests__/lod-selector.profile.test.ts +35 -0
- package/src/__tests__/lod-selector.unit.test.ts +68 -0
- package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
- package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
- package/src/__tests__/ltc-resources.unit.test.ts +32 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +41 -9
- package/src/__tests__/material-cooked-projection.unit.test.ts +19 -1
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +29 -0
- package/src/__tests__/material-stride-surface.unit.test.ts +7 -3
- package/src/__tests__/materials-standard-contract.unit.test.ts +104 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
- package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
- package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
- package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
- package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
- package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
- package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
- package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
- package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
- package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
- package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
- package/src/__tests__/occlusion-query.evidence.ts +178 -0
- package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
- package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +89 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +1 -1
- package/src/__tests__/probe-bindings.unit.test.ts +200 -0
- package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
- package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
- package/src/__tests__/probe-capacity.integration.test.ts +97 -0
- package/src/__tests__/probe-recovery.integration.test.ts +104 -0
- package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
- package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
- package/src/__tests__/profiler-phase-token.test.ts +1 -0
- package/src/__tests__/recover-error-policy-owner.unit.test.ts +6 -3
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +140 -0
- package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
- package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
- package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
- package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
- package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
- package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
- package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
- package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
- package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
- package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +160 -17
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +47 -0
- package/src/__tests__/renderer-generation-assembly.unit.test.ts +77 -0
- package/src/__tests__/renderer-generation-failure.unit.test.ts +108 -0
- package/src/__tests__/renderer-producer-root-matrix.integration.test.ts +33 -0
- package/src/__tests__/renderer-recovery-capability-matrix.unit.test.ts +59 -0
- package/src/__tests__/renderer-recovery-contract.unit.test.ts +73 -0
- package/src/__tests__/renderer-recovery-lifecycle.unit.test.ts +216 -0
- package/src/__tests__/renderer-target-history-recovery.integration.test.ts +80 -0
- package/src/__tests__/shader-manifest-fixture.ts +13 -16
- package/src/__tests__/shader-stage-surface.unit.test.ts +1 -1
- package/src/__tests__/skin-motion-regression.unit.test.ts +22 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +2 -2
- package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
- package/src/__tests__/ssr-composition.unit.test.ts +46 -0
- package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
- package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +67 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +7 -0
- package/src/__tests__/standard-layer-projection.unit.test.ts +23 -0
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +1 -1
- package/src/__tests__/standard-lighting-write.unit.test.ts +66 -2
- package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
- package/src/__tests__/temporal-view.unit.test.ts +3 -3
- package/src/__tests__/transmission-prewarm.unit.test.ts +111 -32
- package/src/__tests__/visibility-budget.integration.test.ts +140 -0
- package/src/__tests__/visibility-budget.unit.test.ts +70 -0
- package/src/__tests__/visibility-extract.integration.test.ts +11 -6
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +3 -1
- package/src/assembly/backend-contract.ts +13 -0
- package/src/assembly/bundler-contract.ts +9 -0
- package/src/assembly/device-feature-admission.ts +26 -9
- package/src/assembly/extended-lighting-fallback.ts +216 -0
- package/src/assembly/factory.ts +81 -9634
- package/src/assembly/host-contract.ts +10 -0
- package/src/assembly/material/assembly.ts +18 -2
- package/src/assembly/material/standard-layer-projection.ts +16 -0
- package/src/assembly/material-shader-policy.ts +854 -0
- package/src/assembly/material-shader-prewarm.ts +88 -0
- package/src/assembly/mesh-ssbo-grow.ts +270 -0
- package/src/assembly/recovery/device-loss-fanout.ts +89 -0
- package/src/assembly/recovery/generation.ts +141 -0
- package/src/assembly/recovery/recovery-attempt.ts +800 -0
- package/src/assembly/recovery/renderer-recover.ts +906 -0
- package/src/assembly/renderer-facade.ts +342 -0
- package/src/assembly/renderer-frame-transaction.ts +45 -0
- package/src/assembly/renderer-helpers.ts +99 -0
- package/src/assembly/renderer-lifecycle.ts +159 -0
- package/src/assembly/shader-prewarm-policy.ts +157 -0
- package/src/assembly/webgpu-ready-contract.ts +14 -0
- package/src/assembly/webgpu-ready.ts +4079 -0
- package/src/assembly/webgpu-renderer.ts +4095 -0
- package/src/cluster-binner.ts +31 -0
- package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
- package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
- package/src/components/camera.ts +1 -1
- package/src/components/index.ts +3 -0
- package/src/components/light-helpers.ts +52 -1
- package/src/components/light-probe.ts +13 -0
- package/src/components/rect-area-light.ts +15 -0
- package/src/components/scene-instance.ts +6 -0
- package/src/components/spot-light.ts +3 -0
- package/src/debug-draw-glue.ts +1 -1
- package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
- package/src/device/device-scope.ts +35 -6
- package/src/device/gpu-residency.ts +334 -35
- package/src/device/lifecycle-transaction.ts +12 -0
- package/src/environment/frame.ts +6 -0
- package/src/environment/inspection.ts +10 -0
- package/src/environment/lifecycle.ts +122 -9
- package/src/errors/gpu-driven.ts +92 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/recover.ts +108 -5
- package/src/errors/render.ts +72 -1
- package/src/extract/camera.ts +3 -3
- package/src/extract/contracts.ts +974 -0
- package/src/extract/gpu-driven.ts +108 -0
- package/src/extract/visibility.ts +0 -23
- package/src/features/host.ts +16 -0
- package/src/features/prepared-gpu-work.ts +20 -2
- package/src/features/prepared-graphics-store.ts +17 -0
- package/src/gpu-driven/batch-topology.ts +206 -28
- package/src/gpu-driven/prepared-draw.ts +208 -0
- package/src/gpu-driven/production-raster.ts +1046 -39
- package/src/gpu-driven/view-gpu.ts +411 -29
- package/src/gpu-scene-schema.ts +13 -0
- package/src/gpu-scene.ts +137 -67
- package/src/gpu-usage.ts +0 -1
- package/src/hdrp-buffers.ts +6 -6
- package/src/ibl/IblPipelineCache.ts +134 -50
- package/src/ibl/skylight-bind-group.ts +26 -0
- package/src/index.ts +83 -1
- package/src/inspection-types.ts +220 -1
- package/src/internal.ts +38 -0
- package/src/light-buffer-layout.ts +157 -324
- package/src/materials.ts +278 -47
- package/src/mesh-material-bindings.ts +59 -0
- package/src/occlusion-proxy.ts +64 -0
- package/src/pbr-pipeline.ts +290 -60
- package/src/pipeline/standard-forward-lane.ts +47 -0
- package/src/pipeline/standard-lighting/graph.ts +2 -1
- package/src/pipeline/standard-lighting/light-frame.ts +3 -2
- package/src/pipeline/standard-lighting/topology.ts +1 -1
- package/src/pipeline/standard-lighting/transport.ts +2 -1
- package/src/pipeline/standard-pipeline.ts +2 -0
- package/src/pipeline-builder.ts +5 -2
- package/src/pipeline-spec.ts +12 -1
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/cache-recovery.unit.test.ts +22 -0
- package/src/points-lines/prepare.ts +9 -0
- package/src/points-lines/standard-owner.ts +403 -0
- package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
- package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
- package/src/prepare/extended-lighting/resources.ts +389 -0
- package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
- package/src/prepare/extended-lighting/state.ts +92 -0
- package/src/record/__tests__/frame-targets-recovery.unit.test.ts +60 -0
- package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +26 -1
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +38 -0
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +124 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +28 -13
- package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +47 -4
- package/src/record/__tests__/temporal-payload.unit.test.ts +29 -28
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +21 -2
- package/src/record/frame-lighting.ts +252 -53
- package/src/record/frame-snapshot.ts +72 -12
- package/src/record/frame-targets.ts +11 -1
- package/src/record/frame.ts +416 -95
- package/src/record/gpu-timing.ts +108 -44
- package/src/record/helpers.ts +1 -59
- package/src/record/main-pass-geometry.ts +434 -44
- package/src/record/main-pass-material.ts +324 -210
- package/src/record/main-pass-sprite-draws.ts +58 -92
- package/src/record/main-pass.ts +94 -6
- package/src/record/mesh-ssbo.ts +79 -46
- package/src/record/recovery-pipeline.ts +695 -0
- package/src/record/render-context.ts +99 -7
- package/src/record/shadow-pass.ts +66 -40
- package/src/record/typed-frame-graph.ts +270 -84
- package/src/record/view-ubo.ts +17 -27
- package/src/recovery/render-system-candidate.ts +839 -0
- package/src/reflection/inspection.ts +67 -0
- package/src/reflection/projection.ts +196 -1
- package/src/reflection/record-owner.ts +1283 -0
- package/src/render-contract.ts +82 -12
- package/src/render-pipeline.ts +5 -0
- package/src/render-system-extract-tail.ts +2983 -0
- package/src/render-system-extract.ts +290 -2784
- package/src/render-system.ts +1597 -1192
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
- package/src/scene/probe-blend-record.ts +54 -0
- package/src/scene/probe-blend.ts +813 -0
- package/src/scene/render-scene-types.ts +0 -7
- package/src/scene/render-scene.ts +972 -184
- package/src/scene/visibility/bounds.ts +57 -0
- package/src/scene/visibility/budget.ts +40 -0
- package/src/scene/visibility/facet.ts +400 -0
- package/src/scene/visibility/gpu-frame-timing.ts +101 -0
- package/src/scene/visibility/gpu-lod.ts +119 -0
- package/src/scene/visibility/inspection.ts +313 -0
- package/src/scene/visibility/lod-selector.ts +84 -0
- package/src/scene/visibility/occlusion-confidence.ts +478 -0
- package/src/scene/visibility/occlusion-pass.ts +165 -0
- package/src/scene/visibility/occlusion-query-pool.ts +178 -0
- package/src/scene/visibility/occlusion-runtime.ts +672 -0
- package/src/scene/visibility/types.ts +50 -0
- package/src/ssr/admission.ts +451 -0
- package/src/ssr/composition.ts +73 -0
- package/src/ssr/errors.ts +76 -0
- package/src/ssr/identity.ts +12 -0
- package/src/systems/skin-palette-allocator.ts +1 -1
- package/src/temporal/frame-coordinator.ts +30 -1
- package/src/temporal/frame.ts +14 -1
- package/src/temporal/taa-history-store.ts +46 -2
- package/src/temporal/temporal-view.ts +1 -1
- package/src/temporal/transaction.ts +9 -0
- package/src/temporal/view.ts +11 -0
- package/src/tilemap-chunk-extract-system.ts +5 -5
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +19 -12
- package/src/typed-render-graph-primitives.ts +48 -0
- package/src/volume/passes.ts +46 -49
- package/dist/.tsbuildinfo +0 -1
- package/dist/chunk-5YADUCA7.mjs.map +0 -1
- package/dist/chunk-6OPXDQ2E.mjs.map +0 -1
- package/dist/chunk-BXBQQKFQ.mjs +0 -67
- package/dist/chunk-BXBQQKFQ.mjs.map +0 -1
- package/dist/chunk-FS2KNUQH.mjs.map +0 -1
- package/dist/chunk-PCHBPYML.mjs.map +0 -1
- package/dist/chunk-VFPLTKCU.mjs +0 -192
- package/dist/chunk-VFPLTKCU.mjs.map +0 -1
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
import {
|
|
33
33
|
blitMipmapsSync,
|
|
34
34
|
getOrCreateMipmapPipeline,
|
|
35
|
+
type MipmapEncoderWork,
|
|
35
36
|
type MipmapShaderModuleFactory,
|
|
37
|
+
prepareMipmaps,
|
|
36
38
|
} from '@forgeax/engine-assets-runtime';
|
|
37
39
|
import type { World } from '@forgeax/engine-ecs';
|
|
38
40
|
import {
|
|
@@ -98,6 +100,7 @@ import {
|
|
|
98
100
|
runIblPrecompute,
|
|
99
101
|
} from '../ibl/IblPipelineCache';
|
|
100
102
|
import type { RhiErrorListenerRegistry } from '../lifecycle';
|
|
103
|
+
import type { RecoveryColdWorkGuard } from '../record/render-context';
|
|
101
104
|
import {
|
|
102
105
|
type CubeRenderData,
|
|
103
106
|
deriveRenderDataCubemap,
|
|
@@ -106,7 +109,7 @@ import {
|
|
|
106
109
|
type MeshRenderData,
|
|
107
110
|
type TextureRenderData,
|
|
108
111
|
} from '../render-data';
|
|
109
|
-
import type { DeviceScope } from './device-scope';
|
|
112
|
+
import type { DeviceScope, LifecycleResourceSpec } from './device-scope';
|
|
110
113
|
|
|
111
114
|
const DYNAMIC_OFFSET_STRIDE = 256;
|
|
112
115
|
const FACE_COUNT = 6;
|
|
@@ -182,6 +185,7 @@ export function writePrefilterUniforms(
|
|
|
182
185
|
subPassIdx: number,
|
|
183
186
|
roughness: number,
|
|
184
187
|
mipFaceSize: number,
|
|
188
|
+
sourceMipLevelCount = 1,
|
|
185
189
|
): Result<void, RhiError> {
|
|
186
190
|
if (subPassIdx < 0 || subPassIdx >= PREFILTER_SUBPASS_COUNT) {
|
|
187
191
|
return invalidUniformInput(
|
|
@@ -189,13 +193,20 @@ export function writePrefilterUniforms(
|
|
|
189
193
|
`writePrefilterUniforms received subPassIdx=${subPassIdx}`,
|
|
190
194
|
);
|
|
191
195
|
}
|
|
192
|
-
|
|
196
|
+
if (!Number.isInteger(sourceMipLevelCount) || sourceMipLevelCount < 1) {
|
|
197
|
+
return invalidUniformInput(
|
|
198
|
+
'sourceMipLevelCount is a positive integer matching the bound source cube mip levels',
|
|
199
|
+
`writePrefilterUniforms received sourceMipLevelCount=${sourceMipLevelCount}`,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
const payload = new Float32Array([roughness, mipFaceSize, sourceMipLevelCount, 0]);
|
|
193
203
|
return device.queue.writeBuffer(buffer, subPassIdx * DYNAMIC_OFFSET_STRIDE, payload);
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
export function writeAllPrefilterUniforms(
|
|
197
207
|
device: FaceUniformsDevice,
|
|
198
208
|
buffer: Buffer,
|
|
209
|
+
sourceMipLevelCount = 1,
|
|
199
210
|
): Result<void, RhiError> {
|
|
200
211
|
for (let mip = 0; mip < PREFILTER_MIP_LEVELS; mip++) {
|
|
201
212
|
const roughness = mip / (PREFILTER_MIP_LEVELS - 1);
|
|
@@ -207,6 +218,7 @@ export function writeAllPrefilterUniforms(
|
|
|
207
218
|
mip * FACE_COUNT + face,
|
|
208
219
|
roughness,
|
|
209
220
|
mipFaceSize,
|
|
221
|
+
sourceMipLevelCount,
|
|
210
222
|
);
|
|
211
223
|
if (!result.ok) return result;
|
|
212
224
|
}
|
|
@@ -303,6 +315,11 @@ export interface TextureGpuEntry {
|
|
|
303
315
|
readonly receipt: TextureResidencyReceipt;
|
|
304
316
|
}
|
|
305
317
|
|
|
318
|
+
/** Candidate-only residency work; no queue submission is hidden here. */
|
|
319
|
+
export interface RecoveryResidencyPreparation {
|
|
320
|
+
readonly mipmapWork?: MipmapEncoderWork;
|
|
321
|
+
}
|
|
322
|
+
|
|
306
323
|
// feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M2 / w11
|
|
307
324
|
// (D-3): the projection-status truth lives here (the store's cubemap map is the
|
|
308
325
|
// single authority — the SkylightSnapshot carries no status, D-3). `status`:
|
|
@@ -324,6 +341,123 @@ interface CubemapGpuEntry {
|
|
|
324
341
|
faceViews: readonly TextureView[];
|
|
325
342
|
}
|
|
326
343
|
|
|
344
|
+
interface PackedMeshLodGeometry {
|
|
345
|
+
readonly vertices: Float32Array;
|
|
346
|
+
readonly indices: Uint16Array | Uint32Array | undefined;
|
|
347
|
+
readonly lodRanges: readonly (readonly MeshGpuRange[])[] | undefined;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function packMeshLodGeometry(
|
|
351
|
+
root: TypesMeshAsset,
|
|
352
|
+
rootData: MeshRenderData,
|
|
353
|
+
lowerMeshes: readonly TypesMeshAsset[],
|
|
354
|
+
): Result<PackedMeshLodGeometry, RhiError> {
|
|
355
|
+
if (lowerMeshes.length === 0) {
|
|
356
|
+
return ok({ vertices: root.vertices, indices: root.indices, lodRanges: undefined });
|
|
357
|
+
}
|
|
358
|
+
const rootStride = rootData.layoutProjection.arrayStride;
|
|
359
|
+
const allMeshes = [root, ...lowerMeshes];
|
|
360
|
+
const lowerData: MeshRenderData[] = [];
|
|
361
|
+
for (const lower of lowerMeshes) {
|
|
362
|
+
const projected = deriveRenderDataMesh(lower);
|
|
363
|
+
if (!projected.ok) {
|
|
364
|
+
return err(
|
|
365
|
+
new RhiError({
|
|
366
|
+
code: 'asset-not-registered',
|
|
367
|
+
expected: 'every MeshAsset LOD to project to a compatible GPU layout',
|
|
368
|
+
hint: 'repair the lower-detail MeshAsset attributes before drawing the LOD chain',
|
|
369
|
+
}),
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
lowerData.push(projected.value);
|
|
373
|
+
}
|
|
374
|
+
if (
|
|
375
|
+
lowerData.some(
|
|
376
|
+
(data) =>
|
|
377
|
+
data.layoutProjection.arrayStride !== rootStride ||
|
|
378
|
+
data.submeshes.length !== rootData.submeshes.length ||
|
|
379
|
+
data.indexFormat !== rootData.indexFormat,
|
|
380
|
+
)
|
|
381
|
+
) {
|
|
382
|
+
return err(
|
|
383
|
+
new RhiError({
|
|
384
|
+
code: 'asset-not-registered',
|
|
385
|
+
expected: 'LOD meshes to share vertex/index layout and material-slot topology',
|
|
386
|
+
hint: 'reimport LOD meshes with matching attributes, index format, and submesh slots',
|
|
387
|
+
}),
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
if (allMeshes.some((mesh) => (mesh.indices === undefined) !== (root.indices === undefined))) {
|
|
391
|
+
return err(
|
|
392
|
+
new RhiError({
|
|
393
|
+
code: 'asset-not-registered',
|
|
394
|
+
expected: 'all LOD meshes to use the same indexed or non-indexed draw mode',
|
|
395
|
+
hint: 'reimport the LOD chain with consistent index data',
|
|
396
|
+
}),
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
const vertices = new Float32Array(allMeshes.reduce((sum, mesh) => sum + mesh.vertices.length, 0));
|
|
400
|
+
const ranges: MeshGpuRange[][] = [];
|
|
401
|
+
let vertexCursor = 0;
|
|
402
|
+
let indexCursor = 0;
|
|
403
|
+
const indexed = root.indices !== undefined;
|
|
404
|
+
const sourceIndices: number[] = [];
|
|
405
|
+
let requiresUint32 = root.indices instanceof Uint32Array;
|
|
406
|
+
for (let level = 0; level < allMeshes.length; level += 1) {
|
|
407
|
+
const mesh = allMeshes[level];
|
|
408
|
+
const data = level === 0 ? rootData : lowerData[level - 1];
|
|
409
|
+
if (mesh === undefined || data === undefined) continue;
|
|
410
|
+
vertices.set(mesh.vertices, vertexCursor);
|
|
411
|
+
const levelRanges: MeshGpuRange[] = [];
|
|
412
|
+
for (let submeshIndex = 0; submeshIndex < data.submeshes.length; submeshIndex += 1) {
|
|
413
|
+
const submesh = data.submeshes[submeshIndex];
|
|
414
|
+
const rootSubmesh = rootData.submeshes[submeshIndex];
|
|
415
|
+
if (
|
|
416
|
+
submesh === undefined ||
|
|
417
|
+
rootSubmesh === undefined ||
|
|
418
|
+
submesh.materialSlot !== rootSubmesh.materialSlot ||
|
|
419
|
+
submesh.topology !== rootSubmesh.topology
|
|
420
|
+
) {
|
|
421
|
+
return err(
|
|
422
|
+
new RhiError({
|
|
423
|
+
code: 'asset-not-registered',
|
|
424
|
+
expected: 'LOD submeshes to preserve root material-slot and topology identity',
|
|
425
|
+
hint: 'repair LOD material slots and primitive topology before import',
|
|
426
|
+
}),
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
levelRanges.push(
|
|
430
|
+
indexed
|
|
431
|
+
? {
|
|
432
|
+
first: indexCursor + submesh.indexOffset,
|
|
433
|
+
count: submesh.indexCount,
|
|
434
|
+
baseVertex: vertexCursor / (rootStride / 4),
|
|
435
|
+
}
|
|
436
|
+
: { first: vertexCursor / (rootStride / 4), count: submesh.vertexCount, baseVertex: 0 },
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
ranges.push(levelRanges);
|
|
440
|
+
if (indexed) {
|
|
441
|
+
const indices = mesh.indices;
|
|
442
|
+
if (indices === undefined) continue;
|
|
443
|
+
for (const value of indices) {
|
|
444
|
+
// Each LOD range carries its vertex cursor as baseVertex, so keep
|
|
445
|
+
// indices local to that LOD and apply the offset exactly once at draw.
|
|
446
|
+
sourceIndices.push(value);
|
|
447
|
+
if (value > 0xffff || indices instanceof Uint32Array) requiresUint32 = true;
|
|
448
|
+
}
|
|
449
|
+
indexCursor += indices.length;
|
|
450
|
+
}
|
|
451
|
+
vertexCursor += mesh.vertices.length;
|
|
452
|
+
}
|
|
453
|
+
const indices = indexed
|
|
454
|
+
? requiresUint32
|
|
455
|
+
? Uint32Array.from(sourceIndices)
|
|
456
|
+
: Uint16Array.from(sourceIndices)
|
|
457
|
+
: undefined;
|
|
458
|
+
return ok({ vertices, indices, lodRanges: ranges });
|
|
459
|
+
}
|
|
460
|
+
|
|
327
461
|
export interface MeshGpuHandles {
|
|
328
462
|
readonly vertexBuffer: GpuBuffer;
|
|
329
463
|
/**
|
|
@@ -374,6 +508,14 @@ export interface MeshGpuHandles {
|
|
|
374
508
|
* For single-submesh meshes this is a 1-element array (byte-identical to pre-M4).
|
|
375
509
|
*/
|
|
376
510
|
readonly submeshes: readonly import('@forgeax/engine-types').Submesh[];
|
|
511
|
+
/** Packed root + lower-detail geometry ranges in the shared mesh buffers. */
|
|
512
|
+
readonly lodRanges?: readonly (readonly MeshGpuRange[])[];
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export interface MeshGpuRange {
|
|
516
|
+
readonly first: number;
|
|
517
|
+
readonly count: number;
|
|
518
|
+
readonly baseVertex: number;
|
|
377
519
|
}
|
|
378
520
|
|
|
379
521
|
/**
|
|
@@ -404,6 +546,7 @@ export class GpuResidencyCache {
|
|
|
404
546
|
// Hardware-probe caps injected at `configureGpuDevice`; guards the HDR cubemap
|
|
405
547
|
// path (_uploadCubemapFromEquirect) when `rgba16floatRenderable` is false.
|
|
406
548
|
private caps: RhiCaps | undefined = undefined;
|
|
549
|
+
private recoveryColdWorkGuard: RecoveryColdWorkGuard | undefined;
|
|
407
550
|
private deviceEpoch = 0;
|
|
408
551
|
private textureGeneration = 0;
|
|
409
552
|
|
|
@@ -482,6 +625,11 @@ export class GpuResidencyCache {
|
|
|
482
625
|
this.deviceScope = scope;
|
|
483
626
|
}
|
|
484
627
|
|
|
628
|
+
/** Arm the first-published-frame assertion on this generation's store. */
|
|
629
|
+
setRecoveryColdWorkGuard(guard: RecoveryColdWorkGuard | undefined): void {
|
|
630
|
+
this.recoveryColdWorkGuard = guard;
|
|
631
|
+
}
|
|
632
|
+
|
|
485
633
|
/**
|
|
486
634
|
* Wrap a raw RHI Buffer handle into a GpuBuffer. The wrapper holds a
|
|
487
635
|
* reference to the device so `.destroy()` forwards to
|
|
@@ -570,6 +718,39 @@ export class GpuResidencyCache {
|
|
|
570
718
|
this.meshGpuHandles.clear();
|
|
571
719
|
}
|
|
572
720
|
|
|
721
|
+
/** Number of candidate-owned GPU resources currently held by this cache. */
|
|
722
|
+
recoveryResourceCount(): number {
|
|
723
|
+
let cubemapResources = 0;
|
|
724
|
+
const seen = new Set<GpuTexture>();
|
|
725
|
+
for (const entry of this.cubemapGpuHandles.values()) {
|
|
726
|
+
if (entry.texture !== null && !seen.has(entry.texture)) {
|
|
727
|
+
seen.add(entry.texture);
|
|
728
|
+
cubemapResources += 1;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return (
|
|
732
|
+
this.meshGpuHandles.size +
|
|
733
|
+
this.textureGpuHandles.size +
|
|
734
|
+
this.samplerGpuHandles.size +
|
|
735
|
+
cubemapResources
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/** Candidate root for the cache owner, not a scalar readiness marker. */
|
|
740
|
+
createRecoveryRoot(scope: DeviceScope): LifecycleResourceSpec<unknown> {
|
|
741
|
+
return {
|
|
742
|
+
kind: 'texture',
|
|
743
|
+
create: () => {
|
|
744
|
+
if (!scope.isAlive()) throw new Error('GPU residency candidate scope is not active.');
|
|
745
|
+
if (this.recoveryResourceCount() === 0) {
|
|
746
|
+
throw new Error('GPU residency candidate has no prepared resources.');
|
|
747
|
+
}
|
|
748
|
+
return this;
|
|
749
|
+
},
|
|
750
|
+
cleanup: () => undefined,
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
|
|
573
754
|
/**
|
|
574
755
|
* Set the error registry channel (wired by createRenderer). evict /
|
|
575
756
|
* releaseUnreferenced fire structured errors here instead of throwing -
|
|
@@ -845,6 +1026,7 @@ export class GpuResidencyCache {
|
|
|
845
1026
|
const key = this.worldKey(handleSlot(handle), worldId);
|
|
846
1027
|
const existing = this.samplerGpuHandles.get(key);
|
|
847
1028
|
if (existing !== undefined) return ok(existing);
|
|
1029
|
+
this.recoveryColdWorkGuard?.noteUploadColdWork();
|
|
848
1030
|
const device = this.gpuDevice;
|
|
849
1031
|
if (device === undefined) {
|
|
850
1032
|
return err(
|
|
@@ -951,6 +1133,7 @@ export class GpuResidencyCache {
|
|
|
951
1133
|
handle: Handle<'MeshAsset', 'shared'>,
|
|
952
1134
|
pod: TypesMeshAsset,
|
|
953
1135
|
worldId?: World | number,
|
|
1136
|
+
lodMeshes?: readonly TypesMeshAsset[],
|
|
954
1137
|
): Result<MeshGpuHandles, RhiError | AssetError | ImageError>;
|
|
955
1138
|
ensureResident(
|
|
956
1139
|
handle: Handle<'TextureAsset', 'shared'>,
|
|
@@ -961,6 +1144,7 @@ export class GpuResidencyCache {
|
|
|
961
1144
|
handle: Handle<'MeshAsset', 'shared'> | Handle<'TextureAsset', 'shared'>,
|
|
962
1145
|
pod: TypesMeshAsset | TextureAsset,
|
|
963
1146
|
worldId: World | number = 0,
|
|
1147
|
+
lodMeshes: readonly TypesMeshAsset[] = [],
|
|
964
1148
|
): Result<TextureGpuEntry | MeshGpuHandles, RhiError | AssetError | ImageError> {
|
|
965
1149
|
const id = handleSlot(handle);
|
|
966
1150
|
// Hit: O(1) cache lookup, never re-projects (AC-09 -- deriveRenderData*
|
|
@@ -975,14 +1159,16 @@ export class GpuResidencyCache {
|
|
|
975
1159
|
const key = this.worldKey(id, worldId);
|
|
976
1160
|
const existing = this.meshGpuHandles.get(key);
|
|
977
1161
|
if (existing !== undefined) return ok(existing);
|
|
1162
|
+
this.recoveryColdWorkGuard?.noteUploadColdWork();
|
|
978
1163
|
const projected = deriveRenderDataMesh(pod);
|
|
979
1164
|
if (!projected.ok) return projected;
|
|
980
|
-
return this.uploadMeshById(key, pod, projected.value);
|
|
1165
|
+
return this.uploadMeshById(key, pod, projected.value, lodMeshes);
|
|
981
1166
|
}
|
|
982
1167
|
case 'texture': {
|
|
983
1168
|
const texKey = this.worldKey(id, worldId);
|
|
984
1169
|
const existing = this.textureGpuHandles.get(texKey);
|
|
985
1170
|
if (existing !== undefined) return ok(existing);
|
|
1171
|
+
this.recoveryColdWorkGuard?.noteUploadColdWork();
|
|
986
1172
|
const projected = deriveRenderDataTexture(pod);
|
|
987
1173
|
if (!projected.ok) return projected;
|
|
988
1174
|
const decoded: DecodedImage = decodedFromTexture(pod);
|
|
@@ -997,6 +1183,101 @@ export class GpuResidencyCache {
|
|
|
997
1183
|
}
|
|
998
1184
|
}
|
|
999
1185
|
|
|
1186
|
+
/**
|
|
1187
|
+
* Prepare one candidate-visible resource without the normal draw-time mip
|
|
1188
|
+
* submission. Base writes and resource creation stay owned by this cache;
|
|
1189
|
+
* generated mip passes are returned to the recovery transaction for one
|
|
1190
|
+
* explicit finish/submit before publication.
|
|
1191
|
+
*/
|
|
1192
|
+
prepareResidentForRecovery(
|
|
1193
|
+
handle: Handle<'MeshAsset', 'shared'>,
|
|
1194
|
+
pod: TypesMeshAsset,
|
|
1195
|
+
worldId?: World | number,
|
|
1196
|
+
): Result<RecoveryResidencyPreparation, RhiError | AssetError | ImageError>;
|
|
1197
|
+
prepareResidentForRecovery(
|
|
1198
|
+
handle: Handle<'TextureAsset', 'shared'>,
|
|
1199
|
+
pod: TextureAsset,
|
|
1200
|
+
worldId?: World | number,
|
|
1201
|
+
): Result<RecoveryResidencyPreparation, RhiError | AssetError | ImageError>;
|
|
1202
|
+
prepareResidentForRecovery(
|
|
1203
|
+
handle: Handle<'MeshAsset', 'shared'> | Handle<'TextureAsset', 'shared'>,
|
|
1204
|
+
pod: TypesMeshAsset | TextureAsset,
|
|
1205
|
+
worldId: World | number = 0,
|
|
1206
|
+
): Result<RecoveryResidencyPreparation, RhiError | AssetError | ImageError> {
|
|
1207
|
+
const id = handleSlot(handle);
|
|
1208
|
+
if (pod.kind === 'mesh') {
|
|
1209
|
+
const key = this.worldKey(id, worldId);
|
|
1210
|
+
if (this.meshGpuHandles.has(key)) return ok({});
|
|
1211
|
+
const projected = deriveRenderDataMesh(pod);
|
|
1212
|
+
if (!projected.ok) return projected;
|
|
1213
|
+
const uploaded = this.uploadMeshById(key, pod, projected.value);
|
|
1214
|
+
return uploaded.ok ? ok({}) : uploaded;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
const cacheKey = this.worldKey(id, worldId);
|
|
1218
|
+
if (this.textureGpuHandles.has(cacheKey)) return ok({});
|
|
1219
|
+
const projected = deriveRenderDataTexture(pod);
|
|
1220
|
+
if (!projected.ok) return projected;
|
|
1221
|
+
const decoded = decodedFromTexture(pod);
|
|
1222
|
+
const prepared = this.prepareTextureUpload(
|
|
1223
|
+
handle as Handle<'TextureAsset', 'shared'>,
|
|
1224
|
+
pod,
|
|
1225
|
+
decoded,
|
|
1226
|
+
projected.value,
|
|
1227
|
+
);
|
|
1228
|
+
if (!prepared.ok) return prepared;
|
|
1229
|
+
const device = this.gpuDevice;
|
|
1230
|
+
const gpuTexture = prepared.value.gpuTexture;
|
|
1231
|
+
if (device === undefined || gpuTexture === undefined) {
|
|
1232
|
+
return err(
|
|
1233
|
+
new RhiError({
|
|
1234
|
+
code: 'rhi-not-available',
|
|
1235
|
+
expected: 'GpuResidencyCache.configureGpuDevice wired before recovery residency',
|
|
1236
|
+
hint: 'configure the candidate store before preparing recovery resources',
|
|
1237
|
+
}),
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
let mipmapWork: MipmapEncoderWork | undefined;
|
|
1242
|
+
if (!projected.value.compressed && pod.mips.kind === 'generate' && prepared.value.levels > 1) {
|
|
1243
|
+
const preparedMipmaps = prepareMipmaps(device, gpuTexture, {
|
|
1244
|
+
format: projected.value.format,
|
|
1245
|
+
width: pod.shape.extent.width,
|
|
1246
|
+
height: pod.shape.extent.height,
|
|
1247
|
+
levels: prepared.value.levels,
|
|
1248
|
+
});
|
|
1249
|
+
if (!preparedMipmaps.ok) {
|
|
1250
|
+
new GpuTexture(device, gpuTexture).destroy();
|
|
1251
|
+
return preparedMipmaps;
|
|
1252
|
+
}
|
|
1253
|
+
mipmapWork = preparedMipmaps.value;
|
|
1254
|
+
}
|
|
1255
|
+
const viewRes = device.createTextureView(gpuTexture, {
|
|
1256
|
+
label: `texture-view-${cacheKey}`,
|
|
1257
|
+
dimension: projected.value.shape.viewDimension,
|
|
1258
|
+
});
|
|
1259
|
+
if (!viewRes.ok) {
|
|
1260
|
+
new GpuTexture(device, gpuTexture).destroy();
|
|
1261
|
+
return viewRes;
|
|
1262
|
+
}
|
|
1263
|
+
const previous = this.textureGpuHandles.get(cacheKey);
|
|
1264
|
+
const entry: TextureGpuEntry = {
|
|
1265
|
+
texture: this.wrapTex(gpuTexture),
|
|
1266
|
+
view: viewRes.value,
|
|
1267
|
+
receipt: this.textureReceipt(pod, projected.value),
|
|
1268
|
+
};
|
|
1269
|
+
this.textureGpuHandles.set(cacheKey, entry);
|
|
1270
|
+
this.materialResourceEpoch += 1;
|
|
1271
|
+
if (
|
|
1272
|
+
previous !== undefined &&
|
|
1273
|
+
previous.texture !== entry.texture &&
|
|
1274
|
+
!previous.texture.isDestroyed
|
|
1275
|
+
) {
|
|
1276
|
+
previous.texture.destroy();
|
|
1277
|
+
}
|
|
1278
|
+
return ok(mipmapWork === undefined ? {} : { mipmapWork });
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1000
1281
|
/**
|
|
1001
1282
|
* Eager public surface: upload decoded image bytes into a GPU texture and
|
|
1002
1283
|
* cache (texture + view) under the handle. The TextureAsset POD supplies the
|
|
@@ -1491,6 +1772,7 @@ export class GpuResidencyCache {
|
|
|
1491
1772
|
// universally renderable rgba8 path; the same format is threaded through
|
|
1492
1773
|
// the cubemap and all three IBL side textures by IblPipelineCache.
|
|
1493
1774
|
const outputFormat = this.caps?.rgba16floatRenderable === false ? 'rgba8unorm' : tex.format;
|
|
1775
|
+
const sourceMipLevelCount = 1;
|
|
1494
1776
|
|
|
1495
1777
|
// Lazy projection runs from the record arm, where the RHI device is always
|
|
1496
1778
|
// wired (research R-5). The IBL path is deliberately independent from the
|
|
@@ -1516,7 +1798,7 @@ export class GpuResidencyCache {
|
|
|
1516
1798
|
const gpuTextureResult = device.createTexture({
|
|
1517
1799
|
label: `cubemap-${sourceId}`,
|
|
1518
1800
|
size: { width: cubeFaceSize, height: cubeFaceSize, depthOrArrayLayers: 6 },
|
|
1519
|
-
mipLevelCount:
|
|
1801
|
+
mipLevelCount: sourceMipLevelCount,
|
|
1520
1802
|
sampleCount: 1,
|
|
1521
1803
|
dimension: '2d',
|
|
1522
1804
|
format: outputFormat,
|
|
@@ -1555,13 +1837,6 @@ export class GpuResidencyCache {
|
|
|
1555
1837
|
// surfacing exactly one destroy call per physical resource.
|
|
1556
1838
|
const gpuTextureWrapper = this.wrapTex(gpuTexture);
|
|
1557
1839
|
|
|
1558
|
-
this.cubemapGpuHandles.set(sourceId, {
|
|
1559
|
-
status: 'ready',
|
|
1560
|
-
texture: gpuTextureWrapper,
|
|
1561
|
-
view: cubeView,
|
|
1562
|
-
faceViews,
|
|
1563
|
-
});
|
|
1564
|
-
|
|
1565
1840
|
// The minted cubemap handle is a synthetic shared ref (identity token for
|
|
1566
1841
|
// the GPU cube residency); its POD is an EquirectAsset placeholder matching
|
|
1567
1842
|
// the projected dimensions/format (D-3: the retired cube-texture asset kind
|
|
@@ -1574,20 +1849,6 @@ export class GpuResidencyCache {
|
|
|
1574
1849
|
data: tex.data,
|
|
1575
1850
|
colorSpace: 'linear',
|
|
1576
1851
|
};
|
|
1577
|
-
const regResult = registerCube(world, cubeAsset);
|
|
1578
|
-
if (!regResult.ok) return recordFailed(regResult.error);
|
|
1579
|
-
const cubeHandle = regResult.value;
|
|
1580
|
-
const cubeId = handleSlot(cubeHandle);
|
|
1581
|
-
|
|
1582
|
-
this.cubemapGpuHandles.set(cubeId, {
|
|
1583
|
-
status: 'ready',
|
|
1584
|
-
texture: gpuTextureWrapper,
|
|
1585
|
-
view: cubeView,
|
|
1586
|
-
faceViews,
|
|
1587
|
-
});
|
|
1588
|
-
|
|
1589
|
-
this.cubemapIdempotentMap.set(sourceId, cubeHandle);
|
|
1590
|
-
|
|
1591
1852
|
const pipelinesResult = await createIblPipelines(
|
|
1592
1853
|
scope,
|
|
1593
1854
|
device,
|
|
@@ -1621,6 +1882,9 @@ export class GpuResidencyCache {
|
|
|
1621
1882
|
});
|
|
1622
1883
|
if (!equirectTextureResult.ok) return recordFailed(equirectTextureResult.error);
|
|
1623
1884
|
const equirectGpuTex = equirectTextureResult.value;
|
|
1885
|
+
scope._adopt('texture', equirectGpuTex, (texture) => {
|
|
1886
|
+
device.destroyTexture(texture);
|
|
1887
|
+
});
|
|
1624
1888
|
|
|
1625
1889
|
const equirectViewResult = device.createTextureView(equirectGpuTex, {
|
|
1626
1890
|
label: `equirect-view-${sourceId}`,
|
|
@@ -1648,9 +1912,15 @@ export class GpuResidencyCache {
|
|
|
1648
1912
|
const faceBufferResult = createFaceUniformsBuffer(device);
|
|
1649
1913
|
if (!faceBufferResult.ok) return recordFailed(faceBufferResult.error);
|
|
1650
1914
|
const faceBuf = faceBufferResult.value;
|
|
1915
|
+
scope._adopt('buffer', faceBuf, (buffer) => {
|
|
1916
|
+
device.destroyBuffer(buffer);
|
|
1917
|
+
});
|
|
1651
1918
|
const prefilterBufferResult = createPrefilterUniformsBuffer(device);
|
|
1652
1919
|
if (!prefilterBufferResult.ok) return recordFailed(prefilterBufferResult.error);
|
|
1653
1920
|
const prefBuf = prefilterBufferResult.value;
|
|
1921
|
+
scope._adopt('buffer', prefBuf, (buffer) => {
|
|
1922
|
+
device.destroyBuffer(buffer);
|
|
1923
|
+
});
|
|
1654
1924
|
|
|
1655
1925
|
const cubeVertexResult = device.createBuffer({
|
|
1656
1926
|
label: 'ibl-cube-verts',
|
|
@@ -1660,15 +1930,18 @@ export class GpuResidencyCache {
|
|
|
1660
1930
|
});
|
|
1661
1931
|
if (!cubeVertexResult.ok) return recordFailed(cubeVertexResult.error);
|
|
1662
1932
|
const cubeVertex = cubeVertexResult.value;
|
|
1933
|
+
scope._adopt('buffer', cubeVertex, (buffer) => {
|
|
1934
|
+
device.destroyBuffer(buffer);
|
|
1935
|
+
});
|
|
1663
1936
|
|
|
1664
1937
|
const cubeVertexWriteResult = device.queue.writeBuffer(cubeVertex, 0, CUBEMAP_FACE_VERTICES);
|
|
1665
1938
|
if (!cubeVertexWriteResult.ok) return recordFailed(cubeVertexWriteResult.error);
|
|
1666
1939
|
const faceUniformsResult = writeAllFaceUniforms(device, faceBuf);
|
|
1667
1940
|
if (!faceUniformsResult.ok) return recordFailed(faceUniformsResult.error);
|
|
1668
|
-
const prefilterUniformsResult = writeAllPrefilterUniforms(device, prefBuf);
|
|
1941
|
+
const prefilterUniformsResult = writeAllPrefilterUniforms(device, prefBuf, sourceMipLevelCount);
|
|
1669
1942
|
if (!prefilterUniformsResult.ok) return recordFailed(prefilterUniformsResult.error);
|
|
1670
1943
|
|
|
1671
|
-
const runResult = runIblPrecompute({
|
|
1944
|
+
const runResult = await runIblPrecompute({
|
|
1672
1945
|
scope,
|
|
1673
1946
|
device,
|
|
1674
1947
|
equirectGpuTex,
|
|
@@ -1690,6 +1963,28 @@ export class GpuResidencyCache {
|
|
|
1690
1963
|
);
|
|
1691
1964
|
}
|
|
1692
1965
|
|
|
1966
|
+
// A source becomes visible to the record arm only after all four passes
|
|
1967
|
+
// completed their queue fence. Registration and the idempotent map are
|
|
1968
|
+
// publication, not allocation, so a failed precompute cannot expose a
|
|
1969
|
+
// ready cube or a loadable handle.
|
|
1970
|
+
this.cubemapGpuHandles.set(sourceId, {
|
|
1971
|
+
status: 'ready',
|
|
1972
|
+
texture: gpuTextureWrapper,
|
|
1973
|
+
view: cubeView,
|
|
1974
|
+
faceViews,
|
|
1975
|
+
});
|
|
1976
|
+
const regResult = registerCube(world, cubeAsset);
|
|
1977
|
+
if (!regResult.ok) return recordFailed(regResult.error);
|
|
1978
|
+
const cubeHandle = regResult.value;
|
|
1979
|
+
const cubeId = handleSlot(cubeHandle);
|
|
1980
|
+
this.cubemapGpuHandles.set(cubeId, {
|
|
1981
|
+
status: 'ready',
|
|
1982
|
+
texture: gpuTextureWrapper,
|
|
1983
|
+
view: cubeView,
|
|
1984
|
+
faceViews,
|
|
1985
|
+
});
|
|
1986
|
+
this.cubemapIdempotentMap.set(sourceId, cubeHandle);
|
|
1987
|
+
|
|
1693
1988
|
return ok(cubeHandle);
|
|
1694
1989
|
}
|
|
1695
1990
|
|
|
@@ -1702,6 +1997,7 @@ export class GpuResidencyCache {
|
|
|
1702
1997
|
id: string | number,
|
|
1703
1998
|
mesh: TypesMeshAsset,
|
|
1704
1999
|
renderData: MeshRenderData,
|
|
2000
|
+
lodMeshes: readonly TypesMeshAsset[] = [],
|
|
1705
2001
|
): Result<MeshGpuHandles, RhiError> {
|
|
1706
2002
|
const device = this.gpuDevice;
|
|
1707
2003
|
if (device === undefined) {
|
|
@@ -1714,13 +2010,15 @@ export class GpuResidencyCache {
|
|
|
1714
2010
|
);
|
|
1715
2011
|
}
|
|
1716
2012
|
|
|
1717
|
-
const
|
|
2013
|
+
const packed = packMeshLodGeometry(mesh, renderData, lodMeshes);
|
|
2014
|
+
if (!packed.ok) return packed;
|
|
2015
|
+
const { vertices, indices, lodRanges } = packed.value;
|
|
1718
2016
|
const indexBytesUnpadded = indices === undefined ? 0 : indices.byteLength;
|
|
1719
|
-
const indexBytes =
|
|
2017
|
+
const indexBytes = ((indexBytesUnpadded + 3) >> 2) << 2;
|
|
1720
2018
|
|
|
1721
2019
|
const vboResult = device.createBuffer({
|
|
1722
2020
|
label: `mesh-${id}-vbo`,
|
|
1723
|
-
size:
|
|
2021
|
+
size: vertices.byteLength,
|
|
1724
2022
|
usage: renderData.vertexUsage,
|
|
1725
2023
|
mappedAtCreation: false,
|
|
1726
2024
|
});
|
|
@@ -1740,7 +2038,7 @@ export class GpuResidencyCache {
|
|
|
1740
2038
|
ibo = iboResult.value;
|
|
1741
2039
|
}
|
|
1742
2040
|
|
|
1743
|
-
const vboWriteResult = device.queue.writeBuffer(vbo, 0,
|
|
2041
|
+
const vboWriteResult = device.queue.writeBuffer(vbo, 0, vertices);
|
|
1744
2042
|
if (!vboWriteResult.ok) return err(vboWriteResult.error);
|
|
1745
2043
|
|
|
1746
2044
|
if (indices !== undefined) {
|
|
@@ -1766,10 +2064,10 @@ export class GpuResidencyCache {
|
|
|
1766
2064
|
const entry: MeshGpuHandles = {
|
|
1767
2065
|
vertexBuffer: this.wrapBuf(vbo),
|
|
1768
2066
|
indexBuffer: ibo === null ? null : this.wrapBuf(ibo),
|
|
1769
|
-
vboBytes:
|
|
2067
|
+
vboBytes: vertices.byteLength,
|
|
1770
2068
|
iboBytes: indices === undefined ? 0 : indexBytes,
|
|
1771
|
-
indexCount:
|
|
1772
|
-
indexFormat:
|
|
2069
|
+
indexCount: mesh.indices === undefined ? 0 : mesh.indices.length,
|
|
2070
|
+
indexFormat: indices instanceof Uint32Array ? 'uint32' : 'uint16',
|
|
1773
2071
|
layout: renderData.layoutProjection.attributes.some(
|
|
1774
2072
|
(attribute) => attribute.key === 'skinIndex' || attribute.key === 'skinWeight',
|
|
1775
2073
|
)
|
|
@@ -1778,9 +2076,10 @@ export class GpuResidencyCache {
|
|
|
1778
2076
|
layoutProjection: renderData.layoutProjection,
|
|
1779
2077
|
uvSetCount: 1 + extraUvSets,
|
|
1780
2078
|
vertexCount: mesh.vertices.byteLength / renderData.layoutProjection.arrayStride,
|
|
1781
|
-
indexed: indices !== undefined,
|
|
2079
|
+
indexed: mesh.indices !== undefined,
|
|
1782
2080
|
topology: renderData.submeshes[0]?.topology ?? 'triangle-list',
|
|
1783
2081
|
submeshes: renderData.submeshes,
|
|
2082
|
+
...(lodRanges === undefined ? {} : { lodRanges }),
|
|
1784
2083
|
};
|
|
1785
2084
|
this.meshGpuHandles.set(id, entry);
|
|
1786
2085
|
this.meshResidencyEpoch += 1;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type DeviceResourceKind,
|
|
3
|
+
DeviceResourceRef,
|
|
4
|
+
DeviceScope,
|
|
5
|
+
type DeviceScopeReceipt,
|
|
6
|
+
type DeviceScopeState,
|
|
7
|
+
type LifecycleFailure,
|
|
8
|
+
type LifecycleResourceSpec,
|
|
9
|
+
type LifecycleResult,
|
|
10
|
+
LifecycleTransaction,
|
|
11
|
+
type ResourceRef,
|
|
12
|
+
} from './device-scope';
|
package/src/environment/frame.ts
CHANGED
|
@@ -12,6 +12,12 @@ import { environmentFactSignatures } from './signature';
|
|
|
12
12
|
|
|
13
13
|
export type { EnvironmentCandidate, EnvironmentFrame, EnvironmentSource, FogCandidate, FogFrame };
|
|
14
14
|
|
|
15
|
+
/** Producer-local fallback while replacement environment storage is uninitialized. */
|
|
16
|
+
export const SKYLIGHT_RECOVERY_FALLBACK = Object.freeze({
|
|
17
|
+
kind: 'skylight',
|
|
18
|
+
active: false,
|
|
19
|
+
} as const);
|
|
20
|
+
|
|
15
21
|
export interface SunCandidate {
|
|
16
22
|
readonly entityKey: number;
|
|
17
23
|
readonly direction: readonly [number, number, number];
|
|
@@ -38,6 +38,14 @@ export interface EnvironmentInspection {
|
|
|
38
38
|
readonly residentBytes: number;
|
|
39
39
|
readonly retiringBytes: number;
|
|
40
40
|
readonly lastCandidateFailure: EnvironmentInspectionFailure | undefined;
|
|
41
|
+
readonly recovery:
|
|
42
|
+
| {
|
|
43
|
+
readonly token: number;
|
|
44
|
+
readonly deviceGeneration: number;
|
|
45
|
+
readonly status: 'uninitialized';
|
|
46
|
+
readonly fallback: 'skylight';
|
|
47
|
+
}
|
|
48
|
+
| undefined;
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
export function inspectEnvironment(
|
|
@@ -50,6 +58,7 @@ export function inspectEnvironment(
|
|
|
50
58
|
readonly lkg?: EnvironmentInspectionGeneration;
|
|
51
59
|
readonly candidate?: EnvironmentInspectionGeneration;
|
|
52
60
|
readonly lastCandidateFailure?: EnvironmentInspectionFailure;
|
|
61
|
+
readonly recovery?: EnvironmentInspection['recovery'];
|
|
53
62
|
readonly retiringBytes?: number;
|
|
54
63
|
} = {},
|
|
55
64
|
): EnvironmentInspection {
|
|
@@ -83,5 +92,6 @@ export function inspectEnvironment(
|
|
|
83
92
|
residentBytes: active?.residentBytes ?? 0,
|
|
84
93
|
retiringBytes: details.retiringBytes ?? active?.retiringBytes ?? 0,
|
|
85
94
|
lastCandidateFailure: details.lastCandidateFailure,
|
|
95
|
+
recovery: details.recovery,
|
|
86
96
|
});
|
|
87
97
|
}
|