diff options
Diffstat (limited to 'src/gpu/sequence_v2.h')
| -rw-r--r-- | src/gpu/sequence_v2.h | 107 |
1 files changed, 107 insertions, 0 deletions
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 <map> +#include <memory> +#include <string> +#include <vector> + +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<WGPUTextureView> 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<WGPUTextureView> + get_output_views(const std::vector<std::string>& 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<std::string, Node> nodes_; + std::map<std::string, std::string> aliases_; // name -> backing node name + + void create_texture(Node& node); +}; + +struct EffectDAGNode { + std::shared_ptr<EffectV2> effect; + std::vector<std::string> input_nodes; + std::vector<std::string> 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<EffectDAGNode> effect_dag_; + UniformsSequenceParams params_; + UniformBuffer<UniformsSequenceParams> uniforms_buffer_; +}; |
