blob: 67b465de8196c47c8d43d5dde4eb7c7ea988bec7 [file] [log] [blame]
// 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_