@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,22 @@
|
|
|
1
|
+
export function pass_inline_constants(instructions: number[][], context: import("./optimize_particle_program.js").ParticleOptimizerContext): number[][];
|
|
2
|
+
/** @type {string} */
|
|
3
|
+
export const PARTICLE_PASS_INLINE_CONSTANTS: string;
|
|
4
|
+
export type ParticleConstantSource = {
|
|
5
|
+
/**
|
|
6
|
+
* first register slot the constant is written to
|
|
7
|
+
*/
|
|
8
|
+
base: number;
|
|
9
|
+
/**
|
|
10
|
+
* slots it fills
|
|
11
|
+
*/
|
|
12
|
+
span: number;
|
|
13
|
+
/**
|
|
14
|
+
* the `f32` bit pattern each slot receives
|
|
15
|
+
*/
|
|
16
|
+
bits: Uint32Array;
|
|
17
|
+
/**
|
|
18
|
+
* whether every slot receives the same bits
|
|
19
|
+
*/
|
|
20
|
+
uniform: boolean;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=pass_inline_constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pass_inline_constants.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_inline_constants.js"],"names":[],"mappings":"AAmHY,wJAUZ;AArHA,qBAAqB;AACrB,6CADW,MAAM,CACgD;;;;;UA0FnD,MAAM;;;;UACN,MAAM;;;;UACN,WAAW;;;;aACX,OAAO"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { VM_KIND, VM_OP, vm_f32_bits, vm_pack_instruction, vm_with_kind } from "../isa/ParticleVMISA.js";
|
|
2
|
+
import {
|
|
3
|
+
decode_particle_instruction,
|
|
4
|
+
decode_particle_instructions,
|
|
5
|
+
particle_instruction_is_well_formed,
|
|
6
|
+
particle_read_slots,
|
|
7
|
+
} from "./particle_program_analysis.js";
|
|
8
|
+
|
|
9
|
+
/** @type {string} */
|
|
10
|
+
export const PARTICLE_PASS_INLINE_CONSTANTS = "inline_constants";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Move constants out of the register file and into the instructions that read them.
|
|
14
|
+
*
|
|
15
|
+
* `LOAD_CONST r, c` puts a value that never changes into a register, so that the next instruction
|
|
16
|
+
* can read a register — which was the only thing an instruction could read, until a source could be
|
|
17
|
+
* a literal (see the operand kinds in {@link ../isa/ParticleVMISA.js}). Now the load is a detour:
|
|
18
|
+
* the consumer can name the value itself. This pass finds every instruction that reads the loaded
|
|
19
|
+
* run before anything overwrites it, rewrites that operand to carry the constant, and deletes the
|
|
20
|
+
* load. A constant read by many instructions is inlined into each of them; unlike a register, a
|
|
21
|
+
* literal costs nothing to repeat.
|
|
22
|
+
*
|
|
23
|
+
* A literal is one value in every lane, so a consumer takes it only where every lane it reads holds
|
|
24
|
+
* the same `f32` — every scalar, every lane-uniform vector, and every swizzle whose selected lanes
|
|
25
|
+
* happen to agree. A vector whose lanes differ keeps its load: the pool is where such a value lives.
|
|
26
|
+
*
|
|
27
|
+
* A load whose value is uniform but that cannot be inlined — a consumer reads past the run, or
|
|
28
|
+
* reads a lane something in between has overwritten — keeps its register, but not its opcode: it
|
|
29
|
+
* becomes a `MOV` from the literal, so that the only `LOAD_CONST`s left in a program this pass has
|
|
30
|
+
* been over are the ones the pool exists for.
|
|
31
|
+
*
|
|
32
|
+
* ## What must not change
|
|
33
|
+
*
|
|
34
|
+
* The rewrite is bit-exact: a literal is the `f32` bits the pool word held, and the interpreters
|
|
35
|
+
* fetch it through the same resolver they fetch a register with. The other passes do not have to
|
|
36
|
+
* know this one exists — a literal is not a register run, so liveness, aliasing and copy propagation
|
|
37
|
+
* see through it by construction — and it is idempotent: a program with nothing left to inline
|
|
38
|
+
* comes back as `null`.
|
|
39
|
+
*
|
|
40
|
+
* @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
|
|
41
|
+
*/
|
|
42
|
+
export function pass_inline_constants(instructions, context) {
|
|
43
|
+
const constants = context.constants;
|
|
44
|
+
|
|
45
|
+
if (constants === undefined || constants.length === 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const decoded = decode_particle_instructions(instructions);
|
|
50
|
+
/** @type {number[][]} the stream being rewritten; `decoded` is kept in step with it */
|
|
51
|
+
const out = instructions.map(words => Array.from(words));
|
|
52
|
+
const removed = new Uint8Array(decoded.length);
|
|
53
|
+
|
|
54
|
+
let changed = false;
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
57
|
+
const source = constant_source(decoded[i], constants);
|
|
58
|
+
|
|
59
|
+
if (source === null) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const rewrites = plan_inlining(decoded, i, source);
|
|
64
|
+
|
|
65
|
+
if (rewrites !== null) {
|
|
66
|
+
for (const [index, words] of rewrites) {
|
|
67
|
+
out[index] = words;
|
|
68
|
+
decoded[index] = decode_particle_instruction(words, index);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
removed[i] = 1;
|
|
72
|
+
changed = true;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// The value has to stay in a register, so the instruction stays — as a MOV from the literal,
|
|
77
|
+
// which is the same work under the opcode the interpreter already has for copies.
|
|
78
|
+
if (decoded[i].op === VM_OP.LOAD_CONST && source.uniform) {
|
|
79
|
+
const words = vm_pack_instruction(
|
|
80
|
+
VM_OP.MOV, decoded[i].width, decoded[i].dst,
|
|
81
|
+
[VM_KIND.IMM, VM_KIND.NONE, VM_KIND.NONE],
|
|
82
|
+
[source.bits[0], 0, 0]
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
out[i] = words;
|
|
86
|
+
decoded[i] = decode_particle_instruction(words, i);
|
|
87
|
+
changed = true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!changed) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return out.filter((words, index) => removed[index] === 0);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @typedef {object} ParticleConstantSource
|
|
100
|
+
* @property {number} base first register slot the constant is written to
|
|
101
|
+
* @property {number} span slots it fills
|
|
102
|
+
* @property {Uint32Array} bits the `f32` bit pattern each slot receives
|
|
103
|
+
* @property {boolean} uniform whether every slot receives the same bits
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* What an instruction writes into its destination when that is a constant: a `LOAD_CONST`, or a
|
|
108
|
+
* `MOV` from a literal. `null` for anything else.
|
|
109
|
+
*
|
|
110
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction} instruction
|
|
111
|
+
* @param {ArrayLike<number>} constants
|
|
112
|
+
* @returns {ParticleConstantSource|null}
|
|
113
|
+
*/
|
|
114
|
+
function constant_source(instruction, constants) {
|
|
115
|
+
if (instruction.write === null) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const span = instruction.write.span;
|
|
120
|
+
const bits = new Uint32Array(span);
|
|
121
|
+
|
|
122
|
+
if (instruction.op === VM_OP.LOAD_CONST) {
|
|
123
|
+
const pool = instruction.words[1];
|
|
124
|
+
|
|
125
|
+
if (pool + span > constants.length) {
|
|
126
|
+
// Out of the pool: a malformed program, left for `validate` to name.
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
for (let lane = 0; lane < span; lane++) {
|
|
131
|
+
bits[lane] = vm_f32_bits(constants[pool + lane]);
|
|
132
|
+
}
|
|
133
|
+
} else if (instruction.op === VM_OP.MOV && instruction.sources[0].kind === VM_KIND.IMM) {
|
|
134
|
+
bits.fill(instruction.sources[0].word);
|
|
135
|
+
} else {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let uniform = true;
|
|
140
|
+
|
|
141
|
+
for (let lane = 1; lane < span; lane++) {
|
|
142
|
+
uniform = uniform && bits[lane] === bits[0];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { base: instruction.write.base, span, bits, uniform };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Every consumer of the constant's run, rewritten to carry the constant — or `null` when one of
|
|
150
|
+
* them cannot.
|
|
151
|
+
*
|
|
152
|
+
* Walks forward from the load until every slot of the run has been overwritten or the section ends.
|
|
153
|
+
* Each register read that touches the run must lie entirely inside the slots the load still owns —
|
|
154
|
+
* a read reaching past it, or into a lane something has since overwritten, is reading a value the
|
|
155
|
+
* constant is not — and must see one value in every lane it reads.
|
|
156
|
+
*
|
|
157
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction[]} decoded
|
|
158
|
+
* @param {number} index of the load
|
|
159
|
+
* @param {ParticleConstantSource} source
|
|
160
|
+
* @returns {Map<number, number[]>|null} instruction index -> its rewritten words
|
|
161
|
+
*/
|
|
162
|
+
function plan_inlining(decoded, index, source) {
|
|
163
|
+
/** slots of the run the load still owns */
|
|
164
|
+
const pending = new Set();
|
|
165
|
+
|
|
166
|
+
for (let lane = 0; lane < source.span; lane++) {
|
|
167
|
+
pending.add(source.base + lane);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** @type {Map<number, number[]>} */
|
|
171
|
+
const rewrites = new Map();
|
|
172
|
+
|
|
173
|
+
for (let j = index + 1; j < decoded.length && pending.size > 0; j++) {
|
|
174
|
+
const instruction = decoded[j];
|
|
175
|
+
|
|
176
|
+
// Nothing past a HALT runs, so nothing past it consumes.
|
|
177
|
+
if (instruction.op === VM_OP.HALT) {
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for (const read of instruction.reads) {
|
|
182
|
+
const slots = particle_read_slots(read);
|
|
183
|
+
|
|
184
|
+
// A slot the run once held but something has since overwritten is not the constant any
|
|
185
|
+
// more, and a read of it is a read of that something. Only the slots still standing count.
|
|
186
|
+
if (!slots.some(slot => pending.has(slot))) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Touches the constant, so it has to be wholly the constant, and one value throughout.
|
|
191
|
+
if (!slots.every(slot => pending.has(slot))) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const first = source.bits[slots[0] - source.base];
|
|
196
|
+
|
|
197
|
+
if (!slots.every(slot => source.bits[slot - source.base] === first)) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const words = (rewrites.get(j) ?? instruction.words).slice();
|
|
202
|
+
|
|
203
|
+
words[0] = vm_with_kind(words[0], read.operand, VM_KIND.IMM);
|
|
204
|
+
words[1 + read.operand] = first;
|
|
205
|
+
|
|
206
|
+
if (!particle_instruction_is_well_formed(words)) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
rewrites.set(j, words);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (instruction.write !== null) {
|
|
214
|
+
for (let lane = 0; lane < instruction.write.span; lane++) {
|
|
215
|
+
pending.delete(instruction.write.base + lane);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return rewrites;
|
|
221
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pass_narrow_widths.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_narrow_widths.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pass_narrow_widths.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_narrow_widths.js"],"names":[],"mappings":"AA+DguE,qJAAqP;AAxDr9E,qBAAqB;AACrB,0CADW,MAAM,CAC0C"}
|
|
@@ -1,72 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
analyze_particle_lanes,
|
|
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_NARROW_WIDTHS = "narrow_widths";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Shrink each instruction to the lanes anything actually reads.
|
|
13
|
-
*
|
|
14
|
-
* Width is what stops every value costing four registers, and a lowering that works one value at a
|
|
15
|
-
* time has no way to know how wide its consumer will turn out to be — the node compiler emits a
|
|
16
|
-
* four-lane broadcast, learns later that one lane of it is read, and cannot go back. Reading the
|
|
17
|
-
* finished stream backwards can: {@link analyze_particle_lanes} already knows the highest live lane
|
|
18
|
-
* of every destination, and this pass writes that width into the instruction.
|
|
19
|
-
*
|
|
20
|
-
* The saving is in slots more often than in instructions. A narrowed value stops occupying the runs
|
|
21
|
-
* above it, which is what lets the register-packing pass reclaim them, and the register file is the
|
|
22
|
-
* interpreter's dominant cost — see the occupancy
|
|
23
|
-
*
|
|
24
|
-
* Lanes are a run from zero, so the width follows the *highest* live lane rather than the count of
|
|
25
|
-
* them: a live lane 2 holds the instruction at three lanes however dead lanes 0 and 1 are. Clearing
|
|
26
|
-
* out a hole in the middle would mean splitting the instruction, which costs more than the lane.
|
|
27
|
-
*
|
|
28
|
-
* A
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
out[i] = words;
|
|
68
|
-
changed = true;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return changed ? out : null;
|
|
72
|
-
}
|
|
1
|
+
import { vm_with_width } from "../isa/ParticleVMISA.js";
|
|
2
|
+
import {
|
|
3
|
+
analyze_particle_lanes,
|
|
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_NARROW_WIDTHS = "narrow_widths";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Shrink each instruction to the lanes anything actually reads.
|
|
13
|
+
*
|
|
14
|
+
* Width is what stops every value costing four registers, and a lowering that works one value at a
|
|
15
|
+
* time has no way to know how wide its consumer will turn out to be — the node compiler emits a
|
|
16
|
+
* four-lane broadcast, learns later that one lane of it is read, and cannot go back. Reading the
|
|
17
|
+
* finished stream backwards can: {@link analyze_particle_lanes} already knows the highest live lane
|
|
18
|
+
* of every destination, and this pass writes that width into the instruction.
|
|
19
|
+
*
|
|
20
|
+
* The saving is in slots more often than in instructions. A narrowed value stops occupying the runs
|
|
21
|
+
* above it, which is what lets the register-packing pass reclaim them, and the register file is the
|
|
22
|
+
* interpreter's dominant cost — see the occupancy note in `vm/chunk_particle_vm.js`.
|
|
23
|
+
*
|
|
24
|
+
* Lanes are a run from zero, so the width follows the *highest* live lane rather than the count of
|
|
25
|
+
* them: a live lane 2 holds the instruction at three lanes however dead lanes 0 and 1 are. Clearing
|
|
26
|
+
* out a hole in the middle would mean splitting the instruction, which costs more than the lane.
|
|
27
|
+
*
|
|
28
|
+
* A source's swizzle needs no trimming: an operand reaches as far as its selectors below the width,
|
|
29
|
+
* so narrowing the instruction narrows what every source keeps alive by itself.
|
|
30
|
+
*
|
|
31
|
+
* @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
|
|
32
|
+
*/
|
|
33
|
+
export function pass_narrow_widths(instructions, context) {
|
|
34
|
+
const decoded = decode_particle_instructions(instructions);
|
|
35
|
+
const { keep, width } = analyze_particle_lanes(decoded, context.register_slots);
|
|
36
|
+
|
|
37
|
+
/** @type {number[][]} */
|
|
38
|
+
const out = instructions.slice();
|
|
39
|
+
|
|
40
|
+
let changed = false;
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < instructions.length; i++) {
|
|
43
|
+
const instruction = decoded[i];
|
|
44
|
+
|
|
45
|
+
// Instructions nothing keeps are the dead-code pass's to remove, not this one's to narrow.
|
|
46
|
+
if (!keep[i] || width[i] === instruction.width) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const words = instruction.words.slice();
|
|
51
|
+
|
|
52
|
+
words[0] = vm_with_width(words[0], width[i]);
|
|
53
|
+
|
|
54
|
+
if (!particle_instruction_is_well_formed(words)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
out[i] = words;
|
|
59
|
+
changed = true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return changed ? out : null;
|
|
63
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pass_pack_registers.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_pack_registers.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pass_pack_registers.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_pack_registers.js"],"names":[],"mappings":"AAuF09C,sJAAqP;AApF/sD,qBAAqB;AACrB,2CADW,MAAM,CAC4C"}
|
|
@@ -1,86 +1,87 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* A slot read but never written stays in the file, holding the zero the reset gave it.
|
|
29
|
-
*
|
|
30
|
-
* @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
|
|
31
|
-
*/
|
|
32
|
-
export function pass_pack_registers(instructions, context) {
|
|
33
|
-
const decoded = decode_particle_instructions(instructions);
|
|
34
|
-
const slots = context.register_slots;
|
|
35
|
-
const used = new Uint8Array(slots);
|
|
36
|
-
|
|
37
|
-
for (const instruction of decoded) {
|
|
38
|
-
const runs = instruction.write === null ? instruction.reads : [instruction.write, ...instruction.reads];
|
|
39
|
-
|
|
40
|
-
for (const run of runs) {
|
|
41
|
-
for (let lane = 0; lane < run.span; lane++) {
|
|
42
|
-
if (run.base + lane < slots) {
|
|
43
|
-
used[run.base + lane] = 1;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const remap = new Int32Array(slots).fill(-1);
|
|
50
|
-
|
|
51
|
-
let next = 0;
|
|
52
|
-
let moved = false;
|
|
53
|
-
|
|
54
|
-
for (let slot = 0; slot < slots; slot++) {
|
|
55
|
-
if (used[slot]) {
|
|
56
|
-
moved = moved || next !== slot;
|
|
57
|
-
remap[slot] = next++;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!moved) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** @type {number[][]} */
|
|
66
|
-
const out = [];
|
|
67
|
-
|
|
68
|
-
for (const instruction of decoded) {
|
|
69
|
-
const words = instruction.words.slice();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
1
|
+
import { vm_operand_with_base, vm_with_dst } from "../isa/ParticleVMISA.js";
|
|
2
|
+
import { decode_particle_instructions, particle_instruction_is_well_formed } from "./particle_program_analysis.js";
|
|
3
|
+
|
|
4
|
+
/** @type {string} */
|
|
5
|
+
export const PARTICLE_PASS_PACK_REGISTERS = "pack_registers";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Close the holes the other passes left in the register file.
|
|
9
|
+
*
|
|
10
|
+
* Everything before this frees slots without moving anything into them: dead code takes whole values
|
|
11
|
+
* out of the middle of the file, narrowing takes the top lanes off the ones that remain, and both
|
|
12
|
+
* leave the survivors exactly where the frontend's allocator put them. The declared register count
|
|
13
|
+
* is then the high-water mark of a file that is mostly gaps — and the count is what the interpreter
|
|
14
|
+
* actually pays for, since `vm_reg` is a `var<private>` array indexed dynamically and its size sets
|
|
15
|
+
* the shader's register footprint outright (see the occupancy note in `vm/chunk_particle_vm.js`).
|
|
16
|
+
*
|
|
17
|
+
* ## Why it is a compaction and not a re-allocation
|
|
18
|
+
*
|
|
19
|
+
* Registers are not in SSA form: a slot is written, read, and written again by something unrelated,
|
|
20
|
+
* and two values that never overlap in time may already be sharing one. Reassigning slots by live
|
|
21
|
+
* range would mean reconstructing what the frontend's allocator knew and discarding what it decided.
|
|
22
|
+
*
|
|
23
|
+
* Deleting the slots nothing touches at all needs none of that, and is safe by construction. Every
|
|
24
|
+
* slot of every operand's span is marked used — including the ones inside a span that a swizzle
|
|
25
|
+
* skips over — so the remap is order-preserving and injective over the slots any operand can name,
|
|
26
|
+
* and every run stays contiguous with its swizzle meaning what it did.
|
|
27
|
+
*
|
|
28
|
+
* A slot read but never written stays in the file, holding the zero the reset gave it.
|
|
29
|
+
*
|
|
30
|
+
* @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
|
|
31
|
+
*/
|
|
32
|
+
export function pass_pack_registers(instructions, context) {
|
|
33
|
+
const decoded = decode_particle_instructions(instructions);
|
|
34
|
+
const slots = context.register_slots;
|
|
35
|
+
const used = new Uint8Array(slots);
|
|
36
|
+
|
|
37
|
+
for (const instruction of decoded) {
|
|
38
|
+
const runs = instruction.write === null ? instruction.reads : [instruction.write, ...instruction.reads];
|
|
39
|
+
|
|
40
|
+
for (const run of runs) {
|
|
41
|
+
for (let lane = 0; lane < run.span; lane++) {
|
|
42
|
+
if (run.base + lane < slots) {
|
|
43
|
+
used[run.base + lane] = 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const remap = new Int32Array(slots).fill(-1);
|
|
50
|
+
|
|
51
|
+
let next = 0;
|
|
52
|
+
let moved = false;
|
|
53
|
+
|
|
54
|
+
for (let slot = 0; slot < slots; slot++) {
|
|
55
|
+
if (used[slot]) {
|
|
56
|
+
moved = moved || next !== slot;
|
|
57
|
+
remap[slot] = next++;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!moved) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** @type {number[][]} */
|
|
66
|
+
const out = [];
|
|
67
|
+
|
|
68
|
+
for (const instruction of decoded) {
|
|
69
|
+
const words = instruction.words.slice();
|
|
70
|
+
|
|
71
|
+
if (instruction.write !== null) {
|
|
72
|
+
words[0] = vm_with_dst(words[0], remap[instruction.write.base]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (const read of instruction.reads) {
|
|
76
|
+
words[1 + read.operand] = vm_operand_with_base(read.word, remap[read.base]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!particle_instruction_is_well_formed(words)) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
out.push(words);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pass_peephole.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_peephole.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pass_peephole.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_peephole.js"],"names":[],"mappings":"AA+GC,gJAMW;AA1GZ,qBAAqB;AACrB,qCADW,MAAM,CACgC"}
|