summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/effects/flash_effect.cc28
-rw-r--r--src/effects/flash_effect.h4
-rw-r--r--src/effects/gaussian_blur_effect.cc22
-rw-r--r--src/effects/gaussian_blur_effect.h2
-rw-r--r--src/effects/heptagon_effect.cc30
-rw-r--r--src/effects/heptagon_effect.h4
-rw-r--r--src/effects/particles_effect.cc10
-rw-r--r--src/effects/particles_effect.h1
-rw-r--r--src/effects/passthrough_effect.cc20
-rw-r--r--src/effects/passthrough_effect.h2
-rw-r--r--src/effects/peak_meter_effect.cc2
-rw-r--r--src/effects/peak_meter_effect.h1
-rw-r--r--src/effects/placeholder_effect.cc18
-rw-r--r--src/effects/placeholder_effect.h2
-rw-r--r--src/gpu/effect.cc19
-rw-r--r--src/gpu/effect.h19
-rw-r--r--src/gpu/gpu.cc35
-rw-r--r--src/gpu/gpu.h9
18 files changed, 108 insertions, 120 deletions
diff --git a/src/effects/flash_effect.cc b/src/effects/flash_effect.cc
index 7baf6a2..2eba2ff 100644
--- a/src/effects/flash_effect.cc
+++ b/src/effects/flash_effect.cc
@@ -10,33 +10,15 @@ Flash::Flash(const GpuContext& ctx, const std::vector<std::string>& inputs,
const std::vector<std::string>& outputs, float start_time,
float end_time)
: Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr),
- bind_group_(nullptr), sampler_(nullptr), dummy_texture_(nullptr),
- dummy_texture_view_(nullptr) {
+ bind_group_(nullptr) {
HEADLESS_RETURN_IF_NULL(ctx_.device);
- uniforms_buffer_.init(ctx_.device);
+ init_uniforms_buffer();
+ create_nearest_sampler();
+ create_dummy_scene_texture();
+
pipeline_ = create_post_process_pipeline(
ctx_.device, WGPUTextureFormat_RGBA8Unorm, flash_shader_wgsl);
-
- // Create dummy sampler (scene effects don't use texture input)
- WGPUSamplerDescriptor sampler_desc = {};
- sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
- sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
- sampler_desc.magFilter = WGPUFilterMode_Nearest;
- sampler_desc.minFilter = WGPUFilterMode_Nearest;
- sampler_desc.maxAnisotropy = 1;
- sampler_ = wgpuDeviceCreateSampler(ctx_.device, &sampler_desc);
-
- // Create 1×1 dummy texture
- WGPUTextureDescriptor tex_desc = {};
- tex_desc.size = {1, 1, 1};
- tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
- tex_desc.usage = WGPUTextureUsage_TextureBinding;
- tex_desc.dimension = WGPUTextureDimension_2D;
- tex_desc.mipLevelCount = 1;
- tex_desc.sampleCount = 1;
- dummy_texture_ = wgpuDeviceCreateTexture(ctx_.device, &tex_desc);
- dummy_texture_view_ = wgpuTextureCreateView(dummy_texture_, nullptr);
}
Flash::~Flash() {
diff --git a/src/effects/flash_effect.h b/src/effects/flash_effect.h
index 1117e0a..d46cd56 100644
--- a/src/effects/flash_effect.h
+++ b/src/effects/flash_effect.h
@@ -18,8 +18,4 @@ class Flash : public Effect {
private:
WGPURenderPipeline pipeline_;
WGPUBindGroup bind_group_;
- WGPUSampler sampler_;
- WGPUTexture dummy_texture_;
- WGPUTextureView dummy_texture_view_;
- UniformBuffer<UniformsSequenceParams> uniforms_buffer_;
};
diff --git a/src/effects/gaussian_blur_effect.cc b/src/effects/gaussian_blur_effect.cc
index 7304321..1d39256 100644
--- a/src/effects/gaussian_blur_effect.cc
+++ b/src/effects/gaussian_blur_effect.cc
@@ -9,27 +9,15 @@ GaussianBlur::GaussianBlur(const GpuContext& ctx,
const std::vector<std::string>& inputs,
const std::vector<std::string>& outputs, float start_time,
float end_time)
- : Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr), bind_group_(nullptr),
- sampler_(nullptr) {
- // Headless mode: skip GPU resource creation (compiled out in STRIP_ALL)
+ : Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr), bind_group_(nullptr) {
HEADLESS_RETURN_IF_NULL(ctx_.device);
- // Create pipeline
+ init_uniforms_buffer();
+ create_linear_sampler();
+ params_buffer_.init(ctx_.device);
+
pipeline_ = create_post_process_pipeline(
ctx_.device, WGPUTextureFormat_RGBA8Unorm, gaussian_blur_shader_wgsl);
-
- // Create sampler
- WGPUSamplerDescriptor sampler_desc = {};
- sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
- sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
- sampler_desc.magFilter = WGPUFilterMode_Linear;
- sampler_desc.minFilter = WGPUFilterMode_Linear;
- sampler_desc.maxAnisotropy = 1;
- sampler_ = wgpuDeviceCreateSampler(ctx_.device, &sampler_desc);
-
- // Init uniform buffers
- params_buffer_.init(ctx_.device);
- uniforms_buffer_.init(ctx_.device);
}
void GaussianBlur::render(WGPUCommandEncoder encoder,
diff --git a/src/effects/gaussian_blur_effect.h b/src/effects/gaussian_blur_effect.h
index cc9ff56..f4b8fcf 100644
--- a/src/effects/gaussian_blur_effect.h
+++ b/src/effects/gaussian_blur_effect.h
@@ -26,8 +26,6 @@ class GaussianBlur : public Effect {
private:
WGPURenderPipeline pipeline_;
WGPUBindGroup bind_group_;
- WGPUSampler sampler_;
GaussianBlurParams blur_params_;
UniformBuffer<GaussianBlurParams> params_buffer_;
- UniformBuffer<UniformsSequenceParams> uniforms_buffer_;
};
diff --git a/src/effects/heptagon_effect.cc b/src/effects/heptagon_effect.cc
index c472f2f..46d6f7f 100644
--- a/src/effects/heptagon_effect.cc
+++ b/src/effects/heptagon_effect.cc
@@ -10,37 +10,15 @@ Heptagon::Heptagon(const GpuContext& ctx,
const std::vector<std::string>& inputs,
const std::vector<std::string>& outputs, float start_time,
float end_time)
- : Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr), bind_group_(nullptr),
- sampler_(nullptr) {
- // Headless mode: skip GPU resource creation (compiled out in STRIP_ALL)
+ : Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr), bind_group_(nullptr) {
HEADLESS_RETURN_IF_NULL(ctx_.device);
- // Init uniforms
- uniforms_buffer_.init(ctx_.device);
+ init_uniforms_buffer();
+ create_nearest_sampler();
+ create_dummy_scene_texture();
- // Create pipeline (standard post-process, no depth)
pipeline_ = create_post_process_pipeline(
ctx_.device, WGPUTextureFormat_RGBA8Unorm, heptagon_shader_wgsl);
-
- // Create dummy sampler (scene effects don't use texture input)
- WGPUSamplerDescriptor sampler_desc = {};
- sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
- sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
- sampler_desc.magFilter = WGPUFilterMode_Nearest;
- sampler_desc.minFilter = WGPUFilterMode_Nearest;
- sampler_desc.maxAnisotropy = 1;
- sampler_ = wgpuDeviceCreateSampler(ctx_.device, &sampler_desc);
-
- // Create 1×1 dummy texture
- WGPUTextureDescriptor tex_desc = {};
- tex_desc.size = {1, 1, 1};
- tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
- tex_desc.usage = WGPUTextureUsage_TextureBinding;
- tex_desc.dimension = WGPUTextureDimension_2D;
- tex_desc.mipLevelCount = 1;
- tex_desc.sampleCount = 1;
- dummy_texture_ = wgpuDeviceCreateTexture(ctx_.device, &tex_desc);
- dummy_texture_view_ = wgpuTextureCreateView(dummy_texture_, nullptr);
}
Heptagon::~Heptagon() {
diff --git a/src/effects/heptagon_effect.h b/src/effects/heptagon_effect.h
index ef05d79..4b7b887 100644
--- a/src/effects/heptagon_effect.h
+++ b/src/effects/heptagon_effect.h
@@ -18,8 +18,4 @@ class Heptagon : public Effect {
private:
WGPURenderPipeline pipeline_;
WGPUBindGroup bind_group_;
- WGPUSampler sampler_;
- WGPUTexture dummy_texture_;
- WGPUTextureView dummy_texture_view_;
- UniformBuffer<UniformsSequenceParams> uniforms_buffer_;
};
diff --git a/src/effects/particles_effect.cc b/src/effects/particles_effect.cc
index d83f303..3c9feb7 100644
--- a/src/effects/particles_effect.cc
+++ b/src/effects/particles_effect.cc
@@ -12,11 +12,9 @@ Particles::Particles(const GpuContext& ctx,
const std::vector<std::string>& outputs, float start_time,
float end_time)
: Effect(ctx, inputs, outputs, start_time, end_time) {
- // Headless mode: skip GPU resource creation (compiled out in STRIP_ALL)
HEADLESS_RETURN_IF_NULL(ctx_.device);
- // Initialize uniforms
- uniforms_.init(ctx_.device);
+ init_uniforms_buffer();
// Initialize particles buffer
std::vector<Particle> init_p(NUM_PARTICLES);
@@ -49,7 +47,7 @@ Particles::Particles(const GpuContext& ctx,
// Create compute shader (particle simulation)
ResourceBinding compute_bindings[] = {
{particles_buffer_, WGPUBufferBindingType_Storage},
- {uniforms_.get(), WGPUBufferBindingType_Uniform}};
+ {uniforms_buffer_.get(), WGPUBufferBindingType_Uniform}};
compute_pass_ = gpu_create_compute_pass(ctx_.device, particle_compute_wgsl,
compute_bindings, 2);
compute_pass_.workgroup_size_x = (NUM_PARTICLES + 63) / 64;
@@ -57,7 +55,7 @@ Particles::Particles(const GpuContext& ctx,
// Create render shader (particle rendering)
ResourceBinding render_bindings[] = {
{particles_buffer_, WGPUBufferBindingType_ReadOnlyStorage},
- {uniforms_.get(), WGPUBufferBindingType_Uniform}};
+ {uniforms_buffer_.get(), WGPUBufferBindingType_Uniform}};
render_pass_ =
gpu_create_render_pass(ctx_.device, WGPUTextureFormat_RGBA8Unorm,
particle_render_wgsl, render_bindings, 2);
@@ -69,7 +67,7 @@ void Particles::render(WGPUCommandEncoder encoder,
const UniformsSequenceParams& params,
NodeRegistry& nodes) {
// Update uniforms
- uniforms_.update(ctx_.queue, params);
+ uniforms_buffer_.update(ctx_.queue, params);
// Run compute pass (particle simulation)
WGPUComputePassEncoder compute =
diff --git a/src/effects/particles_effect.h b/src/effects/particles_effect.h
index 38c60d7..e855b7b 100644
--- a/src/effects/particles_effect.h
+++ b/src/effects/particles_effect.h
@@ -30,5 +30,4 @@ class Particles : public Effect {
ComputePass compute_pass_;
RenderPass render_pass_;
GpuBuffer particles_buffer_;
- UniformBuffer<UniformsSequenceParams> uniforms_;
};
diff --git a/src/effects/passthrough_effect.cc b/src/effects/passthrough_effect.cc
index b9d9337..02f14da 100644
--- a/src/effects/passthrough_effect.cc
+++ b/src/effects/passthrough_effect.cc
@@ -10,26 +10,14 @@ Passthrough::Passthrough(const GpuContext& ctx,
const std::vector<std::string>& outputs,
float start_time, float end_time)
: Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr),
- bind_group_(nullptr), sampler_(nullptr) {
- // Headless mode: skip GPU resource creation (compiled out in STRIP_ALL)
+ bind_group_(nullptr) {
HEADLESS_RETURN_IF_NULL(ctx_.device);
- // Init uniform buffer
- uniforms_buffer_.init(ctx_.device);
- // Create pipeline (simple version without effect params)
+ init_uniforms_buffer();
+ create_linear_sampler();
+
pipeline_ = create_post_process_pipeline_simple(
ctx_.device, WGPUTextureFormat_RGBA8Unorm, passthrough_shader_wgsl);
-
- // Create sampler
- WGPUSamplerDescriptor sampler_desc = {};
- sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
- sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
- sampler_desc.addressModeW = WGPUAddressMode_ClampToEdge;
- sampler_desc.magFilter = WGPUFilterMode_Linear;
- sampler_desc.minFilter = WGPUFilterMode_Linear;
- sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Nearest;
- sampler_desc.maxAnisotropy = 1;
- sampler_ = wgpuDeviceCreateSampler(ctx_.device, &sampler_desc);
}
void Passthrough::render(WGPUCommandEncoder encoder,
diff --git a/src/effects/passthrough_effect.h b/src/effects/passthrough_effect.h
index f684b9b..3813fa8 100644
--- a/src/effects/passthrough_effect.h
+++ b/src/effects/passthrough_effect.h
@@ -17,6 +17,4 @@ class Passthrough : public Effect {
private:
WGPURenderPipeline pipeline_;
WGPUBindGroup bind_group_;
- WGPUSampler sampler_;
- UniformBuffer<UniformsSequenceParams> uniforms_buffer_;
};
diff --git a/src/effects/peak_meter_effect.cc b/src/effects/peak_meter_effect.cc
index d823e20..d077302 100644
--- a/src/effects/peak_meter_effect.cc
+++ b/src/effects/peak_meter_effect.cc
@@ -12,7 +12,7 @@ PeakMeter::PeakMeter(const GpuContext& ctx,
: Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr), bind_group_(nullptr) {
HEADLESS_RETURN_IF_NULL(ctx_.device);
- uniforms_buffer_.init(ctx_.device);
+ init_uniforms_buffer();
const char* shader_main = R"(
struct VertexOutput {
diff --git a/src/effects/peak_meter_effect.h b/src/effects/peak_meter_effect.h
index e397a71..1786522 100644
--- a/src/effects/peak_meter_effect.h
+++ b/src/effects/peak_meter_effect.h
@@ -18,5 +18,4 @@ class PeakMeter : public Effect {
private:
WGPURenderPipeline pipeline_;
WGPUBindGroup bind_group_;
- UniformBuffer<UniformsSequenceParams> uniforms_buffer_;
};
diff --git a/src/effects/placeholder_effect.cc b/src/effects/placeholder_effect.cc
index 3367f1c..e024a6b 100644
--- a/src/effects/placeholder_effect.cc
+++ b/src/effects/placeholder_effect.cc
@@ -12,26 +12,16 @@ Placeholder::Placeholder(const GpuContext& ctx,
float start_time, float end_time,
const char* placeholder_name)
: Effect(ctx, inputs, outputs, start_time, end_time), pipeline_(nullptr),
- bind_group_(nullptr), sampler_(nullptr), name_(placeholder_name) {
- // Log once on construction
+ bind_group_(nullptr), name_(placeholder_name) {
fprintf(stderr, "TODO: %s not yet implemented, using passthrough\n", name_);
- // Headless mode: skip GPU resource creation (compiled out in STRIP_ALL)
HEADLESS_RETURN_IF_NULL(ctx_.device);
- uniforms_buffer_.init(ctx_.device);
+ init_uniforms_buffer();
+ create_linear_sampler();
+
pipeline_ = create_post_process_pipeline(
ctx_.device, WGPUTextureFormat_RGBA8Unorm, passthrough_shader_wgsl);
-
- WGPUSamplerDescriptor sampler_desc = {};
- sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
- sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
- sampler_desc.addressModeW = WGPUAddressMode_ClampToEdge;
- sampler_desc.magFilter = WGPUFilterMode_Linear;
- sampler_desc.minFilter = WGPUFilterMode_Linear;
- sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Nearest;
- sampler_desc.maxAnisotropy = 1;
- sampler_ = wgpuDeviceCreateSampler(ctx_.device, &sampler_desc);
}
void Placeholder::render(WGPUCommandEncoder encoder,
diff --git a/src/effects/placeholder_effect.h b/src/effects/placeholder_effect.h
index 24cf3f4..72b156f 100644
--- a/src/effects/placeholder_effect.h
+++ b/src/effects/placeholder_effect.h
@@ -18,7 +18,5 @@ class Placeholder : public Effect {
private:
WGPURenderPipeline pipeline_;
WGPUBindGroup bind_group_;
- WGPUSampler sampler_;
- UniformBuffer<UniformsSequenceParams> uniforms_buffer_;
const char* name_;
};
diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc
index 752dd84..cd4bc16 100644
--- a/src/gpu/effect.cc
+++ b/src/gpu/effect.cc
@@ -14,6 +14,7 @@ Effect::Effect(const GpuContext& ctx, const std::vector<std::string>& inputs,
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,
@@ -55,3 +56,21 @@ void Effect::blit_input_to_output(WGPUCommandEncoder encoder,
wgpuCommandEncoderCopyTextureToTexture(encoder, &src_copy, &dst_copy,
&extent);
}
+
+void Effect::init_uniforms_buffer() {
+ uniforms_buffer_.init(ctx_.device);
+}
+
+void Effect::create_linear_sampler() {
+ sampler_ = gpu_create_linear_sampler(ctx_.device);
+}
+
+void Effect::create_nearest_sampler() {
+ sampler_ = gpu_create_nearest_sampler(ctx_.device);
+}
+
+void Effect::create_dummy_scene_texture() {
+ TextureWithView dummy = gpu_create_dummy_scene_texture(ctx_.device);
+ dummy_texture_ = dummy.texture;
+ dummy_texture_view_ = dummy.view;
+}
diff --git a/src/gpu/effect.h b/src/gpu/effect.h
index f5cdf2d..82aa6e1 100644
--- a/src/gpu/effect.h
+++ b/src/gpu/effect.h
@@ -6,6 +6,7 @@
#include "gpu/gpu.h"
#include "gpu/sequence.h"
+#include "gpu/uniform_helper.h"
#include <string>
#include <vector>
@@ -51,6 +52,24 @@ class Effect {
int width_ = 1280;
int height_ = 720;
+ // Common resources for most effects
+ UniformBuffer<UniformsSequenceParams> uniforms_buffer_;
+ WGPUSampler sampler_ = nullptr;
+ WGPUTexture dummy_texture_ = nullptr;
+ WGPUTextureView dummy_texture_view_ = nullptr;
+
+ // Helper: Initialize uniforms buffer (call in subclass constructor)
+ void init_uniforms_buffer();
+
+ // Helper: Create linear sampler (call in subclass constructor)
+ void create_linear_sampler();
+
+ // Helper: Create nearest sampler (call in subclass constructor)
+ void create_nearest_sampler();
+
+ // Helper: Create dummy texture for scene effects (call in subclass constructor)
+ void create_dummy_scene_texture();
+
private:
float start_time_;
float end_time_;
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc
index 2226889..e743bf7 100644
--- a/src/gpu/gpu.cc
+++ b/src/gpu/gpu.cc
@@ -124,6 +124,41 @@ WGPUTextureView gpu_create_texture_view_2d(WGPUTexture texture,
return wgpuTextureCreateView(texture, &view_desc);
}
+WGPUSampler gpu_create_linear_sampler(WGPUDevice device) {
+ WGPUSamplerDescriptor desc = {};
+ desc.addressModeU = WGPUAddressMode_ClampToEdge;
+ desc.addressModeV = WGPUAddressMode_ClampToEdge;
+ desc.addressModeW = WGPUAddressMode_ClampToEdge;
+ desc.magFilter = WGPUFilterMode_Linear;
+ desc.minFilter = WGPUFilterMode_Linear;
+ desc.mipmapFilter = WGPUMipmapFilterMode_Nearest;
+ desc.maxAnisotropy = 1;
+ return wgpuDeviceCreateSampler(device, &desc);
+}
+
+WGPUSampler gpu_create_nearest_sampler(WGPUDevice device) {
+ WGPUSamplerDescriptor desc = {};
+ desc.addressModeU = WGPUAddressMode_ClampToEdge;
+ desc.addressModeV = WGPUAddressMode_ClampToEdge;
+ desc.magFilter = WGPUFilterMode_Nearest;
+ desc.minFilter = WGPUFilterMode_Nearest;
+ desc.maxAnisotropy = 1;
+ return wgpuDeviceCreateSampler(device, &desc);
+}
+
+TextureWithView gpu_create_dummy_scene_texture(WGPUDevice device) {
+ WGPUTextureDescriptor desc = {};
+ desc.size = {1, 1, 1};
+ desc.format = WGPUTextureFormat_RGBA8Unorm;
+ desc.usage = WGPUTextureUsage_TextureBinding;
+ desc.dimension = WGPUTextureDimension_2D;
+ desc.mipLevelCount = 1;
+ desc.sampleCount = 1;
+ WGPUTexture texture = wgpuDeviceCreateTexture(device, &desc);
+ WGPUTextureView view = wgpuTextureCreateView(texture, nullptr);
+ return {texture, view};
+}
+
RenderPass gpu_create_render_pass(WGPUDevice device, WGPUTextureFormat format,
const char* shader_code,
ResourceBinding* bindings, int num_bindings) {
diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h
index 9a3fd38..d6c0255 100644
--- a/src/gpu/gpu.h
+++ b/src/gpu/gpu.h
@@ -97,4 +97,11 @@ RenderPass
gpu_create_render_pass(WGPUDevice device,
WGPUTextureFormat format, // Needed for render pipeline
const char* shader_code, ResourceBinding* bindings,
- int num_bindings); \ No newline at end of file
+ int num_bindings);
+
+// Common sampler configurations
+WGPUSampler gpu_create_linear_sampler(WGPUDevice device);
+WGPUSampler gpu_create_nearest_sampler(WGPUDevice device);
+
+// Dummy 1x1 texture for scene effects (don't need texture input)
+TextureWithView gpu_create_dummy_scene_texture(WGPUDevice device); \ No newline at end of file