summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/DemoSourceLists.cmake1
-rw-r--r--src/gpu/pipeline_builder.cc91
-rw-r--r--src/gpu/pipeline_builder.h99
3 files changed, 101 insertions, 90 deletions
diff --git a/cmake/DemoSourceLists.cmake b/cmake/DemoSourceLists.cmake
index bf6b881..f4574c7 100644
--- a/cmake/DemoSourceLists.cmake
+++ b/cmake/DemoSourceLists.cmake
@@ -44,6 +44,7 @@ set(COMMON_GPU_EFFECTS
# cnn_v1/src/cnn_v1_effect.cc
# cnn_v2/src/cnn_v2_effect.cc
src/gpu/post_process_helper.cc
+ src/gpu/pipeline_builder.cc
src/gpu/sampler_cache.cc
src/effects/shaders.cc
src/gpu/shader_composer.cc
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 <string>
#include <vector>
-// 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;
- }
+ explicit RenderPipelineBuilder(WGPUDevice device);
- 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;
- }
+ 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();
};