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 EbtSampler2DRect, // Only valid if ARB_texture_rectangle exists.
68 EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists.
69 EbtISampler2D,
70 EbtISampler3D,
71 EbtISamplerCube,
72 EbtISampler2DArray,
73 EbtUSampler2D,
74 EbtUSampler3D,
75 EbtUSamplerCube,
76 EbtUSampler2DArray,
77 EbtSampler2DShadow,
78 EbtSamplerCubeShadow,
79 EbtSampler2DArrayShadow,
80 EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
81 EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
82 EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
83 EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
84 EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
85 EbtStruct,
86 EbtInterfaceBlock,
87 EbtAddress, // should be deprecated??
88 EbtInvariant // used as a type when qualifying a previously declared variable as being invariant
89 };
90
91 enum TLayoutMatrixPacking
92 {
93 EmpUnspecified,
94 EmpRowMajor,
95 EmpColumnMajor
96 };
97
98 enum TLayoutBlockStorage
99 {
100 EbsUnspecified,
101 EbsShared,
102 EbsPacked,
103 EbsStd140
104 };
105
getBasicString(TBasicType type)106 inline const char *getBasicString(TBasicType type)
107 {
108 switch(type)
109 {
110 case EbtVoid: return "void";
111 case EbtFloat: return "float";
112 case EbtInt: return "int";
113 case EbtUInt: return "uint";
114 case EbtBool: return "bool";
115 case EbtSampler2D: return "sampler2D";
116 case EbtSamplerCube: return "samplerCube";
117 case EbtSampler2DRect: return "sampler2DRect";
118 case EbtSamplerExternalOES: return "samplerExternalOES";
119 case EbtSampler3D: return "sampler3D";
120 case EbtStruct: return "structure";
121 default: UNREACHABLE(type); return "unknown type";
122 }
123 }
124
getMatrixPackingString(TLayoutMatrixPacking mpq)125 inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)
126 {
127 switch(mpq)
128 {
129 case EmpUnspecified: return "mp_unspecified";
130 case EmpRowMajor: return "row_major";
131 case EmpColumnMajor: return "column_major";
132 default: UNREACHABLE(mpq); return "unknown matrix packing";
133 }
134 }
135
getBlockStorageString(TLayoutBlockStorage bsq)136 inline const char* getBlockStorageString(TLayoutBlockStorage bsq)
137 {
138 switch(bsq)
139 {
140 case EbsUnspecified: return "bs_unspecified";
141 case EbsShared: return "shared";
142 case EbsPacked: return "packed";
143 case EbsStd140: return "std140";
144 default: UNREACHABLE(bsq); return "unknown block storage";
145 }
146 }
147
IsSampler(TBasicType type)148 inline bool IsSampler(TBasicType type)
149 {
150 return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
151 }
152
IsIntegerSampler(TBasicType type)153 inline bool IsIntegerSampler(TBasicType type)
154 {
155 switch(type)
156 {
157 case EbtISampler2D:
158 case EbtISampler3D:
159 case EbtISamplerCube:
160 case EbtISampler2DArray:
161 case EbtUSampler2D:
162 case EbtUSampler3D:
163 case EbtUSamplerCube:
164 case EbtUSampler2DArray:
165 return true;
166 case EbtSampler2D:
167 case EbtSampler3D:
168 case EbtSamplerCube:
169 case EbtSampler2DRect:
170 case EbtSamplerExternalOES:
171 case EbtSampler2DArray:
172 case EbtSampler2DShadow:
173 case EbtSamplerCubeShadow:
174 case EbtSampler2DArrayShadow:
175 return false;
176 default:
177 assert(!IsSampler(type));
178 }
179
180 return false;
181 }
182
IsSampler2D(TBasicType type)183 inline bool IsSampler2D(TBasicType type)
184 {
185 switch(type)
186 {
187 case EbtSampler2D:
188 case EbtISampler2D:
189 case EbtUSampler2D:
190 case EbtSampler2DArray:
191 case EbtISampler2DArray:
192 case EbtUSampler2DArray:
193 case EbtSampler2DRect:
194 case EbtSamplerExternalOES:
195 case EbtSampler2DShadow:
196 case EbtSampler2DArrayShadow:
197 return true;
198 case EbtSampler3D:
199 case EbtISampler3D:
200 case EbtUSampler3D:
201 case EbtISamplerCube:
202 case EbtUSamplerCube:
203 case EbtSamplerCube:
204 case EbtSamplerCubeShadow:
205 return false;
206 default:
207 assert(!IsSampler(type));
208 }
209
210 return false;
211 }
212
IsSamplerCube(TBasicType type)213 inline bool IsSamplerCube(TBasicType type)
214 {
215 switch(type)
216 {
217 case EbtSamplerCube:
218 case EbtISamplerCube:
219 case EbtUSamplerCube:
220 case EbtSamplerCubeShadow:
221 return true;
222 case EbtSampler2D:
223 case EbtSampler3D:
224 case EbtSampler2DRect:
225 case EbtSamplerExternalOES:
226 case EbtSampler2DArray:
227 case EbtISampler2D:
228 case EbtISampler3D:
229 case EbtISampler2DArray:
230 case EbtUSampler2D:
231 case EbtUSampler3D:
232 case EbtUSampler2DArray:
233 case EbtSampler2DShadow:
234 case EbtSampler2DArrayShadow:
235 return false;
236 default:
237 assert(!IsSampler(type));
238 }
239
240 return false;
241 }
242
IsSampler3D(TBasicType type)243 inline bool IsSampler3D(TBasicType type)
244 {
245 switch(type)
246 {
247 case EbtSampler3D:
248 case EbtISampler3D:
249 case EbtUSampler3D:
250 return true;
251 case EbtSampler2D:
252 case EbtSamplerCube:
253 case EbtSampler2DRect:
254 case EbtSamplerExternalOES:
255 case EbtSampler2DArray:
256 case EbtISampler2D:
257 case EbtISamplerCube:
258 case EbtISampler2DArray:
259 case EbtUSampler2D:
260 case EbtUSamplerCube:
261 case EbtUSampler2DArray:
262 case EbtSampler2DShadow:
263 case EbtSamplerCubeShadow:
264 case EbtSampler2DArrayShadow:
265 return false;
266 default:
267 assert(!IsSampler(type));
268 }
269
270 return false;
271 }
272
IsSamplerArray(TBasicType type)273 inline bool IsSamplerArray(TBasicType type)
274 {
275 switch(type)
276 {
277 case EbtSampler2DArray:
278 case EbtISampler2DArray:
279 case EbtUSampler2DArray:
280 case EbtSampler2DArrayShadow:
281 return true;
282 case EbtSampler2D:
283 case EbtISampler2D:
284 case EbtUSampler2D:
285 case EbtSampler2DRect:
286 case EbtSamplerExternalOES:
287 case EbtSampler3D:
288 case EbtISampler3D:
289 case EbtUSampler3D:
290 case EbtISamplerCube:
291 case EbtUSamplerCube:
292 case EbtSamplerCube:
293 case EbtSampler2DShadow:
294 case EbtSamplerCubeShadow:
295 return false;
296 default:
297 assert(!IsSampler(type));
298 }
299
300 return false;
301 }
302
IsShadowSampler(TBasicType type)303 inline bool IsShadowSampler(TBasicType type)
304 {
305 switch(type)
306 {
307 case EbtSampler2DShadow:
308 case EbtSamplerCubeShadow:
309 case EbtSampler2DArrayShadow:
310 return true;
311 case EbtISampler2D:
312 case EbtISampler3D:
313 case EbtISamplerCube:
314 case EbtISampler2DArray:
315 case EbtUSampler2D:
316 case EbtUSampler3D:
317 case EbtUSamplerCube:
318 case EbtUSampler2DArray:
319 case EbtSampler2D:
320 case EbtSampler3D:
321 case EbtSamplerCube:
322 case EbtSampler2DRect:
323 case EbtSamplerExternalOES:
324 case EbtSampler2DArray:
325 return false;
326 default:
327 assert(!IsSampler(type));
328 }
329
330 return false;
331 }
332
IsInteger(TBasicType type)333 inline bool IsInteger(TBasicType type)
334 {
335 return type == EbtInt || type == EbtUInt;
336 }
337
SupportsPrecision(TBasicType type)338 inline bool SupportsPrecision(TBasicType type)
339 {
340 return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type);
341 }
342
343 //
344 // Qualifiers and built-ins. These are mainly used to see what can be read
345 // or written, and by the machine dependent translator to know which registers
346 // to allocate variables in. Since built-ins tend to go to different registers
347 // than varying or uniform, it makes sense they are peers, not sub-classes.
348 //
349 enum TQualifier : unsigned char
350 {
351 EvqTemporary, // For temporaries (within a function), read/write
352 EvqGlobal, // For globals read/write
353 EvqConstExpr, // User defined constants
354 EvqAttribute, // Readonly
355 EvqVaryingIn, // readonly, fragment shaders only
356 EvqVaryingOut, // vertex shaders only read/write
357 EvqInvariantVaryingIn, // readonly, fragment shaders only
358 EvqInvariantVaryingOut, // vertex shaders only read/write
359 EvqUniform, // Readonly, vertex and fragment
360
361 EvqVertexIn, // Vertex shader input
362 EvqFragmentOut, // Fragment shader output
363 EvqVertexOut, // Vertex shader output
364 EvqFragmentIn, // Fragment shader input
365
366 // pack/unpack input and output
367 EvqInput,
368 EvqOutput,
369
370 // parameters
371 EvqIn,
372 EvqOut,
373 EvqInOut,
374 EvqConstReadOnly,
375
376 // built-ins written by vertex shader
377 EvqPosition,
378 EvqPointSize,
379 EvqInstanceID,
380 EvqVertexID,
381
382 // built-ins read by fragment shader
383 EvqFragCoord,
384 EvqFrontFacing,
385 EvqPointCoord,
386
387 // built-ins written by fragment shader
388 EvqFragColor,
389 EvqFragData,
390 EvqFragDepth,
391
392 // GLSL ES 3.0 vertex output and fragment input
393 EvqSmooth, // Incomplete qualifier, smooth is the default
394 EvqFlat, // Incomplete qualifier
395 EvqSmoothOut = EvqSmooth,
396 EvqFlatOut = EvqFlat,
397 EvqCentroidOut, // Implies smooth
398 EvqSmoothIn,
399 EvqFlatIn,
400 EvqCentroidIn, // Implies smooth
401
402 // end of list
403 EvqLast
404 };
405
406 struct TLayoutQualifier
407 {
createTLayoutQualifier408 static TLayoutQualifier create()
409 {
410 TLayoutQualifier layoutQualifier;
411
412 layoutQualifier.location = -1;
413 layoutQualifier.matrixPacking = EmpUnspecified;
414 layoutQualifier.blockStorage = EbsUnspecified;
415
416 return layoutQualifier;
417 }
418
isEmptyTLayoutQualifier419 bool isEmpty() const
420 {
421 return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified;
422 }
423
424 int location;
425 TLayoutMatrixPacking matrixPacking;
426 TLayoutBlockStorage blockStorage;
427 };
428
429 //
430 // This is just for debug print out, carried along with the definitions above.
431 //
getQualifierString(TQualifier qualifier)432 inline const char *getQualifierString(TQualifier qualifier)
433 {
434 switch(qualifier)
435 {
436 case EvqTemporary: return "Temporary"; break;
437 case EvqGlobal: return "Global"; break;
438 case EvqConstExpr: return "const"; break;
439 case EvqConstReadOnly: return "const"; break;
440 case EvqAttribute: return "attribute"; break;
441 case EvqVaryingIn: return "varying"; break;
442 case EvqVaryingOut: return "varying"; break;
443 case EvqInvariantVaryingIn: return "invariant varying"; break;
444 case EvqInvariantVaryingOut:return "invariant varying"; break;
445 case EvqUniform: return "uniform"; break;
446 case EvqVertexIn: return "in"; break;
447 case EvqFragmentOut: return "out"; break;
448 case EvqVertexOut: return "out"; break;
449 case EvqFragmentIn: return "in"; break;
450 case EvqIn: return "in"; break;
451 case EvqOut: return "out"; break;
452 case EvqInOut: return "inout"; break;
453 case EvqInput: return "input"; break;
454 case EvqOutput: return "output"; break;
455 case EvqPosition: return "Position"; break;
456 case EvqPointSize: return "PointSize"; break;
457 case EvqInstanceID: return "InstanceID"; break;
458 case EvqVertexID: return "VertexID"; break;
459 case EvqFragCoord: return "FragCoord"; break;
460 case EvqFrontFacing: return "FrontFacing"; break;
461 case EvqFragColor: return "FragColor"; break;
462 case EvqFragData: return "FragData"; break;
463 case EvqFragDepth: return "FragDepth"; break;
464 case EvqSmooth: return "Smooth"; break;
465 case EvqFlat: return "Flat"; break;
466 case EvqCentroidOut: return "CentroidOut"; break;
467 case EvqSmoothIn: return "SmoothIn"; break;
468 case EvqFlatIn: return "FlatIn"; break;
469 case EvqCentroidIn: return "CentroidIn"; break;
470 default: UNREACHABLE(qualifier); return "unknown qualifier";
471 }
472 }
473
474 #endif // _BASICTYPES_INCLUDED_
475