• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #ifndef LIBANGLE_RENDERER_WGPU_PIPELINE_STATE_H_
8 #define LIBANGLE_RENDERER_WGPU_PIPELINE_STATE_H_
9 
10 #include <dawn/webgpu_cpp.h>
11 #include <stdint.h>
12 #include <limits>
13 
14 #include "libANGLE/Constants.h"
15 #include "libANGLE/Error.h"
16 #include "libANGLE/angletypes.h"
17 
18 #include "common/PackedEnums.h"
19 
20 namespace rx
21 {
22 class ContextWgpu;
23 
24 namespace webgpu
25 {
26 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
27 
28 constexpr uint32_t kPrimitiveTopologyBitCount = 3;
29 constexpr uint32_t kIndexFormatBitCount       = 1;
30 constexpr uint32_t kFrontFaceBitCount         = 1;
31 constexpr uint32_t kCullModeBitCount          = 2;
32 
33 struct PackedPrimitiveState final
34 {
35     uint8_t topology : kPrimitiveTopologyBitCount;
36     uint8_t stripIndexFormat : kIndexFormatBitCount;
37     uint8_t frontFace : kFrontFaceBitCount;
38     uint8_t cullMode : kCullModeBitCount;
39     uint8_t pad0 : 1;
40 };
41 
42 constexpr size_t kPackedPrimitiveStateSize = sizeof(PackedPrimitiveState);
43 static_assert(kPackedPrimitiveStateSize == 1, "Size mismatch");
44 
45 constexpr uint32_t kTextureFormatBitCount  = 19;
46 constexpr uint32_t kColorWriteMaskBitCount = 4;
47 constexpr uint32_t kBlendFactorBitCount    = 5;
48 constexpr uint32_t kBlendOperationBitCount = 3;
49 
50 struct PackedColorTargetState final
51 {
52     uint32_t format : kTextureFormatBitCount;
53     uint32_t blendEnabled : 1;
54     uint32_t colorBlendSrcFactor : kBlendFactorBitCount;
55     uint32_t colorBlendDstFactor : kBlendFactorBitCount;
56     uint32_t pad0 : 2;
57     uint32_t colorBlendOp : kBlendOperationBitCount;
58     uint32_t alphaBlendSrcFactor : kBlendFactorBitCount;
59     uint32_t alphaBlendDstFactor : kBlendFactorBitCount;
60     uint32_t alphaBlendOp : kBlendOperationBitCount;
61     uint32_t writeMask : kColorWriteMaskBitCount;
62     uint32_t pad1 : 12;
63 };
64 
65 constexpr size_t kPackedColorTargetStateSize = sizeof(PackedColorTargetState);
66 static_assert(kPackedColorTargetStateSize == 8, "Size mismatch");
67 
68 constexpr uint32_t kCompareFunctionBitCount  = 4;
69 constexpr uint32_t kStencilOperationBitCount = 4;
70 
71 struct PackedDepthStencilState final
72 {
73     uint32_t format : kTextureFormatBitCount;
74 
75     uint32_t depthWriteEnabled : 1;
76     uint32_t depthCompare : kCompareFunctionBitCount;
77 
78     uint32_t stencilFrontCompare : kCompareFunctionBitCount;
79     uint32_t stencilFrontFailOp : kStencilOperationBitCount;
80     uint32_t stencilFrontDepthFailOp : kStencilOperationBitCount;
81     uint32_t stencilFrontPassOp : kStencilOperationBitCount;
82 
83     uint32_t stencilBackCompare : kCompareFunctionBitCount;
84     uint32_t stencilBackFailOp : kStencilOperationBitCount;
85     uint32_t stencilBackDepthFailOp : kStencilOperationBitCount;
86     uint32_t stencilBackPassOp : kStencilOperationBitCount;
87 
88     uint32_t pad0 : 8;
89 
90     uint8_t stencilReadMask;
91     uint8_t stencilWriteMask;
92 
93     uint8_t pad1[2];
94 
95     int32_t depthBias;
96     float depthBiasSlopeScalef;
97     float depthBiasClamp;
98 };
99 
100 constexpr size_t kPackedDepthStencilStateSize = sizeof(PackedDepthStencilState);
101 static_assert(kPackedDepthStencilStateSize == 24, "Size mismatch");
102 
103 constexpr uint32_t kVertexFormatBitCount = 5;
104 
105 // A maximum offset of 4096 covers almost every Vulkan driver on desktop (80%) and mobile (99%). The
106 // next highest values to meet native drivers are 16 bits or 32 bits.
107 constexpr uint32_t kAttributeOffsetMaxBits = 15;
108 
109 // In WebGPU, the maxVertexBufferArrayStride will be at least 2048.
110 constexpr uint32_t kVertexAttributeStrideBits = 16;
111 
112 struct PackedVertexAttribute final
113 {
114     PackedVertexAttribute();
115 
116     uint16_t offset : kAttributeOffsetMaxBits;
117     uint16_t enabled : 1;
118     uint8_t format : kVertexFormatBitCount;
119     uint8_t pad1 : 3;
120     uint8_t shaderLocation;
121     uint16_t stride : kVertexAttributeStrideBits;
122 };
123 
124 constexpr size_t kPackedVertexAttributeSize = sizeof(PackedVertexAttribute);
125 static_assert(kPackedVertexAttributeSize == 6, "Size mismatch");
126 
127 class RenderPipelineDesc final
128 {
129   public:
130     RenderPipelineDesc();
131     ~RenderPipelineDesc();
132     RenderPipelineDesc(const RenderPipelineDesc &other);
133     RenderPipelineDesc &operator=(const RenderPipelineDesc &other);
134 
135     // Returns true if the pipeline description has changed
136 
137     bool setPrimitiveMode(gl::PrimitiveMode primitiveMode, gl::DrawElementsType indexTypeOrInvalid);
138 
139     void setFrontFace(GLenum frontFace);
140     void setCullMode(gl::CullFaceMode cullMode, bool cullFaceEnabled);
141     void setColorWriteMask(size_t colorIndex, bool r, bool g, bool b, bool a);
142 
143     bool setBlendEnabled(size_t colorIndex, bool enabled);
144     bool setBlendFuncs(size_t colorIndex,
145                        wgpu::BlendFactor srcRGB,
146                        wgpu::BlendFactor dstRGB,
147                        wgpu::BlendFactor srcAlpha,
148                        wgpu::BlendFactor dstAlpha);
149     bool setBlendEquations(size_t colorIndex, wgpu::BlendOperation rgb, wgpu::BlendOperation alpha);
150 
151     bool setVertexAttribute(size_t attribIndex, PackedVertexAttribute &newAttrib);
152     bool setColorAttachmentFormat(size_t colorIndex, wgpu::TextureFormat format);
153     bool setDepthStencilAttachmentFormat(wgpu::TextureFormat format);
154     bool setDepthFunc(wgpu::CompareFunction compareFunc);
155     bool setStencilFrontFunc(wgpu::CompareFunction compareFunc);
156     bool setStencilFrontOps(wgpu::StencilOperation failOp,
157                             wgpu::StencilOperation depthFailOp,
158                             wgpu::StencilOperation passOp);
159     bool setStencilBackFunc(wgpu::CompareFunction compareFunc);
160     bool setStencilBackOps(wgpu::StencilOperation failOp,
161                            wgpu::StencilOperation depthFailOp,
162                            wgpu::StencilOperation passOp);
163 
164     bool setStencilReadMask(uint8_t readeMask);
165     bool setStencilWriteMask(uint8_t writeMask);
166 
167     size_t hash() const;
168 
169     angle::Result createPipeline(ContextWgpu *context,
170                                  const wgpu::PipelineLayout &pipelineLayout,
171                                  const gl::ShaderMap<wgpu::ShaderModule> &shaders,
172                                  wgpu::RenderPipeline *pipelineOut) const;
173 
174   private:
175     PackedVertexAttribute mVertexAttributes[gl::MAX_VERTEX_ATTRIBS];
176     PackedColorTargetState mColorTargetStates[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
177     PackedDepthStencilState mDepthStencilState;
178     PackedPrimitiveState mPrimitiveState;
179     uint8_t mPad0[3];
180 };
181 
182 constexpr size_t kRenderPipelineDescSize = sizeof(RenderPipelineDesc);
183 static_assert(kRenderPipelineDescSize % 4 == 0,
184               "RenderPipelineDesc size must be a multiple of 4 bytes.");
185 
186 bool operator==(const RenderPipelineDesc &lhs, const RenderPipelineDesc &rhs);
187 
188 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
189 
190 }  // namespace webgpu
191 }  // namespace rx
192 
193 // Introduce std::hash for the above classes.
194 namespace std
195 {
196 template <>
197 struct hash<rx::webgpu::RenderPipelineDesc>
198 {
199     size_t operator()(const rx::webgpu::RenderPipelineDesc &key) const { return key.hash(); }
200 };
201 }  // namespace std
202 
203 namespace rx
204 {
205 namespace webgpu
206 {
207 
208 class PipelineCache final
209 {
210   public:
211     PipelineCache();
212     ~PipelineCache();
213 
214     angle::Result getRenderPipeline(ContextWgpu *context,
215                                     const RenderPipelineDesc &desc,
216                                     const wgpu::PipelineLayout &pipelineLayout,
217                                     const gl::ShaderMap<wgpu::ShaderModule> &shaders,
218                                     wgpu::RenderPipeline *pipelineOut);
219 
220   private:
221     std::unordered_map<RenderPipelineDesc, wgpu::RenderPipeline> mRenderPipelines;
222 };
223 
224 }  // namespace webgpu
225 
226 }  // namespace rx
227 
228 #endif  // LIBANGLE_RENDERER_WGPU_PIPELINE_STATE_H_
229