summaryrefslogtreecommitdiff
path: root/src/gpu/effect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/effect.cc')
-rw-r--r--src/gpu/effect.cc69
1 files changed, 67 insertions, 2 deletions
diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc
index e4d3a90..d0693ec 100644
--- a/src/gpu/effect.cc
+++ b/src/gpu/effect.cc
@@ -1,11 +1,76 @@
// 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);
+ HEADLESS_RETURN_IF_NULL(ctx_.device);
+}
+
+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;
+ }
+
+ GpuTextureCopyInfo src_copy = {
+ .texture = src, .mipLevel = 0, .origin = {0, 0, 0}};
+ GpuTextureCopyInfo dst_copy = {
+ .texture = dst, .mipLevel = 0, .origin = {0, 0, 0}};
+
+ WGPUExtent3D extent = {(unsigned int)(width_),
+ (unsigned int)(height_), 1};
+
+ wgpuCommandEncoderCopyTextureToTexture(encoder, &src_copy, &dst_copy,
+ &extent);
+}
+
+void Effect::init_uniforms_buffer() {
+ uniforms_buffer_.init(ctx_.device);
+}
+
+void Effect::create_linear_sampler() {
+ sampler_.set(gpu_create_linear_sampler(ctx_.device));
+}
+
+void Effect::create_nearest_sampler() {
+ sampler_.set(gpu_create_nearest_sampler(ctx_.device));
+}
+
+void Effect::create_dummy_scene_texture() {
+ TextureWithView dummy = gpu_create_dummy_scene_texture(ctx_.device);
+ dummy_texture_.set(dummy.texture);
+ dummy_texture_view_.set(dummy.view);
}