diff options
Diffstat (limited to 'src/gpu')
| -rw-r--r-- | src/gpu/effect.cc | 57 | ||||
| -rw-r--r-- | src/gpu/effect.h | 17 | ||||
| -rw-r--r-- | src/gpu/sequence.cc | 2 |
3 files changed, 71 insertions, 5 deletions
diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc index b729321..117ede2 100644 --- a/src/gpu/effect.cc +++ b/src/gpu/effect.cc @@ -1,11 +1,64 @@ // Effect implementation #include "gpu/effect.h" +#include "gpu/gpu.h" +#include "gpu/sequence.h" #include "util/fatal_error.h" Effect::Effect(const GpuContext& ctx, const std::vector<std::string>& inputs, - const std::vector<std::string>& outputs) - : ctx_(ctx), input_nodes_(inputs), output_nodes_(outputs) { + const std::vector<std::string>& outputs, float start_time, + float end_time) + : ctx_(ctx), input_nodes_(inputs), output_nodes_(outputs), + start_time_(start_time), end_time_(end_time) { FATAL_CHECK(!inputs.empty(), "Effect must have at least one input\n"); FATAL_CHECK(!outputs.empty(), "Effect must have at least one output\n"); + FATAL_CHECK(start_time <= end_time, "Invalid time range: %f > %f\n", + start_time, end_time); +} + +void Effect::dispatch_render(WGPUCommandEncoder encoder, + const UniformsSequenceParams& params, + NodeRegistry& nodes) { + // Check if effect is active at current time + const bool active = + (params.time >= start_time_ && params.time < end_time_); + + // Auto-passthrough for 1:1 input/output effects outside active range + if (!active && input_nodes_.size() == 1 && output_nodes_.size() == 1) { + blit_input_to_output(encoder, nodes); + } else if (active) { + render(encoder, params, nodes); + } + // Multi-output effects: output undefined when inactive (validated at compile time) +} + +void Effect::blit_input_to_output(WGPUCommandEncoder encoder, + NodeRegistry& nodes) { + HEADLESS_RETURN_IF_NULL(encoder); + + WGPUTexture src = nodes.get_texture(input_nodes_[0]); + WGPUTexture dst = nodes.get_texture(output_nodes_[0]); + + // Skip passthrough if textures are external (source/sink) or invalid + if (!src || !dst) { + return; + } + +#if defined(DEMO_CROSS_COMPILE_WIN32) + WGPUImageCopyTexture src_copy = { + .texture = src, .mipLevel = 0, .origin = {0, 0, 0}}; + WGPUImageCopyTexture dst_copy = { + .texture = dst, .mipLevel = 0, .origin = {0, 0, 0}}; +#else + WGPUTexelCopyTextureInfo src_copy = { + .texture = src, .mipLevel = 0, .origin = {0, 0, 0}}; + WGPUTexelCopyTextureInfo dst_copy = { + .texture = dst, .mipLevel = 0, .origin = {0, 0, 0}}; +#endif + + WGPUExtent3D extent = {static_cast<unsigned int>(width_), + static_cast<unsigned int>(height_), 1}; + + wgpuCommandEncoderCopyTextureToTexture(encoder, &src_copy, &dst_copy, + &extent); } diff --git a/src/gpu/effect.h b/src/gpu/effect.h index d40e750..0d7e35e 100644 --- a/src/gpu/effect.h +++ b/src/gpu/effect.h @@ -14,7 +14,8 @@ class NodeRegistry; class Effect { public: Effect(const GpuContext& ctx, const std::vector<std::string>& inputs, - const std::vector<std::string>& outputs); + const std::vector<std::string>& outputs, float start_time, + float end_time); virtual ~Effect() = default; // Optional: Declare temporary nodes (e.g., multi-pass intermediate buffers) @@ -22,7 +23,12 @@ class Effect { (void)registry; } - // Render effect (multi-input/multi-output) + // Dispatch render with automatic passthrough outside [start, end] + void dispatch_render(WGPUCommandEncoder encoder, + const UniformsSequenceParams& params, + NodeRegistry& nodes); + + // Render effect (multi-input/multi-output) - override in derived classes virtual void render(WGPUCommandEncoder encoder, const UniformsSequenceParams& params, NodeRegistry& nodes) = 0; @@ -46,5 +52,12 @@ class Effect { std::vector<std::string> output_nodes_; int width_ = 1280; int height_ = 720; + + private: + float start_time_; + float end_time_; + + // Auto-passthrough helper for 1:1 input/output effects + void blit_input_to_output(WGPUCommandEncoder encoder, NodeRegistry& nodes); }; #endif // EFFECT_H diff --git a/src/gpu/sequence.cc b/src/gpu/sequence.cc index 5348992..d2f99bc 100644 --- a/src/gpu/sequence.cc +++ b/src/gpu/sequence.cc @@ -240,7 +240,7 @@ void Sequence::postprocess(WGPUCommandEncoder encoder) { void Sequence::render_effects(WGPUCommandEncoder encoder) { // Execute DAG in topological order (pre-sorted by compiler) for (const auto& dag_node : effect_dag_) { - dag_node.effect->render(encoder, params_, nodes_); + dag_node.effect->dispatch_render(encoder, params_, nodes_); } } |
