1 /*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #ifndef skgpu_graphite_DrawTypes_DEFINED
9 #define skgpu_graphite_DrawTypes_DEFINED
10
11 #include "include/gpu/graphite/GraphiteTypes.h"
12
13 #include "include/core/SkSamplingOptions.h"
14 #include "include/core/SkTileMode.h"
15
16 #include "src/gpu/graphite/ResourceTypes.h"
17
18 #include <array>
19
20 namespace skgpu::graphite {
21
22 class Buffer;
23
24 enum class CType : unsigned {
25 // Any float/half, vector of floats/half, or matrices of floats/halfs are a tightly
26 // packed array of floats. Similarly, any bool/shorts/ints are a tightly packed array
27 // of int32_t.
28 kDefault,
29 // Can be used with kFloat3x3 or kHalf3x3
30 kSkMatrix,
31
32 kLast = kSkMatrix
33 };
34
35 /**
36 * Geometric primitives used for drawing.
37 */
38 enum class PrimitiveType : uint8_t {
39 kTriangles,
40 kTriangleStrip,
41 kPoints,
42 };
43
44 /**
45 * Types used to describe format of vertices in buffers.
46 */
47 enum class VertexAttribType : uint8_t {
48 kFloat = 0,
49 kFloat2,
50 kFloat3,
51 kFloat4,
52 kHalf,
53 kHalf2,
54 kHalf4,
55
56 kInt2, // vector of 2 32-bit ints
57 kInt3, // vector of 3 32-bit ints
58 kInt4, // vector of 4 32-bit ints
59
60 kByte, // signed byte
61 kByte2, // vector of 2 8-bit signed bytes
62 kByte4, // vector of 4 8-bit signed bytes
63 kUByte, // unsigned byte
64 kUByte2, // vector of 2 8-bit unsigned bytes
65 kUByte4, // vector of 4 8-bit unsigned bytes
66
67 kUByte_norm, // unsigned byte, e.g. coverage, 0 -> 0.0f, 255 -> 1.0f.
68 kUByte4_norm, // vector of 4 unsigned bytes, e.g. colors, 0 -> 0.0f, 255 -> 1.0f.
69
70 kShort2, // vector of 2 16-bit shorts.
71 kShort4, // vector of 4 16-bit shorts.
72
73 kUShort2, // vector of 2 unsigned shorts. 0 -> 0, 65535 -> 65535.
74 kUShort2_norm, // vector of 2 unsigned shorts. 0 -> 0.0f, 65535 -> 1.0f.
75
76 kInt,
77 kUInt,
78
79 kUShort_norm, // unsigned short, e.g. depth, 0 -> 0.0f, 65535 -> 1.0f.
80
81 kUShort4_norm, // vector of 4 unsigned shorts. 0 -> 0.0f, 65535 -> 1.0f.
82
83 kLast = kUShort4_norm
84 };
85 static const int kVertexAttribTypeCount = (int)(VertexAttribType::kLast) + 1;
86
87
88 /**
89 * Returns the size of the attrib type in bytes.
90 */
VertexAttribTypeSize(VertexAttribType type)91 static constexpr inline size_t VertexAttribTypeSize(VertexAttribType type) {
92 switch (type) {
93 case VertexAttribType::kFloat:
94 return sizeof(float);
95 case VertexAttribType::kFloat2:
96 return 2 * sizeof(float);
97 case VertexAttribType::kFloat3:
98 return 3 * sizeof(float);
99 case VertexAttribType::kFloat4:
100 return 4 * sizeof(float);
101 case VertexAttribType::kHalf:
102 return sizeof(uint16_t);
103 case VertexAttribType::kHalf2:
104 return 2 * sizeof(uint16_t);
105 case VertexAttribType::kHalf4:
106 return 4 * sizeof(uint16_t);
107 case VertexAttribType::kInt2:
108 return 2 * sizeof(int32_t);
109 case VertexAttribType::kInt3:
110 return 3 * sizeof(int32_t);
111 case VertexAttribType::kInt4:
112 return 4 * sizeof(int32_t);
113 case VertexAttribType::kByte:
114 return 1 * sizeof(char);
115 case VertexAttribType::kByte2:
116 return 2 * sizeof(char);
117 case VertexAttribType::kByte4:
118 return 4 * sizeof(char);
119 case VertexAttribType::kUByte:
120 return 1 * sizeof(char);
121 case VertexAttribType::kUByte2:
122 return 2 * sizeof(char);
123 case VertexAttribType::kUByte4:
124 return 4 * sizeof(char);
125 case VertexAttribType::kUByte_norm:
126 return 1 * sizeof(char);
127 case VertexAttribType::kUByte4_norm:
128 return 4 * sizeof(char);
129 case VertexAttribType::kShort2:
130 return 2 * sizeof(int16_t);
131 case VertexAttribType::kShort4:
132 return 4 * sizeof(int16_t);
133 case VertexAttribType::kUShort2: [[fallthrough]];
134 case VertexAttribType::kUShort2_norm:
135 return 2 * sizeof(uint16_t);
136 case VertexAttribType::kInt:
137 return sizeof(int32_t);
138 case VertexAttribType::kUInt:
139 return sizeof(uint32_t);
140 case VertexAttribType::kUShort_norm:
141 return sizeof(uint16_t);
142 case VertexAttribType::kUShort4_norm:
143 return 4 * sizeof(uint16_t);
144 }
145 SkUNREACHABLE;
146 }
147
148 /**
149 * Struct used to describe how a Texture/TextureProxy/TextureProxyView is sampled.
150 */
151 struct SamplerDesc {
152 SkSamplingOptions fSamplingOptions;
153 SkTileMode fTileModes[2];
154
155 bool operator==(const SamplerDesc& o) const {
156 return fSamplingOptions == o.fSamplingOptions &&
157 fTileModes[0] == o.fTileModes[0] &&
158 fTileModes[1] == o.fTileModes[1];
159 }
160 bool operator!=(const SamplerDesc& o) const {
161 return !(*this == o);
162 }
163
asKeySamplerDesc164 uint32_t asKey() const {
165 static_assert(kSkTileModeCount <= 4 && kSkFilterModeCount <= 2);
166 // Cubic sampling is handled in a shader, with the actual texture sampled by with NN,
167 // but that is what a cubic SkSamplingOptions is set to if you ignore 'cubic', which let's
168 // us simplify how we construct SamplerDec's from the options passed to high-level draws.
169 SkASSERT(!fSamplingOptions.useCubic || (fSamplingOptions.filter == SkFilterMode::kNearest &&
170 fSamplingOptions.mipmap == SkMipmapMode::kNone));
171 // TODO: Add support for anisotropic filtering
172 return (static_cast<int>(fTileModes[0]) << 0) |
173 (static_cast<int>(fTileModes[1]) << 2) |
174 (static_cast<int>(fSamplingOptions.filter) << 4) |
175 (static_cast<int>(fSamplingOptions.mipmap) << 5);
176 }
177 };
178
179 enum class UniformSlot {
180 // TODO: Want this?
181 // Meant for uniforms that change rarely to never over the course of a render pass
182 // kStatic,
183 // Meant for uniforms that are defined and used by the RenderStep portion of the pipeline shader
184 kRenderStep,
185 // Meant for uniforms that are defined and used by the paint parameters (ie SkPaint subset)
186 kPaint,
187 };
188
189 /*
190 * Depth and stencil settings
191 */
192 enum class CompareOp : uint8_t {
193 kAlways,
194 kNever,
195 kGreater,
196 kGEqual,
197 kLess,
198 kLEqual,
199 kEqual,
200 kNotEqual
201 };
202 static constexpr int kCompareOpCount = 1 + (int)CompareOp::kNotEqual;
203
204 enum class StencilOp : uint8_t {
205 kKeep,
206 kZero,
207 kReplace, // Replace stencil value with reference (only the bits enabled in fWriteMask).
208 kInvert,
209 kIncWrap,
210 kDecWrap,
211 // NOTE: clamping occurs before the write mask. So if the MSB is zero and masked out, stencil
212 // values will still wrap when using clamping ops.
213 kIncClamp,
214 kDecClamp
215 };
216 static constexpr int kStencilOpCount = 1 + (int)StencilOp::kDecClamp;
217
218 struct DepthStencilSettings {
219 // Per-face settings for stencil
220 struct Face {
221 constexpr Face() = default;
FaceDepthStencilSettings::Face222 constexpr Face(StencilOp stencilFail,
223 StencilOp depthFail,
224 StencilOp dsPass,
225 CompareOp compare,
226 uint32_t readMask,
227 uint32_t writeMask)
228 : fStencilFailOp(stencilFail)
229 , fDepthFailOp(depthFail)
230 , fDepthStencilPassOp(dsPass)
231 , fCompareOp(compare)
232 , fReadMask(readMask)
233 , fWriteMask(writeMask) {}
234
235 StencilOp fStencilFailOp = StencilOp::kKeep;
236 StencilOp fDepthFailOp = StencilOp::kKeep;
237 StencilOp fDepthStencilPassOp = StencilOp::kKeep;
238 CompareOp fCompareOp = CompareOp::kAlways;
239 uint32_t fReadMask = 0xffffffff;
240 uint32_t fWriteMask = 0xffffffff;
241
242 constexpr bool operator==(const Face& that) const {
243 return this->fStencilFailOp == that.fStencilFailOp &&
244 this->fDepthFailOp == that.fDepthFailOp &&
245 this->fDepthStencilPassOp == that.fDepthStencilPassOp &&
246 this->fCompareOp == that.fCompareOp &&
247 this->fReadMask == that.fReadMask &&
248 this->fWriteMask == that.fWriteMask;
249 }
250 };
251
252 constexpr DepthStencilSettings() = default;
DepthStencilSettingsDepthStencilSettings253 constexpr DepthStencilSettings(Face front,
254 Face back,
255 uint32_t stencilRef,
256 bool stencilTest,
257 CompareOp depthCompare,
258 bool depthTest,
259 bool depthWrite)
260 : fFrontStencil(front)
261 , fBackStencil(back)
262 , fStencilReferenceValue(stencilRef)
263 , fDepthCompareOp(depthCompare)
264 , fStencilTestEnabled(stencilTest)
265 , fDepthTestEnabled(depthTest)
266 , fDepthWriteEnabled(depthWrite) {}
267
268 constexpr bool operator==(const DepthStencilSettings& that) const {
269 return this->fFrontStencil == that.fFrontStencil &&
270 this->fBackStencil == that.fBackStencil &&
271 this->fStencilReferenceValue == that.fStencilReferenceValue &&
272 this->fDepthCompareOp == that.fDepthCompareOp &&
273 this->fStencilTestEnabled == that.fStencilTestEnabled &&
274 this->fDepthTestEnabled == that.fDepthTestEnabled &&
275 this->fDepthWriteEnabled == that.fDepthWriteEnabled;
276 }
277
278 Face fFrontStencil;
279 Face fBackStencil;
280 uint32_t fStencilReferenceValue = 0;
281 CompareOp fDepthCompareOp = CompareOp::kAlways;
282 bool fStencilTestEnabled = false;
283 bool fDepthTestEnabled = false;
284 bool fDepthWriteEnabled = false;
285 };
286
287 }; // namespace skgpu::graphite
288
289 #endif // skgpu_graphite_DrawTypes_DEFINED
290