@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
|
@@ -25,7 +25,10 @@ import {
|
|
|
25
25
|
} from '../ibl/skylight-bind-group';
|
|
26
26
|
import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
|
|
27
27
|
import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
isStandardPbrMaterialShader,
|
|
30
|
+
SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET,
|
|
31
|
+
} from '../pbr-pipeline';
|
|
29
32
|
import {
|
|
30
33
|
buildBeginRenderPassDescriptor,
|
|
31
34
|
standardTopologyVariantSet,
|
|
@@ -33,6 +36,7 @@ import {
|
|
|
33
36
|
} from '../pipeline-spec';
|
|
34
37
|
import type { MaterialSnapshot, SpriteInstancesSnapshot } from '../render-system-extract';
|
|
35
38
|
import { worldEntityKey } from './frame-snapshot';
|
|
39
|
+
import { resolveGeometryInstancesBindGroup, resolveProbeBlendBuffer } from './main-pass-geometry';
|
|
36
40
|
import {
|
|
37
41
|
BUILTIN_USER_REGION_TEXTURE_FIELDS,
|
|
38
42
|
defaultViewForUserRegionField,
|
|
@@ -463,7 +467,7 @@ function recordSpriteTransparentPbrDraws(
|
|
|
463
467
|
) => BindGroup,
|
|
464
468
|
meshGroup2: BindGroup | null,
|
|
465
469
|
): void {
|
|
466
|
-
const { runtime, pipelineState,
|
|
470
|
+
const { runtime, pipelineState, validatedOrdered } = c;
|
|
467
471
|
const isHdrTarget =
|
|
468
472
|
c.tonemapActive || transparentPassColorFormat(c, pipelineState) === 'rgba16float';
|
|
469
473
|
let lastPbrSubPipelineHandle: typeof pipelineState.unlitPipeline = null;
|
|
@@ -497,48 +501,6 @@ function recordSpriteTransparentPbrDraws(
|
|
|
497
501
|
spritePass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);
|
|
498
502
|
lastPbrSubIndexBuffer = entry.mesh.indexBuffer;
|
|
499
503
|
}
|
|
500
|
-
// Identity instance BG (instanceCount=1); reuse the per-entity cache.
|
|
501
|
-
const identityInstBg: BindGroup = getOrCreatePerEntity(
|
|
502
|
-
frameState.instancesBgPerEntity,
|
|
503
|
-
worldEntityKey(entry.source.worldId, entry.source.entityKey),
|
|
504
|
-
[pipelineState.identityInstanceBuffer],
|
|
505
|
-
'instances',
|
|
506
|
-
() => {
|
|
507
|
-
const result = runtime.device.createBindGroup({
|
|
508
|
-
label: 'pbr-transparent-sub-instances-bg',
|
|
509
|
-
layout: pipelineState.instancesBindGroupLayout,
|
|
510
|
-
entries: [
|
|
511
|
-
{
|
|
512
|
-
binding: 0,
|
|
513
|
-
resource: {
|
|
514
|
-
kind: 'buffer',
|
|
515
|
-
value: { buffer: pipelineState.identityInstanceBuffer },
|
|
516
|
-
},
|
|
517
|
-
},
|
|
518
|
-
],
|
|
519
|
-
});
|
|
520
|
-
if (!result.ok) throw result.error;
|
|
521
|
-
return result.value;
|
|
522
|
-
},
|
|
523
|
-
bindGroupCounts,
|
|
524
|
-
);
|
|
525
|
-
spritePass.setBindGroup(3, identityInstBg);
|
|
526
|
-
|
|
527
|
-
const subVariantSet = standardTopologyVariantSet(
|
|
528
|
-
c.standardLighting,
|
|
529
|
-
runtime.device.caps.storageBuffer,
|
|
530
|
-
entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),
|
|
531
|
-
);
|
|
532
|
-
const projectionVariantSetResult = variantSetFromVertexLayoutProjection(
|
|
533
|
-
entry.mesh.layoutProjection,
|
|
534
|
-
subVariantSet,
|
|
535
|
-
);
|
|
536
|
-
if (!projectionVariantSetResult.ok) {
|
|
537
|
-
runtime.errorRegistry.fire(projectionVariantSetResult.error);
|
|
538
|
-
continue;
|
|
539
|
-
}
|
|
540
|
-
const projectionVariantSet = projectionVariantSetResult.value;
|
|
541
|
-
|
|
542
504
|
for (let smIdx = 0; smIdx < entry.mesh.submeshes.length; smIdx++) {
|
|
543
505
|
const sm = entry.mesh.submeshes[smIdx];
|
|
544
506
|
if (sm === undefined) continue;
|
|
@@ -549,6 +511,39 @@ function recordSpriteTransparentPbrDraws(
|
|
|
549
511
|
if (submeshMaterial.transparent !== true) continue;
|
|
550
512
|
const smShaderId = submeshMaterial.materialShaderId;
|
|
551
513
|
if (smShaderId === undefined) continue;
|
|
514
|
+
const probeBlendAvailable =
|
|
515
|
+
runtime.device.caps.storageBuffer &&
|
|
516
|
+
entry.source.probeBlendRecord !== undefined &&
|
|
517
|
+
isStandardPbrMaterialShader(smShaderId);
|
|
518
|
+
const probeBinding = probeBlendAvailable
|
|
519
|
+
? resolveProbeBlendBuffer(
|
|
520
|
+
c,
|
|
521
|
+
entry.source.probeBlendRecord,
|
|
522
|
+
worldEntityKey(entry.source.worldId, entry.source.entityKey),
|
|
523
|
+
)
|
|
524
|
+
: undefined;
|
|
525
|
+
const identityInstBg = resolveGeometryInstancesBindGroup(
|
|
526
|
+
c,
|
|
527
|
+
pipelineState.identityInstanceBuffer,
|
|
528
|
+
probeBinding?.buffer,
|
|
529
|
+
);
|
|
530
|
+
if (probeBinding === undefined) spritePass.setBindGroup(3, identityInstBg);
|
|
531
|
+
else spritePass.setBindGroup(3, identityInstBg, [probeBinding.offset]);
|
|
532
|
+
const subVariantSet = standardTopologyVariantSet(
|
|
533
|
+
c.standardLighting,
|
|
534
|
+
runtime.device.caps.storageBuffer,
|
|
535
|
+
entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),
|
|
536
|
+
probeBlendAvailable,
|
|
537
|
+
);
|
|
538
|
+
const projectionVariantSetResult = variantSetFromVertexLayoutProjection(
|
|
539
|
+
entry.mesh.layoutProjection,
|
|
540
|
+
subVariantSet,
|
|
541
|
+
);
|
|
542
|
+
if (!projectionVariantSetResult.ok) {
|
|
543
|
+
runtime.errorRegistry.fire(projectionVariantSetResult.error);
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
const projectionVariantSet = projectionVariantSetResult.value;
|
|
552
547
|
const subPipelineEntry =
|
|
553
548
|
c.runtime.getMaterialShaderPipelineEntry?.(
|
|
554
549
|
smShaderId,
|
|
@@ -722,12 +717,10 @@ function recordSpriteEntityDraws(
|
|
|
722
717
|
spritePass.setVertexBuffer(0, spriteEntry.mesh.vertexBuffer.handle);
|
|
723
718
|
lastSpriteVertexBuffer = spriteEntry.mesh.vertexBuffer;
|
|
724
719
|
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
spriteEntry.mesh.
|
|
728
|
-
|
|
729
|
-
spritePass.setIndexBuffer(spriteEntry.mesh.indexBuffer.handle, spriteEntry.mesh.indexFormat);
|
|
730
|
-
lastSpriteIndexBuffer = spriteEntry.mesh.indexBuffer;
|
|
720
|
+
const indexBuffer = spriteEntry.mesh.indexBuffer;
|
|
721
|
+
if (indexBuffer !== null && indexBuffer !== lastSpriteIndexBuffer) {
|
|
722
|
+
spritePass.setIndexBuffer(indexBuffer.handle, spriteEntry.mesh.indexFormat);
|
|
723
|
+
lastSpriteIndexBuffer = indexBuffer;
|
|
731
724
|
}
|
|
732
725
|
|
|
733
726
|
// Instance buffer resolution: same cap-gate logic as the geometry
|
|
@@ -837,21 +830,15 @@ function recordSpriteEntityDraws(
|
|
|
837
830
|
);
|
|
838
831
|
spriteInstanceCount = spriteInst.instanceCount;
|
|
839
832
|
spriteInstanceBuffer = pipelineState.identityInstanceBuffer;
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
},
|
|
850
|
-
},
|
|
851
|
-
],
|
|
852
|
-
});
|
|
853
|
-
if (!spriteInstBgResult.ok) throw spriteInstBgResult.error;
|
|
854
|
-
spritePass.setBindGroup(3, spriteInstBgResult.value as BindGroup);
|
|
833
|
+
// Sprite shaders do not declare the Standard PBR Probe ABI. A
|
|
834
|
+
// retained scene record must therefore not change their group(3)
|
|
835
|
+
// bind-group shape.
|
|
836
|
+
const spriteInstBg = resolveGeometryInstancesBindGroup(
|
|
837
|
+
c,
|
|
838
|
+
spriteInstanceBuffer,
|
|
839
|
+
undefined,
|
|
840
|
+
);
|
|
841
|
+
spritePass.setBindGroup(3, spriteInstBg);
|
|
855
842
|
spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);
|
|
856
843
|
continue;
|
|
857
844
|
}
|
|
@@ -959,35 +946,15 @@ function recordSpriteEntityDraws(
|
|
|
959
946
|
? c.hdrpClusterBindGroup
|
|
960
947
|
: meshBindGroup;
|
|
961
948
|
|
|
962
|
-
// M3 / w12: LDR sprite split pass per-entity instances BG cache.
|
|
963
|
-
//
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
worldEntityKey(spriteEntry.source.worldId, spriteEntry.source.entityKey),
|
|
967
|
-
[spriteInstanceBuffer],
|
|
968
|
-
'instances',
|
|
969
|
-
() => {
|
|
970
|
-
const result = runtime.device.createBindGroup({
|
|
971
|
-
label: 'sprite-pass-instances-bg',
|
|
972
|
-
layout: pipelineState.instancesBindGroupLayout,
|
|
973
|
-
entries: [
|
|
974
|
-
{
|
|
975
|
-
binding: 0,
|
|
976
|
-
resource: {
|
|
977
|
-
kind: 'buffer',
|
|
978
|
-
value: { buffer: spriteInstanceBuffer },
|
|
979
|
-
},
|
|
980
|
-
},
|
|
981
|
-
],
|
|
982
|
-
});
|
|
983
|
-
if (!result.ok) throw result.error;
|
|
984
|
-
return result.value;
|
|
985
|
-
},
|
|
986
|
-
bindGroupCounts,
|
|
987
|
-
);
|
|
949
|
+
// M3 / w12: LDR sprite split pass per-entity instances BG cache. Sprite
|
|
950
|
+
// shaders do not declare the Standard PBR Probe ABI, so retained probe
|
|
951
|
+
// records stay out of this bind-group path.
|
|
952
|
+
const spriteInstancesBg = resolveGeometryInstancesBindGroup(c, spriteInstanceBuffer, undefined);
|
|
988
953
|
|
|
989
954
|
spritePass.setBindGroup(2, spriteGroup2 as BindGroup, [i * MESH_PER_ENTITY_STRIDE]);
|
|
990
955
|
|
|
956
|
+
const materialSlot = materialSlotIndices[i]?.[0] ?? 0;
|
|
957
|
+
|
|
991
958
|
// Per-entity sprite material bind group: same standard PBR user-region
|
|
992
959
|
// layout as in the geometry pass sprite branch + Skylight merged entries
|
|
993
960
|
// the geometry pass sprite branch + Skylight merged entries (same
|
|
@@ -1032,7 +999,6 @@ function recordSpriteEntityDraws(
|
|
|
1032
999
|
bindGroupCounts,
|
|
1033
1000
|
);
|
|
1034
1001
|
|
|
1035
|
-
const materialSlot = materialSlotIndices[i]?.[0] ?? 0;
|
|
1036
1002
|
spritePass.setBindGroup(1, spritePassBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);
|
|
1037
1003
|
spritePass.setBindGroup(3, spriteInstancesBg);
|
|
1038
1004
|
spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);
|
package/src/record/main-pass.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type { ReflectionProbeSelectionResult } from '../reflection/projection';
|
|
|
16
16
|
import type { RenderRecordPhase } from '../render-contract';
|
|
17
17
|
import type { MaterialSnapshot } from '../render-system-extract';
|
|
18
18
|
import { resolveReflectionProbeBinding } from './frame-lighting';
|
|
19
|
+
import { getOpaqueResourceIdentity } from './frame-snapshot';
|
|
19
20
|
import { recordGeometryDraws } from './main-pass-geometry';
|
|
20
21
|
import {
|
|
21
22
|
applyMaterialTextureUvScales,
|
|
@@ -42,6 +43,18 @@ export function standardReflectionProbeIndex(
|
|
|
42
43
|
|
|
43
44
|
const ZERO_SKYLIGHT_PAYLOAD = new Float32Array([0, 0, 0, 0, 0, 0, 0, 1]);
|
|
44
45
|
|
|
46
|
+
function materialDiagnosticsEnabled(): boolean {
|
|
47
|
+
if (typeof globalThis !== 'object' || globalThis === null || !('process' in globalThis)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const processValue = (
|
|
51
|
+
globalThis as {
|
|
52
|
+
readonly process?: { readonly env?: Record<string, string | undefined> };
|
|
53
|
+
}
|
|
54
|
+
).process;
|
|
55
|
+
return processValue?.env?.FORGEAX_MATERIAL_DIAGNOSTICS === '1';
|
|
56
|
+
}
|
|
57
|
+
|
|
45
58
|
export type MainPassOptions = {
|
|
46
59
|
readonly colorViews?: readonly (TextureView | null)[];
|
|
47
60
|
readonly colorFormats?: readonly GPUTextureFormat[];
|
|
@@ -52,8 +65,6 @@ export type MainPassOptions = {
|
|
|
52
65
|
readonly transmissionBackdropView?: TextureView | null;
|
|
53
66
|
};
|
|
54
67
|
|
|
55
|
-
const TRANSMISSION_VARIANT_SET = 'TRANSMISSION_AVAILABLE=true';
|
|
56
|
-
|
|
57
68
|
function isTransmissionMaterial(material: MaterialSnapshot): boolean {
|
|
58
69
|
return (
|
|
59
70
|
material.materialShaderId === 'forgeax::default-standard-pbr' &&
|
|
@@ -284,10 +295,6 @@ export function recordMainPass(
|
|
|
284
295
|
: {
|
|
285
296
|
...c,
|
|
286
297
|
splitLdrSprite: recordMode === 'transparent' ? false : c.splitLdrSprite,
|
|
287
|
-
validatedOrdered: c.validatedOrdered.map((entry) => ({
|
|
288
|
-
...entry,
|
|
289
|
-
...(recordMode === 'transmission' ? { variantSet: TRANSMISSION_VARIANT_SET } : {}),
|
|
290
|
-
})),
|
|
291
298
|
};
|
|
292
299
|
|
|
293
300
|
if (clusteredBindGroupMissing) {
|
|
@@ -420,6 +427,64 @@ export function recordMainPass(
|
|
|
420
427
|
brdfLutSampler: skylightFallback.sampler,
|
|
421
428
|
intensityBuffer: skylightFallback.intensityBuffer,
|
|
422
429
|
};
|
|
430
|
+
if (materialDiagnosticsEnabled()) {
|
|
431
|
+
const activeCache =
|
|
432
|
+
activeViews === undefined ? undefined : getOrCreateIblCache(runtime.deviceScope);
|
|
433
|
+
const prefilterViewMipCount =
|
|
434
|
+
activeCache?.prefilterFaceViewsByMip?.length ?? (activeViews === undefined ? 1 : 0);
|
|
435
|
+
frameState.iblBindingInspection = {
|
|
436
|
+
status: 'binding-chain-consistent',
|
|
437
|
+
frameId: frameState.frameNumber,
|
|
438
|
+
deviceGeneration: runtime.deviceScope.generation,
|
|
439
|
+
active: activeViews === undefined ? 'fallback' : 'active',
|
|
440
|
+
cache: {
|
|
441
|
+
identity: getOpaqueResourceIdentity((activeCache ?? skylightFallback) as object),
|
|
442
|
+
generation: runtime.deviceScope.generation,
|
|
443
|
+
prefilterMipCount: prefilterViewMipCount,
|
|
444
|
+
prefilterViewMipCount,
|
|
445
|
+
},
|
|
446
|
+
sampler: {
|
|
447
|
+
expected: {
|
|
448
|
+
magFilter: 'linear',
|
|
449
|
+
minFilter: 'linear',
|
|
450
|
+
mipmapFilter: 'linear',
|
|
451
|
+
addressModeU: 'clamp-to-edge',
|
|
452
|
+
addressModeV: 'clamp-to-edge',
|
|
453
|
+
addressModeW: 'clamp-to-edge',
|
|
454
|
+
},
|
|
455
|
+
identities: [
|
|
456
|
+
getOpaqueResourceIdentity(skylightResources.irradianceSampler as object),
|
|
457
|
+
getOpaqueResourceIdentity(skylightResources.prefilterSampler as object),
|
|
458
|
+
getOpaqueResourceIdentity(skylightResources.brdfLutSampler as object),
|
|
459
|
+
],
|
|
460
|
+
},
|
|
461
|
+
resources: {
|
|
462
|
+
irradiance: {
|
|
463
|
+
viewIdentity: getOpaqueResourceIdentity(skylightResources.irradianceView as object),
|
|
464
|
+
samplerIdentity: getOpaqueResourceIdentity(
|
|
465
|
+
skylightResources.irradianceSampler as object,
|
|
466
|
+
),
|
|
467
|
+
deviceGeneration: runtime.deviceScope.generation,
|
|
468
|
+
},
|
|
469
|
+
prefilter: {
|
|
470
|
+
viewIdentity: getOpaqueResourceIdentity(skylightResources.prefilterView as object),
|
|
471
|
+
samplerIdentity: getOpaqueResourceIdentity(
|
|
472
|
+
skylightResources.prefilterSampler as object,
|
|
473
|
+
),
|
|
474
|
+
deviceGeneration: runtime.deviceScope.generation,
|
|
475
|
+
},
|
|
476
|
+
brdfLut: {
|
|
477
|
+
viewIdentity: getOpaqueResourceIdentity(skylightResources.brdfLutView as object),
|
|
478
|
+
samplerIdentity: getOpaqueResourceIdentity(skylightResources.brdfLutSampler as object),
|
|
479
|
+
deviceGeneration: runtime.deviceScope.generation,
|
|
480
|
+
},
|
|
481
|
+
intensityBufferIdentity: getOpaqueResourceIdentity(
|
|
482
|
+
skylightResources.intensityBuffer as object,
|
|
483
|
+
),
|
|
484
|
+
},
|
|
485
|
+
errors: [],
|
|
486
|
+
};
|
|
487
|
+
}
|
|
423
488
|
// Per-entity material uploads (D-P9 retained path).
|
|
424
489
|
// feat-20260613 fix-issue-1 (D-8 channelMap split): the payload mirrors
|
|
425
490
|
// the post-split sidecar paramSchema for default-standard-pbr (14 entries
|
|
@@ -490,6 +555,7 @@ export function recordMainPass(
|
|
|
490
555
|
},
|
|
491
556
|
materialBgShared: frameState.materialBgShared,
|
|
492
557
|
materialBgAssemblyCache: c.materialBgAssemblyCache,
|
|
558
|
+
frameState,
|
|
493
559
|
bindGroupCounts,
|
|
494
560
|
...(transmissionBackdropView === undefined ? {} : { transmissionBackdropView }),
|
|
495
561
|
};
|
|
@@ -551,6 +617,28 @@ export function recordMainPass(
|
|
|
551
617
|
mat.materialParamSchema ??
|
|
552
618
|
(materialShaderId !== undefined ? runtime.getParamSchema?.(materialShaderId) : undefined);
|
|
553
619
|
applyParamSnapshotToUbo(slotPayloadF32, schema, mat.paramSnapshot);
|
|
620
|
+
const processValue = (
|
|
621
|
+
globalThis as {
|
|
622
|
+
process?: { env?: Record<string, string | undefined> };
|
|
623
|
+
}
|
|
624
|
+
).process;
|
|
625
|
+
if (
|
|
626
|
+
processValue?.env?.FORGEAX_MATERIAL_PIPELINE_DIAGNOSTICS === '1' &&
|
|
627
|
+
(materialShaderId === 'forgeax::default-standard-pbr' ||
|
|
628
|
+
materialShaderId === 'forgeax::pbr-skin')
|
|
629
|
+
) {
|
|
630
|
+
console.error(
|
|
631
|
+
`[render-material] UBO receipt: ${JSON.stringify({
|
|
632
|
+
entityIndex: entry.renderableIndex,
|
|
633
|
+
materialHandle: mat.materialHandle,
|
|
634
|
+
materialShaderId,
|
|
635
|
+
clearcoat: slotPayloadF32[32],
|
|
636
|
+
clearcoatRoughness: slotPayloadF32[33],
|
|
637
|
+
clearcoatNormalScale: slotPayloadF32[34],
|
|
638
|
+
paramSnapshot: mat.paramSnapshot,
|
|
639
|
+
})}`,
|
|
640
|
+
);
|
|
641
|
+
}
|
|
554
642
|
applyMaterialTextureUvScales(slotPayloadF32, mat, world);
|
|
555
643
|
// Missing-texture detection: structural debug-pink fallback overrides
|
|
556
644
|
// the baseColor/colorTint slot when a bound baseColorTexture handle
|
package/src/record/mesh-ssbo.ts
CHANGED
|
@@ -79,12 +79,18 @@ export function extractEntryResourceHandle(entry: {
|
|
|
79
79
|
return v as object;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// Object-only terminal marker keeps a shorter resource chain from colliding
|
|
83
|
+
// with a longer chain that shares the same prefix.
|
|
84
|
+
const BIND_GROUP_CHAIN_LEAF_KEY: object = {};
|
|
85
|
+
|
|
82
86
|
/**
|
|
83
87
|
* feat-20260622-handle-to-id-allocator-elimination M2 / w7: walks a nested
|
|
84
88
|
* WeakMap chain to find or create a BindGroup leaf. Each handle in the
|
|
85
|
-
* `handles` array is a chain node;
|
|
86
|
-
* keyed by `variant` (D-2).
|
|
87
|
-
*
|
|
89
|
+
* `handles` array is a chain node; a dedicated object terminal marker points
|
|
90
|
+
* to the final Map<string, BindGroup> keyed by `variant` (D-2). The marker
|
|
91
|
+
* prevents variable-depth chains with a shared prefix from treating a nested
|
|
92
|
+
* WeakMap as a leaf. Chain keys are always object references, never numeric
|
|
93
|
+
* ids — GC reclaims entries for dead handles automatically.
|
|
88
94
|
*
|
|
89
95
|
* On cache hit returns the cached BindGroup. On miss calls `factory`,
|
|
90
96
|
* bumps `bindGroupCounts.createBindGroup`, stores the result at the leaf,
|
|
@@ -99,9 +105,7 @@ export function getOrCreateFromChain(
|
|
|
99
105
|
counts: { createBindGroup: number; keys: string[] },
|
|
100
106
|
): BindGroup {
|
|
101
107
|
let node = root;
|
|
102
|
-
for (
|
|
103
|
-
// biome-ignore lint/style/noNonNullAssertion: handles length guards the index
|
|
104
|
-
const h = handles[i]!;
|
|
108
|
+
for (const h of handles) {
|
|
105
109
|
let next = node.get(h) as WeakMap<object, unknown> | undefined;
|
|
106
110
|
if (next === undefined) {
|
|
107
111
|
next = new WeakMap();
|
|
@@ -109,12 +113,10 @@ export function getOrCreateFromChain(
|
|
|
109
113
|
}
|
|
110
114
|
node = next;
|
|
111
115
|
}
|
|
112
|
-
|
|
113
|
-
const last = handles[handles.length - 1]!;
|
|
114
|
-
let leaf = node.get(last) as Map<string, BindGroup> | undefined;
|
|
116
|
+
let leaf = node.get(BIND_GROUP_CHAIN_LEAF_KEY) as Map<string, BindGroup> | undefined;
|
|
115
117
|
if (leaf === undefined) {
|
|
116
118
|
leaf = new Map();
|
|
117
|
-
node.set(
|
|
119
|
+
node.set(BIND_GROUP_CHAIN_LEAF_KEY, leaf);
|
|
118
120
|
}
|
|
119
121
|
const hit = leaf.get(variant);
|
|
120
122
|
if (hit !== undefined) return hit;
|
|
@@ -125,6 +127,26 @@ export function getOrCreateFromChain(
|
|
|
125
127
|
return bg;
|
|
126
128
|
}
|
|
127
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Read a cached bind group using the same variable-depth chain contract as
|
|
132
|
+
* `getOrCreateFromChain`. Readers must traverse the terminal marker instead
|
|
133
|
+
* of assuming that the last handle directly stores the variant map.
|
|
134
|
+
*/
|
|
135
|
+
export function findFromChain(
|
|
136
|
+
root: WeakMap<object, unknown>,
|
|
137
|
+
handles: readonly object[],
|
|
138
|
+
variant: string,
|
|
139
|
+
): BindGroup | undefined {
|
|
140
|
+
let node = root;
|
|
141
|
+
for (const handle of handles) {
|
|
142
|
+
const next = node.get(handle);
|
|
143
|
+
if (next === undefined) return undefined;
|
|
144
|
+
node = next as WeakMap<object, unknown>;
|
|
145
|
+
}
|
|
146
|
+
const leaf = node.get(BIND_GROUP_CHAIN_LEAF_KEY) as Map<string, BindGroup> | undefined;
|
|
147
|
+
return leaf?.get(variant);
|
|
148
|
+
}
|
|
149
|
+
|
|
128
150
|
/**
|
|
129
151
|
* feat-20260622-handle-to-id-allocator-elimination M2 / w8: per-entity bind
|
|
130
152
|
* group lookup-or-create helper (D-2). Two-step lookup: outer Map.get(outerKey)
|
|
@@ -325,6 +347,8 @@ export function isMeshSsboDevMode(): boolean {
|
|
|
325
347
|
* @internal
|
|
326
348
|
*/
|
|
327
349
|
let _meshSsboScratch = new Uint8Array(0);
|
|
350
|
+
/** @internal */
|
|
351
|
+
let _meshSsboScratchFloats = new Float32Array(0);
|
|
328
352
|
|
|
329
353
|
/**
|
|
330
354
|
* feat-20260704 M3/w21: per-renderable `entity_world` upload (batched). All N
|
|
@@ -358,60 +382,69 @@ export function uploadMeshSsboBatch(
|
|
|
358
382
|
// Grow the module-scoped scratch monotonically; zero the used range.
|
|
359
383
|
if (_meshSsboScratch.length < neededBytes) {
|
|
360
384
|
_meshSsboScratch = new Uint8Array(neededBytes);
|
|
385
|
+
_meshSsboScratchFloats = new Float32Array(_meshSsboScratch.buffer);
|
|
361
386
|
} else {
|
|
362
387
|
_meshSsboScratch.fill(0, 0, neededBytes);
|
|
363
388
|
}
|
|
364
389
|
const normalMatrixScratch = mat3.create();
|
|
390
|
+
const strideFloats = MESH_PER_ENTITY_STRIDE / Float32Array.BYTES_PER_ELEMENT;
|
|
365
391
|
for (let i = 0; i < slotCount; i++) {
|
|
366
392
|
const entry = validatedOrdered[i];
|
|
367
393
|
if (entry === undefined) continue;
|
|
368
|
-
//
|
|
369
|
-
//
|
|
370
|
-
//
|
|
371
|
-
|
|
372
|
-
const slot = new Float32Array(_meshSsboScratch.buffer, i * MESH_PER_ENTITY_STRIDE, 48);
|
|
394
|
+
// Address the reusable flat view directly. Constructing one typed-array
|
|
395
|
+
// wrapper per visible entity made this otherwise contiguous upload create
|
|
396
|
+
// tens of thousands of short-lived JS objects every frame.
|
|
397
|
+
const slot = i * strideFloats;
|
|
373
398
|
const isFoldHead = foldDispatchPlan?.headBuckets.has(i) === true;
|
|
374
399
|
if (isFoldHead) {
|
|
375
400
|
// identity mat4
|
|
376
|
-
slot
|
|
377
|
-
slot
|
|
378
|
-
slot
|
|
379
|
-
slot
|
|
401
|
+
_meshSsboScratchFloats[slot] = 1;
|
|
402
|
+
_meshSsboScratchFloats[slot + 5] = 1;
|
|
403
|
+
_meshSsboScratchFloats[slot + 10] = 1;
|
|
404
|
+
_meshSsboScratchFloats[slot + 15] = 1;
|
|
380
405
|
// identity mat3 normal (cols at slot offsets 16/20/24)
|
|
381
|
-
slot
|
|
382
|
-
slot
|
|
383
|
-
slot
|
|
406
|
+
_meshSsboScratchFloats[slot + 16] = 1;
|
|
407
|
+
_meshSsboScratchFloats[slot + 20] = 1;
|
|
408
|
+
_meshSsboScratchFloats[slot + 24] = 1;
|
|
384
409
|
// Fold heads use the instance storage path; keep the mesh temporal
|
|
385
410
|
// fields deterministic for shader variants that still read the slot.
|
|
386
|
-
slot
|
|
387
|
-
slot
|
|
388
|
-
slot
|
|
389
|
-
slot
|
|
390
|
-
slot
|
|
411
|
+
_meshSsboScratchFloats[slot + 28] = 1;
|
|
412
|
+
_meshSsboScratchFloats[slot + 33] = 1;
|
|
413
|
+
_meshSsboScratchFloats[slot + 38] = 1;
|
|
414
|
+
_meshSsboScratchFloats[slot + 43] = 1;
|
|
415
|
+
_meshSsboScratchFloats[slot + 44] = 1;
|
|
391
416
|
} else {
|
|
392
417
|
const worldFromLocal = entry.source.transform.world;
|
|
393
|
-
for (let k = 0; k < 16; k++) slot
|
|
418
|
+
for (let k = 0; k < 16; k++) _meshSsboScratchFloats[slot + k] = worldFromLocal[k] ?? 0;
|
|
394
419
|
const normal = mat3.normalMatrix(normalMatrixScratch, worldFromLocal);
|
|
395
|
-
slot
|
|
396
|
-
slot
|
|
397
|
-
slot
|
|
398
|
-
slot
|
|
399
|
-
slot
|
|
400
|
-
slot
|
|
401
|
-
slot
|
|
402
|
-
slot
|
|
403
|
-
slot
|
|
420
|
+
_meshSsboScratchFloats[slot + 16] = normal[0] ?? 0;
|
|
421
|
+
_meshSsboScratchFloats[slot + 17] = normal[1] ?? 0;
|
|
422
|
+
_meshSsboScratchFloats[slot + 18] = normal[2] ?? 0;
|
|
423
|
+
_meshSsboScratchFloats[slot + 20] = normal[3] ?? 0;
|
|
424
|
+
_meshSsboScratchFloats[slot + 21] = normal[4] ?? 0;
|
|
425
|
+
_meshSsboScratchFloats[slot + 22] = normal[5] ?? 0;
|
|
426
|
+
_meshSsboScratchFloats[slot + 24] = normal[6] ?? 0;
|
|
427
|
+
_meshSsboScratchFloats[slot + 25] = normal[7] ?? 0;
|
|
428
|
+
_meshSsboScratchFloats[slot + 26] = normal[8] ?? 0;
|
|
404
429
|
const previousWorld = entry.source.temporal?.previousTransform.world ?? worldFromLocal;
|
|
405
|
-
for (let k = 0; k < 16; k++)
|
|
406
|
-
|
|
407
|
-
|
|
430
|
+
for (let k = 0; k < 16; k++) {
|
|
431
|
+
_meshSsboScratchFloats[slot + 28 + k] = previousWorld[k] ?? 0;
|
|
432
|
+
}
|
|
433
|
+
let reactiveMaterial = false;
|
|
434
|
+
for (const material of entry.source.materials) {
|
|
435
|
+
const shader = material.materialShaderId;
|
|
436
|
+
if (
|
|
408
437
|
material.transparent === true ||
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
438
|
+
shader === 'forgeax::sprite' ||
|
|
439
|
+
shader === 'forgeax::sprite-lit' ||
|
|
440
|
+
(shader !== undefined && !shader.startsWith('forgeax::'))
|
|
441
|
+
) {
|
|
442
|
+
reactiveMaterial = true;
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
_meshSsboScratchFloats[slot + 44] =
|
|
447
|
+
entry.source.temporal?.reactive === true || reactiveMaterial ? 1 : 0;
|
|
415
448
|
}
|
|
416
449
|
}
|
|
417
450
|
if (neededBytes > 0) {
|