summaryrefslogtreecommitdiff
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/effect.cc57
-rw-r--r--src/gpu/effect.h17
-rw-r--r--src/gpu/sequence.cc2
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_);
}
}