Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(514)

Side by Side Diff: src/sksl/ir/SkSLType.h

Issue 1984363002: initial checkin of SkSL compiler (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: more updates, mostly SPIR-V Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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(std::move(name))
30 , fType(std::move(type)) {}
31
32 const std::string description() {
33 return fType->description() + " " + fName + ";";
34 }
35
36 const Modifiers fModifiers;
37 const std::string fName;
38 const 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 // Create an "other" (special) type with the given name. These types cannot be directly
53 // referenced from user code.
54 Type(std::string name)
55 : INHERITED(Position(), kType_Kind, std::move(name))
56 , fTypeKind(kOther_Kind)
57 , fIsNumber(false)
dogben 2016/06/28 02:14:55 nit: Given that there are so many constructors and
ethannicholas 2016/06/30 15:19:28 Last time I did that the reviewer told me not to u
dogben 2016/06/30 18:19:44 It hasn't been fully supported until recently. I'm
58 , fColumns(-1)
59 , fRows(-1)
60 , fDimensions(SpvDim1D)
61 , fIsDepth(false)
62 , fIsArrayed(false)
63 , fIsMultisampled(false)
64 , fIsSampled(false) {}
65
66 // Create a generic type which maps to the listed types.
67 Type(std::string name, std::vector<std::shared_ptr<Type>> types)
68 : INHERITED(Position(), kType_Kind, std::move(name))
69 , fTypeKind(kGeneric_Kind)
70 , fIsNumber(false)
71 , fCoercibleTypes(std::move(types))
72 , fColumns(-1)
73 , fRows(-1)
74 , fDimensions(SpvDim1D)
75 , fIsDepth(false)
76 , fIsArrayed(false)
77 , fIsMultisampled(false)
78 , fIsSampled(false) {
79 ASSERT(fCoercibleTypes.size() == 4);
80 }
81
82 // Create a struct type with the given fields.
83 Type(std::string name, std::vector<Field> fields)
84 : INHERITED(Position(), kType_Kind, std::move(name))
85 , fTypeKind(kStruct_Kind)
86 , fIsNumber(false)
87 , fColumns(-1)
88 , fRows(-1)
89 , fFields(std::move(fields))
90 , fDimensions(SpvDim1D)
91 , fIsDepth(false)
92 , fIsArrayed(false)
93 , fIsMultisampled(false)
94 , fIsSampled(false) {}
95
96 // Create a scalar type.
97 Type(std::string name, bool isNumber)
98 : INHERITED(Position(), kType_Kind, std::move(name))
99 , fTypeKind(kScalar_Kind)
100 , fIsNumber(isNumber)
101 , fColumns(1)
102 , fRows(1)
103 , fDimensions(SpvDim1D)
104 , fIsDepth(false)
105 , fIsArrayed(false)
106 , fIsMultisampled(false)
107 , fIsSampled(false) {}
108
109 // Create a scalar type which can be coerced to the listed types.
110 Type(std::string name, bool isNumber, std::vector<std::shared_ptr<Type>> coe rcibleTypes)
111 : INHERITED(Position(), kType_Kind, std::move(name))
112 , fTypeKind(kScalar_Kind)
113 , fIsNumber(isNumber)
114 , fCoercibleTypes(std::move(coercibleTypes))
115 , fColumns(1)
116 , fRows(1)
117 , fDimensions(SpvDim1D)
118 , fIsDepth(false)
119 , fIsArrayed(false)
120 , fIsMultisampled(false)
121 , fIsSampled(false) {}
122
123 // Create a vector type.
124 Type(std::string name, std::shared_ptr<Type> componentType, int columns)
125 : INHERITED(Position(), kType_Kind, std::move(name))
dogben 2016/06/28 02:14:55 nit: maybe delegate to next constructor?
126 , fTypeKind(kVector_Kind)
127 , fIsNumber(false)
128 , fComponentType(std::move(componentType))
129 , fColumns(columns)
130 , fRows(1)
131 , fDimensions(SpvDim1D)
132 , fIsDepth(false)
133 , fIsArrayed(false)
134 , fIsMultisampled(false)
135 , fIsSampled(false) {}
136
137 // Create a vector or array type.
138 Type(std::string name, Kind kind, std::shared_ptr<Type> componentType, int c olumns)
139 : INHERITED(Position(), kType_Kind, std::move(name))
140 , fTypeKind(kind)
141 , fIsNumber(false)
142 , fComponentType(std::move(componentType))
143 , fColumns(columns)
144 , fRows(1)
145 , fDimensions(SpvDim1D)
146 , fIsDepth(false)
147 , fIsArrayed(false)
148 , fIsMultisampled(false)
149 , fIsSampled(false) {}
150
151 // Create a matrix type.
152 Type(std::string name, std::shared_ptr<Type> componentType, int columns, int rows)
153 : INHERITED(Position(), kType_Kind, std::move(name))
154 , fTypeKind(kMatrix_Kind)
155 , fIsNumber(false)
156 , fComponentType(std::move(componentType))
157 , fColumns(columns)
158 , fRows(rows)
159 , fDimensions(SpvDim1D)
160 , fIsDepth(false)
161 , fIsArrayed(false)
162 , fIsMultisampled(false)
163 , fIsSampled(false) {}
164
165 // Create a sampler type.
166 Type(std::string name, SpvDim_ dimensions, bool isDepth, bool isArrayed, boo l isMultisampled,
167 bool isSampled)
168 : INHERITED(Position(), kType_Kind, std::move(name))
169 , fTypeKind(kSampler_Kind)
170 , fIsNumber(false)
171 , fColumns(-1)
172 , fRows(-1)
173 , fDimensions(dimensions)
174 , fIsDepth(isDepth)
175 , fIsArrayed(isArrayed)
176 , fIsMultisampled(isMultisampled)
177 , fIsSampled(isSampled) {}
178
179 std::string name() const {
180 return fName;
181 }
182
183 std::string description() const override {
184 return fName;
185 }
186
187 bool operator==(const Type& other) const {
188 return fName == other.fName;
189 }
190
191 bool operator!=(const Type& other) const {
192 return fName != other.fName;
193 }
194
195 /**
196 * Returns the category (scalar, vector, matrix, etc.) of this type.
197 */
198 Kind kind() const {
199 return fTypeKind;
200 }
201
202 /**
203 * Returns true if this is a numeric scalar type.
204 */
205 bool isNumber() const {
206 return fIsNumber;
207 }
208
209 /**
210 * Returns true if an instance of this type can be freely coerced (implicitl y converted) to
211 * another type.
212 */
213 bool canCoerceTo(std::shared_ptr<Type> other) const {
214 int cost;
215 return determineCoercionCost(other, &cost);
216 }
217
218 /**
219 * Determines the "cost" of coercing (implicitly converting) this type to an other type. The cost
220 * is a number with no particular meaning other than that lower costs are pr eferable to higher
221 * costs. Returns true if a conversion is possible, false otherwise. The val ue of the out
222 * parameter is undefined if false is returned.
223 */
224 bool determineCoercionCost(std::shared_ptr<Type> other, int* outCost) const;
225
226 /**
227 * For matrices and vectors, returns the type of individual cells (e.g. mat2 has a component
228 * type of kFloat_Type). For all other types, causes an assertion failure.
229 */
230 std::shared_ptr<Type> componentType() const {
231 ASSERT(fComponentType);
232 return fComponentType;
233 }
234
235 /**
236 * For matrices and vectors, returns the number of columns (e.g. both mat3 a nd vec3 return 3).
237 * For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1.
238 * For all other types, causes an assertion failure.
239 */
240 int columns() const {
241 ASSERT(fTypeKind == kScalar_Kind || fTypeKind == kVector_Kind ||
242 fTypeKind == kMatrix_Kind || fTypeKind == kArray_Kind);
243 return fColumns;
244 }
245
246 /**
247 * For matrices, returns the number of rows (e.g. mat2x4 returns 4). For vec tors and scalars,
248 * returns 1. For all other types, causes an assertion failure.
249 */
250 int rows() const {
251 ASSERT(fRows > 0);
252 return fRows;
253 }
254
255 std::vector<Field> fields() const {
256 ASSERT(fTypeKind == kStruct_Kind);
257 return fFields;
258 }
259
260 /**
261 * For generic types, returns the types that this generic type can substitut e for. For other
262 * types, returns a list of other types that this type can be coerced into.
263 */
264 std::vector<std::shared_ptr<Type>> coercibleTypes() const {
265 ASSERT(fCoercibleTypes.size() > 0);
266 return fCoercibleTypes;
267 }
268
269 int dimensions() const {
270 ASSERT(fTypeKind == kSampler_Kind);
271 return fDimensions;
272 }
273
274 bool isDepth() const {
275 ASSERT(fTypeKind == kSampler_Kind);
276 return fIsDepth;
277 }
278
279 bool isArrayed() const {
280 ASSERT(fTypeKind == kSampler_Kind);
281 return fIsArrayed;
282 }
283
284 bool isMultisampled() const {
285 ASSERT(fTypeKind == kSampler_Kind);
286 return fIsMultisampled;
287 }
288
289 bool isSampled() const {
290 ASSERT(fTypeKind == kSampler_Kind);
291 return fIsSampled;
292 }
293
294 /**
295 * Returns the type's required alignment (when putting this type into a stru ct, the offset must
296 * be a multiple of the alignment).
297 */
298 size_t alignment() const {
299 // See OpenGL Spec 7.6.2.2 Standard Uniform Block Layout
300 switch (fTypeKind) {
301 case kScalar_Kind:
302 return this->size();
303 case kVector_Kind:
304 return (fColumns + fColumns % 2) * fComponentType->size();
305 case kMatrix_Kind:
306 return (fRows + fRows % 2) * fComponentType->size();
egdaniel 2016/06/28 15:53:32 This seems wrong. A column matrix should be though
307 case kArray_Kind:
308 switch (fComponentType->kind()) {
309 case kScalar_Kind:
310 return fComponentType->alignment() * 4;
egdaniel 2016/06/28 15:53:32 This should be the base alignment of the scalar ro
ethannicholas 2016/06/30 15:19:28 I based mine on the OpenGL spec, which says "round
311 case kVector_Kind:
312 return fComponentType->componentType()->size() * 4;
egdaniel 2016/06/28 15:53:31 same need for asserts as above
313 case kStruct_Kind:
314 return fComponentType->alignment();
315 default:
316 ABORT("unsupported array type");
317 }
318 case kStruct_Kind: {
319 size_t result = 16;
320 for (size_t i = 0; i < fFields.size(); i++) {
321 size_t alignment = fFields[i].fType->alignment();
322 if (alignment > result) {
323 result = alignment;
324 }
325 }
326 }
327 default:
328 ABORT(("cannot determine size of type " + fName).c_str());
329 }
330 }
331
332 /**
333 * For matrices and arrays, returns the number of bytes from the start of on e entry (row, in
334 * the case of matrices) to the start of the next.
335 */
336 size_t stride() const {
337 // the OpenGL spec specifies a minimum of vec4 stride for these types, w hich is consistent
338 // with what glslang produces. Since the Skia Vulkan engine sets up its structures to fit
339 // with what glslang expects, we have no choice but to be consistent wit h that, which leads
340 // to wasting 75% of the space in a float[]. However, it's possible that (for arrays, at
341 // least) there is no actual reason to require a stride of 16, provided that both the shader
egdaniel 2016/06/28 15:53:32 This is actually all required by the Vulkan spec e
342 // and Skia agree on the stride.
343 // FIXME: see whether we can remove the restriction on array stride
344 switch (fTypeKind) {
345 case kMatrix_Kind:
346 // for the time being, we only handle 32 bit numbers
egdaniel 2016/06/28 15:53:32 is this asserted somewhere?
347 return 16;
348 case kArray_Kind:
349 return std::max(this->componentType()->size(), (size_t) 16);
egdaniel 2016/06/28 15:53:32 If we are trying to match the vulkan spec here, th
350 default:
351 ABORT("type does not have a stride");
352 }
353 }
354
355 /**
356 * Returns the size of this type in bytes.
357 */
358 size_t size() const {
359 switch (fTypeKind) {
360 case kScalar_Kind:
361 // FIXME need to take precision into account, once we figure out how we want to
362 // handle it...
363 return 4;
364 case kVector_Kind:
365 return fColumns * fComponentType->size();
egdaniel 2016/06/28 15:53:31 does a vec3 not have a size of a vec4?
ethannicholas 2016/06/30 15:19:28 No. It has the *alignment* of a vec4, but not the
366 case kMatrix_Kind:
367 return (fRows + fRows % 2) * fColumns * fComponentType->size();
368 case kArray_Kind:
369 return fColumns * this->alignment();
370 case kStruct_Kind: {
371 size_t total = 0;
372 for (size_t i = 0; i < fFields.size(); i++) {
373 size_t alignment = fFields[i].fType->alignment();
374 if (total % alignment != 0) {
375 total += alignment - total % alignment;
376 }
377 ASSERT(false);
378 ASSERT(total % alignment == 0);
379 total += fFields[i].fType->size();
380 }
381 return total;
382 }
383 default:
384 ABORT(("cannot determine size of type " + fName).c_str());
385 }
386 }
387
388 /**
389 * Returns the corresponding vector or matrix type with the specified number of columns and
390 * rows.
391 */
392 std::shared_ptr<Type> toCompound(int columns, int rows);
393
394 private:
395 typedef Symbol INHERITED;
396
397 const Kind fTypeKind;
398 const bool fIsNumber;
399 const std::shared_ptr<Type> fComponentType;
400 const std::vector<std::shared_ptr<Type>> fCoercibleTypes;
401 const int fColumns;
402 const int fRows;
403 const std::vector<Field> fFields;
404 const SpvDim_ fDimensions;
405 const bool fIsDepth;
406 const bool fIsArrayed;
407 const bool fIsMultisampled;
408 const bool fIsSampled;
409 };
410
411 extern const std::shared_ptr<Type> kVoid_Type;
412
413 extern const std::shared_ptr<Type> kFloat_Type;
414 extern const std::shared_ptr<Type> kVec2_Type;
415 extern const std::shared_ptr<Type> kVec3_Type;
416 extern const std::shared_ptr<Type> kVec4_Type;
417 extern const std::shared_ptr<Type> kDouble_Type;
418 extern const std::shared_ptr<Type> kDVec2_Type;
419 extern const std::shared_ptr<Type> kDVec3_Type;
420 extern const std::shared_ptr<Type> kDVec4_Type;
421 extern const std::shared_ptr<Type> kInt_Type;
422 extern const std::shared_ptr<Type> kIVec2_Type;
423 extern const std::shared_ptr<Type> kIVec3_Type;
424 extern const std::shared_ptr<Type> kIVec4_Type;
425 extern const std::shared_ptr<Type> kUInt_Type;
426 extern const std::shared_ptr<Type> kUVec2_Type;
427 extern const std::shared_ptr<Type> kUVec3_Type;
428 extern const std::shared_ptr<Type> kUVec4_Type;
429 extern const std::shared_ptr<Type> kBool_Type;
430 extern const std::shared_ptr<Type> kBVec2_Type;
431 extern const std::shared_ptr<Type> kBVec3_Type;
432 extern const std::shared_ptr<Type> kBVec4_Type;
433
434 extern const std::shared_ptr<Type> kMat2x2_Type;
435 extern const std::shared_ptr<Type> kMat2x3_Type;
436 extern const std::shared_ptr<Type> kMat2x4_Type;
437 extern const std::shared_ptr<Type> kMat3x2_Type;
438 extern const std::shared_ptr<Type> kMat3x3_Type;
439 extern const std::shared_ptr<Type> kMat3x4_Type;
440 extern const std::shared_ptr<Type> kMat4x2_Type;
441 extern const std::shared_ptr<Type> kMat4x3_Type;
442 extern const std::shared_ptr<Type> kMat4x4_Type;
443
444 extern const std::shared_ptr<Type> kDMat2x2_Type;
445 extern const std::shared_ptr<Type> kDMat2x3_Type;
446 extern const std::shared_ptr<Type> kDMat2x4_Type;
447 extern const std::shared_ptr<Type> kDMat3x2_Type;
448 extern const std::shared_ptr<Type> kDMat3x3_Type;
449 extern const std::shared_ptr<Type> kDMat3x4_Type;
450 extern const std::shared_ptr<Type> kDMat4x2_Type;
451 extern const std::shared_ptr<Type> kDMat4x3_Type;
452 extern const std::shared_ptr<Type> kDMat4x4_Type;
453
454 extern const std::shared_ptr<Type> kSampler1D_Type;
455 extern const std::shared_ptr<Type> kSampler2D_Type;
456 extern const std::shared_ptr<Type> kSampler3D_Type;
457 extern const std::shared_ptr<Type> kSamplerCube_Type;
458 extern const std::shared_ptr<Type> kSampler2DRect_Type;
459 extern const std::shared_ptr<Type> kSampler1DArray_Type;
460 extern const std::shared_ptr<Type> kSampler2DArray_Type;
461 extern const std::shared_ptr<Type> kSamplerCubeArray_Type;
462 extern const std::shared_ptr<Type> kSamplerBuffer_Type;
463 extern const std::shared_ptr<Type> kSampler2DMS_Type;
464 extern const std::shared_ptr<Type> kSampler2DMSArray_Type;
465
466 extern const std::shared_ptr<Type> kGSampler1D_Type;
467 extern const std::shared_ptr<Type> kGSampler2D_Type;
468 extern const std::shared_ptr<Type> kGSampler3D_Type;
469 extern const std::shared_ptr<Type> kGSamplerCube_Type;
470 extern const std::shared_ptr<Type> kGSampler2DRect_Type;
471 extern const std::shared_ptr<Type> kGSampler1DArray_Type;
472 extern const std::shared_ptr<Type> kGSampler2DArray_Type;
473 extern const std::shared_ptr<Type> kGSamplerCubeArray_Type;
474 extern const std::shared_ptr<Type> kGSamplerBuffer_Type;
475 extern const std::shared_ptr<Type> kGSampler2DMS_Type;
476 extern const std::shared_ptr<Type> kGSampler2DMSArray_Type;
477
478 extern const std::shared_ptr<Type> kSampler1DShadow_Type;
479 extern const std::shared_ptr<Type> kSampler2DShadow_Type;
480 extern const std::shared_ptr<Type> kSamplerCubeShadow_Type;
481 extern const std::shared_ptr<Type> kSampler2DRectShadow_Type;
482 extern const std::shared_ptr<Type> kSampler1DArrayShadow_Type;
483 extern const std::shared_ptr<Type> kSampler2DArrayShadow_Type;
484 extern const std::shared_ptr<Type> kSamplerCubeArrayShadow_Type;
485 extern const std::shared_ptr<Type> kGSampler2DArrayShadow_Type;
486 extern const std::shared_ptr<Type> kGSamplerCubeArrayShadow_Type;
487
488 extern const std::shared_ptr<Type> kGenType_Type;
489 extern const std::shared_ptr<Type> kGenDType_Type;
490 extern const std::shared_ptr<Type> kGenIType_Type;
491 extern const std::shared_ptr<Type> kGenUType_Type;
492 extern const std::shared_ptr<Type> kGenBType_Type;
493 extern const std::shared_ptr<Type> kMat_Type;
494 extern const std::shared_ptr<Type> kVec_Type;
495 extern const std::shared_ptr<Type> kGVec_Type;
496 extern const std::shared_ptr<Type> kGVec2_Type;
497 extern const std::shared_ptr<Type> kGVec3_Type;
498 extern const std::shared_ptr<Type> kGVec4_Type;
499 extern const std::shared_ptr<Type> kDVec_Type;
500 extern const std::shared_ptr<Type> kIVec_Type;
501 extern const std::shared_ptr<Type> kUVec_Type;
502 extern const std::shared_ptr<Type> kBVec_Type;
503
504 extern const std::shared_ptr<Type> kInvalid_Type;
505
506 } // namespace
507
508 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698