summaryrefslogtreecommitdiff
path: root/src/gpu/sampler_cache.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/sampler_cache.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/sampler_cache.h')
-rw-r--r--src/gpu/sampler_cache.h61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/gpu/sampler_cache.h b/src/gpu/sampler_cache.h
new file mode 100644
index 0000000..0f012a8
--- /dev/null
+++ b/src/gpu/sampler_cache.h
@@ -0,0 +1,61 @@
+// Sampler cache - deduplicates samplers across effects
+#pragma once
+#include <map>
+
+// Forward declarations (users must include gpu.h)
+struct WGPUDeviceImpl;
+typedef struct WGPUDeviceImpl* WGPUDevice;
+struct WGPUSamplerImpl;
+typedef struct WGPUSamplerImpl* WGPUSampler;
+
+#include "platform/platform.h"
+
+struct SamplerSpec {
+ WGPUAddressMode u, v;
+ WGPUFilterMode mag, min;
+ uint16_t anisotropy;
+
+ bool operator<(const SamplerSpec& o) const {
+ if (u != o.u) return u < o.u;
+ if (v != o.v) return v < o.v;
+ if (mag != o.mag) return mag < o.mag;
+ if (min != o.min) return min < o.min;
+ return anisotropy < o.anisotropy;
+ }
+};
+
+class SamplerCache {
+ std::map<SamplerSpec, WGPUSampler> cache_;
+ SamplerCache() = default;
+
+public:
+ static SamplerCache& Get() {
+ static SamplerCache instance;
+ return instance;
+ }
+
+ WGPUSampler get_or_create(WGPUDevice device, const SamplerSpec& spec) {
+ auto it = cache_.find(spec);
+ if (it != cache_.end()) return it->second;
+
+ WGPUSamplerDescriptor desc{};
+ desc.addressModeU = spec.u;
+ desc.addressModeV = spec.v;
+ desc.magFilter = spec.mag;
+ desc.minFilter = spec.min;
+ desc.maxAnisotropy = spec.anisotropy;
+ WGPUSampler sampler = wgpuDeviceCreateSampler(device, &desc);
+ cache_[spec] = sampler;
+ return sampler;
+ }
+
+ // Common presets
+ static SamplerSpec linear() {
+ return {WGPUAddressMode_Repeat, WGPUAddressMode_Repeat,
+ WGPUFilterMode_Linear, WGPUFilterMode_Linear, 1};
+ }
+ static SamplerSpec clamp() {
+ return {WGPUAddressMode_ClampToEdge, WGPUAddressMode_ClampToEdge,
+ WGPUFilterMode_Linear, WGPUFilterMode_Linear, 1};
+ }
+};