diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/effects/flash_effect.cc | 28 | ||||
| -rw-r--r-- | src/effects/flash_effect.h | 4 | ||||
| -rw-r--r-- | src/effects/gaussian_blur_effect.cc | 22 | ||||
| -rw-r--r-- | src/effects/gaussian_blur_effect.h | 2 | ||||
| -rw-r--r-- | src/effects/heptagon_effect.cc | 30 | ||||
| -rw-r--r-- | src/effects/heptagon_effect.h | 4 | ||||
| -rw-r--r-- | src/effects/particles_effect.cc | 10 | ||||
| -rw-r--r-- | src/effects/particles_effect.h | 1 | ||||
| -rw-r--r-- | src/effects/passthrough_effect.cc | 20 | ||||
| -rw-r--r-- | src/effects/passthrough_effect.h | 2 | ||||
| -rw-r--r-- | src/effects/peak_meter_effect.cc | 2 | ||||
| -rw-r--r-- | src/effects/peak_meter_effect.h | 1 | ||||
| -rw-r--r-- | src/effects/placeholder_effect.cc | 18 | ||||
| -rw-r--r-- | src/effects/placeholder_effect.h | 2 | ||||
| -rw-r--r-- | src/gpu/effect.cc | 19 | ||||
| -rw-r--r-- | src/gpu/effect.h | 19 | ||||
| -rw-r--r-- | src/gpu/gpu.cc | 35 | ||||
| -rw-r--r-- | src/gpu/gpu.h | 9 |
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 |
