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