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 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 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 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 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 148 inline bool IsSampler(TBasicType type) 149 { 150 return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd; 151 } 152 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 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 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 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 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 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 333 inline bool IsInteger(TBasicType type) 334 { 335 return type == EbtInt || type == EbtUInt; 336 } 337 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 { 408 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 419 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 // 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