@forgeax/engine-render 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +842 -124
- package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
- package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +52 -0
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +3 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/gpu-driven-owner.d.ts +10 -0
- package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +19 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +7 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +3 -1
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/recovery/failure-location.d.ts +12 -0
- package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
- package/dist/assembly/recovery/renderer-recover.d.ts +6 -4
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
- package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-helpers.d.ts +3 -0
- package/dist/assembly/renderer-helpers.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +4 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +6 -0
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
- package/dist/assembly/skin-palette-owner.d.ts +8 -0
- package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-device-loss.d.ts +15 -0
- package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +7 -3
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +7 -141
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
- package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
- package/dist/authoring.mjs +3 -3
- package/dist/{chunk-ADHHVYLW.mjs → chunk-33XZFTQU.mjs} +245 -39
- package/dist/chunk-33XZFTQU.mjs.map +1 -0
- package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
- package/dist/chunk-BLXGONR2.mjs.map +1 -0
- package/dist/{chunk-KM2NOX2I.mjs → chunk-BQVQOQJH.mjs} +958 -254
- package/dist/chunk-BQVQOQJH.mjs.map +1 -0
- package/dist/{chunk-HKXTW355.mjs → chunk-BTWH7BP4.mjs} +386 -17
- package/dist/chunk-BTWH7BP4.mjs.map +1 -0
- package/dist/{chunk-TMIASV2N.mjs → chunk-FUODTTIA.mjs} +3934 -676
- package/dist/chunk-FUODTTIA.mjs.map +1 -0
- package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
- package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
- package/dist/{chunk-E34VL5VI.mjs → chunk-JQTSEI3Z.mjs} +3 -3
- package/dist/{chunk-E34VL5VI.mjs.map → chunk-JQTSEI3Z.mjs.map} +1 -1
- package/dist/{chunk-GE3SDD72.mjs → chunk-NICXSHAT.mjs} +16 -38
- package/dist/chunk-NICXSHAT.mjs.map +1 -0
- package/dist/{chunk-ZZ4YQ474.mjs → chunk-NRNXBLIJ.mjs} +577 -7
- package/dist/chunk-NRNXBLIJ.mjs.map +1 -0
- package/dist/{chunk-JDWARUOI.mjs → chunk-PA5DRJNI.mjs} +17 -3
- package/dist/chunk-PA5DRJNI.mjs.map +1 -0
- package/dist/{chunk-XDP6XE5V.mjs → chunk-S4DNKQYQ.mjs} +1118 -446
- package/dist/chunk-S4DNKQYQ.mjs.map +1 -0
- package/dist/components/camera.d.ts +62 -2
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +6 -20
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/scene-instance.d.ts +2 -1
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/screen-space-reflection.d.ts +14 -0
- package/dist/components/screen-space-reflection.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +13805 -7186
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +11 -17
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/mesh-residency-lifetime.d.ts +21 -0
- package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
- package/dist/dynamic-geometry.d.ts +125 -0
- package/dist/dynamic-geometry.d.ts.map +1 -0
- package/dist/environment/background.d.ts +6 -0
- package/dist/environment/background.d.ts.map +1 -0
- package/dist/errors/gpu-driven.d.ts +6 -3
- package/dist/errors/gpu-driven.d.ts.map +1 -1
- package/dist/errors/render.d.ts +7 -4
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +33 -3
- package/dist/extract/gpu-driven.d.ts.map +1 -1
- package/dist/features/host.d.ts +23 -1
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/noise-texture.d.ts +17 -0
- package/dist/features/noise-texture.d.ts.map +1 -0
- package/dist/features/plan.d.ts +83 -2
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +37 -4
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/features/prepared-graphics.d.ts +5 -0
- package/dist/features/prepared-graphics.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts +5 -3
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +11 -3
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +19 -3
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/types.d.ts +11 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +2 -0
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/pbr-program.d.ts +10 -0
- package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +144 -23
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-views.d.ts +126 -0
- package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +18 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +2 -8
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +14 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-texture-usage.d.ts +1 -0
- package/dist/gpu-texture-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +6 -0
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts +8 -0
- package/dist/ibl/frame-resources.d.ts.map +1 -0
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +21 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +8 -7
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +164 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +11 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -1
- package/dist/instances.d.ts +89 -44
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +118 -10
- package/dist/internal.mjs.map +1 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/material-row.d.ts +5 -0
- package/dist/material-row.d.ts.map +1 -0
- package/dist/materials.d.ts +15 -0
- package/dist/materials.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +21 -5
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
- package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
- package/dist/pipeline/standard-output/graph.d.ts +15 -0
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
- package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/resources.d.ts +10 -0
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
- package/dist/pipeline/standard-output/types.d.ts +39 -0
- package/dist/pipeline/standard-output/types.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +2 -2
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec-types.d.ts +4 -0
- package/dist/pipeline-spec-types.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +1 -9
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/points-lines/standard-owner.d.ts +1 -1
- package/dist/points-lines/standard-owner.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +3 -3
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +106 -5
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +39 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +7 -8
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +38 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +2 -10
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +12 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +15 -6
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/prepared-material-bindings.d.ts +19 -0
- package/dist/record/prepared-material-bindings.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts +2 -9
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +76 -26
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +62 -7
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +35 -7
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +1 -0
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +10 -2
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/recovery/render-system-roots.d.ts +11 -0
- package/dist/recovery/render-system-roots.d.ts.map +1 -0
- package/dist/recovery/types.d.ts +76 -0
- package/dist/recovery/types.d.ts.map +1 -0
- package/dist/reflection/record-owner.d.ts +0 -2
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +185 -30
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +64 -5
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +7 -5
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +101 -41
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-projections.d.ts +22 -0
- package/dist/render-system-projections.d.ts.map +1 -0
- package/dist/render-system.d.ts +34 -77
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +14 -7
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +29 -11
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/shadow-visibility.d.ts +5 -0
- package/dist/scene/shadow-visibility.d.ts.map +1 -0
- package/dist/ssr/admission.d.ts +70 -1
- package/dist/ssr/admission.d.ts.map +1 -1
- package/dist/ssr/compose.d.ts +13 -0
- package/dist/ssr/compose.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +35 -0
- package/dist/ssr/errors.d.ts.map +1 -1
- package/dist/ssr/graph.d.ts +60 -0
- package/dist/ssr/graph.d.ts.map +1 -0
- package/dist/ssr/history.d.ts +97 -0
- package/dist/ssr/history.d.ts.map +1 -0
- package/dist/ssr/hiz.d.ts +37 -0
- package/dist/ssr/hiz.d.ts.map +1 -0
- package/dist/ssr/inspection.d.ts +42 -0
- package/dist/ssr/inspection.d.ts.map +1 -0
- package/dist/ssr/resources.d.ts +58 -0
- package/dist/ssr/resources.d.ts.map +1 -0
- package/dist/ssr/temporal.d.ts +38 -0
- package/dist/ssr/temporal.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +32 -10
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +15 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +9 -0
- package/dist/systems/transparent-dispatch.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +7 -0
- package/dist/targets/material-source.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts +7 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +8 -0
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/history.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -6
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts +2 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/temporal-view.d.ts +2 -0
- package/dist/temporal/temporal-view.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +35 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +3 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +6 -0
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
- package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
- package/src/__tests__/auto-exposure.browser.test.ts +33 -0
- package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
- package/src/__tests__/detached-inspection.integration.test.ts +5 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
- package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
- package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
- package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
- package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
- package/src/__tests__/factory-contract.integration.test.ts +73 -22
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
- package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
- package/src/__tests__/feature-noise.unit.test.ts +38 -0
- package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
- package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
- package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
- package/src/__tests__/frame-targets.unit.test.ts +24 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +287 -6
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
- package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
- package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +264 -0
- package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +349 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1417 -0
- package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +1075 -93
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
- package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
- package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
- package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
- package/src/__tests__/gpu-driven-view.unit.test.ts +159 -52
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -1
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
- package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
- package/src/__tests__/gpu-scene.unit.test.ts +559 -33
- package/src/__tests__/instances-culling.integration.test.ts +36 -10
- package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
- package/src/__tests__/instances-store.unit.test.ts +242 -39
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
- package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
- package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
- package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
- package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
- package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
- package/src/__tests__/material-texture-source.unit.test.ts +87 -0
- package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
- package/src/__tests__/materials-standard-contract.unit.test.ts +52 -2
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
- package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
- package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +37 -3
- package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
- package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
- package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +35 -4
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
- package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
- package/src/__tests__/public-surface.test-d.ts +3 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
- package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +104 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +2 -1
- package/src/__tests__/render-error-code-owner.test-d.ts +4 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +22 -0
- package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
- package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
- package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
- package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
- package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
- package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +914 -23
- package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
- package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
- package/src/__tests__/render-target-material-source.test-d.ts +27 -3
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +61 -1
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
- package/src/__tests__/shader-manifest-fixture.ts +39 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
- package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
- package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +118 -14
- package/src/__tests__/specular-environment-scale.dawn.test.ts +156 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
- package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
- package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
- package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +91 -0
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +112 -0
- package/src/__tests__/ssr-gpu-dispatch.ts +946 -0
- package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
- package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
- package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
- package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
- package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
- package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
- package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
- package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
- package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
- package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
- package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
- package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
- package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
- package/src/__tests__/ssr-reprojection-probe.ts +90 -0
- package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
- package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
- package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
- package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
- package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
- package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +44 -12
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
- package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
- package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
- package/src/__tests__/standard-output.browser.test.ts +15 -0
- package/src/__tests__/standard-output.dawn.test.ts +15 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +38 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
- package/src/__tests__/standard-profile-oracle.unit.test.ts +22 -0
- package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
- package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
- package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
- package/src/__tests__/taa-coverage-edge.dawn.test.ts +193 -0
- package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
- package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +778 -0
- package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
- package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
- package/src/__tests__/taa-stability-feedback.ts +341 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
- package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
- package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
- package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
- package/src/__tests__/visibility-extract.perf.test.ts +20 -8
- package/src/__tests__/visibility-instances.integration.test.ts +19 -7
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
- package/src/assembly/atmosphere-shader-prewarm.ts +38 -0
- package/src/assembly/dynamic-geometry-host.ts +887 -0
- package/src/assembly/dynamic-geometry-runtime.ts +71 -0
- package/src/assembly/factory.ts +4 -0
- package/src/assembly/gpu-driven-owner.ts +29 -0
- package/src/assembly/host-contract.ts +36 -0
- package/src/assembly/material/assembly.ts +38 -0
- package/src/assembly/material-shader-policy.ts +71 -28
- package/src/assembly/recovery/failure-location.ts +62 -0
- package/src/assembly/recovery/renderer-recover.ts +19 -17
- package/src/assembly/renderer-facade.ts +29 -0
- package/src/assembly/renderer-feature-inspection.ts +13 -0
- package/src/assembly/renderer-frame-transaction.ts +63 -0
- package/src/assembly/renderer-helpers.ts +26 -0
- package/src/assembly/renderer-inspection.ts +6 -0
- package/src/assembly/shader-prewarm-policy.ts +32 -0
- package/src/assembly/skin-palette-owner.ts +21 -0
- package/src/assembly/ssr-shader-prewarm.ts +41 -0
- package/src/assembly/webgpu-device-loss.ts +75 -0
- package/src/assembly/webgpu-pbr-ready.ts +232 -0
- package/src/assembly/webgpu-ready-mipmap.ts +26 -0
- package/src/assembly/webgpu-ready.ts +142 -121
- package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
- package/src/assembly/webgpu-renderer-contract.ts +69 -0
- package/src/assembly/webgpu-renderer-guards.ts +32 -0
- package/src/assembly/webgpu-renderer-observation.ts +43 -0
- package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
- package/src/assembly/webgpu-renderer.ts +675 -614
- package/src/assembly/webgpu-vertex-layouts.ts +233 -87
- package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
- package/src/components/camera.ts +287 -7
- package/src/components/index.ts +1 -0
- package/src/components/instances.ts +45 -18
- package/src/components/scene-instance.ts +2 -1
- package/src/components/screen-space-reflection.ts +21 -0
- package/src/components/sprite-animation.ts +3 -3
- package/src/components/sprite-instances.ts +1 -1
- package/src/device/gpu-residency.ts +96 -93
- package/src/device/mesh-residency-lifetime.ts +73 -0
- package/src/dynamic-geometry.ts +736 -0
- package/src/environment/background.ts +263 -0
- package/src/errors/gpu-driven.ts +39 -5
- package/src/errors/render.ts +27 -3
- package/src/extract/camera.ts +26 -1
- package/src/extract/gpu-driven.ts +185 -10
- package/src/features/host.ts +237 -19
- package/src/features/noise-texture.ts +91 -0
- package/src/features/plan.ts +553 -24
- package/src/features/prepared-gpu-work.ts +631 -49
- package/src/features/prepared-graphics-store.ts +31 -0
- package/src/features/prepared-graphics.ts +5 -0
- package/src/features/render-graph-compute.ts +41 -8
- package/src/features/render-graph-contribution.ts +141 -3
- package/src/features/render-graph-raster.ts +143 -30
- package/src/features/types.ts +11 -0
- package/src/fullscreen-post-process-pass.ts +3 -0
- package/src/gpu-driven/batch-topology.ts +424 -102
- package/src/gpu-driven/pbr-program.ts +31 -0
- package/src/gpu-driven/prepared-draw.ts +29 -4
- package/src/gpu-driven/production-raster.ts +2267 -694
- package/src/gpu-driven/shadow-views.ts +539 -0
- package/src/gpu-driven/view-gpu.ts +188 -41
- package/src/gpu-scene-schema.ts +52 -11
- package/src/gpu-scene.ts +186 -99
- package/src/gpu-texture-usage.ts +1 -0
- package/src/hdrp-buffers.ts +72 -36
- package/src/ibl/frame-resources.ts +38 -0
- package/src/ibl/skylight-bind-group.ts +5 -4
- package/src/index.ts +125 -1
- package/src/inspection-types.ts +191 -0
- package/src/instances-derived-bounds.ts +258 -34
- package/src/instances.ts +459 -150
- package/src/internal.ts +22 -0
- package/src/lifecycle.ts +2 -0
- package/src/material-row.ts +145 -0
- package/src/materials.ts +44 -8
- package/src/pbr-pipeline.ts +159 -17
- package/src/pipeline/standard-forward-lane.ts +52 -24
- package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
- package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
- package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
- package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
- package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
- package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
- package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
- package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
- package/src/pipeline/standard-output/color-transform.ts +124 -0
- package/src/pipeline/standard-output/graph.ts +139 -0
- package/src/pipeline/standard-output/lut-admission.ts +121 -0
- package/src/pipeline/standard-output/lut-gpu.ts +399 -0
- package/src/pipeline/standard-output/lut-state.ts +176 -0
- package/src/pipeline/standard-output/resources.ts +121 -0
- package/src/pipeline/standard-output/types.ts +58 -0
- package/src/pipeline/standard-pipeline.ts +192 -59
- package/src/pipeline/standard-post.ts +186 -27
- package/src/pipeline-builder.ts +16 -6
- package/src/pipeline-spec-types.ts +4 -0
- package/src/pipeline-spec.ts +37 -29
- package/src/points-lines/standard-owner.ts +6 -14
- package/src/prepare/prepared-graphics-resolver.ts +9 -2
- package/src/record/__tests__/material-slot-plan.unit.test.ts +48 -0
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +2 -29
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +36 -5
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
- package/src/record/dynamic-geometry-consumption.ts +59 -0
- package/src/record/frame-lighting.ts +12 -11
- package/src/record/frame-snapshot.ts +133 -23
- package/src/record/frame-targets.ts +9 -0
- package/src/record/frame.ts +727 -133
- package/src/record/main-pass-geometry.ts +162 -98
- package/src/record/main-pass-material.ts +115 -26
- package/src/record/main-pass-sprite-draws.ts +18 -107
- package/src/record/main-pass.ts +78 -8
- package/src/record/material-uniforms.ts +1 -1
- package/src/record/mesh-ssbo.ts +59 -15
- package/src/record/prepared-material-bindings.ts +234 -0
- package/src/record/recovery-pipeline.ts +59 -136
- package/src/record/render-context.ts +92 -22
- package/src/record/shadow-pass.ts +1231 -209
- package/src/record/skybox-post-pass.ts +14 -3
- package/src/record/typed-frame-graph.ts +1006 -53
- package/src/record/view-ubo.ts +11 -0
- package/src/recovery/render-system-candidate.ts +90 -66
- package/src/recovery/render-system-roots.ts +113 -0
- package/src/recovery/types.ts +77 -0
- package/src/reflection/record-owner.ts +26 -54
- package/src/render-contract.ts +219 -25
- package/src/render-graph-primitives.ts +6 -2
- package/src/render-pipeline.ts +70 -1
- package/src/render-system-extract-tail.ts +409 -160
- package/src/render-system-extract.ts +376 -102
- package/src/render-system-projections.ts +241 -0
- package/src/render-system.ts +692 -791
- package/src/scene/render-scene-types.ts +13 -4
- package/src/scene/render-scene.ts +569 -355
- package/src/scene/shadow-visibility.ts +21 -0
- package/src/ssr/admission.ts +380 -14
- package/src/ssr/compose.ts +144 -0
- package/src/ssr/errors.ts +48 -0
- package/src/ssr/graph.ts +777 -0
- package/src/ssr/history.ts +436 -0
- package/src/ssr/hiz.ts +124 -0
- package/src/ssr/inspection.ts +124 -0
- package/src/ssr/resources.ts +202 -0
- package/src/ssr/temporal.ts +164 -0
- package/src/systems/skin-palette-allocator.ts +495 -148
- package/src/systems/skin-palette-types.ts +17 -0
- package/src/systems/transparent-dispatch.ts +90 -0
- package/src/targets/material-source.ts +34 -0
- package/src/temporal/coverage.ts +1 -1
- package/src/temporal/frame-coordinator.ts +23 -2
- package/src/temporal/gpu.ts +74 -12
- package/src/temporal/history.ts +3 -1
- package/src/temporal/inspection.ts +2 -1
- package/src/temporal/standard-scene-data.ts +3 -1
- package/src/temporal/temporal-view.ts +3 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +204 -139
- package/src/typed-render-graph-primitives.ts +266 -74
- package/src/typed-shadow-passes.ts +122 -12
- package/src/volume/temporal.ts +10 -0
- package/dist/chunk-ADHHVYLW.mjs.map +0 -1
- package/dist/chunk-FJ6P52EE.mjs.map +0 -1
- package/dist/chunk-GE3SDD72.mjs.map +0 -1
- package/dist/chunk-GF523LHF.mjs.map +0 -1
- package/dist/chunk-HKXTW355.mjs.map +0 -1
- package/dist/chunk-JDWARUOI.mjs.map +0 -1
- package/dist/chunk-KM2NOX2I.mjs.map +0 -1
- package/dist/chunk-TMIASV2N.mjs.map +0 -1
- package/dist/chunk-XDP6XE5V.mjs.map +0 -1
- package/dist/chunk-ZZ4YQ474.mjs.map +0 -1
- package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
|
@@ -44,6 +44,15 @@ function snapshot(entityKey: number, x: number): RenderableSnapshot {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function updateSnapshot(value: RenderableSnapshot) {
|
|
48
|
+
return {
|
|
49
|
+
kind: 'update' as const,
|
|
50
|
+
worldId: value.worldId,
|
|
51
|
+
entityKey: value.entityKey,
|
|
52
|
+
snapshot: value,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
47
56
|
export interface GpuDrivenViewGpuEvidence {
|
|
48
57
|
readonly visibleInstance: number;
|
|
49
58
|
readonly indexCount: number;
|
|
@@ -90,12 +99,17 @@ export async function runGpuDrivenViewLifecycleEvidence(
|
|
|
90
99
|
for (let frame = 0; frame < frames; frame += 1) {
|
|
91
100
|
const targetCount = frame < 4 ? 2 ** frame : frame % 2 === 0 ? 1 : 8;
|
|
92
101
|
const operations: Array<
|
|
93
|
-
| {
|
|
102
|
+
| {
|
|
103
|
+
readonly kind: 'update';
|
|
104
|
+
readonly worldId: number;
|
|
105
|
+
readonly entityKey: number;
|
|
106
|
+
readonly snapshot: RenderableSnapshot;
|
|
107
|
+
}
|
|
94
108
|
| { readonly kind: 'remove'; readonly worldId: number; readonly entityKey: number }
|
|
95
109
|
> = [];
|
|
96
110
|
while (activeCount < targetCount) {
|
|
97
111
|
activeCount += 1;
|
|
98
|
-
operations.push(
|
|
112
|
+
operations.push(updateSnapshot(snapshot(activeCount, activeCount * 0.05)));
|
|
99
113
|
}
|
|
100
114
|
while (activeCount > targetCount) {
|
|
101
115
|
operations.push({ kind: 'remove', worldId: 0, entityKey: activeCount });
|
|
@@ -140,6 +154,9 @@ export async function runGpuDrivenViewLifecycleEvidence(
|
|
|
140
154
|
export async function runGpuDrivenViewGpuEvidence(): Promise<GpuDrivenViewGpuEvidence> {
|
|
141
155
|
const adapter = (await rhi.requestAdapter()).unwrap();
|
|
142
156
|
const device = (await adapter.requestDevice()).unwrap();
|
|
157
|
+
const rawDevice = _internal_getRawDevice(device);
|
|
158
|
+
if (rawDevice === undefined) throw new Error('GPU-driven evidence raw device unavailable');
|
|
159
|
+
rawDevice.pushErrorScope('validation');
|
|
143
160
|
const shader = (
|
|
144
161
|
await rhi.createShaderModule(device, {
|
|
145
162
|
code: GPU_DRIVEN_VIEW_WGSL,
|
|
@@ -168,19 +185,16 @@ export async function runGpuDrivenViewGpuEvidence(): Promise<GpuDrivenViewGpuEvi
|
|
|
168
185
|
],
|
|
169
186
|
};
|
|
170
187
|
const delta = projection.apply([
|
|
171
|
-
{
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
...
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
cacheKey: 1,
|
|
179
|
-
archVersion: 1,
|
|
180
|
-
},
|
|
188
|
+
updateSnapshot({
|
|
189
|
+
...instancedWithLod,
|
|
190
|
+
instances: {
|
|
191
|
+
transforms: new Float32Array([...visibleInstance, ...culledInstance]),
|
|
192
|
+
instanceCount: 2,
|
|
193
|
+
cacheKey: 1,
|
|
194
|
+
archVersion: 1,
|
|
181
195
|
},
|
|
182
|
-
},
|
|
183
|
-
|
|
196
|
+
}),
|
|
197
|
+
updateSnapshot(snapshot(2, 10)),
|
|
184
198
|
]);
|
|
185
199
|
const sceneAvailability = GpuScene.create(device, 2).unwrap();
|
|
186
200
|
if (sceneAvailability.status !== 'available') throw new Error('GPU Scene unavailable');
|
|
@@ -248,16 +262,54 @@ export async function runGpuDrivenViewGpuEvidence(): Promise<GpuDrivenViewGpuEvi
|
|
|
248
262
|
64,
|
|
249
263
|
);
|
|
250
264
|
device.queue.submit([encoder.finish().unwrap()]).unwrap();
|
|
251
|
-
await device.queue.onSubmittedWorkDone();
|
|
252
265
|
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
|
|
257
|
-
|
|
266
|
+
// Start observing immediately, then submit the cached graph again before
|
|
267
|
+
// the first mapAsync settles. The second copy must be skipped while the
|
|
268
|
+
// readback is pending; compute/raster work remains submit-able.
|
|
269
|
+
const pendingLodSelection = view.readLodSelection();
|
|
270
|
+
if (view.readLodSelection() !== pendingLodSelection) {
|
|
271
|
+
throw new Error('GPU-driven LOD telemetry did not coalesce concurrent observers');
|
|
272
|
+
}
|
|
273
|
+
const overlappingEncoder = device
|
|
274
|
+
.createCommandEncoder({ label: 'gpu-driven-evidence-overlap' })
|
|
275
|
+
.unwrap();
|
|
276
|
+
compiled.execute({ encoder: overlappingEncoder }).unwrap();
|
|
277
|
+
device.queue.submit([overlappingEncoder.finish().unwrap()]).unwrap();
|
|
278
|
+
const lodSelection = await pendingLodSelection;
|
|
258
279
|
if (lodSelection === undefined || lodSelection.batches.length !== lodSelection.batchCount) {
|
|
259
280
|
throw new Error('GPU-driven LOD selection readback unavailable or incomplete');
|
|
260
281
|
}
|
|
282
|
+
await device.queue.onSubmittedWorkDone();
|
|
283
|
+
|
|
284
|
+
// After unmap, a later cached-graph submission must restore telemetry
|
|
285
|
+
// observation rather than leaving the latch permanently consumed.
|
|
286
|
+
const recoveryProjection = mat4.identity(mat4.create());
|
|
287
|
+
recoveryProjection[12] = 10;
|
|
288
|
+
view
|
|
289
|
+
.update(
|
|
290
|
+
topology.plan(),
|
|
291
|
+
sceneAvailability.scene,
|
|
292
|
+
frustum.fromViewProjection(frustum.create(), recoveryProjection),
|
|
293
|
+
)
|
|
294
|
+
.unwrap();
|
|
295
|
+
const recoveryEncoder = device
|
|
296
|
+
.createCommandEncoder({ label: 'gpu-driven-evidence-recovery' })
|
|
297
|
+
.unwrap();
|
|
298
|
+
compiled.execute({ encoder: recoveryEncoder }).unwrap();
|
|
299
|
+
device.queue.submit([recoveryEncoder.finish().unwrap()]).unwrap();
|
|
300
|
+
await device.queue.onSubmittedWorkDone();
|
|
301
|
+
const recoveredLodSelection = await view.readLodSelection();
|
|
302
|
+
if (
|
|
303
|
+
recoveredLodSelection === undefined ||
|
|
304
|
+
recoveredLodSelection === lodSelection ||
|
|
305
|
+
recoveredLodSelection.visible === lodSelection.visible
|
|
306
|
+
) {
|
|
307
|
+
throw new Error('GPU-driven LOD telemetry did not recover after a skipped copy');
|
|
308
|
+
}
|
|
309
|
+
const validationError = await rawDevice.popErrorScope();
|
|
310
|
+
if (validationError !== null) {
|
|
311
|
+
throw new Error(`GPU-driven telemetry overlap validation failed: ${validationError.message}`);
|
|
312
|
+
}
|
|
261
313
|
|
|
262
314
|
const visibleMap = (await visibleReadback.mapAsync(GPU_MAP_MODE_READ)).unwrap();
|
|
263
315
|
const visibleValue = new DataView(visibleMap.getMappedRange().unwrap()).getUint32(0, true);
|
|
@@ -53,11 +53,26 @@ function snapshot(entityKey: number): RenderableSnapshot {
|
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
function updateSnapshot(value: RenderableSnapshot) {
|
|
57
|
+
return {
|
|
58
|
+
kind: 'update' as const,
|
|
59
|
+
worldId: value.worldId,
|
|
60
|
+
entityKey: value.entityKey,
|
|
61
|
+
snapshot: value,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
function preparedFrame(view: GpuDrivenView): PreparedGpuDrivenFrame {
|
|
57
66
|
return {
|
|
58
67
|
topologySignature: `view-generation:${view.inspect().resourceGeneration}`,
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
ownsAllDrawItems: true,
|
|
69
|
+
standardPbrFrameResources: {
|
|
70
|
+
materialBindGroups: [],
|
|
71
|
+
materialSlotIndicesByEntity: new Map(),
|
|
72
|
+
instancesBindGroup: {} as never,
|
|
73
|
+
materialStride: 0,
|
|
74
|
+
sceneMaterialBuffer: {} as never,
|
|
75
|
+
},
|
|
61
76
|
_commitResourceReplacement: () => view._commitResourceReplacement(),
|
|
62
77
|
project: (graph) => {
|
|
63
78
|
const projected = view.addPasses(graph);
|
|
@@ -126,8 +141,14 @@ describe('GpuDrivenView graph projection', () => {
|
|
|
126
141
|
if (first === null) return;
|
|
127
142
|
const prepared: PreparedGpuDrivenFrame = {
|
|
128
143
|
topologySignature: 'stable-gpu-driven-test',
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
ownsAllDrawItems: true,
|
|
145
|
+
standardPbrFrameResources: {
|
|
146
|
+
materialBindGroups: [],
|
|
147
|
+
materialSlotIndicesByEntity: new Map(),
|
|
148
|
+
instancesBindGroup: {} as never,
|
|
149
|
+
materialStride: 0,
|
|
150
|
+
sceneMaterialBuffer: {} as never,
|
|
151
|
+
},
|
|
131
152
|
_commitResourceReplacement: () => undefined,
|
|
132
153
|
project: (graph) => {
|
|
133
154
|
const pass = graph.addComputePass('gpu-driven-test', {
|
|
@@ -153,7 +174,7 @@ describe('GpuDrivenView graph projection', () => {
|
|
|
153
174
|
const device = (await adapter.requestDevice()).unwrap();
|
|
154
175
|
const shader = (await rhi.createShaderModule(device, { code: 'synthetic' })).unwrap();
|
|
155
176
|
const projection = new RenderScene();
|
|
156
|
-
const delta = projection.apply([
|
|
177
|
+
const delta = projection.apply([updateSnapshot(snapshot(1))]);
|
|
157
178
|
const sceneAvailability = GpuScene.create(device, 1).unwrap();
|
|
158
179
|
expect(sceneAvailability.status).toBe('available');
|
|
159
180
|
if (sceneAvailability.status !== 'available') return;
|
|
@@ -240,7 +261,7 @@ describe('GpuDrivenView graph projection', () => {
|
|
|
240
261
|
const shader = (await rhi.createShaderModule(device, { code: 'synthetic' })).unwrap();
|
|
241
262
|
const destroyBuffer = vi.spyOn(device, 'destroyBuffer');
|
|
242
263
|
const projection = new RenderScene();
|
|
243
|
-
const firstDelta = projection.apply([
|
|
264
|
+
const firstDelta = projection.apply([updateSnapshot(snapshot(1))]);
|
|
244
265
|
const sceneAvailability = GpuScene.create(device, 2).unwrap();
|
|
245
266
|
expect(sceneAvailability.status).toBe('available');
|
|
246
267
|
if (sceneAvailability.status !== 'available') return;
|
|
@@ -351,7 +372,7 @@ describe('GpuDrivenView graph projection', () => {
|
|
|
351
372
|
delete (device as unknown as { caps?: unknown }).caps;
|
|
352
373
|
delete (device as unknown as { surfaceViewFormats?: unknown }).surfaceViewFormats;
|
|
353
374
|
|
|
354
|
-
const secondDelta = projection.apply([
|
|
375
|
+
const secondDelta = projection.apply([updateSnapshot(snapshot(2))]);
|
|
355
376
|
sceneAvailability.scene.sync(secondDelta).unwrap();
|
|
356
377
|
topology.rebuild(projection.slotsSnapshot());
|
|
357
378
|
view.update(topology.plan(), sceneAvailability.scene, planes).unwrap();
|
|
@@ -389,7 +410,7 @@ describe('GpuDrivenView graph projection', () => {
|
|
|
389
410
|
const shader = (await rhi.createShaderModule(device, { code: 'synthetic' })).unwrap();
|
|
390
411
|
const destroyBuffer = vi.spyOn(device, 'destroyBuffer');
|
|
391
412
|
const projection = new RenderScene();
|
|
392
|
-
const firstDelta = projection.apply([
|
|
413
|
+
const firstDelta = projection.apply([updateSnapshot(snapshot(1))]);
|
|
393
414
|
const sceneAvailability = GpuScene.create(device, 2).unwrap();
|
|
394
415
|
expect(sceneAvailability.status).toBe('available');
|
|
395
416
|
if (sceneAvailability.status !== 'available') return;
|
|
@@ -406,7 +427,7 @@ describe('GpuDrivenView graph projection', () => {
|
|
|
406
427
|
expect(firstVisible).toBeDefined();
|
|
407
428
|
if (firstVisible === undefined) return;
|
|
408
429
|
|
|
409
|
-
const secondDelta = projection.apply([
|
|
430
|
+
const secondDelta = projection.apply([updateSnapshot(snapshot(2))]);
|
|
410
431
|
sceneAvailability.scene.sync(secondDelta).unwrap();
|
|
411
432
|
topology.rebuild(projection.slotsSnapshot());
|
|
412
433
|
view.update(topology.plan(), sceneAvailability.scene, planes).unwrap();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { frustum, mat4 } from '@forgeax/engine-math';
|
|
2
2
|
import { describe, expect, it } from 'vitest';
|
|
3
3
|
import { BatchTopology } from '../gpu-driven/batch-topology';
|
|
4
|
+
import { GPU_DRIVEN_VIEW_WGSL } from '../gpu-driven/view-gpu';
|
|
4
5
|
import type { MaterialSnapshot, RenderableSnapshot } from '../render-system-extract';
|
|
5
6
|
import { RenderScene } from '../scene/render-scene';
|
|
6
7
|
import { classifyGpuDrivenView } from './gpu-driven-view-reference';
|
|
@@ -38,13 +39,22 @@ function snapshot(entityKey: number, x: number, resourceClass = 'plain'): Render
|
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
function updateSnapshot(value: RenderableSnapshot) {
|
|
43
|
+
return {
|
|
44
|
+
kind: 'update' as const,
|
|
45
|
+
worldId: value.worldId,
|
|
46
|
+
entityKey: value.entityKey,
|
|
47
|
+
snapshot: value,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
41
51
|
describe('GPU-driven batch topology and CPU oracle', () => {
|
|
42
52
|
it('isolates LOD candidates so one indirect range cannot serve different meshes', () => {
|
|
43
53
|
const projection = new RenderScene();
|
|
44
54
|
const lods = [{ mesh: '00000000-0000-7000-8000-000000000001' as never, screenCoverage: 0.5 }];
|
|
45
55
|
projection.apply([
|
|
46
|
-
{
|
|
47
|
-
{
|
|
56
|
+
updateSnapshot({ ...snapshot(1, 0), lods }),
|
|
57
|
+
updateSnapshot({ ...snapshot(2, 4), lods }),
|
|
48
58
|
]);
|
|
49
59
|
const topology = new BatchTopology();
|
|
50
60
|
topology.rebuild(projection.slotsSnapshot());
|
|
@@ -54,7 +64,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
54
64
|
|
|
55
65
|
const transformOnly = projection.apply([
|
|
56
66
|
{
|
|
57
|
-
kind: 'update
|
|
67
|
+
kind: 'update',
|
|
58
68
|
worldId: 0,
|
|
59
69
|
entityKey: 1,
|
|
60
70
|
world: snapshot(1, 0.25).transform.world,
|
|
@@ -64,22 +74,19 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
64
74
|
|
|
65
75
|
const instancedProjection = new RenderScene();
|
|
66
76
|
instancedProjection.apply([
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
cacheKey: 3,
|
|
79
|
-
archVersion: 1,
|
|
80
|
-
},
|
|
77
|
+
updateSnapshot({
|
|
78
|
+
...snapshot(3, 0),
|
|
79
|
+
lods,
|
|
80
|
+
instances: {
|
|
81
|
+
transforms: new Float32Array([
|
|
82
|
+
...mat4.identity(mat4.create()),
|
|
83
|
+
...mat4.identity(mat4.create()),
|
|
84
|
+
]),
|
|
85
|
+
instanceCount: 2,
|
|
86
|
+
cacheKey: 3,
|
|
87
|
+
archVersion: 1,
|
|
81
88
|
},
|
|
82
|
-
},
|
|
89
|
+
}),
|
|
83
90
|
]);
|
|
84
91
|
const instancedTopology = new BatchTopology();
|
|
85
92
|
instancedTopology.rebuild(instancedProjection.slotsSnapshot());
|
|
@@ -89,12 +96,25 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
89
96
|
);
|
|
90
97
|
});
|
|
91
98
|
|
|
99
|
+
it('projects compact visible items into batch-local mesh and material indices', () => {
|
|
100
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toMatch(
|
|
101
|
+
/vec2<u32>\(\s*candidate\.submitAdmission >> 1u,\s*materialOrPalette,/,
|
|
102
|
+
);
|
|
103
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toContain('(candidate.submitAdmission & 1u)');
|
|
104
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toContain('instance.customDataStart');
|
|
105
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toContain('(candidate.materialSlot & 0x80000000u)');
|
|
106
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toContain('visibleIndices[candidate.visibleBase + localVisible]');
|
|
107
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toContain('overflowIndex(candidate.batchIndex)');
|
|
108
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toContain('visibleCount = 0u');
|
|
109
|
+
expect(GPU_DRIVEN_VIEW_WGSL).toContain('indirectArgs[args + 4u] = 0u');
|
|
110
|
+
});
|
|
111
|
+
|
|
92
112
|
it('patches topology only when compatibility membership changes', () => {
|
|
93
113
|
const projection = new RenderScene();
|
|
94
114
|
projection.apply([
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
115
|
+
updateSnapshot(snapshot(1, 0)),
|
|
116
|
+
updateSnapshot(snapshot(2, 0.5)),
|
|
117
|
+
updateSnapshot(snapshot(3, 0, 'textured')),
|
|
98
118
|
]);
|
|
99
119
|
const topology = new BatchTopology();
|
|
100
120
|
topology.rebuild(projection.slotsSnapshot());
|
|
@@ -103,7 +123,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
103
123
|
|
|
104
124
|
const transformOnly = projection.apply([
|
|
105
125
|
{
|
|
106
|
-
kind: 'update
|
|
126
|
+
kind: 'update',
|
|
107
127
|
worldId: 0,
|
|
108
128
|
entityKey: 1,
|
|
109
129
|
world: snapshot(1, 0.25).transform.world,
|
|
@@ -120,10 +140,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
120
140
|
|
|
121
141
|
it('compacts visible primitive indices and writes portable indexed indirect args', () => {
|
|
122
142
|
const projection = new RenderScene();
|
|
123
|
-
projection.apply([
|
|
124
|
-
{ kind: 'create', snapshot: snapshot(1, 0) },
|
|
125
|
-
{ kind: 'create', snapshot: snapshot(2, 10) },
|
|
126
|
-
]);
|
|
143
|
+
projection.apply([updateSnapshot(snapshot(1, 0)), updateSnapshot(snapshot(2, 10))]);
|
|
127
144
|
const topology = new BatchTopology();
|
|
128
145
|
topology.rebuild(projection.slotsSnapshot());
|
|
129
146
|
const planes = frustum.fromViewProjection(frustum.create(), mat4.identity(mat4.create()));
|
|
@@ -152,16 +169,13 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
152
169
|
expect(first).toBeDefined();
|
|
153
170
|
if (first === undefined) return;
|
|
154
171
|
projection.apply([
|
|
155
|
-
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
...
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
],
|
|
163
|
-
},
|
|
164
|
-
},
|
|
172
|
+
updateSnapshot({
|
|
173
|
+
...source,
|
|
174
|
+
gpuDrivenDraws: [
|
|
175
|
+
{ ...first, kind: 'non-indexed', first: 0, count: 3 },
|
|
176
|
+
{ ...first, kind: 'non-indexed', first: 3, count: 6 },
|
|
177
|
+
],
|
|
178
|
+
}),
|
|
165
179
|
]);
|
|
166
180
|
const topology = new BatchTopology();
|
|
167
181
|
topology.rebuild(projection.slotsSnapshot());
|
|
@@ -180,6 +194,105 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
180
194
|
expect(secondArgs.getUint32(12, true)).toBe(0);
|
|
181
195
|
});
|
|
182
196
|
|
|
197
|
+
it('retains source draw identity when an earlier compact draw is ineligible', () => {
|
|
198
|
+
const source = snapshot(1, 0);
|
|
199
|
+
const first = source.gpuDrivenDraws?.[0];
|
|
200
|
+
expect(first).toBeDefined();
|
|
201
|
+
if (first === undefined) return;
|
|
202
|
+
const projection = new RenderScene();
|
|
203
|
+
projection.apply([
|
|
204
|
+
updateSnapshot({
|
|
205
|
+
...source,
|
|
206
|
+
gpuDrivenDraws: [
|
|
207
|
+
{
|
|
208
|
+
...first,
|
|
209
|
+
drawItemIndex: 10,
|
|
210
|
+
prepared: {
|
|
211
|
+
identity: { material: 'custom', geometry: 'triangle', deformation: 'rigid' },
|
|
212
|
+
} as never,
|
|
213
|
+
},
|
|
214
|
+
{ ...first, drawItemIndex: 20, first: 9, count: 12 },
|
|
215
|
+
],
|
|
216
|
+
}),
|
|
217
|
+
]);
|
|
218
|
+
const topology = new BatchTopology();
|
|
219
|
+
topology.rebuild(projection.slotsSnapshot());
|
|
220
|
+
const candidates = topology.plan().batches.flatMap((batch) => batch.candidates);
|
|
221
|
+
expect(candidates).toHaveLength(1);
|
|
222
|
+
expect(candidates[0]?.drawItemIndex).toBe(20);
|
|
223
|
+
expect(topology.plan().batches[0]?.key).toMatchObject({ first: 9, count: 12 });
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('patches a same-key eligibility swap using the retained draw identity', () => {
|
|
227
|
+
const source = snapshot(1, 0);
|
|
228
|
+
const first = source.gpuDrivenDraws?.[0];
|
|
229
|
+
expect(first).toBeDefined();
|
|
230
|
+
if (first === undefined) return;
|
|
231
|
+
const ineligible = {
|
|
232
|
+
...first,
|
|
233
|
+
drawItemIndex: 10,
|
|
234
|
+
prepared: {
|
|
235
|
+
identity: { material: 'custom', geometry: 'triangle', deformation: 'rigid' },
|
|
236
|
+
} as never,
|
|
237
|
+
};
|
|
238
|
+
const eligible = { ...first, drawItemIndex: 20, first: 9, count: 12 };
|
|
239
|
+
const eligibleAt10 = { ...eligible, drawItemIndex: 10 };
|
|
240
|
+
const ineligibleAt20 = { ...ineligible, drawItemIndex: 20 };
|
|
241
|
+
const projection = new RenderScene();
|
|
242
|
+
projection.apply([updateSnapshot({ ...source, gpuDrivenDraws: [ineligible, eligible] })]);
|
|
243
|
+
const topology = new BatchTopology();
|
|
244
|
+
topology.rebuild(projection.slotsSnapshot());
|
|
245
|
+
const swapped = projection.apply([
|
|
246
|
+
updateSnapshot({ ...source, gpuDrivenDraws: [eligibleAt10, ineligibleAt20] }),
|
|
247
|
+
]);
|
|
248
|
+
expect(topology.apply(swapped)).toBe(true);
|
|
249
|
+
expect(topology.inspect().patches).toBe(1);
|
|
250
|
+
expect(topology.plan().batches.flatMap((batch) => batch.candidates)[0]?.drawItemIndex).toBe(10);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('keeps prepared material and range identity after reversing submesh order', () => {
|
|
254
|
+
const source = snapshot(1, 0);
|
|
255
|
+
const first = source.gpuDrivenDraws?.[0];
|
|
256
|
+
expect(first).toBeDefined();
|
|
257
|
+
if (first === undefined) return;
|
|
258
|
+
const materialA = { ...material, materialHandle: 11 } as MaterialSnapshot;
|
|
259
|
+
const materialB = { ...material, materialHandle: 12 } as MaterialSnapshot;
|
|
260
|
+
const orderedDraws = [
|
|
261
|
+
{ ...first, drawItemIndex: 4, materialSlot: 0, first: 0, count: 3 },
|
|
262
|
+
{ ...first, drawItemIndex: 9, materialSlot: 1, first: 3, count: 6 },
|
|
263
|
+
];
|
|
264
|
+
const [orderedFirst, orderedSecond] = orderedDraws;
|
|
265
|
+
if (orderedFirst === undefined || orderedSecond === undefined) return;
|
|
266
|
+
const ordered = {
|
|
267
|
+
...source,
|
|
268
|
+
materials: [materialA, materialB],
|
|
269
|
+
material: materialA,
|
|
270
|
+
gpuDrivenDraws: orderedDraws,
|
|
271
|
+
};
|
|
272
|
+
const reversed = {
|
|
273
|
+
...ordered,
|
|
274
|
+
gpuDrivenDraws: [orderedSecond, orderedFirst],
|
|
275
|
+
};
|
|
276
|
+
const orderedTopology = new BatchTopology();
|
|
277
|
+
const reversedTopology = new BatchTopology();
|
|
278
|
+
const orderedScene = new RenderScene();
|
|
279
|
+
const reversedScene = new RenderScene();
|
|
280
|
+
orderedScene.apply([updateSnapshot(ordered)]);
|
|
281
|
+
reversedScene.apply([updateSnapshot(reversed)]);
|
|
282
|
+
orderedTopology.rebuild(orderedScene.slotsSnapshot());
|
|
283
|
+
reversedTopology.rebuild(reversedScene.slotsSnapshot());
|
|
284
|
+
const describe = (topology: BatchTopology) =>
|
|
285
|
+
topology
|
|
286
|
+
.plan()
|
|
287
|
+
.batches.map((batch) => [
|
|
288
|
+
batch.key.materialSlot,
|
|
289
|
+
batch.key.first,
|
|
290
|
+
batch.key.count,
|
|
291
|
+
batch.candidates[0]?.drawItemIndex,
|
|
292
|
+
]);
|
|
293
|
+
expect(describe(reversedTopology).sort()).toEqual(describe(orderedTopology).sort());
|
|
294
|
+
});
|
|
295
|
+
|
|
183
296
|
it('culls ordinary instance-local transforms and emits instance identities', () => {
|
|
184
297
|
const source = snapshot(1, 0);
|
|
185
298
|
const identity = mat4.identity(mat4.create());
|
|
@@ -187,18 +300,15 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
187
300
|
outside[12] = 10;
|
|
188
301
|
const projection = new RenderScene();
|
|
189
302
|
projection.apply([
|
|
190
|
-
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
...
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
cacheKey: 1,
|
|
198
|
-
archVersion: 1,
|
|
199
|
-
},
|
|
303
|
+
updateSnapshot({
|
|
304
|
+
...source,
|
|
305
|
+
instances: {
|
|
306
|
+
transforms: new Float32Array([...identity, ...outside]),
|
|
307
|
+
instanceCount: 2,
|
|
308
|
+
cacheKey: 1,
|
|
309
|
+
archVersion: 1,
|
|
200
310
|
},
|
|
201
|
-
},
|
|
311
|
+
}),
|
|
202
312
|
]);
|
|
203
313
|
const topology = new BatchTopology();
|
|
204
314
|
topology.rebuild(projection.slotsSnapshot());
|
|
@@ -215,10 +325,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
215
325
|
|
|
216
326
|
it('reports overflow instead of silently accepting a truncated batch', () => {
|
|
217
327
|
const projection = new RenderScene();
|
|
218
|
-
projection.apply([
|
|
219
|
-
{ kind: 'create', snapshot: snapshot(1, 0) },
|
|
220
|
-
{ kind: 'create', snapshot: snapshot(2, 0.5) },
|
|
221
|
-
]);
|
|
328
|
+
projection.apply([updateSnapshot(snapshot(1, 0)), updateSnapshot(snapshot(2, 0.5))]);
|
|
222
329
|
const topology = new BatchTopology();
|
|
223
330
|
topology.rebuild(projection.slotsSnapshot());
|
|
224
331
|
const plan = topology.plan();
|
|
@@ -239,7 +346,7 @@ describe('GPU-driven batch topology and CPU oracle', () => {
|
|
|
239
346
|
const projection = new RenderScene();
|
|
240
347
|
const { localAabb: _localAabb, ...withoutBounds } = snapshot(1, 0);
|
|
241
348
|
const topology = new BatchTopology();
|
|
242
|
-
topology.rebuild(projection.apply([
|
|
349
|
+
topology.rebuild(projection.apply([updateSnapshot(withoutBounds)]).createdSlots);
|
|
243
350
|
expect(topology.inspect().ineligible).toBe(1);
|
|
244
351
|
|
|
245
352
|
const removed = projection.apply([{ kind: 'remove', worldId: 0, entityKey: 1 }]);
|
|
@@ -4,7 +4,12 @@ import { runBrowserGpuPassTiming } from './gpu-pass-timing-browser-runner.js';
|
|
|
4
4
|
const browserReady = typeof navigator !== 'undefined' && navigator.gpu !== undefined;
|
|
5
5
|
|
|
6
6
|
describe.skipIf(!browserReady)('GPU pass timing Browser dev-server runner', () => {
|
|
7
|
-
|
|
7
|
+
// The first live lavapipe renderer pair can exceed Vitest's 15s default while
|
|
8
|
+
// the shader manifest and timestamp-query path are cold; keep this bound
|
|
9
|
+
// local to the real WebGPU owner instead of weakening the global timeout.
|
|
10
|
+
it('keeps receipt facts and unsupported timing structured without stopping draw', {
|
|
11
|
+
timeout: 30_000,
|
|
12
|
+
}, async () => {
|
|
8
13
|
const result = await runBrowserGpuPassTiming();
|
|
9
14
|
expect(result.frames).toBe(3);
|
|
10
15
|
if (result.supported) {
|
|
@@ -121,4 +121,46 @@ describe('GpuResidencyCache mesh stride', () => {
|
|
|
121
121
|
if (packedIndices === undefined) return;
|
|
122
122
|
expect(new Uint16Array(packedIndices.buffer)).toEqual(new Uint16Array([0, 1, 2, 0, 2, 1]));
|
|
123
123
|
});
|
|
124
|
+
|
|
125
|
+
it('refuses a payload whose bytes do not match the projected stride', async () => {
|
|
126
|
+
const adapter = (await rhi.requestAdapter()).unwrap();
|
|
127
|
+
const device = (await adapter.requestDevice()).unwrap();
|
|
128
|
+
const store = new GpuResidencyCache();
|
|
129
|
+
store.configureGpuDevice(
|
|
130
|
+
device,
|
|
131
|
+
undefined,
|
|
132
|
+
() => {
|
|
133
|
+
throw new Error('cubemap registration is not part of this test');
|
|
134
|
+
},
|
|
135
|
+
device.caps,
|
|
136
|
+
);
|
|
137
|
+
const mesh: MeshAsset = {
|
|
138
|
+
kind: 'mesh',
|
|
139
|
+
vertices: new Float32Array(49),
|
|
140
|
+
attributes: {
|
|
141
|
+
position: new Float32Array(9),
|
|
142
|
+
normal: new Float32Array(9),
|
|
143
|
+
uv: new Float32Array(6),
|
|
144
|
+
tangent: new Float32Array(12),
|
|
145
|
+
},
|
|
146
|
+
submeshes: [
|
|
147
|
+
{
|
|
148
|
+
indexOffset: 0,
|
|
149
|
+
indexCount: 0,
|
|
150
|
+
vertexCount: 3,
|
|
151
|
+
topology: 'triangle-list',
|
|
152
|
+
materialSlot: 0,
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
materialSlots: [{ slotName: 'default' }],
|
|
156
|
+
};
|
|
157
|
+
const world = new World();
|
|
158
|
+
const handle = world.allocSharedRef('MeshAsset', mesh);
|
|
159
|
+
|
|
160
|
+
const resident = store.ensureResident(handle, mesh);
|
|
161
|
+
|
|
162
|
+
expect(resident.ok).toBe(false);
|
|
163
|
+
if (!resident.ok) expect(resident.error.code).toBe('asset-not-registered');
|
|
164
|
+
expect(store.getMeshGpuHandles(handle)).toBeUndefined();
|
|
165
|
+
});
|
|
124
166
|
});
|
|
@@ -76,7 +76,12 @@ fn fs(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
|
76
76
|
}
|
|
77
77
|
`;
|
|
78
78
|
|
|
79
|
-
const material = {
|
|
79
|
+
const material = {
|
|
80
|
+
baseColor: new Float32Array([1, 1, 1]),
|
|
81
|
+
metallic: 0,
|
|
82
|
+
roughness: 1,
|
|
83
|
+
materialHandle: 1,
|
|
84
|
+
} as MaterialSnapshot;
|
|
80
85
|
|
|
81
86
|
function snapshot(entityKey: number, translationX: number): RenderableSnapshot {
|
|
82
87
|
const world = new Float32Array(16);
|
|
@@ -97,6 +102,15 @@ function snapshot(entityKey: number, translationX: number): RenderableSnapshot {
|
|
|
97
102
|
};
|
|
98
103
|
}
|
|
99
104
|
|
|
105
|
+
function updateSnapshot(value: RenderableSnapshot) {
|
|
106
|
+
return {
|
|
107
|
+
kind: 'update' as const,
|
|
108
|
+
worldId: value.worldId,
|
|
109
|
+
entityKey: value.entityKey,
|
|
110
|
+
snapshot: value,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
100
114
|
function bufferBinding(buffer: Buffer) {
|
|
101
115
|
return { kind: 'buffer' as const, value: { buffer } };
|
|
102
116
|
}
|
|
@@ -119,10 +133,10 @@ export async function runGpuSceneGraph(): Promise<GpuSceneGraphEvidence> {
|
|
|
119
133
|
scene
|
|
120
134
|
.sync(
|
|
121
135
|
projection.apply([
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
updateSnapshot(snapshot(10, -3)),
|
|
137
|
+
updateSnapshot(snapshot(11, -0.5)),
|
|
138
|
+
updateSnapshot(snapshot(12, 0.5)),
|
|
139
|
+
updateSnapshot(snapshot(13, 3)),
|
|
126
140
|
]),
|
|
127
141
|
)
|
|
128
142
|
.unwrap();
|