@forgeax/engine-runtime 0.1.4 → 0.1.6
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 +49 -83
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/animation-graph-serialize.unit.test.d.ts +2 -0
- package/dist/__tests__/animation-graph-serialize.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts +2 -0
- package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts.map +1 -0
- package/dist/__tests__/asset-error-exhaustive.test-d.d.ts +11 -0
- package/dist/__tests__/asset-error-exhaustive.test-d.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-guid-reverse.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-guid-reverse.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-mounts.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-mounts.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.browser.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.browser.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.dawn.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.listCatalog.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.listCatalog.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.mesh-bin.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.mesh-bin.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.pack-cache.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.pack-cache.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.recursive.spec.d.ts +2 -0
- package/dist/__tests__/asset-registry.recursive.spec.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset.unit.test.d.ts +2 -0
- package/dist/__tests__/asset.unit.test.d.ts.map +1 -0
- package/dist/__tests__/audio-load-by-guid.unit.test.d.ts +2 -0
- package/dist/__tests__/audio-load-by-guid.unit.test.d.ts.map +1 -0
- package/dist/__tests__/backend-selection.integration.test.d.ts +2 -0
- package/dist/__tests__/backend-selection.integration.test.d.ts.map +1 -0
- package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts +2 -0
- package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts.map +1 -0
- package/dist/__tests__/builtin-asset-registry.unit.test.d.ts +2 -0
- package/dist/__tests__/builtin-asset-registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/collect-scene-asset.test.d.ts +1 -2
- package/dist/__tests__/collect-scene-asset.test.d.ts.map +1 -1
- package/dist/__tests__/collect-scene-mount-collapse.test.d.ts +2 -0
- package/dist/__tests__/collect-scene-mount-collapse.test.d.ts.map +1 -0
- package/dist/__tests__/collect-transient-roundtrip.test.d.ts +1 -1
- package/dist/__tests__/collect-transient-roundtrip.test.d.ts.map +1 -1
- package/dist/__tests__/collect-transient-skip.test.d.ts +1 -2
- package/dist/__tests__/collect-transient-skip.test.d.ts.map +1 -1
- package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts +2 -0
- package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts.map +1 -0
- package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts +2 -0
- package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts.map +1 -0
- package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts +2 -0
- package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/draw-published.d.ts +2 -2
- package/dist/__tests__/draw-published.d.ts.map +1 -1
- package/dist/__tests__/dynamic-texture-store.unit.test.d.ts +2 -0
- package/dist/__tests__/dynamic-texture-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/errors.unit.test.d.ts +2 -0
- package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
- package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts +2 -0
- package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts.map +1 -0
- package/dist/__tests__/fetch-binary-decompress.test.d.ts +2 -0
- package/dist/__tests__/fetch-binary-decompress.test.d.ts.map +1 -0
- package/dist/__tests__/four-path-compression.integration.test.d.ts +2 -0
- package/dist/__tests__/four-path-compression.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts +2 -0
- package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/guid-for-asset.unit.test.d.ts +2 -0
- package/dist/__tests__/guid-for-asset.unit.test.d.ts.map +1 -0
- package/dist/__tests__/handle-migration.test.d.ts +2 -0
- package/dist/__tests__/handle-migration.test.d.ts.map +1 -0
- package/dist/__tests__/helpers/register-runtime-components.d.ts.map +1 -1
- package/dist/__tests__/host-custom-kind-contract.test-d.d.ts +2 -0
- package/dist/__tests__/host-custom-kind-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/host-custom-kind-contract.test.d.ts +2 -0
- package/dist/__tests__/host-custom-kind-contract.test.d.ts.map +1 -0
- package/dist/__tests__/inspect-name.test.d.ts +2 -0
- package/dist/__tests__/inspect-name.test.d.ts.map +1 -0
- package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts +2 -0
- package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts.map +1 -0
- package/dist/__tests__/loadbyguid-payload.unit.test.d.ts +2 -0
- package/dist/__tests__/loadbyguid-payload.unit.test.d.ts.map +1 -0
- package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts +2 -0
- package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts.map +1 -0
- package/dist/__tests__/loader-extract-graceful.test.d.ts +2 -0
- package/dist/__tests__/loader-extract-graceful.test.d.ts.map +1 -0
- package/dist/__tests__/loader-name-survival.test.d.ts +2 -0
- package/dist/__tests__/loader-name-survival.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin-contract.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin-contract.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/new-kind-refs-contract.test.d.ts +2 -0
- package/dist/__tests__/new-kind-refs-contract.test.d.ts.map +1 -0
- package/dist/__tests__/package-promotion.test.d.ts +2 -0
- package/dist/__tests__/package-promotion.test.d.ts.map +1 -0
- package/dist/__tests__/package-rename.test.d.ts +2 -0
- package/dist/__tests__/package-rename.test.d.ts.map +1 -0
- package/dist/__tests__/recover-error-exhaustive.test-d.d.ts +1 -1
- package/dist/__tests__/recover-error-exhaustive.test-d.d.ts.map +1 -1
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts +1 -1
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
- package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts +10 -0
- package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts.map +1 -0
- package/dist/__tests__/render-system-extract.unit.test.d.ts +2 -0
- package/dist/__tests__/render-system-extract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-test-utils.d.ts +10 -0
- package/dist/__tests__/renderer-test-utils.d.ts.map +1 -0
- package/dist/__tests__/renderer.test-d.d.ts +2 -0
- package/dist/__tests__/renderer.test-d.d.ts.map +1 -0
- package/dist/__tests__/resolve-asset-handle-err.test.d.ts +2 -0
- package/dist/__tests__/resolve-asset-handle-err.test.d.ts.map +1 -0
- package/dist/__tests__/resolve-asset-handle.unit.test.d.ts +2 -0
- package/dist/__tests__/resolve-asset-handle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName-fallback.test.d.ts +2 -0
- package/dist/__tests__/resolveName-fallback.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName-null-package.test.d.ts +2 -0
- package/dist/__tests__/resolveName-null-package.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName-unified-entry.test.d.ts +2 -0
- package/dist/__tests__/resolveName-unified-entry.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName.test.d.ts +2 -0
- package/dist/__tests__/resolveName.test.d.ts.map +1 -0
- package/dist/__tests__/roots-to-scene-asset.test.d.ts +1 -1
- package/dist/__tests__/roots-to-scene-asset.test.d.ts.map +1 -1
- package/dist/__tests__/roundtrip-primitive.test.d.ts +2 -0
- package/dist/__tests__/roundtrip-primitive.test.d.ts.map +1 -0
- package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts +2 -0
- package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts.map +1 -0
- package/dist/__tests__/scene-instance-authoring.integration.test.d.ts +2 -0
- package/dist/__tests__/scene-instance-authoring.integration.test.d.ts.map +1 -0
- package/dist/__tests__/scene-mount-fixed-point.test.d.ts +2 -0
- package/dist/__tests__/scene-mount-fixed-point.test.d.ts.map +1 -0
- package/dist/__tests__/scene-mount-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/scene-mount-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/scene-sugar-instantiate.test.d.ts +2 -0
- package/dist/__tests__/scene-sugar-instantiate.test.d.ts.map +1 -0
- package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/serialize-scene-asset.test.d.ts +1 -1
- package/dist/__tests__/serialize-scene-asset.test.d.ts.map +1 -1
- package/dist/__tests__/template-game-default-api-contract.test.d.ts +2 -0
- package/dist/__tests__/template-game-default-api-contract.test.d.ts.map +1 -0
- package/dist/__tests__/tileset-asset-validate.test.d.ts +2 -0
- package/dist/__tests__/tileset-asset-validate.test.d.ts.map +1 -0
- package/dist/__tests__/transcode-fallback.unit.test.d.ts +2 -0
- package/dist/__tests__/transcode-fallback.unit.test.d.ts.map +1 -0
- package/dist/__tests__/transient-runtime-behavior.test.d.ts +2 -0
- package/dist/__tests__/transient-runtime-behavior.test.d.ts.map +1 -0
- package/dist/__tests__/video-loader-consumption.test.d.ts +2 -0
- package/dist/__tests__/video-loader-consumption.test.d.ts.map +1 -0
- package/dist/__tests__/video-loader-smoke.dawn.test.d.ts +2 -0
- package/dist/__tests__/video-loader-smoke.dawn.test.d.ts.map +1 -0
- package/dist/backend-selection.d.ts +13 -0
- package/dist/backend-selection.d.ts.map +1 -0
- package/dist/collect-scene-asset.d.ts +3 -3
- package/dist/collect-scene-asset.d.ts.map +1 -1
- package/dist/createRenderer.d.ts +14 -2
- package/dist/createRenderer.d.ts.map +1 -1
- package/dist/errors/environment.d.ts +1 -1
- package/dist/errors/environment.d.ts.map +1 -1
- package/dist/index.d.ts +19 -81
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +105 -108
- package/dist/index.mjs.map +1 -1
- package/dist/renderer-host.d.ts +9 -0
- package/dist/renderer-host.d.ts.map +1 -0
- package/dist/renderer-host.mjs +62 -0
- package/dist/renderer-host.mjs.map +1 -0
- package/dist/scene-instances/index.d.ts +2 -0
- package/dist/scene-instances/index.d.ts.map +1 -0
- package/dist/scene-utils/mount-override-fold.d.ts +1 -2
- package/dist/scene-utils/mount-override-fold.d.ts.map +1 -1
- package/dist/systems/sprite-animation-tick.d.ts +1 -1
- package/dist/systems/sprite-animation-tick.d.ts.map +1 -1
- package/dist/systems/transparent-sort.d.ts +1 -2
- package/dist/systems/transparent-sort.d.ts.map +1 -1
- package/dist/tilemap-register-validate.d.ts.map +1 -1
- package/package.json +34 -33
- package/src/__tests__/active-camera.unit.test.ts +19 -9
- package/src/__tests__/animation-graph-collect-roundtrip.test.ts +213 -0
- package/src/__tests__/animation-graph-serialize.unit.test.ts +171 -0
- package/src/__tests__/append-injection.test.ts +1 -1
- package/src/__tests__/asset-brand-and-name-retirement.test.ts +102 -0
- package/src/__tests__/asset-error-exhaustive.test-d.ts +62 -0
- package/src/__tests__/asset-registry-guid-reverse.test.ts +575 -0
- package/src/__tests__/asset-registry-hdr-equirect.test.ts +78 -0
- package/src/__tests__/asset-registry-mesh-pack-payload.dawn.test.ts +232 -0
- package/src/__tests__/asset-registry-mounts.test.ts +806 -0
- package/src/__tests__/asset-registry.browser.test.ts +81 -0
- package/src/__tests__/asset-registry.dawn.test.ts +94 -0
- package/src/__tests__/asset-registry.listCatalog.test.ts +170 -0
- package/src/__tests__/asset-registry.mesh-bin.test.ts +316 -0
- package/src/__tests__/asset-registry.pack-cache.test.ts +969 -0
- package/src/__tests__/asset-registry.raw-container-failfast.test.ts +225 -0
- package/src/__tests__/asset-registry.recursive.spec.ts +1397 -0
- package/src/__tests__/asset-registry.unit.test.ts +1030 -0
- package/src/__tests__/asset.unit.test.ts +7107 -0
- package/src/__tests__/audio-load-by-guid.unit.test.ts +126 -0
- package/src/__tests__/backend-selection.integration.test.ts +11 -0
- package/src/__tests__/basis-catalog-dispatch.integration.test.ts +320 -0
- package/src/__tests__/bind-group-cache-keying.test.ts +4 -4
- package/src/__tests__/block-upload-math.unit.test.ts +2 -2
- package/src/__tests__/builtin-asset-registry.unit.test.ts +112 -0
- package/src/__tests__/builtin-shader-register-e2e.test.ts +1 -1
- package/src/__tests__/cache-false-eviction.test.ts +2 -1
- package/src/__tests__/cache-isolation-matrix.test.ts +2 -1
- package/src/__tests__/camera-clear-snapshot-equivalence.unit.test.ts +5 -6
- package/src/__tests__/clamp-to-last.e2e.browser.test.ts +29 -19
- package/src/__tests__/collect-scene-asset.test.ts +49 -52
- package/src/__tests__/collect-scene-mount-collapse.test.ts +391 -0
- package/src/__tests__/collect-subtree.unit.test.ts +1 -2
- package/src/__tests__/collect-transient-children-absent.test.ts +24 -10
- package/src/__tests__/collect-transient-roundtrip.test.ts +44 -20
- package/src/__tests__/collect-transient-skip.test.ts +24 -13
- package/src/__tests__/components.test-d.ts +1 -6
- package/src/__tests__/components.unit.test.ts +20 -19
- package/src/__tests__/composite-skybox-cross-world.browser.test.ts +59 -27
- package/src/__tests__/compressed-texture-physical-extent.integration.test.ts +139 -0
- package/src/__tests__/create-renderer-assembly.integration.test.ts +42 -29
- package/src/__tests__/createRenderer-dispose.test.ts +35 -402
- package/src/__tests__/createRenderer.browser-no-webgpu.test.ts +25 -30
- package/src/__tests__/createRenderer.unit.test.ts +1 -1
- package/src/__tests__/dawn/hello-sprite-nineslice-section.dawn.test.ts +27 -63
- package/src/__tests__/dawn/ibl-precompute-readback.dawn.test.ts +56 -47
- package/src/__tests__/dawn/instances-per-instance-pbr.dawn.test.ts +49 -29
- package/src/__tests__/dawn/instances-shadow.dawn.test.ts +26 -15
- package/src/__tests__/dawn/instances-uniform-fallback.dawn.test.ts +13 -14
- package/src/__tests__/dawn/material-alpha.dawn.test.ts +23 -31
- package/src/__tests__/dawn/material-cooked-fixture.dawn.test.ts +0 -18
- package/src/__tests__/dawn/{mesh-update.dawn.test.ts → mesh-update-dawn.test.ts} +42 -134
- package/src/__tests__/dawn/mipmap-srgb-linear.dawn.test.ts +14 -7
- package/src/__tests__/dawn/per-entity-material-texture-isolation.dawn.test.ts +16 -28
- package/src/__tests__/dawn/sprite-nineslice-mesh-bind.dawn.test.ts +23 -39
- package/src/__tests__/dawn/upload-texture.dawn.test.ts +198 -0
- package/src/__tests__/dawn/user-handle-mesh-render.dawn.test.ts +12 -14
- package/src/__tests__/dawn/user-mesh-upload.dawn.test.ts +27 -22
- package/src/__tests__/dawn/zero-manifest-mesh-fail.dawn.test.ts +25 -28
- package/src/__tests__/dawn/zero-manifest-ready.dawn.test.ts +10 -11
- package/src/__tests__/demo-sortscope-migration.unit.test.ts +5 -5
- package/src/__tests__/derive-bgl-integration.test.ts +34 -44
- package/src/__tests__/derive-render-data-skin.unit.test.ts +1 -1
- package/src/__tests__/draw-published.ts +11 -4
- package/src/__tests__/dynamic-texture-store.unit.test.ts +190 -0
- package/src/__tests__/equirect-bc6h.integration.test.ts +144 -21
- package/src/__tests__/errors.unit.test.ts +1203 -0
- package/src/__tests__/extract-frames-graceful-degradation.test.ts +3 -7
- package/src/__tests__/extract-frames-merge.test.ts +35 -22
- package/src/__tests__/extract-record-no-hardcoded-texture-fields.test.ts +5 -16
- package/src/__tests__/extract-skin-mismatch.unit.test.ts +322 -0
- package/src/__tests__/fetch-binary-decompress.test.ts +356 -0
- package/src/__tests__/four-path-compression.integration.test.ts +395 -0
- package/src/__tests__/frame-targets-shadow-regression.unit.test.ts +1 -1
- package/src/__tests__/fullscreen-feature-host.dawn.test.ts +80 -0
- package/src/__tests__/fullscreen-post-bgl-depth.test.ts +4 -2
- package/src/__tests__/fullscreen-post-depth-params-arity.test.ts +3 -3
- package/src/__tests__/fullscreen-post-process-pass.dawn.test.ts +39 -23
- package/src/__tests__/fullscreen-post-process-pass.unit.test.ts +4 -2
- package/src/__tests__/fxaa-pixel-diff.dawn.test.ts +28 -17
- package/src/__tests__/fxaa-validation-and-resize.dawn.test.ts +29 -18
- package/src/__tests__/fxaa-zero-overhead.dawn.test.ts +16 -12
- package/src/__tests__/geometry.unit.test.ts +525 -159
- package/src/__tests__/glyph-tilemap-worldid.test.ts +1 -1
- package/src/__tests__/gpu-resource-cow-survivor.test.ts +6 -4
- package/src/__tests__/guid-for-asset.unit.test.ts +102 -0
- package/src/__tests__/handle-migration.test.ts +136 -0
- package/src/__tests__/helpers/register-runtime-components.ts +4 -2
- package/src/__tests__/helpers/register-scene-components.ts +1 -1
- package/src/__tests__/host-custom-kind-contract.test-d.ts +47 -0
- package/src/__tests__/host-custom-kind-contract.test.ts +578 -0
- package/src/__tests__/inspect-name.test.ts +139 -0
- package/src/__tests__/instances.test-d.ts +1 -1
- package/src/__tests__/instantiate-mount-deferred-wiring.test.ts +112 -0
- package/src/__tests__/light-casters-9-light.browser.test.ts +73 -76
- package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +7 -10
- package/src/__tests__/light-snapshot.test-d.ts +2 -2
- package/src/__tests__/lights-vec-negative.unit.test.ts +1 -1
- package/src/__tests__/lights.unit.test.ts +16 -500
- package/src/__tests__/loadbyguid-payload.unit.test.ts +117 -0
- package/src/__tests__/loadbyguid-texture-intern.unit.test.ts +213 -0
- package/src/__tests__/loader-extract-graceful.test.ts +146 -0
- package/src/__tests__/loader-name-survival.test.ts +213 -0
- package/src/__tests__/m3-vec-negative.unit.test.ts +3 -2
- package/src/__tests__/material-texture-uv-scale.unit.test.ts +101 -31
- package/src/__tests__/materials.unit.test.ts +10 -27
- package/src/__tests__/mesh-bin-contract.test.ts +28 -0
- package/src/__tests__/mesh-bin-skin-roundtrip.unit.test.ts +149 -0
- package/src/__tests__/mesh-bin.test.ts +38 -0
- package/src/__tests__/mesh-loader-skin-contract.unit.test.ts +120 -0
- package/src/__tests__/mesh-ssbo-grow.unit.test.ts +3 -3
- package/src/__tests__/mip-gate.unit.test.ts +1 -1
- package/src/__tests__/msaa-sprite-pixel-diff.dawn.test.ts +29 -68
- package/src/__tests__/new-kind-refs-contract.test.ts +132 -0
- package/src/__tests__/node-shims.d.ts +4 -6
- package/src/__tests__/package-promotion.test.ts +88 -0
- package/src/__tests__/package-rename.test.ts +103 -0
- package/src/__tests__/pass-selector.unit.test.ts +2 -2
- package/src/__tests__/pbr-pipeline.unit.test.ts +14 -21
- package/src/__tests__/pipeline-builder-msaa.unit.test.ts +6 -9
- package/src/__tests__/pipeline-cache-keying.unit.test.ts +6 -9
- package/src/__tests__/pipeline-spec.test.ts +16 -177
- package/src/__tests__/pipeline.unit.test.ts +154 -1693
- package/src/__tests__/point-light-shadow.dawn.test.ts +33 -42
- package/src/__tests__/point-light-shadow.unit.test.ts +19 -60
- package/src/__tests__/post-process-error-codes.unit.test.ts +4 -1
- package/src/__tests__/post-process-params-component.unit.test.ts +1 -1
- package/src/__tests__/post-process-params-extract.unit.test.ts +2 -5
- package/src/__tests__/postprocess-camera-consistency.test.ts +4 -7
- package/src/__tests__/profiler-assembly.integration.test.ts +1 -1
- package/src/__tests__/propagate-transforms.dawn.test.ts +12 -11
- package/src/__tests__/record-worldid-isolation.test.ts +7 -29
- package/src/__tests__/recover-error-exhaustive.test-d.ts +1 -1
- package/src/__tests__/render-error-exhaustive.test-d.ts +81 -71
- package/src/__tests__/render-feature-assembly.test-d.ts +20 -9
- package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +8 -6
- package/src/__tests__/render-feature-prepared-graphics.browser.test.ts +60 -558
- package/src/__tests__/render-feature-prepared-graphics.dawn.test.ts +57 -544
- package/src/__tests__/render-feature-prepared-graphics.fixture.ts +104 -0
- package/src/__tests__/render-feature-prepared-graphics.integration.test.ts +40 -248
- package/src/__tests__/render-feature-prepared-graphics.regression.integration.test.ts +83 -340
- package/src/__tests__/render-feature-recover.integration.test.ts +9 -49
- package/src/__tests__/render-feature-runtime-surface.test-d.ts +17 -20
- package/src/__tests__/render-schema-consumer.integration.test.ts +20 -13
- package/src/__tests__/render-schema-owner-boundary.unit.test.ts +2 -6
- package/src/__tests__/render-system-cross-world-overlay-queue.test.ts +5 -5
- package/src/__tests__/render-system-extract-dispatch-ordering.test.ts +16 -31
- package/src/__tests__/render-system-extract.test.ts +36 -51
- package/src/__tests__/render-system-extract.unit.test.ts +360 -0
- package/src/__tests__/render-system-fold-bucket.unit.test.ts +3 -5
- package/src/__tests__/render-system-fold-fallback.unit.test.ts +6 -3
- package/src/__tests__/render-system-fold-material.unit.test.ts +3 -5
- package/src/__tests__/render-system-fold-metrics.unit.test.ts +5 -5
- package/src/__tests__/render-system-fold-modegate.unit.test.ts +6 -6
- package/src/__tests__/render-system-fold.dawn.test.ts +7 -5
- package/src/__tests__/render-system-mega.test.ts +292 -190
- package/src/__tests__/render-system-owner-split-contract.test.ts +10 -32
- package/src/__tests__/render-system-record-multi-material-textureview.test.ts +59 -45
- package/src/__tests__/render-system-record-per-submesh-transparency.test.ts +23 -29
- package/src/__tests__/render-system-record.test.ts +398 -235
- package/src/__tests__/render-system-record.unit.test.ts +25 -26
- package/src/__tests__/render-system-skin-bg.unit.test.ts +8 -12
- package/src/__tests__/renderer-consumer.test-d.ts +16 -3
- package/src/__tests__/renderer-health.unit.test.ts +26 -916
- package/src/__tests__/renderer-lifecycle.integration.test.ts +19 -6
- package/src/__tests__/renderer-recover.unit.test.ts +49 -1069
- package/src/__tests__/renderer-result.test-d.ts +19 -9
- package/src/__tests__/renderer-surface.unit.test.ts +3 -5
- package/src/__tests__/renderer-test-utils.ts +56 -0
- package/src/__tests__/renderer.test-d.ts +59 -0
- package/src/__tests__/resolve-asset-handle-err.test.ts +111 -0
- package/src/__tests__/resolve-asset-handle.unit.test.ts +64 -0
- package/src/__tests__/resolve-depth-only-view.test.ts +1 -1
- package/src/__tests__/resolveName-fallback.test.ts +64 -0
- package/src/__tests__/resolveName-null-package.test.ts +38 -0
- package/src/__tests__/resolveName-unified-entry.test.ts +65 -0
- package/src/__tests__/resolveName.test.ts +64 -0
- package/src/__tests__/rhi-null-command-flow.unit.test.ts +43 -261
- package/src/__tests__/rhi-null-renderer-lifecycle.unit.test.ts +41 -169
- package/src/__tests__/roots-to-scene-asset.test.ts +199 -93
- package/src/__tests__/roundtrip-primitive.test.ts +351 -0
- package/src/__tests__/scene-bare-guid-refs-instantiate.test.ts +123 -0
- package/src/__tests__/scene-equirect-roundtrip.test.ts +103 -16
- package/src/__tests__/scene-instance-authoring.integration.test.ts +8 -0
- package/src/__tests__/scene-instance-bridge.integration.test.ts +1 -1
- package/src/__tests__/scene-instance-component.test.ts +1 -1
- package/src/__tests__/scene-mount-fixed-point.test.ts +257 -0
- package/src/__tests__/scene-mount-roundtrip.test.ts +987 -0
- package/src/__tests__/scene-mount-wrapper-roundtrip.test.ts +202 -0
- package/src/__tests__/scene-sugar-instantiate.test.ts +324 -0
- package/src/__tests__/serialize-mounts-roundtrip.test.ts +533 -0
- package/src/__tests__/serialize-scene-asset.test.ts +219 -22
- package/src/__tests__/shadow-caster-empty-schema.test.ts +3 -3
- package/src/__tests__/shadow-csm-cascade-loadop.test.ts +37 -17
- package/src/__tests__/shadow-csm-component.test.ts +3 -5
- package/src/__tests__/shadow-csm-extract.test.ts +2 -100
- package/src/__tests__/shadow-csm-orthoz.test.ts +2 -16
- package/src/__tests__/shadow-csm-runtime-vary.dawn.test.ts +19 -14
- package/src/__tests__/shadow-csm-tile-consistency.test.ts +32 -26
- package/src/__tests__/shadow-csm-ubo.dawn.test.ts +8 -49
- package/src/__tests__/shadow-csm-ubo.test.ts +3 -25
- package/src/__tests__/shadow-csm-viewport.browser.test.ts +1 -1
- package/src/__tests__/shadow-fields-observable.dawn.test.ts +67 -56
- package/src/__tests__/shadow-m1.dawn.test.ts +8 -9
- package/src/__tests__/shadow-mesh-ssbo-order.test.ts +11 -27
- package/src/__tests__/skin-errors.unit.test.ts +1 -1
- package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +7 -5
- package/src/__tests__/skylight-lazy-projection.test.ts +36 -15
- package/src/__tests__/sparse-tag-scene-roundtrip.test.ts +5 -5
- package/src/__tests__/sprite-cullmode-flip.dawn.test.ts +47 -64
- package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +12 -11
- package/src/__tests__/sprite-lit-extract-branch.test.ts +1 -1
- package/src/__tests__/sprite-lit-pipeline-cache-key.test.ts +1 -1
- package/src/__tests__/ssao-bgl.test.ts +16 -9
- package/src/__tests__/ssao-buffers.test.ts +2 -2
- package/src/__tests__/ssao-data.test.ts +2 -2
- package/src/__tests__/ssao-errors.test.ts +1 -1
- package/src/__tests__/ssao-passes.test.ts +64 -392
- package/src/__tests__/ssao-pipelines.test.ts +1 -1
- package/src/__tests__/ssao-uniform-layout.test.ts +8 -6
- package/src/__tests__/stencil-outline-pixel.dawn.test.ts +25 -17
- package/src/__tests__/swap-chain-format.unit.test.ts +5 -7
- package/src/__tests__/systems.unit.test.ts +536 -1326
- package/src/__tests__/template-game-default-api-contract.test.ts +362 -0
- package/src/__tests__/text.unit.test.ts +56 -33
- package/src/__tests__/tilemap-childed-despawn.test.ts +8 -14
- package/src/__tests__/tilemap-chunk-extract.overhang-bounds.test.ts +8 -12
- package/src/__tests__/tilemap-chunk-extract.propagate-order.test.ts +2 -1
- package/src/__tests__/tilemap-chunk-extract.test.ts +13 -17
- package/src/__tests__/tilemap-dirty-rebuild.test.ts +7 -11
- package/src/__tests__/tilemap-material-cache.test.ts +8 -13
- package/src/__tests__/tilemap-multi-atlas.test.ts +12 -32
- package/src/__tests__/tilemap-owner-boundary.unit.test.ts +5 -2
- package/src/__tests__/tilemap-region-pack.test.ts +8 -12
- package/src/__tests__/tilemap-spawn-flip-pivot.test.ts +8 -12
- package/src/__tests__/tilemap-uv-inset.test.ts +11 -14
- package/src/__tests__/tilemap-validate.test.ts +1 -1
- package/src/__tests__/tileset-asset-validate.test.ts +638 -0
- package/src/__tests__/transcode-fallback.unit.test.ts +207 -0
- package/src/__tests__/transform-hierarchy-pixel-diff.dawn.test.ts +36 -28
- package/src/__tests__/transient-fields-collect.test.ts +28 -21
- package/src/__tests__/transient-runtime-behavior.test.ts +227 -0
- package/src/__tests__/transparent-sort-tilemap-sprite-interleave.test.ts +4 -4
- package/src/__tests__/variant-selection.unit.test.ts +1 -1
- package/src/__tests__/video-extract-bindgroup.dawn.test.ts +89 -136
- package/src/__tests__/video-loader-consumption.test.ts +86 -0
- package/src/__tests__/video-loader-smoke.dawn.test.ts +60 -0
- package/src/__tests__/view-ubo-layout.browser.test.ts +0 -22
- package/src/__tests__/world-entity-key.test.ts +1 -1
- package/src/__tests__/world-scene-despawn.test.ts +1 -1
- package/src/__tests__/world-scene-instantiate.test.ts +2 -36
- package/src/__tests__/world-scene-nested.test.ts +1 -1
- package/src/__tests__/world-scene-override.test.ts +1 -1
- package/src/backend-selection.ts +69 -0
- package/src/collect-scene-asset.ts +28 -23
- package/src/components/__tests__/camera.test-d.ts +1 -1
- package/src/components/__tests__/camera.test.ts +1 -1
- package/src/components/__tests__/sprite-animation.test-d.ts +2 -2
- package/src/components/__tests__/tile-layer.test-d.ts +1 -1
- package/src/components/__tests__/tile-layer.unit.test.ts +2 -2
- package/src/createRenderer.ts +24 -36
- package/src/errors/environment.ts +1 -1
- package/src/index.ts +47 -113
- package/src/renderer-host.ts +33 -0
- package/src/scene-instances/__tests__/post-spawn-resolve-joints.unit.test.ts +1 -1
- package/src/scene-instances/index.ts +4 -0
- package/src/scene-utils/mount-override-fold.ts +3 -7
- package/src/systems/__tests__/transparent-sort.bench.ts +3 -3
- package/src/systems/sprite-animation-tick.ts +1 -1
- package/src/systems/transparent-sort.ts +38 -38
- package/src/tilemap-register-validate.ts +4 -4
- package/dist/__tests__/bind-group-cache-binding.test.d.ts +0 -2
- package/dist/__tests__/bind-group-cache-binding.test.d.ts.map +0 -1
- package/dist/__tests__/bind-group-cache-frame.test.d.ts +0 -2
- package/dist/__tests__/bind-group-cache-frame.test.d.ts.map +0 -1
- package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts +0 -2
- package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-manifest.d.ts +0 -131
- package/dist/__tests__/fog-producer-manifest.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-pixel-probe.d.ts +0 -42
- package/dist/__tests__/fog-producer-pixel-probe.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-pixel.browser.test.d.ts +0 -2
- package/dist/__tests__/fog-producer-pixel.browser.test.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts +0 -2
- package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-real-fixture.d.ts +0 -5
- package/dist/__tests__/fog-producer-real-fixture.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-vfx-effect.d.ts +0 -3
- package/dist/__tests__/fog-producer-vfx-effect.d.ts.map +0 -1
- package/dist/__tests__/fog-scene-asset.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-scene-asset.integration.test.d.ts.map +0 -1
- package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts +0 -2
- package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts.map +0 -1
- package/dist/__tests__/gpu-resource.test.d.ts +0 -2
- package/dist/__tests__/gpu-resource.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts +0 -2
- package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-buffers.unit.test.d.ts +0 -2
- package/dist/__tests__/hdrp-buffers.unit.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts +0 -2
- package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts +0 -2
- package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts +0 -2
- package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts.map +0 -1
- package/dist/__tests__/hdrp-ssao-boundary.test.d.ts +0 -2
- package/dist/__tests__/hdrp-ssao-boundary.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-ssao-falsification.test.d.ts +0 -2
- package/dist/__tests__/hdrp-ssao-falsification.test.d.ts.map +0 -1
- package/dist/__tests__/helpers/primitive-world.d.ts +0 -8
- package/dist/__tests__/helpers/primitive-world.d.ts.map +0 -1
- package/dist/__tests__/helpers/render-asset-port.d.ts +0 -15
- package/dist/__tests__/helpers/render-asset-port.d.ts.map +0 -1
- package/dist/__tests__/helpers/scene-asset-port.d.ts +0 -9
- package/dist/__tests__/helpers/scene-asset-port.d.ts.map +0 -1
- package/dist/__tests__/material-derived-coordinates.integration.test.d.ts +0 -2
- package/dist/__tests__/material-derived-coordinates.integration.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-layout-selection.test.d.ts +0 -2
- package/dist/__tests__/pipeline-layout-selection.test.d.ts.map +0 -1
- package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts +0 -2
- package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts.map +0 -1
- package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts +0 -2
- package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts +0 -2
- package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts.map +0 -1
- package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts +0 -2
- package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-caster-membership.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-caster-membership.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-pssm.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-pssm.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-viewport.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-viewport.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-m2.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-m2.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-m3-calibrate.d.ts +0 -83
- package/dist/__tests__/shadow-m3-calibrate.d.ts.map +0 -1
- package/dist/__tests__/shadow-m3.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-m3.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/temporal-off-path.unit.test.d.ts +0 -2
- package/dist/__tests__/temporal-off-path.unit.test.d.ts.map +0 -1
- package/dist/__tests__/video-cache-regression.unit.test.d.ts +0 -2
- package/dist/__tests__/video-cache-regression.unit.test.d.ts.map +0 -1
- package/dist/asset-kind.d.ts +0 -4
- package/dist/asset-kind.d.ts.map +0 -1
- package/dist/errors/sprite-animation.d.ts +0 -3
- package/dist/errors/sprite-animation.d.ts.map +0 -1
- package/dist/scene-asset-port.d.ts +0 -17
- package/dist/scene-asset-port.d.ts.map +0 -1
- package/dist/scene-collect-errors.d.ts +0 -22
- package/dist/scene-collect-errors.d.ts.map +0 -1
- package/dist/shadow-m3-calibrate.d.ts +0 -40
- package/dist/shadow-m3-calibrate.d.ts.map +0 -1
- package/src/__tests__/bind-group-cache-binding.test.ts +0 -2513
- package/src/__tests__/bind-group-cache-frame.test.ts +0 -1511
- package/src/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.ts +0 -204
- package/src/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.ts +0 -297
- package/src/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.ts +0 -271
- package/src/__tests__/dispatch-fullscreen-pass-params.unit.test.ts +0 -321
- package/src/__tests__/fog-producer-manifest.ts +0 -162
- package/src/__tests__/fog-producer-pixel-probe.ts +0 -263
- package/src/__tests__/fog-producer-pixel.browser.test.ts +0 -26
- package/src/__tests__/fog-producer-pixel.dawn.test.ts +0 -55
- package/src/__tests__/fog-producer-real-fixture.ts +0 -805
- package/src/__tests__/fog-producer-vfx-effect.ts +0 -272
- package/src/__tests__/fog-scene-asset.integration.test.ts +0 -123
- package/src/__tests__/gpu-resource-store-cubemap-status.test.ts +0 -207
- package/src/__tests__/gpu-resource.test.ts +0 -1206
- package/src/__tests__/hdrp-bgl-slots.browser.test.ts +0 -50
- package/src/__tests__/hdrp-buffers.unit.test.ts +0 -70
- package/src/__tests__/hdrp-execute-filter.unit.test.ts +0 -200
- package/src/__tests__/hdrp-gbuffer-attachments.browser.test.ts +0 -64
- package/src/__tests__/hdrp-pipeline-asset-type.test-d.ts +0 -139
- package/src/__tests__/hdrp-ssao-boundary.test.ts +0 -237
- package/src/__tests__/hdrp-ssao-falsification.test.ts +0 -289
- package/src/__tests__/helpers/primitive-world.ts +0 -91
- package/src/__tests__/helpers/render-asset-port.ts +0 -65
- package/src/__tests__/helpers/scene-asset-port.ts +0 -23
- package/src/__tests__/material-derived-coordinates.integration.test.ts +0 -100
- package/src/__tests__/pipeline-layout-selection.test.ts +0 -298
- package/src/__tests__/post-process-reads-narrowing.test-d.ts +0 -52
- package/src/__tests__/post-process-register-roundtrip.dawn.test.ts +0 -230
- package/src/__tests__/render-feature-zero-feature.browser.test.ts +0 -152
- package/src/__tests__/render-pipeline-trivial.dawn.test.ts +0 -525
- package/src/__tests__/shadow-csm-caster-membership.test.ts +0 -232
- package/src/__tests__/shadow-csm-pssm.test.ts +0 -142
- package/src/__tests__/shadow-csm-temporal.browser.test.ts +0 -145
- package/src/__tests__/shadow-csm-viewport.test.ts +0 -74
- package/src/__tests__/shadow-m2.dawn.test.ts +0 -394
- package/src/__tests__/shadow-m3-calibrate-run.dawn.test.ts +0 -248
- package/src/__tests__/shadow-m3-calibrate.ts +0 -203
- package/src/__tests__/shadow-m3.dawn.test.ts +0 -288
- package/src/__tests__/shadow-probe-control-flow.dawn.test.ts +0 -264
- package/src/__tests__/shadow-quality-metrics.dawn.test.ts +0 -324
- package/src/__tests__/temporal-off-path.unit.test.ts +0 -69
- package/src/__tests__/video-cache-regression.unit.test.ts +0 -186
- package/src/asset-kind.ts +0 -7
- package/src/errors/sprite-animation.ts +0 -5
- package/src/scene-asset-port.ts +0 -32
- package/src/scene-collect-errors.ts +0 -30
- package/src/shadow-m3-calibrate.ts +0 -171
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
// std140 walk produced by derive — caller writes scalars at the
|
|
26
26
|
// reported offsets and the totalBytes is the buffer allocation size.
|
|
27
27
|
|
|
28
|
-
import { appendInjection } from '@forgeax/engine-render/internal';
|
|
29
28
|
import type { ParamSchemaEntry } from '@forgeax/engine-types';
|
|
30
29
|
import { derive } from '@forgeax/engine-types';
|
|
31
30
|
import { describe, expect, it } from 'vitest';
|
|
31
|
+
import { appendInjection } from '../../../render/src/pbr-pipeline';
|
|
32
32
|
|
|
33
33
|
// ─── Synthetic schemas (one per built-in shader family) ─────────────────────
|
|
34
34
|
//
|
|
@@ -54,9 +54,7 @@ const standardPbrSchema: readonly ParamSchemaEntry[] = [
|
|
|
54
54
|
{ name: 'baseColorTexture', type: 'texture2d' },
|
|
55
55
|
{ name: 'metallicRoughnessTexture', type: 'texture2d' },
|
|
56
56
|
{ name: 'normalTexture', type: 'texture2d' },
|
|
57
|
-
{ name: 'specularTintTexture', type: 'texture2d' },
|
|
58
57
|
{ name: 'emissiveTexture', type: 'texture2d' },
|
|
59
|
-
{ name: 'occlusionTexture', type: 'texture2d' },
|
|
60
58
|
];
|
|
61
59
|
|
|
62
60
|
const skinSchema: readonly ParamSchemaEntry[] = [
|
|
@@ -179,7 +177,7 @@ describe('derive(schema) integration over 5 built-in shader families (M3 w11)',
|
|
|
179
177
|
// injection order ibl-then-lightmap (D-8).
|
|
180
178
|
|
|
181
179
|
// Exact paramSchema from packages/shader/src/default-standard-pbr.material.json:68-77
|
|
182
|
-
// (15 numeric entries +
|
|
180
|
+
// (15 numeric entries + 4 texture2d entries).
|
|
183
181
|
const defaultStandardPbrSchema: readonly ParamSchemaEntry[] = [
|
|
184
182
|
{ name: 'baseColor', type: 'color', default: [1, 1, 1, 1] },
|
|
185
183
|
{ name: 'metallic', type: 'f32', default: 0 },
|
|
@@ -199,22 +197,20 @@ const defaultStandardPbrSchema: readonly ParamSchemaEntry[] = [
|
|
|
199
197
|
{ name: 'metallicRoughnessTexture', type: 'texture2d' },
|
|
200
198
|
{ name: 'normalTexture', type: 'texture2d' },
|
|
201
199
|
{ name: 'specularTintTexture', type: 'texture2d' },
|
|
202
|
-
{ name: 'emissiveTexture', type: 'texture2d' },
|
|
203
|
-
{ name: 'occlusionTexture', type: 'texture2d' },
|
|
204
200
|
];
|
|
205
201
|
|
|
206
202
|
describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
|
|
207
|
-
it('w1 user-region: derive produces
|
|
203
|
+
it('w1 user-region: derive produces 9 entries (binding 0 UBO + 4 sampler/texture pairs), userRegionBindingEnd=9', () => {
|
|
208
204
|
const out = derive(defaultStandardPbrSchema);
|
|
209
205
|
|
|
210
|
-
// 15 numeric entries run-merged into binding 0 UBO +
|
|
211
|
-
expect(out.bglEntries.length).toBe(
|
|
212
|
-
expect(out.userRegionBindingEnd).toBe(
|
|
206
|
+
// 15 numeric entries run-merged into binding 0 UBO + 4 textures x 2 = 1 + 8 = 9.
|
|
207
|
+
expect(out.bglEntries.length).toBe(9);
|
|
208
|
+
expect(out.userRegionBindingEnd).toBe(9);
|
|
213
209
|
|
|
214
210
|
// Bindings 0..6 dense, no gaps.
|
|
215
211
|
const bindings = out.bglEntries.map((e) => e.binding);
|
|
216
|
-
expect(new Set(bindings).size).toBe(
|
|
217
|
-
for (let i = 0; i <
|
|
212
|
+
expect(new Set(bindings).size).toBe(9);
|
|
213
|
+
for (let i = 0; i < 9; i++) {
|
|
218
214
|
expect(bindings).toContain(i);
|
|
219
215
|
}
|
|
220
216
|
|
|
@@ -222,28 +218,24 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
|
|
|
222
218
|
expect(out.bglEntries[0]?.binding).toBe(0);
|
|
223
219
|
expect(out.bglEntries[0]?.buffer?.type).toBe('uniform');
|
|
224
220
|
|
|
225
|
-
// textureFieldNames covers exactly the
|
|
226
|
-
expect(out.textureFieldNames.size).toBe(
|
|
221
|
+
// textureFieldNames covers exactly the 4 texture2d entries.
|
|
222
|
+
expect(out.textureFieldNames.size).toBe(4);
|
|
227
223
|
expect(out.textureFieldNames.has('baseColorTexture')).toBe(true);
|
|
228
224
|
expect(out.textureFieldNames.has('metallicRoughnessTexture')).toBe(true);
|
|
229
225
|
expect(out.textureFieldNames.has('normalTexture')).toBe(true);
|
|
230
226
|
expect(out.textureFieldNames.has('specularTintTexture')).toBe(true);
|
|
231
|
-
expect(out.textureFieldNames.has('emissiveTexture')).toBe(true);
|
|
232
|
-
expect(out.textureFieldNames.has('occlusionTexture')).toBe(true);
|
|
233
227
|
|
|
234
228
|
// sampler map: each texture has a paired sampler.
|
|
235
|
-
expect(out.samplerForTexture.size).toBe(
|
|
229
|
+
expect(out.samplerForTexture.size).toBe(4);
|
|
236
230
|
expect(out.samplerForTexture.get('baseColorTexture')).toBe('baseColorTexture_sampler');
|
|
237
231
|
expect(out.samplerForTexture.get('metallicRoughnessTexture')).toBe(
|
|
238
232
|
'metallicRoughnessTexture_sampler',
|
|
239
233
|
);
|
|
240
234
|
expect(out.samplerForTexture.get('normalTexture')).toBe('normalTexture_sampler');
|
|
241
235
|
expect(out.samplerForTexture.get('specularTintTexture')).toBe('specularTintTexture_sampler');
|
|
242
|
-
expect(out.samplerForTexture.get('emissiveTexture')).toBe('emissiveTexture_sampler');
|
|
243
|
-
expect(out.samplerForTexture.get('occlusionTexture')).toBe('occlusionTexture_sampler');
|
|
244
236
|
});
|
|
245
237
|
|
|
246
|
-
it('w1 full pipeline: derive + ibl injection + lightmap injection =
|
|
238
|
+
it('w1 full pipeline: derive + ibl injection + lightmap injection = 20 entries dense 0..19', () => {
|
|
247
239
|
const out = derive(defaultStandardPbrSchema);
|
|
248
240
|
// Same cast as append-injection.test.ts — forgeax shim → @webgpu/types via
|
|
249
241
|
// explicit two-step `as unknown as`, exempt from RHI gate j.
|
|
@@ -252,21 +244,21 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
|
|
|
252
244
|
// Injection start = userRegionBindingEnd (NOT a hardcoded 7 literal).
|
|
253
245
|
const afterIbl = appendInjection(userBgl, 'ibl');
|
|
254
246
|
expect(afterIbl.length).toBe(7);
|
|
255
|
-
expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd); //
|
|
247
|
+
expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd); // 9
|
|
256
248
|
|
|
257
249
|
const mergedAfterIbl = [...userBgl, ...afterIbl];
|
|
258
250
|
|
|
259
251
|
const afterLightmap = appendInjection(mergedAfterIbl, 'lightmap');
|
|
260
252
|
expect(afterLightmap.length).toBe(4);
|
|
261
|
-
expect(afterLightmap[0]?.binding).toBe(mergedAfterIbl.length); //
|
|
253
|
+
expect(afterLightmap[0]?.binding).toBe(mergedAfterIbl.length); // 16
|
|
262
254
|
|
|
263
255
|
const fullSet = [...mergedAfterIbl, ...afterLightmap];
|
|
264
|
-
expect(fullSet.length).toBe(
|
|
256
|
+
expect(fullSet.length).toBe(20);
|
|
265
257
|
|
|
266
258
|
// Bindings 0..17 dense, no gaps.
|
|
267
259
|
const bindings = fullSet.map((e) => e.binding);
|
|
268
|
-
expect(new Set(bindings).size).toBe(
|
|
269
|
-
for (let i = 0; i <
|
|
260
|
+
expect(new Set(bindings).size).toBe(20);
|
|
261
|
+
for (let i = 0; i < 20; i++) {
|
|
270
262
|
expect(bindings).toContain(i);
|
|
271
263
|
}
|
|
272
264
|
|
|
@@ -289,7 +281,7 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
|
|
|
289
281
|
|
|
290
282
|
it('w1 injection start is userRegionBindingEnd, not a hardcoded literal', () => {
|
|
291
283
|
const out = derive(defaultStandardPbrSchema);
|
|
292
|
-
// Prove that userRegionBindingEnd (
|
|
284
|
+
// Prove that userRegionBindingEnd (9 today) is what feeds injection, not a
|
|
293
285
|
// hardcoded constant embedded in test logic. The derive() output IS the SSOT.
|
|
294
286
|
const userBgl = [...out.bglEntries] as unknown as readonly GPUBindGroupLayoutEntry[];
|
|
295
287
|
|
|
@@ -299,8 +291,8 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
|
|
|
299
291
|
// derive later shifts userRegionBindingEnd (e.g. to 9 for 4-texture),
|
|
300
292
|
// this assertion catches the desync.
|
|
301
293
|
expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd);
|
|
302
|
-
// read-back guard: confirm the
|
|
303
|
-
expect(out.userRegionBindingEnd).toBe(
|
|
294
|
+
// read-back guard: confirm the derive result really is 9 today.
|
|
295
|
+
expect(out.userRegionBindingEnd).toBe(9);
|
|
304
296
|
});
|
|
305
297
|
});
|
|
306
298
|
|
|
@@ -336,21 +328,19 @@ const parallax4TextureSchema: readonly ParamSchemaEntry[] = [
|
|
|
336
328
|
{ name: 'normalTexture', type: 'texture2d' },
|
|
337
329
|
{ name: 'specularTintTexture', type: 'texture2d' },
|
|
338
330
|
{ name: 'heightTexture', type: 'texture2d' },
|
|
339
|
-
{ name: 'emissiveTexture', type: 'texture2d' },
|
|
340
|
-
{ name: 'occlusionTexture', type: 'texture2d' },
|
|
341
331
|
];
|
|
342
332
|
|
|
343
333
|
describe('5-texture custom schema derive: heightTexture binding + injection shift (M2 w2)', () => {
|
|
344
334
|
it('(a) heightTexture earns a distinct sampler(7)/texture(8) binding pair', () => {
|
|
345
335
|
const out = derive(parallax4TextureSchema);
|
|
346
336
|
|
|
347
|
-
// textureFieldNames covers all
|
|
348
|
-
expect(out.textureFieldNames.size).toBe(
|
|
337
|
+
// textureFieldNames covers all 5 declared textures.
|
|
338
|
+
expect(out.textureFieldNames.size).toBe(5);
|
|
349
339
|
expect(out.textureFieldNames.has('heightTexture')).toBe(true);
|
|
350
340
|
expect(out.samplerForTexture.get('heightTexture')).toBe('heightTexture_sampler');
|
|
351
341
|
|
|
352
|
-
// 1 UBO +
|
|
353
|
-
expect(out.bglEntries.length).toBe(
|
|
342
|
+
// 1 UBO + 5 sampler/texture pairs = 11 entries.
|
|
343
|
+
expect(out.bglEntries.length).toBe(11);
|
|
354
344
|
|
|
355
345
|
// heightTexture is the 5th texture: sampler at binding 9, texture at binding 10.
|
|
356
346
|
// (after baseColor 1/2, MR 3/4, normal 5/6, specular tint 7/8).
|
|
@@ -365,8 +355,8 @@ describe('5-texture custom schema derive: heightTexture binding + injection shif
|
|
|
365
355
|
it('(b) userRegionBindingEnd=11 (4-texture baseline 9, shifted +2 by heightTexture)', () => {
|
|
366
356
|
const baseline = derive(defaultStandardPbrSchema);
|
|
367
357
|
const parallax = derive(parallax4TextureSchema);
|
|
368
|
-
expect(baseline.userRegionBindingEnd).toBe(
|
|
369
|
-
expect(parallax.userRegionBindingEnd).toBe(
|
|
358
|
+
expect(baseline.userRegionBindingEnd).toBe(9);
|
|
359
|
+
expect(parallax.userRegionBindingEnd).toBe(11);
|
|
370
360
|
// Exactly one sampler/texture pair (2 bindings) of shift.
|
|
371
361
|
expect(parallax.userRegionBindingEnd - baseline.userRegionBindingEnd).toBe(2);
|
|
372
362
|
});
|
|
@@ -377,21 +367,21 @@ describe('5-texture custom schema derive: heightTexture binding + injection shif
|
|
|
377
367
|
|
|
378
368
|
const afterIbl = appendInjection(userBgl, 'ibl');
|
|
379
369
|
// Injection start follows derive().userRegionBindingEnd dynamically — for a
|
|
380
|
-
//
|
|
370
|
+
// 5-texture schema that is 11, not the 4-texture baseline's 9.
|
|
381
371
|
expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd);
|
|
382
|
-
expect(afterIbl[0]?.binding).toBe(
|
|
372
|
+
expect(afterIbl[0]?.binding).toBe(11);
|
|
383
373
|
|
|
384
374
|
const mergedAfterIbl = [...userBgl, ...afterIbl];
|
|
385
375
|
const afterLightmap = appendInjection(mergedAfterIbl, 'lightmap');
|
|
386
|
-
// Lightmap follows IBL:
|
|
387
|
-
expect(afterLightmap[0]?.binding).toBe(
|
|
376
|
+
// Lightmap follows IBL: 11 + 7 = 18.
|
|
377
|
+
expect(afterLightmap[0]?.binding).toBe(18);
|
|
388
378
|
|
|
389
|
-
// Full set:
|
|
379
|
+
// Full set: 11 user-region + 7 ibl + 4 lightmap = 22 entries, dense 0..21.
|
|
390
380
|
const fullSet = [...mergedAfterIbl, ...afterLightmap];
|
|
391
|
-
expect(fullSet.length).toBe(
|
|
381
|
+
expect(fullSet.length).toBe(22);
|
|
392
382
|
const bindings = fullSet.map((e) => e.binding);
|
|
393
|
-
expect(new Set(bindings).size).toBe(
|
|
394
|
-
for (let i = 0; i <
|
|
383
|
+
expect(new Set(bindings).size).toBe(22);
|
|
384
|
+
for (let i = 0; i < 22; i++) {
|
|
395
385
|
expect(bindings).toContain(i);
|
|
396
386
|
}
|
|
397
387
|
});
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
// order, including skin streams, without a parallel stride discriminator.
|
|
4
4
|
|
|
5
5
|
import { deriveVertexLayoutProjection } from '@forgeax/engine-geometry';
|
|
6
|
-
import { deriveRenderDataMesh } from '@forgeax/engine-render/internal';
|
|
7
6
|
import type { MeshAsset } from '@forgeax/engine-types';
|
|
8
7
|
import { describe, expect, it } from 'vitest';
|
|
8
|
+
import { deriveRenderDataMesh } from '../../../render/src/render-data';
|
|
9
9
|
|
|
10
10
|
function canonicalAttributes(vertexCount: number): MeshAsset['attributes'] {
|
|
11
11
|
return {
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { World } from '@forgeax/engine-ecs';
|
|
2
|
-
import type { Renderer } from '@forgeax/engine-render';
|
|
2
|
+
import type { FrameReceipt, RenderError, Renderer, RenderResult } from '@forgeax/engine-render';
|
|
3
3
|
|
|
4
4
|
/** Drive the production attach -> update -> draw contract in direct-render tests. */
|
|
5
|
-
export function drawPublished(
|
|
6
|
-
|
|
5
|
+
export function drawPublished(
|
|
6
|
+
renderer: Renderer,
|
|
7
|
+
world: World,
|
|
8
|
+
): RenderResult<FrameReceipt, RenderError> {
|
|
9
|
+
const attached = renderer.attach(world);
|
|
7
10
|
if (!attached.ok) throw attached.error;
|
|
8
11
|
world.update(1 / 60).unwrap();
|
|
9
|
-
return renderer.draw(
|
|
12
|
+
return renderer.draw({
|
|
13
|
+
leases: [attached.value],
|
|
14
|
+
camera: { lease: attached.value },
|
|
15
|
+
environment: { lease: attached.value },
|
|
16
|
+
});
|
|
10
17
|
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// feat-20260623-world-space-video-asset M4 / w15 — DynamicTextureStore unit.
|
|
2
|
+
//
|
|
3
|
+
// D-3 / AC-08: the transient video texture path is fully independent of
|
|
4
|
+
// GpuResidencyCache.ensureResident (the static "upload once / cache forever"
|
|
5
|
+
// cache). This test pins the three load-bearing properties:
|
|
6
|
+
// 1. isolation — the module does NOT import GpuResidencyCache (source scan).
|
|
7
|
+
// 2. allocate-once — a steady-size clip creates exactly one GPU texture; each
|
|
8
|
+
// subsequent frame is a copyExternalImageToTexture write, not a new create.
|
|
9
|
+
// 3. resize-on-change — a dimension change destroys the old texture and
|
|
10
|
+
// allocates a new one (so a clip whose intrinsic size resolves late still
|
|
11
|
+
// renders correctly).
|
|
12
|
+
// Plus the structured-failure contract (charter P3): a device that rejects the
|
|
13
|
+
// copy returns a Result.err, never throws.
|
|
14
|
+
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import { type DynamicTextureDevice, DynamicTextureStore } from '@forgeax/engine-assets-runtime';
|
|
18
|
+
import type { Result, Texture, TextureView } from '@forgeax/engine-rhi';
|
|
19
|
+
import { err, ok, RhiError } from '@forgeax/engine-rhi';
|
|
20
|
+
import type { Handle } from '@forgeax/engine-types';
|
|
21
|
+
import { toShared } from '@forgeax/engine-types';
|
|
22
|
+
import { describe, expect, it } from 'vitest';
|
|
23
|
+
|
|
24
|
+
const STORE_SRC = fileURLToPath(
|
|
25
|
+
new URL('../../../assets-runtime/src/dynamic-texture-store.ts', import.meta.url),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
interface DeviceProbe {
|
|
29
|
+
created: number;
|
|
30
|
+
destroyed: number;
|
|
31
|
+
copies: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function makeMockDevice(
|
|
35
|
+
probe: DeviceProbe,
|
|
36
|
+
opts: { copyFails?: boolean } = {},
|
|
37
|
+
): DynamicTextureDevice {
|
|
38
|
+
let nextTex = 0;
|
|
39
|
+
return {
|
|
40
|
+
createTexture: (): Result<Texture, RhiError> => {
|
|
41
|
+
probe.created += 1;
|
|
42
|
+
return ok({ __tex: `tex-${++nextTex}` } as unknown as Texture);
|
|
43
|
+
},
|
|
44
|
+
createTextureView: (tex: Texture): Result<TextureView, RhiError> =>
|
|
45
|
+
ok({ __view: tex } as unknown as TextureView),
|
|
46
|
+
destroyTexture: (): Result<void, RhiError> => {
|
|
47
|
+
probe.destroyed += 1;
|
|
48
|
+
return ok(undefined);
|
|
49
|
+
},
|
|
50
|
+
queue: {
|
|
51
|
+
copyExternalImageToTexture: (): Result<void, RhiError> => {
|
|
52
|
+
probe.copies += 1;
|
|
53
|
+
if (opts.copyFails === true) {
|
|
54
|
+
return err(
|
|
55
|
+
new RhiError({
|
|
56
|
+
code: 'webgpu-runtime-error',
|
|
57
|
+
expected: 'copyExternalImageToTexture succeeds',
|
|
58
|
+
hint: 'video source not yet decodable',
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return ok(undefined);
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const FAKE_SOURCE = {} as unknown as GPUCopyExternalImageSourceInfo['source'];
|
|
69
|
+
|
|
70
|
+
function clip(id: number): Handle<'VideoAsset', 'shared'> {
|
|
71
|
+
return toShared<'VideoAsset'>(id);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
describe('DynamicTextureStore isolation (M4 / w15)', () => {
|
|
75
|
+
it('does NOT import GpuResidencyCache (AC-08 / D-3 independence)', () => {
|
|
76
|
+
const src = readFileSync(STORE_SRC, 'utf8');
|
|
77
|
+
// Scan import statements only — the file's prose comments reference the
|
|
78
|
+
// store/ensureResident to explain WHY they are kept separate (D-3); the
|
|
79
|
+
// load-bearing invariant is the absence of an actual import edge.
|
|
80
|
+
const importLines = src.split('\n').filter((l) => /^\s*import\b/.test(l));
|
|
81
|
+
for (const line of importLines) {
|
|
82
|
+
expect(line.includes('device/gpu-residency'), `unexpected import: ${line}`).toBe(false);
|
|
83
|
+
}
|
|
84
|
+
// No call to the static residency cache method anywhere in executable code
|
|
85
|
+
// (strip comments first so the explanatory prose does not trip the gate).
|
|
86
|
+
const stripped = src.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/[^\n]*/g, '');
|
|
87
|
+
expect(stripped.includes('ensureResident')).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('DynamicTextureStore lifecycle (M4 / w15)', () => {
|
|
92
|
+
it('allocate-once: a steady-size clip creates one texture, writes every frame', () => {
|
|
93
|
+
const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
94
|
+
const store = new DynamicTextureStore();
|
|
95
|
+
store.configureGpuDevice(makeMockDevice(probe));
|
|
96
|
+
const h = clip(701);
|
|
97
|
+
|
|
98
|
+
for (let frame = 0; frame < 5; frame++) {
|
|
99
|
+
const res = store.uploadFrame(h, FAKE_SOURCE, 320, 240);
|
|
100
|
+
expect(res?.ok).toBe(true);
|
|
101
|
+
}
|
|
102
|
+
expect(probe.created).toBe(1);
|
|
103
|
+
expect(probe.copies).toBe(5);
|
|
104
|
+
expect(probe.destroyed).toBe(0);
|
|
105
|
+
expect(store.getView(h)).toBeDefined();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('resize-on-change: a dimension change destroys the old texture + allocates a new one', () => {
|
|
109
|
+
const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
110
|
+
const store = new DynamicTextureStore();
|
|
111
|
+
store.configureGpuDevice(makeMockDevice(probe));
|
|
112
|
+
const h = clip(702);
|
|
113
|
+
|
|
114
|
+
expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
|
|
115
|
+
expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
|
|
116
|
+
expect(probe.created).toBe(1);
|
|
117
|
+
|
|
118
|
+
// Intrinsic size resolved (e.g. metadata loaded) -> new dimensions.
|
|
119
|
+
expect(store.uploadFrame(h, FAKE_SOURCE, 640, 480)?.ok).toBe(true);
|
|
120
|
+
expect(probe.created).toBe(2);
|
|
121
|
+
expect(probe.destroyed).toBe(1);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('two clips get independent transient textures', () => {
|
|
125
|
+
const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
126
|
+
const store = new DynamicTextureStore();
|
|
127
|
+
store.configureGpuDevice(makeMockDevice(probe));
|
|
128
|
+
|
|
129
|
+
expect(store.uploadFrame(clip(710), FAKE_SOURCE, 100, 100)?.ok).toBe(true);
|
|
130
|
+
expect(store.uploadFrame(clip(711), FAKE_SOURCE, 100, 100)?.ok).toBe(true);
|
|
131
|
+
expect(probe.created).toBe(2);
|
|
132
|
+
expect(store.getView(clip(710))).not.toBe(store.getView(clip(711)));
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('device swap destroys stale entries before reusing a clip', () => {
|
|
136
|
+
const first: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
137
|
+
const second: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
138
|
+
const store = new DynamicTextureStore();
|
|
139
|
+
const h = clip(740);
|
|
140
|
+
|
|
141
|
+
store.configureGpuDevice(makeMockDevice(first));
|
|
142
|
+
expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
|
|
143
|
+
|
|
144
|
+
store.configureGpuDevice(makeMockDevice(second));
|
|
145
|
+
expect(first.destroyed).toBe(1);
|
|
146
|
+
expect(store.getView(h)).toBeUndefined();
|
|
147
|
+
|
|
148
|
+
expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
|
|
149
|
+
expect(second.created).toBe(1);
|
|
150
|
+
expect(second.copies).toBe(1);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('DynamicTextureStore degrade paths (M4 / w15, charter P3)', () => {
|
|
155
|
+
it('returns undefined (not an error) before a device is wired', () => {
|
|
156
|
+
const store = new DynamicTextureStore();
|
|
157
|
+
expect(store.uploadFrame(clip(720), FAKE_SOURCE, 320, 240)).toBeUndefined();
|
|
158
|
+
expect(store.getView(clip(720))).toBeUndefined();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('returns undefined for zero / unknown source dimensions (metadata pending)', () => {
|
|
162
|
+
const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
163
|
+
const store = new DynamicTextureStore();
|
|
164
|
+
store.configureGpuDevice(makeMockDevice(probe));
|
|
165
|
+
expect(store.uploadFrame(clip(721), FAKE_SOURCE, 0, 0)).toBeUndefined();
|
|
166
|
+
expect(probe.created).toBe(0);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('returns a structured RhiError when the copy fails (never throws)', () => {
|
|
170
|
+
const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
171
|
+
const store = new DynamicTextureStore();
|
|
172
|
+
store.configureGpuDevice(makeMockDevice(probe, { copyFails: true }));
|
|
173
|
+
const res = store.uploadFrame(clip(722), FAKE_SOURCE, 320, 240);
|
|
174
|
+
expect(res?.ok).toBe(false);
|
|
175
|
+
if (res !== undefined && !res.ok) {
|
|
176
|
+
expect(res.error.code).toBe('webgpu-runtime-error');
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('destroyAll destroys every transient texture + clears the views', () => {
|
|
181
|
+
const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
|
|
182
|
+
const store = new DynamicTextureStore();
|
|
183
|
+
store.configureGpuDevice(makeMockDevice(probe));
|
|
184
|
+
store.uploadFrame(clip(730), FAKE_SOURCE, 64, 64);
|
|
185
|
+
store.uploadFrame(clip(731), FAKE_SOURCE, 64, 64);
|
|
186
|
+
store.destroyAll();
|
|
187
|
+
expect(probe.destroyed).toBe(2);
|
|
188
|
+
expect(store.getView(clip(730))).toBeUndefined();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
@@ -1,23 +1,148 @@
|
|
|
1
|
-
|
|
1
|
+
// equirect renderable-source integration test (feat-20260707 M5 fix, dawn env).
|
|
2
|
+
//
|
|
3
|
+
// The full HDR equirect chain, end to end: an equirect is ALWAYS an IBL / skybox
|
|
4
|
+
// source (Skylight.equirect / SkyboxBackground.equirect drive equirect-to-cube /
|
|
5
|
+
// irradiance / prefilter RENDER passes). A block-compressed HDR format
|
|
6
|
+
// (bc6h-rgb-ufloat) is sample-only, never a color-renderable render target
|
|
7
|
+
// ("BC6HRGBUfloat is not color renderable"), so an equirect is never
|
|
8
|
+
// block-compressed: it is delivered uncompressed rgba16float. This test asserts
|
|
9
|
+
// the equirect loader yields an rgba16float POD and `deriveRenderDataCubemap`
|
|
10
|
+
// accepts it (renderable cube source), regardless of the device bc cap.
|
|
11
|
+
//
|
|
12
|
+
// This replaces the earlier "equirect -> BC6H by cap" premise, which was itself
|
|
13
|
+
// the bug: BC6H equirect broke cube projection with a WebGPU device error.
|
|
14
|
+
//
|
|
15
|
+
// dawn env: the caps triple is printed so the lavapipe/llvmpipe BC-support
|
|
16
|
+
// question stays empirically visible in CI logs; the equirect path is
|
|
17
|
+
// cap-independent (always rgba16float).
|
|
18
|
+
//
|
|
19
|
+
// File is named `.integration.test.ts`; it is added to the dawn project
|
|
20
|
+
// `include` array in the root vitest.config.ts so it runs under the dawn-node GPU
|
|
21
|
+
// env, and skips itself when navigator.gpu is absent (the per-package unit
|
|
22
|
+
// project) rather than failing.
|
|
23
|
+
|
|
24
|
+
import { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
25
|
+
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
2
26
|
import type { EquirectAsset } from '@forgeax/engine-types';
|
|
3
|
-
import { describe, expect, it } from 'vitest';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
27
|
+
import { beforeAll, describe, expect, it } from 'vitest';
|
|
28
|
+
import { deriveRenderDataCubemap } from '../../../render/src/render-data';
|
|
29
|
+
import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
|
|
30
|
+
|
|
31
|
+
const gpu = globalThis.navigator?.gpu;
|
|
32
|
+
const hasGpu = gpu !== undefined;
|
|
33
|
+
|
|
34
|
+
const GUID_EQUI = 'c0000000-0000-4000-a000-000065717569';
|
|
35
|
+
const PACK_INDEX_URL = '/test-equirect-renderable-pack-index.json';
|
|
36
|
+
|
|
37
|
+
function parseGuid(g: string): AssetGuid {
|
|
38
|
+
const parsed = AssetGuid.parse(g);
|
|
39
|
+
if (!parsed.ok) throw new Error(`bad guid ${g}`);
|
|
40
|
+
return parsed.value;
|
|
16
41
|
}
|
|
17
42
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
43
|
+
/** A deterministic WxH rgba16float (IEEE-754 binary16) HDR image. */
|
|
44
|
+
function makeHdrHalf(w: number, h: number): Uint8Array {
|
|
45
|
+
// 0x3c00 = 1.0 in binary16; vary channels so the bytes are non-trivial.
|
|
46
|
+
const px = new Uint16Array(w * h * 4);
|
|
47
|
+
for (let i = 0; i < w * h; i++) {
|
|
48
|
+
px[i * 4] = 0x3c00;
|
|
49
|
+
px[i * 4 + 1] = 0x3800; // 0.5
|
|
50
|
+
px[i * 4 + 2] = 0x3400; // 0.25
|
|
51
|
+
px[i * 4 + 3] = 0x3c00;
|
|
52
|
+
}
|
|
53
|
+
return new Uint8Array(px.buffer);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let bcCap = false;
|
|
57
|
+
|
|
58
|
+
describe.skipIf(!hasGpu)('equirect renderable-source integration (feat-20260707 fix)', () => {
|
|
59
|
+
const width = 64;
|
|
60
|
+
const height = 32;
|
|
61
|
+
let binBytes: Uint8Array;
|
|
62
|
+
const packageUrl = '/ddc/equirect.pack.json';
|
|
63
|
+
const artifactUrl = '/ddc/equirect.bin';
|
|
64
|
+
|
|
65
|
+
beforeAll(async () => {
|
|
66
|
+
// biome-ignore lint/style/noNonNullAssertion: skipIf(!hasGpu) guards this
|
|
67
|
+
const adapter = await gpu!.requestAdapter();
|
|
68
|
+
if (adapter === null) throw new Error('no GPU adapter under dawn');
|
|
69
|
+
bcCap = adapter.features.has('texture-compression-bc');
|
|
70
|
+
// biome-ignore lint/suspicious/noConsole: keep the caps triple empirically visible in CI logs
|
|
71
|
+
console.info(
|
|
72
|
+
`[equirect caps] bc=${bcCap} etc2=${adapter.features.has(
|
|
73
|
+
'texture-compression-etc2',
|
|
74
|
+
)} astc=${adapter.features.has('texture-compression-astc')}`,
|
|
75
|
+
);
|
|
76
|
+
binBytes = makeHdrHalf(width, height);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
function wireFetch(): void {
|
|
80
|
+
globalThis.fetch = (async (input: RequestInfo | URL) => {
|
|
81
|
+
const url = typeof input === 'string' ? input : String(input);
|
|
82
|
+
if (url === PACK_INDEX_URL) {
|
|
83
|
+
return {
|
|
84
|
+
ok: true,
|
|
85
|
+
json: async () => [{ guid: GUID_EQUI, packageUrl, kind: 'equirect' }],
|
|
86
|
+
} as Response;
|
|
87
|
+
}
|
|
88
|
+
if (url === packageUrl) {
|
|
89
|
+
return {
|
|
90
|
+
ok: true,
|
|
91
|
+
json: async () => ({
|
|
92
|
+
schemaVersion: '2.0.0',
|
|
93
|
+
kind: 'internal-text-package',
|
|
94
|
+
assets: [
|
|
95
|
+
{
|
|
96
|
+
guid: GUID_EQUI,
|
|
97
|
+
kind: 'equirect',
|
|
98
|
+
payload: {
|
|
99
|
+
kind: 'equirect',
|
|
100
|
+
width,
|
|
101
|
+
height,
|
|
102
|
+
format: 'rgba16float',
|
|
103
|
+
colorSpace: 'linear',
|
|
104
|
+
},
|
|
105
|
+
refs: [],
|
|
106
|
+
artifacts: {
|
|
107
|
+
body: {
|
|
108
|
+
path: 'equirect.bin',
|
|
109
|
+
mediaType: 'application/x-forgeax-rgba16f',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
}),
|
|
115
|
+
} as Response;
|
|
116
|
+
}
|
|
117
|
+
if (url === artifactUrl) {
|
|
118
|
+
return { ok: true, arrayBuffer: async () => binBytes.buffer } as Response;
|
|
119
|
+
}
|
|
120
|
+
return { ok: false, status: 404 } as Response;
|
|
121
|
+
}) as typeof globalThis.fetch;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function loadEquirect(): Promise<EquirectAsset> {
|
|
125
|
+
wireFetch();
|
|
126
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
127
|
+
reg.configurePackIndex(PACK_INDEX_URL);
|
|
128
|
+
reg.setTranscodeCaps({ bc: bcCap, etc2: false, astc: false });
|
|
129
|
+
const res = await reg.loadByGuid<EquirectAsset>(parseGuid(GUID_EQUI));
|
|
130
|
+
if (!res.ok) throw new Error(`equirect load failed: ${(res.error as { code: string }).code}`);
|
|
131
|
+
return res.value;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
it('equirect is uncompressed rgba16float regardless of bc cap (IBL render source)', async () => {
|
|
135
|
+
const asset = await loadEquirect();
|
|
136
|
+
expect(asset.kind).toBe('equirect');
|
|
137
|
+
// Never a block-compressed format: an equirect drives cube RENDER passes and
|
|
138
|
+
// BC6H is not color-renderable.
|
|
139
|
+
expect(asset.format).toBe('rgba16float');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('deriveRenderDataCubemap accepts the rgba16float equirect (renderable cube source)', async () => {
|
|
143
|
+
const asset = await loadEquirect();
|
|
144
|
+
// deriveRenderDataCubemap consumes a TextureAsset-shaped source; the equirect
|
|
145
|
+
// POD mirrors that 2D surface.
|
|
21
146
|
const source = {
|
|
22
147
|
kind: 'texture' as const,
|
|
23
148
|
width: asset.width,
|
|
@@ -27,9 +152,7 @@ describe('equirect renderable-source integration', () => {
|
|
|
27
152
|
colorSpace: asset.colorSpace,
|
|
28
153
|
mipmap: false,
|
|
29
154
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
expect(result.ok).toBe(true);
|
|
155
|
+
const res = deriveRenderDataCubemap(source);
|
|
156
|
+
expect(res.ok).toBe(true);
|
|
34
157
|
});
|
|
35
158
|
});
|