xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/wgpu/wgpu_pipeline_state.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 setVertexAttribute(size_t attribIndex, PackedVertexAttribute &newAttrib);
144     bool setColorAttachmentFormat(size_t colorIndex, wgpu::TextureFormat format);
145     bool setDepthStencilAttachmentFormat(wgpu::TextureFormat format);
146     bool setDepthFunc(wgpu::CompareFunction compareFunc);
147     bool setStencilFrontFunc(wgpu::CompareFunction compareFunc);
148     bool setStencilFrontOps(wgpu::StencilOperation failOp,
149                             wgpu::StencilOperation depthFailOp,
150                             wgpu::StencilOperation passOp);
151     bool setStencilBackFunc(wgpu::CompareFunction compareFunc);
152     bool setStencilBackOps(wgpu::StencilOperation failOp,
153                            wgpu::StencilOperation depthFailOp,
154                            wgpu::StencilOperation passOp);
155 
156     bool setStencilReadMask(uint8_t readeMask);
157     bool setStencilWriteMask(uint8_t writeMask);
158 
159     size_t hash() const;
160 
161     angle::Result createPipeline(ContextWgpu *context,
162                                  const wgpu::PipelineLayout &pipelineLayout,
163                                  const gl::ShaderMap<wgpu::ShaderModule> &shaders,
164                                  wgpu::RenderPipeline *pipelineOut) const;
165 
166   private:
167     PackedVertexAttribute mVertexAttributes[gl::MAX_VERTEX_ATTRIBS];
168     PackedColorTargetState mColorTargetStates[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
169     PackedDepthStencilState mDepthStencilState;
170     PackedPrimitiveState mPrimitiveState;
171     uint8_t mPad0[3];
172 };
173 
174 constexpr size_t kRenderPipelineDescSize = sizeof(RenderPipelineDesc);
175 static_assert(kRenderPipelineDescSize % 4 == 0,
176               "RenderPipelineDesc size must be a multiple of 4 bytes.");
177 
178 bool operator==(const RenderPipelineDesc &lhs, const RenderPipelineDesc &rhs);
179 
180 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
181 
182 }  // namespace webgpu
183 }  // namespace rx
184 
185 // Introduce std::hash for the above classes.
186 namespace std
187 {
188 template <>
189 struct hash<rx::webgpu::RenderPipelineDesc>
190 {
191     size_t operator()(const rx::webgpu::RenderPipelineDesc &key) const { return key.hash(); }
192 };
193 }  // namespace std
194 
195 namespace rx
196 {
197 namespace webgpu
198 {
199 
200 class PipelineCache final
201 {
202   public:
203     PipelineCache();
204     ~PipelineCache();
205 
206     angle::Result getRenderPipeline(ContextWgpu *context,
207                                     const RenderPipelineDesc &desc,
208                                     const wgpu::PipelineLayout &pipelineLayout,
209                                     const gl::ShaderMap<wgpu::ShaderModule> &shaders,
210                                     wgpu::RenderPipeline *pipelineOut);
211 
212   private:
213     std::unordered_map<RenderPipelineDesc, wgpu::RenderPipeline> mRenderPipelines;
214 };
215 
216 }  // namespace webgpu
217 
218 }  // namespace rx
219 
220 #endif  // LIBANGLE_RENDERER_WGPU_PIPELINE_STATE_H_
221