blob: 06b4cebb8f6da67672210b6efab760af336a76a3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
// WGPU render pipeline builder - reduces pipeline creation boilerplate
#pragma once
#include <vector>
#include <string>
// Forward declarations (users must include gpu.h and shader_composer.h)
struct WGPUDeviceImpl;
typedef struct WGPUDeviceImpl* WGPUDevice;
struct WGPUBindGroupLayoutImpl;
typedef struct WGPUBindGroupLayoutImpl* WGPUBindGroupLayout;
struct WGPURenderPipelineImpl;
typedef struct WGPURenderPipelineImpl* WGPURenderPipeline;
struct WGPUShaderModuleImpl;
typedef struct WGPUShaderModuleImpl* WGPUShaderModule;
#include "platform/platform.h"
#include "gpu/effects/shader_composer.h"
class RenderPipelineBuilder {
WGPUDevice device_;
WGPURenderPipelineDescriptor desc_{};
WGPUColorTargetState color_{};
WGPUBlendState blend_{};
WGPUDepthStencilState depth_{};
std::vector<WGPUBindGroupLayout> layouts_;
std::string shader_text_;
WGPUShaderModule shader_module_ = nullptr;
bool has_blend_ = false;
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;
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() {
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;
}
};
|