载入中...
搜索中...
未找到
PipelineBuilder.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4
5namespace eve::graphics::webgpu {
6
7PipelineBuilder &PipelineBuilder::vertexLayout(uint64_t stride, wgpu::VertexStepMode stepMode,
8 const wgpu::VertexAttribute *attrs,
9 size_t attrCount) {
10 wgpu::VertexBufferLayout l{};
11 l.arrayStride = stride;
12 l.stepMode = stepMode;
13 l.attributeCount = attrCount;
14 l.attributes = attrs;
15 vertexBuffers_.push_back(l);
16 return *this;
17}
18
19PipelineBuilder &PipelineBuilder::shader(wgpu::ShaderModule vert, const char *vertEntry,
20 wgpu::ShaderModule frag, const char *fragEntry) {
21 vertModule_ = vert;
22 fragModule_ = frag;
23 vertEntry_ = vertEntry;
24 fragEntry_ = fragEntry;
25 return *this;
26}
27
30 hasColorTarget_ = true;
31 colorFormat_ = static_cast<wgpu::TextureFormat>(format);
32 blendMode_ = mode;
33 return *this;
34}
35
36PipelineBuilder &PipelineBuilder::depth(WGPUTextureFormat format, wgpu::CompareFunction compare,
37 bool writeEnabled) {
38 hasDepth_ = true;
39 depthFormat_ = static_cast<wgpu::TextureFormat>(format);
40 depthCompare_ = compare;
41 depthWrite_ = writeEnabled;
42 return *this;
43}
44
45wgpu::RenderPipeline PipelineBuilder::build(const wgpu::Device &device) const {
46 if (!device) throw Exception("PipelineBuilder::build: null device");
47 if (!vertModule_) throw Exception("PipelineBuilder::build: no vertex shader");
48 if (!hasColorTarget_ && !hasDepth_)
49 throw Exception("PipelineBuilder::build: no color or depth target");
50
51 wgpu::RenderPipelineDescriptor d{};
52 d.label = label_;
53 d.layout = layout_;
54 d.multisample.count = sampleCount_;
55 // C++ wrapper default mask = 0xFFFFFFFF (all samples); zero-init is safe.
56
57 // Vertex state.
58 d.vertex.module = vertModule_;
59 d.vertex.entryPoint = vertEntry_;
60 d.vertex.bufferCount = static_cast<uint32_t>(vertexBuffers_.size());
61 d.vertex.buffers = vertexBuffers_.data();
62
63 // Primitive state.
64 d.primitive.topology = topology_;
65 d.primitive.frontFace = frontFace_;
66 d.primitive.cullMode = cullMode_;
67 d.primitive.stripIndexFormat = wgpu::IndexFormat::Undefined;
68
69 // Depth/stencil.
70 wgpu::DepthStencilState ds{};
71 if (hasDepth_) {
72 ds.format = depthFormat_;
73 ds.depthCompare = depthCompare_;
74 ds.depthWriteEnabled = depthWrite_;
75 d.depthStencil = &ds;
76 }
77
78 // Fragment state.
79 wgpu::ColorTargetState target{};
80 wgpu::FragmentState fs{};
81 wgpu::BlendState blend{};
82 if (hasColorTarget_) {
83 target.format = colorFormat_;
84 // C++ wrapper default writeMask = All; only override blend explicitly.
85 target.blend = nullptr;
86 switch (blendMode_) {
87 case eve::graphics::BlendMode::Alpha:
88 blend.color = {wgpu::BlendOperation::Add, wgpu::BlendFactor::SrcAlpha,
89 wgpu::BlendFactor::OneMinusSrcAlpha};
90 blend.alpha = {wgpu::BlendOperation::Add, wgpu::BlendFactor::One,
91 wgpu::BlendFactor::OneMinusSrcAlpha};
92 target.blend = &blend;
93 break;
94 case eve::graphics::BlendMode::Additive:
95 blend.color = {wgpu::BlendOperation::Add, wgpu::BlendFactor::SrcAlpha,
96 wgpu::BlendFactor::One};
97 blend.alpha = {wgpu::BlendOperation::Add, wgpu::BlendFactor::One,
98 wgpu::BlendFactor::One};
99 target.blend = &blend;
100 break;
101 case eve::graphics::BlendMode::Premultiplied:
102 blend.color = {wgpu::BlendOperation::Add, wgpu::BlendFactor::One,
103 wgpu::BlendFactor::OneMinusSrcAlpha};
104 blend.alpha = {wgpu::BlendOperation::Add, wgpu::BlendFactor::One,
105 wgpu::BlendFactor::OneMinusSrcAlpha};
106 target.blend = &blend;
107 break;
108 case eve::graphics::BlendMode::Multiply:
109 blend.color = {wgpu::BlendOperation::Add, wgpu::BlendFactor::Dst,
110 wgpu::BlendFactor::OneMinusSrcAlpha};
111 blend.alpha = {wgpu::BlendOperation::Add, wgpu::BlendFactor::One,
112 wgpu::BlendFactor::OneMinusSrcAlpha};
113 target.blend = &blend;
114 break;
115 case eve::graphics::BlendMode::Opaque:
116 default:
117 target.blend = nullptr;
118 break;
119 }
120 fs.module = fragModule_;
121 fs.entryPoint = fragEntry_;
122 fs.targetCount = 1;
123 fs.targets = &target;
124 d.fragment = &fs;
125 }
126
127 return device.CreateRenderPipeline(&d);
128}
129
130} // namespace eve::graphics::webgpu
LogicalId target
vkb::Device & device
vk::ShaderModule vert
vk::ShaderModule frag
float blend
float d
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
Fluent builder for wgpu::RenderPipeline.
PipelineBuilder & shader(wgpu::ShaderModule vert, const char *vertEntry, wgpu::ShaderModule frag, const char *fragEntry)
Shader.
PipelineBuilder & colorTarget(WGPUTextureFormat format, eve::graphics::BlendMode mode)
Set color target format + blend mode (Alpha default = no blend state override risk).
PipelineBuilder & vertexLayout(uint64_t stride, wgpu::VertexStepMode stepMode, const wgpu::VertexAttribute *attrs, size_t attrCount)
Vertex layout.
PipelineBuilder & depth(WGPUTextureFormat format, wgpu::CompareFunction compare, bool writeEnabled)
Depth.
wgpu::RenderPipeline build(const wgpu::Device &device) const
Create the pipeline. Throws on null device.
BlendMode
Render-neutral 2D blend mode shared by graphics-facing modules.
Definition RenderTypes.h:11