@zephyr3d/scene 0.9.22 → 0.9.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/joint_dynamics/collision.js +1 -7
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/constraints.js +2 -17
- package/dist/animation/joint_dynamics/constraints.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +2 -20
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +1 -3
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +14 -60
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js +3 -3
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/app/app.js +23 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/scriptregistry.js +16 -53
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +2 -0
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +22 -0
- package/dist/asset/model.js.map +1 -1
- package/dist/blitter/bilateralblur.js +3 -1
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/blitter.js +3 -3
- package/dist/blitter/blitter.js.map +1 -1
- package/dist/camera/camera.js +398 -45
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +69 -2
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +9113 -8740
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/lambert.js +3 -3
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +8 -5
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +17 -10
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +21 -6
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +33 -11
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/brdf.js +44 -12
- package/dist/material/mixins/pbr/brdf.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +149 -14
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +7 -4
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +5 -1
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js +1 -1
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +512 -334
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/skin.js +2 -2
- package/dist/material/skin.js.map +1 -1
- package/dist/material/terrain-cm.js +5 -5
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/water.js +6 -4
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +54 -4
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js +41 -0
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/posteffect.js +35 -0
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js +7 -6
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +3 -3
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +988 -436
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +83 -45
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +18 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +5 -4
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +15 -3
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +2 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +22 -16
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/drawable_mixin.js +8 -5
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +10 -5
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +298 -5
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/gpu_picking.js +7 -5
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +28 -19
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +18 -4
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/render_queue.js +37 -4
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +8 -3
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +20 -48
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +18 -58
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +89 -115
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +1003 -715
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +1 -1
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +14 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -0
- package/dist/render/rendergraph/history_resource_manager.js +74 -140
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +7 -5
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/render_context.js +19 -0
- package/dist/render/rendergraph/render_context.js.map +1 -0
- package/dist/render/rendergraph/render_pipeline.js +315 -0
- package/dist/render/rendergraph/render_pipeline.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +158 -141
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +267 -0
- package/dist/render/rendergraph/scene_render_context.js.map +1 -0
- package/dist/render/rendergraph/texture_affinity_cache.js +19 -0
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -0
- package/dist/render/rendergraph/types.js +19 -31
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +3 -3
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +7 -6
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +257 -95
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +4 -3
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +2 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +10 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +61 -2
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/light.js +178 -10
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/meshdrawable.js +89 -2
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +2 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +2 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +2 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +34 -1
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +2 -1
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +2 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +2 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js +5 -4
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +10 -3
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/shadow.js +149 -40
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/ssgi_reprojection.js +118 -0
- package/dist/shaders/ssgi_reprojection.js.map +1 -0
- package/dist/shaders/ssr.js +322 -154
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shadow/esm.js +10 -7
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +12 -12
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +12 -12
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +16 -11
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +29 -3
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +5 -2
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +13 -13
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +7 -7
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/physical.js +74 -0
- package/dist/utility/physical.js.map +1 -0
- package/dist/utility/rendermipmap.js +2 -2
- package/dist/utility/rendermipmap.js.map +1 -1
- package/dist/utility/serialization/manager.js +3 -1
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +3 -1
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +3 -1
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +598 -2
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +180 -9
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +43 -3
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +3 -1
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +3 -1
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +3 -1
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +2 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +70 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +3 -1
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +3 -1
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +3 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +3 -1
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/values.js +59 -65
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame_graph_context.js","sources":["../../../src/render/rendergraph/frame_graph_context.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\nimport type { RGHandle, RGPassBuilder } from './types';\nimport type { RenderGraph } from './rendergraph';\nimport type { RGBlackboard } from './blackboard';\nimport type { HistoryResourceManager } from './history_resource_manager';\nimport type { DrawContext } from '../drawable';\nimport type { RenderQueue } from '../render_queue';\nimport type { Texture2D, FrameBuffer } from '@zephyr3d/device';\nimport type { ForwardPlusOptions, FrameState, ForwardPlusBuildState } from './forward_plus_builder';\n\n/**\n * Ordering helper that encapsulates the side-effect \"order token\" chain.\n *\n * Side-effect passes (SkyUpdate, ClusterLights, ...) carry no data product, so\n * they are ordered relative to one another through logical tokens rather than\n * texture reads/writes. This scope tracks the most recently emitted token so a\n * pass can chain after the previous one and (optionally) emit its own, without\n * the builder threading a mutable `orderToken` local between blocks.\n *\n * @
|
|
1
|
+
{"version":3,"file":"frame_graph_context.js","sources":["../../../src/render/rendergraph/frame_graph_context.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\nimport type { RGHandle, RGPassBuilder } from './types';\nimport type { RenderGraph } from './rendergraph';\nimport type { RGBlackboard } from './blackboard';\nimport type { HistoryResourceManager } from './history_resource_manager';\nimport type { DrawContext } from '../drawable';\nimport type { RenderQueue } from '../render_queue';\nimport type { Texture2D, FrameBuffer } from '@zephyr3d/device';\nimport type { ForwardPlusOptions, FrameState, ForwardPlusBuildState } from './forward_plus_builder';\n\n/**\n * Ordering helper that encapsulates the side-effect \"order token\" chain.\n *\n * Side-effect passes (SkyUpdate, ClusterLights, ...) carry no data product, so\n * they are ordered relative to one another through logical tokens rather than\n * texture reads/writes. This scope tracks the most recently emitted token so a\n * pass can chain after the previous one and (optionally) emit its own, without\n * the builder threading a mutable `orderToken` local between blocks.\n *\n * @public\n */\nexport class OrderingScope {\n /** @internal */\n private _last: Nullable<RGHandle> = null;\n\n /**\n * Declare a read on the most recently emitted ordering token, if any, to\n * order the current pass after the previous side-effect pass.\n *\n * @param builder - The pass builder of the current pass.\n */\n chainInto(builder: RGPassBuilder): void {\n if (this._last) {\n builder.read(this._last);\n }\n }\n\n /**\n * Emit a new ordering token from the current pass and record it as the latest\n * link in the chain.\n *\n * @param builder - The pass builder of the current pass.\n * @param name - Debug label for the token.\n * @returns The newly created token handle.\n */\n emit(builder: RGPassBuilder, name: string): RGHandle {\n const token = builder.createToken(name);\n this._last = token;\n return token;\n }\n\n /** The most recently emitted ordering token, or null. */\n get last(): Nullable<RGHandle> {\n return this._last;\n }\n}\n\n/**\n * Build-time context threaded through the Forward+ graph assembly.\n *\n * This aggregates everything the individual pass-build blocks previously reached\n * through enclosing function locals (`orderToken`, the mutable `depthHandle`,\n * result bundles, ...). Collecting them here is the seam that lets each pass be\n * expressed as an independent unit reading its inputs from a shared context\n * rather than from closure-captured variables.\n *\n * Handles for well-known frame resources (linear depth, scene color, ...) flow\n * through {@link RenderModuleContext.blackboard} keyed by\n * {@link ./blackboard#FrameResources}; the mutable execute-time state that is\n * not a render-graph resource stays on {@link FrameGraphContext.frame}.\n *\n * @public\n */\nexport interface RenderModuleContext {\n /** The render graph being populated for this frame. */\n readonly graph: RenderGraph;\n /** Frame draw context. */\n readonly ctx: DrawContext;\n /** The culled render queue for this frame. */\n readonly renderQueue: RenderQueue;\n /** Named registry of shared frame-resource handles (see {@link ./blackboard#FrameResources}). */\n readonly blackboard: RGBlackboard;\n /** Cross-frame history resource manager, or null when unavailable. */\n readonly history: Nullable<HistoryResourceManager<Texture2D>>;\n /** Pipeline feature toggles derived from scene/camera state. */\n readonly options: ForwardPlusOptions;\n /** Ordering-token chain for side-effect passes. */\n readonly ordering: OrderingScope;\n /** The imported backbuffer handle (graph sink). */\n readonly backbuffer: RGHandle;\n}\n\n/**\n * Full build-time context threaded through the Forward+ pipeline. Extends the\n * public {@link RenderModuleContext} with the Forward+ pipeline's internal\n * mutable state, which built-in modules read/write but custom modules should\n * not depend on.\n *\n * @internal\n */\nexport interface FrameGraphContext extends RenderModuleContext {\n /** Mutable execute-time state shared between pass callbacks. */\n readonly frame: FrameState;\n /** Mutable build-state shared between modules for non-resource intermediates. */\n readonly state: ForwardPlusBuildState;\n}\n\n/** Backend framebuffer type used by the Forward+ allocator. */\nexport type ForwardPlusFramebuffer = FrameBuffer;\n"],"names":["OrderingScope","_last","chainInto","builder","read","emit","name","token","createToken","last"],"mappings":"AAUA;;;;;;;;;;AAUC,IACM,MAAMA,aAAAA,CAAAA;qBAEX,KAAQC,GAA4B,IAAK;AAEzC;;;;;MAMAC,SAAAA,CAAUC,OAAsB,EAAQ;QACtC,IAAI,IAAI,CAACF,KAAK,EAAE;AACdE,YAAAA,OAAAA,CAAQC,IAAI,CAAC,IAAI,CAACH,KAAK,CAAA;AACzB;AACF;AAEA;;;;;;;AAOC,MACDI,IAAKF,CAAAA,OAAsB,EAAEG,IAAY,EAAY;QACnD,MAAMC,KAAAA,GAAQJ,OAAQK,CAAAA,WAAW,CAACF,IAAAA,CAAAA;QAClC,IAAI,CAACL,KAAK,GAAGM,KAAAA;QACb,OAAOA,KAAAA;AACT;8DAGA,IAAIE,IAA2B,GAAA;QAC7B,OAAO,IAAI,CAACR,KAAK;AACnB;AACF;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Frame resources requested before Forward+ module setup. @public */ /** Merge frame-resource requirements using monotonic OR semantics. @public */ function mergeFrameResourceRequirements(target, source) {
|
|
2
|
+
if (!source) {
|
|
3
|
+
return target;
|
|
4
|
+
}
|
|
5
|
+
target.motionVector = !!target.motionVector || !!source.motionVector;
|
|
6
|
+
target.hiZ = !!target.hiZ || !!source.hiZ;
|
|
7
|
+
target.sceneNormal = !!target.sceneNormal || !!source.sceneNormal;
|
|
8
|
+
target.sceneRoughness = !!target.sceneRoughness || !!source.sceneRoughness;
|
|
9
|
+
target.shadowMask = !!target.shadowMask || !!source.shadowMask;
|
|
10
|
+
return target;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { mergeFrameResourceRequirements };
|
|
14
|
+
//# sourceMappingURL=frame_resource_requirements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame_resource_requirements.js","sources":["../../../src/render/rendergraph/frame_resource_requirements.ts"],"sourcesContent":["/** Frame resources requested before Forward+ module setup. @public */\r\nexport interface FrameResourceRequirements {\r\n motionVector?: boolean;\r\n hiZ?: boolean;\r\n sceneNormal?: boolean;\r\n sceneRoughness?: boolean;\r\n shadowMask?: boolean;\r\n}\r\n\r\n/** Merge frame-resource requirements using monotonic OR semantics. @public */\r\nexport function mergeFrameResourceRequirements(\r\n target: FrameResourceRequirements,\r\n source: FrameResourceRequirements | null | undefined\r\n): FrameResourceRequirements {\r\n if (!source) {\r\n return target;\r\n }\r\n target.motionVector = !!target.motionVector || !!source.motionVector;\r\n target.hiZ = !!target.hiZ || !!source.hiZ;\r\n target.sceneNormal = !!target.sceneNormal || !!source.sceneNormal;\r\n target.sceneRoughness = !!target.sceneRoughness || !!source.sceneRoughness;\r\n target.shadowMask = !!target.shadowMask || !!source.shadowMask;\r\n return target;\r\n}\r\n"],"names":["mergeFrameResourceRequirements","target","source","motionVector","hiZ","sceneNormal","sceneRoughness","shadowMask"],"mappings":"AAAA,sJAUO,SAASA,8BACdC,CAAAA,MAAiC,EACjCC,MAAoD,EAAA;AAEpD,IAAA,IAAI,CAACA,MAAQ,EAAA;QACX,OAAOD,MAAAA;AACT;IACAA,MAAOE,CAAAA,YAAY,GAAG,CAAC,CAACF,MAAAA,CAAOE,YAAY,IAAI,CAAC,CAACD,MAAAA,CAAOC,YAAY;IACpEF,MAAOG,CAAAA,GAAG,GAAG,CAAC,CAACH,MAAAA,CAAOG,GAAG,IAAI,CAAC,CAACF,MAAAA,CAAOE,GAAG;IACzCH,MAAOI,CAAAA,WAAW,GAAG,CAAC,CAACJ,MAAAA,CAAOI,WAAW,IAAI,CAAC,CAACH,MAAAA,CAAOG,WAAW;IACjEJ,MAAOK,CAAAA,cAAc,GAAG,CAAC,CAACL,MAAAA,CAAOK,cAAc,IAAI,CAAC,CAACJ,MAAAA,CAAOI,cAAc;IAC1EL,MAAOM,CAAAA,UAAU,GAAG,CAAC,CAACN,MAAAA,CAAOM,UAAU,IAAI,CAAC,CAACL,MAAAA,CAAOK,UAAU;IAC9D,OAAON,MAAAA;AACT;;;;"}
|
|
@@ -1,48 +1,18 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Manages cross-frame history resources that can be imported into a render graph.
|
|
3
|
-
*
|
|
4
|
-
* History resources are textures that persist across frames for temporal effects
|
|
5
|
-
* like TAA, motion blur, or temporal upscaling. Previous-frame textures can be
|
|
6
|
-
* imported into a {@link RenderGraph}, and current-frame textures are committed
|
|
7
|
-
* only after graph execution succeeds.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* ```ts
|
|
11
|
-
* const historyMgr = new HistoryResourceManager(allocator);
|
|
12
|
-
* historyMgr.beginFrame();
|
|
13
|
-
* const prev = historyMgr.importPrevious(graph, 'taaColor');
|
|
14
|
-
* // declare builder.read(prev) if non-null
|
|
15
|
-
* historyMgr.bindImportedTextures(executor);
|
|
16
|
-
* // after successful execution:
|
|
17
|
-
* historyMgr.commitFrame();
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* @typeParam TTexture - The concrete texture type (e.g. `Texture2D`).
|
|
21
|
-
* @public
|
|
22
|
-
*/ class HistoryResourceManager {
|
|
1
|
+
/** Manages render graph textures retained across frames. @public */ class HistoryResourceManager {
|
|
23
2
|
_resources = new Map();
|
|
24
3
|
_allocator;
|
|
25
4
|
_pendingImports = new Map();
|
|
26
5
|
_pendingCommits = new Map();
|
|
27
6
|
_readScopeStack = [];
|
|
28
7
|
_frameActive = false;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* @param allocator - Texture allocator for creating history textures.
|
|
33
|
-
*/ constructor(allocator){
|
|
8
|
+
// Delay replaced commits until frame end to prevent pool reuse while queued.
|
|
9
|
+
_deferredReleases = [];
|
|
10
|
+
/** Create a history manager using the given allocator. */ constructor(allocator){
|
|
34
11
|
this._allocator = allocator;
|
|
35
12
|
}
|
|
36
13
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* The resource must have been imported with {@link HistoryResourceManager.importPrevious} or
|
|
40
|
-
* {@link HistoryResourceManager.importPreviousIfCompatible}, declared as a pass read, and bound with
|
|
41
|
-
* {@link HistoryResourceManager.beginReadScope} before this method is called.
|
|
42
|
-
*
|
|
43
|
-
* @param name - Name of the history resource.
|
|
44
|
-
* @returns The graph-resolved previous-frame texture.
|
|
45
|
-
* @throws If no read scope is active for the resource.
|
|
14
|
+
* Return a previous-frame texture from the active read scope.
|
|
15
|
+
* @throws When the resource is not available in that scope.
|
|
46
16
|
*/ getPrevious(name) {
|
|
47
17
|
const scoped = this._getScopedRead(name);
|
|
48
18
|
if (scoped) {
|
|
@@ -50,49 +20,23 @@
|
|
|
50
20
|
}
|
|
51
21
|
throw new Error(`History resource '${name}' is not available in the current render graph read scope. ` + `Import it and declare a pass read before accessing it.`);
|
|
52
22
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Try to get a previous-frame texture from the current render graph read scope.
|
|
55
|
-
*
|
|
56
|
-
* Returns null when the resource was not imported for the current pass.
|
|
57
|
-
*
|
|
58
|
-
* @param name - Name of the history resource.
|
|
59
|
-
* @returns The scoped previous-frame texture, or null.
|
|
60
|
-
*/ tryGetPrevious(name) {
|
|
23
|
+
/** Return a scoped previous-frame texture, or null. */ tryGetPrevious(name) {
|
|
61
24
|
return this._getScopedRead(name);
|
|
62
25
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Whether this manager is currently collecting imports/commits for a graph frame.
|
|
65
|
-
*/ get frameActive() {
|
|
26
|
+
/** Whether a history frame is active. */ get frameActive() {
|
|
66
27
|
return this._frameActive;
|
|
67
28
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Check whether a valid history resource exists and matches the descriptor.
|
|
70
|
-
*
|
|
71
|
-
* @param name - Name of the history resource.
|
|
72
|
-
* @param desc - Expected texture descriptor.
|
|
73
|
-
* @param size - Expected resolved size.
|
|
74
|
-
* @returns True if the resource exists, is valid, and matches.
|
|
75
|
-
*/ isCompatible(name, desc, size) {
|
|
29
|
+
/** Check for valid history matching the descriptor and size. */ isCompatible(name, desc, size) {
|
|
76
30
|
const resource = this._resources.get(name);
|
|
77
31
|
return !!resource?.valid && this._matches(resource, desc, size);
|
|
78
32
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Start collecting graph imports and deferred commits for a new frame.
|
|
81
|
-
*/ beginFrame() {
|
|
33
|
+
/** Begin collecting imports and commits for a frame. */ beginFrame() {
|
|
82
34
|
this.discardFrame();
|
|
83
35
|
this._pendingImports.clear();
|
|
84
36
|
this._readScopeStack.length = 0;
|
|
85
37
|
this._frameActive = true;
|
|
86
38
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Import the latest committed texture for a history resource into the graph.
|
|
89
|
-
*
|
|
90
|
-
* Returns null when the resource has no valid previous frame.
|
|
91
|
-
*
|
|
92
|
-
* @param graph - Render graph to import into.
|
|
93
|
-
* @param name - History resource name.
|
|
94
|
-
* @returns Imported graph handle, or null when no valid previous texture exists.
|
|
95
|
-
*/ importPrevious(graph, name) {
|
|
39
|
+
/** Import the latest history texture, or return null when unavailable. */ importPrevious(graph, name) {
|
|
96
40
|
const resource = this._resources.get(name);
|
|
97
41
|
const texture = resource?.valid ? resource.textures[resource.currentIndex] : null;
|
|
98
42
|
if (!texture) {
|
|
@@ -103,60 +47,36 @@
|
|
|
103
47
|
return handle;
|
|
104
48
|
}
|
|
105
49
|
/**
|
|
106
|
-
* Import the latest
|
|
107
|
-
*
|
|
108
|
-
* This is the preferred API for effects that can declare their history reads
|
|
109
|
-
* while building the graph: incompatible history is treated as absent, so the
|
|
110
|
-
* pass does not declare stale reads after resize or format changes.
|
|
111
|
-
*
|
|
112
|
-
* @param graph - Render graph to import into.
|
|
113
|
-
* @param name - History resource name.
|
|
114
|
-
* @param desc - Expected texture descriptor.
|
|
115
|
-
* @param size - Expected resolved size.
|
|
116
|
-
* @returns Imported graph handle, or null when no compatible history exists.
|
|
50
|
+
* Import the latest history only when its descriptor and size match.
|
|
117
51
|
*/ importPreviousIfCompatible(graph, name, desc, size) {
|
|
118
52
|
return this.isCompatible(name, desc, size) ? this.importPrevious(graph, name) : null;
|
|
119
53
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Bind all history imports created for this frame to the executor.
|
|
122
|
-
*
|
|
123
|
-
* @param executor - Render graph executor for the current frame.
|
|
124
|
-
*/ bindImportedTextures(executor) {
|
|
54
|
+
/** Bind this frame's history imports to an executor. */ bindImportedTextures(executor) {
|
|
125
55
|
for (const [handle, texture] of this._pendingImports){
|
|
126
56
|
executor.setImportedTexture(handle, texture);
|
|
127
57
|
}
|
|
128
58
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Make resolved history textures available to code executing inside a pass.
|
|
131
|
-
*
|
|
132
|
-
* @param bindings - History name to resolved texture bindings.
|
|
133
|
-
*/ beginReadScope(bindings) {
|
|
59
|
+
/** Push a history read scope for pass execution. */ beginReadScope(bindings) {
|
|
134
60
|
const scope = new Map();
|
|
135
61
|
for (const binding of bindings){
|
|
136
62
|
scope.set(binding.name, binding.texture);
|
|
137
63
|
}
|
|
138
64
|
this._readScopeStack.push(scope);
|
|
139
65
|
}
|
|
140
|
-
/**
|
|
141
|
-
* End the most recent history read scope.
|
|
142
|
-
*/ endReadScope() {
|
|
66
|
+
/** Pop the latest history read scope. */ endReadScope() {
|
|
143
67
|
this._readScopeStack.pop();
|
|
144
68
|
}
|
|
145
69
|
/**
|
|
146
|
-
* Queue
|
|
147
|
-
*
|
|
148
|
-
* The texture is committed only when {@link HistoryResourceManager.commitFrame} is called. If the
|
|
149
|
-
* frame fails, {@link HistoryResourceManager.discardFrame} releases owned pending textures instead.
|
|
150
|
-
*
|
|
151
|
-
* @param name - History resource name.
|
|
152
|
-
* @param desc - Texture descriptor.
|
|
153
|
-
* @param size - Resolved texture size.
|
|
154
|
-
* @param texture - Texture produced by the current frame.
|
|
155
|
-
* @param ownsTexture - Whether this manager should release the texture later.
|
|
70
|
+
* Queue the next history texture. It becomes visible on `commitFrame`; owned
|
|
71
|
+
* textures are released on `discardFrame`.
|
|
156
72
|
*/ queueCommit(name, desc, size, texture, ownsTexture = true) {
|
|
73
|
+
if (!this._frameActive) {
|
|
74
|
+
throw new Error(`HistoryResourceManager: cannot queue history commit '${name}' outside an active frame. ` + `Call beginFrame() first.`);
|
|
75
|
+
}
|
|
157
76
|
const existing = this._pendingCommits.get(name);
|
|
158
|
-
if (existing?.ownsTexture) {
|
|
159
|
-
|
|
77
|
+
if (existing?.ownsTexture && existing.texture !== texture) {
|
|
78
|
+
// Re-queuing the same texture keeps its existing reference.
|
|
79
|
+
this._deferredReleases.push(existing.texture);
|
|
160
80
|
}
|
|
161
81
|
this._pendingCommits.set(name, {
|
|
162
82
|
desc: {
|
|
@@ -170,44 +90,20 @@
|
|
|
170
90
|
});
|
|
171
91
|
}
|
|
172
92
|
/**
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* The allocator must retain the texture before the graph executor releases its
|
|
176
|
-
* transient reference. Use this from inside the pass that declares access to
|
|
177
|
-
* the handle being committed.
|
|
178
|
-
*
|
|
179
|
-
* @param name - History resource name.
|
|
180
|
-
* @param desc - Texture descriptor.
|
|
181
|
-
* @param size - Resolved texture size.
|
|
182
|
-
* @param ctx - Current render graph execute context.
|
|
183
|
-
* @param handle - Graph texture handle to commit.
|
|
184
|
-
* @returns The retained texture.
|
|
93
|
+
* Retain and queue a graph texture from its declaring pass.
|
|
185
94
|
*/ queueCommitFromGraph(name, desc, size, ctx, handle) {
|
|
186
95
|
const texture = ctx.getTexture(handle);
|
|
187
96
|
this.queueRetainedCommit(name, desc, size, texture);
|
|
188
97
|
return texture;
|
|
189
98
|
}
|
|
190
|
-
/**
|
|
191
|
-
* Queue a texture after retaining it through the allocator.
|
|
192
|
-
*
|
|
193
|
-
* Use this for textures produced by the graph allocator. The manager owns the
|
|
194
|
-
* retained reference and releases it when the history slot is overwritten,
|
|
195
|
-
* discarded, or disposed.
|
|
196
|
-
*
|
|
197
|
-
* @param name - History resource name.
|
|
198
|
-
* @param desc - Texture descriptor.
|
|
199
|
-
* @param size - Resolved texture size.
|
|
200
|
-
* @param texture - Texture to retain and commit.
|
|
201
|
-
*/ queueRetainedCommit(name, desc, size, texture) {
|
|
99
|
+
/** Retain a texture through the allocator and queue it as history. */ queueRetainedCommit(name, desc, size, texture) {
|
|
202
100
|
if (!this._allocator.retain) {
|
|
203
101
|
throw new Error(`HistoryResourceManager: cannot retain history resource '${name}'. ` + `The allocator does not support retained graph texture handoff.`);
|
|
204
102
|
}
|
|
205
103
|
this._allocator.retain(texture);
|
|
206
104
|
this.queueCommit(name, desc, size, texture, true);
|
|
207
105
|
}
|
|
208
|
-
/**
|
|
209
|
-
* Commit all current-frame history writes.
|
|
210
|
-
*/ commitFrame() {
|
|
106
|
+
/** Commit all pending history writes. */ commitFrame() {
|
|
211
107
|
for (const [name, pending] of this._pendingCommits){
|
|
212
108
|
let resource = this._resources.get(name);
|
|
213
109
|
if (resource && !this._matches(resource, pending.desc, pending.size)) {
|
|
@@ -253,10 +149,9 @@
|
|
|
253
149
|
this._pendingImports.clear();
|
|
254
150
|
this._readScopeStack.length = 0;
|
|
255
151
|
this._frameActive = false;
|
|
152
|
+
this._flushDeferredReleases();
|
|
256
153
|
}
|
|
257
|
-
/**
|
|
258
|
-
* Discard all uncommitted frame history writes.
|
|
259
|
-
*/ discardFrame() {
|
|
154
|
+
/** Discard all pending history writes. */ discardFrame() {
|
|
260
155
|
for (const pending of this._pendingCommits.values()){
|
|
261
156
|
if (pending.ownsTexture) {
|
|
262
157
|
this._allocator.release(pending.texture);
|
|
@@ -266,12 +161,50 @@
|
|
|
266
161
|
this._pendingImports.clear();
|
|
267
162
|
this._readScopeStack.length = 0;
|
|
268
163
|
this._frameActive = false;
|
|
164
|
+
this._flushDeferredReleases();
|
|
269
165
|
}
|
|
270
166
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*/
|
|
167
|
+
* Invalidate one named history resource without disturbing unrelated
|
|
168
|
+
* temporal effects. If called during a frame, owned textures are released
|
|
169
|
+
* after that frame so already-imported graph reads remain valid.
|
|
170
|
+
*/ invalidate(name) {
|
|
171
|
+
const pending = this._pendingCommits.get(name);
|
|
172
|
+
if (pending) {
|
|
173
|
+
if (pending.ownsTexture) {
|
|
174
|
+
if (this._frameActive) {
|
|
175
|
+
this._deferredReleases.push(pending.texture);
|
|
176
|
+
} else {
|
|
177
|
+
this._allocator.release(pending.texture);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
this._pendingCommits.delete(name);
|
|
181
|
+
}
|
|
182
|
+
const resource = this._resources.get(name);
|
|
183
|
+
if (!resource) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (this._frameActive) {
|
|
187
|
+
for(let i = 0; i < resource.textures.length; i++){
|
|
188
|
+
const texture = resource.textures[i];
|
|
189
|
+
if (texture && resource.ownsTexture[i]) {
|
|
190
|
+
this._deferredReleases.push(texture);
|
|
191
|
+
}
|
|
192
|
+
resource.textures[i] = null;
|
|
193
|
+
resource.ownsTexture[i] = false;
|
|
194
|
+
}
|
|
195
|
+
resource.valid = false;
|
|
196
|
+
} else {
|
|
197
|
+
this._releaseResource(resource);
|
|
198
|
+
}
|
|
199
|
+
this._resources.delete(name);
|
|
200
|
+
}
|
|
201
|
+
/** @internal */ _flushDeferredReleases() {
|
|
202
|
+
for (const texture of this._deferredReleases){
|
|
203
|
+
this._allocator.release(texture);
|
|
204
|
+
}
|
|
205
|
+
this._deferredReleases.length = 0;
|
|
206
|
+
}
|
|
207
|
+
/** Release all history resources. */ dispose() {
|
|
275
208
|
this.discardFrame();
|
|
276
209
|
for (const resource of this._resources.values()){
|
|
277
210
|
this._releaseResource(resource);
|
|
@@ -288,7 +221,8 @@
|
|
|
288
221
|
return null;
|
|
289
222
|
}
|
|
290
223
|
/** @internal */ _matches(resource, desc, size) {
|
|
291
|
-
return resource.desc.format === desc.format && (resource.desc.mipLevels ?? 1) === (desc.mipLevels ?? 1) &&
|
|
224
|
+
return resource.desc.format === desc.format && (resource.desc.mipLevels ?? 1) === (desc.mipLevels ?? 1) && // A 2D texture and a one-layer array are distinct types.
|
|
225
|
+
resource.desc.arrayLayers === desc.arrayLayers && resource.size.width === size.width && resource.size.height === size.height;
|
|
292
226
|
}
|
|
293
227
|
/** @internal */ _releaseResource(resource) {
|
|
294
228
|
this._releaseSlot(resource, 0);
|
|
@@ -300,8 +234,8 @@
|
|
|
300
234
|
if (!texture) {
|
|
301
235
|
return;
|
|
302
236
|
}
|
|
303
|
-
|
|
304
|
-
if (resource.ownsTexture[index]
|
|
237
|
+
// Each owning slot represents one retained reference.
|
|
238
|
+
if (resource.ownsTexture[index]) {
|
|
305
239
|
this._allocator.release(texture);
|
|
306
240
|
}
|
|
307
241
|
resource.textures[index] = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history_resource_manager.js","sources":["../../../src/render/rendergraph/history_resource_manager.ts"],"sourcesContent":["import type { Texture2D } from '@zephyr3d/device';\r\nimport type { RenderGraph } from './rendergraph';\r\nimport type { RenderGraphExecutor } from './executor';\r\nimport type { RGHandle, RGExecuteContext, RGTextureAllocator, RGTextureDesc, RGResolvedSize } from './types';\r\n\r\ninterface HistoryResource<TTexture> {\r\n desc: RGTextureDesc;\r\n size: RGResolvedSize;\r\n textures: [TTexture | null, TTexture | null];\r\n ownsTexture: [boolean, boolean];\r\n currentIndex: number;\r\n valid: boolean;\r\n}\r\n\r\ninterface PendingHistoryCommit<TTexture> {\r\n desc: RGTextureDesc;\r\n size: RGResolvedSize;\r\n texture: TTexture;\r\n ownsTexture: boolean;\r\n}\r\n\r\n/**\r\n * Manages cross-frame history resources that can be imported into a render graph.\r\n *\r\n * History resources are textures that persist across frames for temporal effects\r\n * like TAA, motion blur, or temporal upscaling. Previous-frame textures can be\r\n * imported into a {@link RenderGraph}, and current-frame textures are committed\r\n * only after graph execution succeeds.\r\n *\r\n * Usage:\r\n * ```ts\r\n * const historyMgr = new HistoryResourceManager(allocator);\r\n * historyMgr.beginFrame();\r\n * const prev = historyMgr.importPrevious(graph, 'taaColor');\r\n * // declare builder.read(prev) if non-null\r\n * historyMgr.bindImportedTextures(executor);\r\n * // after successful execution:\r\n * historyMgr.commitFrame();\r\n * ```\r\n *\r\n * @typeParam TTexture - The concrete texture type (e.g. `Texture2D`).\r\n * @public\r\n */\r\nexport class HistoryResourceManager<TTexture = Texture2D> {\r\n private _resources: Map<string, HistoryResource<TTexture>> = new Map();\r\n private _allocator: RGTextureAllocator<TTexture>;\r\n private _pendingImports: Map<RGHandle, TTexture> = new Map();\r\n private _pendingCommits: Map<string, PendingHistoryCommit<TTexture>> = new Map();\r\n private _readScopeStack: Array<Map<string, TTexture>> = [];\r\n private _frameActive = false;\r\n\r\n /**\r\n * Create a new history resource manager.\r\n *\r\n * @param allocator - Texture allocator for creating history textures.\r\n */\r\n constructor(allocator: RGTextureAllocator<TTexture>) {\r\n this._allocator = allocator;\r\n }\r\n\r\n /**\r\n * Get the previous-frame texture resolved by the current render graph pass.\r\n *\r\n * The resource must have been imported with {@link HistoryResourceManager.importPrevious} or\r\n * {@link HistoryResourceManager.importPreviousIfCompatible}, declared as a pass read, and bound with\r\n * {@link HistoryResourceManager.beginReadScope} before this method is called.\r\n *\r\n * @param name - Name of the history resource.\r\n * @returns The graph-resolved previous-frame texture.\r\n * @throws If no read scope is active for the resource.\r\n */\r\n getPrevious(name: string): TTexture {\r\n const scoped = this._getScopedRead(name);\r\n if (scoped) {\r\n return scoped;\r\n }\r\n throw new Error(\r\n `History resource '${name}' is not available in the current render graph read scope. ` +\r\n `Import it and declare a pass read before accessing it.`\r\n );\r\n }\r\n\r\n /**\r\n * Try to get a previous-frame texture from the current render graph read scope.\r\n *\r\n * Returns null when the resource was not imported for the current pass.\r\n *\r\n * @param name - Name of the history resource.\r\n * @returns The scoped previous-frame texture, or null.\r\n */\r\n tryGetPrevious(name: string): TTexture | null {\r\n return this._getScopedRead(name);\r\n }\r\n\r\n /**\r\n * Whether this manager is currently collecting imports/commits for a graph frame.\r\n */\r\n get frameActive(): boolean {\r\n return this._frameActive;\r\n }\r\n\r\n /**\r\n * Check whether a valid history resource exists and matches the descriptor.\r\n *\r\n * @param name - Name of the history resource.\r\n * @param desc - Expected texture descriptor.\r\n * @param size - Expected resolved size.\r\n * @returns True if the resource exists, is valid, and matches.\r\n */\r\n isCompatible(name: string, desc: RGTextureDesc, size: RGResolvedSize): boolean {\r\n const resource = this._resources.get(name);\r\n return !!resource?.valid && this._matches(resource, desc, size);\r\n }\r\n\r\n /**\r\n * Start collecting graph imports and deferred commits for a new frame.\r\n */\r\n beginFrame(): void {\r\n this.discardFrame();\r\n this._pendingImports.clear();\r\n this._readScopeStack.length = 0;\r\n this._frameActive = true;\r\n }\r\n\r\n /**\r\n * Import the latest committed texture for a history resource into the graph.\r\n *\r\n * Returns null when the resource has no valid previous frame.\r\n *\r\n * @param graph - Render graph to import into.\r\n * @param name - History resource name.\r\n * @returns Imported graph handle, or null when no valid previous texture exists.\r\n */\r\n importPrevious(graph: RenderGraph, name: string): RGHandle | null {\r\n const resource = this._resources.get(name);\r\n const texture = resource?.valid ? resource.textures[resource.currentIndex] : null;\r\n if (!texture) {\r\n return null;\r\n }\r\n const handle = graph.importTexture(`history:${name}:previous`);\r\n this._pendingImports.set(handle, texture);\r\n return handle;\r\n }\r\n\r\n /**\r\n * Import the latest committed texture only when it matches the expected shape.\r\n *\r\n * This is the preferred API for effects that can declare their history reads\r\n * while building the graph: incompatible history is treated as absent, so the\r\n * pass does not declare stale reads after resize or format changes.\r\n *\r\n * @param graph - Render graph to import into.\r\n * @param name - History resource name.\r\n * @param desc - Expected texture descriptor.\r\n * @param size - Expected resolved size.\r\n * @returns Imported graph handle, or null when no compatible history exists.\r\n */\r\n importPreviousIfCompatible(\r\n graph: RenderGraph,\r\n name: string,\r\n desc: RGTextureDesc,\r\n size: RGResolvedSize\r\n ): RGHandle | null {\r\n return this.isCompatible(name, desc, size) ? this.importPrevious(graph, name) : null;\r\n }\r\n\r\n /**\r\n * Bind all history imports created for this frame to the executor.\r\n *\r\n * @param executor - Render graph executor for the current frame.\r\n */\r\n bindImportedTextures(executor: Pick<RenderGraphExecutor<TTexture>, 'setImportedTexture'>): void {\r\n for (const [handle, texture] of this._pendingImports) {\r\n executor.setImportedTexture(handle, texture);\r\n }\r\n }\r\n\r\n /**\r\n * Make resolved history textures available to code executing inside a pass.\r\n *\r\n * @param bindings - History name to resolved texture bindings.\r\n */\r\n beginReadScope(bindings: Array<{ name: string; texture: TTexture }>): void {\r\n const scope = new Map<string, TTexture>();\r\n for (const binding of bindings) {\r\n scope.set(binding.name, binding.texture);\r\n }\r\n this._readScopeStack.push(scope);\r\n }\r\n\r\n /**\r\n * End the most recent history read scope.\r\n */\r\n endReadScope(): void {\r\n this._readScopeStack.pop();\r\n }\r\n\r\n /**\r\n * Queue a current-frame texture to become the next previous-frame history.\r\n *\r\n * The texture is committed only when {@link HistoryResourceManager.commitFrame} is called. If the\r\n * frame fails, {@link HistoryResourceManager.discardFrame} releases owned pending textures instead.\r\n *\r\n * @param name - History resource name.\r\n * @param desc - Texture descriptor.\r\n * @param size - Resolved texture size.\r\n * @param texture - Texture produced by the current frame.\r\n * @param ownsTexture - Whether this manager should release the texture later.\r\n */\r\n queueCommit(\r\n name: string,\r\n desc: RGTextureDesc,\r\n size: RGResolvedSize,\r\n texture: TTexture,\r\n ownsTexture = true\r\n ): void {\r\n const existing = this._pendingCommits.get(name);\r\n if (existing?.ownsTexture) {\r\n this._allocator.release(existing.texture);\r\n }\r\n this._pendingCommits.set(name, {\r\n desc: { ...desc },\r\n size: { ...size },\r\n texture,\r\n ownsTexture\r\n });\r\n }\r\n\r\n /**\r\n * Queue a graph-produced texture as a current-frame history write.\r\n *\r\n * The allocator must retain the texture before the graph executor releases its\r\n * transient reference. Use this from inside the pass that declares access to\r\n * the handle being committed.\r\n *\r\n * @param name - History resource name.\r\n * @param desc - Texture descriptor.\r\n * @param size - Resolved texture size.\r\n * @param ctx - Current render graph execute context.\r\n * @param handle - Graph texture handle to commit.\r\n * @returns The retained texture.\r\n */\r\n queueCommitFromGraph(\r\n name: string,\r\n desc: RGTextureDesc,\r\n size: RGResolvedSize,\r\n ctx: Pick<RGExecuteContext, 'getTexture'>,\r\n handle: RGHandle\r\n ): TTexture {\r\n const texture = ctx.getTexture<TTexture>(handle);\r\n this.queueRetainedCommit(name, desc, size, texture);\r\n return texture;\r\n }\r\n\r\n /**\r\n * Queue a texture after retaining it through the allocator.\r\n *\r\n * Use this for textures produced by the graph allocator. The manager owns the\r\n * retained reference and releases it when the history slot is overwritten,\r\n * discarded, or disposed.\r\n *\r\n * @param name - History resource name.\r\n * @param desc - Texture descriptor.\r\n * @param size - Resolved texture size.\r\n * @param texture - Texture to retain and commit.\r\n */\r\n queueRetainedCommit(name: string, desc: RGTextureDesc, size: RGResolvedSize, texture: TTexture): void {\r\n if (!this._allocator.retain) {\r\n throw new Error(\r\n `HistoryResourceManager: cannot retain history resource '${name}'. ` +\r\n `The allocator does not support retained graph texture handoff.`\r\n );\r\n }\r\n this._allocator.retain(texture);\r\n this.queueCommit(name, desc, size, texture, true);\r\n }\r\n\r\n /**\r\n * Commit all current-frame history writes.\r\n */\r\n commitFrame(): void {\r\n for (const [name, pending] of this._pendingCommits) {\r\n let resource = this._resources.get(name);\r\n if (resource && !this._matches(resource, pending.desc, pending.size)) {\r\n this._releaseResource(resource);\r\n this._resources.delete(name);\r\n resource = undefined;\r\n }\r\n if (!resource) {\r\n resource = {\r\n desc: { ...pending.desc },\r\n size: { ...pending.size },\r\n textures: [null, null],\r\n ownsTexture: [false, false],\r\n currentIndex: 0,\r\n valid: false\r\n };\r\n this._resources.set(name, resource);\r\n }\r\n\r\n const writeIndex = resource.valid ? 1 - resource.currentIndex : resource.currentIndex;\r\n this._releaseSlot(resource, writeIndex);\r\n resource.textures[writeIndex] = pending.texture;\r\n resource.ownsTexture[writeIndex] = pending.ownsTexture;\r\n resource.desc = { ...pending.desc };\r\n resource.size = { ...pending.size };\r\n resource.currentIndex = writeIndex;\r\n resource.valid = true;\r\n }\r\n this._pendingCommits.clear();\r\n this._pendingImports.clear();\r\n this._readScopeStack.length = 0;\r\n this._frameActive = false;\r\n }\r\n\r\n /**\r\n * Discard all uncommitted frame history writes.\r\n */\r\n discardFrame(): void {\r\n for (const pending of this._pendingCommits.values()) {\r\n if (pending.ownsTexture) {\r\n this._allocator.release(pending.texture);\r\n }\r\n }\r\n this._pendingCommits.clear();\r\n this._pendingImports.clear();\r\n this._readScopeStack.length = 0;\r\n this._frameActive = false;\r\n }\r\n\r\n /**\r\n * Release all history resources and clear the manager.\r\n *\r\n * Call this when disposing the render context or when history is no longer needed.\r\n */\r\n dispose(): void {\r\n this.discardFrame();\r\n for (const resource of this._resources.values()) {\r\n this._releaseResource(resource);\r\n }\r\n this._resources.clear();\r\n }\r\n\r\n /** @internal */\r\n private _getScopedRead(name: string): TTexture | null {\r\n for (let i = this._readScopeStack.length - 1; i >= 0; i--) {\r\n const texture = this._readScopeStack[i].get(name);\r\n if (texture) {\r\n return texture;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /** @internal */\r\n private _matches(resource: HistoryResource<TTexture>, desc: RGTextureDesc, size: RGResolvedSize): boolean {\r\n return (\r\n resource.desc.format === desc.format &&\r\n (resource.desc.mipLevels ?? 1) === (desc.mipLevels ?? 1) &&\r\n resource.size.width === size.width &&\r\n resource.size.height === size.height\r\n );\r\n }\r\n\r\n /** @internal */\r\n private _releaseResource(resource: HistoryResource<TTexture>): void {\r\n this._releaseSlot(resource, 0);\r\n this._releaseSlot(resource, 1);\r\n resource.valid = false;\r\n }\r\n\r\n /** @internal */\r\n private _releaseSlot(resource: HistoryResource<TTexture>, index: number): void {\r\n const texture = resource.textures[index];\r\n if (!texture) {\r\n return;\r\n }\r\n const otherIndex = 1 - index;\r\n if (resource.ownsTexture[index] && resource.textures[otherIndex] !== texture) {\r\n this._allocator.release(texture);\r\n }\r\n resource.textures[index] = null;\r\n resource.ownsTexture[index] = false;\r\n }\r\n}\r\n"],"names":["HistoryResourceManager","_resources","Map","_allocator","_pendingImports","_pendingCommits","_readScopeStack","_frameActive","allocator","getPrevious","name","scoped","_getScopedRead","Error","tryGetPrevious","frameActive","isCompatible","desc","size","resource","get","valid","_matches","beginFrame","discardFrame","clear","length","importPrevious","graph","texture","textures","currentIndex","handle","importTexture","set","importPreviousIfCompatible","bindImportedTextures","executor","setImportedTexture","beginReadScope","bindings","scope","binding","push","endReadScope","pop","queueCommit","ownsTexture","existing","release","queueCommitFromGraph","ctx","getTexture","queueRetainedCommit","retain","commitFrame","pending","_releaseResource","delete","undefined","writeIndex","_releaseSlot","values","dispose","i","format","mipLevels","width","height","index","otherIndex"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"history_resource_manager.js","sources":["../../../src/render/rendergraph/history_resource_manager.ts"],"sourcesContent":["import type { Texture2D } from '@zephyr3d/device';\r\nimport type { RenderGraph } from './rendergraph';\r\nimport type { RenderGraphExecutor } from './executor';\r\nimport type { RGHandle, RGExecuteContext, RGTextureAllocator, RGTextureDesc, RGResolvedSize } from './types';\r\n\r\ninterface HistoryResource<TTexture> {\r\n desc: RGTextureDesc;\r\n size: RGResolvedSize;\r\n textures: [TTexture | null, TTexture | null];\r\n ownsTexture: [boolean, boolean];\r\n currentIndex: number;\r\n valid: boolean;\r\n}\r\n\r\ninterface PendingHistoryCommit<TTexture> {\r\n desc: RGTextureDesc;\r\n size: RGResolvedSize;\r\n texture: TTexture;\r\n ownsTexture: boolean;\r\n}\r\n\r\n/** Manages render graph textures retained across frames. @public */\r\nexport class HistoryResourceManager<TTexture = Texture2D> {\r\n private _resources: Map<string, HistoryResource<TTexture>> = new Map();\r\n private _allocator: RGTextureAllocator<TTexture>;\r\n private _pendingImports: Map<RGHandle, TTexture> = new Map();\r\n private _pendingCommits: Map<string, PendingHistoryCommit<TTexture>> = new Map();\r\n private _readScopeStack: Array<Map<string, TTexture>> = [];\r\n private _frameActive = false;\r\n // Delay replaced commits until frame end to prevent pool reuse while queued.\r\n private _deferredReleases: TTexture[] = [];\r\n\r\n /** Create a history manager using the given allocator. */\r\n constructor(allocator: RGTextureAllocator<TTexture>) {\r\n this._allocator = allocator;\r\n }\r\n\r\n /**\r\n * Return a previous-frame texture from the active read scope.\r\n * @throws When the resource is not available in that scope.\r\n */\r\n getPrevious(name: string): TTexture {\r\n const scoped = this._getScopedRead(name);\r\n if (scoped) {\r\n return scoped;\r\n }\r\n throw new Error(\r\n `History resource '${name}' is not available in the current render graph read scope. ` +\r\n `Import it and declare a pass read before accessing it.`\r\n );\r\n }\r\n\r\n /** Return a scoped previous-frame texture, or null. */\r\n tryGetPrevious(name: string): TTexture | null {\r\n return this._getScopedRead(name);\r\n }\r\n\r\n /** Whether a history frame is active. */\r\n get frameActive(): boolean {\r\n return this._frameActive;\r\n }\r\n\r\n /** Check for valid history matching the descriptor and size. */\r\n isCompatible(name: string, desc: RGTextureDesc, size: RGResolvedSize): boolean {\r\n const resource = this._resources.get(name);\r\n return !!resource?.valid && this._matches(resource, desc, size);\r\n }\r\n\r\n /** Begin collecting imports and commits for a frame. */\r\n beginFrame(): void {\r\n this.discardFrame();\r\n this._pendingImports.clear();\r\n this._readScopeStack.length = 0;\r\n this._frameActive = true;\r\n }\r\n\r\n /** Import the latest history texture, or return null when unavailable. */\r\n importPrevious(graph: RenderGraph, name: string): RGHandle | null {\r\n const resource = this._resources.get(name);\r\n const texture = resource?.valid ? resource.textures[resource.currentIndex] : null;\r\n if (!texture) {\r\n return null;\r\n }\r\n const handle = graph.importTexture(`history:${name}:previous`);\r\n this._pendingImports.set(handle, texture);\r\n return handle;\r\n }\r\n\r\n /**\r\n * Import the latest history only when its descriptor and size match.\r\n */\r\n importPreviousIfCompatible(\r\n graph: RenderGraph,\r\n name: string,\r\n desc: RGTextureDesc,\r\n size: RGResolvedSize\r\n ): RGHandle | null {\r\n return this.isCompatible(name, desc, size) ? this.importPrevious(graph, name) : null;\r\n }\r\n\r\n /** Bind this frame's history imports to an executor. */\r\n bindImportedTextures(executor: Pick<RenderGraphExecutor<TTexture>, 'setImportedTexture'>): void {\r\n for (const [handle, texture] of this._pendingImports) {\r\n executor.setImportedTexture(handle, texture);\r\n }\r\n }\r\n\r\n /** Push a history read scope for pass execution. */\r\n beginReadScope(bindings: Array<{ name: string; texture: TTexture }>): void {\r\n const scope = new Map<string, TTexture>();\r\n for (const binding of bindings) {\r\n scope.set(binding.name, binding.texture);\r\n }\r\n this._readScopeStack.push(scope);\r\n }\r\n\r\n /** Pop the latest history read scope. */\r\n endReadScope(): void {\r\n this._readScopeStack.pop();\r\n }\r\n\r\n /**\r\n * Queue the next history texture. It becomes visible on `commitFrame`; owned\r\n * textures are released on `discardFrame`.\r\n */\r\n queueCommit(\r\n name: string,\r\n desc: RGTextureDesc,\r\n size: RGResolvedSize,\r\n texture: TTexture,\r\n ownsTexture = true\r\n ): void {\r\n if (!this._frameActive) {\r\n throw new Error(\r\n `HistoryResourceManager: cannot queue history commit '${name}' outside an active frame. ` +\r\n `Call beginFrame() first.`\r\n );\r\n }\r\n const existing = this._pendingCommits.get(name);\r\n if (existing?.ownsTexture && existing.texture !== texture) {\r\n // Re-queuing the same texture keeps its existing reference.\r\n this._deferredReleases.push(existing.texture);\r\n }\r\n this._pendingCommits.set(name, {\r\n desc: { ...desc },\r\n size: { ...size },\r\n texture,\r\n ownsTexture\r\n });\r\n }\r\n\r\n /**\r\n * Retain and queue a graph texture from its declaring pass.\r\n */\r\n queueCommitFromGraph(\r\n name: string,\r\n desc: RGTextureDesc,\r\n size: RGResolvedSize,\r\n ctx: Pick<RGExecuteContext, 'getTexture'>,\r\n handle: RGHandle\r\n ): TTexture {\r\n const texture = ctx.getTexture<TTexture>(handle);\r\n this.queueRetainedCommit(name, desc, size, texture);\r\n return texture;\r\n }\r\n\r\n /** Retain a texture through the allocator and queue it as history. */\r\n queueRetainedCommit(name: string, desc: RGTextureDesc, size: RGResolvedSize, texture: TTexture): void {\r\n if (!this._allocator.retain) {\r\n throw new Error(\r\n `HistoryResourceManager: cannot retain history resource '${name}'. ` +\r\n `The allocator does not support retained graph texture handoff.`\r\n );\r\n }\r\n this._allocator.retain(texture);\r\n this.queueCommit(name, desc, size, texture, true);\r\n }\r\n\r\n /** Commit all pending history writes. */\r\n commitFrame(): void {\r\n for (const [name, pending] of this._pendingCommits) {\r\n let resource = this._resources.get(name);\r\n if (resource && !this._matches(resource, pending.desc, pending.size)) {\r\n this._releaseResource(resource);\r\n this._resources.delete(name);\r\n resource = undefined;\r\n }\r\n if (!resource) {\r\n resource = {\r\n desc: { ...pending.desc },\r\n size: { ...pending.size },\r\n textures: [null, null],\r\n ownsTexture: [false, false],\r\n currentIndex: 0,\r\n valid: false\r\n };\r\n this._resources.set(name, resource);\r\n }\r\n\r\n const writeIndex = resource.valid ? 1 - resource.currentIndex : resource.currentIndex;\r\n this._releaseSlot(resource, writeIndex);\r\n resource.textures[writeIndex] = pending.texture;\r\n resource.ownsTexture[writeIndex] = pending.ownsTexture;\r\n resource.desc = { ...pending.desc };\r\n resource.size = { ...pending.size };\r\n resource.currentIndex = writeIndex;\r\n resource.valid = true;\r\n }\r\n this._pendingCommits.clear();\r\n this._pendingImports.clear();\r\n this._readScopeStack.length = 0;\r\n this._frameActive = false;\r\n this._flushDeferredReleases();\r\n }\r\n\r\n /** Discard all pending history writes. */\r\n discardFrame(): void {\r\n for (const pending of this._pendingCommits.values()) {\r\n if (pending.ownsTexture) {\r\n this._allocator.release(pending.texture);\r\n }\r\n }\r\n this._pendingCommits.clear();\r\n this._pendingImports.clear();\r\n this._readScopeStack.length = 0;\r\n this._frameActive = false;\r\n this._flushDeferredReleases();\r\n }\r\n\r\n /**\r\n * Invalidate one named history resource without disturbing unrelated\r\n * temporal effects. If called during a frame, owned textures are released\r\n * after that frame so already-imported graph reads remain valid.\r\n */\r\n invalidate(name: string): void {\r\n const pending = this._pendingCommits.get(name);\r\n if (pending) {\r\n if (pending.ownsTexture) {\r\n if (this._frameActive) {\r\n this._deferredReleases.push(pending.texture);\r\n } else {\r\n this._allocator.release(pending.texture);\r\n }\r\n }\r\n this._pendingCommits.delete(name);\r\n }\r\n const resource = this._resources.get(name);\r\n if (!resource) {\r\n return;\r\n }\r\n if (this._frameActive) {\r\n for (let i = 0; i < resource.textures.length; i++) {\r\n const texture = resource.textures[i];\r\n if (texture && resource.ownsTexture[i]) {\r\n this._deferredReleases.push(texture);\r\n }\r\n resource.textures[i] = null;\r\n resource.ownsTexture[i] = false;\r\n }\r\n resource.valid = false;\r\n } else {\r\n this._releaseResource(resource);\r\n }\r\n this._resources.delete(name);\r\n }\r\n\r\n /** @internal */\r\n private _flushDeferredReleases(): void {\r\n for (const texture of this._deferredReleases) {\r\n this._allocator.release(texture);\r\n }\r\n this._deferredReleases.length = 0;\r\n }\r\n\r\n /** Release all history resources. */\r\n dispose(): void {\r\n this.discardFrame();\r\n for (const resource of this._resources.values()) {\r\n this._releaseResource(resource);\r\n }\r\n this._resources.clear();\r\n }\r\n\r\n /** @internal */\r\n private _getScopedRead(name: string): TTexture | null {\r\n for (let i = this._readScopeStack.length - 1; i >= 0; i--) {\r\n const texture = this._readScopeStack[i].get(name);\r\n if (texture) {\r\n return texture;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /** @internal */\r\n private _matches(resource: HistoryResource<TTexture>, desc: RGTextureDesc, size: RGResolvedSize): boolean {\r\n return (\r\n resource.desc.format === desc.format &&\r\n (resource.desc.mipLevels ?? 1) === (desc.mipLevels ?? 1) &&\r\n // A 2D texture and a one-layer array are distinct types.\r\n resource.desc.arrayLayers === desc.arrayLayers &&\r\n resource.size.width === size.width &&\r\n resource.size.height === size.height\r\n );\r\n }\r\n\r\n /** @internal */\r\n private _releaseResource(resource: HistoryResource<TTexture>): void {\r\n this._releaseSlot(resource, 0);\r\n this._releaseSlot(resource, 1);\r\n resource.valid = false;\r\n }\r\n\r\n /** @internal */\r\n private _releaseSlot(resource: HistoryResource<TTexture>, index: number): void {\r\n const texture = resource.textures[index];\r\n if (!texture) {\r\n return;\r\n }\r\n // Each owning slot represents one retained reference.\r\n if (resource.ownsTexture[index]) {\r\n this._allocator.release(texture);\r\n }\r\n resource.textures[index] = null;\r\n resource.ownsTexture[index] = false;\r\n }\r\n}\r\n"],"names":["HistoryResourceManager","_resources","Map","_allocator","_pendingImports","_pendingCommits","_readScopeStack","_frameActive","_deferredReleases","allocator","getPrevious","name","scoped","_getScopedRead","Error","tryGetPrevious","frameActive","isCompatible","desc","size","resource","get","valid","_matches","beginFrame","discardFrame","clear","length","importPrevious","graph","texture","textures","currentIndex","handle","importTexture","set","importPreviousIfCompatible","bindImportedTextures","executor","setImportedTexture","beginReadScope","bindings","scope","binding","push","endReadScope","pop","queueCommit","ownsTexture","existing","queueCommitFromGraph","ctx","getTexture","queueRetainedCommit","retain","commitFrame","pending","_releaseResource","delete","undefined","writeIndex","_releaseSlot","_flushDeferredReleases","values","release","invalidate","i","dispose","format","mipLevels","arrayLayers","width","height","index"],"mappings":"AAqBA,qEACO,MAAMA,sBAAAA,CAAAA;AACHC,IAAAA,UAAAA,GAAqD,IAAIC,GAAM,EAAA;IAC/DC,UAAyC;AACzCC,IAAAA,eAAAA,GAA2C,IAAIF,GAAM,EAAA;AACrDG,IAAAA,eAAAA,GAA+D,IAAIH,GAAM,EAAA;AACzEI,IAAAA,eAAAA,GAAgD,EAAE;AAClDC,IAAAA,YAAAA,GAAe,KAAM;;AAErBC,IAAAA,iBAAAA,GAAgC,EAAE;+DAG1C,WAAYC,CAAAA,SAAuC,CAAE;QACnD,IAAI,CAACN,UAAU,GAAGM,SAAAA;AACpB;AAEA;;;MAIAC,WAAAA,CAAYC,IAAY,EAAY;AAClC,QAAA,MAAMC,MAAS,GAAA,IAAI,CAACC,cAAc,CAACF,IAAAA,CAAAA;AACnC,QAAA,IAAIC,MAAQ,EAAA;YACV,OAAOA,MAAAA;AACT;QACA,MAAM,IAAIE,KACR,CAAA,CAAC,kBAAkB,EAAEH,IAAK,CAAA,2DAA2D,CAAC,GACpF,CAAC,sDAAsD,CAAC,CAAA;AAE9D;4DAGAI,cAAeJ,CAAAA,IAAY,EAAmB;QAC5C,OAAO,IAAI,CAACE,cAAc,CAACF,IAAAA,CAAAA;AAC7B;8CAGA,IAAIK,WAAuB,GAAA;QACzB,OAAO,IAAI,CAACT,YAAY;AAC1B;AAEA,qEACAU,YAAaN,CAAAA,IAAY,EAAEO,IAAmB,EAAEC,IAAoB,EAAW;AAC7E,QAAA,MAAMC,WAAW,IAAI,CAACnB,UAAU,CAACoB,GAAG,CAACV,IAAAA,CAAAA;QACrC,OAAO,CAAC,CAACS,QAAUE,EAAAA,KAAAA,IAAS,IAAI,CAACC,QAAQ,CAACH,QAAAA,EAAUF,IAAMC,EAAAA,IAAAA,CAAAA;AAC5D;AAEA,6DACAK,UAAmB,GAAA;AACjB,QAAA,IAAI,CAACC,YAAY,EAAA;QACjB,IAAI,CAACrB,eAAe,CAACsB,KAAK,EAAA;AAC1B,QAAA,IAAI,CAACpB,eAAe,CAACqB,MAAM,GAAG,CAAA;QAC9B,IAAI,CAACpB,YAAY,GAAG,IAAA;AACtB;AAEA,+EACAqB,cAAAA,CAAeC,KAAkB,EAAElB,IAAY,EAAmB;AAChE,QAAA,MAAMS,WAAW,IAAI,CAACnB,UAAU,CAACoB,GAAG,CAACV,IAAAA,CAAAA;QACrC,MAAMmB,OAAAA,GAAUV,UAAUE,KAAQF,GAAAA,QAAAA,CAASW,QAAQ,CAACX,QAAAA,CAASY,YAAY,CAAC,GAAG,IAAA;AAC7E,QAAA,IAAI,CAACF,OAAS,EAAA;YACZ,OAAO,IAAA;AACT;QACA,MAAMG,MAAAA,GAASJ,MAAMK,aAAa,CAAC,CAAC,QAAQ,EAAEvB,IAAK,CAAA,SAAS,CAAC,CAAA;AAC7D,QAAA,IAAI,CAACP,eAAe,CAAC+B,GAAG,CAACF,MAAQH,EAAAA,OAAAA,CAAAA;QACjC,OAAOG,MAAAA;AACT;AAEA;;MAGAG,0BAAAA,CACEP,KAAkB,EAClBlB,IAAY,EACZO,IAAmB,EACnBC,IAAoB,EACH;AACjB,QAAA,OAAO,IAAI,CAACF,YAAY,CAACN,IAAMO,EAAAA,IAAAA,EAAMC,IAAQ,CAAA,GAAA,IAAI,CAACS,cAAc,CAACC,KAAAA,EAAOlB,IAAQ,CAAA,GAAA,IAAA;AAClF;6DAGA0B,oBAAqBC,CAAAA,QAAmE,EAAQ;QAC9F,KAAK,MAAM,CAACL,MAAQH,EAAAA,OAAAA,CAAQ,IAAI,IAAI,CAAC1B,eAAe,CAAE;YACpDkC,QAASC,CAAAA,kBAAkB,CAACN,MAAQH,EAAAA,OAAAA,CAAAA;AACtC;AACF;yDAGAU,cAAeC,CAAAA,QAAoD,EAAQ;AACzE,QAAA,MAAMC,QAAQ,IAAIxC,GAAAA,EAAAA;QAClB,KAAK,MAAMyC,WAAWF,QAAU,CAAA;AAC9BC,YAAAA,KAAAA,CAAMP,GAAG,CAACQ,OAAAA,CAAQhC,IAAI,EAAEgC,QAAQb,OAAO,CAAA;AACzC;AACA,QAAA,IAAI,CAACxB,eAAe,CAACsC,IAAI,CAACF,KAAAA,CAAAA;AAC5B;AAEA,8CACAG,YAAqB,GAAA;QACnB,IAAI,CAACvC,eAAe,CAACwC,GAAG,EAAA;AAC1B;AAEA;;;MAIAC,WAAAA,CACEpC,IAAY,EACZO,IAAmB,EACnBC,IAAoB,EACpBW,OAAiB,EACjBkB,WAAc,GAAA,IAAI,EACZ;AACN,QAAA,IAAI,CAAC,IAAI,CAACzC,YAAY,EAAE;YACtB,MAAM,IAAIO,KACR,CAAA,CAAC,qDAAqD,EAAEH,IAAK,CAAA,2BAA2B,CAAC,GACvF,CAAC,wBAAwB,CAAC,CAAA;AAEhC;AACA,QAAA,MAAMsC,WAAW,IAAI,CAAC5C,eAAe,CAACgB,GAAG,CAACV,IAAAA,CAAAA;AAC1C,QAAA,IAAIsC,QAAUD,EAAAA,WAAAA,IAAeC,QAASnB,CAAAA,OAAO,KAAKA,OAAS,EAAA;;AAEzD,YAAA,IAAI,CAACtB,iBAAiB,CAACoC,IAAI,CAACK,SAASnB,OAAO,CAAA;AAC9C;AACA,QAAA,IAAI,CAACzB,eAAe,CAAC8B,GAAG,CAACxB,IAAM,EAAA;YAC7BO,IAAM,EAAA;AAAE,gBAAA,GAAGA;AAAK,aAAA;YAChBC,IAAM,EAAA;AAAE,gBAAA,GAAGA;AAAK,aAAA;AAChBW,YAAAA,OAAAA;AACAkB,YAAAA;AACF,SAAA,CAAA;AACF;AAEA;;MAGAE,oBAAAA,CACEvC,IAAY,EACZO,IAAmB,EACnBC,IAAoB,EACpBgC,GAAyC,EACzClB,MAAgB,EACN;QACV,MAAMH,OAAAA,GAAUqB,GAAIC,CAAAA,UAAU,CAAWnB,MAAAA,CAAAA;AACzC,QAAA,IAAI,CAACoB,mBAAmB,CAAC1C,IAAAA,EAAMO,MAAMC,IAAMW,EAAAA,OAAAA,CAAAA;QAC3C,OAAOA,OAAAA;AACT;2EAGAuB,oBAAoB1C,IAAY,EAAEO,IAAmB,EAAEC,IAAoB,EAAEW,OAAiB,EAAQ;AACpG,QAAA,IAAI,CAAC,IAAI,CAAC3B,UAAU,CAACmD,MAAM,EAAE;YAC3B,MAAM,IAAIxC,KACR,CAAA,CAAC,wDAAwD,EAAEH,IAAK,CAAA,GAAG,CAAC,GAClE,CAAC,8DAA8D,CAAC,CAAA;AAEtE;AACA,QAAA,IAAI,CAACR,UAAU,CAACmD,MAAM,CAACxB,OAAAA,CAAAA;AACvB,QAAA,IAAI,CAACiB,WAAW,CAACpC,IAAMO,EAAAA,IAAAA,EAAMC,MAAMW,OAAS,EAAA,IAAA,CAAA;AAC9C;AAEA,8CACAyB,WAAoB,GAAA;QAClB,KAAK,MAAM,CAAC5C,IAAM6C,EAAAA,OAAAA,CAAQ,IAAI,IAAI,CAACnD,eAAe,CAAE;AAClD,YAAA,IAAIe,WAAW,IAAI,CAACnB,UAAU,CAACoB,GAAG,CAACV,IAAAA,CAAAA;AACnC,YAAA,IAAIS,QAAY,IAAA,CAAC,IAAI,CAACG,QAAQ,CAACH,QAAUoC,EAAAA,OAAAA,CAAQtC,IAAI,EAAEsC,OAAQrC,CAAAA,IAAI,CAAG,EAAA;gBACpE,IAAI,CAACsC,gBAAgB,CAACrC,QAAAA,CAAAA;AACtB,gBAAA,IAAI,CAACnB,UAAU,CAACyD,MAAM,CAAC/C,IAAAA,CAAAA;gBACvBS,QAAWuC,GAAAA,SAAAA;AACb;AACA,YAAA,IAAI,CAACvC,QAAU,EAAA;gBACbA,QAAW,GAAA;oBACTF,IAAM,EAAA;AAAE,wBAAA,GAAGsC,QAAQtC;AAAK,qBAAA;oBACxBC,IAAM,EAAA;AAAE,wBAAA,GAAGqC,QAAQrC;AAAK,qBAAA;oBACxBY,QAAU,EAAA;AAAC,wBAAA,IAAA;AAAM,wBAAA;AAAK,qBAAA;oBACtBiB,WAAa,EAAA;AAAC,wBAAA,KAAA;AAAO,wBAAA;AAAM,qBAAA;oBAC3BhB,YAAc,EAAA,CAAA;oBACdV,KAAO,EAAA;AACT,iBAAA;AACA,gBAAA,IAAI,CAACrB,UAAU,CAACkC,GAAG,CAACxB,IAAMS,EAAAA,QAAAA,CAAAA;AAC5B;YAEA,MAAMwC,UAAAA,GAAaxC,SAASE,KAAK,GAAG,IAAIF,QAASY,CAAAA,YAAY,GAAGZ,QAAAA,CAASY,YAAY;YACrF,IAAI,CAAC6B,YAAY,CAACzC,QAAUwC,EAAAA,UAAAA,CAAAA;AAC5BxC,YAAAA,QAAAA,CAASW,QAAQ,CAAC6B,UAAW,CAAA,GAAGJ,QAAQ1B,OAAO;AAC/CV,YAAAA,QAAAA,CAAS4B,WAAW,CAACY,UAAW,CAAA,GAAGJ,QAAQR,WAAW;AACtD5B,YAAAA,QAAAA,CAASF,IAAI,GAAG;AAAE,gBAAA,GAAGsC,QAAQtC;AAAK,aAAA;AAClCE,YAAAA,QAAAA,CAASD,IAAI,GAAG;AAAE,gBAAA,GAAGqC,QAAQrC;AAAK,aAAA;AAClCC,YAAAA,QAAAA,CAASY,YAAY,GAAG4B,UAAAA;AACxBxC,YAAAA,QAAAA,CAASE,KAAK,GAAG,IAAA;AACnB;QACA,IAAI,CAACjB,eAAe,CAACqB,KAAK,EAAA;QAC1B,IAAI,CAACtB,eAAe,CAACsB,KAAK,EAAA;AAC1B,QAAA,IAAI,CAACpB,eAAe,CAACqB,MAAM,GAAG,CAAA;QAC9B,IAAI,CAACpB,YAAY,GAAG,KAAA;AACpB,QAAA,IAAI,CAACuD,sBAAsB,EAAA;AAC7B;AAEA,+CACArC,YAAqB,GAAA;AACnB,QAAA,KAAK,MAAM+B,OAAW,IAAA,IAAI,CAACnD,eAAe,CAAC0D,MAAM,EAAI,CAAA;YACnD,IAAIP,OAAAA,CAAQR,WAAW,EAAE;AACvB,gBAAA,IAAI,CAAC7C,UAAU,CAAC6D,OAAO,CAACR,QAAQ1B,OAAO,CAAA;AACzC;AACF;QACA,IAAI,CAACzB,eAAe,CAACqB,KAAK,EAAA;QAC1B,IAAI,CAACtB,eAAe,CAACsB,KAAK,EAAA;AAC1B,QAAA,IAAI,CAACpB,eAAe,CAACqB,MAAM,GAAG,CAAA;QAC9B,IAAI,CAACpB,YAAY,GAAG,KAAA;AACpB,QAAA,IAAI,CAACuD,sBAAsB,EAAA;AAC7B;AAEA;;;;MAKAG,UAAAA,CAAWtD,IAAY,EAAQ;AAC7B,QAAA,MAAM6C,UAAU,IAAI,CAACnD,eAAe,CAACgB,GAAG,CAACV,IAAAA,CAAAA;AACzC,QAAA,IAAI6C,OAAS,EAAA;YACX,IAAIA,OAAAA,CAAQR,WAAW,EAAE;gBACvB,IAAI,IAAI,CAACzC,YAAY,EAAE;AACrB,oBAAA,IAAI,CAACC,iBAAiB,CAACoC,IAAI,CAACY,QAAQ1B,OAAO,CAAA;iBACtC,MAAA;AACL,oBAAA,IAAI,CAAC3B,UAAU,CAAC6D,OAAO,CAACR,QAAQ1B,OAAO,CAAA;AACzC;AACF;AACA,YAAA,IAAI,CAACzB,eAAe,CAACqD,MAAM,CAAC/C,IAAAA,CAAAA;AAC9B;AACA,QAAA,MAAMS,WAAW,IAAI,CAACnB,UAAU,CAACoB,GAAG,CAACV,IAAAA,CAAAA;AACrC,QAAA,IAAI,CAACS,QAAU,EAAA;AACb,YAAA;AACF;QACA,IAAI,IAAI,CAACb,YAAY,EAAE;YACrB,IAAK,IAAI2D,IAAI,CAAGA,EAAAA,CAAAA,GAAI9C,SAASW,QAAQ,CAACJ,MAAM,EAAEuC,CAAK,EAAA,CAAA;AACjD,gBAAA,MAAMpC,OAAUV,GAAAA,QAAAA,CAASW,QAAQ,CAACmC,CAAE,CAAA;AACpC,gBAAA,IAAIpC,OAAWV,IAAAA,QAAAA,CAAS4B,WAAW,CAACkB,EAAE,EAAE;AACtC,oBAAA,IAAI,CAAC1D,iBAAiB,CAACoC,IAAI,CAACd,OAAAA,CAAAA;AAC9B;gBACAV,QAASW,CAAAA,QAAQ,CAACmC,CAAAA,CAAE,GAAG,IAAA;gBACvB9C,QAAS4B,CAAAA,WAAW,CAACkB,CAAAA,CAAE,GAAG,KAAA;AAC5B;AACA9C,YAAAA,QAAAA,CAASE,KAAK,GAAG,KAAA;SACZ,MAAA;YACL,IAAI,CAACmC,gBAAgB,CAACrC,QAAAA,CAAAA;AACxB;AACA,QAAA,IAAI,CAACnB,UAAU,CAACyD,MAAM,CAAC/C,IAAAA,CAAAA;AACzB;qBAGA,sBAAuC,GAAA;AACrC,QAAA,KAAK,MAAMmB,OAAAA,IAAW,IAAI,CAACtB,iBAAiB,CAAE;AAC5C,YAAA,IAAI,CAACL,UAAU,CAAC6D,OAAO,CAAClC,OAAAA,CAAAA;AAC1B;AACA,QAAA,IAAI,CAACtB,iBAAiB,CAACmB,MAAM,GAAG,CAAA;AAClC;AAEA,0CACAwC,OAAgB,GAAA;AACd,QAAA,IAAI,CAAC1C,YAAY,EAAA;AACjB,QAAA,KAAK,MAAML,QAAY,IAAA,IAAI,CAACnB,UAAU,CAAC8D,MAAM,EAAI,CAAA;YAC/C,IAAI,CAACN,gBAAgB,CAACrC,QAAAA,CAAAA;AACxB;QACA,IAAI,CAACnB,UAAU,CAACyB,KAAK,EAAA;AACvB;AAEA,qBACQb,cAAeF,CAAAA,IAAY,EAAmB;QACpD,IAAK,IAAIuD,CAAI,GAAA,IAAI,CAAC5D,eAAe,CAACqB,MAAM,GAAG,CAAA,EAAGuC,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;YACzD,MAAMpC,OAAAA,GAAU,IAAI,CAACxB,eAAe,CAAC4D,CAAE,CAAA,CAAC7C,GAAG,CAACV,IAAAA,CAAAA;AAC5C,YAAA,IAAImB,OAAS,EAAA;gBACX,OAAOA,OAAAA;AACT;AACF;QACA,OAAO,IAAA;AACT;qBAGA,QAAiBV,CAAAA,QAAmC,EAAEF,IAAmB,EAAEC,IAAoB,EAAW;QACxG,OACEC,QAAAA,CAASF,IAAI,CAACkD,MAAM,KAAKlD,IAAKkD,CAAAA,MAAM,IACnChD,CAAAA,QAAAA,CAASF,IAAI,CAACmD,SAAS,IAAI,CAAA,OAAQnD,KAAKmD,SAAS,IAAI,CAAA,CAAA;QAEtDjD,QAASF,CAAAA,IAAI,CAACoD,WAAW,KAAKpD,KAAKoD,WAAW,IAC9ClD,SAASD,IAAI,CAACoD,KAAK,KAAKpD,IAAAA,CAAKoD,KAAK,IAClCnD,QAAAA,CAASD,IAAI,CAACqD,MAAM,KAAKrD,IAAAA,CAAKqD,MAAM;AAExC;AAEA,qBACQf,gBAAiBrC,CAAAA,QAAmC,EAAQ;QAClE,IAAI,CAACyC,YAAY,CAACzC,QAAU,EAAA,CAAA,CAAA;QAC5B,IAAI,CAACyC,YAAY,CAACzC,QAAU,EAAA,CAAA,CAAA;AAC5BA,QAAAA,QAAAA,CAASE,KAAK,GAAG,KAAA;AACnB;AAEA,qBACA,YAAQuC,CAAazC,QAAmC,EAAEqD,KAAa,EAAQ;AAC7E,QAAA,MAAM3C,OAAUV,GAAAA,QAAAA,CAASW,QAAQ,CAAC0C,KAAM,CAAA;AACxC,QAAA,IAAI,CAAC3C,OAAS,EAAA;AACZ,YAAA;AACF;;AAEA,QAAA,IAAIV,QAAS4B,CAAAA,WAAW,CAACyB,KAAAA,CAAM,EAAE;AAC/B,YAAA,IAAI,CAACtE,UAAU,CAAC6D,OAAO,CAAClC,OAAAA,CAAAA;AAC1B;QACAV,QAASW,CAAAA,QAAQ,CAAC0C,KAAAA,CAAM,GAAG,IAAA;QAC3BrD,QAAS4B,CAAAA,WAAW,CAACyB,KAAAA,CAAM,GAAG,KAAA;AAChC;AACF;;;;"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resource names for render graph history resources.
|
|
3
|
-
* @public
|
|
4
|
-
*/ const RGHistoryResources = {
|
|
1
|
+
/** Render graph history resource names. @public */ const RGHistoryResources = {
|
|
5
2
|
TAA_COLOR: 'taaColor',
|
|
6
3
|
TAA_MOTION_VECTOR: 'taaMotionVector',
|
|
7
4
|
SSR_REFLECT: 'ssrReflect',
|
|
8
|
-
SSR_MOTION_VECTOR: 'ssrMotionVector'
|
|
5
|
+
SSR_MOTION_VECTOR: 'ssrMotionVector',
|
|
6
|
+
/** Opaque linear-HDR scene color sampled by SSGI rays on the next frame. */ SSGI_SCENE_COLOR: 'ssgiSceneColor',
|
|
7
|
+
/** Denoised diffuse irradiance reprojected into the next frame's lighting pass. */ SSGI_IRRADIANCE: 'ssgiIrradiance',
|
|
8
|
+
/** Depth/normal surface data used to validate SSGI reprojection. */ SSGI_SURFACE: 'ssgiSurface',
|
|
9
|
+
/** First and second luminance moments used by the SSGI temporal filter. */ SSGI_MOMENTS: 'ssgiMoments',
|
|
10
|
+
/** Temporally accumulated screen space ambient occlusion traced alongside SSGI. */ SSGI_AO: 'ssgiAO'
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
export { RGHistoryResources };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history_resources.js","sources":["../../../src/render/rendergraph/history_resources.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"history_resources.js","sources":["../../../src/render/rendergraph/history_resources.ts"],"sourcesContent":["/** Render graph history resource names. @public */\r\nexport const RGHistoryResources = {\r\n TAA_COLOR: 'taaColor',\r\n TAA_MOTION_VECTOR: 'taaMotionVector',\r\n SSR_REFLECT: 'ssrReflect',\r\n SSR_MOTION_VECTOR: 'ssrMotionVector',\r\n /** Opaque linear-HDR scene color sampled by SSGI rays on the next frame. */\r\n SSGI_SCENE_COLOR: 'ssgiSceneColor',\r\n /** Denoised diffuse irradiance reprojected into the next frame's lighting pass. */\r\n SSGI_IRRADIANCE: 'ssgiIrradiance',\r\n /** Depth/normal surface data used to validate SSGI reprojection. */\r\n SSGI_SURFACE: 'ssgiSurface',\r\n /** First and second luminance moments used by the SSGI temporal filter. */\r\n SSGI_MOMENTS: 'ssgiMoments',\r\n /** Temporally accumulated screen space ambient occlusion traced alongside SSGI. */\r\n SSGI_AO: 'ssgiAO'\r\n} as const;\r\n"],"names":["RGHistoryResources","TAA_COLOR","TAA_MOTION_VECTOR","SSR_REFLECT","SSR_MOTION_VECTOR","SSGI_SCENE_COLOR","SSGI_IRRADIANCE","SSGI_SURFACE","SSGI_MOMENTS","SSGI_AO"],"mappings":"AAAA,oDACO,MAAMA,kBAAqB,GAAA;IAChCC,SAAW,EAAA,UAAA;IACXC,iBAAmB,EAAA,iBAAA;IACnBC,WAAa,EAAA,YAAA;IACbC,iBAAmB,EAAA,iBAAA;AACnB,iFACAC,gBAAkB,EAAA,gBAAA;AAClB,wFACAC,eAAiB,EAAA,gBAAA;AACjB,yEACAC,YAAc,EAAA,aAAA;AACd,gFACAC,YAAc,EAAA,aAAA;AACd,wFACAC,OAAS,EAAA;AACX;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Orders side-effect passes through logical tokens. @public */ class OrderingScope {
|
|
2
|
+
/** @internal */ _last = null;
|
|
3
|
+
/** Order the current pass after the latest token, if any. */ chainInto(builder) {
|
|
4
|
+
if (this._last) {
|
|
5
|
+
builder.read(this._last);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/** Emit and record a new ordering token. */ emit(builder, name) {
|
|
9
|
+
const token = builder.createToken(name);
|
|
10
|
+
this._last = token;
|
|
11
|
+
return token;
|
|
12
|
+
}
|
|
13
|
+
/** The most recently emitted ordering token, or null. */ get last() {
|
|
14
|
+
return this._last;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { OrderingScope };
|
|
19
|
+
//# sourceMappingURL=render_context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render_context.js","sources":["../../../src/render/rendergraph/render_context.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport type { FrameBuffer, Texture2D } from '@zephyr3d/device';\r\nimport type { RGHandle, RGPassBuilder } from './types';\r\nimport type { RenderGraph } from './rendergraph';\r\nimport type { RGBlackboard } from './blackboard';\r\nimport type { HistoryResourceManager } from './history_resource_manager';\r\nimport type { RenderQueue } from '../render_queue';\r\n\r\n/** Orders side-effect passes through logical tokens. @public */\r\nexport class OrderingScope {\r\n /** @internal */\r\n private _last: Nullable<RGHandle> = null;\r\n\r\n /** Order the current pass after the latest token, if any. */\r\n chainInto(builder: RGPassBuilder): void {\r\n if (this._last) {\r\n builder.read(this._last);\r\n }\r\n }\r\n\r\n /** Emit and record a new ordering token. */\r\n emit(builder: RGPassBuilder, name: string): RGHandle {\r\n const token = builder.createToken(name);\r\n this._last = token;\r\n return token;\r\n }\r\n\r\n /** The most recently emitted ordering token, or null. */\r\n get last(): Nullable<RGHandle> {\r\n return this._last;\r\n }\r\n}\r\n\r\n/** Pipeline-independent context used while building graph modules. @public */\r\nexport interface RenderContext {\r\n /** The external framebuffer presented by this frame, or null for the screen. */\r\n readonly finalFramebuffer: FrameBuffer | null;\r\n /** The render graph being populated for this frame. */\r\n readonly graph: RenderGraph;\r\n /** The culled render queue for this frame. */\r\n readonly renderQueue: RenderQueue;\r\n /** Named registry of shared frame-resource handles (see {@link ./blackboard#FrameResources}). */\r\n readonly blackboard: RGBlackboard;\r\n /** Cross-frame history resource manager, or null when unavailable. */\r\n readonly history: Nullable<HistoryResourceManager<Texture2D>>;\r\n /** Ordering-token chain for side-effect passes. */\r\n readonly ordering: OrderingScope;\r\n /** The imported backbuffer handle (graph sink). */\r\n readonly backbuffer: RGHandle;\r\n}\r\n"],"names":["OrderingScope","_last","chainInto","builder","read","emit","name","token","createToken","last"],"mappings":"AAQA,iEACO,MAAMA,aAAAA,CAAAA;qBAEX,KAAQC,GAA4B,IAAK;kEAGzCC,SAAUC,CAAAA,OAAsB,EAAQ;QACtC,IAAI,IAAI,CAACF,KAAK,EAAE;AACdE,YAAAA,OAAAA,CAAQC,IAAI,CAAC,IAAI,CAACH,KAAK,CAAA;AACzB;AACF;AAEA,iDACAI,IAAAA,CAAKF,OAAsB,EAAEG,IAAY,EAAY;QACnD,MAAMC,KAAAA,GAAQJ,OAAQK,CAAAA,WAAW,CAACF,IAAAA,CAAAA;QAClC,IAAI,CAACL,KAAK,GAAGM,KAAAA;QACb,OAAOA,KAAAA;AACT;8DAGA,IAAIE,IAA2B,GAAA;QAC7B,OAAO,IAAI,CAACR,KAAK;AACnB;AACF;;;;"}
|