| // Copyright 2016 The SwiftShader Authors. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #ifndef _BASICTYPES_INCLUDED_ | |
| #define _BASICTYPES_INCLUDED_ | |
| #include "debug.h" | |
| // | |
| // Precision qualifiers | |
| // | |
| enum TPrecision : unsigned char | |
| { | |
| // These need to be kept sorted | |
| EbpUndefined, | |
| EbpLow, | |
| EbpMedium, | |
| EbpHigh | |
| }; | |
| inline const char *getPrecisionString(TPrecision precision) | |
| { | |
| switch(precision) | |
| { | |
| case EbpHigh: return "highp"; break; | |
| case EbpMedium: return "mediump"; break; | |
| case EbpLow: return "lowp"; break; | |
| default: return "mediump"; break; // Safest fallback | |
| } | |
| } | |
| // | |
| // Basic type. Arrays, vectors, etc., are orthogonal to this. | |
| // | |
| enum TBasicType : unsigned char | |
| { | |
| EbtVoid, | |
| EbtFloat, | |
| EbtInt, | |
| EbtUInt, | |
| EbtBool, | |
| EbtGVec4, // non type: represents vec4, ivec4, and uvec4 | |
| EbtGenType, // non type: represents float, vec2, vec3, and vec4 | |
| EbtGenIType, // non type: represents int, ivec2, ivec3, and ivec4 | |
| EbtGenUType, // non type: represents uint, uvec2, uvec3, and uvec4 | |
| EbtGenBType, // non type: represents bool, bvec2, bvec3, and bvec4 | |
| EbtVec, // non type: represents vec2, vec3, and vec4 | |
| EbtIVec, // non type: represents ivec2, ivec3, and ivec4 | |
| EbtUVec, // non type: represents uvec2, uvec3, and uvec4 | |
| EbtBVec, // non type: represents bvec2, bvec3, and bvec4 | |
| EbtGuardSamplerBegin, // non type: see implementation of IsSampler() | |
| EbtSampler2D, | |
| EbtSampler3D, | |
| EbtSamplerCube, | |
| EbtSampler2DArray, | |
| EbtSampler2DRect, // Only valid if ARB_texture_rectangle exists. | |
| EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists. | |
| EbtISampler2D, | |
| EbtISampler3D, | |
| EbtISamplerCube, | |
| EbtISampler2DArray, | |
| EbtUSampler2D, | |
| EbtUSampler3D, | |
| EbtUSamplerCube, | |
| EbtUSampler2DArray, | |
| EbtSampler2DShadow, | |
| EbtSamplerCubeShadow, | |
| EbtSampler2DArrayShadow, | |
| EbtGuardSamplerEnd, // non type: see implementation of IsSampler() | |
| EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D | |
| EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D | |
| EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube | |
| EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray | |
| EbtStruct, | |
| EbtInterfaceBlock, | |
| EbtAddress, // should be deprecated?? | |
| EbtInvariant // used as a type when qualifying a previously declared variable as being invariant | |
| }; | |
| enum TLayoutMatrixPacking | |
| { | |
| EmpUnspecified, | |
| EmpRowMajor, | |
| EmpColumnMajor | |
| }; | |
| enum TLayoutBlockStorage | |
| { | |
| EbsUnspecified, | |
| EbsShared, | |
| EbsPacked, | |
| EbsStd140 | |
| }; | |
| inline const char *getBasicString(TBasicType type) | |
| { | |
| switch(type) | |
| { | |
| case EbtVoid: return "void"; | |
| case EbtFloat: return "float"; | |
| case EbtInt: return "int"; | |
| case EbtUInt: return "uint"; | |
| case EbtBool: return "bool"; | |
| case EbtSampler2D: return "sampler2D"; | |
| case EbtSamplerCube: return "samplerCube"; | |
| case EbtSampler2DRect: return "sampler2DRect"; | |
| case EbtSamplerExternalOES: return "samplerExternalOES"; | |
| case EbtSampler3D: return "sampler3D"; | |
| case EbtStruct: return "structure"; | |
| default: UNREACHABLE(type); return "unknown type"; | |
| } | |
| } | |
| inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq) | |
| { | |
| switch(mpq) | |
| { | |
| case EmpUnspecified: return "mp_unspecified"; | |
| case EmpRowMajor: return "row_major"; | |
| case EmpColumnMajor: return "column_major"; | |
| default: UNREACHABLE(mpq); return "unknown matrix packing"; | |
| } | |
| } | |
| inline const char* getBlockStorageString(TLayoutBlockStorage bsq) | |
| { | |
| switch(bsq) | |
| { | |
| case EbsUnspecified: return "bs_unspecified"; | |
| case EbsShared: return "shared"; | |
| case EbsPacked: return "packed"; | |
| case EbsStd140: return "std140"; | |
| default: UNREACHABLE(bsq); return "unknown block storage"; | |
| } | |
| } | |
| inline bool IsSampler(TBasicType type) | |
| { | |
| return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd; | |
| } | |
| inline bool IsIntegerSampler(TBasicType type) | |
| { | |
| switch(type) | |
| { | |
| case EbtISampler2D: | |
| case EbtISampler3D: | |
| case EbtISamplerCube: | |
| case EbtISampler2DArray: | |
| case EbtUSampler2D: | |
| case EbtUSampler3D: | |
| case EbtUSamplerCube: | |
| case EbtUSampler2DArray: | |
| return true; | |
| case EbtSampler2D: | |
| case EbtSampler3D: | |
| case EbtSamplerCube: | |
| case EbtSampler2DRect: | |
| case EbtSamplerExternalOES: | |
| case EbtSampler2DArray: | |
| case EbtSampler2DShadow: | |
| case EbtSamplerCubeShadow: | |
| case EbtSampler2DArrayShadow: | |
| return false; | |
| default: | |
| assert(!IsSampler(type)); | |
| } | |
| return false; | |
| } | |
| inline bool IsSampler2D(TBasicType type) | |
| { | |
| switch(type) | |
| { | |
| case EbtSampler2D: | |
| case EbtISampler2D: | |
| case EbtUSampler2D: | |
| case EbtSampler2DArray: | |
| case EbtISampler2DArray: | |
| case EbtUSampler2DArray: | |
| case EbtSampler2DRect: | |
| case EbtSamplerExternalOES: | |
| case EbtSampler2DShadow: | |
| case EbtSampler2DArrayShadow: | |
| return true; | |
| case EbtSampler3D: | |
| case EbtISampler3D: | |
| case EbtUSampler3D: | |
| case EbtISamplerCube: | |
| case EbtUSamplerCube: | |
| case EbtSamplerCube: | |
| case EbtSamplerCubeShadow: | |
| return false; | |
| default: | |
| assert(!IsSampler(type)); | |
| } | |
| return false; | |
| } | |
| inline bool IsSamplerCube(TBasicType type) | |
| { | |
| switch(type) | |
| { | |
| case EbtSamplerCube: | |
| case EbtISamplerCube: | |
| case EbtUSamplerCube: | |
| case EbtSamplerCubeShadow: | |
| return true; | |
| case EbtSampler2D: | |
| case EbtSampler3D: | |
| case EbtSampler2DRect: | |
| case EbtSamplerExternalOES: | |
| case EbtSampler2DArray: | |
| case EbtISampler2D: | |
| case EbtISampler3D: | |
| case EbtISampler2DArray: | |
| case EbtUSampler2D: | |
| case EbtUSampler3D: | |
| case EbtUSampler2DArray: | |
| case EbtSampler2DShadow: | |
| case EbtSampler2DArrayShadow: | |
| return false; | |
| default: | |
| assert(!IsSampler(type)); | |
| } | |
| return false; | |
| } | |
| inline bool IsSampler3D(TBasicType type) | |
| { | |
| switch(type) | |
| { | |
| case EbtSampler3D: | |
| case EbtISampler3D: | |
| case EbtUSampler3D: | |
| return true; | |
| case EbtSampler2D: | |
| case EbtSamplerCube: | |
| case EbtSampler2DRect: | |
| case EbtSamplerExternalOES: | |
| case EbtSampler2DArray: | |
| case EbtISampler2D: | |
| case EbtISamplerCube: | |
| case EbtISampler2DArray: | |
| case EbtUSampler2D: | |
| case EbtUSamplerCube: | |
| case EbtUSampler2DArray: | |
| case EbtSampler2DShadow: | |
| case EbtSamplerCubeShadow: | |
| case EbtSampler2DArrayShadow: | |
| return false; | |
| default: | |
| assert(!IsSampler(type)); | |
| } | |
| return false; | |
| } | |
| inline bool IsSamplerArray(TBasicType type) | |
| { | |
| switch(type) | |
| { | |
| case EbtSampler2DArray: | |
| case EbtISampler2DArray: | |
| case EbtUSampler2DArray: | |
| case EbtSampler2DArrayShadow: | |
| return true; | |
| case EbtSampler2D: | |
| case EbtISampler2D: | |
| case EbtUSampler2D: | |
| case EbtSampler2DRect: | |
| case EbtSamplerExternalOES: | |
| case EbtSampler3D: | |
| case EbtISampler3D: | |
| case EbtUSampler3D: | |
| case EbtISamplerCube: | |
| case EbtUSamplerCube: | |
| case EbtSamplerCube: | |
| case EbtSampler2DShadow: | |
| case EbtSamplerCubeShadow: | |
| return false; | |
| default: | |
| assert(!IsSampler(type)); | |
| } | |
| return false; | |
| } | |
| inline bool IsShadowSampler(TBasicType type) | |
| { | |
| switch(type) | |
| { | |
| case EbtSampler2DShadow: | |
| case EbtSamplerCubeShadow: | |
| case EbtSampler2DArrayShadow: | |
| return true; | |
| case EbtISampler2D: | |
| case EbtISampler3D: | |
| case EbtISamplerCube: | |
| case EbtISampler2DArray: | |
| case EbtUSampler2D: | |
| case EbtUSampler3D: | |
| case EbtUSamplerCube: | |
| case EbtUSampler2DArray: | |
| case EbtSampler2D: | |
| case EbtSampler3D: | |
| case EbtSamplerCube: | |
| case EbtSampler2DRect: | |
| case EbtSamplerExternalOES: | |
| case EbtSampler2DArray: | |
| return false; | |
| default: | |
| assert(!IsSampler(type)); | |
| } | |
| return false; | |
| } | |
| inline bool IsInteger(TBasicType type) | |
| { | |
| return type == EbtInt || type == EbtUInt; | |
| } | |
| inline bool SupportsPrecision(TBasicType type) | |
| { | |
| return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type); | |
| } | |
| // | |
| // Qualifiers and built-ins. These are mainly used to see what can be read | |
| // or written, and by the machine dependent translator to know which registers | |
| // to allocate variables in. Since built-ins tend to go to different registers | |
| // than varying or uniform, it makes sense they are peers, not sub-classes. | |
| // | |
| enum TQualifier : unsigned char | |
| { | |
| EvqTemporary, // For temporaries (within a function), read/write | |
| EvqGlobal, // For globals read/write | |
| EvqConstExpr, // User defined constants | |
| EvqAttribute, // Readonly | |
| EvqVaryingIn, // readonly, fragment shaders only | |
| EvqVaryingOut, // vertex shaders only read/write | |
| EvqInvariantVaryingIn, // readonly, fragment shaders only | |
| EvqInvariantVaryingOut, // vertex shaders only read/write | |
| EvqUniform, // Readonly, vertex and fragment | |
| EvqVertexIn, // Vertex shader input | |
| EvqFragmentOut, // Fragment shader output | |
| EvqVertexOut, // Vertex shader output | |
| EvqFragmentIn, // Fragment shader input | |
| // pack/unpack input and output | |
| EvqInput, | |
| EvqOutput, | |
| // parameters | |
| EvqIn, | |
| EvqOut, | |
| EvqInOut, | |
| EvqConstReadOnly, | |
| // built-ins written by vertex shader | |
| EvqPosition, | |
| EvqPointSize, | |
| EvqInstanceID, | |
| EvqVertexID, | |
| // built-ins read by fragment shader | |
| EvqFragCoord, | |
| EvqFrontFacing, | |
| EvqPointCoord, | |
| // built-ins written by fragment shader | |
| EvqFragColor, | |
| EvqFragData, | |
| EvqFragDepth, | |
| // GLSL ES 3.0 vertex output and fragment input | |
| EvqSmooth, // Incomplete qualifier, smooth is the default | |
| EvqFlat, // Incomplete qualifier | |
| EvqSmoothOut = EvqSmooth, | |
| EvqFlatOut = EvqFlat, | |
| EvqCentroidOut, // Implies smooth | |
| EvqSmoothIn, | |
| EvqFlatIn, | |
| EvqCentroidIn, // Implies smooth | |
| // end of list | |
| EvqLast | |
| }; | |
| struct TLayoutQualifier | |
| { | |
| static TLayoutQualifier create() | |
| { | |
| TLayoutQualifier layoutQualifier; | |
| layoutQualifier.location = -1; | |
| layoutQualifier.matrixPacking = EmpUnspecified; | |
| layoutQualifier.blockStorage = EbsUnspecified; | |
| return layoutQualifier; | |
| } | |
| bool isEmpty() const | |
| { | |
| return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified; | |
| } | |
| int location; | |
| TLayoutMatrixPacking matrixPacking; | |
| TLayoutBlockStorage blockStorage; | |
| }; | |
| // | |
| // This is just for debug print out, carried along with the definitions above. | |
| // | |
| inline const char *getQualifierString(TQualifier qualifier) | |
| { | |
| switch(qualifier) | |
| { | |
| case EvqTemporary: return "Temporary"; break; | |
| case EvqGlobal: return "Global"; break; | |
| case EvqConstExpr: return "const"; break; | |
| case EvqConstReadOnly: return "const"; break; | |
| case EvqAttribute: return "attribute"; break; | |
| case EvqVaryingIn: return "varying"; break; | |
| case EvqVaryingOut: return "varying"; break; | |
| case EvqInvariantVaryingIn: return "invariant varying"; break; | |
| case EvqInvariantVaryingOut:return "invariant varying"; break; | |
| case EvqUniform: return "uniform"; break; | |
| case EvqVertexIn: return "in"; break; | |
| case EvqFragmentOut: return "out"; break; | |
| case EvqVertexOut: return "out"; break; | |
| case EvqFragmentIn: return "in"; break; | |
| case EvqIn: return "in"; break; | |
| case EvqOut: return "out"; break; | |
| case EvqInOut: return "inout"; break; | |
| case EvqInput: return "input"; break; | |
| case EvqOutput: return "output"; break; | |
| case EvqPosition: return "Position"; break; | |
| case EvqPointSize: return "PointSize"; break; | |
| case EvqInstanceID: return "InstanceID"; break; | |
| case EvqVertexID: return "VertexID"; break; | |
| case EvqFragCoord: return "FragCoord"; break; | |
| case EvqFrontFacing: return "FrontFacing"; break; | |
| case EvqFragColor: return "FragColor"; break; | |
| case EvqFragData: return "FragData"; break; | |
| case EvqFragDepth: return "FragDepth"; break; | |
| case EvqSmooth: return "Smooth"; break; | |
| case EvqFlat: return "Flat"; break; | |
| case EvqCentroidOut: return "CentroidOut"; break; | |
| case EvqSmoothIn: return "SmoothIn"; break; | |
| case EvqFlatIn: return "FlatIn"; break; | |
| case EvqCentroidIn: return "CentroidIn"; break; | |
| default: UNREACHABLE(qualifier); return "unknown qualifier"; | |
| } | |
| } | |
| #endif // _BASICTYPES_INCLUDED_ |