diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-28 08:45:28 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-28 08:45:28 +0100 |
| commit | e07f87cba89ef738781399b079840615f27e1667 (patch) | |
| tree | 8a6cd84a3e9b40e781300c3acccc8ad0f7300b7b /src/gpu/pipeline_builder.cc | |
| parent | af06b3512598c81c472fdbbeb4994c7eb8621d4c (diff) | |
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.
Diffstat (limited to 'src/gpu/pipeline_builder.cc')
| -rw-r--r-- | src/gpu/pipeline_builder.cc | 91 |
1 files changed, 91 insertions, 0 deletions
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; +} |
