From e07f87cba89ef738781399b079840615f27e1667 Mon Sep 17 00:00:00 2001 From: skal Date: Sat, 28 Feb 2026 08:45:28 +0100 Subject: refactor(gpu): move RenderPipelineBuilder impl to pipeline_builder.cc Keeps .h as declarations only; moves all method bodies to .cc. Adds pipeline_builder.cc to COMMON_GPU_EFFECTS in DemoSourceLists.cmake. handoff(Claude): pipeline_builder split to .h/.cc, builds clean. --- src/gpu/pipeline_builder.cc | 91 +++++++++++++++++++++++++++++++++++++++ src/gpu/pipeline_builder.h | 101 +++++--------------------------------------- 2 files changed, 101 insertions(+), 91 deletions(-) create mode 100644 src/gpu/pipeline_builder.cc (limited to 'src') diff --git a/src/gpu/pipeline_builder.cc b/src/gpu/pipeline_builder.cc new file mode 100644 index 0000000..b3fa5f8 --- /dev/null +++ b/src/gpu/pipeline_builder.cc @@ -0,0 +1,91 @@ +// WGPU render pipeline builder - implementation +#include "gpu/pipeline_builder.h" +#include "util/fatal_error.h" + +RenderPipelineBuilder::RenderPipelineBuilder(WGPUDevice device) + : device_(device) { + desc_.primitive.topology = WGPUPrimitiveTopology_TriangleList; + desc_.primitive.cullMode = WGPUCullMode_None; + desc_.multisample.count = 1; + desc_.multisample.mask = 0xFFFFFFFF; +} + +RenderPipelineBuilder& RenderPipelineBuilder::shader(const char* wgsl, + bool compose) { + shader_text_ = compose ? ShaderComposer::Get().Compose({}, wgsl) : wgsl; + if (device_ == nullptr) + return *this; + WGPUShaderSourceWGSL wgsl_src{}; + wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; + wgsl_src.code = str_view(shader_text_.c_str()); + WGPUShaderModuleDescriptor shader_desc{}; + shader_desc.nextInChain = &wgsl_src.chain; + shader_module_ = wgpuDeviceCreateShaderModule(device_, &shader_desc); + desc_.vertex.module = shader_module_; + desc_.vertex.entryPoint = str_view("vs_main"); + return *this; +} + +RenderPipelineBuilder& RenderPipelineBuilder::bind_group_layout( + WGPUBindGroupLayout layout) { + layouts_.push_back(layout); + return *this; +} + +RenderPipelineBuilder& RenderPipelineBuilder::format(WGPUTextureFormat fmt) { + color_.format = fmt; + return *this; +} + +RenderPipelineBuilder& RenderPipelineBuilder::blend_alpha() { + has_blend_ = true; + blend_.color.operation = WGPUBlendOperation_Add; + blend_.color.srcFactor = WGPUBlendFactor_SrcAlpha; + blend_.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; + blend_.alpha.operation = WGPUBlendOperation_Add; + blend_.alpha.srcFactor = WGPUBlendFactor_One; + blend_.alpha.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; + return *this; +} + +RenderPipelineBuilder& RenderPipelineBuilder::depth( + WGPUTextureFormat depth_fmt) { + has_depth_ = true; + depth_.format = depth_fmt; + depth_.depthWriteEnabled = WGPUOptionalBool_True; + depth_.depthCompare = WGPUCompareFunction_Less; + return *this; +} + +RenderPipelineBuilder& RenderPipelineBuilder::cull_back() { + desc_.primitive.cullMode = WGPUCullMode_Back; + return *this; +} + +WGPURenderPipeline RenderPipelineBuilder::build() { + HEADLESS_RETURN_VAL_IF_NULL(device_, nullptr); + + color_.writeMask = WGPUColorWriteMask_All; + if (has_blend_) + color_.blend = &blend_; + + WGPUFragmentState fragment{}; + fragment.module = shader_module_; + fragment.entryPoint = str_view("fs_main"); + fragment.targetCount = 1; + fragment.targets = &color_; + + WGPUPipelineLayoutDescriptor pl_desc{}; + pl_desc.bindGroupLayoutCount = layouts_.size(); + pl_desc.bindGroupLayouts = layouts_.data(); + WGPUPipelineLayout layout = wgpuDeviceCreatePipelineLayout(device_, &pl_desc); + + desc_.layout = layout; + desc_.fragment = &fragment; + if (has_depth_) + desc_.depthStencil = &depth_; + + WGPURenderPipeline pipeline = wgpuDeviceCreateRenderPipeline(device_, &desc_); + wgpuPipelineLayoutRelease(layout); + return pipeline; +} diff --git a/src/gpu/pipeline_builder.h b/src/gpu/pipeline_builder.h index 937c55f..9fd76f9 100644 --- a/src/gpu/pipeline_builder.h +++ b/src/gpu/pipeline_builder.h @@ -3,7 +3,6 @@ #include #include -// Forward declarations (users must include gpu.h and shader_composer.h) struct WGPUDeviceImpl; typedef struct WGPUDeviceImpl* WGPUDevice; struct WGPUBindGroupLayoutImpl; @@ -15,7 +14,6 @@ typedef struct WGPUShaderModuleImpl* WGPUShaderModule; #include "gpu/shader_composer.h" #include "platform/platform.h" -#include "util/fatal_error.h" class RenderPipelineBuilder { WGPUDevice device_; @@ -30,93 +28,14 @@ class RenderPipelineBuilder { bool has_depth_ = false; public: - explicit RenderPipelineBuilder(WGPUDevice device) : device_(device) { - desc_.primitive.topology = WGPUPrimitiveTopology_TriangleList; - desc_.primitive.cullMode = WGPUCullMode_None; - desc_.multisample.count = 1; - desc_.multisample.mask = 0xFFFFFFFF; - } - - RenderPipelineBuilder& shader(const char* wgsl, bool compose = true) { - shader_text_ = compose ? ShaderComposer::Get().Compose({}, wgsl) : wgsl; - // Headless mode: skip shader module creation (compiled out in STRIP_ALL) - if (device_ == nullptr) { - return *this; - } - WGPUShaderSourceWGSL wgsl_src{}; - wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; - wgsl_src.code = str_view(shader_text_.c_str()); - WGPUShaderModuleDescriptor shader_desc{}; - shader_desc.nextInChain = &wgsl_src.chain; - shader_module_ = wgpuDeviceCreateShaderModule(device_, &shader_desc); - desc_.vertex.module = shader_module_; - desc_.vertex.entryPoint = str_view("vs_main"); - return *this; - } - - RenderPipelineBuilder& bind_group_layout(WGPUBindGroupLayout layout) { - layouts_.push_back(layout); - return *this; - } - - RenderPipelineBuilder& format(WGPUTextureFormat fmt) { - color_.format = fmt; - return *this; - } - - RenderPipelineBuilder& blend_alpha() { - has_blend_ = true; - blend_.color.operation = WGPUBlendOperation_Add; - blend_.color.srcFactor = WGPUBlendFactor_SrcAlpha; - blend_.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; - blend_.alpha.operation = WGPUBlendOperation_Add; - blend_.alpha.srcFactor = WGPUBlendFactor_One; - blend_.alpha.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; - return *this; - } - - RenderPipelineBuilder& - depth(WGPUTextureFormat depth_fmt = WGPUTextureFormat_Depth24Plus) { - has_depth_ = true; - depth_.format = depth_fmt; - depth_.depthWriteEnabled = WGPUOptionalBool_True; - depth_.depthCompare = WGPUCompareFunction_Less; - return *this; - } - - RenderPipelineBuilder& cull_back() { - desc_.primitive.cullMode = WGPUCullMode_Back; - return *this; - } - - WGPURenderPipeline build() { - // Headless mode: skip pipeline creation (compiled out in STRIP_ALL) - HEADLESS_RETURN_VAL_IF_NULL(device_, nullptr); - - color_.writeMask = WGPUColorWriteMask_All; - if (has_blend_) - color_.blend = &blend_; - - WGPUFragmentState fragment{}; - fragment.module = shader_module_; - fragment.entryPoint = str_view("fs_main"); - fragment.targetCount = 1; - fragment.targets = &color_; - - WGPUPipelineLayoutDescriptor pl_desc{}; - pl_desc.bindGroupLayoutCount = layouts_.size(); - pl_desc.bindGroupLayouts = layouts_.data(); - WGPUPipelineLayout layout = - wgpuDeviceCreatePipelineLayout(device_, &pl_desc); - - desc_.layout = layout; - desc_.fragment = &fragment; - if (has_depth_) - desc_.depthStencil = &depth_; - - WGPURenderPipeline pipeline = - wgpuDeviceCreateRenderPipeline(device_, &desc_); - wgpuPipelineLayoutRelease(layout); - return pipeline; - } + explicit RenderPipelineBuilder(WGPUDevice device); + + RenderPipelineBuilder& shader(const char* wgsl, bool compose = true); + RenderPipelineBuilder& bind_group_layout(WGPUBindGroupLayout layout); + RenderPipelineBuilder& format(WGPUTextureFormat fmt); + RenderPipelineBuilder& blend_alpha(); + RenderPipelineBuilder& depth( + WGPUTextureFormat depth_fmt = WGPUTextureFormat_Depth24Plus); + RenderPipelineBuilder& cull_back(); + WGPURenderPipeline build(); }; -- cgit v1.2.3