// // Copyright 2010 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. //
namespace
{ // [primarySize-1][secondarySize-1] is the GL type with a basic type of float.
constexpr GLenum kFloatGLType[4][4] = { // float1xS only makes sense for S == 1
{
GL_FLOAT,
GL_NONE,
GL_NONE,
GL_NONE,
}, // float2xS is vec2 for S == 1, and mat2xS o.w.
{
GL_FLOAT_VEC2,
GL_FLOAT_MAT2,
GL_FLOAT_MAT2x3,
GL_FLOAT_MAT2x4,
}, // float3xS is vec3 for S == 1, and mat3xS o.w.
{
GL_FLOAT_VEC3,
GL_FLOAT_MAT3x2,
GL_FLOAT_MAT3,
GL_FLOAT_MAT3x4,
}, // float4xS is vec4 for S == 1, and mat4xS o.w.
{
GL_FLOAT_VEC4,
GL_FLOAT_MAT4x2,
GL_FLOAT_MAT4x3,
GL_FLOAT_MAT4,
},
}; // [primarySize-1] is the GL type with a basic type of int.
constexpr GLenum kIntGLType[4] = {GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4}; // [primarySize-1] is the GL type with a basic type of uint.
constexpr GLenum kUIntGLType[4] = {GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
GL_UNSIGNED_INT_VEC4}; // [primarySize-1] is the GL type with a basic type of bool.
constexpr GLenum kBoolGLType[4] = {GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4};
bool IsInterpolationIn(TQualifier qualifier)
{ switch (qualifier)
{ case EvqSmoothIn: case EvqFlatIn: case EvqNoPerspectiveIn: case EvqCentroidIn: case EvqSampleIn: returntrue; default: returnfalse;
}
}
bool IsInterpolationOut(TQualifier qualifier)
{ switch (qualifier)
{ case EvqSmoothOut: case EvqFlatOut: case EvqNoPerspectiveOut: case EvqCentroidOut: case EvqSampleOut: returntrue; default: returnfalse;
}
}
} // anonymous namespace
float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
{ // Parses a decimal string using scientific notation into a floating point number. // Out-of-range values are converted to infinity. Values that are too small to be // represented are converted to zero.
// The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not // matter. unsignedint decimalMantissa = 0;
size_t i = 0; bool decimalPointSeen = false; bool nonZeroSeenInMantissa = false;
// The exponent offset reflects the position of the decimal point. int exponentOffset = -1;
// This is just a counter for how many decimal digits are written to decimalMantissa. int mantissaDecimalDigits = 0;
while (i < str.length())
{ constchar c = str[i]; if (c == 'e' || c == 'E')
{ break;
} if (c == '.')
{
decimalPointSeen = true;
++i; continue;
}
unsignedint digit = static_cast<unsignedint>(c - '0');
ASSERT(digit < 10u); if (digit != 0u)
{
nonZeroSeenInMantissa = true;
} if (nonZeroSeenInMantissa)
{ // Add bits to the mantissa until space runs out in 32-bit int. This should be // enough precision to make the resulting binary mantissa accurate to 1 ULP. if (decimalMantissa <= (std::numeric_limits<unsignedint>::max() - 9u) / 10u)
{
decimalMantissa = decimalMantissa * 10u + digit;
++mantissaDecimalDigits;
} if (!decimalPointSeen)
{
++exponentOffset;
}
} elseif (decimalPointSeen)
{
--exponentOffset;
}
++i;
} if (decimalMantissa == 0)
{ return 0.0f;
} int exponent = 0; if (i < str.length())
{
ASSERT(str[i] == 'e' || str[i] == 'E');
++i; bool exponentOutOfRange = false; bool negativeExponent = false; if (str[i] == '-')
{
negativeExponent = true;
++i;
} elseif (str[i] == '+')
{
++i;
} while (i < str.length())
{ constchar c = str[i]; unsignedint digit = static_cast<unsignedint>(c - '0');
ASSERT(digit < 10u); if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
{
exponent = exponent * 10 + digit;
} else
{
exponentOutOfRange = true;
}
++i;
} if (negativeExponent)
{
exponent = -exponent;
} if (exponentOutOfRange)
{ if (negativeExponent)
{ return 0.0f;
} else
{ return std::numeric_limits<float>::infinity();
}
}
} // Do the calculation in 64-bit to avoid overflow. longlong exponentLong = static_cast<longlong>(exponent) + static_cast<longlong>(exponentOffset); if (exponentLong > std::numeric_limits<float>::max_exponent10)
{ return std::numeric_limits<float>::infinity();
} elseif (exponentLong < std::numeric_limits<float>::min_exponent10)
{ return 0.0f;
} // The exponent is in range, so we need to actually evaluate the float.
exponent = static_cast<int>(exponentLong); double value = decimalMantissa;
// Calculate the exponent offset to normalize the mantissa. int normalizationExponentOffset = 1 - mantissaDecimalDigits; // Apply the exponent.
value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset)); if (value > static_cast<double>(std::numeric_limits<float>::max()))
{ return std::numeric_limits<float>::infinity();
} if (value < static_cast<double>(std::numeric_limits<float>::min()))
{ return 0.0f;
} returnstatic_cast<float>(value);
}
bool strtof_clamp(const std::string &str, float *value)
{ // Custom float parsing that can handle the following corner cases: // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting // number inside the float range. // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting // number inside the float range. // 3. The value is out-of-range and should be evaluated as infinity. // 4. The value is too small and should be evaluated as zero. // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
*value = NumericLexFloat32OutOfRangeToInfinity(str); return !gl::isInf(*value);
}
case EbtSampler2D: return GL_SAMPLER_2D; case EbtSampler3D: return GL_SAMPLER_3D; case EbtSamplerCube: return GL_SAMPLER_CUBE; case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES; case EbtSamplerExternal2DY2YEXT: return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT; case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ANGLE; case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY; case EbtSampler2DMS: return GL_SAMPLER_2D_MULTISAMPLE; case EbtSampler2DMSArray: return GL_SAMPLER_2D_MULTISAMPLE_ARRAY; case EbtSamplerCubeArray: return GL_SAMPLER_CUBE_MAP_ARRAY; case EbtSamplerBuffer: return GL_SAMPLER_BUFFER; case EbtISampler2D: return GL_INT_SAMPLER_2D; case EbtISampler3D: return GL_INT_SAMPLER_3D; case EbtISamplerCube: return GL_INT_SAMPLER_CUBE; case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY; case EbtISampler2DMS: return GL_INT_SAMPLER_2D_MULTISAMPLE; case EbtISampler2DMSArray: return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY; case EbtISamplerCubeArray: return GL_INT_SAMPLER_CUBE_MAP_ARRAY; case EbtISamplerBuffer: return GL_INT_SAMPLER_BUFFER; case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D; case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D; case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE; case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; case EbtUSampler2DMS: return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE; case EbtUSampler2DMSArray: return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY; case EbtUSamplerCubeArray: return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY; case EbtUSamplerBuffer: return GL_UNSIGNED_INT_SAMPLER_BUFFER; case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW; case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW; case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW; case EbtSamplerCubeArrayShadow: return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW; case EbtImage2D: return GL_IMAGE_2D; case EbtIImage2D: return GL_INT_IMAGE_2D; case EbtUImage2D: return GL_UNSIGNED_INT_IMAGE_2D; case EbtImage2DArray: return GL_IMAGE_2D_ARRAY; case EbtIImage2DArray: return GL_INT_IMAGE_2D_ARRAY; case EbtUImage2DArray: return GL_UNSIGNED_INT_IMAGE_2D_ARRAY; case EbtImage3D: return GL_IMAGE_3D; case EbtIImage3D: return GL_INT_IMAGE_3D; case EbtUImage3D: return GL_UNSIGNED_INT_IMAGE_3D; case EbtImageCube: return GL_IMAGE_CUBE; case EbtIImageCube: return GL_INT_IMAGE_CUBE; case EbtUImageCube: return GL_UNSIGNED_INT_IMAGE_CUBE; case EbtImageCubeArray: return GL_IMAGE_CUBE_MAP_ARRAY; case EbtIImageCubeArray: return GL_INT_IMAGE_CUBE_MAP_ARRAY; case EbtUImageCubeArray: return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY; case EbtImageBuffer: return GL_IMAGE_BUFFER; case EbtIImageBuffer: return GL_INT_IMAGE_BUFFER; case EbtUImageBuffer: return GL_UNSIGNED_INT_IMAGE_BUFFER; case EbtAtomicCounter: return GL_UNSIGNED_INT_ATOMIC_COUNTER; case EbtSamplerVideoWEBGL: return GL_SAMPLER_VIDEO_IMAGE_WEBGL; case EbtPixelLocalANGLE: case EbtIPixelLocalANGLE: case EbtUPixelLocalANGLE: // TODO(anglebug.com/7279): For now, we can expect PLS handles to be rewritten to images // before anyone calls into here.
[[fallthrough]]; default:
UNREACHABLE(); return GL_NONE;
}
}
GLenum GLVariablePrecision(const TType &type)
{ if (type.getBasicType() == EbtFloat)
{ switch (type.getPrecision())
{ case EbpHigh: return GL_HIGH_FLOAT; case EbpMedium: return GL_MEDIUM_FLOAT; case EbpLow: return GL_LOW_FLOAT; case EbpUndefined: // Desktop specs do not use precision return GL_NONE; default:
UNREACHABLE();
}
} elseif (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
{ switch (type.getPrecision())
{ case EbpHigh: return GL_HIGH_INT; case EbpMedium: return GL_MEDIUM_INT; case EbpLow: return GL_LOW_INT; case EbpUndefined: // Desktop specs do not use precision return GL_NONE; default:
UNREACHABLE();
}
}
// Other types (boolean, sampler) don't have a precision return GL_NONE;
}
ImmutableString ArrayString(const TType &type)
{ if (!type.isArray()) return ImmutableString("");
bool IsVaryingOut(TQualifier qualifier)
{ switch (qualifier)
{ case EvqVaryingOut: case EvqSmoothOut: case EvqFlatOut: case EvqNoPerspectiveOut: case EvqCentroidOut: case EvqVertexOut: case EvqGeometryOut: case EvqTessControlOut: case EvqTessEvaluationOut: case EvqSampleOut: case EvqPatchOut: returntrue;
default: break;
}
returnfalse;
}
bool IsVaryingIn(TQualifier qualifier)
{ switch (qualifier)
{ case EvqVaryingIn: case EvqSmoothIn: case EvqFlatIn: case EvqNoPerspectiveIn: case EvqCentroidIn: case EvqFragmentIn: case EvqGeometryIn: case EvqTessControlIn: case EvqTessEvaluationIn: case EvqSampleIn: case EvqPatchIn: returntrue;
bool IsMatrixGLType(GLenum type)
{ switch (type)
{ case GL_FLOAT_MAT2: case GL_FLOAT_MAT3: case GL_FLOAT_MAT4: case GL_FLOAT_MAT2x3: case GL_FLOAT_MAT2x4: case GL_FLOAT_MAT3x2: case GL_FLOAT_MAT3x4: case GL_FLOAT_MAT4x2: case GL_FLOAT_MAT4x3: returntrue; default: returnfalse;
}
}
InterpolationType GetInterpolationType(TQualifier qualifier)
{ switch (qualifier)
{ case EvqFlatIn: case EvqFlatOut: // The auxiliary storage qualifier patch is not used for interpolation // it is a compile-time error to use interpolation qualifiers with patch case EvqPatchIn: case EvqPatchOut: return INTERPOLATION_FLAT;
case EvqNoPerspectiveIn: case EvqNoPerspectiveOut: return INTERPOLATION_NOPERSPECTIVE;
case EvqSmoothIn: case EvqSmoothOut: case EvqVertexOut: case EvqFragmentIn: case EvqVaryingIn: case EvqVaryingOut: case EvqGeometryIn: case EvqGeometryOut: case EvqTessControlIn: case EvqTessControlOut: case EvqTessEvaluationIn: case EvqTessEvaluationOut: return INTERPOLATION_SMOOTH;
case EvqCentroidIn: case EvqCentroidOut: return INTERPOLATION_CENTROID;
case EvqSampleIn: case EvqSampleOut: return INTERPOLATION_SAMPLE; default:
UNREACHABLE(); return INTERPOLATION_SMOOTH;
}
}
// a field may not have qualifer without in or out.
InterpolationType GetFieldInterpolationType(TQualifier qualifier)
{ switch (qualifier)
{ case EvqFlat: return INTERPOLATION_FLAT; case EvqNoPerspective: return INTERPOLATION_NOPERSPECTIVE; case EvqSmooth: return INTERPOLATION_SMOOTH; case EvqCentroid: return INTERPOLATION_CENTROID; default: return GetInterpolationType(qualifier);
}
}
TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
{ switch (var.type)
{ case GL_BOOL: return TType(EbtBool); case GL_BOOL_VEC2: return TType(EbtBool, 2); case GL_BOOL_VEC3: return TType(EbtBool, 3); case GL_BOOL_VEC4: return TType(EbtBool, 4); case GL_FLOAT: return TType(EbtFloat); case GL_FLOAT_VEC2: return TType(EbtFloat, 2); case GL_FLOAT_VEC3: return TType(EbtFloat, 3); case GL_FLOAT_VEC4: return TType(EbtFloat, 4); case GL_FLOAT_MAT2: return TType(EbtFloat, 2, 2); case GL_FLOAT_MAT3: return TType(EbtFloat, 3, 3); case GL_FLOAT_MAT4: return TType(EbtFloat, 4, 4); case GL_FLOAT_MAT2x3: return TType(EbtFloat, 2, 3); case GL_FLOAT_MAT2x4: return TType(EbtFloat, 2, 4); case GL_FLOAT_MAT3x2: return TType(EbtFloat, 3, 2); case GL_FLOAT_MAT3x4: return TType(EbtFloat, 3, 4); case GL_FLOAT_MAT4x2: return TType(EbtFloat, 4, 2); case GL_FLOAT_MAT4x3: return TType(EbtFloat, 4, 3); case GL_INT: return TType(EbtInt); case GL_INT_VEC2: return TType(EbtInt, 2); case GL_INT_VEC3: return TType(EbtInt, 3); case GL_INT_VEC4: return TType(EbtInt, 4); case GL_UNSIGNED_INT: return TType(EbtUInt); case GL_UNSIGNED_INT_VEC2: return TType(EbtUInt, 2); case GL_UNSIGNED_INT_VEC3: return TType(EbtUInt, 3); case GL_UNSIGNED_INT_VEC4: return TType(EbtUInt, 4); default:
UNREACHABLE(); return TType();
}
}
// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
{ return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut;
}
bool IsBuiltinOutputVariable(TQualifier qualifier)
{ switch (qualifier)
{ case EvqPosition: case EvqPointSize: case EvqFragDepth: case EvqFragColor: case EvqSecondaryFragColorEXT: case EvqFragData: case EvqSecondaryFragDataEXT: case EvqClipDistance: case EvqCullDistance: case EvqLastFragData: case EvqSampleMask: returntrue; default: break;
} returnfalse;
}
bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
{ switch (qualifier)
{ case EvqFragCoord: case EvqPointCoord: case EvqFrontFacing: case EvqHelperInvocation: case EvqLastFragData: returntrue; default: break;
} returnfalse;
}
TIntermBinary *binaryNode = node->getAsBinaryNode(); if (binaryNode)
{ switch (binaryNode->getOp())
{ case EOpIndexDirectInterfaceBlock: case EOpIndexIndirect: case EOpIndexDirect: case EOpIndexDirectStruct: return IsInShaderStorageBlock(binaryNode->getLeft()); default: returnfalse;
}
}
GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq)
{ switch (iifq)
{ case EiifRGBA32F: return GL_RGBA32F; case EiifRGBA16F: return GL_RGBA16F; case EiifR32F: return GL_R32F; case EiifRGBA32UI: return GL_RGBA32UI; case EiifRGBA16UI: return GL_RGBA16UI; case EiifRGBA8UI: return GL_RGBA8UI; case EiifR32UI: return GL_R32UI; case EiifRGBA32I: return GL_RGBA32I; case EiifRGBA16I: return GL_RGBA16I; case EiifRGBA8I: return GL_RGBA8I; case EiifR32I: return GL_R32I; case EiifRGBA8: return GL_RGBA8; case EiifRGBA8_SNORM: return GL_RGBA8_SNORM; default: return GL_NONE;
}
}
switch (t1)
{ case EbtInt: switch (t2)
{ case EbtInt:
UNREACHABLE(); break; case EbtUInt: return ImplicitTypeConversion::Invalid; case EbtFloat: return ImplicitTypeConversion::Left; default: return ImplicitTypeConversion::Invalid;
} break; case EbtUInt: switch (t2)
{ case EbtInt: return ImplicitTypeConversion::Invalid; case EbtUInt:
UNREACHABLE(); break; case EbtFloat: return ImplicitTypeConversion::Left; default: return ImplicitTypeConversion::Invalid;
} break; case EbtFloat: switch (t2)
{ case EbtInt: case EbtUInt: return ImplicitTypeConversion::Right; case EbtFloat:
UNREACHABLE(); break; default: return ImplicitTypeConversion::Invalid;
} break; default: return ImplicitTypeConversion::Invalid;
} return ImplicitTypeConversion::Invalid;
}
bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op)
{ switch (conversion)
{ case sh::ImplicitTypeConversion::Same: returntrue; case sh::ImplicitTypeConversion::Left: switch (op)
{ case EOpEqual: case EOpNotEqual: case EOpLessThan: case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: case EOpAdd: case EOpSub: case EOpMul: case EOpDiv: returntrue; default: break;
} break; case sh::ImplicitTypeConversion::Right: switch (op)
{ case EOpAssign: case EOpInitialize: case EOpEqual: case EOpNotEqual: case EOpLessThan: case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: case EOpAdd: case EOpSub: case EOpMul: case EOpDiv: case EOpAddAssign: case EOpSubAssign: case EOpMulAssign: case EOpDivAssign: returntrue; default: break;
} break; case sh::ImplicitTypeConversion::Invalid: break;
} returnfalse;
}
bool IsPrecisionApplicableToType(TBasicType type)
{ switch (type)
{ case EbtInt: case EbtUInt: case EbtFloat: // TODO: find all types where precision is applicable; for example samplers. // http://anglebug.com/6132 returntrue; default: returnfalse;
}
}
bool IsRedeclarableBuiltIn(const ImmutableString &name)
{ return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_LastFragData" ||
name == "gl_PerVertex" || name == "gl_Position" || name == "gl_PointSize";
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.17Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.