summaryrefslogtreecommitdiff
path: root/src/gpu/bind_group_builder.h
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-10 17:27:34 +0100
committerskal <pascal.massimino@gmail.com>2026-02-10 17:27:34 +0100
commite7cd4d65f9f55ccc14045cbcac9d61358ba0c2bf (patch)
treec9365a3cb26953478a4bcaf684b7e2ec92442557 /src/gpu/bind_group_builder.h
parent61104d5b9e1774c11f0dba3b6d6018dabc2bce8f (diff)
refactor: Factor WGPU boilerplate into builder pattern helpers
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 <noreply@anthropic.com>
Diffstat (limited to 'src/gpu/bind_group_builder.h')
-rw-r--r--src/gpu/bind_group_builder.h111
1 files changed, 111 insertions, 0 deletions
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 <vector>
+
+// 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<WGPUBindGroupLayoutEntry> 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<WGPUBindGroupEntry> 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);
+ }
+};