@forgeax/engine-render 0.0.0-dev.8d955ade1c79
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/LICENSE +202 -0
- package/README.md +647 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__tests__/authoring-path.unit.test.d.ts +2 -0
- package/dist/__tests__/authoring-path.unit.test.d.ts.map +1 -0
- package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts +2 -0
- package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts.map +1 -0
- package/dist/__tests__/callback-inference.test-d.d.ts +2 -0
- package/dist/__tests__/callback-inference.test-d.d.ts.map +1 -0
- package/dist/__tests__/cluster-binner.test.d.ts +2 -0
- package/dist/__tests__/cluster-binner.test.d.ts.map +1 -0
- package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/construct-renderer-identity.unit.test.d.ts +2 -0
- package/dist/__tests__/construct-renderer-identity.unit.test.d.ts.map +1 -0
- package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts +2 -0
- package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts +2 -0
- package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts.map +1 -0
- package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts +2 -0
- package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/direct-light-snapshot.unit.test.d.ts +2 -0
- package/dist/__tests__/direct-light-snapshot.unit.test.d.ts.map +1 -0
- package/dist/__tests__/factory-contract.integration.test.d.ts +2 -0
- package/dist/__tests__/factory-contract.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/frame-observation.contract.test.d.ts +2 -0
- package/dist/__tests__/frame-observation.contract.test.d.ts.map +1 -0
- package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts +2 -0
- package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts +6 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-production.integration.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-production.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +18 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-reference.d.ts +15 -0
- package/dist/__tests__/gpu-driven-view-reference.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts +7 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-schema.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-schema.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts +2 -0
- package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts.map +1 -0
- package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts +2 -0
- package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts.map +1 -0
- package/dist/__tests__/injection-kind-owner.test-d.d.ts +2 -0
- package/dist/__tests__/injection-kind-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts +2 -0
- package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/light-buffer-layout.unit.test.d.ts +2 -0
- package/dist/__tests__/light-buffer-layout.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-contract-inventory.unit.test.d.ts +2 -0
- package/dist/__tests__/material-contract-inventory.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-cooked-projection.unit.test.d.ts +2 -0
- package/dist/__tests__/material-cooked-projection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts +2 -0
- package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts.map +1 -0
- package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts +2 -0
- package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/material-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-material-bindings.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-material-bindings.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts +2 -0
- package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts +2 -0
- package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts.map +1 -0
- package/dist/__tests__/morph-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/morph-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/morph-visual-evidence.integration.test.d.ts +2 -0
- package/dist/__tests__/morph-visual-evidence.integration.test.d.ts.map +1 -0
- package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts +2 -0
- package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-store.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-default-off.test.d.ts +2 -0
- package/dist/__tests__/profiler-default-off.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-catalog.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-catalog.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-integration.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-integration.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-token.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-token.test.d.ts.map +1 -0
- package/dist/__tests__/public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-error-code-owner.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-code-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-error-detail-ssot.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-detail-ssot.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-assembly.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-assembly.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-context.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-context.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-contract.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-docs.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-docs.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-errors.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-errors.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts +2 -0
- package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-plan.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-plan.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-retry.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-retry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-scheduling.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-scheduling.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-visibility-context.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-visibility-context.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-zero-work.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-zero-work.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster-gpu.d.ts +7 -0
- package/dist/__tests__/render-graph-compute-raster-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb-gpu.d.ts +7 -0
- package/dist/__tests__/render-graph-hzb-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-hzb.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-hzb.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-primitives.unit.test.d.ts +2 -0
- package/dist/__tests__/render-graph-primitives.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts +12 -0
- package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-scene-projection.unit.test.d.ts +2 -0
- package/dist/__tests__/render-scene-projection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-lifecycle.integration.test.d.ts +2 -0
- package/dist/__tests__/renderer-lifecycle.integration.test.d.ts.map +1 -0
- package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts +2 -0
- package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts.map +1 -0
- package/dist/__tests__/shader-stage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/shader-stage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ssao-config.unit.test.d.ts +2 -0
- package/dist/__tests__/ssao-config.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/standard-descriptors.test-d.d.ts +2 -0
- package/dist/__tests__/standard-descriptors.test-d.d.ts.map +1 -0
- package/dist/__tests__/standard-pipeline.dawn.test.d.ts +2 -0
- package/dist/__tests__/standard-pipeline.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/standard-pipeline.integration.test.d.ts +2 -0
- package/dist/__tests__/standard-pipeline.integration.test.d.ts.map +1 -0
- package/dist/__tests__/standard-profile-oracle.unit.test.d.ts +2 -0
- package/dist/__tests__/standard-profile-oracle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/surface-configuration.unit.test.d.ts +2 -0
- package/dist/__tests__/surface-configuration.unit.test.d.ts.map +1 -0
- package/dist/__tests__/texture-usage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/texture-usage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts +2 -0
- package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts.map +1 -0
- package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts +2 -0
- package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts.map +1 -0
- package/dist/__tests__/urp-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/urp-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts +2 -0
- package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-diagnostics.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-diagnostics.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-extract.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-extract.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-extract.perf.test.d.ts +2 -0
- package/dist/__tests__/visibility-extract.perf.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-hidden-report.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-hidden-report.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-instances.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-instances.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-multi-world.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-multi-world.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/visibility-public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/visibility-resolver.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-resolver.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vocabulary.unit.test.d.ts +2 -0
- package/dist/__tests__/vocabulary.unit.test.d.ts.map +1 -0
- package/dist/assembly/backend-contract.d.ts +37 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +207 -0
- package/dist/assembly/factory.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +84 -0
- package/dist/assembly/host-contract.d.ts.map +1 -0
- package/dist/assembly/material/assembly.d.ts +21 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -0
- package/dist/assembly/material/pipeline-projection.d.ts +30 -0
- package/dist/assembly/material/pipeline-projection.d.ts.map +1 -0
- package/dist/assets/asset-decoders.d.ts +5 -0
- package/dist/assets/asset-decoders.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts +17 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -0
- package/dist/assets/resolve-render-asset.d.ts +6 -0
- package/dist/assets/resolve-render-asset.d.ts.map +1 -0
- package/dist/authoring.d.ts +12 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.mjs +27 -0
- package/dist/authoring.mjs.map +1 -0
- package/dist/chunk-CQXZC5XI.mjs +182 -0
- package/dist/chunk-CQXZC5XI.mjs.map +1 -0
- package/dist/chunk-HCOGPHKS.mjs +93 -0
- package/dist/chunk-HCOGPHKS.mjs.map +1 -0
- package/dist/chunk-YEJIUW7D.mjs +1152 -0
- package/dist/chunk-YEJIUW7D.mjs.map +1 -0
- package/dist/cluster-binner.d.ts +152 -0
- package/dist/cluster-binner.d.ts.map +1 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/schema-contract.unit.test.d.ts +2 -0
- package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/schema-parity.unit.test.d.ts +2 -0
- package/dist/components/__tests__/schema-parity.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/visibility-schema.unit.test.d.ts +2 -0
- package/dist/components/__tests__/visibility-schema.unit.test.d.ts.map +1 -0
- package/dist/components/camera.d.ts +311 -0
- package/dist/components/camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +76 -0
- package/dist/components/directional-light.d.ts.map +1 -0
- package/dist/components/glyph-text.d.ts +26 -0
- package/dist/components/glyph-text.d.ts.map +1 -0
- package/dist/components/index.d.ts +24 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/instances.d.ts +41 -0
- package/dist/components/instances.d.ts.map +1 -0
- package/dist/components/layer.d.ts +34 -0
- package/dist/components/layer.d.ts.map +1 -0
- package/dist/components/light-helpers.d.ts +53 -0
- package/dist/components/light-helpers.d.ts.map +1 -0
- package/dist/components/lines.d.ts +5 -0
- package/dist/components/lines.d.ts.map +1 -0
- package/dist/components/mesh-filter.d.ts +24 -0
- package/dist/components/mesh-filter.d.ts.map +1 -0
- package/dist/components/mesh-renderer.d.ts +33 -0
- package/dist/components/mesh-renderer.d.ts.map +1 -0
- package/dist/components/point-light-shadow.d.ts +27 -0
- package/dist/components/point-light-shadow.d.ts.map +1 -0
- package/dist/components/point-light.d.ts +35 -0
- package/dist/components/point-light.d.ts.map +1 -0
- package/dist/components/points.d.ts +15 -0
- package/dist/components/points.d.ts.map +1 -0
- package/dist/components/post-process-params.d.ts +5 -0
- package/dist/components/post-process-params.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +140 -0
- package/dist/components/scene-instance.d.ts.map +1 -0
- package/dist/components/skybox-background.d.ts +56 -0
- package/dist/components/skybox-background.d.ts.map +1 -0
- package/dist/components/skylight.d.ts +55 -0
- package/dist/components/skylight.d.ts.map +1 -0
- package/dist/components/sort-key.d.ts +44 -0
- package/dist/components/sort-key.d.ts.map +1 -0
- package/dist/components/spot-light.d.ts +81 -0
- package/dist/components/spot-light.d.ts.map +1 -0
- package/dist/components/sprite-animation.d.ts +74 -0
- package/dist/components/sprite-animation.d.ts.map +1 -0
- package/dist/components/sprite-instances.d.ts +51 -0
- package/dist/components/sprite-instances.d.ts.map +1 -0
- package/dist/components/sprite-playback-mode.d.ts +42 -0
- package/dist/components/sprite-playback-mode.d.ts.map +1 -0
- package/dist/components/sprite-region-override.d.ts +46 -0
- package/dist/components/sprite-region-override.d.ts.map +1 -0
- package/dist/components/tile-layer.d.ts +106 -0
- package/dist/components/tile-layer.d.ts.map +1 -0
- package/dist/components/tilemap.d.ts +25 -0
- package/dist/components/tilemap.d.ts.map +1 -0
- package/dist/components/visibility.d.ts +22 -0
- package/dist/components/visibility.d.ts.map +1 -0
- package/dist/construct-renderer.d.ts +19 -0
- package/dist/construct-renderer.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +27462 -0
- package/dist/construct-renderer.mjs.map +1 -0
- package/dist/debug-draw-glue.d.ts +5 -0
- package/dist/debug-draw-glue.d.ts.map +1 -0
- package/dist/device/device-scope.d.ts +83 -0
- package/dist/device/device-scope.d.ts.map +1 -0
- package/dist/device/gpu-residency.d.ts +337 -0
- package/dist/device/gpu-residency.d.ts.map +1 -0
- package/dist/device/resource-types.d.ts +8 -0
- package/dist/device/resource-types.d.ts.map +1 -0
- package/dist/engine-metrics.d.ts +23 -0
- package/dist/engine-metrics.d.ts.map +1 -0
- package/dist/errors/ecs-validation.d.ts +3 -0
- package/dist/errors/ecs-validation.d.ts.map +1 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/recover.d.ts +105 -0
- package/dist/errors/recover.d.ts.map +1 -0
- package/dist/errors/render.d.ts +705 -0
- package/dist/errors/render.d.ts.map +1 -0
- package/dist/extract/visibility.d.ts +26 -0
- package/dist/extract/visibility.d.ts.map +1 -0
- package/dist/features/fullscreen.d.ts +19 -0
- package/dist/features/fullscreen.d.ts.map +1 -0
- package/dist/features/host.d.ts +106 -0
- package/dist/features/host.d.ts.map +1 -0
- package/dist/features/morph/morph-feature.d.ts +79 -0
- package/dist/features/morph/morph-feature.d.ts.map +1 -0
- package/dist/features/plan.d.ts +182 -0
- package/dist/features/plan.d.ts.map +1 -0
- package/dist/features/prepared-gpu-work.d.ts +117 -0
- package/dist/features/prepared-gpu-work.d.ts.map +1 -0
- package/dist/features/prepared-graphics-store.d.ts +66 -0
- package/dist/features/prepared-graphics-store.d.ts.map +1 -0
- package/dist/features/prepared-graphics.d.ts +215 -0
- package/dist/features/prepared-graphics.d.ts.map +1 -0
- package/dist/features/render-graph-compute.d.ts +13 -0
- package/dist/features/render-graph-compute.d.ts.map +1 -0
- package/dist/features/render-graph-contribution.d.ts +12 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -0
- package/dist/features/render-graph-raster.d.ts +38 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -0
- package/dist/features/render-graph-resources.d.ts +11 -0
- package/dist/features/render-graph-resources.d.ts.map +1 -0
- package/dist/features/targets.d.ts +32 -0
- package/dist/features/targets.d.ts.map +1 -0
- package/dist/features/types.d.ts +68 -0
- package/dist/features/types.d.ts.map +1 -0
- package/dist/features/vocabulary.d.ts +14 -0
- package/dist/features/vocabulary.d.ts.map +1 -0
- package/dist/fullscreen-post-process-pass.d.ts +157 -0
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -0
- package/dist/glyph-text-layout-system.d.ts +19 -0
- package/dist/glyph-text-layout-system.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +55 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +51 -0
- package/dist/gpu-driven/production-raster.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +85 -0
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -0
- package/dist/gpu-resource.d.ts +73 -0
- package/dist/gpu-resource.d.ts.map +1 -0
- package/dist/gpu-scene-schema.d.ts +78 -0
- package/dist/gpu-scene-schema.d.ts.map +1 -0
- package/dist/gpu-scene.d.ts +55 -0
- package/dist/gpu-scene.d.ts.map +1 -0
- package/dist/gpu-stage.d.ts +4 -0
- package/dist/gpu-stage.d.ts.map +1 -0
- package/dist/gpu-texture-usage.d.ts +6 -0
- package/dist/gpu-texture-usage.d.ts.map +1 -0
- package/dist/gpu-usage.d.ts +9 -0
- package/dist/gpu-usage.d.ts.map +1 -0
- package/dist/hdrp-buffers.d.ts +163 -0
- package/dist/hdrp-buffers.d.ts.map +1 -0
- package/dist/ibl/IblPipelineCache.d.ts +168 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -0
- package/dist/ibl/skylight-bind-group.d.ts +130 -0
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +169 -0
- package/dist/index.mjs.map +1 -0
- package/dist/inspection-types.d.ts +72 -0
- package/dist/inspection-types.d.ts.map +1 -0
- package/dist/instance-buffer-cache.d.ts +56 -0
- package/dist/instance-buffer-cache.d.ts.map +1 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.mjs +3 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/lifecycle.d.ts +62 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/light-buffer-layout.d.ts +164 -0
- package/dist/light-buffer-layout.d.ts.map +1 -0
- package/dist/materials.d.ts +47 -0
- package/dist/materials.d.ts.map +1 -0
- package/dist/mesh-material-bindings.d.ts +43 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -0
- package/dist/pbr-pipeline.d.ts +301 -0
- package/dist/pbr-pipeline.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts +5 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +31 -0
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -0
- package/dist/pipeline/standard-profile.d.ts +40 -0
- package/dist/pipeline/standard-profile.d.ts.map +1 -0
- package/dist/pipeline-builder.d.ts +122 -0
- package/dist/pipeline-builder.d.ts.map +1 -0
- package/dist/pipeline-spec-types.d.ts +24 -0
- package/dist/pipeline-spec-types.d.ts.map +1 -0
- package/dist/pipeline-spec.d.ts +367 -0
- package/dist/pipeline-spec.d.ts.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts +2 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +1 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +1 -0
- package/dist/points-lines/admission.d.ts +36 -0
- package/dist/points-lines/admission.d.ts.map +1 -0
- package/dist/points-lines/bounds.d.ts +8 -0
- package/dist/points-lines/bounds.d.ts.map +1 -0
- package/dist/points-lines/expansion-cache.d.ts +28 -0
- package/dist/points-lines/expansion-cache.d.ts.map +1 -0
- package/dist/points-lines/inspection.d.ts +53 -0
- package/dist/points-lines/inspection.d.ts.map +1 -0
- package/dist/points-lines/prepare.d.ts +67 -0
- package/dist/points-lines/prepare.d.ts.map +1 -0
- package/dist/points-lines/record.d.ts +60 -0
- package/dist/points-lines/record.d.ts.map +1 -0
- package/dist/points-lines/snapshot.d.ts +49 -0
- package/dist/points-lines/snapshot.d.ts.map +1 -0
- package/dist/post-process-errors.d.ts +182 -0
- package/dist/post-process-errors.d.ts.map +1 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts +59 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -0
- package/dist/record/__tests__/material-bg-cache.unit.test.d.ts +2 -0
- package/dist/record/__tests__/material-bg-cache.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/material-slot-plan.unit.test.d.ts +2 -0
- package/dist/record/__tests__/material-slot-plan.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +2 -0
- package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/video-texture-view.unit.test.d.ts +2 -0
- package/dist/record/__tests__/video-texture-view.unit.test.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +121 -0
- package/dist/record/frame-lighting.d.ts.map +1 -0
- package/dist/record/frame-snapshot.d.ts +429 -0
- package/dist/record/frame-snapshot.d.ts.map +1 -0
- package/dist/record/frame-targets.d.ts +20 -0
- package/dist/record/frame-targets.d.ts.map +1 -0
- package/dist/record/frame.d.ts +71 -0
- package/dist/record/frame.d.ts.map +1 -0
- package/dist/record/helpers.d.ts +102 -0
- package/dist/record/helpers.d.ts.map +1 -0
- package/dist/record/main-pass-geometry.d.ts +28 -0
- package/dist/record/main-pass-geometry.d.ts.map +1 -0
- package/dist/record/main-pass-material.d.ts +204 -0
- package/dist/record/main-pass-material.d.ts.map +1 -0
- package/dist/record/main-pass-sprite-draws.d.ts +43 -0
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -0
- package/dist/record/main-pass.d.ts +20 -0
- package/dist/record/main-pass.d.ts.map +1 -0
- package/dist/record/mesh-ssbo.d.ts +446 -0
- package/dist/record/mesh-ssbo.d.ts.map +1 -0
- package/dist/record/render-context.d.ts +252 -0
- package/dist/record/render-context.d.ts.map +1 -0
- package/dist/record/shadow-pass.d.ts +52 -0
- package/dist/record/shadow-pass.d.ts.map +1 -0
- package/dist/record/skybox-post-pass.d.ts +33 -0
- package/dist/record/skybox-post-pass.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +35 -0
- package/dist/record/typed-frame-graph.d.ts.map +1 -0
- package/dist/record/view-ubo.d.ts +45 -0
- package/dist/record/view-ubo.d.ts.map +1 -0
- package/dist/render-contract.d.ts +424 -0
- package/dist/render-contract.d.ts.map +1 -0
- package/dist/render-data.d.ts +143 -0
- package/dist/render-data.d.ts.map +1 -0
- package/dist/render-graph-primitives.d.ts +76 -0
- package/dist/render-graph-primitives.d.ts.map +1 -0
- package/dist/render-pipeline.d.ts +110 -0
- package/dist/render-pipeline.d.ts.map +1 -0
- package/dist/render-system-extract.d.ts +868 -0
- package/dist/render-system-extract.d.ts.map +1 -0
- package/dist/render-system.d.ts +125 -0
- package/dist/render-system.d.ts.map +1 -0
- package/dist/scene/render-scene-types.d.ts +61 -0
- package/dist/scene/render-scene-types.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +112 -0
- package/dist/scene/render-scene.d.ts.map +1 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts +30 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -0
- package/dist/shadow-atlas.d.ts +117 -0
- package/dist/shadow-atlas.d.ts.map +1 -0
- package/dist/ssao-buffers.d.ts +50 -0
- package/dist/ssao-buffers.d.ts.map +1 -0
- package/dist/ssao-config.d.ts +28 -0
- package/dist/ssao-config.d.ts.map +1 -0
- package/dist/systems/active-camera.d.ts +53 -0
- package/dist/systems/active-camera.d.ts.map +1 -0
- package/dist/systems/pass-selector.d.ts +24 -0
- package/dist/systems/pass-selector.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +49 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -0
- package/dist/systems/skin-palette-types.d.ts +14 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -0
- package/dist/systems/transparent-sort-config.d.ts +112 -0
- package/dist/systems/transparent-sort-config.d.ts.map +1 -0
- package/dist/tilemap-chunk-extract-system.d.ts +143 -0
- package/dist/tilemap-chunk-extract-system.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +57 -0
- package/dist/typed-render-graph-primitives.d.ts.map +1 -0
- package/dist/typed-shadow-passes.d.ts +11 -0
- package/dist/typed-shadow-passes.d.ts.map +1 -0
- package/package.json +94 -0
- package/src/__tests__/authoring-path.unit.test.ts +23 -0
- package/src/__tests__/backend-selection-rhi-capture.test-d.ts +21 -0
- package/src/__tests__/callback-inference.test-d.ts +8 -0
- package/src/__tests__/cluster-binner.test.ts +272 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +20 -0
- package/src/__tests__/construct-renderer-identity.unit.test.ts +23 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +151 -0
- package/src/__tests__/device-scope-stale-matrix.unit.test.ts +42 -0
- package/src/__tests__/direct-extract-consumer-contract.test-d.ts +23 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +61 -0
- package/src/__tests__/factory-contract.integration.test.ts +280 -0
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +15 -0
- package/src/__tests__/frame-observation.contract.test.ts +112 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
- package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +167 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +350 -0
- package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +12 -0
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +16 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +436 -0
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +87 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +271 -0
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +290 -0
- package/src/__tests__/gpu-driven-view-reference.ts +111 -0
- package/src/__tests__/gpu-driven-view.browser.test.ts +30 -0
- package/src/__tests__/gpu-driven-view.dawn.test.ts +28 -0
- package/src/__tests__/gpu-driven-view.unit.test.ts +199 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +59 -0
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +308 -0
- package/src/__tests__/gpu-scene-render-graph.browser.test.ts +19 -0
- package/src/__tests__/gpu-scene-render-graph.dawn.test.ts +19 -0
- package/src/__tests__/gpu-scene-schema.unit.test.ts +16 -0
- package/src/__tests__/gpu-scene.dawn.test.ts +205 -0
- package/src/__tests__/gpu-scene.unit.test.ts +147 -0
- package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
- package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +92 -0
- package/src/__tests__/injection-kind-owner.test-d.ts +14 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +728 -0
- package/src/__tests__/light-buffer-layout.unit.test.ts +40 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +24 -0
- package/src/__tests__/material-cooked-projection.unit.test.ts +150 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +53 -0
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +94 -0
- package/src/__tests__/material-stride-surface.unit.test.ts +32 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +106 -0
- package/src/__tests__/mesh-material-bindings.unit.test.ts +89 -0
- package/src/__tests__/mesh-stride-surface.unit.test.ts +16 -0
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +157 -0
- package/src/__tests__/morph-feature-gpu-work.integration.test.ts +80 -0
- package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
- package/src/__tests__/morph-visual-evidence.integration.test.ts +80 -0
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +19 -0
- package/src/__tests__/post-process-error-policy-owner.unit.test.ts +201 -0
- package/src/__tests__/prepared-buffer-kind-owner.test-d.ts +29 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +65 -0
- package/src/__tests__/prepared-graphics-generation.unit.test.ts +161 -0
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +138 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +29 -0
- package/src/__tests__/prepared-graphics-resolver.unit.test.ts +285 -0
- package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +105 -0
- package/src/__tests__/prepared-graphics-store.unit.test.ts +154 -0
- package/src/__tests__/prepared-graphics-validation.unit.test.ts +176 -0
- package/src/__tests__/profiler-default-off.test.ts +22 -0
- package/src/__tests__/profiler-phase-catalog.test.ts +66 -0
- package/src/__tests__/profiler-phase-integration.test.ts +62 -0
- package/src/__tests__/profiler-phase-token.test.ts +79 -0
- package/src/__tests__/public-surface.test-d.ts +94 -0
- package/src/__tests__/recover-error-policy-owner.unit.test.ts +107 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +116 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +139 -0
- package/src/__tests__/render-error-exhaustive.test-d.ts +110 -0
- package/src/__tests__/render-feature-assembly.test-d.ts +43 -0
- package/src/__tests__/render-feature-context.test-d.ts +57 -0
- package/src/__tests__/render-feature-contract.test-d.ts +49 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +149 -0
- package/src/__tests__/render-feature-docs.unit.test.ts +89 -0
- package/src/__tests__/render-feature-errors.unit.test.ts +47 -0
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +316 -0
- package/src/__tests__/render-feature-plan.test-d.ts +161 -0
- package/src/__tests__/render-feature-plan.unit.test.ts +170 -0
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +90 -0
- package/src/__tests__/render-feature-prepared-errors.test-d.ts +79 -0
- package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +80 -0
- package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +72 -0
- package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +36 -0
- package/src/__tests__/render-feature-prepared-graphics.test-d.ts +74 -0
- package/src/__tests__/render-feature-prepared-graphics.unit.test.ts +121 -0
- package/src/__tests__/render-feature-public-surface.test-d.ts +57 -0
- package/src/__tests__/render-feature-retry.unit.test.ts +87 -0
- package/src/__tests__/render-feature-scheduling.unit.test.ts +110 -0
- package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +137 -0
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +146 -0
- package/src/__tests__/render-feature-visibility-context.test-d.ts +33 -0
- package/src/__tests__/render-feature-visibility-context.unit.test.ts +37 -0
- package/src/__tests__/render-feature-zero-work.unit.test.ts +76 -0
- package/src/__tests__/render-graph-compute-raster-gpu.ts +342 -0
- package/src/__tests__/render-graph-compute-raster.browser.test.ts +16 -0
- package/src/__tests__/render-graph-compute-raster.dawn.test.ts +22 -0
- package/src/__tests__/render-graph-hzb-gpu.ts +239 -0
- package/src/__tests__/render-graph-hzb.browser.test.ts +16 -0
- package/src/__tests__/render-graph-hzb.dawn.test.ts +23 -0
- package/src/__tests__/render-graph-primitives.unit.test.ts +22 -0
- package/src/__tests__/render-graph-storage-indirect-gpu.ts +162 -0
- package/src/__tests__/render-graph-storage-indirect.browser.test.ts +21 -0
- package/src/__tests__/render-graph-storage-indirect.dawn.test.ts +28 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +168 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +121 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +58 -0
- package/src/__tests__/rhi-backend-package-boundary.unit.test.ts +11 -0
- package/src/__tests__/scriptable-pack-consumer.test-d.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +43 -0
- package/src/__tests__/ssao-config.unit.test.ts +36 -0
- package/src/__tests__/ssao-kernel-surface.unit.test.ts +14 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +28 -0
- package/src/__tests__/standard-descriptors.test-d.ts +22 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +61 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +124 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +62 -0
- package/src/__tests__/surface-configuration.unit.test.ts +91 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +58 -0
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +223 -0
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +42 -0
- package/src/__tests__/urp-pipeline.unit.test.ts +14 -0
- package/src/__tests__/vertex-color-pipeline.unit.test.ts +132 -0
- package/src/__tests__/vertex-layout-consumer.unit.test.ts +25 -0
- package/src/__tests__/visibility-diagnostics.integration.test.ts +62 -0
- package/src/__tests__/visibility-extract.integration.test.ts +98 -0
- package/src/__tests__/visibility-extract.perf.test.ts +130 -0
- package/src/__tests__/visibility-feature-dedup.integration.test.ts +55 -0
- package/src/__tests__/visibility-hidden-report.unit.test.ts +36 -0
- package/src/__tests__/visibility-instances.integration.test.ts +46 -0
- package/src/__tests__/visibility-multi-world.integration.test.ts +86 -0
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +168 -0
- package/src/__tests__/visibility-producer-matrix.unit.test.ts +96 -0
- package/src/__tests__/visibility-public-surface.test-d.ts +27 -0
- package/src/__tests__/visibility-resolver.unit.test.ts +85 -0
- package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
- package/src/__tests__/visibility-snapshot-contract.unit.test.ts +60 -0
- package/src/__tests__/vocabulary.unit.test.ts +21 -0
- package/src/assembly/backend-contract.ts +57 -0
- package/src/assembly/factory.ts +8130 -0
- package/src/assembly/host-contract.ts +101 -0
- package/src/assembly/material/assembly.ts +48 -0
- package/src/assembly/material/pipeline-projection.ts +63 -0
- package/src/assets/asset-decoders.ts +158 -0
- package/src/assets/render-asset-port.ts +44 -0
- package/src/assets/resolve-render-asset.ts +13 -0
- package/src/authoring.ts +17 -0
- package/src/cluster-binner.ts +700 -0
- package/src/components/__tests__/points-lines-admission.unit.test.ts +219 -0
- package/src/components/__tests__/points-lines-schema.unit.test.ts +56 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +25 -0
- package/src/components/__tests__/visibility-schema.unit.test.ts +35 -0
- package/src/components/camera.ts +512 -0
- package/src/components/directional-light.ts +120 -0
- package/src/components/glyph-text.ts +64 -0
- package/src/components/index.ts +54 -0
- package/src/components/instances.ts +206 -0
- package/src/components/layer.ts +69 -0
- package/src/components/light-helpers.ts +188 -0
- package/src/components/lines.ts +18 -0
- package/src/components/mesh-filter.ts +60 -0
- package/src/components/mesh-renderer.ts +61 -0
- package/src/components/point-light-shadow.ts +43 -0
- package/src/components/point-light.ts +65 -0
- package/src/components/points.ts +40 -0
- package/src/components/post-process-params.ts +35 -0
- package/src/components/scene-instance.ts +193 -0
- package/src/components/skybox-background.ts +103 -0
- package/src/components/skylight.ts +97 -0
- package/src/components/sort-key.ts +75 -0
- package/src/components/spot-light.ts +124 -0
- package/src/components/sprite-animation.ts +168 -0
- package/src/components/sprite-instances.ts +179 -0
- package/src/components/sprite-playback-mode.ts +79 -0
- package/src/components/sprite-region-override.ts +105 -0
- package/src/components/tile-layer.ts +167 -0
- package/src/components/tilemap.ts +48 -0
- package/src/components/visibility.ts +53 -0
- package/src/construct-renderer.ts +67 -0
- package/src/debug-draw-glue.ts +48 -0
- package/src/device/device-scope.ts +306 -0
- package/src/device/gpu-residency.ts +1822 -0
- package/src/device/resource-types.ts +20 -0
- package/src/engine-metrics.ts +82 -0
- package/src/errors/ecs-validation.ts +16 -0
- package/src/errors/index.ts +3 -0
- package/src/errors/recover.ts +161 -0
- package/src/errors/render.ts +1284 -0
- package/src/extract/visibility.ts +120 -0
- package/src/features/fullscreen.ts +46 -0
- package/src/features/host.ts +1363 -0
- package/src/features/morph/morph-feature.ts +377 -0
- package/src/features/plan.ts +447 -0
- package/src/features/prepared-gpu-work.ts +959 -0
- package/src/features/prepared-graphics-store.ts +449 -0
- package/src/features/prepared-graphics.ts +420 -0
- package/src/features/render-graph-compute.ts +69 -0
- package/src/features/render-graph-contribution.ts +75 -0
- package/src/features/render-graph-raster.ts +332 -0
- package/src/features/render-graph-resources.ts +38 -0
- package/src/features/targets.ts +70 -0
- package/src/features/types.ts +103 -0
- package/src/features/vocabulary.ts +24 -0
- package/src/fullscreen-post-process-pass.ts +363 -0
- package/src/glyph-text-layout-system.ts +421 -0
- package/src/gpu-driven/batch-topology.ts +245 -0
- package/src/gpu-driven/production-raster.ts +695 -0
- package/src/gpu-driven/view-gpu.ts +703 -0
- package/src/gpu-resource.ts +159 -0
- package/src/gpu-scene-schema.ts +136 -0
- package/src/gpu-scene.ts +722 -0
- package/src/gpu-stage.ts +9 -0
- package/src/gpu-texture-usage.ts +12 -0
- package/src/gpu-usage.ts +14 -0
- package/src/hdrp-buffers.ts +480 -0
- package/src/ibl/IblPipelineCache.ts +1006 -0
- package/src/ibl/skylight-bind-group.ts +513 -0
- package/src/index.ts +129 -0
- package/src/inspection-types.ts +80 -0
- package/src/instance-buffer-cache.ts +95 -0
- package/src/internal.ts +9 -0
- package/src/lifecycle.ts +168 -0
- package/src/light-buffer-layout.ts +346 -0
- package/src/materials.ts +214 -0
- package/src/mesh-material-bindings.ts +103 -0
- package/src/pbr-pipeline.ts +1137 -0
- package/src/pipeline/standard-forward-lane.ts +229 -0
- package/src/pipeline/standard-pipeline.ts +555 -0
- package/src/pipeline/standard-profile.ts +65 -0
- package/src/pipeline-builder.ts +382 -0
- package/src/pipeline-spec-types.ts +28 -0
- package/src/pipeline-spec.ts +1231 -0
- package/src/plugin.ts +69 -0
- package/src/points-lines/__tests__/bounds.unit.test.ts +21 -0
- package/src/points-lines/__tests__/cache-recovery.unit.test.ts +157 -0
- package/src/points-lines/__tests__/inspection-lanes.integration.test.ts +146 -0
- package/src/points-lines/__tests__/inspection.unit.test.ts +173 -0
- package/src/points-lines/__tests__/lane-structural.integration.test.ts +122 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +400 -0
- package/src/points-lines/__tests__/raster-lane.integration.test.ts +44 -0
- package/src/points-lines/__tests__/snapshot.unit.test.ts +101 -0
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +73 -0
- package/src/points-lines/admission.ts +238 -0
- package/src/points-lines/bounds.ts +23 -0
- package/src/points-lines/expansion-cache.ts +215 -0
- package/src/points-lines/inspection.ts +97 -0
- package/src/points-lines/prepare.ts +177 -0
- package/src/points-lines/record.ts +125 -0
- package/src/points-lines/snapshot.ts +130 -0
- package/src/post-process-errors.ts +302 -0
- package/src/prepare/prepared-graphics-resolver.ts +456 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +41 -0
- package/src/record/__tests__/material-slot-plan.unit.test.ts +44 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
- package/src/record/__tests__/video-texture-view.unit.test.ts +90 -0
- package/src/record/frame-lighting.ts +1074 -0
- package/src/record/frame-snapshot.ts +500 -0
- package/src/record/frame-targets.ts +137 -0
- package/src/record/frame.ts +1598 -0
- package/src/record/helpers.ts +284 -0
- package/src/record/main-pass-geometry.ts +1065 -0
- package/src/record/main-pass-material.ts +1043 -0
- package/src/record/main-pass-sprite-draws.ts +1137 -0
- package/src/record/main-pass.ts +610 -0
- package/src/record/mesh-ssbo.ts +885 -0
- package/src/record/render-context.ts +384 -0
- package/src/record/shadow-pass.ts +698 -0
- package/src/record/skybox-post-pass.ts +593 -0
- package/src/record/typed-frame-graph.ts +461 -0
- package/src/record/view-ubo.ts +222 -0
- package/src/render-contract.ts +582 -0
- package/src/render-data.ts +385 -0
- package/src/render-graph-primitives.ts +811 -0
- package/src/render-pipeline.ts +259 -0
- package/src/render-system-extract.ts +4585 -0
- package/src/render-system.ts +1933 -0
- package/src/scene/render-scene-types.ts +67 -0
- package/src/scene/render-scene.ts +1087 -0
- package/src/scene-instances/post-spawn-resolve-joints.ts +165 -0
- package/src/shadow-atlas.ts +244 -0
- package/src/ssao-buffers.ts +334 -0
- package/src/ssao-config.ts +61 -0
- package/src/systems/active-camera.ts +116 -0
- package/src/systems/pass-selector.ts +49 -0
- package/src/systems/skin-palette-allocator.ts +251 -0
- package/src/systems/skin-palette-types.ts +14 -0
- package/src/systems/transparent-sort-config.ts +233 -0
- package/src/tilemap-chunk-extract-system.ts +1290 -0
- package/src/typed-render-graph-primitives.ts +541 -0
- package/src/typed-shadow-passes.ts +165 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
// @forgeax/engine-runtime - glyphTextLayoutSystem
|
|
2
|
+
// (feat-20260531-world-space-msdf-text-rendering M4 / w18).
|
|
3
|
+
//
|
|
4
|
+
// The named ECS system that turns `GlyphText` authoring data into a rendered
|
|
5
|
+
// world-space label (plan-strategy D-2). A Renderer attaches it to World's
|
|
6
|
+
// internal render-derived phase,
|
|
7
|
+
// so a freshly-spawned `GlyphText` entity gains its `MeshFilter` +
|
|
8
|
+
// `MeshRenderer` before final publication resolves transforms and the same frame's
|
|
9
|
+
// read-only render walk reaches it. Per `GlyphText` entity:
|
|
10
|
+
//
|
|
11
|
+
// 1. First observation (entity has no `MeshFilter`): resolve the FontAsset,
|
|
12
|
+
// run `layoutGlyphText` (w15) + `bakeGlyphMesh` (w17), then attach
|
|
13
|
+
// `MeshFilter` + `MeshRenderer` (AC-07). The attach uses the same
|
|
14
|
+
// immediate `world.addComponent` path as `spriteAnimationTickSystem`'s
|
|
15
|
+
// auto-add (the system runs ahead of the render walk in the same frame).
|
|
16
|
+
// 2. Dirty (text / fontSize / color changed since last bake): re-layout and
|
|
17
|
+
// `updateMesh` IN PLACE (plan-strategy D-1) -- never re-`register`, never
|
|
18
|
+
// re-attach. The AssetRegistry size stays constant (AC-08; avoids the
|
|
19
|
+
// unbounded growth R-1 would otherwise cause).
|
|
20
|
+
//
|
|
21
|
+
// D-8 concurrency: at most 8 distinct FontAsset handles may be active in one
|
|
22
|
+
// frame. The system resets the per-frame tracker (resetFontConcurrency) at the
|
|
23
|
+
// top and tracks each distinct font; the 9th distinct font surfaces a
|
|
24
|
+
// structured `TextError('font-concurrency-exceeded')` (it does NOT silently
|
|
25
|
+
// evict the oldest font).
|
|
26
|
+
//
|
|
27
|
+
// The system does NOT modify `pick.ts` (D-5): the baked mesh carries a local
|
|
28
|
+
// AABB and the entity carries MeshFilter + MeshRenderer + Transform, so the
|
|
29
|
+
// existing `pick()` raycast walk catches it for free.
|
|
30
|
+
|
|
31
|
+
import { resolveAssetHandle } from '@forgeax/engine-assets-runtime';
|
|
32
|
+
import type { EntityHandle, World } from '@forgeax/engine-ecs';
|
|
33
|
+
import { PROCEDURAL_FLOATS_PER_VERTEX } from '@forgeax/engine-geometry';
|
|
34
|
+
import {
|
|
35
|
+
bakeGlyphMesh,
|
|
36
|
+
conservativeCubeAabb,
|
|
37
|
+
layoutGlyphText,
|
|
38
|
+
resetFontConcurrency,
|
|
39
|
+
trackFontConcurrency,
|
|
40
|
+
} from '@forgeax/engine-graphics-extras';
|
|
41
|
+
import type { FontAsset, Handle, MaterialAsset, MeshAsset, Submesh } from '@forgeax/engine-types';
|
|
42
|
+
import { err, ok, type Result, TextError, toShared, unpackSlot } from '@forgeax/engine-types';
|
|
43
|
+
import { MeshFilter, MeshRenderer } from './components';
|
|
44
|
+
import { GlyphText } from './components/glyph-text';
|
|
45
|
+
import type { GpuResidencyCache } from './device/gpu-residency';
|
|
46
|
+
|
|
47
|
+
// Per-entity bake bookkeeping: the baked mesh handle id + the authoring
|
|
48
|
+
// signature it was baked from. A WeakMap owns one cache per World and each
|
|
49
|
+
// entry is bounded by entity slot while retaining the full generation-bearing
|
|
50
|
+
// EntityHandle, so slot reuse replaces stale state instead of aliasing it or
|
|
51
|
+
// growing one historical entry per generation.
|
|
52
|
+
interface BakeRecord {
|
|
53
|
+
readonly meshHandle: Handle<'MeshAsset', 'shared'>;
|
|
54
|
+
signature: string;
|
|
55
|
+
/** The MeshRenderer.material handle assigned on first observation. */
|
|
56
|
+
readonly materialHandle: Handle<'MaterialAsset', 'shared'>;
|
|
57
|
+
}
|
|
58
|
+
interface BakeCacheEntry {
|
|
59
|
+
readonly handle: EntityHandle;
|
|
60
|
+
readonly record: BakeRecord;
|
|
61
|
+
}
|
|
62
|
+
let bakeCache = new WeakMap<World, Map<number, BakeCacheEntry>>();
|
|
63
|
+
|
|
64
|
+
// One current material producer handle per GlyphText entity slot. Continuous
|
|
65
|
+
// tint edits replace and release the previous producer instead of growing a
|
|
66
|
+
// historical color-key cache.
|
|
67
|
+
let materialCache = new WeakMap<World, Map<number, Handle<'MaterialAsset', 'shared'>>>();
|
|
68
|
+
let liveGlyphSlots = new WeakMap<World, Set<number>>();
|
|
69
|
+
|
|
70
|
+
function entitySlot(entity: EntityHandle): number {
|
|
71
|
+
return unpackSlot(entity as number);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Clear the per-entity bake + per-font material caches (test isolation). */
|
|
75
|
+
export function resetGlyphBakeCache(): void {
|
|
76
|
+
bakeCache = new WeakMap();
|
|
77
|
+
materialCache = new WeakMap();
|
|
78
|
+
liveGlyphSlots = new WeakMap();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function worldBakeCache(world: World): Map<number, BakeCacheEntry> {
|
|
82
|
+
let cache = bakeCache.get(world);
|
|
83
|
+
if (cache === undefined) {
|
|
84
|
+
cache = new Map();
|
|
85
|
+
bakeCache.set(world, cache);
|
|
86
|
+
}
|
|
87
|
+
return cache;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function worldMaterialCache(world: World): Map<number, Handle<'MaterialAsset', 'shared'>> {
|
|
91
|
+
let cache = materialCache.get(world);
|
|
92
|
+
if (cache === undefined) {
|
|
93
|
+
cache = new Map();
|
|
94
|
+
materialCache.set(world, cache);
|
|
95
|
+
}
|
|
96
|
+
return cache;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Release renderer-derived producer refs at GlyphText removal time. */
|
|
100
|
+
function releaseGlyphProducers(world: World, entity: EntityHandle): void {
|
|
101
|
+
const slot = entitySlot(entity);
|
|
102
|
+
const bake = bakeCache.get(world)?.get(slot);
|
|
103
|
+
if (bake?.handle === entity) {
|
|
104
|
+
world.sharedRefs.release(bake.record.meshHandle);
|
|
105
|
+
bakeCache.get(world)?.delete(slot);
|
|
106
|
+
}
|
|
107
|
+
const material = materialCache.get(world)?.get(slot);
|
|
108
|
+
if (material !== undefined) {
|
|
109
|
+
world.sharedRefs.release(material);
|
|
110
|
+
materialCache.get(world)?.delete(slot);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Remove stale renderer-derived state when a previously baked font is rejected. */
|
|
115
|
+
function clearRejectedGlyphState(world: World, entity: EntityHandle): void {
|
|
116
|
+
const slot = entitySlot(entity);
|
|
117
|
+
const bake = bakeCache.get(world)?.get(slot);
|
|
118
|
+
if (bake?.handle !== entity) return;
|
|
119
|
+
|
|
120
|
+
// These components are owned by this system only when the matching bake
|
|
121
|
+
// record exists. Removing them before releasing the producer refs leaves no
|
|
122
|
+
// stale draw/material handles and lets the next valid frame take the normal
|
|
123
|
+
// first-observation path.
|
|
124
|
+
if (world.get(entity, MeshFilter).ok) world.removeComponent(entity, MeshFilter);
|
|
125
|
+
if (world.get(entity, MeshRenderer).ok) world.removeComponent(entity, MeshRenderer);
|
|
126
|
+
releaseGlyphProducers(world, entity);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Premultiplied-alpha blend (mirrors the sprite path, plan D-7). The
|
|
130
|
+
// `forgeax::msdf-text` fragment emits premultiplied RGB so the over-composite
|
|
131
|
+
// math (`dst' = src + dst * (1 - src.a)`) is direct. The pass rides the
|
|
132
|
+
// Transparent queue (3000) so text composites after opaque geometry while
|
|
133
|
+
// honoring depth occlusion (depthCompare less-equal, depthWrite off via the
|
|
134
|
+
// material-shader pipeline render state).
|
|
135
|
+
const MSDF_TEXT_BLEND = {
|
|
136
|
+
color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },
|
|
137
|
+
alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },
|
|
138
|
+
} as const;
|
|
139
|
+
|
|
140
|
+
interface GlyphTextData {
|
|
141
|
+
readonly fontHandle: number;
|
|
142
|
+
readonly text: string;
|
|
143
|
+
readonly fontSize: number;
|
|
144
|
+
// feat-20260709 M3: color collapsed into one inline array<f32,4>; the
|
|
145
|
+
// world.get read path materialises it as a Float32Array (color[0..3] = rgba).
|
|
146
|
+
readonly color: ArrayLike<number>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** @internal archetype-walk view (same shape reached for in render-system-extract). */
|
|
150
|
+
/**
|
|
151
|
+
* Lay out + bake every `GlyphText` entity, attaching MeshFilter + MeshRenderer
|
|
152
|
+
* on first observation and re-baking in place on a text / size / color change.
|
|
153
|
+
*
|
|
154
|
+
* @param world The ECS world holding the GlyphText entities.
|
|
155
|
+
* @returns `ok(void)` on a clean pass, or `err(TextError)` carrying the FIRST
|
|
156
|
+
* structured failure (currently only `font-concurrency-exceeded`). Healthy
|
|
157
|
+
* entities observed before the failing one are still baked.
|
|
158
|
+
*/
|
|
159
|
+
export function glyphTextLayoutSystem(
|
|
160
|
+
world: World,
|
|
161
|
+
gpuStore: GpuResidencyCache,
|
|
162
|
+
): Result<void, TextError> {
|
|
163
|
+
resetFontConcurrency();
|
|
164
|
+
|
|
165
|
+
// No GlyphText entity in this World -> empty query -> no-op pass. The
|
|
166
|
+
// ECS query is the single owner of component presence and entity iteration;
|
|
167
|
+
// the renderer does not reach into archetype storage internals.
|
|
168
|
+
const entities = collectGlyphEntities(world);
|
|
169
|
+
const live = liveGlyphSlots.get(world) ?? new Set<number>();
|
|
170
|
+
live.clear();
|
|
171
|
+
for (const entity of entities) live.add(entitySlot(entity));
|
|
172
|
+
liveGlyphSlots.set(world, live);
|
|
173
|
+
for (const entry of worldBakeCache(world).values()) {
|
|
174
|
+
if (!live.has(entitySlot(entry.handle))) releaseGlyphProducers(world, entry.handle);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let firstError: TextError | null = null;
|
|
178
|
+
for (const entity of entities) {
|
|
179
|
+
const error = processEntity(world, gpuStore, entity);
|
|
180
|
+
if (error !== null && firstError === null) firstError = error;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (firstError !== null) return err(firstError);
|
|
184
|
+
return ok(undefined);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Collect every Entity handle carrying GlyphText (single archetype walk). */
|
|
188
|
+
function collectGlyphEntities(world: World): EntityHandle[] {
|
|
189
|
+
const entities: EntityHandle[] = [];
|
|
190
|
+
const query = world.query({ read: [GlyphText] }).unwrap();
|
|
191
|
+
for (const row of query) {
|
|
192
|
+
entities.push(row.entity);
|
|
193
|
+
}
|
|
194
|
+
return entities;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Process one GlyphText entity. Returns a TextError when the concurrency limit
|
|
199
|
+
* is exceeded after clearing stale derived state; returns null otherwise.
|
|
200
|
+
*/
|
|
201
|
+
function processEntity(
|
|
202
|
+
world: World,
|
|
203
|
+
gpuStore: GpuResidencyCache,
|
|
204
|
+
entity: EntityHandle,
|
|
205
|
+
): TextError | null {
|
|
206
|
+
const gtRes = world.get(entity, GlyphText);
|
|
207
|
+
if (!gtRes.ok) return null;
|
|
208
|
+
const gt = gtRes.value;
|
|
209
|
+
|
|
210
|
+
// Unresolved font handle (zero sentinel) -> skip (entity not yet wired).
|
|
211
|
+
if (gt.fontHandle === 0) return null;
|
|
212
|
+
|
|
213
|
+
// D-8 concurrency: track this distinct font; the 9th throws a TextError.
|
|
214
|
+
try {
|
|
215
|
+
trackFontConcurrency(gt.fontHandle);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
if (e instanceof TextError) {
|
|
218
|
+
clearRejectedGlyphState(world, entity);
|
|
219
|
+
return e;
|
|
220
|
+
}
|
|
221
|
+
throw e;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const fontRes = resolveAssetHandle<FontAsset>(world, asFontHandle(gt.fontHandle));
|
|
225
|
+
if (!fontRes.ok) return null; // font not registered yet -> skip silently
|
|
226
|
+
const font = fontRes.value;
|
|
227
|
+
|
|
228
|
+
const signature = signatureOf(gt);
|
|
229
|
+
const entityCache = worldBakeCache(world);
|
|
230
|
+
const slot = entitySlot(entity);
|
|
231
|
+
const cachedEntry = entityCache.get(slot);
|
|
232
|
+
if (cachedEntry !== undefined && cachedEntry.handle !== entity) {
|
|
233
|
+
world.sharedRefs.release(cachedEntry.record.meshHandle);
|
|
234
|
+
const staleMaterial = worldMaterialCache(world).get(slot);
|
|
235
|
+
if (staleMaterial !== undefined) {
|
|
236
|
+
world.sharedRefs.release(staleMaterial);
|
|
237
|
+
worldMaterialCache(world).delete(slot);
|
|
238
|
+
}
|
|
239
|
+
entityCache.delete(slot);
|
|
240
|
+
}
|
|
241
|
+
const cached = cachedEntry?.handle === entity ? cachedEntry.record : undefined;
|
|
242
|
+
|
|
243
|
+
// Dirty path: same entity already baked, but the authoring signature changed.
|
|
244
|
+
if (cached !== undefined) {
|
|
245
|
+
ensureGlyphMeshMaterialSlots(world, cached.meshHandle);
|
|
246
|
+
if (cached.signature === signature) return null; // clean -> nothing to do
|
|
247
|
+
const layout = layoutGlyphText(font, gt.text, gt.fontSize);
|
|
248
|
+
// feat-20260601-device/gpu-residency-extraction M1: in-place GPU mesh update
|
|
249
|
+
// moved to the store. The mesh became GPU-resident on the first render
|
|
250
|
+
// frame's `ensureResident` pull; the dirty re-layout overwrites those
|
|
251
|
+
// buffers in place (a no-op if not yet resident -- the next render's
|
|
252
|
+
// ensureResident then uploads the latest registered POD).
|
|
253
|
+
const meshHandle = cached.meshHandle;
|
|
254
|
+
const submeshes = [
|
|
255
|
+
{
|
|
256
|
+
indexOffset: 0,
|
|
257
|
+
indexCount: layout.indices.length,
|
|
258
|
+
vertexCount: layout.vertices.length / PROCEDURAL_FLOATS_PER_VERTEX,
|
|
259
|
+
topology: 'triangle-list',
|
|
260
|
+
materialSlot: 0,
|
|
261
|
+
},
|
|
262
|
+
] satisfies readonly Submesh[];
|
|
263
|
+
// A dynamic label can begin empty, so its first bake has a degenerate AABB.
|
|
264
|
+
// Keep the shared MeshAsset's culling/picking bounds in lockstep with the
|
|
265
|
+
// dirty layout; otherwise the GPU buffers update but the render walk still
|
|
266
|
+
// rejects the label as an empty mesh.
|
|
267
|
+
const mesh = world.sharedRefs.resolve<'MeshAsset', MeshAsset>(meshHandle);
|
|
268
|
+
if (mesh.ok) {
|
|
269
|
+
const aabb = conservativeCubeAabb(layout.radius);
|
|
270
|
+
// Keep both sides of the pull boundary coherent. A zero-glyph first
|
|
271
|
+
// bake may have no resident GPU buffers yet, so updating only the GPU
|
|
272
|
+
// store would lose the new text on the next ensureResident pull.
|
|
273
|
+
Object.assign(mesh.value, {
|
|
274
|
+
vertices: layout.vertices,
|
|
275
|
+
indices: layout.indices,
|
|
276
|
+
submeshes,
|
|
277
|
+
materialSlots: [{ slotName: 'Default' }],
|
|
278
|
+
aabb,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
gpuStore.updateMesh(meshHandle, layout.vertices, layout.indices, 0, submeshes);
|
|
282
|
+
// A color change replaces the material payload at this entity's stable
|
|
283
|
+
// derived slot and re-binds the new producer handle in place.
|
|
284
|
+
const materialId = resolveTextMaterial(world, gt, font, slot);
|
|
285
|
+
if (materialId !== cached.materialHandle) {
|
|
286
|
+
world.set(entity, MeshRenderer, {
|
|
287
|
+
materials: [materialId],
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
entityCache.set(slot, {
|
|
291
|
+
handle: entity,
|
|
292
|
+
record: {
|
|
293
|
+
meshHandle: cached.meshHandle,
|
|
294
|
+
signature,
|
|
295
|
+
materialHandle: materialId,
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// First-observation path. If this entity already carries a MeshFilter (e.g.
|
|
302
|
+
// the bake cache was reset between frames), skip without re-baking. `world.get`
|
|
303
|
+
// returns err(component-not-present) (never throws) when the column is absent,
|
|
304
|
+
// so the column probe needs no registration guard (feat-20260602).
|
|
305
|
+
const existingFilter = world.get(entity, MeshFilter);
|
|
306
|
+
if (existingFilter.ok) {
|
|
307
|
+
ensureGlyphMeshMaterialSlots(world, existingFilter.value.assetHandle);
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const layout = layoutGlyphText(font, gt.text, gt.fontSize);
|
|
312
|
+
const bake = bakeGlyphMesh(world, layout);
|
|
313
|
+
if (!bake.ok) return null; // register fail-fast (should not happen for w15 output)
|
|
314
|
+
|
|
315
|
+
// F-1: resolve the entity-owned MSDF MaterialAsset so the
|
|
316
|
+
// `forgeax::msdf-text` shader + atlas texture + sampler are bound to this
|
|
317
|
+
// text entity (plan D-7). Without this the MeshRenderer would carry material
|
|
318
|
+
// handle 0 -> default mid-grey unlit, and the atlas would never be sampled.
|
|
319
|
+
const materialId = resolveTextMaterial(world, gt, font, slot);
|
|
320
|
+
|
|
321
|
+
world.addComponent(entity, {
|
|
322
|
+
component: MeshFilter,
|
|
323
|
+
data: { assetHandle: bake.value.handle },
|
|
324
|
+
});
|
|
325
|
+
world.addComponent(entity, {
|
|
326
|
+
component: MeshRenderer,
|
|
327
|
+
data: { materials: [materialId] },
|
|
328
|
+
});
|
|
329
|
+
entityCache.set(slot, {
|
|
330
|
+
handle: entity,
|
|
331
|
+
record: {
|
|
332
|
+
meshHandle: bake.value.handle,
|
|
333
|
+
signature,
|
|
334
|
+
materialHandle: materialId,
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function ensureGlyphMeshMaterialSlots(
|
|
341
|
+
world: World,
|
|
342
|
+
meshHandle: Handle<'MeshAsset', 'shared'>,
|
|
343
|
+
): void {
|
|
344
|
+
const mesh = world.sharedRefs.resolve<'MeshAsset', MeshAsset>(meshHandle);
|
|
345
|
+
if (mesh.ok && !Array.isArray(mesh.value.materialSlots)) {
|
|
346
|
+
Object.assign(mesh.value, { materialSlots: [{ slotName: 'Default' }] });
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Build the MSDF text MaterialAsset for one World/entity slot and
|
|
352
|
+
* return its raw unmanaged handle id. The material carries a single
|
|
353
|
+
* Transparent-queue pass on the `forgeax::msdf-text` shader with premultiplied
|
|
354
|
+
* blend, and values binding the tint color, packed atlas distance data, and an
|
|
355
|
+
* embedded atlas texture reference (the record stage supplies the sampler).
|
|
356
|
+
* HDR tint components (>1) flow through unchanged so bloom-enabled cameras
|
|
357
|
+
* pick up bright text (AC-12).
|
|
358
|
+
*/
|
|
359
|
+
function resolveTextMaterial(
|
|
360
|
+
world: World,
|
|
361
|
+
gt: GlyphTextData,
|
|
362
|
+
font: FontAsset,
|
|
363
|
+
slot: number,
|
|
364
|
+
): Handle<'MaterialAsset', 'shared'> {
|
|
365
|
+
const cache = worldMaterialCache(world);
|
|
366
|
+
const material = {
|
|
367
|
+
kind: 'material',
|
|
368
|
+
passes: [
|
|
369
|
+
{
|
|
370
|
+
name: 'text',
|
|
371
|
+
program: { module: 'forgeax::msdf-text' },
|
|
372
|
+
renderState: {
|
|
373
|
+
...{
|
|
374
|
+
blend: MSDF_TEXT_BLEND as never,
|
|
375
|
+
cullMode: 'none',
|
|
376
|
+
depthWriteEnabled: false,
|
|
377
|
+
depthCompare: 'less-equal',
|
|
378
|
+
},
|
|
379
|
+
tags: { LightMode: 'Forward' },
|
|
380
|
+
queue: 3000,
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
values: {
|
|
385
|
+
tintColor: [gt.color[0] ?? 1, gt.color[1] ?? 1, gt.color[2] ?? 1, gt.color[3] ?? 1],
|
|
386
|
+
distanceRange: [
|
|
387
|
+
font.common.distanceRange,
|
|
388
|
+
font.common.atlasWidth,
|
|
389
|
+
font.common.atlasHeight,
|
|
390
|
+
0,
|
|
391
|
+
],
|
|
392
|
+
baseColorTexture: { texture: font.atlas },
|
|
393
|
+
},
|
|
394
|
+
parameters: [
|
|
395
|
+
{ name: 'tintColor', type: 'color', default: [1, 1, 1, 1] },
|
|
396
|
+
{ name: 'distanceRange', type: 'vec4', default: [4, 512, 512, 0] },
|
|
397
|
+
{ name: 'baseColorTexture', type: 'texture' },
|
|
398
|
+
{ name: 'metallicRoughnessTexture', type: 'texture', optional: true },
|
|
399
|
+
{ name: 'normalTexture', type: 'texture', optional: true },
|
|
400
|
+
],
|
|
401
|
+
} satisfies MaterialAsset;
|
|
402
|
+
const id = world.allocSharedRef('MaterialAsset', material);
|
|
403
|
+
const previous = cache.get(slot);
|
|
404
|
+
cache.set(slot, id);
|
|
405
|
+
if (previous !== undefined && previous !== id) {
|
|
406
|
+
world.sharedRefs.release(previous);
|
|
407
|
+
}
|
|
408
|
+
return id;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function signatureOf(gt: GlyphTextData): string {
|
|
412
|
+
return `${gt.fontHandle}|${gt.fontSize}|${gt.text}|${gt.color[0]},${gt.color[1]},${gt.color[2]},${gt.color[3]}`;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Handle bridges: GlyphText.fontHandle / cached mesh ids are packed u32 values;
|
|
416
|
+
// AssetRegistry expects branded Handles. The brand is a compile-time phantom
|
|
417
|
+
// (runtime value is the raw number), so a cast is the canonical bridge
|
|
418
|
+
// (mirrors pick.ts toShared).
|
|
419
|
+
function asFontHandle(raw: number): Handle<'FontAsset', 'shared'> {
|
|
420
|
+
return toShared<'FontAsset'>(raw);
|
|
421
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import type { PrimitiveTopology } from '@forgeax/engine-types';
|
|
2
|
+
import type { BatchTopologyInspection } from '../inspection-types';
|
|
3
|
+
import type { RenderSceneApplyResult, RenderSceneSlot } from '../scene/render-scene-types';
|
|
4
|
+
|
|
5
|
+
export type { BatchTopologyInspection } from '../inspection-types';
|
|
6
|
+
|
|
7
|
+
export interface GpuDrivenBatchKey {
|
|
8
|
+
readonly assetHandle: number;
|
|
9
|
+
readonly drawKind: 'indexed' | 'non-indexed';
|
|
10
|
+
readonly first: number;
|
|
11
|
+
readonly count: number;
|
|
12
|
+
readonly baseVertex: number;
|
|
13
|
+
readonly materialSlot: number;
|
|
14
|
+
readonly topology: PrimitiveTopology;
|
|
15
|
+
readonly pipelineClass: string;
|
|
16
|
+
readonly materialResourceClass: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface GpuDrivenCandidate {
|
|
20
|
+
readonly primitiveIndex: number;
|
|
21
|
+
readonly generation: number;
|
|
22
|
+
readonly drawItemIndex: number;
|
|
23
|
+
readonly instanceOrdinal: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface GpuDrivenBatch {
|
|
27
|
+
readonly batchId: number;
|
|
28
|
+
readonly generation: number;
|
|
29
|
+
readonly key: GpuDrivenBatchKey;
|
|
30
|
+
readonly candidates: readonly GpuDrivenCandidate[];
|
|
31
|
+
readonly visibleBase: number;
|
|
32
|
+
readonly visibleCapacity: number;
|
|
33
|
+
readonly indirectOffset: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface SubmissionPlan {
|
|
37
|
+
readonly revision: number;
|
|
38
|
+
readonly batches: readonly GpuDrivenBatch[];
|
|
39
|
+
readonly candidateCount: number;
|
|
40
|
+
readonly visibleCapacity: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface MutableBatch {
|
|
44
|
+
readonly batchId: number;
|
|
45
|
+
readonly generation: number;
|
|
46
|
+
readonly key: GpuDrivenBatchKey;
|
|
47
|
+
readonly candidates: Map<string, GpuDrivenCandidate>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
|
|
51
|
+
const snapshot = slot.snapshot;
|
|
52
|
+
const draws = snapshot.gpuDrivenDraws;
|
|
53
|
+
if (
|
|
54
|
+
draws === undefined ||
|
|
55
|
+
draws.length === 0 ||
|
|
56
|
+
snapshot.localAabb === undefined ||
|
|
57
|
+
snapshot.skin !== undefined ||
|
|
58
|
+
snapshot.spriteInstances !== undefined
|
|
59
|
+
) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
return draws.map((draw) => ({
|
|
63
|
+
assetHandle: snapshot.assetHandle,
|
|
64
|
+
drawKind: draw.kind,
|
|
65
|
+
first: draw.first,
|
|
66
|
+
count: draw.count,
|
|
67
|
+
baseVertex: draw.baseVertex,
|
|
68
|
+
materialSlot: draw.materialSlot,
|
|
69
|
+
topology: draw.topology,
|
|
70
|
+
pipelineClass: draw.pipelineClass,
|
|
71
|
+
materialResourceClass: draw.materialResourceClass,
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function keyText(key: GpuDrivenBatchKey): string {
|
|
76
|
+
return JSON.stringify(key);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function alignInstanceBase(value: number): number {
|
|
80
|
+
// Raster binds each batch's visible-index and compact-transform segment at
|
|
81
|
+
// a static storage-buffer offset. WebGPU requires those offsets to satisfy
|
|
82
|
+
// minStorageBufferOffsetAlignment (256 bytes on the portable baseline), so
|
|
83
|
+
// both the u32 stream (64 entries) and mat4 stream (4 entries) align when
|
|
84
|
+
// the shared instance base is a multiple of 64.
|
|
85
|
+
return Math.ceil(value / 64) * 64;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Stable compatibility grouping; per-view visibility never mutates this owner. */
|
|
89
|
+
export class BatchTopology {
|
|
90
|
+
private readonly batches = new Map<string, MutableBatch>();
|
|
91
|
+
private readonly membershipByPrimitive = new Map<
|
|
92
|
+
number,
|
|
93
|
+
readonly { readonly batchText: string; readonly candidateKey: string }[]
|
|
94
|
+
>();
|
|
95
|
+
private readonly ineligiblePrimitives = new Set<number>();
|
|
96
|
+
private readonly generationByBatchId: number[] = [];
|
|
97
|
+
private readonly freeBatchIds: number[] = [];
|
|
98
|
+
private revision = 0;
|
|
99
|
+
private rebuilds = 0;
|
|
100
|
+
private patches = 0;
|
|
101
|
+
private cachedPlan: SubmissionPlan | undefined;
|
|
102
|
+
|
|
103
|
+
rebuild(slots: readonly RenderSceneSlot[]): void {
|
|
104
|
+
this.batches.clear();
|
|
105
|
+
this.membershipByPrimitive.clear();
|
|
106
|
+
this.ineligiblePrimitives.clear();
|
|
107
|
+
this.generationByBatchId.length = 0;
|
|
108
|
+
this.freeBatchIds.length = 0;
|
|
109
|
+
for (const slot of slots) this.add(slot);
|
|
110
|
+
this.revision += 1;
|
|
111
|
+
this.rebuilds += 1;
|
|
112
|
+
this.cachedPlan = undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
apply(delta: RenderSceneApplyResult): boolean {
|
|
116
|
+
let changed = false;
|
|
117
|
+
for (const removed of delta.removedSlots) changed = this.remove(removed.slot) || changed;
|
|
118
|
+
for (const slot of delta.recreatedSlots) {
|
|
119
|
+
changed = this.remove(slot.slot) || changed;
|
|
120
|
+
changed = this.add(slot) || changed;
|
|
121
|
+
}
|
|
122
|
+
for (const slot of delta.updatedSlots) {
|
|
123
|
+
const instanceCount = slot.snapshot.instances?.instanceCount ?? 1;
|
|
124
|
+
const nextTexts = eligibleKeys(slot).flatMap((key) =>
|
|
125
|
+
Array.from({ length: instanceCount }, () => keyText(key)),
|
|
126
|
+
);
|
|
127
|
+
const current = this.membershipByPrimitive.get(slot.slot) ?? [];
|
|
128
|
+
if (
|
|
129
|
+
current.length === nextTexts.length &&
|
|
130
|
+
current.every((membership, index) => membership.batchText === nextTexts[index])
|
|
131
|
+
) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
changed = this.remove(slot.slot) || changed;
|
|
135
|
+
changed = this.add(slot) || changed;
|
|
136
|
+
}
|
|
137
|
+
for (const slot of delta.createdSlots) changed = this.add(slot) || changed;
|
|
138
|
+
if (changed) {
|
|
139
|
+
this.revision += 1;
|
|
140
|
+
this.patches += 1;
|
|
141
|
+
this.cachedPlan = undefined;
|
|
142
|
+
}
|
|
143
|
+
return changed;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
plan(): SubmissionPlan {
|
|
147
|
+
if (this.cachedPlan !== undefined) return this.cachedPlan;
|
|
148
|
+
const ordered = [...this.batches.values()].sort((left, right) => left.batchId - right.batchId);
|
|
149
|
+
let visibleBase = 0;
|
|
150
|
+
const batches = ordered.map((batch): GpuDrivenBatch => {
|
|
151
|
+
visibleBase = alignInstanceBase(visibleBase);
|
|
152
|
+
const candidates = [...batch.candidates.values()].sort(
|
|
153
|
+
(left, right) =>
|
|
154
|
+
left.primitiveIndex - right.primitiveIndex ||
|
|
155
|
+
left.drawItemIndex - right.drawItemIndex ||
|
|
156
|
+
left.instanceOrdinal - right.instanceOrdinal,
|
|
157
|
+
);
|
|
158
|
+
const result = {
|
|
159
|
+
batchId: batch.batchId,
|
|
160
|
+
generation: batch.generation,
|
|
161
|
+
key: batch.key,
|
|
162
|
+
candidates,
|
|
163
|
+
visibleBase,
|
|
164
|
+
visibleCapacity: candidates.length,
|
|
165
|
+
indirectOffset: batch.batchId * 20,
|
|
166
|
+
};
|
|
167
|
+
visibleBase += candidates.length;
|
|
168
|
+
return Object.freeze(result);
|
|
169
|
+
});
|
|
170
|
+
this.cachedPlan = Object.freeze({
|
|
171
|
+
revision: this.revision,
|
|
172
|
+
batches: Object.freeze(batches),
|
|
173
|
+
candidateCount: batches.reduce((total, batch) => total + batch.candidates.length, 0),
|
|
174
|
+
visibleCapacity: visibleBase,
|
|
175
|
+
});
|
|
176
|
+
return this.cachedPlan;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
inspect(): BatchTopologyInspection {
|
|
180
|
+
let candidateCount = 0;
|
|
181
|
+
for (const batch of this.batches.values()) candidateCount += batch.candidates.size;
|
|
182
|
+
return {
|
|
183
|
+
revision: this.revision,
|
|
184
|
+
batchCount: this.batches.size,
|
|
185
|
+
candidateCount,
|
|
186
|
+
rebuilds: this.rebuilds,
|
|
187
|
+
patches: this.patches,
|
|
188
|
+
ineligible: this.ineligiblePrimitives.size,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private add(slot: RenderSceneSlot): boolean {
|
|
193
|
+
const keys = eligibleKeys(slot);
|
|
194
|
+
if (keys.length === 0) {
|
|
195
|
+
this.ineligiblePrimitives.add(slot.slot);
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
this.ineligiblePrimitives.delete(slot.slot);
|
|
199
|
+
const memberships: Array<{ batchText: string; candidateKey: string }> = [];
|
|
200
|
+
const instanceCount = slot.snapshot.instances?.instanceCount ?? 1;
|
|
201
|
+
for (let drawItemIndex = 0; drawItemIndex < keys.length; drawItemIndex += 1) {
|
|
202
|
+
const key = keys[drawItemIndex];
|
|
203
|
+
if (key === undefined) continue;
|
|
204
|
+
const text = keyText(key);
|
|
205
|
+
let batch = this.batches.get(text);
|
|
206
|
+
if (batch === undefined) {
|
|
207
|
+
const reused = this.freeBatchIds.pop();
|
|
208
|
+
const batchId = reused ?? this.generationByBatchId.length;
|
|
209
|
+
const generation = reused === undefined ? 0 : (this.generationByBatchId[batchId] ?? -1) + 1;
|
|
210
|
+
this.generationByBatchId[batchId] = generation;
|
|
211
|
+
batch = { batchId, generation, key, candidates: new Map() };
|
|
212
|
+
this.batches.set(text, batch);
|
|
213
|
+
}
|
|
214
|
+
for (let instanceOrdinal = 0; instanceOrdinal < instanceCount; instanceOrdinal += 1) {
|
|
215
|
+
const candidateKey = `${slot.slot}:${drawItemIndex}:${instanceOrdinal}`;
|
|
216
|
+
batch.candidates.set(candidateKey, {
|
|
217
|
+
primitiveIndex: slot.slot,
|
|
218
|
+
generation: slot.generation,
|
|
219
|
+
drawItemIndex,
|
|
220
|
+
instanceOrdinal,
|
|
221
|
+
});
|
|
222
|
+
memberships.push({ batchText: text, candidateKey });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
this.membershipByPrimitive.set(slot.slot, memberships);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private remove(primitiveIndex: number): boolean {
|
|
230
|
+
this.ineligiblePrimitives.delete(primitiveIndex);
|
|
231
|
+
const memberships = this.membershipByPrimitive.get(primitiveIndex);
|
|
232
|
+
this.membershipByPrimitive.delete(primitiveIndex);
|
|
233
|
+
if (memberships === undefined) return false;
|
|
234
|
+
for (const membership of memberships) {
|
|
235
|
+
const batch = this.batches.get(membership.batchText);
|
|
236
|
+
if (batch === undefined) continue;
|
|
237
|
+
batch.candidates.delete(membership.candidateKey);
|
|
238
|
+
if (batch.candidates.size === 0) {
|
|
239
|
+
this.batches.delete(membership.batchText);
|
|
240
|
+
this.freeBatchIds.push(batch.batchId);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
}
|