OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 Google Inc. | |
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 SKIASL_TYPE | |
9 #define SKIASL_TYPE | |
10 | |
11 #include "SkSLModifiers.h" | |
12 #include "SkSLSymbol.h" | |
13 #include "../SkSLPosition.h" | |
14 #include "../SkSLUtil.h" | |
15 #include "../spirv.h" | |
16 #include <vector> | |
17 #include <memory> | |
18 | |
19 namespace SkSL { | |
20 | |
21 /** | |
22 * Represents a type, such as int or vec4. | |
23 */ | |
24 class Type : public Symbol { | |
25 public: | |
26 struct Field { | |
27 Field(Modifiers modifiers, std::string name, std::shared_ptr<Type> type) | |
28 : fModifiers(modifiers) | |
29 , fName(name) | |
30 , fType(type) {} | |
31 | |
32 std::string description() { | |
dogben
2016/06/22 17:43:58
override? const?
ethannicholas
2016/06/24 21:23:10
You are correct that it should have been const, bu
dogben
2016/06/26 03:57:53
Class hierarchy is Type -> Symbol -> IRNode. IRNod
ethannicholas
2016/06/27 20:35:03
Well, sure, but aren't we talking about Field, not
dogben
2016/06/28 02:14:54
Gah! Sorry.
| |
33 return fType->description() + " " + fName + ";"; | |
34 } | |
35 | |
36 Modifiers fModifiers; | |
37 std::string fName; | |
38 std::shared_ptr<Type> fType; | |
39 }; | |
40 | |
41 enum Kind { | |
42 kScalar_Kind, | |
43 kVector_Kind, | |
44 kMatrix_Kind, | |
45 kArray_Kind, | |
46 kStruct_Kind, | |
47 kGeneric_Kind, | |
48 kSampler_Kind, | |
49 kOther_Kind | |
50 }; | |
51 | |
52 Type(std::string name) | |
53 : INHERITED(Position(), kType_Kind, name) | |
54 , fKind(kOther_Kind) | |
55 , fIsNumber(false) | |
56 , fColumns(-1) | |
57 , fRows(-1) {} | |
58 | |
59 Type(std::string name, std::vector<std::shared_ptr<Type>> types) | |
60 : INHERITED(Position(), kType_Kind, name) | |
61 , fKind(kGeneric_Kind) | |
62 , fIsNumber(false) | |
63 , fCoercibleTypes(types) | |
64 , fColumns(-1) | |
65 , fRows(-1) {} | |
66 | |
67 Type(std::string name, std::vector<Field> fields) | |
68 : INHERITED(Position(), kType_Kind, name) | |
69 , fKind(kStruct_Kind) | |
70 , fIsNumber(false) | |
71 , fColumns(-1) | |
72 , fRows(-1) | |
73 , fFields(fields) {} | |
74 | |
75 Type(std::string name, bool isNumber) | |
76 : INHERITED(Position(), kType_Kind, name) | |
77 , fKind(kScalar_Kind) | |
78 , fIsNumber(isNumber) | |
79 , fColumns(1) | |
80 , fRows(1) {} | |
81 | |
82 Type(std::string name, bool isNumber, std::vector<std::shared_ptr<Type>> typ es) | |
83 : INHERITED(Position(), kType_Kind, name) | |
84 , fKind(kScalar_Kind) | |
85 , fIsNumber(isNumber) | |
86 , fCoercibleTypes(types) | |
87 , fColumns(1) | |
88 , fRows(1) {} | |
89 | |
90 Type(std::string name, std::shared_ptr<Type> componentType, int columns) | |
91 : INHERITED(Position(), kType_Kind, name) | |
92 , fKind(kVector_Kind) | |
93 , fIsNumber(false) | |
94 , fComponentType(componentType) | |
95 , fColumns(columns) | |
96 , fRows(1) {} | |
97 | |
98 Type(std::string name, Kind kind, std::shared_ptr<Type> componentType, int c olumns) | |
99 : INHERITED(Position(), kType_Kind, name) | |
100 , fKind(kind) | |
101 , fIsNumber(false) | |
102 , fComponentType(componentType) | |
103 , fColumns(columns) | |
104 , fRows(1) {} | |
105 | |
106 Type(std::string name, std::shared_ptr<Type> componentType, int columns, int rows) | |
107 : INHERITED(Position(), kType_Kind, name) | |
108 , fKind(kMatrix_Kind) | |
109 , fIsNumber(false) | |
110 , fComponentType(componentType) | |
111 , fColumns(columns) | |
112 , fRows(rows) {} | |
113 | |
114 Type(std::string name, SpvDim_ dimensions, bool isDepth, bool isArrayed, boo l isMultisampled, | |
115 bool isSampled) | |
116 : INHERITED(Position(), kType_Kind, name) | |
117 , fKind(kSampler_Kind) | |
118 , fIsNumber(false) | |
119 , fColumns(-1) | |
120 , fRows(-1) | |
121 , fDimensions(dimensions) | |
122 , fIsDepth(isDepth) | |
123 , fIsArrayed(isArrayed) | |
124 , fIsMultisampled(isMultisampled) | |
125 , fIsSampled(isSampled) {} | |
126 | |
127 std::string name() const { | |
128 return fName; | |
129 } | |
130 | |
131 std::string description() const override { | |
132 return fName; | |
133 } | |
134 | |
135 bool operator==(const Type& other) const { | |
136 return fName == other.fName; | |
137 } | |
138 | |
139 bool operator!=(const Type& other) const { | |
140 return fName != other.fName; | |
141 } | |
142 | |
143 /** | |
144 * Returns the category (scalar, vector, matrix, etc.) of this type. | |
145 */ | |
146 Kind kind() const { | |
147 return fKind; | |
148 } | |
149 | |
150 /** | |
151 * Returns true if this is a numeric scalar type. | |
152 */ | |
153 bool isNumber() const { | |
154 return fIsNumber; | |
155 } | |
156 | |
157 /** | |
158 * Returns true if an instance of this type can be freely coerced (implicitl y converted) to | |
159 * another type. | |
160 */ | |
161 bool canCoerceTo(std::shared_ptr<Type> other) const { | |
162 int cost; | |
163 return determineCoercionCost(other, &cost); | |
164 } | |
165 | |
166 /** | |
167 * Determines the "cost" of coercing (implicitly converting) this type to an other type. The cost | |
168 * is a number with no particular meaning other than that lower costs are pr eferable to higher | |
169 * costs. Returns true if a conversion is possible, false otherwise. The val ue of the out | |
170 * parameter is undefined if false is returned. | |
171 */ | |
172 bool determineCoercionCost(std::shared_ptr<Type> other, int* outCost) const; | |
173 | |
174 /** | |
175 * For matrices and vectors, returns the type of individual cells (e.g. mat2 has a component | |
176 * type of kFloat_Type). For all other types, causes an assertion failure. | |
177 */ | |
178 std::shared_ptr<Type> componentType() const { | |
179 ASSERT(fComponentType); | |
180 return fComponentType; | |
181 } | |
182 | |
183 /** | |
184 * For matrices and vectors, returns the number of columns (e.g. both mat3 a nd vec3 return 3). | |
185 * For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1. | |
186 * For all other types, causes an assertion failure. | |
187 */ | |
188 int columns() const { | |
189 ASSERT(fKind == kScalar_Kind || fKind == kVector_Kind || fKind == kMatri x_Kind || | |
190 fKind == kArray_Kind); | |
191 return fColumns; | |
192 } | |
193 | |
194 /** | |
195 * For matrices, returns the number of rows (e.g. mat2x4 returns 4). For vec tors and scalars, | |
196 * returns 1. For all other types, causes an assertion failure. | |
197 */ | |
198 int rows() const { | |
199 ASSERT(fRows > 0); | |
200 return fRows; | |
201 } | |
202 | |
203 std::vector<Field> fields() const { | |
204 ASSERT(fKind == kStruct_Kind); | |
205 return fFields; | |
206 } | |
207 | |
208 /** | |
209 * For generic types, teturns the types that this generic type can substitut e for. For other | |
210 * types, returns a list of other types that this type can be coerced into. | |
211 */ | |
212 std::vector<std::shared_ptr<Type>> coercibleTypes() const { | |
213 ASSERT(fCoercibleTypes.size() > 0); | |
214 return fCoercibleTypes; | |
215 } | |
216 | |
217 int dimensions() { | |
dogben
2016/06/22 17:43:58
nit: should this and all following methods be cons
ethannicholas
2016/06/24 21:23:10
The fields should all have been defined const (whi
| |
218 ASSERT(fKind == kSampler_Kind); | |
219 return fDimensions; | |
220 } | |
221 | |
222 bool isDepth() { | |
223 ASSERT(fKind == kSampler_Kind); | |
224 return fIsDepth; | |
225 } | |
226 | |
227 bool isArrayed() { | |
228 ASSERT(fKind == kSampler_Kind); | |
229 return fIsArrayed; | |
230 } | |
231 | |
232 bool isMultisampled() { | |
233 ASSERT(fKind == kSampler_Kind); | |
234 return fIsMultisampled; | |
235 } | |
236 | |
237 bool isSampled() { | |
238 ASSERT(fKind == kSampler_Kind); | |
239 return fIsSampled; | |
240 } | |
241 | |
242 /** | |
243 * Returns the type's required alignment (when putting this type into a stru ct, the offset must | |
244 * be a multiple of the alignment). | |
245 */ | |
246 size_t alignment() { | |
247 switch (fKind) { | |
248 case kScalar_Kind: | |
249 return this->size(); | |
250 case kVector_Kind: // fall through | |
251 return (fColumns + fColumns % 2) * fComponentType->size(); | |
252 case kMatrix_Kind: | |
253 return (fRows + fRows % 2) * fComponentType->size(); | |
254 case kArray_Kind: | |
255 switch (fComponentType->kind()) { | |
256 case kScalar_Kind: | |
257 return fComponentType->alignment() * 4; | |
258 case kVector_Kind: | |
259 return fComponentType->componentType()->size() * 4; | |
260 case kStruct_Kind: | |
261 return fComponentType->alignment(); | |
262 default: | |
263 ABORT("unsupported array type"); | |
264 } | |
265 case kStruct_Kind: { | |
266 size_t result = 16; | |
267 for (size_t i = 0; i < fFields.size(); i++) { | |
268 size_t alignment = fFields[i].fType->alignment(); | |
269 if (alignment > result) { | |
270 result = alignment; | |
271 } | |
272 } | |
273 } | |
274 default: | |
275 ABORT(("cannot determine size of type " + fName).c_str()); | |
276 } | |
277 } | |
278 | |
279 /** | |
280 * For matrices and arrays, returns the number of bytes from the start of on e entry (row, in | |
281 * the case of matrices) to the start of the next. | |
282 */ | |
283 size_t stride() { | |
284 // the OpenGL spec specifies a stride of 16 for these types, which is co nsistent with what | |
285 // glslang produces. Since the Skia Vulkan engine sets up its structures to fit with what | |
286 // glslang expects, we have no choice but to be consistent with that, wh ich leads to wasting | |
287 // 75% of the space in a float[]. However, it's possible that (for array s, at least) there | |
288 // is no actual reason to require a stride of 16, provided that both the shader and Skia | |
289 // agree on the stride. | |
290 // FIXME: see whether we can remove the restriction on array stride | |
291 switch (fKind) { | |
292 case kMatrix_Kind: | |
293 return 16; | |
294 case kArray_Kind: | |
295 return 16; | |
296 default: | |
297 ABORT("type does not have a stride"); | |
298 } | |
299 } | |
300 | |
301 /** | |
302 * Returns the size of this type in bytes. | |
303 */ | |
304 size_t size() { | |
305 switch (fKind) { | |
306 case kScalar_Kind: | |
307 // FIXME need to take precision into account, once we figure out how we want to | |
308 // handle it... | |
309 return 4; | |
310 case kVector_Kind: | |
311 return fColumns * fComponentType->size(); | |
312 case kMatrix_Kind: | |
313 return (fRows + fRows % 2) * fColumns * fComponentType->size(); | |
314 case kArray_Kind: | |
315 return fColumns * this->alignment(); | |
316 case kStruct_Kind: { | |
317 size_t total = 0; | |
318 for (size_t i = 0; i < fFields.size(); i++) { | |
319 size_t alignment = fFields[i].fType->alignment(); | |
320 if (total % alignment != 0) { | |
321 total += alignment - total % alignment; | |
322 } | |
323 ASSERT(offset % alignment == 0); | |
324 total += fFields[i].fType->size(); | |
325 } | |
326 return total; | |
327 } | |
328 default: | |
329 ABORT(("cannot determine size of type " + fName).c_str()); | |
330 } | |
331 } | |
332 | |
333 /** | |
334 * Returns the corresponding vector or matrix type with the specified number of columns and | |
335 * rows. | |
336 */ | |
337 std::shared_ptr<Type> toCompound(int columns, int rows); | |
338 | |
339 private: | |
340 typedef Symbol INHERITED; | |
341 | |
342 Kind fKind; | |
343 bool fIsNumber; | |
344 std::shared_ptr<Type> fComponentType; | |
345 std::vector<std::shared_ptr<Type>> fCoercibleTypes; | |
346 int fColumns; | |
347 int fRows; | |
348 std::vector<Field> fFields; | |
349 SpvDim_ fDimensions; | |
350 bool fIsDepth; | |
351 bool fIsArrayed; | |
352 bool fIsMultisampled; | |
353 bool fIsSampled; | |
354 }; | |
355 | |
356 extern const std::shared_ptr<Type> kVoid_Type; | |
357 | |
358 extern const std::shared_ptr<Type> kFloat_Type; | |
359 extern const std::shared_ptr<Type> kVec2_Type; | |
360 extern const std::shared_ptr<Type> kVec3_Type; | |
361 extern const std::shared_ptr<Type> kVec4_Type; | |
362 extern const std::shared_ptr<Type> kDouble_Type; | |
363 extern const std::shared_ptr<Type> kDVec2_Type; | |
364 extern const std::shared_ptr<Type> kDVec3_Type; | |
365 extern const std::shared_ptr<Type> kDVec4_Type; | |
366 extern const std::shared_ptr<Type> kInt_Type; | |
367 extern const std::shared_ptr<Type> kIVec2_Type; | |
368 extern const std::shared_ptr<Type> kIVec3_Type; | |
369 extern const std::shared_ptr<Type> kIVec4_Type; | |
370 extern const std::shared_ptr<Type> kUInt_Type; | |
371 extern const std::shared_ptr<Type> kUVec2_Type; | |
372 extern const std::shared_ptr<Type> kUVec3_Type; | |
373 extern const std::shared_ptr<Type> kUVec4_Type; | |
374 extern const std::shared_ptr<Type> kBool_Type; | |
375 extern const std::shared_ptr<Type> kBVec2_Type; | |
376 extern const std::shared_ptr<Type> kBVec3_Type; | |
377 extern const std::shared_ptr<Type> kBVec4_Type; | |
378 | |
379 extern const std::shared_ptr<Type> kMat2x2_Type; | |
380 extern const std::shared_ptr<Type> kMat2x3_Type; | |
381 extern const std::shared_ptr<Type> kMat2x4_Type; | |
382 extern const std::shared_ptr<Type> kMat3x2_Type; | |
383 extern const std::shared_ptr<Type> kMat3x3_Type; | |
384 extern const std::shared_ptr<Type> kMat3x4_Type; | |
385 extern const std::shared_ptr<Type> kMat4x2_Type; | |
386 extern const std::shared_ptr<Type> kMat4x3_Type; | |
387 extern const std::shared_ptr<Type> kMat4x4_Type; | |
388 | |
389 extern const std::shared_ptr<Type> kDMat2x2_Type; | |
390 extern const std::shared_ptr<Type> kDMat2x3_Type; | |
391 extern const std::shared_ptr<Type> kDMat2x4_Type; | |
392 extern const std::shared_ptr<Type> kDMat3x2_Type; | |
393 extern const std::shared_ptr<Type> kDMat3x3_Type; | |
394 extern const std::shared_ptr<Type> kDMat3x4_Type; | |
395 extern const std::shared_ptr<Type> kDMat4x2_Type; | |
396 extern const std::shared_ptr<Type> kDMat4x3_Type; | |
397 extern const std::shared_ptr<Type> kDMat4x4_Type; | |
398 | |
399 extern const std::shared_ptr<Type> kSampler1D_Type; | |
400 extern const std::shared_ptr<Type> kSampler2D_Type; | |
401 extern const std::shared_ptr<Type> kSampler3D_Type; | |
402 extern const std::shared_ptr<Type> kSamplerCube_Type; | |
403 extern const std::shared_ptr<Type> kSampler2DRect_Type; | |
404 extern const std::shared_ptr<Type> kSampler1DArray_Type; | |
405 extern const std::shared_ptr<Type> kSampler2DArray_Type; | |
406 extern const std::shared_ptr<Type> kSamplerCubeArray_Type; | |
407 extern const std::shared_ptr<Type> kSamplerBuffer_Type; | |
408 extern const std::shared_ptr<Type> kSampler2DMS_Type; | |
409 extern const std::shared_ptr<Type> kSampler2DMSArray_Type; | |
410 | |
411 extern const std::shared_ptr<Type> kGSampler1D_Type; | |
412 extern const std::shared_ptr<Type> kGSampler2D_Type; | |
413 extern const std::shared_ptr<Type> kGSampler3D_Type; | |
414 extern const std::shared_ptr<Type> kGSamplerCube_Type; | |
415 extern const std::shared_ptr<Type> kGSampler2DRect_Type; | |
416 extern const std::shared_ptr<Type> kGSampler1DArray_Type; | |
417 extern const std::shared_ptr<Type> kGSampler2DArray_Type; | |
418 extern const std::shared_ptr<Type> kGSamplerCubeArray_Type; | |
419 extern const std::shared_ptr<Type> kGSamplerBuffer_Type; | |
420 extern const std::shared_ptr<Type> kGSampler2DMS_Type; | |
421 extern const std::shared_ptr<Type> kGSampler2DMSArray_Type; | |
422 | |
423 extern const std::shared_ptr<Type> kSampler1DShadow_Type; | |
424 extern const std::shared_ptr<Type> kSampler2DShadow_Type; | |
425 extern const std::shared_ptr<Type> kSamplerCubeShadow_Type; | |
426 extern const std::shared_ptr<Type> kSampler2DRectShadow_Type; | |
427 extern const std::shared_ptr<Type> kSampler1DArrayShadow_Type; | |
428 extern const std::shared_ptr<Type> kSampler2DArrayShadow_Type; | |
429 extern const std::shared_ptr<Type> kSamplerCubeArrayShadow_Type; | |
430 extern const std::shared_ptr<Type> kGSampler2DArrayShadow_Type; | |
431 extern const std::shared_ptr<Type> kGSamplerCubeArrayShadow_Type; | |
432 | |
433 extern const std::shared_ptr<Type> kGenType_Type; | |
434 extern const std::shared_ptr<Type> kGenDType_Type; | |
435 extern const std::shared_ptr<Type> kGenIType_Type; | |
436 extern const std::shared_ptr<Type> kGenUType_Type; | |
437 extern const std::shared_ptr<Type> kGenBType_Type; | |
438 extern const std::shared_ptr<Type> kMat_Type; | |
439 extern const std::shared_ptr<Type> kVec_Type; | |
440 extern const std::shared_ptr<Type> kGVec_Type; | |
441 extern const std::shared_ptr<Type> kGVec2_Type; | |
442 extern const std::shared_ptr<Type> kGVec3_Type; | |
443 extern const std::shared_ptr<Type> kGVec4_Type; | |
444 extern const std::shared_ptr<Type> kDVec_Type; | |
445 extern const std::shared_ptr<Type> kIVec_Type; | |
446 extern const std::shared_ptr<Type> kUVec_Type; | |
447 extern const std::shared_ptr<Type> kBVec_Type; | |
448 | |
449 extern const std::shared_ptr<Type> kInvalid_Type; | |
450 | |
451 } // namespace | |
452 | |
453 #endif | |
OLD | NEW |