@forgeax/engine-render 0.1.34 → 0.1.36
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 +69 -3
- package/dist/assembly/device-feature-admission.d.ts +2 -2
- package/dist/assembly/host-contract.d.ts +3 -2
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +5 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts +1 -0
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -4
- package/dist/authoring.mjs.map +1 -1
- package/dist/chunk-2OZAS3WU.mjs +3489 -0
- package/dist/chunk-2OZAS3WU.mjs.map +1 -0
- package/dist/{chunk-UI5SFODX.mjs → chunk-BZQ4CDRF.mjs} +2338 -1991
- package/dist/chunk-BZQ4CDRF.mjs.map +1 -0
- package/dist/{chunk-MKDIT2EM.mjs → chunk-CJOV2XLO.mjs} +216 -261
- package/dist/chunk-CJOV2XLO.mjs.map +1 -0
- package/dist/chunk-D6WSBXJ2.mjs +1842 -0
- package/dist/chunk-D6WSBXJ2.mjs.map +1 -0
- package/dist/{chunk-HEB564WF.mjs → chunk-DRF6OULX.mjs} +4 -4
- package/dist/{chunk-HEB564WF.mjs.map → chunk-DRF6OULX.mjs.map} +1 -1
- package/dist/{chunk-OCDLEI6I.mjs → chunk-OB5WAFYH.mjs} +117 -5
- package/dist/chunk-OB5WAFYH.mjs.map +1 -0
- package/dist/{chunk-ODZWR6JQ.mjs → chunk-OEYKKMXG.mjs} +2042 -27
- package/dist/chunk-OEYKKMXG.mjs.map +1 -0
- package/dist/chunk-RIPAEGI6.mjs +48 -0
- package/dist/chunk-RIPAEGI6.mjs.map +1 -0
- package/dist/{chunk-ELJFJ2BU.mjs → chunk-X2KA6WHM.mjs} +29 -4
- package/dist/chunk-X2KA6WHM.mjs.map +1 -0
- package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
- package/dist/chunk-XSFB7XXQ.mjs.map +1 -0
- package/dist/cloud/frame-context.d.ts +2 -2
- package/dist/cloud/frame-context.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +936 -2140
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -19
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/errors/render.d.ts +3 -2
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/material-context.d.ts +7 -0
- package/dist/extract/material-context.d.ts.map +1 -0
- package/dist/features/host.d.ts +5 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/particle-mesh-layout.d.ts +19 -0
- package/dist/features/particle-mesh-layout.d.ts.map +1 -0
- package/dist/features/plan.d.ts +2 -0
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/types.d.ts +8 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/glyph-text-layout-system.d.ts +1 -1
- package/dist/glyph-text-layout-system.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +1 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-ownership.d.ts +3 -3
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-views.d.ts +1 -1
- package/dist/gpu-driven/shadow-views.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +1 -1
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +4 -4
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +542 -9
- package/dist/index.mjs.map +1 -1
- package/dist/instances.d.ts +3 -4
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -8
- package/dist/internal.mjs.map +1 -1
- package/dist/pbr-pipeline.d.ts +3 -3
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-output/lut-gpu.d.ts +2 -2
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
- package/dist/pipeline/standard-output/resources.d.ts +2 -2
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -1
- package/dist/publication/contract.d.ts +77 -0
- package/dist/publication/contract.d.ts.map +1 -0
- package/dist/publication/dependencies.d.ts +7 -0
- package/dist/publication/dependencies.d.ts.map +1 -0
- package/dist/publication/prepare-geometry.d.ts +9 -0
- package/dist/publication/prepare-geometry.d.ts.map +1 -0
- package/dist/publication/programs.d.ts +5 -0
- package/dist/publication/programs.d.ts.map +1 -0
- package/dist/publication/publisher.d.ts +34 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/receiver.d.ts +29 -0
- package/dist/publication/receiver.d.ts.map +1 -0
- package/dist/publication/resource-scope.d.ts +18 -0
- package/dist/publication/resource-scope.d.ts.map +1 -0
- package/dist/publication/targets.d.ts +33 -0
- package/dist/publication/targets.d.ts.map +1 -0
- package/dist/publication/video.d.ts +5 -0
- package/dist/publication/video.d.ts.map +1 -0
- package/dist/record/fold-buckets.d.ts +3 -3
- package/dist/record/fold-buckets.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +6 -6
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +5 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +2 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +2 -2
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -9
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +3 -16
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/prepared-material-bindings.d.ts +2 -3
- package/dist/record/prepared-material-bindings.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +4 -2
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -2
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/sprite-instance-buffer.d.ts +31 -0
- package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
- package/dist/record/target-capture-graph.d.ts +19 -0
- package/dist/record/target-capture-graph.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +2 -13
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +2 -2
- package/dist/record/volume-params.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +5 -12
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/render-contract.d.ts +4 -1
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +2 -0
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +2 -2
- package/dist/render-system-presentation.d.ts.map +1 -1
- package/dist/render-system-projections.d.ts +3 -2
- package/dist/render-system-projections.d.ts.map +1 -1
- package/dist/render-system-residency.d.ts +2 -2
- package/dist/render-system-residency.d.ts.map +1 -1
- package/dist/render-system.d.ts +3 -7
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +8 -4
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/render-source.d.ts +42 -0
- package/dist/scene/render-source.d.ts.map +1 -0
- package/dist/scene/source-systems.d.ts +6 -0
- package/dist/scene/source-systems.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +10 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +2 -2
- package/dist/systems/transparent-dispatch.d.ts.map +1 -1
- package/dist/systems/transparent-sort-config.d.ts +2 -1
- package/dist/systems/transparent-sort-config.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -7
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/package.json +21 -21
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
- package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +26 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +3 -4
- package/src/__tests__/gpu-driven-production.integration.test.ts +18 -1
- package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +23 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +0 -1
- package/src/__tests__/material-vertex-texture.browser.test.ts +7 -0
- package/src/__tests__/material-vertex-texture.dawn.test.ts +7 -0
- package/src/__tests__/material-vertex-texture.fixture.ts +31 -0
- package/src/__tests__/materials-standard-contract.unit.test.ts +0 -1
- package/src/__tests__/physical-clearcoat.integration.test.ts +23 -23
- package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +5 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +107 -5
- package/src/__tests__/runtime-material-program.integration.test.ts +79 -0
- package/src/__tests__/vertex-layouts-ssot.unit.test.ts +23 -3
- package/src/assembly/device-feature-admission.ts +2 -2
- package/src/assembly/host-contract.ts +5 -2
- package/src/assembly/recovery/renderer-recover.ts +9 -0
- package/src/assembly/render-target-host.ts +57 -47
- package/src/assembly/renderer-facade.ts +3 -1
- package/src/assembly/webgpu-ready.ts +1 -1
- package/src/assembly/webgpu-renderer.ts +101 -70
- package/src/assembly/webgpu-vertex-layouts.ts +2 -9
- package/src/cloud/frame-context.ts +2 -2
- package/src/device/device-scope.ts +3 -0
- package/src/device/gpu-residency.ts +26 -25
- package/src/errors/render.ts +3 -1
- package/src/extract/material-context.ts +21 -0
- package/src/features/host.ts +13 -5
- package/src/features/particle-mesh-layout.ts +25 -0
- package/src/features/plan.ts +2 -0
- package/src/features/types.ts +8 -0
- package/src/glyph-text-layout-system.ts +2 -2
- package/src/gpu-driven/production-raster.ts +9 -3
- package/src/gpu-driven/shadow-ownership.ts +3 -3
- package/src/gpu-driven/shadow-views.ts +27 -2
- package/src/gpu-driven/view-gpu.ts +5 -0
- package/src/ibl/frame-resources.ts +0 -1
- package/src/ibl/skylight-bind-group.ts +13 -25
- package/src/index.ts +9 -0
- package/src/instances.ts +9 -6
- package/src/pbr-pipeline.ts +15 -18
- package/src/pipeline/standard-output/lut-gpu.ts +3 -3
- package/src/pipeline/standard-output/resources.ts +2 -2
- package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
- package/src/publication/__tests__/features.integration.test.ts +173 -0
- package/src/publication/__tests__/programs.unit.test.ts +25 -0
- package/src/publication/__tests__/publication.integration.test.ts +415 -0
- package/src/publication/__tests__/targets.integration.test.ts +120 -0
- package/src/publication/__tests__/video.browser.test.ts +50 -0
- package/src/publication/contract.ts +104 -0
- package/src/publication/dependencies.ts +54 -0
- package/src/publication/prepare-geometry.ts +94 -0
- package/src/publication/programs.ts +45 -0
- package/src/publication/publisher.ts +645 -0
- package/src/publication/receiver.ts +297 -0
- package/src/publication/resource-scope.ts +31 -0
- package/src/publication/targets.ts +182 -0
- package/src/publication/video.ts +33 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
- package/src/record/__tests__/prepared-runtime-material.integration.test.ts +134 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +8 -10
- package/src/record/__tests__/video-texture-view.unit.test.ts +9 -9
- package/src/record/fold-buckets.ts +8 -5
- package/src/record/frame-snapshot.ts +6 -6
- package/src/record/frame.ts +87 -28
- package/src/record/helpers.ts +2 -2
- package/src/record/main-pass-geometry.ts +21 -2
- package/src/record/main-pass-material.ts +37 -33
- package/src/record/main-pass-sprite-draws.ts +6 -152
- package/src/record/main-pass.ts +8 -7
- package/src/record/prepared-material-bindings.ts +16 -37
- package/src/record/render-context.ts +4 -2
- package/src/record/shadow-pass.ts +65 -7
- package/src/record/sprite-instance-buffer.ts +155 -0
- package/src/record/target-capture-graph.ts +258 -0
- package/src/record/typed-frame-graph.ts +11 -207
- package/src/record/view-ubo.ts +1 -1
- package/src/record/volume-params.ts +6 -6
- package/src/recovery/render-system-candidate.ts +10 -18
- package/src/render-contract.ts +6 -1
- package/src/render-system-extract-tail.ts +48 -23
- package/src/render-system-extract.ts +11 -2
- package/src/render-system-presentation.ts +2 -2
- package/src/render-system-projections.ts +3 -2
- package/src/render-system-residency.ts +2 -2
- package/src/render-system.ts +82 -54
- package/src/scene/render-scene.ts +110 -100
- package/src/scene/render-source.ts +90 -0
- package/src/scene/source-systems.ts +33 -0
- package/src/systems/skin-palette-allocator.ts +1 -0
- package/src/systems/skin-palette-types.ts +11 -0
- package/src/systems/transparent-dispatch.ts +2 -2
- package/src/systems/transparent-sort-config.ts +3 -1
- package/src/typed-shadow-passes.ts +36 -5
- package/dist/chunk-BLXGONR2.mjs.map +0 -1
- package/dist/chunk-ELJFJ2BU.mjs.map +0 -1
- package/dist/chunk-ILQ5MEZF.mjs +0 -32
- package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
- package/dist/chunk-MKDIT2EM.mjs.map +0 -1
- package/dist/chunk-OCDLEI6I.mjs.map +0 -1
- package/dist/chunk-ODZWR6JQ.mjs.map +0 -1
- package/dist/chunk-RXZ3RGOU.mjs +0 -53
- package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
- package/dist/chunk-SHFUFJ5N.mjs +0 -1781
- package/dist/chunk-SHFUFJ5N.mjs.map +0 -1
- package/dist/chunk-UI5SFODX.mjs.map +0 -1
- package/dist/chunk-UINHLCZA.mjs +0 -2389
- package/dist/chunk-UINHLCZA.mjs.map +0 -1
- package/dist/chunk-WEX45HKH.mjs +0 -1524
- package/dist/chunk-WEX45HKH.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/temporal/temporal-view.ts","../src/temporal/taa-history-store.ts","../src/temporal/frame-coordinator.ts"],"names":[],"mappings":"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","file":"chunk-HEB564WF.mjs","sourcesContent":["import { mat4 } from '@forgeax/engine-math';\nimport type { CameraProjection } from '../components/camera';\nimport type { CameraSnapshot } from '../render-contract';\n\nexport const TEMPORAL_JITTER_SAMPLE_COUNT = 8;\n\n/** TAAU shares the temporal view owner; its internal dimensions are optional. */\nexport const TEMPORAL_TAAU_DEPENDENCY_STATUS = 'available' as const;\n\nexport type TemporalViewResetReason =\n | 'first-frame'\n | 'camera-switch'\n | 'history-version-changed'\n | 'projection-kind-changed'\n | 'projection-range-changed';\n\nexport interface SubmittedTemporalView {\n readonly viewId: string;\n readonly historyVersion: number;\n readonly projection: CameraProjection;\n readonly near: number;\n readonly far: number;\n readonly jitterUv: readonly [number, number];\n readonly unjitteredViewProjection: Float32Array;\n}\n\nexport interface TemporalView {\n readonly viewId: string;\n readonly historyVersion: number;\n readonly temporalFrameIndex: number;\n readonly historyValid: boolean;\n readonly resetReason: TemporalViewResetReason | undefined;\n readonly currentJitterUv: readonly [number, number];\n readonly internalWidth: number;\n readonly internalHeight: number;\n readonly previousJitterUv: readonly [number, number];\n readonly currentJitteredViewProjection: Float32Array;\n readonly currentUnjitteredViewProjection: Float32Array;\n readonly previousUnjitteredViewProjection: Float32Array;\n readonly projection: CameraProjection;\n readonly near: number;\n readonly far: number;\n}\n\nexport interface TemporalViewInput {\n readonly camera: CameraSnapshot;\n readonly temporalFrameIndex: number;\n readonly surfaceWidth: number;\n readonly surfaceHeight: number;\n readonly internalWidth?: number;\n readonly internalHeight?: number;\n readonly lastSubmitted?: SubmittedTemporalView;\n}\n\nexport function temporalViewId(worldId: number, entityKey: number): string {\n const raw = entityKey >>> 0;\n const index = raw & 0x00ffffff;\n const generation = (raw >>> 24) & 0xff;\n return `${worldId}:${index}:${generation}`;\n}\n\nfunction halton(index: number, base: number): number {\n let result = 0;\n let fraction = 1 / base;\n let value = index;\n while (value > 0) {\n result += fraction * (value % base);\n value = Math.floor(value / base);\n fraction /= base;\n }\n return result;\n}\n\nexport function temporalJitterSample(temporalFrameIndex: number): readonly [number, number] {\n const sampleIndex =\n ((Math.trunc(temporalFrameIndex) % TEMPORAL_JITTER_SAMPLE_COUNT) +\n TEMPORAL_JITTER_SAMPLE_COUNT) %\n TEMPORAL_JITTER_SAMPLE_COUNT;\n const haltonIndex = sampleIndex + 1;\n return [halton(haltonIndex, 2) - 0.5, halton(haltonIndex, 3) - 0.5];\n}\n\nfunction temporalJitterUv(\n temporalFrameIndex: number,\n surfaceWidth: number,\n surfaceHeight: number,\n): readonly [number, number] {\n const sample = temporalJitterSample(temporalFrameIndex);\n return [sample[0] / Math.max(1, surfaceWidth), sample[1] / Math.max(1, surfaceHeight)];\n}\n\nfunction cameraProjection(camera: CameraSnapshot): Float32Array {\n const projection = mat4.create();\n if (camera.projection === 'orthographic') {\n mat4.orthographic(\n projection,\n camera.orthoLeft,\n camera.orthoRight,\n camera.orthoTop,\n camera.orthoBottom,\n camera.near,\n camera.far,\n );\n } else {\n mat4.perspective(projection, camera.fov, camera.aspect, camera.near, camera.far);\n }\n return projection;\n}\n\nfunction resetReason(\n current: CameraSnapshot,\n viewId: string,\n previous: SubmittedTemporalView | undefined,\n): TemporalViewResetReason | undefined {\n if (previous === undefined) return 'first-frame';\n if (previous.viewId !== viewId) return 'camera-switch';\n if (previous.historyVersion !== (current.historyVersion ?? 0)) {\n return 'history-version-changed';\n }\n if (previous.projection !== current.projection) return 'projection-kind-changed';\n if (!Object.is(previous.near, current.near) || !Object.is(previous.far, current.far)) {\n return 'projection-range-changed';\n }\n return undefined;\n}\n\nexport function projectTemporalView(input: TemporalViewInput): TemporalView {\n const { camera } = input;\n const viewId = temporalViewId(camera.worldId ?? 0, camera.entityKey ?? 0);\n const currentJitterUv = temporalJitterUv(\n input.temporalFrameIndex,\n input.internalWidth ?? input.surfaceWidth,\n input.internalHeight ?? input.surfaceHeight,\n );\n const view = mat4.invert(mat4.create(), camera.world);\n const projection = cameraProjection(camera);\n const currentUnjitteredViewProjection = mat4.multiply(mat4.create(), projection, view);\n const clipJitter = mat4.identity(mat4.create());\n clipJitter[12] = currentJitterUv[0] * 2;\n clipJitter[13] = currentJitterUv[1] * -2;\n const jitteredProjection = mat4.multiply(mat4.create(), clipJitter, projection);\n const currentJitteredViewProjection = mat4.multiply(mat4.create(), jitteredProjection, view);\n const reason = resetReason(camera, viewId, input.lastSubmitted);\n const historyValid = reason === undefined;\n return {\n viewId,\n historyVersion: camera.historyVersion ?? 0,\n temporalFrameIndex: input.temporalFrameIndex,\n historyValid,\n resetReason: reason,\n currentJitterUv,\n internalWidth: input.internalWidth ?? input.surfaceWidth,\n internalHeight: input.internalHeight ?? input.surfaceHeight,\n previousJitterUv: historyValid\n ? (input.lastSubmitted?.jitterUv ?? currentJitterUv)\n : currentJitterUv,\n currentJitteredViewProjection,\n currentUnjitteredViewProjection,\n previousUnjitteredViewProjection: historyValid\n ? (input.lastSubmitted?.unjitteredViewProjection ?? currentUnjitteredViewProjection)\n : currentUnjitteredViewProjection,\n projection: camera.projection,\n near: camera.near,\n far: camera.far,\n };\n}\n\nexport function snapshotSubmittedTemporalView(view: TemporalView): SubmittedTemporalView {\n return {\n viewId: view.viewId,\n historyVersion: view.historyVersion,\n projection: view.projection,\n near: view.near,\n far: view.far,\n jitterUv: [view.currentJitterUv[0], view.currentJitterUv[1]],\n unjitteredViewProjection: new Float32Array(view.currentUnjitteredViewProjection),\n };\n}\n","export type TaaHistoryResetReason =\n | 'first-frame'\n | 'camera-cut'\n | 'resize'\n | 'recover'\n | 'device-generation';\n\nexport interface TaaHistoryInspection {\n readonly token: number;\n readonly deviceGeneration: number;\n readonly content: 'uninitialized' | 'active';\n readonly fallback: 'neutral-texture';\n readonly requestVersion: number;\n readonly generation: number;\n readonly seed: number;\n readonly attempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly valid: boolean;\n readonly resetReason: TaaHistoryResetReason | undefined;\n}\n\nexport interface TaaHistoryReceipt {\n readonly deviceGeneration: number;\n readonly completed: boolean;\n}\n\nexport interface TaaHistoryAttempt {\n readonly generation: number;\n readonly seed: number;\n commit(receipt?: TaaHistoryReceipt): void;\n abort(): void;\n}\n\nlet nextHistoryToken = 1;\n\n/** TAA-only history owner. No global registry or backend handle crosses this boundary. */\nexport class TaaHistoryStore {\n private readonly token = nextHistoryToken++;\n private deviceGeneration = 0;\n private content: TaaHistoryInspection['content'] = 'uninitialized';\n private requestVersion = 0;\n private generation = 0;\n private seed = 0;\n private valid = false;\n private attempt: TaaHistoryInspection['attempt'] = 'none';\n private resetReason: TaaHistoryResetReason | undefined;\n\n begin(reason: TaaHistoryResetReason | undefined = undefined): TaaHistoryAttempt {\n const generation = this.generation;\n const seed = this.seed;\n this.attempt = 'active';\n let state: 'active' | 'committed' | 'aborted' = 'active';\n return {\n generation,\n seed,\n commit: (receipt) => {\n if (state !== 'active') return;\n if (\n receipt !== undefined &&\n (!receipt.completed || receipt.deviceGeneration !== this.deviceGeneration)\n ) {\n state = 'aborted';\n this.attempt = 'aborted';\n return;\n }\n state = 'committed';\n this.attempt = 'committed';\n this.valid = true;\n this.content = 'active';\n this.requestVersion += 1;\n this.generation += 1;\n this.seed += 1;\n this.resetReason = reason;\n },\n abort: () => {\n if (state !== 'active') return;\n state = 'aborted';\n this.attempt = 'aborted';\n },\n };\n }\n\n seedHistory(reason: TaaHistoryResetReason = 'first-frame'): void {\n this.valid = false;\n this.content = 'uninitialized';\n this.resetReason = reason;\n this.attempt = 'none';\n }\n\n reset(reason: TaaHistoryResetReason): void {\n this.generation = 0;\n this.seed = 0;\n this.valid = false;\n this.content = 'uninitialized';\n this.attempt = 'none';\n this.resetReason = reason;\n }\n\n recoverForGeneration(deviceGeneration: number): void {\n if (!Number.isSafeInteger(deviceGeneration) || deviceGeneration < 0) {\n throw new RangeError('deviceGeneration must be a non-negative safe integer.');\n }\n this.deviceGeneration = deviceGeneration;\n this.valid = false;\n this.content = 'uninitialized';\n this.attempt = 'none';\n this.resetReason = 'device-generation';\n }\n\n inspect(): TaaHistoryInspection {\n return {\n token: this.token,\n deviceGeneration: this.deviceGeneration,\n content: this.content,\n fallback: 'neutral-texture',\n requestVersion: this.requestVersion,\n generation: this.generation,\n seed: this.seed,\n attempt: this.attempt,\n valid: this.valid,\n resetReason: this.resetReason,\n };\n }\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport { motionBlurTemporalDemand } from '../features/motion-blur/motion-blur-params';\nimport type { CameraSnapshot } from '../render-contract';\nimport { classifySceneDataCoverage, type SceneDataContributor } from './coverage';\nimport { type TaaHistoryAttempt, TaaHistoryStore } from './taa-history-store';\nimport {\n projectTemporalView,\n type SubmittedTemporalView,\n snapshotSubmittedTemporalView,\n type TemporalView,\n} from './temporal-view';\n\n/** The only stages that may publish a temporal frame. */\nexport type TemporalFrameStage = 'build' | 'encode' | 'finish' | 'submit';\n\n/** Closed list of consumers that share the renderer temporal transaction. */\nexport type TemporalFrameConsumerId = 'taa' | 'motion-blur' | 'ssr';\n\nexport type TemporalFrameErrorCode = 'taa-unavailable' | 'temporal-active' | 'temporal-not-active';\n\nexport interface TemporalFrameError {\n readonly code: TemporalFrameErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: Readonly<Record<string, unknown>>;\n}\n\nexport interface TemporalFrameSnapshot<T = unknown> {\n readonly epoch: number;\n readonly previous: T | undefined;\n readonly consumerIds: readonly TemporalFrameConsumerId[];\n readonly historyAttempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly attempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly lastFailure: TemporalFrameStage | undefined;\n readonly coverage: {\n readonly exactContributorIds: readonly string[];\n readonly reactiveContributorIds: readonly string[];\n readonly missingContributorIds: readonly string[];\n readonly omittedMissingContributorCount: number;\n };\n}\n\nexport interface TemporalFrameBeginInput<T = unknown> {\n readonly current: T;\n readonly antialias: 'none' | 'fxaa' | 'msaa' | 'taa';\n /** Enables the shared transaction for a temporal feature without TAA. */\n readonly temporalDemand?: boolean;\n /** Consumers registered on this one renderer-owned frame transaction. */\n readonly consumerIds?: readonly TemporalFrameConsumerId[];\n readonly available?: boolean;\n readonly contributors?: readonly SceneDataContributor[];\n readonly requiredContributorIds?: readonly string[];\n /** Projection produced before record uploads; it commits with the frame. */\n readonly temporalView?: TemporalView;\n}\n\nexport interface TemporalFrameCandidate<T = unknown> {\n readonly epoch: number;\n readonly current: T;\n readonly previous: T | undefined;\n readonly history: { readonly direction: 'a-to-b' | 'b-to-a'; readonly valid: boolean };\n readonly contributors: readonly SceneDataContributor[];\n readonly requiredContributorIds: readonly string[];\n readonly consumerIds: readonly TemporalFrameConsumerId[];\n readonly temporalView?: TemporalView;\n}\n\nexport interface TemporalFramePhases<T = unknown> {\n readonly build: () => T;\n readonly encode: (built: T) => void;\n readonly finish: () => void;\n readonly submit: () => void;\n}\n\nexport interface TemporalFrameReceipt<T = unknown> {\n readonly epoch: number;\n readonly previous: T;\n readonly historyDirection: 'a-to-b' | 'b-to-a';\n}\n\nexport type ReflectionFallbackTemporalReset =\n | { readonly reset: false }\n | { readonly reset: true; readonly reason: 'reflection-fallback-generation' };\n\n/** Maps committed producer generations into the existing temporal reset seam. */\nexport function resolveReflectionFallbackTemporalReset(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): ReflectionFallbackTemporalReset {\n if (previousGeneration === undefined || nextGeneration === undefined) return { reset: false };\n return previousGeneration === nextGeneration\n ? { reset: false }\n : { reset: true, reason: 'reflection-fallback-generation' };\n}\n\n/**\n * Keeps SSR admission on the existing producer-generation reset seam. The\n * admission path never allocates or resolves temporal history itself.\n */\nexport function resolveSsrAdmissionTemporalReset(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): ReflectionFallbackTemporalReset {\n return resolveReflectionFallbackTemporalReset(previousGeneration, nextGeneration);\n}\n\nfunction failure(code: TemporalFrameErrorCode, hint: string): TemporalFrameError {\n return {\n code,\n expected:\n code === 'taa-unavailable'\n ? 'TAA resources and capability are available'\n : 'one temporal frame is active',\n hint,\n };\n}\n\n/**\n * Renderer-owned temporal transaction. It has no graph or backend dependency:\n * graph assembly supplies the four phase callbacks and only submit publishes\n * the candidate snapshot.\n */\nexport class TemporalFrameCoordinator<T = unknown> {\n readonly historyStore: TaaHistoryStore;\n private epoch: number;\n private previous: T | undefined;\n private consumerIds: readonly TemporalFrameConsumerId[] = [];\n private active: TemporalFrameCandidate<T> | undefined;\n private attempt: TemporalFrameSnapshot<T>['attempt'] = 'none';\n private historyAttempt: TemporalFrameSnapshot<T>['historyAttempt'] = 'none';\n private lastFailure: TemporalFrameStage | undefined;\n private historyDirection: 'a-to-b' | 'b-to-a' = 'a-to-b';\n private temporalFrameIndex = 0;\n private lastSubmittedView: SubmittedTemporalView | undefined;\n private coverage: TemporalFrameSnapshot<T>['coverage'] = {\n exactContributorIds: [],\n reactiveContributorIds: [],\n missingContributorIds: [],\n omittedMissingContributorCount: 0,\n };\n private readonly historyAttempts = new WeakMap<object, TaaHistoryAttempt>();\n\n constructor(\n initial: {\n readonly epoch?: number;\n readonly previous?: T;\n readonly historyStore?: TaaHistoryStore;\n } = {},\n ) {\n this.historyStore = initial.historyStore ?? new TaaHistoryStore();\n this.epoch = initial.epoch ?? 0;\n this.previous = initial.previous;\n }\n\n begin(input: TemporalFrameBeginInput<T>): Result<TemporalFrameCandidate<T>, TemporalFrameError> {\n const consumerIds = Object.freeze([...(input.consumerIds ?? [])]);\n const demanded =\n input.antialias === 'taa' || input.temporalDemand === true || consumerIds.length > 0;\n if (!demanded) {\n return ok({\n epoch: this.epoch,\n current: input.current,\n previous: this.previous,\n history: { direction: this.historyDirection, valid: false },\n contributors: Object.freeze([...(input.contributors ?? [])]),\n requiredContributorIds: Object.freeze([...(input.requiredContributorIds ?? [])]),\n consumerIds,\n ...(input.temporalView === undefined ? {} : { temporalView: input.temporalView }),\n });\n }\n if (input.available === false) {\n return err(\n failure('taa-unavailable', 'enable rgba16float temporal targets and retry the frame'),\n );\n }\n if (this.active !== undefined) {\n return err(\n failure(\n 'temporal-active',\n 'commit or abort the active temporal frame before beginning another',\n ),\n );\n }\n const candidate: TemporalFrameCandidate<T> = {\n epoch: this.epoch + 1,\n current: input.current,\n previous: this.previous,\n history: { direction: this.historyDirection, valid: this.previous !== undefined },\n contributors: Object.freeze([...(input.contributors ?? [])]),\n requiredContributorIds: Object.freeze([...(input.requiredContributorIds ?? [])]),\n consumerIds,\n ...(input.temporalView === undefined ? {} : { temporalView: input.temporalView }),\n };\n if (input.antialias === 'taa') {\n this.historyAttempts.set(candidate, this.historyStore.begin());\n }\n this.active = candidate;\n this.attempt = 'active';\n this.historyAttempt = input.antialias === 'taa' ? 'active' : 'none';\n this.lastFailure = undefined;\n return ok(candidate);\n }\n\n commit(\n candidate: TemporalFrameCandidate<T>,\n ): Result<TemporalFrameReceipt<T>, TemporalFrameError> {\n if (this.active !== candidate) {\n return err(failure('temporal-not-active', 'commit the candidate returned by begin'));\n }\n this.epoch = candidate.epoch;\n this.previous = candidate.current;\n if (candidate.temporalView !== undefined) {\n this.lastSubmittedView = snapshotSubmittedTemporalView(candidate.temporalView);\n this.temporalFrameIndex += 1;\n }\n this.historyDirection = candidate.history.direction === 'a-to-b' ? 'b-to-a' : 'a-to-b';\n this.consumerIds = candidate.consumerIds;\n const historyAttempt = this.historyAttempts.get(candidate);\n historyAttempt?.commit({\n deviceGeneration: this.historyStore.inspect().deviceGeneration,\n completed: true,\n });\n this.coverage = classifySceneDataCoverage({\n contributors: candidate.contributors,\n requiredContributorIds: candidate.requiredContributorIds,\n });\n this.active = undefined;\n historyAttempt?.abort();\n this.historyAttempts.delete(candidate);\n this.attempt = 'committed';\n this.historyAttempt = historyAttempt === undefined ? 'none' : 'committed';\n return ok({\n epoch: this.epoch,\n previous: candidate.current,\n historyDirection: candidate.history.direction,\n });\n }\n\n abort(candidate: TemporalFrameCandidate<T>, stage: TemporalFrameStage = 'submit'): void {\n if (this.active !== candidate) return;\n this.historyAttempts.get(candidate)?.abort();\n this.historyAttempts.delete(candidate);\n this.active = undefined;\n this.attempt = 'aborted';\n this.historyAttempt = 'aborted';\n this.lastFailure = stage;\n }\n\n run(\n input: TemporalFrameBeginInput<T>,\n phases: TemporalFramePhases<T>,\n ): Result<TemporalFrameReceipt<T> | undefined, TemporalFrameError> {\n const started = this.begin(input);\n if (!started.ok) return started;\n const candidate = started.value;\n if (\n input.antialias !== 'taa' &&\n input.temporalDemand !== true &&\n (input.consumerIds?.length ?? 0) === 0\n ) {\n return ok(undefined);\n }\n try {\n const built = phases.build();\n phases.encode(built);\n phases.finish();\n phases.submit();\n } catch (cause) {\n const stage = this.stageFromError(cause);\n this.abort(candidate, stage);\n return err({\n code: 'temporal-not-active',\n expected: `temporal ${stage} succeeds before commit`,\n hint: 'inspect the underlying stage failure and retry the frame',\n detail: { stage, cause },\n });\n }\n return this.commit(candidate);\n }\n\n inspect(): TemporalFrameSnapshot<T> {\n return {\n epoch: this.epoch,\n previous: this.previous,\n consumerIds: this.consumerIds,\n historyAttempt: this.historyAttempt,\n attempt: this.attempt,\n lastFailure: this.lastFailure,\n coverage: this.coverage,\n };\n }\n\n /**\n * Derive the current/previous camera matrices without mutating history.\n * `commit()` is the only operation that publishes the returned view, so a\n * graph/finish/submit failure leaves the last successful view intact.\n */\n prepareTemporalView(\n camera: CameraSnapshot,\n surfaceWidth: number,\n surfaceHeight: number,\n ): TemporalView | undefined {\n const demanded =\n camera.antialias === 'taa' ||\n (camera.motionBlur !== undefined &&\n motionBlurTemporalDemand({\n shutterAngle: camera.motionBlur.shutterAngle,\n maxRadiusPixels: camera.motionBlur.maxRadiusPixels,\n sampleCount: camera.motionBlur.sampleCount,\n targetFps: camera.motionBlur.targetFps ?? 60,\n }));\n if (!demanded) return undefined;\n return projectTemporalView({\n camera,\n temporalFrameIndex: this.temporalFrameIndex,\n surfaceWidth,\n surfaceHeight,\n ...(this.lastSubmittedView === undefined ? {} : { lastSubmitted: this.lastSubmittedView }),\n });\n }\n\n reset(\n reason:\n | 'cut'\n | 'resize'\n | 'camera-switch'\n | 'detach'\n | 'recover'\n | 'device-loss'\n | 'device-generation' = 'recover',\n ): void {\n void reason;\n this.active = undefined;\n this.epoch = 0;\n this.previous = undefined;\n this.temporalFrameIndex = 0;\n this.lastSubmittedView = undefined;\n this.historyDirection = 'a-to-b';\n this.historyStore.reset(\n reason === 'cut' || reason === 'camera-switch'\n ? 'camera-cut'\n : reason === 'resize'\n ? 'resize'\n : reason === 'device-generation' || reason === 'device-loss'\n ? 'device-generation'\n : 'recover',\n );\n this.attempt = 'none';\n this.historyAttempt = 'none';\n this.lastFailure = undefined;\n this.coverage = {\n exactContributorIds: [],\n reactiveContributorIds: [],\n missingContributorIds: [],\n omittedMissingContributorCount: 0,\n };\n this.consumerIds = [];\n }\n\n private stageFromError(cause: unknown): TemporalFrameStage {\n if (typeof cause === 'object' && cause !== null && 'stage' in cause) {\n const stage = (cause as { stage?: unknown }).stage;\n if (stage === 'build' || stage === 'encode' || stage === 'finish' || stage === 'submit')\n return stage;\n }\n return 'submit';\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/temporal/temporal-view.ts","../src/temporal/taa-history-store.ts","../src/temporal/frame-coordinator.ts"],"names":[],"mappings":"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","file":"chunk-DRF6OULX.mjs","sourcesContent":["import { mat4 } from '@forgeax/engine-math';\nimport type { CameraProjection } from '../components/camera';\nimport type { CameraSnapshot } from '../render-contract';\n\nexport const TEMPORAL_JITTER_SAMPLE_COUNT = 8;\n\n/** TAAU shares the temporal view owner; its internal dimensions are optional. */\nexport const TEMPORAL_TAAU_DEPENDENCY_STATUS = 'available' as const;\n\nexport type TemporalViewResetReason =\n | 'first-frame'\n | 'camera-switch'\n | 'history-version-changed'\n | 'projection-kind-changed'\n | 'projection-range-changed';\n\nexport interface SubmittedTemporalView {\n readonly viewId: string;\n readonly historyVersion: number;\n readonly projection: CameraProjection;\n readonly near: number;\n readonly far: number;\n readonly jitterUv: readonly [number, number];\n readonly unjitteredViewProjection: Float32Array;\n}\n\nexport interface TemporalView {\n readonly viewId: string;\n readonly historyVersion: number;\n readonly temporalFrameIndex: number;\n readonly historyValid: boolean;\n readonly resetReason: TemporalViewResetReason | undefined;\n readonly currentJitterUv: readonly [number, number];\n readonly internalWidth: number;\n readonly internalHeight: number;\n readonly previousJitterUv: readonly [number, number];\n readonly currentJitteredViewProjection: Float32Array;\n readonly currentUnjitteredViewProjection: Float32Array;\n readonly previousUnjitteredViewProjection: Float32Array;\n readonly projection: CameraProjection;\n readonly near: number;\n readonly far: number;\n}\n\nexport interface TemporalViewInput {\n readonly camera: CameraSnapshot;\n readonly temporalFrameIndex: number;\n readonly surfaceWidth: number;\n readonly surfaceHeight: number;\n readonly internalWidth?: number;\n readonly internalHeight?: number;\n readonly lastSubmitted?: SubmittedTemporalView;\n}\n\nexport function temporalViewId(worldId: number, entityKey: number): string {\n const raw = entityKey >>> 0;\n const index = raw & 0x00ffffff;\n const generation = (raw >>> 24) & 0xff;\n return `${worldId}:${index}:${generation}`;\n}\n\nfunction halton(index: number, base: number): number {\n let result = 0;\n let fraction = 1 / base;\n let value = index;\n while (value > 0) {\n result += fraction * (value % base);\n value = Math.floor(value / base);\n fraction /= base;\n }\n return result;\n}\n\nexport function temporalJitterSample(temporalFrameIndex: number): readonly [number, number] {\n const sampleIndex =\n ((Math.trunc(temporalFrameIndex) % TEMPORAL_JITTER_SAMPLE_COUNT) +\n TEMPORAL_JITTER_SAMPLE_COUNT) %\n TEMPORAL_JITTER_SAMPLE_COUNT;\n const haltonIndex = sampleIndex + 1;\n return [halton(haltonIndex, 2) - 0.5, halton(haltonIndex, 3) - 0.5];\n}\n\nfunction temporalJitterUv(\n temporalFrameIndex: number,\n surfaceWidth: number,\n surfaceHeight: number,\n): readonly [number, number] {\n const sample = temporalJitterSample(temporalFrameIndex);\n return [sample[0] / Math.max(1, surfaceWidth), sample[1] / Math.max(1, surfaceHeight)];\n}\n\nfunction cameraProjection(camera: CameraSnapshot): Float32Array {\n const projection = mat4.create();\n if (camera.projection === 'orthographic') {\n mat4.orthographic(\n projection,\n camera.orthoLeft,\n camera.orthoRight,\n camera.orthoTop,\n camera.orthoBottom,\n camera.near,\n camera.far,\n );\n } else {\n mat4.perspective(projection, camera.fov, camera.aspect, camera.near, camera.far);\n }\n return projection;\n}\n\nfunction resetReason(\n current: CameraSnapshot,\n viewId: string,\n previous: SubmittedTemporalView | undefined,\n): TemporalViewResetReason | undefined {\n if (previous === undefined) return 'first-frame';\n if (previous.viewId !== viewId) return 'camera-switch';\n if (previous.historyVersion !== (current.historyVersion ?? 0)) {\n return 'history-version-changed';\n }\n if (previous.projection !== current.projection) return 'projection-kind-changed';\n if (!Object.is(previous.near, current.near) || !Object.is(previous.far, current.far)) {\n return 'projection-range-changed';\n }\n return undefined;\n}\n\nexport function projectTemporalView(input: TemporalViewInput): TemporalView {\n const { camera } = input;\n const viewId = temporalViewId(camera.worldId ?? 0, camera.entityKey ?? 0);\n const currentJitterUv = temporalJitterUv(\n input.temporalFrameIndex,\n input.internalWidth ?? input.surfaceWidth,\n input.internalHeight ?? input.surfaceHeight,\n );\n const view = mat4.invert(mat4.create(), camera.world);\n const projection = cameraProjection(camera);\n const currentUnjitteredViewProjection = mat4.multiply(mat4.create(), projection, view);\n const clipJitter = mat4.identity(mat4.create());\n clipJitter[12] = currentJitterUv[0] * 2;\n clipJitter[13] = currentJitterUv[1] * -2;\n const jitteredProjection = mat4.multiply(mat4.create(), clipJitter, projection);\n const currentJitteredViewProjection = mat4.multiply(mat4.create(), jitteredProjection, view);\n const reason = resetReason(camera, viewId, input.lastSubmitted);\n const historyValid = reason === undefined;\n return {\n viewId,\n historyVersion: camera.historyVersion ?? 0,\n temporalFrameIndex: input.temporalFrameIndex,\n historyValid,\n resetReason: reason,\n currentJitterUv,\n internalWidth: input.internalWidth ?? input.surfaceWidth,\n internalHeight: input.internalHeight ?? input.surfaceHeight,\n previousJitterUv: historyValid\n ? (input.lastSubmitted?.jitterUv ?? currentJitterUv)\n : currentJitterUv,\n currentJitteredViewProjection,\n currentUnjitteredViewProjection,\n previousUnjitteredViewProjection: historyValid\n ? (input.lastSubmitted?.unjitteredViewProjection ?? currentUnjitteredViewProjection)\n : currentUnjitteredViewProjection,\n projection: camera.projection,\n near: camera.near,\n far: camera.far,\n };\n}\n\nexport function snapshotSubmittedTemporalView(view: TemporalView): SubmittedTemporalView {\n return {\n viewId: view.viewId,\n historyVersion: view.historyVersion,\n projection: view.projection,\n near: view.near,\n far: view.far,\n jitterUv: [view.currentJitterUv[0], view.currentJitterUv[1]],\n unjitteredViewProjection: new Float32Array(view.currentUnjitteredViewProjection),\n };\n}\n","export type TaaHistoryResetReason =\n | 'first-frame'\n | 'camera-cut'\n | 'resize'\n | 'recover'\n | 'device-generation';\n\nexport interface TaaHistoryInspection {\n readonly token: number;\n readonly deviceGeneration: number;\n readonly content: 'uninitialized' | 'active';\n readonly fallback: 'neutral-texture';\n readonly requestVersion: number;\n readonly generation: number;\n readonly seed: number;\n readonly attempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly valid: boolean;\n readonly resetReason: TaaHistoryResetReason | undefined;\n}\n\nexport interface TaaHistoryReceipt {\n readonly deviceGeneration: number;\n readonly completed: boolean;\n}\n\nexport interface TaaHistoryAttempt {\n readonly generation: number;\n readonly seed: number;\n commit(receipt?: TaaHistoryReceipt): void;\n abort(): void;\n}\n\nlet nextHistoryToken = 1;\n\n/** TAA-only history owner. No global registry or backend handle crosses this boundary. */\nexport class TaaHistoryStore {\n private readonly token = nextHistoryToken++;\n private deviceGeneration = 0;\n private content: TaaHistoryInspection['content'] = 'uninitialized';\n private requestVersion = 0;\n private generation = 0;\n private seed = 0;\n private valid = false;\n private attempt: TaaHistoryInspection['attempt'] = 'none';\n private resetReason: TaaHistoryResetReason | undefined;\n\n begin(reason: TaaHistoryResetReason | undefined = undefined): TaaHistoryAttempt {\n const generation = this.generation;\n const seed = this.seed;\n this.attempt = 'active';\n let state: 'active' | 'committed' | 'aborted' = 'active';\n return {\n generation,\n seed,\n commit: (receipt) => {\n if (state !== 'active') return;\n if (\n receipt !== undefined &&\n (!receipt.completed || receipt.deviceGeneration !== this.deviceGeneration)\n ) {\n state = 'aborted';\n this.attempt = 'aborted';\n return;\n }\n state = 'committed';\n this.attempt = 'committed';\n this.valid = true;\n this.content = 'active';\n this.requestVersion += 1;\n this.generation += 1;\n this.seed += 1;\n this.resetReason = reason;\n },\n abort: () => {\n if (state !== 'active') return;\n state = 'aborted';\n this.attempt = 'aborted';\n },\n };\n }\n\n seedHistory(reason: TaaHistoryResetReason = 'first-frame'): void {\n this.valid = false;\n this.content = 'uninitialized';\n this.resetReason = reason;\n this.attempt = 'none';\n }\n\n reset(reason: TaaHistoryResetReason): void {\n this.generation = 0;\n this.seed = 0;\n this.valid = false;\n this.content = 'uninitialized';\n this.attempt = 'none';\n this.resetReason = reason;\n }\n\n recoverForGeneration(deviceGeneration: number): void {\n if (!Number.isSafeInteger(deviceGeneration) || deviceGeneration < 0) {\n throw new RangeError('deviceGeneration must be a non-negative safe integer.');\n }\n this.deviceGeneration = deviceGeneration;\n this.valid = false;\n this.content = 'uninitialized';\n this.attempt = 'none';\n this.resetReason = 'device-generation';\n }\n\n inspect(): TaaHistoryInspection {\n return {\n token: this.token,\n deviceGeneration: this.deviceGeneration,\n content: this.content,\n fallback: 'neutral-texture',\n requestVersion: this.requestVersion,\n generation: this.generation,\n seed: this.seed,\n attempt: this.attempt,\n valid: this.valid,\n resetReason: this.resetReason,\n };\n }\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport { motionBlurTemporalDemand } from '../features/motion-blur/motion-blur-params';\nimport type { CameraSnapshot } from '../render-contract';\nimport { classifySceneDataCoverage, type SceneDataContributor } from './coverage';\nimport { type TaaHistoryAttempt, TaaHistoryStore } from './taa-history-store';\nimport {\n projectTemporalView,\n type SubmittedTemporalView,\n snapshotSubmittedTemporalView,\n type TemporalView,\n} from './temporal-view';\n\n/** The only stages that may publish a temporal frame. */\nexport type TemporalFrameStage = 'build' | 'encode' | 'finish' | 'submit';\n\n/** Closed list of consumers that share the renderer temporal transaction. */\nexport type TemporalFrameConsumerId = 'taa' | 'motion-blur' | 'ssr';\n\nexport type TemporalFrameErrorCode = 'taa-unavailable' | 'temporal-active' | 'temporal-not-active';\n\nexport interface TemporalFrameError {\n readonly code: TemporalFrameErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: Readonly<Record<string, unknown>>;\n}\n\nexport interface TemporalFrameSnapshot<T = unknown> {\n readonly epoch: number;\n readonly previous: T | undefined;\n readonly consumerIds: readonly TemporalFrameConsumerId[];\n readonly historyAttempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly attempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly lastFailure: TemporalFrameStage | undefined;\n readonly coverage: {\n readonly exactContributorIds: readonly string[];\n readonly reactiveContributorIds: readonly string[];\n readonly missingContributorIds: readonly string[];\n readonly omittedMissingContributorCount: number;\n };\n}\n\nexport interface TemporalFrameBeginInput<T = unknown> {\n readonly current: T;\n readonly antialias: 'none' | 'fxaa' | 'msaa' | 'taa';\n /** Enables the shared transaction for a temporal feature without TAA. */\n readonly temporalDemand?: boolean;\n /** Consumers registered on this one renderer-owned frame transaction. */\n readonly consumerIds?: readonly TemporalFrameConsumerId[];\n readonly available?: boolean;\n readonly contributors?: readonly SceneDataContributor[];\n readonly requiredContributorIds?: readonly string[];\n /** Projection produced before record uploads; it commits with the frame. */\n readonly temporalView?: TemporalView;\n}\n\nexport interface TemporalFrameCandidate<T = unknown> {\n readonly epoch: number;\n readonly current: T;\n readonly previous: T | undefined;\n readonly history: { readonly direction: 'a-to-b' | 'b-to-a'; readonly valid: boolean };\n readonly contributors: readonly SceneDataContributor[];\n readonly requiredContributorIds: readonly string[];\n readonly consumerIds: readonly TemporalFrameConsumerId[];\n readonly temporalView?: TemporalView;\n}\n\nexport interface TemporalFramePhases<T = unknown> {\n readonly build: () => T;\n readonly encode: (built: T) => void;\n readonly finish: () => void;\n readonly submit: () => void;\n}\n\nexport interface TemporalFrameReceipt<T = unknown> {\n readonly epoch: number;\n readonly previous: T;\n readonly historyDirection: 'a-to-b' | 'b-to-a';\n}\n\nexport type ReflectionFallbackTemporalReset =\n | { readonly reset: false }\n | { readonly reset: true; readonly reason: 'reflection-fallback-generation' };\n\n/** Maps committed producer generations into the existing temporal reset seam. */\nexport function resolveReflectionFallbackTemporalReset(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): ReflectionFallbackTemporalReset {\n if (previousGeneration === undefined || nextGeneration === undefined) return { reset: false };\n return previousGeneration === nextGeneration\n ? { reset: false }\n : { reset: true, reason: 'reflection-fallback-generation' };\n}\n\n/**\n * Keeps SSR admission on the existing producer-generation reset seam. The\n * admission path never allocates or resolves temporal history itself.\n */\nexport function resolveSsrAdmissionTemporalReset(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): ReflectionFallbackTemporalReset {\n return resolveReflectionFallbackTemporalReset(previousGeneration, nextGeneration);\n}\n\nfunction failure(code: TemporalFrameErrorCode, hint: string): TemporalFrameError {\n return {\n code,\n expected:\n code === 'taa-unavailable'\n ? 'TAA resources and capability are available'\n : 'one temporal frame is active',\n hint,\n };\n}\n\n/**\n * Renderer-owned temporal transaction. It has no graph or backend dependency:\n * graph assembly supplies the four phase callbacks and only submit publishes\n * the candidate snapshot.\n */\nexport class TemporalFrameCoordinator<T = unknown> {\n readonly historyStore: TaaHistoryStore;\n private epoch: number;\n private previous: T | undefined;\n private consumerIds: readonly TemporalFrameConsumerId[] = [];\n private active: TemporalFrameCandidate<T> | undefined;\n private attempt: TemporalFrameSnapshot<T>['attempt'] = 'none';\n private historyAttempt: TemporalFrameSnapshot<T>['historyAttempt'] = 'none';\n private lastFailure: TemporalFrameStage | undefined;\n private historyDirection: 'a-to-b' | 'b-to-a' = 'a-to-b';\n private temporalFrameIndex = 0;\n private lastSubmittedView: SubmittedTemporalView | undefined;\n private coverage: TemporalFrameSnapshot<T>['coverage'] = {\n exactContributorIds: [],\n reactiveContributorIds: [],\n missingContributorIds: [],\n omittedMissingContributorCount: 0,\n };\n private readonly historyAttempts = new WeakMap<object, TaaHistoryAttempt>();\n\n constructor(\n initial: {\n readonly epoch?: number;\n readonly previous?: T;\n readonly historyStore?: TaaHistoryStore;\n } = {},\n ) {\n this.historyStore = initial.historyStore ?? new TaaHistoryStore();\n this.epoch = initial.epoch ?? 0;\n this.previous = initial.previous;\n }\n\n begin(input: TemporalFrameBeginInput<T>): Result<TemporalFrameCandidate<T>, TemporalFrameError> {\n const consumerIds = Object.freeze([...(input.consumerIds ?? [])]);\n const demanded =\n input.antialias === 'taa' || input.temporalDemand === true || consumerIds.length > 0;\n if (!demanded) {\n return ok({\n epoch: this.epoch,\n current: input.current,\n previous: this.previous,\n history: { direction: this.historyDirection, valid: false },\n contributors: Object.freeze([...(input.contributors ?? [])]),\n requiredContributorIds: Object.freeze([...(input.requiredContributorIds ?? [])]),\n consumerIds,\n ...(input.temporalView === undefined ? {} : { temporalView: input.temporalView }),\n });\n }\n if (input.available === false) {\n return err(\n failure('taa-unavailable', 'enable rgba16float temporal targets and retry the frame'),\n );\n }\n if (this.active !== undefined) {\n return err(\n failure(\n 'temporal-active',\n 'commit or abort the active temporal frame before beginning another',\n ),\n );\n }\n const candidate: TemporalFrameCandidate<T> = {\n epoch: this.epoch + 1,\n current: input.current,\n previous: this.previous,\n history: { direction: this.historyDirection, valid: this.previous !== undefined },\n contributors: Object.freeze([...(input.contributors ?? [])]),\n requiredContributorIds: Object.freeze([...(input.requiredContributorIds ?? [])]),\n consumerIds,\n ...(input.temporalView === undefined ? {} : { temporalView: input.temporalView }),\n };\n if (input.antialias === 'taa') {\n this.historyAttempts.set(candidate, this.historyStore.begin());\n }\n this.active = candidate;\n this.attempt = 'active';\n this.historyAttempt = input.antialias === 'taa' ? 'active' : 'none';\n this.lastFailure = undefined;\n return ok(candidate);\n }\n\n commit(\n candidate: TemporalFrameCandidate<T>,\n ): Result<TemporalFrameReceipt<T>, TemporalFrameError> {\n if (this.active !== candidate) {\n return err(failure('temporal-not-active', 'commit the candidate returned by begin'));\n }\n this.epoch = candidate.epoch;\n this.previous = candidate.current;\n if (candidate.temporalView !== undefined) {\n this.lastSubmittedView = snapshotSubmittedTemporalView(candidate.temporalView);\n this.temporalFrameIndex += 1;\n }\n this.historyDirection = candidate.history.direction === 'a-to-b' ? 'b-to-a' : 'a-to-b';\n this.consumerIds = candidate.consumerIds;\n const historyAttempt = this.historyAttempts.get(candidate);\n historyAttempt?.commit({\n deviceGeneration: this.historyStore.inspect().deviceGeneration,\n completed: true,\n });\n this.coverage = classifySceneDataCoverage({\n contributors: candidate.contributors,\n requiredContributorIds: candidate.requiredContributorIds,\n });\n this.active = undefined;\n historyAttempt?.abort();\n this.historyAttempts.delete(candidate);\n this.attempt = 'committed';\n this.historyAttempt = historyAttempt === undefined ? 'none' : 'committed';\n return ok({\n epoch: this.epoch,\n previous: candidate.current,\n historyDirection: candidate.history.direction,\n });\n }\n\n abort(candidate: TemporalFrameCandidate<T>, stage: TemporalFrameStage = 'submit'): void {\n if (this.active !== candidate) return;\n this.historyAttempts.get(candidate)?.abort();\n this.historyAttempts.delete(candidate);\n this.active = undefined;\n this.attempt = 'aborted';\n this.historyAttempt = 'aborted';\n this.lastFailure = stage;\n }\n\n run(\n input: TemporalFrameBeginInput<T>,\n phases: TemporalFramePhases<T>,\n ): Result<TemporalFrameReceipt<T> | undefined, TemporalFrameError> {\n const started = this.begin(input);\n if (!started.ok) return started;\n const candidate = started.value;\n if (\n input.antialias !== 'taa' &&\n input.temporalDemand !== true &&\n (input.consumerIds?.length ?? 0) === 0\n ) {\n return ok(undefined);\n }\n try {\n const built = phases.build();\n phases.encode(built);\n phases.finish();\n phases.submit();\n } catch (cause) {\n const stage = this.stageFromError(cause);\n this.abort(candidate, stage);\n return err({\n code: 'temporal-not-active',\n expected: `temporal ${stage} succeeds before commit`,\n hint: 'inspect the underlying stage failure and retry the frame',\n detail: { stage, cause },\n });\n }\n return this.commit(candidate);\n }\n\n inspect(): TemporalFrameSnapshot<T> {\n return {\n epoch: this.epoch,\n previous: this.previous,\n consumerIds: this.consumerIds,\n historyAttempt: this.historyAttempt,\n attempt: this.attempt,\n lastFailure: this.lastFailure,\n coverage: this.coverage,\n };\n }\n\n /**\n * Derive the current/previous camera matrices without mutating history.\n * `commit()` is the only operation that publishes the returned view, so a\n * graph/finish/submit failure leaves the last successful view intact.\n */\n prepareTemporalView(\n camera: CameraSnapshot,\n surfaceWidth: number,\n surfaceHeight: number,\n ): TemporalView | undefined {\n const demanded =\n camera.antialias === 'taa' ||\n (camera.motionBlur !== undefined &&\n motionBlurTemporalDemand({\n shutterAngle: camera.motionBlur.shutterAngle,\n maxRadiusPixels: camera.motionBlur.maxRadiusPixels,\n sampleCount: camera.motionBlur.sampleCount,\n targetFps: camera.motionBlur.targetFps ?? 60,\n }));\n if (!demanded) return undefined;\n return projectTemporalView({\n camera,\n temporalFrameIndex: this.temporalFrameIndex,\n surfaceWidth,\n surfaceHeight,\n ...(this.lastSubmittedView === undefined ? {} : { lastSubmitted: this.lastSubmittedView }),\n });\n }\n\n reset(\n reason:\n | 'cut'\n | 'resize'\n | 'camera-switch'\n | 'detach'\n | 'recover'\n | 'device-loss'\n | 'device-generation' = 'recover',\n ): void {\n void reason;\n this.active = undefined;\n this.epoch = 0;\n this.previous = undefined;\n this.temporalFrameIndex = 0;\n this.lastSubmittedView = undefined;\n this.historyDirection = 'a-to-b';\n this.historyStore.reset(\n reason === 'cut' || reason === 'camera-switch'\n ? 'camera-cut'\n : reason === 'resize'\n ? 'resize'\n : reason === 'device-generation' || reason === 'device-loss'\n ? 'device-generation'\n : 'recover',\n );\n this.attempt = 'none';\n this.historyAttempt = 'none';\n this.lastFailure = undefined;\n this.coverage = {\n exactContributorIds: [],\n reactiveContributorIds: [],\n missingContributorIds: [],\n omittedMissingContributorCount: 0,\n };\n this.consumerIds = [];\n }\n\n private stageFromError(cause: unknown): TemporalFrameStage {\n if (typeof cause === 'object' && cause !== null && 'stage' in cause) {\n const stage = (cause as { stage?: unknown }).stage;\n if (stage === 'build' || stage === 'encode' || stage === 'finish' || stage === 'submit')\n return stage;\n }\n return 'submit';\n }\n}\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { RenderFeaturePreparedStateMismatchError, SceneDataUnavailableError } from './chunk-
|
|
2
|
-
import { err, ok } from '@forgeax/engine-types';
|
|
1
|
+
import { RenderFeaturePreparedStateMismatchError, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT, GPU_TEXTURE_USAGE_TEXTURE_BINDING, GPU_TEXTURE_USAGE_COPY_SRC, SceneDataUnavailableError } from './chunk-2OZAS3WU.mjs';
|
|
2
|
+
import { derive, err, ok } from '@forgeax/engine-types';
|
|
3
|
+
import { ok as ok$1, err as err$1, RhiError } from '@forgeax/engine-rhi';
|
|
4
|
+
import { DEFAULT_STANDARD_PBR_PARAM_SCHEMA } from '@forgeax/engine-shader';
|
|
3
5
|
|
|
4
6
|
// src/pipeline/standard-lighting/layout.ts
|
|
5
7
|
var DEFAULT_CLUSTER_GRID = { x: 16, y: 9, z: 24 };
|
|
@@ -290,7 +292,117 @@ function createSceneDataCatalog(options) {
|
|
|
290
292
|
}
|
|
291
293
|
};
|
|
292
294
|
}
|
|
295
|
+
var STANDARD_PBR_UBO_SIZE = derive(DEFAULT_STANDARD_PBR_PARAM_SCHEMA).uboLayout.totalBytes;
|
|
296
|
+
var MATERIAL_PER_ENTITY_STRIDE = Math.ceil(STANDARD_PBR_UBO_SIZE / 256) * 256;
|
|
297
|
+
function resolveSurfaceProfile(storageFormat, viewFormat, facts) {
|
|
298
|
+
if (facts.surfaceViewFormats) {
|
|
299
|
+
return ok$1({
|
|
300
|
+
kind: "dual-view",
|
|
301
|
+
storageFormat,
|
|
302
|
+
viewFormat,
|
|
303
|
+
viewFormats: [viewFormat],
|
|
304
|
+
hasDisplayEndpoint: true
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
if (!facts.rawAttachment || !facts.floatRenderAttachment) {
|
|
308
|
+
return err$1(
|
|
309
|
+
new RhiError({
|
|
310
|
+
code: "webgpu-runtime-error",
|
|
311
|
+
expected: "raw surface attachment and rgba16float render attachment capabilities",
|
|
312
|
+
hint: "surface profile cannot establish a raw-only linear output route",
|
|
313
|
+
detail: {
|
|
314
|
+
error: {
|
|
315
|
+
code: "surface-raw-endpoint-failed",
|
|
316
|
+
message: "raw-only surface capabilities are incomplete"
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
return ok$1({
|
|
323
|
+
kind: "raw-only",
|
|
324
|
+
storageFormat,
|
|
325
|
+
viewFormat: storageFormat,
|
|
326
|
+
viewFormats: [],
|
|
327
|
+
hasDisplayEndpoint: false
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
function resolveSurfaceFormatPair(_backendKind, storage, view) {
|
|
331
|
+
return { storage, view };
|
|
332
|
+
}
|
|
333
|
+
function surfaceCapabilityFacts(device, storageFormat) {
|
|
334
|
+
const internal = device;
|
|
335
|
+
return {
|
|
336
|
+
surfaceViewFormats: internal.surfaceViewFormats ?? device.caps?.backendKind !== "wgpu-webgl2",
|
|
337
|
+
rawAttachment: storageFormat === "rgba8unorm" || storageFormat === "bgra8unorm",
|
|
338
|
+
floatRenderAttachment: device.caps?.rgba16floatRenderable ?? true
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function configureSurface(context, device, format, colorAttachmentFormat) {
|
|
342
|
+
const backendKind = device.caps?.backendKind ?? "webgpu";
|
|
343
|
+
const isWebGl2 = backendKind === "wgpu-webgl2";
|
|
344
|
+
const surfaceFormats = resolveSurfaceFormatPair(
|
|
345
|
+
backendKind,
|
|
346
|
+
format,
|
|
347
|
+
colorAttachmentFormat
|
|
348
|
+
);
|
|
349
|
+
const profile = resolveSurfaceProfile(
|
|
350
|
+
surfaceFormats.storage,
|
|
351
|
+
surfaceFormats.view,
|
|
352
|
+
surfaceCapabilityFacts(device, surfaceFormats.storage)
|
|
353
|
+
);
|
|
354
|
+
if (!profile.ok) return profile;
|
|
355
|
+
const supportsTextureBinding = backendKind !== "wgpu-webgl2" && (device.caps?.storageBuffer ?? true);
|
|
356
|
+
const configured = context.configure({
|
|
357
|
+
device,
|
|
358
|
+
format: surfaceFormats.storage,
|
|
359
|
+
alphaMode: isWebGl2 ? "opaque" : "premultiplied",
|
|
360
|
+
usage: GPU_TEXTURE_USAGE_RENDER_ATTACHMENT | (supportsTextureBinding ? GPU_TEXTURE_USAGE_TEXTURE_BINDING : 0) | (isWebGl2 ? 0 : GPU_TEXTURE_USAGE_COPY_SRC),
|
|
361
|
+
viewFormats: [...profile.value.viewFormats]
|
|
362
|
+
});
|
|
363
|
+
if (!configured.ok) return configured;
|
|
364
|
+
if (isWebGl2 && (context.presentationProof === void 0 || !context.presentationProof.descriptor || !context.presentationProof.acquisition || !context.presentationProof.validation || typeof context.presentationProof.surfaceIdentity !== "string" || context.presentationProof.surfaceIdentity.length === 0 || context.presentationProof.requested === void 0 || context.presentationProof.validated === void 0 || JSON.stringify(context.presentationProof.requested) !== JSON.stringify(context.presentationProof.validated))) {
|
|
365
|
+
return err$1(
|
|
366
|
+
new RhiError({
|
|
367
|
+
code: "webgpu-runtime-error",
|
|
368
|
+
expected: "WebGL2 surface storage has descriptor, acquisition, and validation proof",
|
|
369
|
+
hint: "run the concrete presentation probe and retain the last-known-good graph when proof is absent",
|
|
370
|
+
detail: {
|
|
371
|
+
error: {
|
|
372
|
+
code: "surface-raw-endpoint-failed",
|
|
373
|
+
message: "surface storage raw endpoint proof is incomplete"
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
})
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
return ok$1(void 0);
|
|
380
|
+
}
|
|
381
|
+
function selectSwapChainFormat(storageBufferCapable, surfaceViewFormats = true) {
|
|
382
|
+
if (!storageBufferCapable) {
|
|
383
|
+
return {
|
|
384
|
+
storage: "rgba8unorm",
|
|
385
|
+
view: surfaceViewFormats ? "rgba8unorm-srgb" : "rgba8unorm"
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
const nav = globalThis.navigator;
|
|
389
|
+
const gpu = nav?.gpu;
|
|
390
|
+
const getPreferred = gpu?.getPreferredCanvasFormat;
|
|
391
|
+
if (gpu !== void 0 && typeof getPreferred === "function") {
|
|
392
|
+
const storage = getPreferred.call(gpu);
|
|
393
|
+
const view = storage === "rgba8unorm" ? "rgba8unorm-srgb" : storage === "bgra8unorm" ? "bgra8unorm-srgb" : storage;
|
|
394
|
+
return {
|
|
395
|
+
storage,
|
|
396
|
+
view: surfaceViewFormats ? view : storage
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
storage: "rgba8unorm",
|
|
401
|
+
view: surfaceViewFormats ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
402
|
+
fallbackReason: "preferred-canvas-format-missing"
|
|
403
|
+
};
|
|
404
|
+
}
|
|
293
405
|
|
|
294
|
-
export { CLUSTER_GRID_STRIDE_U32, DEFAULT_CLUSTER_GRID, DEFAULT_STANDARD_PROFILE, LIGHT_INDEX_LIST_CAPACITY, MAX_LIGHTS, REFLECTION_PROBE_IBL_STAGES, SCENE_DATA_TEMPORAL_V1_DESCRIPTOR, SCENE_DATA_TEMPORAL_V1_SCHEMA, STANDARD_LIGHT_COUNTS, STANDARD_PIPELINE_ID, STANDARD_POST_STAGE_NAMES, beginProbeIblUpdate, createIblKernelCache, createProbeIblOutput, createSceneDataCatalog, createStandardClusterLayout, isSceneDataTarget, publishProbeIblOutput, registerSceneDataTarget, resetIblKernelCaches, resolveVolumetricFogProfile, sceneDataError, sceneDataTargetAsAttachment, sceneDataTargetOwner, sceneDataTokenMismatch };
|
|
295
|
-
//# sourceMappingURL=chunk-
|
|
296
|
-
//# sourceMappingURL=chunk-
|
|
406
|
+
export { CLUSTER_GRID_STRIDE_U32, DEFAULT_CLUSTER_GRID, DEFAULT_STANDARD_PROFILE, LIGHT_INDEX_LIST_CAPACITY, MATERIAL_PER_ENTITY_STRIDE, MAX_LIGHTS, REFLECTION_PROBE_IBL_STAGES, SCENE_DATA_TEMPORAL_V1_DESCRIPTOR, SCENE_DATA_TEMPORAL_V1_SCHEMA, STANDARD_LIGHT_COUNTS, STANDARD_PBR_UBO_SIZE, STANDARD_PIPELINE_ID, STANDARD_POST_STAGE_NAMES, beginProbeIblUpdate, configureSurface, createIblKernelCache, createProbeIblOutput, createSceneDataCatalog, createStandardClusterLayout, isSceneDataTarget, publishProbeIblOutput, registerSceneDataTarget, resetIblKernelCaches, resolveSurfaceFormatPair, resolveSurfaceProfile, resolveVolumetricFogProfile, sceneDataError, sceneDataTargetAsAttachment, sceneDataTargetOwner, sceneDataTokenMismatch, selectSwapChainFormat };
|
|
407
|
+
//# sourceMappingURL=chunk-OB5WAFYH.mjs.map
|
|
408
|
+
//# sourceMappingURL=chunk-OB5WAFYH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pipeline/standard-lighting/layout.ts","../src/pipeline/standard-profile.ts","../src/ibl/kernel-cache.ts","../src/temporal/scene-data.ts","../src/temporal/scene-data-catalog.ts","../src/record/render-context.ts"],"names":["ok","err"],"mappings":"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","file":"chunk-OB5WAFYH.mjs","sourcesContent":["export const DEFAULT_CLUSTER_GRID = { x: 16, y: 9, z: 24 } as const;\nexport const CLUSTER_GRID_STRIDE_U32 = 2 as const;\nexport const LIGHT_INDEX_LIST_CAPACITY = 1048576 as const;\nexport const MAX_LIGHTS = 256 as const;\n\nexport interface StandardClusterLayout {\n readonly grid: { readonly x: number; readonly y: number; readonly z: number };\n readonly clusterCount: number;\n readonly clusterGridStrideU32: typeof CLUSTER_GRID_STRIDE_U32;\n readonly clusterGridU32Length: number;\n readonly lightIndexListCapacity: typeof LIGHT_INDEX_LIST_CAPACITY;\n readonly lightDataSlotCount: typeof MAX_LIGHTS;\n readonly lightBoundsInt32Length: number;\n}\n\nexport function createStandardClusterLayout(\n grid: { readonly x: number; readonly y: number; readonly z: number } = DEFAULT_CLUSTER_GRID,\n): StandardClusterLayout {\n const clusterCount = grid.x * grid.y * grid.z;\n return Object.freeze({\n grid,\n clusterCount,\n clusterGridStrideU32: CLUSTER_GRID_STRIDE_U32,\n clusterGridU32Length: clusterCount * CLUSTER_GRID_STRIDE_U32,\n lightIndexListCapacity: LIGHT_INDEX_LIST_CAPACITY,\n lightDataSlotCount: MAX_LIGHTS,\n lightBoundsInt32Length: MAX_LIGHTS * 6,\n });\n}\n\nexport const STANDARD_CLUSTER_LAYOUT = createStandardClusterLayout();\n","import type { SsaoParameterConfig } from '../ssao-config';\nexport const STANDARD_PIPELINE_ID = 'forgeax::standard' as const;\nexport const STANDARD_LIGHT_COUNTS = [1, 32, 256] as const;\nexport {\n CLUSTER_GRID_STRIDE_U32,\n DEFAULT_CLUSTER_GRID,\n LIGHT_INDEX_LIST_CAPACITY,\n MAX_LIGHTS,\n} from './standard-lighting/layout';\n\nexport type StandardLightCount = (typeof STANDARD_LIGHT_COUNTS)[number];\nexport type StandardShadowMode = 'off' | 'hard' | 'filtered';\nexport type StandardVolumetricFogQuality = 'low' | 'high';\n\nexport interface StandardVolumetricFogProfile {\n readonly quality: StandardVolumetricFogQuality;\n readonly depth: 48 | 64;\n readonly tileSize: 4 | 16;\n}\n\nexport const STANDARD_POST_STAGE_NAMES = [\n 'transparent-blend',\n 'bloom',\n 'output-transform',\n 'fxaa',\n 'post-effect',\n 'present',\n] as const;\nexport type StandardPostStage = (typeof STANDARD_POST_STAGE_NAMES)[number];\nexport interface StandardProfile {\n readonly pipelineId: typeof STANDARD_PIPELINE_ID;\n readonly lightCount: StandardLightCount;\n /** Graph topology selector; all local lights use the shared Cluster path. */\n readonly renderPath: 'forward' | 'deferred';\n readonly shadows: StandardShadowMode;\n readonly pbr: boolean;\n readonly ibl: boolean;\n readonly ssao: boolean | SsaoParameterConfig;\n /** Renderer-owned 1080p volume profile; tile width/height remain surface-derived. */\n readonly volumetricFog?: StandardVolumetricFogProfile | undefined;\n readonly postStages: typeof STANDARD_POST_STAGE_NAMES;\n}\n\nexport const DEFAULT_STANDARD_PROFILE: StandardProfile = Object.freeze({\n pipelineId: STANDARD_PIPELINE_ID,\n lightCount: 32,\n renderPath: 'forward',\n shadows: 'filtered',\n pbr: true,\n ibl: true,\n ssao: false,\n postStages: STANDARD_POST_STAGE_NAMES,\n});\n\nexport function resolveVolumetricFogProfile(\n profile: Pick<StandardProfile, 'volumetricFog'>,\n): StandardVolumetricFogProfile {\n return profile.volumetricFog ?? { quality: 'high', depth: 64, tileSize: 4 };\n}\n","export const REFLECTION_PROBE_IBL_STAGES = ['raw', 'filtered', 'publish'] as const;\nexport type ReflectionProbeIblStage = (typeof REFLECTION_PROBE_IBL_STAGES)[number];\n\nexport interface IblKernelCache {\n readonly generation: number;\n readonly pipelineIdentity: object;\n readonly samplerIdentity: object;\n readonly brdfLutIdentity: object;\n}\n\nconst kernelCaches = new Map<number, IblKernelCache>();\n\nexport function createIblKernelCache(generation: number): IblKernelCache {\n const existing = kernelCaches.get(generation);\n if (existing !== undefined) return existing;\n const created: IblKernelCache = {\n generation,\n pipelineIdentity: {},\n samplerIdentity: {},\n brdfLutIdentity: {},\n };\n kernelCaches.set(generation, created);\n return created;\n}\n\nexport interface ProbeIblOutput {\n readonly entityKey: number;\n readonly resolution: number;\n readonly deviceGeneration: number;\n readonly raw: object;\n readonly filtered: object;\n readonly rawGeneration: number;\n readonly filteredGeneration: number;\n readonly lkg: boolean;\n}\n\nexport interface ProbeIblUpdate extends ProbeIblOutput {\n readonly stages: typeof REFLECTION_PROBE_IBL_STAGES;\n readonly nextStage: ReflectionProbeIblStage;\n readonly candidateGeneration: number;\n}\n\nexport function createProbeIblOutput(input: {\n readonly entityKey: number;\n readonly resolution: number;\n readonly deviceGeneration: number;\n}): ProbeIblOutput {\n return {\n ...input,\n raw: {},\n filtered: {},\n rawGeneration: 0,\n filteredGeneration: 0,\n lkg: true,\n };\n}\n\nexport function beginProbeIblUpdate(output: ProbeIblOutput): ProbeIblUpdate {\n return {\n ...output,\n stages: REFLECTION_PROBE_IBL_STAGES,\n nextStage: 'raw',\n candidateGeneration: output.filteredGeneration + 1,\n };\n}\n\nexport function publishProbeIblOutput(\n update: ProbeIblUpdate,\n result: { readonly stage: ReflectionProbeIblStage; readonly ok: boolean },\n): ProbeIblOutput {\n if (!result.ok || result.stage !== update.nextStage) return update;\n if (result.stage === 'raw') {\n return {\n ...update,\n rawGeneration: update.candidateGeneration,\n };\n }\n if (result.stage === 'filtered') return update;\n return {\n ...update,\n filteredGeneration: update.candidateGeneration,\n lkg: true,\n };\n}\n\nexport function resetIblKernelCaches(): void {\n kernelCaches.clear();\n}\n","import { type RenderError, RenderFeaturePreparedStateMismatchError } from '../errors/render';\nimport type { RenderFeatureTargetHandle } from '../features/targets';\n\n/** The closed semantic schema namespace published by the render owner. */\nexport const SCENE_DATA_TEMPORAL_V1_SCHEMA = 'forgeax::scene-data::temporal-v1' as const;\nexport type SceneDataSchemaId = typeof SCENE_DATA_TEMPORAL_V1_SCHEMA;\n\nexport type SceneDataLane = 'direct' | 'clustered' | 'cpu-webgl2';\n\nexport interface SceneDataTemporalV1Descriptor {\n readonly schema: typeof SCENE_DATA_TEMPORAL_V1_SCHEMA;\n readonly format: 'rgba16float';\n readonly sampleCount: 1;\n readonly extent: 'render-resolution';\n readonly clearValue: readonly [0, 0, -1, 1];\n readonly channels: Readonly<{\n readonly motionUv: 'rg';\n readonly viewDepth: 'b-log2-1-plus-depth';\n readonly reactive: 'a';\n }>;\n}\n\nexport const SCENE_DATA_TEMPORAL_V1_DESCRIPTOR: SceneDataTemporalV1Descriptor = Object.freeze({\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n format: 'rgba16float',\n sampleCount: 1,\n extent: 'render-resolution',\n clearValue: [0, 0, -1, 1] as const,\n channels: Object.freeze({\n motionUv: 'rg',\n viewDepth: 'b-log2-1-plus-depth',\n reactive: 'a',\n }),\n});\n\n/** Opaque, sampled-read-only semantic data token. */\nexport interface SceneDataTarget<Schema extends SceneDataSchemaId = SceneDataSchemaId> {\n readonly kind: 'scene-data';\n readonly schema: Schema;\n readonly access: 'sampled-read';\n readonly format: 'rgba16float';\n readonly sampleCount: 1;\n readonly extent: 'render-resolution';\n readonly __sceneDataTarget: unique symbol;\n}\n\nexport type SceneDataTokenMismatch = RenderFeaturePreparedStateMismatchError;\n\nconst targetOwners = new WeakMap<object, SceneDataCatalogIdentity>();\n\nexport interface SceneDataCatalogIdentity {\n readonly featureIdentity: string;\n readonly planIdentity: string;\n readonly generation: number;\n}\n\nexport function registerSceneDataTarget(\n target: SceneDataTarget,\n owner: SceneDataCatalogIdentity,\n): void {\n targetOwners.set(target, owner);\n}\n\nexport function sceneDataTargetOwner(\n target: SceneDataTarget,\n): SceneDataCatalogIdentity | undefined {\n return typeof target === 'object' && target !== null ? targetOwners.get(target) : undefined;\n}\n\nexport function sceneDataTokenMismatch(\n operation: string,\n reason: 'foreign-feature' | 'foreign-kind' | 'generation-mismatch' | 'layout-mismatch',\n owner: SceneDataCatalogIdentity,\n target: Partial<SceneDataTarget> | undefined,\n): SceneDataTokenMismatch {\n const detail =\n reason === 'generation-mismatch'\n ? {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedGeneration: owner.generation,\n actualGeneration: targetOwners.get(target as object)?.generation ?? -1,\n recovery: 'renderer-recover' as const,\n }\n : reason === 'foreign-feature'\n ? {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedFeatureIdentity: owner.featureIdentity,\n actualFeatureIdentity: targetOwners.get(target as object)?.featureIdentity ?? 'unknown',\n recovery: 'next-frame' as const,\n }\n : reason === 'foreign-kind'\n ? {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedKind: 'attachment' as const,\n actualKind: 'pipeline' as const,\n recovery: 'next-frame' as const,\n }\n : {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedLayout: 'sampled-read-temporal-v1',\n actualLayout: target?.access ?? 'unknown',\n recovery: 'next-frame' as const,\n };\n return new RenderFeaturePreparedStateMismatchError(detail);\n}\n\nexport function isSceneDataTarget(value: unknown): value is SceneDataTarget {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as Partial<SceneDataTarget>;\n return (\n candidate.kind === 'scene-data' &&\n candidate.schema === SCENE_DATA_TEMPORAL_V1_SCHEMA &&\n candidate.access === 'sampled-read' &&\n candidate.format === 'rgba16float' &&\n candidate.sampleCount === 1 &&\n candidate.extent === 'render-resolution' &&\n targetOwners.has(value)\n );\n}\n\nexport function sceneDataTargetAsAttachment(_target: SceneDataTarget): never {\n throw new TypeError('SceneDataTarget is sampled-read-only and cannot be used as an attachment');\n}\n\nexport type SceneDataTargetInput = RenderFeatureTargetHandle | SceneDataTarget;\n\nexport function sceneDataError(error: SceneDataTokenMismatch): RenderError {\n return error;\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport type { RenderError } from '../errors/render';\nimport { SceneDataUnavailableError } from '../errors/render';\nimport {\n registerSceneDataTarget,\n SCENE_DATA_TEMPORAL_V1_DESCRIPTOR,\n SCENE_DATA_TEMPORAL_V1_SCHEMA,\n type SceneDataLane,\n type SceneDataSchemaId,\n type SceneDataTarget,\n sceneDataTargetOwner,\n sceneDataTokenMismatch,\n} from './scene-data';\n\nexport type SceneDataAvailability =\n | {\n readonly status: 'available';\n readonly completeness: 'exact' | 'exact-with-reactive-fallback';\n }\n | {\n readonly status: 'unavailable';\n readonly reason:\n | 'capability-missing'\n | 'producer-missing'\n | 'coverage-incomplete'\n | 'renderer-recovering';\n };\n\nexport interface SceneDataInspection {\n readonly schema: SceneDataSchemaId;\n readonly status: SceneDataAvailability['status'];\n readonly generation: number;\n readonly planIdentity: string;\n readonly lane: SceneDataLane;\n readonly completeness?: 'exact' | 'exact-with-reactive-fallback';\n readonly reason?: Exclude<SceneDataAvailability, { status: 'available' }>['reason'];\n readonly missingContributorIds: readonly string[];\n readonly omittedMissingContributorCount: number;\n}\n\nexport interface SceneDataCatalogOptions {\n readonly featureIdentity: string;\n readonly generation: number;\n readonly planIdentity: string;\n readonly lane?: SceneDataLane;\n readonly rgba16floatRenderable: boolean;\n readonly producerPresent?: boolean;\n readonly coverageComplete?: boolean;\n readonly recovering?: boolean;\n readonly reactiveFallback?: boolean;\n readonly missingContributorIds?: readonly string[];\n}\n\nexport interface SceneDataCatalog {\n readonly schema: typeof SCENE_DATA_TEMPORAL_V1_SCHEMA;\n readonly generation: number;\n readonly planIdentity: string;\n readonly availability: SceneDataAvailability;\n require<Schema extends SceneDataSchemaId>(schema: Schema): SceneDataTarget<Schema>;\n validate(target: SceneDataTarget, generation?: number): Result<SceneDataTarget, RenderError>;\n inspect(): SceneDataInspection;\n}\n\nfunction availability(options: SceneDataCatalogOptions): SceneDataAvailability {\n if (options.recovering) return { status: 'unavailable', reason: 'renderer-recovering' };\n if (!options.rgba16floatRenderable)\n return { status: 'unavailable', reason: 'capability-missing' };\n if (options.producerPresent === false)\n return { status: 'unavailable', reason: 'producer-missing' };\n if (options.coverageComplete === false)\n return { status: 'unavailable', reason: 'coverage-incomplete' };\n return {\n status: 'available',\n completeness: options.reactiveFallback ? 'exact-with-reactive-fallback' : 'exact',\n };\n}\n\nfunction createTarget(owner: SceneDataCatalogOptions): SceneDataTarget {\n const target = Object.freeze({\n kind: 'scene-data' as const,\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n access: 'sampled-read' as const,\n format: 'rgba16float' as const,\n sampleCount: 1 as const,\n extent: 'render-resolution' as const,\n }) as SceneDataTarget;\n registerSceneDataTarget(target, {\n featureIdentity: owner.featureIdentity,\n planIdentity: owner.planIdentity,\n generation: owner.generation,\n });\n return target;\n}\n\nfunction tokenError(catalog: SceneDataCatalogOptions, operation: string): RenderError {\n return sceneDataTokenMismatch(\n operation,\n 'foreign-kind',\n {\n featureIdentity: catalog.featureIdentity,\n planIdentity: catalog.planIdentity,\n generation: catalog.generation,\n },\n undefined,\n );\n}\n\nfunction unavailableError(\n options: SceneDataCatalogOptions,\n reason: Exclude<SceneDataAvailability, { status: 'available' }>['reason'],\n): RenderError {\n const recovery =\n reason === 'capability-missing'\n ? 'enable-capability'\n : reason === 'renderer-recovering'\n ? 'renderer-recover'\n : 'next-frame';\n return new SceneDataUnavailableError({\n featureIdentity: options.featureIdentity,\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n lane: options.lane ?? 'direct',\n reason,\n missingContributorIds: options.missingContributorIds ?? [],\n omittedMissingContributorCount: 0,\n recovery,\n });\n}\n\nexport function createSceneDataCatalog(options: SceneDataCatalogOptions): SceneDataCatalog {\n const state = availability(options);\n const owner = {\n featureIdentity: options.featureIdentity,\n planIdentity: options.planIdentity,\n generation: options.generation,\n };\n const missing = [...(options.missingContributorIds ?? [])];\n const inspectionBase = {\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n generation: options.generation,\n planIdentity: options.planIdentity,\n lane: options.lane ?? 'direct',\n missingContributorIds: Object.freeze(missing.slice(0, 32)),\n omittedMissingContributorCount: Math.max(0, missing.length - 32),\n };\n return {\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n generation: options.generation,\n planIdentity: options.planIdentity,\n availability: state,\n require(schema) {\n if (schema !== SCENE_DATA_TEMPORAL_V1_SCHEMA || state.status !== 'available') {\n if (state.status === 'unavailable') throw unavailableError(options, state.reason);\n throw tokenError(options, 'require scene-data target');\n }\n return createTarget(options) as SceneDataTarget<typeof schema>;\n },\n validate(target, generation = options.generation) {\n const targetOwner = sceneDataTargetOwner(target);\n if (targetOwner === undefined) {\n return err(\n sceneDataTokenMismatch('validate scene-data target', 'foreign-feature', owner, target),\n );\n }\n if (\n targetOwner.planIdentity !== owner.planIdentity ||\n targetOwner.featureIdentity !== owner.featureIdentity\n ) {\n return err(\n sceneDataTokenMismatch('validate scene-data target', 'foreign-feature', owner, target),\n );\n }\n if (generation !== owner.generation || targetOwner.generation !== owner.generation) {\n return err(\n sceneDataTokenMismatch(\n 'validate scene-data target',\n 'generation-mismatch',\n owner,\n target,\n ),\n );\n }\n if (target.access !== 'sampled-read') {\n return err(\n sceneDataTokenMismatch('validate scene-data target', 'layout-mismatch', owner, target),\n );\n }\n return ok(target);\n },\n inspect() {\n return Object.freeze(\n state.status === 'available'\n ? { ...inspectionBase, status: state.status, completeness: state.completeness }\n : { ...inspectionBase, status: state.status, reason: state.reason },\n );\n },\n };\n}\n\nexport { SCENE_DATA_TEMPORAL_V1_SCHEMA } from './scene-data';\nexport { SCENE_DATA_TEMPORAL_V1_DESCRIPTOR };\n","import type { AssetRegistry, DynamicTextureStore } from '@forgeax/engine-assets-runtime';\nimport type { VertexLayoutProjection } from '@forgeax/engine-geometry';\nimport type { Profiler } from '@forgeax/engine-profiler';\nimport type { CompiledRenderGraphInfo } from '@forgeax/engine-render-graph';\nimport type {\n BindGroup,\n BindGroupLayout,\n Buffer,\n ComputePipeline,\n PipelineLayout,\n Result,\n RhiCanvasContext,\n RhiCommandEncoder,\n RhiDevice,\n RenderPipeline as RhiRenderPipeline,\n Sampler,\n ShaderModule,\n Texture,\n TextureFormat,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport { err, ok, RhiError } from '@forgeax/engine-rhi';\nimport {\n DEFAULT_STANDARD_PBR_PARAM_SCHEMA,\n type MaterialRuntimeArtifact,\n type MaterialShaderArtifact,\n} from '@forgeax/engine-shader';\nimport type {\n MaterialAsset,\n MaterialRenderState,\n ParamSchemaEntry,\n PassKind,\n PrimitiveTopology,\n VertexAttributeMap,\n} from '@forgeax/engine-types';\nimport { derive } from '@forgeax/engine-types';\nimport type { MaterialRenderProjection } from '../assembly/material/assembly';\nimport type { DeviceScope } from '../device/device-scope';\nimport type { MeshGpuHandles } from '../device/gpu-residency';\nimport type { EngineMetrics } from '../engine-metrics';\nimport type { RenderFeatureHost } from '../features/host';\nimport type { RenderFeatureShaderModuleMode } from '../features/types';\nimport type { GpuDrivenPbrProgram } from '../gpu-driven/pbr-program';\nimport type { GpuDrivenShadowBatchProjection } from '../gpu-driven/production-raster';\nimport type { ShadowViewStatePool } from '../gpu-driven/shadow-views';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\nimport type { SkylightFallback } from '../ibl/skylight-bind-group';\nimport type { BloomInspection } from '../inspection-types';\nimport type { HealthListenerRegistry, RhiErrorListenerRegistry } from '../lifecycle';\nimport type { PipelineGroup2Contract } from '../pbr-pipeline';\nimport type { StandardTopologyInputValue } from '../pipeline/standard-lighting/topology';\nimport type { StandardProfile } from '../pipeline/standard-profile';\nimport type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';\nimport type { PointsLinesInspection } from '../points-lines/inspection';\nimport type { PointsLinesRecordPlan } from '../points-lines/record';\nimport type { RenderResourceScope } from '../publication/resource-scope';\nimport type { ReflectionProbeTable } from '../reflection/gpu-table';\nimport type { ReflectionProbeSelectionResult } from '../reflection/projection';\nimport type { FrameObservationDomain } from '../render-contract';\nimport type { SsrAdmissionIdentity } from '../ssr/identity';\nimport type { TypedFrameObservationCapture } from '../typed-render-graph-primitives';\nimport type { GpuPassTimingReason } from './gpu-pass-timing/errors';\nimport type {\n GpuPassTimingCapture,\n GpuPassTimingFrameIdentity,\n GpuPassTimingSession,\n} from './gpu-pass-timing/session';\n\nexport interface PointsLinesRecordSubmission {\n readonly plan: PointsLinesRecordPlan;\n readonly vertexBuffer: Buffer;\n readonly indexBuffer: Buffer;\n readonly layoutProjection: VertexLayoutProjection;\n}\n\nexport interface ReflectionProbeRecordState {\n readonly table: ReflectionProbeTable;\n readonly selections: ReadonlyMap<string, ReflectionProbeSelectionResult>;\n readonly graph: import('./typed-frame-graph').ReflectionProbeGraphState;\n /** Detached committed fallback projections joined by main-pass renderable key. */\n readonly fallbackProjections?: ReadonlyMap<\n string,\n import('../inspection-types').ReflectionFallbackReceipt\n >;\n /** Demand is derived from this frame's renderable/source selection. */\n readonly fallbackDemand?: boolean;\n /** Non-neutral sources require a nonzero diagnostic sample when capture is enabled. */\n readonly fallbackHasNonNeutral?: boolean;\n readonly completeSubmission: (\n submitted: boolean,\n completed?: Promise<unknown>,\n fallbackOutput?: {\n readonly format: TextureFormat;\n readonly size: { readonly width: number; readonly height: number };\n readonly frameId: number;\n readonly graphGeneration: number;\n readonly textureIdentity: number;\n readonly readback?: Promise<{\n readonly linearHdr: readonly [number, number, number, number];\n readonly hash: string;\n readonly graphGeneration: number;\n readonly textureIdentity: number;\n }>;\n },\n fallbackRequested?: boolean,\n ) => Promise<void>;\n}\n\nexport interface MaterialShaderPipelineEntry {\n readonly pipeline: RhiRenderPipeline;\n readonly group2Contract: PipelineGroup2Contract;\n /** Producer receipt for the exact artifact selected with this pipeline. */\n readonly receipt?: {\n readonly identity: string;\n readonly generation: number;\n };\n}\n\nimport type {\n AtmosphereShaderSources,\n RenderDebugOverlay,\n RenderPipelineContext,\n RenderRecordPhase,\n SsrShaderSources,\n VolumetricFogShaderSources,\n} from '../render-contract';\nimport type { GpuDrivenStandardPbrFrameResources } from '../render-pipeline';\nimport type {\n DispatchEntry,\n MaterialSnapshot,\n ShadowCasterMembership,\n SkyboxSnapshot,\n SkylightSnapshot,\n} from '../render-system-extract';\nimport type { SkinPaletteAllocator } from '../systems/skin-palette-allocator';\nimport type { RenderTarget } from '../targets/contracts';\nimport type { RenderTargetPhysical } from '../targets/physical';\nimport type {\n BindGroupCounts,\n BloomFrameReceipts,\n DispatchCounts,\n MaterialBgAssemblyCacheEntry,\n RenderFrameState,\n ValidatedRenderable,\n} from './frame-snapshot';\nimport type { FoldDispatchPlan } from './mesh-ssbo';\n\n/**\n * Armed only for the first published recovery frame. Candidate preparation\n * must make every pipeline and static residency lookup a cache hit before this\n * guard is armed; a miss during draw is a hard failure before queue submission.\n * Explicit preparation between draws remains allowed, including new geometry\n * admitted on the first fixed step after device recovery.\n */\nexport interface RecoveryColdWorkGuard {\n arm(): void;\n beginFrame(): void;\n endFrame(): void;\n notePipelineColdWork(): void;\n noteUploadColdWork(): void;\n finish(): void;\n}\n\nexport interface RenderSystemRuntime {\n readonly device: RhiDevice;\n /** Current renderer device generation used to fence receipt-bound captures. */\n readonly deviceGeneration?: number;\n /** Public receipt identity reserved before graph encoding. */\n readonly observationFrameId?: number | undefined;\n /** Graph identity written by the typed graph for the current receipt. */\n observationGraphGeneration?: number | undefined;\n /** Renderer-owned capture bridge consumed after queue submission. */\n readonly observationCaptureOwner?:\n | {\n register(capture: TypedFrameObservationCapture): void;\n consume(frameNumber: number): readonly TypedFrameObservationCapture[];\n drain(): readonly TypedFrameObservationCapture[];\n }\n | undefined;\n /** Internal backend-fixture hook evaluated at the submit transaction edge. */\n readonly beforeSubmit?: ((device: RhiDevice) => RhiError | undefined) | undefined;\n readonly deviceScope: DeviceScope;\n /** Domains explicitly armed for the frame being encoded. */\n readonly observationCaptureDomains?: readonly FrameObservationDomain[] | undefined;\n /** Resolve a recorder/backend wrapper before configuring the native surface. */\n readonly resolveSurfaceDevice?: (device: RhiDevice) => Result<RhiDevice, RhiError>;\n readonly errorRegistry: RhiErrorListenerRegistry;\n readonly debugOverlay?: RenderDebugOverlay | undefined;\n readonly healthRegistry: HealthListenerRegistry;\n readonly getMaterialProjectionForPayload?: (\n material: MaterialAsset,\n ) => MaterialRenderProjection | undefined;\n readonly getMaterialProjection?: (materialGuid: string) => MaterialRenderProjection | undefined;\n readonly getMaterialArtifact?: (specializationKey: string) => MaterialRuntimeArtifact | undefined;\n /** Producer-owned cooked Standard PBR artifact used by GPU-driven projection. */\n readonly getMaterialShaderArtifact?: (\n materialShaderId: string,\n request?:\n | {\n readonly vertexColorAvailable?: boolean;\n readonly deformation?: 'rigid' | 'skin';\n readonly variantSet?: string;\n readonly clustered?: boolean;\n readonly reflectionFallback?: boolean;\n readonly pass?: 'forward' | 'shadow' | 'depth';\n readonly address?: 'direct' | 'scene-index';\n }\n | boolean,\n ) => MaterialShaderArtifact | undefined;\n readonly getMaterialShaderPipeline?: (\n materialShaderId: string,\n isHdr: boolean,\n renderState?: MaterialRenderState,\n topology?: PrimitiveTopology,\n indexFormat?: 'uint16' | 'uint32',\n variantSet?: string,\n passKind?: PassKind,\n meshAttributes?: VertexAttributeMap,\n sampleCount?: number,\n colorFormatOverride?: GPUTextureFormat,\n shaderUvSetCount?: number,\n depthFormatOverride?: GPUTextureFormat | null,\n vertexLayout?: string,\n vertexLayoutProjection?: VertexLayoutProjection,\n shaderModuleMode?: RenderFeatureShaderModuleMode,\n layoutKindOverride?:\n | 'pbr'\n | 'pbr-skin'\n | 'gpu-driven-pbr'\n | 'gpu-driven-skin'\n | 'gpu-driven-cluster-pbr'\n | 'gpu-driven-cluster-skin'\n | 'surface-direct-pbr'\n | 'surface-direct-cluster-pbr',\n /** Optional vertex entry override for receipt-owned scene-index passes. */\n vertexEntryPoint?: string,\n additionalColorFormats?: readonly GPUTextureFormat[],\n vertexEntry?: string,\n fragmentEntry?: string,\n particleInputLanes?: number,\n fragmentConstants?: Readonly<Record<string, number>>,\n ) => RhiRenderPipeline | null;\n readonly getMaterialShaderPipelineEntry?: (\n materialShaderId: string,\n isHdr: boolean,\n renderState?: MaterialRenderState,\n topology?: PrimitiveTopology,\n indexFormat?: 'uint16' | 'uint32',\n variantSet?: string,\n passKind?: PassKind,\n meshAttributes?: VertexAttributeMap,\n sampleCount?: number,\n colorFormatOverride?: GPUTextureFormat,\n shaderUvSetCount?: number,\n depthFormatOverride?: GPUTextureFormat | null,\n vertexLayout?: string,\n vertexLayoutProjection?: VertexLayoutProjection,\n shaderModuleMode?: RenderFeatureShaderModuleMode,\n layoutKindOverride?:\n | 'pbr'\n | 'pbr-skin'\n | 'gpu-driven-pbr'\n | 'gpu-driven-skin'\n | 'gpu-driven-cluster-pbr'\n | 'gpu-driven-cluster-skin'\n | 'surface-direct-pbr'\n | 'surface-direct-cluster-pbr',\n /** Optional vertex entry override for receipt-owned scene-index passes. */\n vertexEntryPoint?: string,\n additionalColorFormats?: readonly GPUTextureFormat[],\n vertexEntry?: string,\n fragmentEntry?: string,\n particleInputLanes?: number,\n fragmentConstants?: Readonly<Record<string, number>>,\n ) => MaterialShaderPipelineEntry | null;\n /** Reflection-derived UV count included in the material PipelineSpec cache key. */\n readonly getMaterialShaderUvSetCount?: (materialShaderId: string) => number | undefined;\n readonly getMaterialShaderBindingContract?: (\n materialShaderId: string,\n ) =>\n | 'group-0'\n | 'group-0-resource'\n | 'view-only'\n | 'view-and-scene-depth'\n | 'render-material-with-scene-depth'\n | 'render-material-and-scene-depth'\n | 'render-material';\n readonly getParamSchema?: (materialShaderId: string) => readonly ParamSchemaEntry[] | undefined;\n readonly getMaterialBindGroupLayout?: (\n materialShaderId: string,\n materialParamSchema?: readonly ParamSchemaEntry[],\n ) => BindGroupLayout | undefined;\n /** Handle-first factory for built-in same-frame GPU producers. */\n readonly immediateShaderModuleFactory?: PipelineBuilderShaderModuleFactory;\n /** Optional guard for the first recovery frame's cold-work boundary. */\n readonly recoveryColdWorkGuard?: RecoveryColdWorkGuard | undefined;\n readonly metrics: EngineMetrics;\n readonly lookupPostProcess?: (\n id: string,\n ) => import('../fullscreen-post-process-pass').PostProcessShaderEntry | undefined;\n readonly getPostProcessParamsBuffer?: (id: string) => Buffer | undefined;\n readonly getPostProcessPipeline?: (\n id: string,\n bgl: BindGroupLayout,\n colorFormats: readonly GPUTextureFormat[],\n entry?: import('../fullscreen-post-process-pass').PostProcessShaderEntry,\n ) => RhiRenderPipeline | null;\n /** Candidate-owned post-process pipelines transferred at publication. */\n readonly getRecoveryPostProcessPipelines?: () => ReadonlyMap<string, RhiRenderPipeline>;\n readonly clearPostProcessPipelineCache?: (id: string) => void;\n readonly invalidateShaderModule?: (label: string) => void;\n readonly dynamicTextureStore?: DynamicTextureStore | undefined;\n /** Resolves a render-target source to the active generation-owned GPU view. */\n readonly resolveRenderTargetTextureSource?: (\n source: import('../targets/contracts').RenderTargetTextureSource,\n ) => import('../targets/material-source').RenderTargetMaterialSourceBinding | undefined;\n}\n\n/** Renderer-owned bridge from retained Points/Lines facts into main geometry. */\nexport interface PointsLinesRecordOwner {\n prepare(entry: ValidatedRenderable, clustered: boolean): PointsLinesRecordSubmission | undefined;\n beginFrame(): void;\n resetForDeviceLoss(): void;\n inspections(): readonly PointsLinesInspection[];\n}\n\nexport interface PerPassResources {\n depthTexture: Texture | null;\n depthTextureView: TextureView | null;\n depthTextureWidth: number;\n depthTextureHeight: number;\n configured: boolean;\n hdrColorTexture: Texture | null;\n hdrColorView: TextureView | null;\n hdrDepthTexture: Texture | null;\n hdrDepthView: TextureView | null;\n hdrTextureWidth: number;\n hdrTextureHeight: number;\n hdrDepthSampleCount: number;\n readonly fxaaPipeline: RhiRenderPipeline | null;\n readonly fxaaBindGroupLayout: BindGroupLayout | null;\n readonly fxaaSampler: Sampler | null;\n msaaColorTexture: Texture | null;\n msaaColorView: TextureView | null;\n msaaSpriteColorTexture: Texture | null;\n msaaSpriteColorView: TextureView | null;\n msaaDepthTexture: Texture | null;\n msaaDepthView: TextureView | null;\n msaaTextureWidth: number;\n msaaTextureHeight: number;\n hdrColorMsaaTexture: Texture | null;\n hdrColorMsaaView: TextureView | null;\n readonly skyboxPipeline: RhiRenderPipeline | null;\n readonly skyboxPipelineMsaa: RhiRenderPipeline | null;\n readonly skyboxBindGroupLayout: BindGroupLayout | null;\n readonly skyboxSampler: Sampler | null;\n readonly skyboxRotationBuffer: Buffer | null;\n bloomDownsamplePipeline: RhiRenderPipeline | null;\n bloomUpsamplePipeline: RhiRenderPipeline | null;\n bloomCompositePipeline: RhiRenderPipeline | null;\n bloomDownsampleBindGroupLayout: BindGroupLayout | null;\n bloomUpsampleBindGroupLayout: BindGroupLayout | null;\n bloomCompositeBindGroupLayout: BindGroupLayout | null;\n bloomSampler: Sampler | null;\n bloomDownsampleParamsBuffer: Buffer | null;\n bloomUpsampleParamsBuffer: Buffer | null;\n bloomCompositeParamsBuffer: Buffer | null;\n ensureBloomResources?: () => void;\n getBloomResources?: () => BloomPersistentBundle | null;\n commitBloomResources?: () => void;\n commitBloomFrameReceipts?: (receipts: BloomFrameReceipts) => void;\n discardBloomResources?: () => void;\n retireBloomResources?: (completion: Promise<unknown>) => void;\n /** Drain candidate, active, and fence-retiring Bloom generations. */\n drainBloomResources?: () => void;\n inspectBloomResources?: (graph?: CompiledRenderGraphInfo) => BloomInspection;\n ssaoCalcPipeline: RhiRenderPipeline | null;\n ssaoBlurPipeline: RhiRenderPipeline | null;\n ssaoBgl: BindGroupLayout | null;\n ssaoFilteringSampler: Sampler | null;\n ssaoDepthSampler: Sampler | null;\n ssaoFallbackRawView: TextureView | null;\n shadowTexture: Texture | null;\n shadowMapSize: number;\n shadowCascadeCount: number;\n shadowSampler: Sampler | null;\n shadowLightSpaceMatrix: Float32Array | null;\n shadowCsmLightViewProj: Float32Array | null;\n shadowCsmSelection: {\n readonly viewMatrix: Float32Array;\n readonly splitPlanes: Float32Array;\n } | null;\n}\n\n/** Renderer-private Bloom bundle selected for one record transaction. */\nexport interface BloomPersistentBundle {\n readonly scope: DeviceScope;\n readonly generation: number;\n readonly bloomDownsamplePipeline: RhiRenderPipeline | null;\n readonly bloomUpsamplePipeline: RhiRenderPipeline | null;\n readonly bloomCompositePipeline: RhiRenderPipeline | null;\n readonly bloomDownsampleBindGroupLayout: BindGroupLayout | null;\n readonly bloomUpsampleBindGroupLayout: BindGroupLayout | null;\n readonly bloomCompositeBindGroupLayout: BindGroupLayout | null;\n readonly bloomSampler: Sampler | null;\n readonly bloomDownsampleParamsBuffer: Buffer | null;\n readonly bloomUpsampleParamsBuffer: Buffer | null;\n readonly bloomCompositeParamsBuffer: Buffer | null;\n}\n\nexport interface PipelineState {\n /** Device that owns every opaque handle in this pipeline state. */\n readonly device: RhiDevice;\n readonly meshes: ReadonlyMap<number, MeshGpuHandles>;\n readonly format: TextureFormat;\n readonly colorAttachmentFormat: TextureFormat;\n /** Surface route committed by configureSurface for inspection provenance. */\n readonly surfaceProfile?: 'dual-view' | 'raw-only';\n readonly viewBindGroupLayout: BindGroupLayout;\n /** Device capability gate for the optional SpotLight projector binding. */\n readonly projectorAvailable?: boolean;\n readonly materialBindGroupLayout: BindGroupLayout;\n readonly meshBindGroupLayout: BindGroupLayout;\n readonly viewUniformBuffer: Buffer;\n readonly pointsLinesViewBuffer?: Buffer;\n readonly shadowCasterCascadeBuffer: Buffer;\n readonly materialUniformBuffer: { readonly buffer: Buffer; readonly sizeInBytes: number };\n readonly meshStorageBuffer: { readonly buffer: Buffer; readonly sizeInBytes: number };\n readonly instancesBindGroupLayout: BindGroupLayout;\n /** Probe-enabled slot-3 layout; omitted from no-probe bind groups. */\n readonly probeInstancesBindGroupLayout?: BindGroupLayout;\n readonly identityInstanceBuffer: Buffer;\n readonly defaultSampler: Sampler;\n /** Nearest/clamp sampler required by r32float Surface depth input. */\n readonly surfaceMediumDepthSampler?: Sampler;\n readonly fallbackTextureView: TextureView;\n readonly unlitPipeline: RhiRenderPipeline | null;\n readonly standardPipeline: RhiRenderPipeline | null;\n /** Producer-owned Standard PBR module for this device generation. */\n readonly standardPbrShaderModule: ShaderModule | null;\n /** Producer-owned skinned Standard PBR module for this device generation. */\n readonly pbrSkinShaderModule: ShaderModule | null;\n /** Producer-resolved Standard PBR UV ABI count for geometry projection. */\n readonly standardPbrShaderUvSetCount: number;\n readonly unlitPipelineMsaa: RhiRenderPipeline | null;\n readonly unlitPipelineHdrMsaa: RhiRenderPipeline | null;\n readonly pbrPipelineLayout: PipelineLayout | null;\n /** Dedicated slot-3 layout for scene-index GPU-driven Standard PBR draws. */\n readonly gpuDrivenInstancesBindGroupLayout?: BindGroupLayout | null;\n /** Direct Surface slot-3 ABI: instances + retained medium frame resources. */\n readonly surfaceDirectInstancesBindGroupLayout?: BindGroupLayout | null;\n readonly gpuDrivenPbrPipelineLayout?: PipelineLayout | null;\n /** Device-owned shader modules paired with their exact Standard PBR receipts. */\n readonly gpuDrivenPbrPrograms?: ReadonlyMap<string, GpuDrivenPbrProgram>;\n readonly gpuDrivenPbrSkinPipelineLayout?: PipelineLayout | null;\n /** Clustered group(2) layouts paired with the scene-index slot(3). */\n readonly gpuDrivenClusterPbrPipelineLayout?: PipelineLayout | null;\n readonly gpuDrivenClusterPbrSkinPipelineLayout?: PipelineLayout | null;\n readonly gpuDrivenClusterMeshBindGroupLayout?: BindGroupLayout | null;\n readonly pbrProbePipelineLayout?: PipelineLayout | null;\n readonly hdrpPbrPipelineLayout: PipelineLayout | null;\n readonly hdrpMeshBindGroupLayout?: BindGroupLayout | null;\n readonly hdrpProbePbrPipelineLayout?: PipelineLayout | null;\n readonly hdrpClusterMembershipPipeline: ComputePipeline | null;\n readonly hdrpClusterMembershipBindGroupLayout: BindGroupLayout | null;\n readonly pbrSkinPipelineLayout: PipelineLayout | null;\n readonly pbrSkinProbePipelineLayout?: PipelineLayout | null;\n readonly pbrSkinMeshBindGroupLayout: BindGroupLayout | null;\n readonly hdrpSkinPipelineLayout: PipelineLayout | null;\n readonly hdrpSkinMeshBindGroupLayout: BindGroupLayout | null;\n readonly skinPaletteAllocator: SkinPaletteAllocator | null;\n readonly defaultWhiteTextureView: TextureView;\n readonly defaultNormalTextureView: TextureView;\n /** Missing anisotropy maps encode a neutral direction and unit strength. */\n readonly defaultAnisotropyTextureView?: TextureView;\n readonly unlitPipelineHdr: RhiRenderPipeline | null;\n readonly shadowFallbackTextureView: TextureView;\n readonly shadowAtlasFallbackTextureView: TextureView;\n readonly extendedLightingAvailable?: boolean;\n readonly iesProfileTexture?: Texture;\n readonly cookieTexture?: Texture;\n readonly cookieMatrixBuffer?: Buffer;\n spotModifierUploadState?: {\n readonly ies: Map<number, number>;\n readonly cookie: Map<number, number>;\n readonly cookieMatrix: Map<number, number>;\n };\n readonly iesProfileTextureView?: TextureView;\n readonly cookieTextureView?: TextureView;\n readonly ltcLambertTextureView?: TextureView;\n readonly ltcGgxTextureView?: TextureView;\n readonly shadowParamsBuffer: Buffer;\n readonly skylightFallback: SkylightFallback | null;\n readonly perPassResources: PerPassResources;\n}\n\nexport interface RenderSystemInternals extends RenderSystemRuntime {\n readonly canvas: HTMLCanvasElement | OffscreenCanvas;\n /** Build identity injected by the host's build-tool adapter. */\n readonly build?: string | undefined;\n /** Host identity binding for the renderer-owned SSR dependency seam. */\n readonly ssrIdentity?: SsrAdmissionIdentity | undefined;\n readonly captureReflectionFallbackReadback?: boolean | undefined;\n readonly standardProfile?: StandardProfile | undefined;\n readonly standardPipeline: RenderFrameState['activePipeline'];\n readonly featureHost?: RenderFeatureHost | undefined;\n /** Install a detached feature host only at the recovery publication boundary. */\n readonly setFeatureHost?: ((host: RenderFeatureHost) => void) | undefined;\n readonly shaderModuleFactory?: PipelineBuilderShaderModuleFactory;\n readonly createShaderModule?: (\n device: import('@forgeax/engine-rhi').RhiDevice,\n descriptor: { readonly code: string; readonly label?: string },\n ) => Promise<\n Result<import('@forgeax/engine-rhi').ShaderModule, import('@forgeax/engine-rhi').RhiError>\n >;\n /** Optional handle-first factory for feature-owned generated shader programs. */\n readonly immediateShaderModuleFactory?: PipelineBuilderShaderModuleFactory;\n readonly profiler?: Profiler | undefined;\n readonly context: RhiCanvasContext | null;\n readonly getPipelineState: () => PipelineState | null;\n readonly assets: AssetRegistry;\n readonly gpuStore: import('../device/gpu-residency').GpuResidencyCache;\n readonly growMeshSsbo?:\n | ((neededSlots: number) =>\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly code: 'mesh-ssbo-ceiling-reached' | 'mesh-ssbo-capacity-exceeded';\n readonly degradedToSlotCount: number;\n })\n | undefined;\n readonly meshSsboState?: { readonly slotCount: number } | undefined;\n readonly buildPostProcessPipeline?:\n | ((\n entry: import('../fullscreen-post-process-pass').PostProcessShaderEntry,\n bgl: BindGroupLayout,\n colorFormats: readonly GPUTextureFormat[],\n label: string,\n ) => RhiRenderPipeline | null)\n | undefined;\n gpuPassTimingSession?: GpuPassTimingSession | undefined;\n gpuPassTimingCapture?: GpuPassTimingCapture | undefined;\n gpuPassTimingSubmittedWork?: Promise<void> | undefined;\n gpuPassTimingFrameIdentity?: GpuPassTimingFrameIdentity | undefined;\n gpuPassTimingBeginReason?: GpuPassTimingReason | undefined;\n readonly getRenderTargetPhysical?: (target: RenderTarget) => RenderTargetPhysical | undefined;\n readonly encodeRenderTargetReadbacks?: (\n encoder: RhiCommandEncoder,\n faces?: readonly number[],\n ) => void;\n /** Composed renderer utility sources installed atomically at build-ready. */\n volumetricFogShaders?: VolumetricFogShaderSources | undefined;\n /** Composed renderer utility sources installed atomically at build-ready. */\n ssrShaders?: SsrShaderSources | undefined;\n /** Composed renderer utility sources installed atomically at build-ready. */\n atmosphereShaders?: AtmosphereShaderSources | undefined;\n}\n\nexport interface _StandardForwardSceneView {\n readonly environmentIbl?: { readonly irradiance: TextureView; readonly prefilter: TextureView };\n readonly captureDispatch?: readonly DispatchEntry[];\n readonly assets: AssetRegistry;\n readonly store: import('../device/gpu-residency').GpuResidencyCache;\n readonly pipelineState: PipelineState;\n readonly bloomResources?: BloomPersistentBundle | null;\n readonly runtime: RenderSystemRuntime;\n readonly validated: readonly ValidatedRenderable[];\n readonly validatedOrdered: readonly ValidatedRenderable[];\n readonly viewBindGroup: BindGroup | null;\n /** Dynamic View-UBO slot used by auxiliary cube/probe face cameras. */\n readonly viewBindGroupDynamicOffset?: number;\n readonly meshBindGroup: BindGroup | null;\n readonly frameState: RenderFrameState;\n readonly dispatchCounts: DispatchCounts;\n readonly bindGroupCounts: BindGroupCounts;\n readonly skylight: SkylightSnapshot | undefined;\n readonly skylightCount: number;\n readonly skybox: SkyboxSnapshot | undefined;\n readonly profilePhase?: <T>(phase: RenderRecordPhase, action: () => T) => T;\n readonly directionalShadowCacheReuse: boolean;\n readonly world: RenderResourceScope;\n readonly tonemapActive: boolean;\n readonly geometryColorView: TextureView | null;\n readonly geometryDepthView: TextureView | null;\n readonly geometryDepthKey: string | null;\n readonly skyboxActive: boolean;\n readonly splitLdrSprite: boolean;\n readonly ldrSpritePassView: TextureView | null;\n readonly transparentColorFormat?: GPUTextureFormat;\n /** Second Standard main-pass attachment used by the fallback producer. */\n readonly reflectionFallbackColorFormat?: GPUTextureFormat;\n readonly dispatch: readonly DispatchEntry[];\n readonly hdrpClusterBindGroup: BindGroup | null;\n readonly hdrpClusterMembershipBindGroup: BindGroup | null;\n /** Prepared Standard lighting declaration accepted by this graph frame. */\n readonly standardLighting?: StandardTopologyInputValue;\n readonly foldDispatchPlan: FoldDispatchPlan | null;\n readonly materialSlotIndices: readonly (readonly number[])[];\n readonly materialSlots: readonly MaterialSnapshot[];\n readonly materialSlotOwners: readonly ValidatedRenderable[];\n readonly materialSlotCount: number;\n /** Filled by main-pass material producers before the GPU-driven raster tail. */\n readonly gpuDrivenStandardPbrFrameResources?: GpuDrivenStandardPbrFrameResources;\n /** Scene table retained by the renderer even when no draw is GPU-admitted. */\n readonly gpuDrivenSceneMaterialBuffer?: Buffer;\n /** Concrete main-pass draw identities already claimed by the capable GPU lane. */\n readonly gpuDrivenDrawKeys?: ReadonlySet<string>;\n /** Stable world identities used to construct the claimed draw keys. */\n readonly gpuDrivenWorldKeys?: readonly number[];\n readonly gpuDrivenShadowViews?: ShadowViewStatePool;\n readonly gpuDrivenShadowBatchProjections?: ReadonlyMap<\n string,\n ReadonlyMap<number, GpuDrivenShadowBatchProjection>\n >;\n /** Concrete ShadowCaster keys already claimed by the capable GPU subset. */\n readonly gpuDrivenShadowDrawKeys?: ReadonlySet<string>;\n /** View-scoped ShadowCaster claims for exact CPU residual routing. */\n readonly gpuDrivenShadowDrawKeysByView?: ReadonlyMap<string, ReadonlySet<string>>;\n /** Per-shadow-view frusta shared by GPU compaction and CPU residual routing. */\n readonly shadowViewPlanesByView?: ReadonlyMap<string, Float32Array>;\n /** Extracted structured ShadowCaster ownership facts. */\n readonly shadowCasterMembership?: readonly ShadowCasterMembership[];\n /** Complete retained ShadowCaster rows, including camera-culled casters. */\n readonly shadowValidatedOrdered?: readonly ValidatedRenderable[];\n /** Dispatch entries remapped to the complete retained ShadowCaster rows. */\n readonly shadowDispatch?: readonly DispatchEntry[];\n /** Mesh-SSBO slot base reserved for the retained ShadowCaster rows. */\n readonly shadowMeshSsboBase?: number;\n /** Renderer-stable world keys used by ShadowCaster ownership identities. */\n readonly shadowCasterWorldKeys?: readonly number[];\n readonly pointsLines: PointsLinesRecordOwner | undefined;\n readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;\n /** Record-stage proof callback; invoked only after a real draw command is encoded. */\n readonly onRenderableDraw?: (\n entry: ValidatedRenderable,\n submeshIndex?: number,\n receipt?: { readonly lane: 'cpu' | 'gpu'; readonly ready: boolean },\n ) => void;\n readonly reflectionProbes?: ReflectionProbeRecordState;\n materialUboPayloadCache?: {\n readonly materialSlots: readonly MaterialSnapshot[];\n readonly materialSlotCount: number;\n readonly payload: Uint8Array;\n };\n hdrpSsaoBlurredView?: TextureView;\n readonly occlusion?: import('../scene/visibility/occlusion-runtime').OcclusionFrameProjection;\n}\n\nexport type _InternalRenderPipelineContext = RenderPipelineContext & _StandardForwardSceneView;\n\nexport type RecordProfileRunner = <T>(phase: RenderRecordPhase, action: () => T) => T;\n\nexport const STANDARD_PBR_UBO_SIZE = derive(DEFAULT_STANDARD_PBR_PARAM_SCHEMA).uboLayout.totalBytes;\nexport const MATERIAL_PER_ENTITY_STRIDE = Math.ceil(STANDARD_PBR_UBO_SIZE / 256) * 256;\n\nexport type SwapChainFormatPair = {\n readonly storage: GPUTextureFormat;\n readonly view: GPUTextureFormat;\n readonly fallbackReason?: 'preferred-canvas-format-missing';\n};\n\n/** Internal closed projection of the concrete surface route. */\nexport type SurfaceProfile =\n | {\n readonly kind: 'dual-view';\n readonly storageFormat: GPUTextureFormat;\n readonly viewFormat: GPUTextureFormat;\n readonly viewFormats: readonly [GPUTextureFormat];\n readonly hasDisplayEndpoint: true;\n }\n | {\n readonly kind: 'raw-only';\n readonly storageFormat: GPUTextureFormat;\n readonly viewFormat: GPUTextureFormat;\n readonly viewFormats: readonly [];\n readonly hasDisplayEndpoint: false;\n };\n\nexport interface SurfaceCapabilityFacts {\n /** Concrete wgpu downlevel `SURFACE_VIEW_FORMATS` flag. */\n readonly surfaceViewFormats: boolean;\n readonly rawAttachment: boolean;\n readonly floatRenderAttachment: boolean;\n}\n\nexport function resolveSurfaceProfile(\n storageFormat: GPUTextureFormat,\n viewFormat: GPUTextureFormat,\n facts: SurfaceCapabilityFacts,\n): Result<SurfaceProfile, RhiError> {\n if (facts.surfaceViewFormats) {\n return ok({\n kind: 'dual-view',\n storageFormat,\n viewFormat,\n viewFormats: [viewFormat],\n hasDisplayEndpoint: true,\n });\n }\n if (!facts.rawAttachment || !facts.floatRenderAttachment) {\n return err(\n new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'raw surface attachment and rgba16float render attachment capabilities',\n hint: 'surface profile cannot establish a raw-only linear output route',\n detail: {\n error: {\n code: 'surface-raw-endpoint-failed',\n message: 'raw-only surface capabilities are incomplete',\n },\n },\n }),\n );\n }\n return ok({\n kind: 'raw-only',\n storageFormat,\n viewFormat: storageFormat,\n viewFormats: [],\n hasDisplayEndpoint: false,\n });\n}\n\nexport type SurfaceBackendKind = 'webgpu' | 'wgpu-native' | 'wgpu-webgl2' | 'null';\n\nexport function resolveSurfaceFormatPair(\n _backendKind: SurfaceBackendKind,\n storage: GPUTextureFormat,\n view: GPUTextureFormat,\n): SwapChainFormatPair {\n return { storage, view };\n}\n\nfunction surfaceCapabilityFacts(\n device: RhiDevice,\n storageFormat: GPUTextureFormat,\n): SurfaceCapabilityFacts {\n const internal = device as unknown as { readonly surfaceViewFormats?: boolean };\n return {\n surfaceViewFormats: internal.surfaceViewFormats ?? device.caps?.backendKind !== 'wgpu-webgl2',\n rawAttachment: storageFormat === 'rgba8unorm' || storageFormat === 'bgra8unorm',\n floatRenderAttachment: device.caps?.rgba16floatRenderable ?? true,\n };\n}\n\nexport function configureSurface(\n context: RhiCanvasContext,\n device: RhiDevice,\n format: TextureFormat,\n colorAttachmentFormat: TextureFormat,\n): Result<void, RhiError> {\n const backendKind = device.caps?.backendKind ?? 'webgpu';\n const isWebGl2 = backendKind === 'wgpu-webgl2';\n const surfaceFormats = resolveSurfaceFormatPair(\n backendKind,\n format as GPUTextureFormat,\n colorAttachmentFormat as GPUTextureFormat,\n );\n const profile = resolveSurfaceProfile(\n surfaceFormats.storage,\n surfaceFormats.view,\n surfaceCapabilityFacts(device, surfaceFormats.storage),\n );\n if (!profile.ok) return profile;\n // WebGL2 surface pixels are proven by the compositor fixture, so it has no\n // surface consumer for optional TEXTURE_BINDING/COPY_SRC usage. The concrete\n // wgpu surface derives supported usages from SurfaceCapabilities and rejects\n // unsupported requests; this path requests only the guaranteed attachment\n // usage. Raw-only deliberately has no alternate view.\n const supportsTextureBinding =\n backendKind !== 'wgpu-webgl2' && (device.caps?.storageBuffer ?? true);\n const configured = context.configure({\n device,\n format: surfaceFormats.storage,\n alphaMode: isWebGl2 ? 'opaque' : 'premultiplied',\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n (supportsTextureBinding ? GPU_TEXTURE_USAGE_TEXTURE_BINDING : 0) |\n (isWebGl2 ? 0 : GPU_TEXTURE_USAGE_COPY_SRC),\n viewFormats: [...profile.value.viewFormats],\n });\n if (!configured.ok) return configured;\n if (\n isWebGl2 &&\n (context.presentationProof === undefined ||\n !context.presentationProof.descriptor ||\n !context.presentationProof.acquisition ||\n !context.presentationProof.validation ||\n typeof context.presentationProof.surfaceIdentity !== 'string' ||\n context.presentationProof.surfaceIdentity.length === 0 ||\n context.presentationProof.requested === undefined ||\n context.presentationProof.validated === undefined ||\n JSON.stringify(context.presentationProof.requested) !==\n JSON.stringify(context.presentationProof.validated))\n ) {\n return err(\n new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'WebGL2 surface storage has descriptor, acquisition, and validation proof',\n hint: 'run the concrete presentation probe and retain the last-known-good graph when proof is absent',\n detail: {\n error: {\n code: 'surface-raw-endpoint-failed',\n message: 'surface storage raw endpoint proof is incomplete',\n },\n },\n }),\n );\n }\n return ok(undefined);\n}\n\nexport function selectSwapChainFormat(\n storageBufferCapable: boolean,\n surfaceViewFormats = true,\n): SwapChainFormatPair {\n if (!storageBufferCapable) {\n return {\n storage: 'rgba8unorm',\n view: surfaceViewFormats ? 'rgba8unorm-srgb' : 'rgba8unorm',\n };\n }\n const nav = (\n globalThis as { navigator?: { gpu?: { getPreferredCanvasFormat?: () => GPUTextureFormat } } }\n ).navigator;\n const gpu = nav?.gpu;\n const getPreferred = gpu?.getPreferredCanvasFormat;\n if (gpu !== undefined && typeof getPreferred === 'function') {\n const storage = getPreferred.call(gpu);\n const view =\n storage === 'rgba8unorm'\n ? 'rgba8unorm-srgb'\n : storage === 'bgra8unorm'\n ? 'bgra8unorm-srgb'\n : storage;\n return {\n storage,\n view: surfaceViewFormats ? view : storage,\n };\n }\n return {\n storage: 'rgba8unorm',\n view: surfaceViewFormats ? 'rgba8unorm-srgb' : 'rgba8unorm',\n fallbackReason: 'preferred-canvas-format-missing',\n };\n}\n"]}
|