@woosh/meep-engine 3.16.0 → 3.17.0
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/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
- package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
- package/editor/particles/effect/ParticleEffectDocument.js +38 -17
- package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
- package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
- package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
- package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
- package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
- package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphView.js +84 -8
- package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
- package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
- package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
- package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
- package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
- package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
- package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
- package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
- package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
- package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
- package/editor/view/particles/effect/particle-editor.css +123 -35
- package/package.json +1 -1
- package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +10 -1
- package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
- package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
- package/src/core/collection/array/typed/float32_array_hash.js +38 -0
- package/src/core/graph/csr/CSRGraph.d.ts +8 -1
- package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
- package/src/core/graph/csr/CSRGraph.js +14 -6
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
- package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
- package/src/engine/animation/AnimationUtils.js +246 -246
- package/src/engine/animation/Animations.js +74 -74
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
- package/src/engine/ecs/EventType.d.ts +0 -1
- package/src/engine/ecs/EventType.js +1 -26
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
- package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
- package/src/engine/ecs/parent/EntityNode.js +4 -9
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
- package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
- package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
- package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
- package/src/engine/ecs/transform/t64_announce_change.js +12 -12
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
- package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
- package/src/engine/graphics3/LightSystem.js +4 -8
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +9 -19
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
- package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
- package/src/shade/playground/particle_editor/README.md +43 -2
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_prototype.js +4 -5
- package/src/shade/playground/particle_system/particle_scene.js +4 -4
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +13 -1
- package/src/shade/renderer/particles/DESIGN.md +104 -19
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
- package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
- package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
- package/src/shade/renderer/particles/ParticleConstants.js +66 -23
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
- package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
- package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
- package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
- package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
- package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
- package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
- package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
- package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
- package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
- package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
- package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
- package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +105 -262
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
- package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
- package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
- package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
- package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
- package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
- package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
- package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
- package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
- package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
- package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
- package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapCameraView.js +4 -9
- package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
- package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
- package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
- package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
- package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
- package/src/engine/ecs/transform/__probe.d.ts +0 -4
- package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
- package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
- package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
- package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
- package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
- package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { decode_particle_instructions, particle_peak_live_slots, particle_read_slots } from "./particle_program_analysis.js";
|
|
2
|
+
|
|
3
|
+
/** @type {string} */
|
|
4
|
+
export const PARTICLE_PASS_SCHEDULE = "schedule";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reorder the instructions so that fewer values are alive at once.
|
|
8
|
+
*
|
|
9
|
+
* A frontend lowers in whatever order it visits, and the node compiler's order is the graph's: a
|
|
10
|
+
* constant is loaded where the graph mentions it and a corner offset is computed alongside the
|
|
11
|
+
* others, both a long way above their one consumer. Every instruction in between then carries that
|
|
12
|
+
* value in the file. The register allocator can only reuse slots whose values have died, so a
|
|
13
|
+
* value that lives longer than it needs to is a slot the allocator cannot give back — the
|
|
14
|
+
* curl-noise effect held a vec4 across seventy instructions this way.
|
|
15
|
+
*
|
|
16
|
+
* ## What may be reordered
|
|
17
|
+
*
|
|
18
|
+
* Straight-line code has three hazards per slot — a read must follow the write it reads, a write
|
|
19
|
+
* must follow the reads of the value it replaces, and two writes keep their order — and the
|
|
20
|
+
* schedule keeps every one of them, so the sequence of writes and reads of each slot is the one the
|
|
21
|
+
* program had. Instructions with side effects are barriers: nothing crosses a draw, a store, a kill
|
|
22
|
+
* or a halt in either direction, and they keep their order among themselves. That is stricter than
|
|
23
|
+
* a pure instruction crossing a store needs, and it is what keeps the ordering promises of
|
|
24
|
+
* `optimize_particle_program.js` — the draw sequence, attribute aliasing — structural for this pass
|
|
25
|
+
* as for every other.
|
|
26
|
+
*
|
|
27
|
+
* ## How the order is chosen
|
|
28
|
+
*
|
|
29
|
+
* Backwards, one instruction at a time, from the set whose consumers are all already placed: the
|
|
30
|
+
* one whose placement leaves the fewest slots alive above it, which is the one that frees the most
|
|
31
|
+
* of what it writes against what it reads. Ties go to the instruction that came last in the program
|
|
32
|
+
* as it was, so an order that is already as good as this greedy can make it comes back unchanged —
|
|
33
|
+
* and the schedule is kept only when its peak is strictly lower than the program's, so the pass is
|
|
34
|
+
* a fixed point of itself and never makes a program worse by the one measure it is for.
|
|
35
|
+
*
|
|
36
|
+
* It is a greedy, and a greedy can be fooled; the differential harness holds it to bit-identity
|
|
37
|
+
* whatever order it picks, and the peak is measured rather than assumed.
|
|
38
|
+
*
|
|
39
|
+
* @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
|
|
40
|
+
*/
|
|
41
|
+
export function pass_schedule(instructions, context) {
|
|
42
|
+
const decoded = decode_particle_instructions(instructions);
|
|
43
|
+
const slots = context.register_slots;
|
|
44
|
+
const order = schedule(decoded, slots);
|
|
45
|
+
|
|
46
|
+
if (order === null) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const scheduled = order.map(index => decoded[index]);
|
|
51
|
+
|
|
52
|
+
if (particle_peak_live_slots(scheduled, slots) >= particle_peak_live_slots(decoded, slots)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return order.map(index => instructions[index]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction[]} decoded
|
|
61
|
+
* @param {number} slots size of the register file
|
|
62
|
+
* @returns {number[]|null} instruction indices in their new order, or `null` when an operand
|
|
63
|
+
* reaches outside the file
|
|
64
|
+
*/
|
|
65
|
+
function schedule(decoded, slots) {
|
|
66
|
+
const count = decoded.length;
|
|
67
|
+
const predecessors = build_dependencies(decoded, slots);
|
|
68
|
+
|
|
69
|
+
if (predecessors === null) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** @type {Int32Array} per instruction, how many of its dependents are still unplaced */
|
|
74
|
+
const pending = new Int32Array(count);
|
|
75
|
+
|
|
76
|
+
for (let i = 0; i < count; i++) {
|
|
77
|
+
for (const predecessor of predecessors[i]) {
|
|
78
|
+
pending[predecessor]++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** @type {Set<number>} instructions whose dependents are all placed */
|
|
83
|
+
const ready = new Set();
|
|
84
|
+
|
|
85
|
+
for (let i = 0; i < count; i++) {
|
|
86
|
+
if (pending[i] === 0) {
|
|
87
|
+
ready.add(i);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** @type {Uint8Array} slots alive just above the instructions placed so far */
|
|
92
|
+
const live = new Uint8Array(slots);
|
|
93
|
+
/** @type {Uint8Array} scratch for scoring a candidate */
|
|
94
|
+
const trial = new Uint8Array(slots);
|
|
95
|
+
/** @type {number[]} placed instructions, last first */
|
|
96
|
+
const reversed = [];
|
|
97
|
+
|
|
98
|
+
while (reversed.length < count) {
|
|
99
|
+
let best = -1;
|
|
100
|
+
let best_live = Infinity;
|
|
101
|
+
|
|
102
|
+
for (const candidate of ready) {
|
|
103
|
+
const alive = live_above(decoded[candidate], live, trial);
|
|
104
|
+
|
|
105
|
+
if (alive < best_live || (alive === best_live && candidate > best)) {
|
|
106
|
+
best = candidate;
|
|
107
|
+
best_live = alive;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
live_above(decoded[best], live, trial);
|
|
112
|
+
live.set(trial);
|
|
113
|
+
reversed.push(best);
|
|
114
|
+
ready.delete(best);
|
|
115
|
+
|
|
116
|
+
for (const predecessor of predecessors[best]) {
|
|
117
|
+
if (--pending[predecessor] === 0) {
|
|
118
|
+
ready.add(predecessor);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return reversed.reverse();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The slots alive just above an instruction, given those alive just below it: what it reads, plus
|
|
128
|
+
* whatever was alive that it does not write.
|
|
129
|
+
*
|
|
130
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction} instruction
|
|
131
|
+
* @param {Uint8Array} below
|
|
132
|
+
* @param {Uint8Array} above written here
|
|
133
|
+
* @returns {number} how many
|
|
134
|
+
*/
|
|
135
|
+
function live_above(instruction, below, above) {
|
|
136
|
+
above.set(below);
|
|
137
|
+
|
|
138
|
+
if (instruction.write !== null) {
|
|
139
|
+
for (let lane = 0; lane < instruction.write.span; lane++) {
|
|
140
|
+
above[instruction.write.base + lane] = 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const read of instruction.reads) {
|
|
145
|
+
for (const slot of particle_read_slots(read)) {
|
|
146
|
+
above[slot] = 1;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let alive = 0;
|
|
151
|
+
|
|
152
|
+
for (let slot = 0; slot < above.length; slot++) {
|
|
153
|
+
alive += above[slot];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return alive;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Per instruction, the instructions it must come after.
|
|
161
|
+
*
|
|
162
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction[]} decoded
|
|
163
|
+
* @param {number} slots
|
|
164
|
+
* @returns {Set<number>[]|null} `null` when an operand reaches outside the file
|
|
165
|
+
*/
|
|
166
|
+
function build_dependencies(decoded, slots) {
|
|
167
|
+
const predecessors = decoded.map(() => new Set());
|
|
168
|
+
/** @type {Int32Array} per slot, the last instruction to write it */
|
|
169
|
+
const writer = new Int32Array(slots).fill(-1);
|
|
170
|
+
/** @type {number[][]} per slot, the instructions that read its current value */
|
|
171
|
+
const readers = Array.from({ length: slots }, () => []);
|
|
172
|
+
|
|
173
|
+
let barrier = -1;
|
|
174
|
+
|
|
175
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
176
|
+
const instruction = decoded[i];
|
|
177
|
+
const read_slots = new Set();
|
|
178
|
+
|
|
179
|
+
for (const read of instruction.reads) {
|
|
180
|
+
for (const slot of particle_read_slots(read)) {
|
|
181
|
+
if (slot < 0 || slot >= slots) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
read_slots.add(slot);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// After the write it reads.
|
|
190
|
+
for (const slot of read_slots) {
|
|
191
|
+
if (writer[slot] >= 0) {
|
|
192
|
+
predecessors[i].add(writer[slot]);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const write = instruction.write;
|
|
197
|
+
|
|
198
|
+
if (write !== null) {
|
|
199
|
+
if (write.base + write.span > slots) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// After the previous write, and after every read of the value it replaces.
|
|
204
|
+
for (let lane = 0; lane < write.span; lane++) {
|
|
205
|
+
const slot = write.base + lane;
|
|
206
|
+
|
|
207
|
+
if (writer[slot] >= 0) {
|
|
208
|
+
predecessors[i].add(writer[slot]);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const reader of readers[slot]) {
|
|
212
|
+
predecessors[i].add(reader);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
for (const slot of read_slots) {
|
|
218
|
+
readers[slot].push(i);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (write !== null) {
|
|
222
|
+
for (let lane = 0; lane < write.span; lane++) {
|
|
223
|
+
writer[write.base + lane] = i;
|
|
224
|
+
readers[write.base + lane] = [];
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// A barrier comes after everything above it — the previous barrier included, since two of
|
|
229
|
+
// them may be adjacent — and everything below it comes after it.
|
|
230
|
+
if (instruction.semantics.side_effects) {
|
|
231
|
+
for (let j = Math.max(barrier, 0); j < i; j++) {
|
|
232
|
+
predecessors[i].add(j);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
barrier = i;
|
|
236
|
+
} else if (barrier >= 0) {
|
|
237
|
+
predecessors[i].add(barrier);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
predecessors[i].delete(i);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return predecessors;
|
|
244
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pass_share_subexpressions.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_share_subexpressions.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pass_share_subexpressions.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_share_subexpressions.js"],"names":[],"mappings":"AA8GU,4JAM8C;AA7GxD,qBAAqB;AACrB,iDADW,MAAM,CACwD"}
|
|
@@ -1,151 +1,154 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
ParticleValueNumbering,
|
|
4
|
-
decode_particle_instructions,
|
|
5
|
-
particle_instruction_is_well_formed,
|
|
6
|
-
} from "./particle_program_analysis.js";
|
|
7
|
-
|
|
8
|
-
/** @type {string} */
|
|
9
|
-
export const PARTICLE_PASS_SHARE_SUBEXPRESSIONS = "share_subexpressions";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Recognise an instruction that recomputes something a register already holds, and read the register
|
|
13
|
-
* instead.
|
|
14
|
-
*
|
|
15
|
-
* Two executions of a shareable opcode over equal operands produce equal results, so the second is
|
|
16
|
-
* a copy of the first — and where the two write the same register, it is not even that: the register
|
|
17
|
-
* already holds the answer and the instruction goes entirely.
|
|
18
|
-
*
|
|
19
|
-
* Equality is by value number rather than by register: the same expression computed from registers
|
|
20
|
-
* that have since been copied about still matches, and a register overwritten since fails the match
|
|
21
|
-
* without any separate invalidation. It is the machinery `pass_propagate_copies` uses, asked a
|
|
22
|
-
* different question.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* `
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
*
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
1
|
+
import { VM_KIND, VM_OP, vm_dest_width, vm_pack_instruction } from "../isa/ParticleVMISA.js";
|
|
2
|
+
import {
|
|
3
|
+
ParticleValueNumbering,
|
|
4
|
+
decode_particle_instructions,
|
|
5
|
+
particle_instruction_is_well_formed,
|
|
6
|
+
} from "./particle_program_analysis.js";
|
|
7
|
+
|
|
8
|
+
/** @type {string} */
|
|
9
|
+
export const PARTICLE_PASS_SHARE_SUBEXPRESSIONS = "share_subexpressions";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Recognise an instruction that recomputes something a register already holds, and read the register
|
|
13
|
+
* instead.
|
|
14
|
+
*
|
|
15
|
+
* Two executions of a shareable opcode over equal operands produce equal results, so the second is
|
|
16
|
+
* a copy of the first — and where the two write the same register, it is not even that: the register
|
|
17
|
+
* already holds the answer and the instruction goes entirely.
|
|
18
|
+
*
|
|
19
|
+
* Equality is by value number rather than by register: the same expression computed from registers
|
|
20
|
+
* that have since been copied about still matches, and a register overwritten since fails the match
|
|
21
|
+
* without any separate invalidation. It is the machinery `pass_propagate_copies` uses, asked a
|
|
22
|
+
* different question. A register operand contributes the numbers of the lanes it reads, through its
|
|
23
|
+
* swizzle, so `r0.xxx` and `r4.yyy` match when r0 and r5 hold the same value; a literal contributes
|
|
24
|
+
* itself.
|
|
25
|
+
*
|
|
26
|
+
* ## What is not shared
|
|
27
|
+
*
|
|
28
|
+
* `LOAD_ATTR` reads the record, which a `STORE_ATTR` in between may have changed, and `RANDOM` reads
|
|
29
|
+
* the RNG, which every draw changes. Neither is shareable, so neither is ever considered here — the
|
|
30
|
+
* `shareable` column of {@link ./particle_vm_semantics.js} is the whole of the rule, which is what
|
|
31
|
+
* keeps the aliasing question from having to be answered a second time in this file.
|
|
32
|
+
*
|
|
33
|
+
* `ADD`, `MUL` and `CMP_EQ` match with their operands either way round. `MIN` and `MAX` do not,
|
|
34
|
+
* although they look just as commutative: `min(-0, 0)` and `min(0, -0)` are different registers'
|
|
35
|
+
* worth of zero, and the record is compared to the bit.
|
|
36
|
+
*
|
|
37
|
+
* @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
|
|
38
|
+
*/
|
|
39
|
+
export function pass_share_subexpressions(instructions, context) {
|
|
40
|
+
const decoded = decode_particle_instructions(instructions);
|
|
41
|
+
const values = new ParticleValueNumbering(context.register_slots);
|
|
42
|
+
|
|
43
|
+
/** @type {Map<string, {base: number, ids: number[]}>} expression -> where its result was left */
|
|
44
|
+
const available = new Map();
|
|
45
|
+
|
|
46
|
+
/** @type {number[][]} */
|
|
47
|
+
const out = [];
|
|
48
|
+
|
|
49
|
+
let changed = false;
|
|
50
|
+
|
|
51
|
+
for (const instruction of decoded) {
|
|
52
|
+
const span = instruction.write === null ? 0 : vm_dest_width(instruction.op, instruction.width);
|
|
53
|
+
const key = is_shareable(instruction) && span > 0 ? expression_key(instruction, values) : null;
|
|
54
|
+
const previous = key === null ? undefined : available.get(key);
|
|
55
|
+
|
|
56
|
+
let shared = false;
|
|
57
|
+
|
|
58
|
+
if (previous !== undefined && values.holds(previous.base, previous.ids)) {
|
|
59
|
+
const replacement = share(instruction, previous, span);
|
|
60
|
+
|
|
61
|
+
if (replacement !== null) {
|
|
62
|
+
for (const words of replacement) {
|
|
63
|
+
out.push(words);
|
|
64
|
+
values.publish(words);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
shared = true;
|
|
68
|
+
changed = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!shared) {
|
|
73
|
+
out.push(instruction.words);
|
|
74
|
+
values.publish(instruction.words);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Recorded after the write, so an expression that overwrites one of its own sources names
|
|
78
|
+
// the register as it stands once the instruction has run.
|
|
79
|
+
if (key !== null && !shared) {
|
|
80
|
+
available.set(key, { base: instruction.write.base, ids: values.ids_of(instruction.write.base, span) });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return changed ? out : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* `MOV` is shareable in the sense the semantics table means, but it is not shared here: replacing
|
|
89
|
+
* one copy with another copy is no gain, and `pass_propagate_copies` — which reads THROUGH copies —
|
|
90
|
+
* would immediately rewrite the result back, leaving the two passes trading the same instruction
|
|
91
|
+
* between them for as many sweeps as they are given.
|
|
92
|
+
*
|
|
93
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction} instruction
|
|
94
|
+
* @returns {boolean}
|
|
95
|
+
*/
|
|
96
|
+
function is_shareable(instruction) {
|
|
97
|
+
return instruction.semantics.shareable && instruction.op !== VM_OP.MOV;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Opcodes whose two register operands may be matched either way round. */
|
|
101
|
+
const COMMUTATIVE = new Set([VM_OP.ADD, VM_OP.MUL, VM_OP.CMP_EQ]);
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* What makes two executions the same one: the opcode, the width, every raw field, and per source
|
|
105
|
+
* either the value numbers behind the lanes it reads or the literal it is.
|
|
106
|
+
*
|
|
107
|
+
* @returns {string|null} `null` when an operand reaches outside the file, which is nothing to match
|
|
108
|
+
*/
|
|
109
|
+
function expression_key(instruction, values) {
|
|
110
|
+
/** @type {string[]} */
|
|
111
|
+
const parts = [];
|
|
112
|
+
|
|
113
|
+
for (let slot = 0; slot < 3; slot++) {
|
|
114
|
+
const source = instruction.sources.find(candidate => candidate.operand === slot);
|
|
115
|
+
|
|
116
|
+
if (source === undefined) {
|
|
117
|
+
parts.push(`i${instruction.words[1 + slot]}`);
|
|
118
|
+
} else if (source.kind === VM_KIND.IMM) {
|
|
119
|
+
parts.push(`#${source.word}`);
|
|
120
|
+
} else {
|
|
121
|
+
const ids = values.ids_read(source);
|
|
122
|
+
|
|
123
|
+
if (ids === null) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
parts.push(`r${ids.join(",")}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (COMMUTATIVE.has(instruction.op)) {
|
|
132
|
+
parts.sort();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return `${instruction.op}.${instruction.width}|${parts.join("|")}`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @returns {number[][]|null} what to emit instead — nothing at all when the result is already in the
|
|
140
|
+
* destination, otherwise a copy of it — or `null` when the copy would not be a legal instruction
|
|
141
|
+
*/
|
|
142
|
+
function share(instruction, previous, span) {
|
|
143
|
+
if (previous.base === instruction.write.base) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const words = vm_pack_instruction(
|
|
148
|
+
VM_OP.MOV, span, instruction.write.base,
|
|
149
|
+
[VM_KIND.REG, VM_KIND.NONE, VM_KIND.NONE],
|
|
150
|
+
[previous.base, 0, 0]
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
return particle_instruction_is_well_formed(words) ? [words] : null;
|
|
154
|
+
}
|
|
@@ -32,6 +32,26 @@ export function particle_scene_fixture(): ParticleSceneFixture;
|
|
|
32
32
|
* @returns {ParticleEmitter}
|
|
33
33
|
*/
|
|
34
34
|
export function place_emitter(fixture: ParticleSceneFixture, config: ParticleEmitter | object, parent?: import("../scene/Node3D.js").Node3D): ParticleEmitter;
|
|
35
|
+
/**
|
|
36
|
+
* What the fixture's registry assigned an emitter: its table row, its generation, the heap
|
|
37
|
+
* placement of its program, the atlas patch. The emitter carries none of it — see
|
|
38
|
+
* {@link ./runtime/GPUParticleEmitterContext.js} — so a spec that wants the row a particle header
|
|
39
|
+
* should carry asks the registry, the way the passes' own callers do.
|
|
40
|
+
*
|
|
41
|
+
* @param {ParticleSceneFixture} fixture
|
|
42
|
+
* @param {ParticleEmitter} emitter
|
|
43
|
+
* @returns {import("./runtime/GPUParticleEmitterContext.js").GPUParticleEmitterContext}
|
|
44
|
+
*/
|
|
45
|
+
export function emitter_context(fixture: ParticleSceneFixture, emitter: ParticleEmitter): import("./runtime/GPUParticleEmitterContext.js").GPUParticleEmitterContext;
|
|
46
|
+
/**
|
|
47
|
+
* The emitter table row an emitter was given — {@link emitter_context}`.row`, which specs index
|
|
48
|
+
* per-emitter buffers with often enough to be worth naming.
|
|
49
|
+
*
|
|
50
|
+
* @param {ParticleSceneFixture} fixture
|
|
51
|
+
* @param {ParticleEmitter} emitter
|
|
52
|
+
* @returns {number}
|
|
53
|
+
*/
|
|
54
|
+
export function emitter_row(fixture: ParticleSceneFixture, emitter: ParticleEmitter): number;
|
|
35
55
|
/**
|
|
36
56
|
* The two databases as the `array<u32>` buffers the particle shaders bind. Call after the last
|
|
37
57
|
* change to either; it flushes both.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"particle_test_fixtures.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/particle_test_fixtures.js"],"names":[],"mappings":"AAWA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AAEH;;;;GAIG;AACH,0CAFa,oBAAoB,CAUhC;AAED;;;;;;;;GAQG;AACH,uCALW,oBAAoB,UACpB,eAAe,GAAC,MAAM,WACtB,OAAO,oBAAoB,EAAE,MAAM,GACjC,eAAe,CAkB3B;AAED;;;;;;GAMG;AACH,iDAHW,oBAAoB,GAClB;IAAC,cAAc,EAAE,WAAW,CAAC;IAAC,gBAAgB,EAAE,WAAW,CAAA;CAAC,CAUxE;AAED;;;;;;GAMG;AACH,qCAJW,MAAM,SACN,MAAM,GACJ;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,EAAE,CAI7B;AAED;;;;GAIG;AACH,qCAFa;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,EAAE,CAI7B;AA2BD;;;;;;GAMG;AACH,qDAJW,WAAW,OACX,MAAM,GACJ;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAalG;AAED;;;;;;;GAOG;AACH,sDAJW,WAAW,OACX,MAAM,UACN;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAC,QAWrG;AAED;;;;;;;GAOG;AACH,sCAJW,MAAM,aACN,UAAU,MAAM,CAAC,GACf;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAC,CAIlD;AAED;;;;;;GAMG;AACH,2CAHW;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAC,GACpC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAC,CAWlD;;
|
|
1
|
+
{"version":3,"file":"particle_test_fixtures.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/particle_test_fixtures.js"],"names":[],"mappings":"AAWA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AAEH;;;;GAIG;AACH,0CAFa,oBAAoB,CAUhC;AAED;;;;;;;;GAQG;AACH,uCALW,oBAAoB,UACpB,eAAe,GAAC,MAAM,WACtB,OAAO,oBAAoB,EAAE,MAAM,GACjC,eAAe,CAkB3B;AAED;;;;;;;;;GASG;AACH,yCAJW,oBAAoB,WACpB,eAAe,GACb,OAAO,wCAAwC,EAAE,yBAAyB,CAItF;AAED;;;;;;;GAOG;AACH,qCAJW,oBAAoB,WACpB,eAAe,GACb,MAAM,CAIlB;AAED;;;;;;GAMG;AACH,iDAHW,oBAAoB,GAClB;IAAC,cAAc,EAAE,WAAW,CAAC;IAAC,gBAAgB,EAAE,WAAW,CAAA;CAAC,CAUxE;AAED;;;;;;GAMG;AACH,qCAJW,MAAM,SACN,MAAM,GACJ;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,EAAE,CAI7B;AAED;;;;GAIG;AACH,qCAFa;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,EAAE,CAI7B;AA2BD;;;;;;GAMG;AACH,qDAJW,WAAW,OACX,MAAM,GACJ;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAalG;AAED;;;;;;;GAOG;AACH,sDAJW,WAAW,OACX,MAAM,UACN;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAC,QAWrG;AAED;;;;;;;GAOG;AACH,sCAJW,MAAM,aACN,UAAU,MAAM,CAAC,GACf;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAC,CAIlD;AAED;;;;;;GAMG;AACH,2CAHW;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAC,GACpC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAC,CAWlD;;YA5Ma,iBAAiB;cACjB,eAAe;WACf,KAAK;mBACL,OAAO,6BAA6B,EAAE,eAAe;cACrD,eAAe;;gCAnBG,8BAA8B;kCAT5B,wCAAwC;gCAC1C,uBAAuB;sBAEjC,mBAAmB;gCAKT,8BAA8B"}
|