1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef _BASICTYPES_INCLUDED_
16 #define _BASICTYPES_INCLUDED_
17
18 #include "debug.h"
19
20 //
21 // Precision qualifiers
22 //
23 enum TPrecision : unsigned char
24 {
25 // These need to be kept sorted
26 EbpUndefined,
27 EbpLow,
28 EbpMedium,
29 EbpHigh
30 };
31
getPrecisionString(TPrecision precision)32 inline const char *getPrecisionString(TPrecision precision)
33 {
34 switch(precision)
35 {
36 case EbpHigh: return "highp"; break;
37 case EbpMedium: return "mediump"; break;
38 case EbpLow: return "lowp"; break;
39 default: return "mediump"; break; // Safest fallback
40 }
41 }
42
43 //
44 // Basic type. Arrays, vectors, etc., are orthogonal to this.
45 //
46 enum TBasicType : unsigned char
47 {
48 EbtVoid,
49 EbtFloat,
50 EbtInt,
51 EbtUInt,
52 EbtBool,
53 EbtGVec4, // non type: represents vec4, ivec4, and uvec4
54 EbtGenType, // non type: represents float, vec2, vec3, and vec4
55 EbtGenIType, // non type: represents int, ivec2, ivec3, and ivec4
56 EbtGenUType, // non type: represents uint, uvec2, uvec3, and uvec4
57 EbtGenBType, // non type: represents bool, bvec2, bvec3, and bvec4
58 EbtVec, // non type: represents vec2, vec3, and vec4
59 EbtIVec, // non type: represents ivec2, ivec3, and ivec4
60 EbtUVec, // non type: represents uvec2, uvec3, and uvec4
61 EbtBVec, // non type: represents bvec2, bvec3, and bvec4
62 EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
63 EbtSampler2D,
64 EbtSampler3D,
65 EbtSamplerCube,
66 EbtSampler2DArray,
67 EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists.
68 EbtISampler2D,
69 EbtISampler3D,
70 EbtISamplerCube,
71 EbtISampler2DArray,
72 EbtUSampler2D,
73 EbtUSampler3D,
74 EbtUSamplerCube,
75 EbtUSampler2DArray,
76 EbtSampler2DShadow,
77 EbtSamplerCubeShadow,
78 EbtSampler2DArrayShadow,
79 EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
80 EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
81 EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
82 EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
83 EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
84 EbtStruct,
85 EbtInterfaceBlock,
86 EbtAddress, // should be deprecated??
87 EbtInvariant // used as a type when qualifying a previously declared variable as being invariant
88 };
89
90 enum TLayoutMatrixPacking
91 {
92 EmpUnspecified,
93 EmpRowMajor,
94 EmpColumnMajor
95 };
96
97 enum TLayoutBlockStorage
98 {
99 EbsUnspecified,
100 EbsShared,
101 EbsPacked,
102 EbsStd140
103 };
104
getBasicString(TBasicType type)105 inline const char *getBasicString(TBasicType type)
106 {
107 switch(type)
108 {
109 case EbtVoid: return "void";
110 case EbtFloat: return "float";
111 case EbtInt: return "int";
112 case EbtUInt: return "uint";
113 case EbtBool: return "bool";
114 case EbtSampler2D: return "sampler2D";
115 case EbtSamplerCube: return "samplerCube";
116 case EbtSamplerExternalOES: return "samplerExternalOES";
117 case EbtSampler3D: return "sampler3D";
118 case EbtStruct: return "structure";
119 default: UNREACHABLE(type); return "unknown type";
120 }
121 }
122
getMatrixPackingString(TLayoutMatrixPacking mpq)123 inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)
124 {
125 switch(mpq)
126 {
127 case EmpUnspecified: return "mp_unspecified";
128 case EmpRowMajor: return "row_major";
129 case EmpColumnMajor: return "column_major";
130 default: UNREACHABLE(mpq); return "unknown matrix packing";
131 }
132 }
133
getBlockStorageString(TLayoutBlockStorage bsq)134 inline const char* getBlockStorageString(TLayoutBlockStorage bsq)
135 {
136 switch(bsq)
137 {
138 case EbsUnspecified: return "bs_unspecified";
139 case EbsShared: return "shared";
140 case EbsPacked: return "packed";
141 case EbsStd140: return "std140";
142 default: UNREACHABLE(bsq); return "unknown block storage";
143 }
144 }
145
IsSampler(TBasicType type)146 inline bool IsSampler(TBasicType type)
147 {
148 return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
149 }
150
IsIntegerSampler(TBasicType type)151 inline bool IsIntegerSampler(TBasicType type)
152 {
153 switch(type)
154 {
155 case EbtISampler2D:
156 case EbtISampler3D:
157 case EbtISamplerCube:
158 case EbtISampler2DArray:
159 case EbtUSampler2D:
160 case EbtUSampler3D:
161 case EbtUSamplerCube:
162 case EbtUSampler2DArray:
163 return true;
164 case EbtSampler2D:
165 case EbtSampler3D:
166 case EbtSamplerCube:
167 case EbtSamplerExternalOES:
168 case EbtSampler2DArray:
169 case EbtSampler2DShadow:
170 case EbtSamplerCubeShadow:
171 case EbtSampler2DArrayShadow:
172 return false;
173 default:
174 assert(!IsSampler(type));
175 }
176
177 return false;
178 }
179
IsSampler2D(TBasicType type)180 inline bool IsSampler2D(TBasicType type)
181 {
182 switch(type)
183 {
184 case EbtSampler2D:
185 case EbtISampler2D:
186 case EbtUSampler2D:
187 case EbtSampler2DArray:
188 case EbtISampler2DArray:
189 case EbtUSampler2DArray:
190 case EbtSamplerExternalOES:
191 case EbtSampler2DShadow:
192 case EbtSampler2DArrayShadow:
193 return true;
194 case EbtSampler3D:
195 case EbtISampler3D:
196 case EbtUSampler3D:
197 case EbtISamplerCube:
198 case EbtUSamplerCube:
199 case EbtSamplerCube:
200 case EbtSamplerCubeShadow:
201 return false;
202 default:
203 assert(!IsSampler(type));
204 }
205
206 return false;
207 }
208
IsSamplerCube(TBasicType type)209 inline bool IsSamplerCube(TBasicType type)
210 {
211 switch(type)
212 {
213 case EbtSamplerCube:
214 case EbtISamplerCube:
215 case EbtUSamplerCube:
216 case EbtSamplerCubeShadow:
217 return true;
218 case EbtSampler2D:
219 case EbtSampler3D:
220 case EbtSamplerExternalOES:
221 case EbtSampler2DArray:
222 case EbtISampler2D:
223 case EbtISampler3D:
224 case EbtISampler2DArray:
225 case EbtUSampler2D:
226 case EbtUSampler3D:
227 case EbtUSampler2DArray:
228 case EbtSampler2DShadow:
229 case EbtSampler2DArrayShadow:
230 return false;
231 default:
232 assert(!IsSampler(type));
233 }
234
235 return false;
236 }
237
IsSampler3D(TBasicType type)238 inline bool IsSampler3D(TBasicType type)
239 {
240 switch(type)
241 {
242 case EbtSampler3D:
243 case EbtISampler3D:
244 case EbtUSampler3D:
245 return true;
246 case EbtSampler2D:
247 case EbtSamplerCube:
248 case EbtSamplerExternalOES:
249 case EbtSampler2DArray:
250 case EbtISampler2D:
251 case EbtISamplerCube:
252 case EbtISampler2DArray:
253 case EbtUSampler2D:
254 case EbtUSamplerCube:
255 case EbtUSampler2DArray:
256 case EbtSampler2DShadow:
257 case EbtSamplerCubeShadow:
258 case EbtSampler2DArrayShadow:
259 return false;
260 default:
261 assert(!IsSampler(type));
262 }
263
264 return false;
265 }
266
IsSamplerArray(TBasicType type)267 inline bool IsSamplerArray(TBasicType type)
268 {
269 switch(type)
270 {
271 case EbtSampler2DArray:
272 case EbtISampler2DArray:
273 case EbtUSampler2DArray:
274 case EbtSampler2DArrayShadow:
275 return true;
276 case EbtSampler2D:
277 case EbtISampler2D:
278 case EbtUSampler2D:
279 case EbtSamplerExternalOES:
280 case EbtSampler3D:
281 case EbtISampler3D:
282 case EbtUSampler3D:
283 case EbtISamplerCube:
284 case EbtUSamplerCube:
285 case EbtSamplerCube:
286 case EbtSampler2DShadow:
287 case EbtSamplerCubeShadow:
288 return false;
289 default:
290 assert(!IsSampler(type));
291 }
292
293 return false;
294 }
295
IsShadowSampler(TBasicType type)296 inline bool IsShadowSampler(TBasicType type)
297 {
298 switch(type)
299 {
300 case EbtSampler2DShadow:
301 case EbtSamplerCubeShadow:
302 case EbtSampler2DArrayShadow:
303 return true;
304 case EbtISampler2D:
305 case EbtISampler3D:
306 case EbtISamplerCube:
307 case EbtISampler2DArray:
308 case EbtUSampler2D:
309 case EbtUSampler3D:
310 case EbtUSamplerCube:
311 case EbtUSampler2DArray:
312 case EbtSampler2D:
313 case EbtSampler3D:
314 case EbtSamplerCube:
315 case EbtSamplerExternalOES:
316 case EbtSampler2DArray:
317 return false;
318 default:
319 assert(!IsSampler(type));
320 }
321
322 return false;
323 }
324
IsInteger(TBasicType type)325 inline bool IsInteger(TBasicType type)
326 {
327 return type == EbtInt || type == EbtUInt;
328 }
329
SupportsPrecision(TBasicType type)330 inline bool SupportsPrecision(TBasicType type)
331 {
332 return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type);
333 }
334
335 //
336 // Qualifiers and built-ins. These are mainly used to see what can be read
337 // or written, and by the machine dependent translator to know which registers
338 // to allocate variables in. Since built-ins tend to go to different registers
339 // than varying or uniform, it makes sense they are peers, not sub-classes.
340 //
341 enum TQualifier : unsigned char
342 {
343 EvqTemporary, // For temporaries (within a function), read/write
344 EvqGlobal, // For globals read/write
345 EvqConstExpr, // User defined constants
346 EvqAttribute, // Readonly
347 EvqVaryingIn, // readonly, fragment shaders only
348 EvqVaryingOut, // vertex shaders only read/write
349 EvqInvariantVaryingIn, // readonly, fragment shaders only
350 EvqInvariantVaryingOut, // vertex shaders only read/write
351 EvqUniform, // Readonly, vertex and fragment
352
353 EvqVertexIn, // Vertex shader input
354 EvqFragmentOut, // Fragment shader output
355 EvqVertexOut, // Vertex shader output
356 EvqFragmentIn, // Fragment shader input
357
358 // pack/unpack input and output
359 EvqInput,
360 EvqOutput,
361
362 // parameters
363 EvqIn,
364 EvqOut,
365 EvqInOut,
366 EvqConstReadOnly,
367
368 // built-ins written by vertex shader
369 EvqPosition,
370 EvqPointSize,
371 EvqInstanceID,
372 EvqVertexID,
373
374 // built-ins read by fragment shader
375 EvqFragCoord,
376 EvqFrontFacing,
377 EvqPointCoord,
378
379 // built-ins written by fragment shader
380 EvqFragColor,
381 EvqFragData,
382 EvqFragDepth,
383
384 // GLSL ES 3.0 vertex output and fragment input
385 EvqSmooth, // Incomplete qualifier, smooth is the default
386 EvqFlat, // Incomplete qualifier
387 EvqSmoothOut = EvqSmooth,
388 EvqFlatOut = EvqFlat,
389 EvqCentroidOut, // Implies smooth
390 EvqSmoothIn,
391 EvqFlatIn,
392 EvqCentroidIn, // Implies smooth
393
394 // end of list
395 EvqLast
396 };
397
398 struct TLayoutQualifier
399 {
createTLayoutQualifier400 static TLayoutQualifier create()
401 {
402 TLayoutQualifier layoutQualifier;
403
404 layoutQualifier.location = -1;
405 layoutQualifier.matrixPacking = EmpUnspecified;
406 layoutQualifier.blockStorage = EbsUnspecified;
407
408 return layoutQualifier;
409 }
410
isEmptyTLayoutQualifier411 bool isEmpty() const
412 {
413 return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified;
414 }
415
416 int location;
417 TLayoutMatrixPacking matrixPacking;
418 TLayoutBlockStorage blockStorage;
419 };
420
421 //
422 // This is just for debug print out, carried along with the definitions above.
423 //
getQualifierString(TQualifier qualifier)424 inline const char *getQualifierString(TQualifier qualifier)
425 {
426 switch(qualifier)
427 {
428 case EvqTemporary: return "Temporary"; break;
429 case EvqGlobal: return "Global"; break;
430 case EvqConstExpr: return "const"; break;
431 case EvqConstReadOnly: return "const"; break;
432 case EvqAttribute: return "attribute"; break;
433 case EvqVaryingIn: return "varying"; break;
434 case EvqVaryingOut: return "varying"; break;
435 case EvqInvariantVaryingIn: return "invariant varying"; break;
436 case EvqInvariantVaryingOut:return "invariant varying"; break;
437 case EvqUniform: return "uniform"; break;
438 case EvqVertexIn: return "in"; break;
439 case EvqFragmentOut: return "out"; break;
440 case EvqVertexOut: return "out"; break;
441 case EvqFragmentIn: return "in"; break;
442 case EvqIn: return "in"; break;
443 case EvqOut: return "out"; break;
444 case EvqInOut: return "inout"; break;
445 case EvqInput: return "input"; break;
446 case EvqOutput: return "output"; break;
447 case EvqPosition: return "Position"; break;
448 case EvqPointSize: return "PointSize"; break;
449 case EvqInstanceID: return "InstanceID"; break;
450 case EvqVertexID: return "VertexID"; break;
451 case EvqFragCoord: return "FragCoord"; break;
452 case EvqFrontFacing: return "FrontFacing"; break;
453 case EvqFragColor: return "FragColor"; break;
454 case EvqFragData: return "FragData"; break;
455 case EvqFragDepth: return "FragDepth"; break;
456 case EvqSmooth: return "Smooth"; break;
457 case EvqFlat: return "Flat"; break;
458 case EvqCentroidOut: return "CentroidOut"; break;
459 case EvqSmoothIn: return "SmoothIn"; break;
460 case EvqFlatIn: return "FlatIn"; break;
461 case EvqCentroidIn: return "CentroidIn"; break;
462 default: UNREACHABLE(qualifier); return "unknown qualifier";
463 }
464 }
465
466 #endif // _BASICTYPES_INCLUDED_
467