From 9d1d4df877f96f1970dce2ab30cfae49d3d796e1 Mon Sep 17 00:00:00 2001 From: skal Date: Mon, 16 Feb 2026 08:26:45 +0100 Subject: feat(sequence): Phase 1 - Sequence v2 foundation - Add Node system with typed buffers (u8x4_norm, f32x4, f16x8, depth24) - Add NodeRegistry with aliasing support for ping-pong optimization - Add SequenceV2 base class with DAG execution - Add EffectV2 base class with multi-input/multi-output - Add comprehensive tests (5 test cases, all passing) - Corrected FATAL_CHECK usage (checks ERROR conditions, not success) Phase 1 complete: Core v2 architecture functional. Next: Phase 2 compiler (seq_compiler_v2.py) handoff(Claude): Phase 1 foundation complete, all tests passing (35/35) --- src/gpu/sequence_v2.h | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/gpu/sequence_v2.h (limited to 'src/gpu/sequence_v2.h') diff --git a/src/gpu/sequence_v2.h b/src/gpu/sequence_v2.h new file mode 100644 index 0000000..9cd93c6 --- /dev/null +++ b/src/gpu/sequence_v2.h @@ -0,0 +1,107 @@ +// Sequence v2: Explicit node system with DAG effect routing +// Replaces implicit framebuffer ping-pong with compile-time optimized nodes + +#pragma once + +#include "gpu/gpu.h" +#include "gpu/uniform_helper.h" +#include "util/mini_math.h" +#include +#include +#include +#include + +class EffectV2; + +enum class NodeType { + U8X4_NORM, // RGBAu8 normalized (0-1) - default Source/Sink + F32X4, // RGBA float32 + F16X8, // 8-channel float16 + DEPTH24, // Depth buffer + COMPUTE_F32, // Compute buffer +}; + +struct Node { + NodeType type; + int width; + int height; + WGPUTexture texture; + WGPUTextureView view; + std::vector mip_views; // For multi-target render +}; + +struct UniformsSequenceParams { + vec2 resolution; + float aspect_ratio; + float time; // Per-sequence relative time + float beat_time; // Musical beats + float beat_phase; // Fractional beat 0.0-1.0 + float audio_intensity; + float _pad; +}; +static_assert(sizeof(UniformsSequenceParams) == 32, + "UniformsSequenceParams must be 32 bytes for WGSL alignment"); + +class NodeRegistry { + public: + NodeRegistry(WGPUDevice device, int default_width, int default_height); + ~NodeRegistry(); + + // Declare new node with explicit type/dimensions + void declare_node(const std::string& name, NodeType type, int width, + int height); + + // Declare aliased node (ping-pong optimization) + void declare_aliased_node(const std::string& name, + const std::string& alias_of); + + // Retrieve views + WGPUTextureView get_view(const std::string& name); + std::vector + get_output_views(const std::vector& names); + + // Resize all nodes + void resize(int width, int height); + + // Check if node exists + bool has_node(const std::string& name) const; + + private: + WGPUDevice device_; + int default_width_; + int default_height_; + std::map nodes_; + std::map aliases_; // name -> backing node name + + void create_texture(Node& node); +}; + +struct EffectDAGNode { + std::shared_ptr effect; + std::vector input_nodes; + std::vector output_nodes; + int execution_order; // Topologically sorted +}; + +class SequenceV2 { + public: + SequenceV2(const GpuContext& ctx, int width, int height); + virtual ~SequenceV2() = default; + + // Virtual methods (most sequences use defaults) + virtual void preprocess(float seq_time, float beat_time, float beat_phase, + float audio_intensity); + virtual void postprocess(WGPUCommandEncoder encoder); + virtual void render_effects(WGPUCommandEncoder encoder); + + void resize(int width, int height); + + protected: + const GpuContext& ctx_; + int width_; + int height_; + NodeRegistry nodes_; + std::vector effect_dag_; + UniformsSequenceParams params_; + UniformBuffer uniforms_buffer_; +}; -- cgit v1.2.3