From e7cd4d65f9f55ccc14045cbcac9d61358ba0c2bf Mon Sep 17 00:00:00 2001 From: skal Date: Tue, 10 Feb 2026 17:27:34 +0100 Subject: refactor: Factor WGPU boilerplate into builder pattern helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add BindGroupLayoutBuilder, BindGroupBuilder, RenderPipelineBuilder, and SamplerCache to reduce repetitive WGPU code. Refactor post_process_helper, cnn_effect, and rotating_cube_effect. Changes: - Bind group creation: 19 instances, 14→4 lines each - Pipeline creation: 30-50→8 lines - Sampler deduplication: 6 instances → cached - Total boilerplate reduction: -122 lines across 3 files Builder pattern prevents binding index errors and consolidates platform-specific #ifdef in fewer locations. Binary size unchanged (6.3M debug). Tests pass. Co-Authored-By: Claude Sonnet 4.5 --- src/gpu/bind_group_builder.h | 111 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/gpu/bind_group_builder.h (limited to 'src/gpu/bind_group_builder.h') diff --git a/src/gpu/bind_group_builder.h b/src/gpu/bind_group_builder.h new file mode 100644 index 0000000..d63f6e2 --- /dev/null +++ b/src/gpu/bind_group_builder.h @@ -0,0 +1,111 @@ +// WGPU bind group builder - reduces boilerplate for bind group creation +#pragma once +#include + +// Forward declarations (users must include gpu.h) +struct WGPUBindGroupLayoutEntry; +struct WGPUBindGroupEntry; +struct WGPUDeviceImpl; +typedef struct WGPUDeviceImpl* WGPUDevice; +struct WGPUBindGroupLayoutImpl; +typedef struct WGPUBindGroupLayoutImpl* WGPUBindGroupLayout; +struct WGPUBindGroupImpl; +typedef struct WGPUBindGroupImpl* WGPUBindGroup; +struct WGPUBufferImpl; +typedef struct WGPUBufferImpl* WGPUBuffer; +struct WGPUTextureViewImpl; +typedef struct WGPUTextureViewImpl* WGPUTextureView; +struct WGPUSamplerImpl; +typedef struct WGPUSamplerImpl* WGPUSampler; +typedef uint32_t WGPUShaderStageFlags; + +#include "platform/platform.h" + +class BindGroupLayoutBuilder { + std::vector entries_; + +public: + BindGroupLayoutBuilder& uniform(uint32_t binding, WGPUShaderStageFlags vis, size_t min_size = 0) { + WGPUBindGroupLayoutEntry e{}; + e.binding = binding; + e.visibility = vis; + e.buffer.type = WGPUBufferBindingType_Uniform; + if (min_size) e.buffer.minBindingSize = min_size; + entries_.push_back(e); + return *this; + } + + BindGroupLayoutBuilder& storage(uint32_t binding, WGPUShaderStageFlags vis, size_t min_size = 0) { + WGPUBindGroupLayoutEntry e{}; + e.binding = binding; + e.visibility = vis; + e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; + if (min_size) e.buffer.minBindingSize = min_size; + entries_.push_back(e); + return *this; + } + + BindGroupLayoutBuilder& texture(uint32_t binding, WGPUShaderStageFlags vis) { + WGPUBindGroupLayoutEntry e{}; + e.binding = binding; + e.visibility = vis; + e.texture.sampleType = WGPUTextureSampleType_Float; + e.texture.viewDimension = WGPUTextureViewDimension_2D; + entries_.push_back(e); + return *this; + } + + BindGroupLayoutBuilder& sampler(uint32_t binding, WGPUShaderStageFlags vis) { + WGPUBindGroupLayoutEntry e{}; + e.binding = binding; + e.visibility = vis; + e.sampler.type = WGPUSamplerBindingType_Filtering; + entries_.push_back(e); + return *this; + } + + WGPUBindGroupLayout build(WGPUDevice device) { + WGPUBindGroupLayoutDescriptor desc{}; + desc.entryCount = entries_.size(); + desc.entries = entries_.data(); + return wgpuDeviceCreateBindGroupLayout(device, &desc); + } +}; + +class BindGroupBuilder { + std::vector entries_; + +public: + BindGroupBuilder& buffer(uint32_t binding, WGPUBuffer buf, size_t size) { + WGPUBindGroupEntry e{}; + e.binding = binding; + e.buffer = buf; + e.size = size; + entries_.push_back(e); + return *this; + } + + BindGroupBuilder& texture(uint32_t binding, WGPUTextureView view) { + WGPUBindGroupEntry e{}; + e.binding = binding; + e.textureView = view; + entries_.push_back(e); + return *this; + } + + BindGroupBuilder& sampler(uint32_t binding, WGPUSampler samp) { + WGPUBindGroupEntry e{}; + e.binding = binding; + e.sampler = samp; + entries_.push_back(e); + return *this; + } + + WGPUBindGroup build(WGPUDevice device, WGPUBindGroupLayout layout) { + WGPUBindGroupDescriptor desc{}; + desc.layout = layout; + desc.entryCount = entries_.size(); + desc.entries = entries_.data(); + return wgpuDeviceCreateBindGroup(device, &desc); + } +}; -- cgit v1.2.3