| File: | root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp |
| Warning: | line 267, column 13 Undefined or garbage value returned to caller |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // | |||
| 2 | // Copyright 2010 The ANGLE Project Authors. All rights reserved. | |||
| 3 | // Use of this source code is governed by a BSD-style license that can be | |||
| 4 | // found in the LICENSE file. | |||
| 5 | // | |||
| 6 | ||||
| 7 | #include "compiler/translator/util.h" | |||
| 8 | ||||
| 9 | #include <limits> | |||
| 10 | ||||
| 11 | #include "common/utilities.h" | |||
| 12 | #include "compiler/preprocessor/numeric_lex.h" | |||
| 13 | #include "compiler/translator/ImmutableStringBuilder.h" | |||
| 14 | #include "compiler/translator/SymbolTable.h" | |||
| 15 | ||||
| 16 | bool atoi_clamp(const char *str, unsigned int *value) | |||
| 17 | { | |||
| 18 | bool success = angle::pp::numeric_lex_int(str, value); | |||
| 19 | if (!success) | |||
| 20 | *value = std::numeric_limits<unsigned int>::max(); | |||
| 21 | return success; | |||
| 22 | } | |||
| 23 | ||||
| 24 | namespace sh | |||
| 25 | { | |||
| 26 | ||||
| 27 | namespace | |||
| 28 | { | |||
| 29 | // [primarySize-1][secondarySize-1] is the GL type with a basic type of float. | |||
| 30 | constexpr GLenum kFloatGLType[4][4] = { | |||
| 31 | // float1xS only makes sense for S == 1 | |||
| 32 | { | |||
| 33 | GL_FLOAT0x1406, | |||
| 34 | GL_NONE0, | |||
| 35 | GL_NONE0, | |||
| 36 | GL_NONE0, | |||
| 37 | }, | |||
| 38 | // float2xS is vec2 for S == 1, and mat2xS o.w. | |||
| 39 | { | |||
| 40 | GL_FLOAT_VEC20x8B50, | |||
| 41 | GL_FLOAT_MAT20x8B5A, | |||
| 42 | GL_FLOAT_MAT2x30x8B65, | |||
| 43 | GL_FLOAT_MAT2x40x8B66, | |||
| 44 | }, | |||
| 45 | // float3xS is vec3 for S == 1, and mat3xS o.w. | |||
| 46 | { | |||
| 47 | GL_FLOAT_VEC30x8B51, | |||
| 48 | GL_FLOAT_MAT3x20x8B67, | |||
| 49 | GL_FLOAT_MAT30x8B5B, | |||
| 50 | GL_FLOAT_MAT3x40x8B68, | |||
| 51 | }, | |||
| 52 | // float4xS is vec4 for S == 1, and mat4xS o.w. | |||
| 53 | { | |||
| 54 | GL_FLOAT_VEC40x8B52, | |||
| 55 | GL_FLOAT_MAT4x20x8B69, | |||
| 56 | GL_FLOAT_MAT4x30x8B6A, | |||
| 57 | GL_FLOAT_MAT40x8B5C, | |||
| 58 | }, | |||
| 59 | }; | |||
| 60 | // [primarySize-1] is the GL type with a basic type of int. | |||
| 61 | constexpr GLenum kIntGLType[4] = {GL_INT0x1404, GL_INT_VEC20x8B53, GL_INT_VEC30x8B54, GL_INT_VEC40x8B55}; | |||
| 62 | // [primarySize-1] is the GL type with a basic type of uint. | |||
| 63 | constexpr GLenum kUIntGLType[4] = {GL_UNSIGNED_INT0x1405, GL_UNSIGNED_INT_VEC20x8DC6, GL_UNSIGNED_INT_VEC30x8DC7, | |||
| 64 | GL_UNSIGNED_INT_VEC40x8DC8}; | |||
| 65 | // [primarySize-1] is the GL type with a basic type of bool. | |||
| 66 | constexpr GLenum kBoolGLType[4] = {GL_BOOL0x8B56, GL_BOOL_VEC20x8B57, GL_BOOL_VEC30x8B58, GL_BOOL_VEC40x8B59}; | |||
| 67 | ||||
| 68 | bool IsInterpolationIn(TQualifier qualifier) | |||
| 69 | { | |||
| 70 | switch (qualifier) | |||
| 71 | { | |||
| 72 | case EvqSmoothIn: | |||
| 73 | case EvqFlatIn: | |||
| 74 | case EvqNoPerspectiveIn: | |||
| 75 | case EvqCentroidIn: | |||
| 76 | case EvqSampleIn: | |||
| 77 | return true; | |||
| 78 | default: | |||
| 79 | return false; | |||
| 80 | } | |||
| 81 | } | |||
| 82 | ||||
| 83 | bool IsInterpolationOut(TQualifier qualifier) | |||
| 84 | { | |||
| 85 | switch (qualifier) | |||
| 86 | { | |||
| 87 | case EvqSmoothOut: | |||
| 88 | case EvqFlatOut: | |||
| 89 | case EvqNoPerspectiveOut: | |||
| 90 | case EvqCentroidOut: | |||
| 91 | case EvqSampleOut: | |||
| 92 | return true; | |||
| 93 | default: | |||
| 94 | return false; | |||
| 95 | } | |||
| 96 | } | |||
| 97 | } // anonymous namespace | |||
| 98 | ||||
| 99 | float NumericLexFloat32OutOfRangeToInfinity(const std::string &str) | |||
| 100 | { | |||
| 101 | // Parses a decimal string using scientific notation into a floating point number. | |||
| 102 | // Out-of-range values are converted to infinity. Values that are too small to be | |||
| 103 | // represented are converted to zero. | |||
| 104 | ||||
| 105 | // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not | |||
| 106 | // matter. | |||
| 107 | unsigned int decimalMantissa = 0; | |||
| 108 | size_t i = 0; | |||
| 109 | bool decimalPointSeen = false; | |||
| 110 | bool nonZeroSeenInMantissa = false; | |||
| 111 | ||||
| 112 | // The exponent offset reflects the position of the decimal point. | |||
| 113 | int exponentOffset = -1; | |||
| 114 | ||||
| 115 | // This is just a counter for how many decimal digits are written to decimalMantissa. | |||
| 116 | int mantissaDecimalDigits = 0; | |||
| 117 | ||||
| 118 | while (i < str.length()) | |||
| 119 | { | |||
| 120 | const char c = str[i]; | |||
| 121 | if (c == 'e' || c == 'E') | |||
| 122 | { | |||
| 123 | break; | |||
| 124 | } | |||
| 125 | if (c == '.') | |||
| 126 | { | |||
| 127 | decimalPointSeen = true; | |||
| 128 | ++i; | |||
| 129 | continue; | |||
| 130 | } | |||
| 131 | ||||
| 132 | unsigned int digit = static_cast<unsigned int>(c - '0'); | |||
| 133 | ASSERT(digit < 10u)(digit < 10u ? static_cast<void>(0) : (!((::gl::priv ::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL))) ? static_cast <void>(0) : ::gl::priv::LogMessageVoidify() & (::gl ::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 133, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 133 << "): " << "digit < 10u" )); | |||
| 134 | if (digit != 0u) | |||
| 135 | { | |||
| 136 | nonZeroSeenInMantissa = true; | |||
| 137 | } | |||
| 138 | if (nonZeroSeenInMantissa) | |||
| 139 | { | |||
| 140 | // Add bits to the mantissa until space runs out in 32-bit int. This should be | |||
| 141 | // enough precision to make the resulting binary mantissa accurate to 1 ULP. | |||
| 142 | if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u) | |||
| 143 | { | |||
| 144 | decimalMantissa = decimalMantissa * 10u + digit; | |||
| 145 | ++mantissaDecimalDigits; | |||
| 146 | } | |||
| 147 | if (!decimalPointSeen) | |||
| 148 | { | |||
| 149 | ++exponentOffset; | |||
| 150 | } | |||
| 151 | } | |||
| 152 | else if (decimalPointSeen) | |||
| 153 | { | |||
| 154 | --exponentOffset; | |||
| 155 | } | |||
| 156 | ++i; | |||
| 157 | } | |||
| 158 | if (decimalMantissa == 0) | |||
| 159 | { | |||
| 160 | return 0.0f; | |||
| 161 | } | |||
| 162 | int exponent = 0; | |||
| 163 | if (i < str.length()) | |||
| 164 | { | |||
| 165 | ASSERT(str[i] == 'e' || str[i] == 'E')(str[i] == 'e' || str[i] == 'E' ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 165, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 165 << "): " << "str[i] == 'e' || str[i] == 'E'" )); | |||
| 166 | ++i; | |||
| 167 | bool exponentOutOfRange = false; | |||
| 168 | bool negativeExponent = false; | |||
| 169 | if (str[i] == '-') | |||
| 170 | { | |||
| 171 | negativeExponent = true; | |||
| 172 | ++i; | |||
| 173 | } | |||
| 174 | else if (str[i] == '+') | |||
| 175 | { | |||
| 176 | ++i; | |||
| 177 | } | |||
| 178 | while (i < str.length()) | |||
| 179 | { | |||
| 180 | const char c = str[i]; | |||
| 181 | unsigned int digit = static_cast<unsigned int>(c - '0'); | |||
| 182 | ASSERT(digit < 10u)(digit < 10u ? static_cast<void>(0) : (!((::gl::priv ::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL))) ? static_cast <void>(0) : ::gl::priv::LogMessageVoidify() & (::gl ::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 182, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 182 << "): " << "digit < 10u" )); | |||
| 183 | if (exponent <= (std::numeric_limits<int>::max() - 9) / 10) | |||
| 184 | { | |||
| 185 | exponent = exponent * 10 + digit; | |||
| 186 | } | |||
| 187 | else | |||
| 188 | { | |||
| 189 | exponentOutOfRange = true; | |||
| 190 | } | |||
| 191 | ++i; | |||
| 192 | } | |||
| 193 | if (negativeExponent) | |||
| 194 | { | |||
| 195 | exponent = -exponent; | |||
| 196 | } | |||
| 197 | if (exponentOutOfRange) | |||
| 198 | { | |||
| 199 | if (negativeExponent) | |||
| 200 | { | |||
| 201 | return 0.0f; | |||
| 202 | } | |||
| 203 | else | |||
| 204 | { | |||
| 205 | return std::numeric_limits<float>::infinity(); | |||
| 206 | } | |||
| 207 | } | |||
| 208 | } | |||
| 209 | // Do the calculation in 64-bit to avoid overflow. | |||
| 210 | long long exponentLong = | |||
| 211 | static_cast<long long>(exponent) + static_cast<long long>(exponentOffset); | |||
| 212 | if (exponentLong > std::numeric_limits<float>::max_exponent10) | |||
| 213 | { | |||
| 214 | return std::numeric_limits<float>::infinity(); | |||
| 215 | } | |||
| 216 | else if (exponentLong < std::numeric_limits<float>::min_exponent10) | |||
| 217 | { | |||
| 218 | return 0.0f; | |||
| 219 | } | |||
| 220 | // The exponent is in range, so we need to actually evaluate the float. | |||
| 221 | exponent = static_cast<int>(exponentLong); | |||
| 222 | double value = decimalMantissa; | |||
| 223 | ||||
| 224 | // Calculate the exponent offset to normalize the mantissa. | |||
| 225 | int normalizationExponentOffset = 1 - mantissaDecimalDigits; | |||
| 226 | // Apply the exponent. | |||
| 227 | value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset)); | |||
| 228 | if (value > static_cast<double>(std::numeric_limits<float>::max())) | |||
| 229 | { | |||
| 230 | return std::numeric_limits<float>::infinity(); | |||
| 231 | } | |||
| 232 | if (value < static_cast<double>(std::numeric_limits<float>::min())) | |||
| 233 | { | |||
| 234 | return 0.0f; | |||
| 235 | } | |||
| 236 | return static_cast<float>(value); | |||
| 237 | } | |||
| 238 | ||||
| 239 | bool strtof_clamp(const std::string &str, float *value) | |||
| 240 | { | |||
| 241 | // Custom float parsing that can handle the following corner cases: | |||
| 242 | // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting | |||
| 243 | // number inside the float range. | |||
| 244 | // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting | |||
| 245 | // number inside the float range. | |||
| 246 | // 3. The value is out-of-range and should be evaluated as infinity. | |||
| 247 | // 4. The value is too small and should be evaluated as zero. | |||
| 248 | // See ESSL 3.00.6 section 4.1.4 for the relevant specification. | |||
| 249 | *value = NumericLexFloat32OutOfRangeToInfinity(str); | |||
| 250 | return !gl::isInf(*value); | |||
| 251 | } | |||
| 252 | ||||
| 253 | GLenum GLVariableType(const TType &type) | |||
| 254 | { | |||
| 255 | switch (type.getBasicType()) | |||
| ||||
| 256 | { | |||
| 257 | case EbtFloat: | |||
| 258 | ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize () <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage (::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv ::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 258, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 258 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4" )); | |||
| 259 | ASSERT(type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4)(type.getSecondarySize() >= 1 && type.getSecondarySize () <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage (::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv ::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 259, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 259 << "): " << "type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4" )); | |||
| 260 | ||||
| 261 | return kFloatGLType[type.getNominalSize() - 1][type.getSecondarySize() - 1]; | |||
| 262 | ||||
| 263 | case EbtInt: | |||
| 264 | ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize () <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage (::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv ::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 264, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 264 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4" )); | |||
| 265 | ASSERT(type.getSecondarySize() == 1)(type.getSecondarySize() == 1 ? static_cast<void>(0) : ( !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 265, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 265 << "): " << "type.getSecondarySize() == 1" )); | |||
| 266 | ||||
| 267 | return kIntGLType[type.getNominalSize() - 1]; | |||
| ||||
| 268 | ||||
| 269 | case EbtUInt: | |||
| 270 | ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize () <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage (::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv ::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 270, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 270 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4" )); | |||
| 271 | ASSERT(type.getSecondarySize() == 1)(type.getSecondarySize() == 1 ? static_cast<void>(0) : ( !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 271, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 271 << "): " << "type.getSecondarySize() == 1" )); | |||
| 272 | ||||
| 273 | return kUIntGLType[type.getNominalSize() - 1]; | |||
| 274 | ||||
| 275 | case EbtBool: | |||
| 276 | ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize () <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage (::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv ::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 276, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 276 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4" )); | |||
| 277 | ASSERT(type.getSecondarySize() == 1)(type.getSecondarySize() == 1 ? static_cast<void>(0) : ( !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 277, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in " << __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 277 << "): " << "type.getSecondarySize() == 1" )); | |||
| 278 | ||||
| 279 | return kBoolGLType[type.getNominalSize() - 1]; | |||
| 280 | ||||
| 281 | case EbtSampler2D: | |||
| 282 | return GL_SAMPLER_2D0x8B5E; | |||
| 283 | case EbtSampler3D: | |||
| 284 | return GL_SAMPLER_3D0x8B5F; | |||
| 285 | case EbtSamplerCube: | |||
| 286 | return GL_SAMPLER_CUBE0x8B60; | |||
| 287 | case EbtSamplerExternalOES: | |||
| 288 | return GL_SAMPLER_EXTERNAL_OES0x8D66; | |||
| 289 | case EbtSamplerExternal2DY2YEXT: | |||
| 290 | return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT0x8BE7; | |||
| 291 | case EbtSampler2DRect: | |||
| 292 | return GL_SAMPLER_2D_RECT_ANGLE0x8B63; | |||
| 293 | case EbtSampler2DArray: | |||
| 294 | return GL_SAMPLER_2D_ARRAY0x8DC1; | |||
| 295 | case EbtSampler2DMS: | |||
| 296 | return GL_SAMPLER_2D_MULTISAMPLE0x9108; | |||
| 297 | case EbtSampler2DMSArray: | |||
| 298 | return GL_SAMPLER_2D_MULTISAMPLE_ARRAY0x910B; | |||
| 299 | case EbtSamplerCubeArray: | |||
| 300 | return GL_SAMPLER_CUBE_MAP_ARRAY0x900C; | |||
| 301 | case EbtSamplerBuffer: | |||
| 302 | return GL_SAMPLER_BUFFER0x8DC2; | |||
| 303 | case EbtISampler2D: | |||
| 304 | return GL_INT_SAMPLER_2D0x8DCA; | |||
| 305 | case EbtISampler3D: | |||
| 306 | return GL_INT_SAMPLER_3D0x8DCB; | |||
| 307 | case EbtISamplerCube: | |||
| 308 | return GL_INT_SAMPLER_CUBE0x8DCC; | |||
| 309 | case EbtISampler2DArray: | |||
| 310 | return GL_INT_SAMPLER_2D_ARRAY0x8DCF; | |||
| 311 | case EbtISampler2DMS: | |||
| 312 | return GL_INT_SAMPLER_2D_MULTISAMPLE0x9109; | |||
| 313 | case EbtISampler2DMSArray: | |||
| 314 | return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY0x910C; | |||
| 315 | case EbtISamplerCubeArray: | |||
| 316 | return GL_INT_SAMPLER_CUBE_MAP_ARRAY0x900E; | |||
| 317 | case EbtISamplerBuffer: | |||
| 318 | return GL_INT_SAMPLER_BUFFER0x8DD0; | |||
| 319 | case EbtUSampler2D: | |||
| 320 | return GL_UNSIGNED_INT_SAMPLER_2D0x8DD2; | |||
| 321 | case EbtUSampler3D: | |||
| 322 | return GL_UNSIGNED_INT_SAMPLER_3D0x8DD3; | |||
| 323 | case EbtUSamplerCube: | |||
| 324 | return GL_UNSIGNED_INT_SAMPLER_CUBE0x8DD4; | |||
| 325 | case EbtUSampler2DArray: | |||
| 326 | return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY0x8DD7; | |||
| 327 | case EbtUSampler2DMS: | |||
| 328 | return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE0x910A; | |||
| 329 | case EbtUSampler2DMSArray: | |||
| 330 | return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY0x910D; | |||
| 331 | case EbtUSamplerCubeArray: | |||
| 332 | return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY0x900F; | |||
| 333 | case EbtUSamplerBuffer: | |||
| 334 | return GL_UNSIGNED_INT_SAMPLER_BUFFER0x8DD8; | |||
| 335 | case EbtSampler2DShadow: | |||
| 336 | return GL_SAMPLER_2D_SHADOW0x8B62; | |||
| 337 | case EbtSamplerCubeShadow: | |||
| 338 | return GL_SAMPLER_CUBE_SHADOW0x8DC5; | |||
| 339 | case EbtSampler2DArrayShadow: | |||
| 340 | return GL_SAMPLER_2D_ARRAY_SHADOW0x8DC4; | |||
| 341 | case EbtSamplerCubeArrayShadow: | |||
| 342 | return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW0x900D; | |||
| 343 | case EbtImage2D: | |||
| 344 | return GL_IMAGE_2D0x904D; | |||
| 345 | case EbtIImage2D: | |||
| 346 | return GL_INT_IMAGE_2D0x9058; | |||
| 347 | case EbtUImage2D: | |||
| 348 | return GL_UNSIGNED_INT_IMAGE_2D0x9063; | |||
| 349 | case EbtImage2DArray: | |||
| 350 | return GL_IMAGE_2D_ARRAY0x9053; | |||
| 351 | case EbtIImage2DArray: | |||
| 352 | return GL_INT_IMAGE_2D_ARRAY0x905E; | |||
| 353 | case EbtUImage2DArray: | |||
| 354 | return GL_UNSIGNED_INT_IMAGE_2D_ARRAY0x9069; | |||
| 355 | case EbtImage3D: | |||
| 356 | return GL_IMAGE_3D0x904E; | |||
| 357 | case EbtIImage3D: | |||
| 358 | return GL_INT_IMAGE_3D0x9059; | |||
| 359 | case EbtUImage3D: | |||
| 360 | return GL_UNSIGNED_INT_IMAGE_3D0x9064; | |||
| 361 | case EbtImageCube: | |||
| 362 | return GL_IMAGE_CUBE0x9050; | |||
| 363 | case EbtIImageCube: | |||
| 364 | return GL_INT_IMAGE_CUBE0x905B; | |||
| 365 | case EbtUImageCube: | |||
| 366 | return GL_UNSIGNED_INT_IMAGE_CUBE0x9066; | |||
| 367 | case EbtImageCubeArray: | |||
| 368 | return GL_IMAGE_CUBE_MAP_ARRAY0x9054; | |||
| 369 | case EbtIImageCubeArray: | |||
| 370 | return GL_INT_IMAGE_CUBE_MAP_ARRAY0x905F; | |||
| 371 | case EbtUImageCubeArray: | |||
| 372 | return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY0x906A; | |||
| 373 | case EbtImageBuffer: | |||
| 374 | return GL_IMAGE_BUFFER0x9051; | |||
| 375 | case EbtIImageBuffer: | |||
| 376 | return GL_INT_IMAGE_BUFFER0x905C; | |||
| 377 | case EbtUImageBuffer: | |||
| 378 | return GL_UNSIGNED_INT_IMAGE_BUFFER0x9067; | |||
| 379 | case EbtAtomicCounter: | |||
| 380 | return GL_UNSIGNED_INT_ATOMIC_COUNTER0x92DB; | |||
| 381 | case EbtSamplerVideoWEBGL: | |||
| 382 | return GL_SAMPLER_VIDEO_IMAGE_WEBGL0x9249; | |||
| 383 | case EbtPixelLocalANGLE: | |||
| 384 | case EbtIPixelLocalANGLE: | |||
| 385 | case EbtUPixelLocalANGLE: | |||
| 386 | // TODO(anglebug.com/7279): For now, we can expect PLS handles to be rewritten to images | |||
| 387 | // before anyone calls into here. | |||
| 388 | [[fallthrough]]; | |||
| 389 | default: | |||
| 390 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 390, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 390 << ")"; } while (0); | |||
| 391 | return GL_NONE0; | |||
| 392 | } | |||
| 393 | } | |||
| 394 | ||||
| 395 | GLenum GLVariablePrecision(const TType &type) | |||
| 396 | { | |||
| 397 | if (type.getBasicType() == EbtFloat) | |||
| 398 | { | |||
| 399 | switch (type.getPrecision()) | |||
| 400 | { | |||
| 401 | case EbpHigh: | |||
| 402 | return GL_HIGH_FLOAT0x8DF2; | |||
| 403 | case EbpMedium: | |||
| 404 | return GL_MEDIUM_FLOAT0x8DF1; | |||
| 405 | case EbpLow: | |||
| 406 | return GL_LOW_FLOAT0x8DF0; | |||
| 407 | case EbpUndefined: | |||
| 408 | // Desktop specs do not use precision | |||
| 409 | return GL_NONE0; | |||
| 410 | default: | |||
| 411 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 411, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 411 << ")"; } while (0); | |||
| 412 | } | |||
| 413 | } | |||
| 414 | else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt) | |||
| 415 | { | |||
| 416 | switch (type.getPrecision()) | |||
| 417 | { | |||
| 418 | case EbpHigh: | |||
| 419 | return GL_HIGH_INT0x8DF5; | |||
| 420 | case EbpMedium: | |||
| 421 | return GL_MEDIUM_INT0x8DF4; | |||
| 422 | case EbpLow: | |||
| 423 | return GL_LOW_INT0x8DF3; | |||
| 424 | case EbpUndefined: | |||
| 425 | // Desktop specs do not use precision | |||
| 426 | return GL_NONE0; | |||
| 427 | default: | |||
| 428 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 428, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 428 << ")"; } while (0); | |||
| 429 | } | |||
| 430 | } | |||
| 431 | ||||
| 432 | // Other types (boolean, sampler) don't have a precision | |||
| 433 | return GL_NONE0; | |||
| 434 | } | |||
| 435 | ||||
| 436 | ImmutableString ArrayString(const TType &type) | |||
| 437 | { | |||
| 438 | if (!type.isArray()) | |||
| 439 | return ImmutableString(""); | |||
| 440 | ||||
| 441 | const TSpan<const unsigned int> &arraySizes = type.getArraySizes(); | |||
| 442 | constexpr const size_t kMaxDecimalDigitsPerSize = 10u; | |||
| 443 | ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u)); | |||
| 444 | for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend(); | |||
| 445 | ++arraySizeIter) | |||
| 446 | { | |||
| 447 | arrayString << "["; | |||
| 448 | if (*arraySizeIter > 0) | |||
| 449 | { | |||
| 450 | arrayString.appendDecimal(*arraySizeIter); | |||
| 451 | } | |||
| 452 | arrayString << "]"; | |||
| 453 | } | |||
| 454 | return arrayString; | |||
| 455 | } | |||
| 456 | ||||
| 457 | ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap) | |||
| 458 | { | |||
| 459 | if (type.getBasicType() == EbtStruct) | |||
| 460 | return HashName(type.getStruct(), hashFunction, nameMap); | |||
| 461 | else | |||
| 462 | return ImmutableString(type.getBuiltInTypeNameString()); | |||
| 463 | } | |||
| 464 | ||||
| 465 | bool IsVaryingOut(TQualifier qualifier) | |||
| 466 | { | |||
| 467 | switch (qualifier) | |||
| 468 | { | |||
| 469 | case EvqVaryingOut: | |||
| 470 | case EvqSmoothOut: | |||
| 471 | case EvqFlatOut: | |||
| 472 | case EvqNoPerspectiveOut: | |||
| 473 | case EvqCentroidOut: | |||
| 474 | case EvqVertexOut: | |||
| 475 | case EvqGeometryOut: | |||
| 476 | case EvqTessControlOut: | |||
| 477 | case EvqTessEvaluationOut: | |||
| 478 | case EvqSampleOut: | |||
| 479 | case EvqPatchOut: | |||
| 480 | return true; | |||
| 481 | ||||
| 482 | default: | |||
| 483 | break; | |||
| 484 | } | |||
| 485 | ||||
| 486 | return false; | |||
| 487 | } | |||
| 488 | ||||
| 489 | bool IsVaryingIn(TQualifier qualifier) | |||
| 490 | { | |||
| 491 | switch (qualifier) | |||
| 492 | { | |||
| 493 | case EvqVaryingIn: | |||
| 494 | case EvqSmoothIn: | |||
| 495 | case EvqFlatIn: | |||
| 496 | case EvqNoPerspectiveIn: | |||
| 497 | case EvqCentroidIn: | |||
| 498 | case EvqFragmentIn: | |||
| 499 | case EvqGeometryIn: | |||
| 500 | case EvqTessControlIn: | |||
| 501 | case EvqTessEvaluationIn: | |||
| 502 | case EvqSampleIn: | |||
| 503 | case EvqPatchIn: | |||
| 504 | return true; | |||
| 505 | ||||
| 506 | default: | |||
| 507 | break; | |||
| 508 | } | |||
| 509 | ||||
| 510 | return false; | |||
| 511 | } | |||
| 512 | ||||
| 513 | bool IsVarying(TQualifier qualifier) | |||
| 514 | { | |||
| 515 | return IsVaryingIn(qualifier) || IsVaryingOut(qualifier); | |||
| 516 | } | |||
| 517 | ||||
| 518 | bool IsMatrixGLType(GLenum type) | |||
| 519 | { | |||
| 520 | switch (type) | |||
| 521 | { | |||
| 522 | case GL_FLOAT_MAT20x8B5A: | |||
| 523 | case GL_FLOAT_MAT30x8B5B: | |||
| 524 | case GL_FLOAT_MAT40x8B5C: | |||
| 525 | case GL_FLOAT_MAT2x30x8B65: | |||
| 526 | case GL_FLOAT_MAT2x40x8B66: | |||
| 527 | case GL_FLOAT_MAT3x20x8B67: | |||
| 528 | case GL_FLOAT_MAT3x40x8B68: | |||
| 529 | case GL_FLOAT_MAT4x20x8B69: | |||
| 530 | case GL_FLOAT_MAT4x30x8B6A: | |||
| 531 | return true; | |||
| 532 | default: | |||
| 533 | return false; | |||
| 534 | } | |||
| 535 | } | |||
| 536 | ||||
| 537 | bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier) | |||
| 538 | { | |||
| 539 | return (qualifier == EvqGeometryIn) || | |||
| 540 | ((shaderType == GL_GEOMETRY_SHADER_EXT0x8DD9) && IsInterpolationIn(qualifier)); | |||
| 541 | } | |||
| 542 | ||||
| 543 | bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier) | |||
| 544 | { | |||
| 545 | return qualifier == EvqTessControlIn || | |||
| 546 | ((shaderType == GL_TESS_CONTROL_SHADER0x8E88) && IsInterpolationIn(qualifier)); | |||
| 547 | } | |||
| 548 | ||||
| 549 | bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier) | |||
| 550 | { | |||
| 551 | return qualifier == EvqTessControlOut || | |||
| 552 | ((shaderType == GL_TESS_CONTROL_SHADER0x8E88) && IsInterpolationOut(qualifier)); | |||
| 553 | } | |||
| 554 | ||||
| 555 | bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier) | |||
| 556 | { | |||
| 557 | return qualifier == EvqTessEvaluationIn || | |||
| 558 | ((shaderType == GL_TESS_EVALUATION_SHADER0x8E87) && IsInterpolationIn(qualifier)); | |||
| 559 | } | |||
| 560 | ||||
| 561 | InterpolationType GetInterpolationType(TQualifier qualifier) | |||
| 562 | { | |||
| 563 | switch (qualifier) | |||
| 564 | { | |||
| 565 | case EvqFlatIn: | |||
| 566 | case EvqFlatOut: | |||
| 567 | // The auxiliary storage qualifier patch is not used for interpolation | |||
| 568 | // it is a compile-time error to use interpolation qualifiers with patch | |||
| 569 | case EvqPatchIn: | |||
| 570 | case EvqPatchOut: | |||
| 571 | return INTERPOLATION_FLAT; | |||
| 572 | ||||
| 573 | case EvqNoPerspectiveIn: | |||
| 574 | case EvqNoPerspectiveOut: | |||
| 575 | return INTERPOLATION_NOPERSPECTIVE; | |||
| 576 | ||||
| 577 | case EvqSmoothIn: | |||
| 578 | case EvqSmoothOut: | |||
| 579 | case EvqVertexOut: | |||
| 580 | case EvqFragmentIn: | |||
| 581 | case EvqVaryingIn: | |||
| 582 | case EvqVaryingOut: | |||
| 583 | case EvqGeometryIn: | |||
| 584 | case EvqGeometryOut: | |||
| 585 | case EvqTessControlIn: | |||
| 586 | case EvqTessControlOut: | |||
| 587 | case EvqTessEvaluationIn: | |||
| 588 | case EvqTessEvaluationOut: | |||
| 589 | return INTERPOLATION_SMOOTH; | |||
| 590 | ||||
| 591 | case EvqCentroidIn: | |||
| 592 | case EvqCentroidOut: | |||
| 593 | return INTERPOLATION_CENTROID; | |||
| 594 | ||||
| 595 | case EvqSampleIn: | |||
| 596 | case EvqSampleOut: | |||
| 597 | return INTERPOLATION_SAMPLE; | |||
| 598 | default: | |||
| 599 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 599, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 599 << ")"; } while (0); | |||
| 600 | return INTERPOLATION_SMOOTH; | |||
| 601 | } | |||
| 602 | } | |||
| 603 | ||||
| 604 | // a field may not have qualifer without in or out. | |||
| 605 | InterpolationType GetFieldInterpolationType(TQualifier qualifier) | |||
| 606 | { | |||
| 607 | switch (qualifier) | |||
| 608 | { | |||
| 609 | case EvqFlat: | |||
| 610 | return INTERPOLATION_FLAT; | |||
| 611 | case EvqNoPerspective: | |||
| 612 | return INTERPOLATION_NOPERSPECTIVE; | |||
| 613 | case EvqSmooth: | |||
| 614 | return INTERPOLATION_SMOOTH; | |||
| 615 | case EvqCentroid: | |||
| 616 | return INTERPOLATION_CENTROID; | |||
| 617 | default: | |||
| 618 | return GetInterpolationType(qualifier); | |||
| 619 | } | |||
| 620 | } | |||
| 621 | ||||
| 622 | TType GetShaderVariableBasicType(const sh::ShaderVariable &var) | |||
| 623 | { | |||
| 624 | switch (var.type) | |||
| 625 | { | |||
| 626 | case GL_BOOL0x8B56: | |||
| 627 | return TType(EbtBool); | |||
| 628 | case GL_BOOL_VEC20x8B57: | |||
| 629 | return TType(EbtBool, 2); | |||
| 630 | case GL_BOOL_VEC30x8B58: | |||
| 631 | return TType(EbtBool, 3); | |||
| 632 | case GL_BOOL_VEC40x8B59: | |||
| 633 | return TType(EbtBool, 4); | |||
| 634 | case GL_FLOAT0x1406: | |||
| 635 | return TType(EbtFloat); | |||
| 636 | case GL_FLOAT_VEC20x8B50: | |||
| 637 | return TType(EbtFloat, 2); | |||
| 638 | case GL_FLOAT_VEC30x8B51: | |||
| 639 | return TType(EbtFloat, 3); | |||
| 640 | case GL_FLOAT_VEC40x8B52: | |||
| 641 | return TType(EbtFloat, 4); | |||
| 642 | case GL_FLOAT_MAT20x8B5A: | |||
| 643 | return TType(EbtFloat, 2, 2); | |||
| 644 | case GL_FLOAT_MAT30x8B5B: | |||
| 645 | return TType(EbtFloat, 3, 3); | |||
| 646 | case GL_FLOAT_MAT40x8B5C: | |||
| 647 | return TType(EbtFloat, 4, 4); | |||
| 648 | case GL_FLOAT_MAT2x30x8B65: | |||
| 649 | return TType(EbtFloat, 2, 3); | |||
| 650 | case GL_FLOAT_MAT2x40x8B66: | |||
| 651 | return TType(EbtFloat, 2, 4); | |||
| 652 | case GL_FLOAT_MAT3x20x8B67: | |||
| 653 | return TType(EbtFloat, 3, 2); | |||
| 654 | case GL_FLOAT_MAT3x40x8B68: | |||
| 655 | return TType(EbtFloat, 3, 4); | |||
| 656 | case GL_FLOAT_MAT4x20x8B69: | |||
| 657 | return TType(EbtFloat, 4, 2); | |||
| 658 | case GL_FLOAT_MAT4x30x8B6A: | |||
| 659 | return TType(EbtFloat, 4, 3); | |||
| 660 | case GL_INT0x1404: | |||
| 661 | return TType(EbtInt); | |||
| 662 | case GL_INT_VEC20x8B53: | |||
| 663 | return TType(EbtInt, 2); | |||
| 664 | case GL_INT_VEC30x8B54: | |||
| 665 | return TType(EbtInt, 3); | |||
| 666 | case GL_INT_VEC40x8B55: | |||
| 667 | return TType(EbtInt, 4); | |||
| 668 | case GL_UNSIGNED_INT0x1405: | |||
| 669 | return TType(EbtUInt); | |||
| 670 | case GL_UNSIGNED_INT_VEC20x8DC6: | |||
| 671 | return TType(EbtUInt, 2); | |||
| 672 | case GL_UNSIGNED_INT_VEC30x8DC7: | |||
| 673 | return TType(EbtUInt, 3); | |||
| 674 | case GL_UNSIGNED_INT_VEC40x8DC8: | |||
| 675 | return TType(EbtUInt, 4); | |||
| 676 | default: | |||
| 677 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 677, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 677 << ")"; } while (0); | |||
| 678 | return TType(); | |||
| 679 | } | |||
| 680 | } | |||
| 681 | ||||
| 682 | void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable) | |||
| 683 | { | |||
| 684 | TIntermDeclaration *declaration = new TIntermDeclaration(); | |||
| 685 | declaration->appendDeclarator(new TIntermSymbol(variable)); | |||
| 686 | ||||
| 687 | TIntermSequence *globalSequence = root->getSequence(); | |||
| 688 | globalSequence->insert(globalSequence->begin(), declaration); | |||
| 689 | } | |||
| 690 | ||||
| 691 | // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier | |||
| 692 | bool CanBeInvariantESSL1(TQualifier qualifier) | |||
| 693 | { | |||
| 694 | return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) || | |||
| 695 | IsBuiltinOutputVariable(qualifier) || | |||
| 696 | (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing); | |||
| 697 | } | |||
| 698 | ||||
| 699 | // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier | |||
| 700 | // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier | |||
| 701 | bool CanBeInvariantESSL3OrGreater(TQualifier qualifier) | |||
| 702 | { | |||
| 703 | return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut || | |||
| 704 | IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut; | |||
| 705 | } | |||
| 706 | ||||
| 707 | bool IsBuiltinOutputVariable(TQualifier qualifier) | |||
| 708 | { | |||
| 709 | switch (qualifier) | |||
| 710 | { | |||
| 711 | case EvqPosition: | |||
| 712 | case EvqPointSize: | |||
| 713 | case EvqFragDepth: | |||
| 714 | case EvqFragColor: | |||
| 715 | case EvqSecondaryFragColorEXT: | |||
| 716 | case EvqFragData: | |||
| 717 | case EvqSecondaryFragDataEXT: | |||
| 718 | case EvqClipDistance: | |||
| 719 | case EvqCullDistance: | |||
| 720 | case EvqLastFragData: | |||
| 721 | case EvqSampleMask: | |||
| 722 | return true; | |||
| 723 | default: | |||
| 724 | break; | |||
| 725 | } | |||
| 726 | return false; | |||
| 727 | } | |||
| 728 | ||||
| 729 | bool IsBuiltinFragmentInputVariable(TQualifier qualifier) | |||
| 730 | { | |||
| 731 | switch (qualifier) | |||
| 732 | { | |||
| 733 | case EvqFragCoord: | |||
| 734 | case EvqPointCoord: | |||
| 735 | case EvqFrontFacing: | |||
| 736 | case EvqHelperInvocation: | |||
| 737 | case EvqLastFragData: | |||
| 738 | return true; | |||
| 739 | default: | |||
| 740 | break; | |||
| 741 | } | |||
| 742 | return false; | |||
| 743 | } | |||
| 744 | ||||
| 745 | bool IsShaderOutput(TQualifier qualifier) | |||
| 746 | { | |||
| 747 | return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier); | |||
| 748 | } | |||
| 749 | ||||
| 750 | bool IsFragmentOutput(TQualifier qualifier) | |||
| 751 | { | |||
| 752 | switch (qualifier) | |||
| 753 | { | |||
| 754 | case EvqFragmentOut: | |||
| 755 | case EvqFragmentInOut: | |||
| 756 | return true; | |||
| 757 | default: | |||
| 758 | return false; | |||
| 759 | } | |||
| 760 | } | |||
| 761 | ||||
| 762 | bool IsOutputESSL(ShShaderOutput output) | |||
| 763 | { | |||
| 764 | return output == SH_ESSL_OUTPUT; | |||
| 765 | } | |||
| 766 | ||||
| 767 | bool IsOutputGLSL(ShShaderOutput output) | |||
| 768 | { | |||
| 769 | switch (output) | |||
| 770 | { | |||
| 771 | case SH_GLSL_130_OUTPUT: | |||
| 772 | case SH_GLSL_140_OUTPUT: | |||
| 773 | case SH_GLSL_150_CORE_OUTPUT: | |||
| 774 | case SH_GLSL_330_CORE_OUTPUT: | |||
| 775 | case SH_GLSL_400_CORE_OUTPUT: | |||
| 776 | case SH_GLSL_410_CORE_OUTPUT: | |||
| 777 | case SH_GLSL_420_CORE_OUTPUT: | |||
| 778 | case SH_GLSL_430_CORE_OUTPUT: | |||
| 779 | case SH_GLSL_440_CORE_OUTPUT: | |||
| 780 | case SH_GLSL_450_CORE_OUTPUT: | |||
| 781 | case SH_GLSL_COMPATIBILITY_OUTPUT: | |||
| 782 | return true; | |||
| 783 | default: | |||
| 784 | break; | |||
| 785 | } | |||
| 786 | return false; | |||
| 787 | } | |||
| 788 | bool IsOutputHLSL(ShShaderOutput output) | |||
| 789 | { | |||
| 790 | switch (output) | |||
| 791 | { | |||
| 792 | case SH_HLSL_3_0_OUTPUT: | |||
| 793 | case SH_HLSL_4_1_OUTPUT: | |||
| 794 | case SH_HLSL_4_0_FL9_3_OUTPUT: | |||
| 795 | return true; | |||
| 796 | default: | |||
| 797 | break; | |||
| 798 | } | |||
| 799 | return false; | |||
| 800 | } | |||
| 801 | bool IsOutputVulkan(ShShaderOutput output) | |||
| 802 | { | |||
| 803 | return output == SH_SPIRV_VULKAN_OUTPUT; | |||
| 804 | } | |||
| 805 | bool IsOutputMetal(ShShaderOutput output) | |||
| 806 | { | |||
| 807 | return output == SH_SPIRV_METAL_OUTPUT; | |||
| 808 | } | |||
| 809 | bool IsOutputMetalDirect(ShShaderOutput output) | |||
| 810 | { | |||
| 811 | return output == SH_MSL_METAL_OUTPUT; | |||
| 812 | } | |||
| 813 | ||||
| 814 | bool IsInShaderStorageBlock(TIntermTyped *node) | |||
| 815 | { | |||
| 816 | TIntermSwizzle *swizzleNode = node->getAsSwizzleNode(); | |||
| 817 | if (swizzleNode) | |||
| 818 | { | |||
| 819 | return IsInShaderStorageBlock(swizzleNode->getOperand()); | |||
| 820 | } | |||
| 821 | ||||
| 822 | TIntermBinary *binaryNode = node->getAsBinaryNode(); | |||
| 823 | if (binaryNode) | |||
| 824 | { | |||
| 825 | switch (binaryNode->getOp()) | |||
| 826 | { | |||
| 827 | case EOpIndexDirectInterfaceBlock: | |||
| 828 | case EOpIndexIndirect: | |||
| 829 | case EOpIndexDirect: | |||
| 830 | case EOpIndexDirectStruct: | |||
| 831 | return IsInShaderStorageBlock(binaryNode->getLeft()); | |||
| 832 | default: | |||
| 833 | return false; | |||
| 834 | } | |||
| 835 | } | |||
| 836 | ||||
| 837 | const TType &type = node->getType(); | |||
| 838 | return type.getQualifier() == EvqBuffer; | |||
| 839 | } | |||
| 840 | ||||
| 841 | GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq) | |||
| 842 | { | |||
| 843 | switch (iifq) | |||
| 844 | { | |||
| 845 | case EiifRGBA32F: | |||
| 846 | return GL_RGBA32F0x8814; | |||
| 847 | case EiifRGBA16F: | |||
| 848 | return GL_RGBA16F0x881A; | |||
| 849 | case EiifR32F: | |||
| 850 | return GL_R32F0x822E; | |||
| 851 | case EiifRGBA32UI: | |||
| 852 | return GL_RGBA32UI0x8D70; | |||
| 853 | case EiifRGBA16UI: | |||
| 854 | return GL_RGBA16UI0x8D76; | |||
| 855 | case EiifRGBA8UI: | |||
| 856 | return GL_RGBA8UI0x8D7C; | |||
| 857 | case EiifR32UI: | |||
| 858 | return GL_R32UI0x8236; | |||
| 859 | case EiifRGBA32I: | |||
| 860 | return GL_RGBA32I0x8D82; | |||
| 861 | case EiifRGBA16I: | |||
| 862 | return GL_RGBA16I0x8D88; | |||
| 863 | case EiifRGBA8I: | |||
| 864 | return GL_RGBA8I0x8D8E; | |||
| 865 | case EiifR32I: | |||
| 866 | return GL_R32I0x8235; | |||
| 867 | case EiifRGBA8: | |||
| 868 | return GL_RGBA80x8058; | |||
| 869 | case EiifRGBA8_SNORM: | |||
| 870 | return GL_RGBA8_SNORM0x8F97; | |||
| 871 | default: | |||
| 872 | return GL_NONE0; | |||
| 873 | } | |||
| 874 | } | |||
| 875 | ||||
| 876 | bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion) | |||
| 877 | { | |||
| 878 | return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec)); | |||
| 879 | } | |||
| 880 | ||||
| 881 | ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2) | |||
| 882 | { | |||
| 883 | if (t1 == t2) | |||
| 884 | return ImplicitTypeConversion::Same; | |||
| 885 | ||||
| 886 | switch (t1) | |||
| 887 | { | |||
| 888 | case EbtInt: | |||
| 889 | switch (t2) | |||
| 890 | { | |||
| 891 | case EbtInt: | |||
| 892 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 892, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 892 << ")"; } while (0); | |||
| 893 | break; | |||
| 894 | case EbtUInt: | |||
| 895 | return ImplicitTypeConversion::Invalid; | |||
| 896 | case EbtFloat: | |||
| 897 | return ImplicitTypeConversion::Left; | |||
| 898 | default: | |||
| 899 | return ImplicitTypeConversion::Invalid; | |||
| 900 | } | |||
| 901 | break; | |||
| 902 | case EbtUInt: | |||
| 903 | switch (t2) | |||
| 904 | { | |||
| 905 | case EbtInt: | |||
| 906 | return ImplicitTypeConversion::Invalid; | |||
| 907 | case EbtUInt: | |||
| 908 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 908, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 908 << ")"; } while (0); | |||
| 909 | break; | |||
| 910 | case EbtFloat: | |||
| 911 | return ImplicitTypeConversion::Left; | |||
| 912 | default: | |||
| 913 | return ImplicitTypeConversion::Invalid; | |||
| 914 | } | |||
| 915 | break; | |||
| 916 | case EbtFloat: | |||
| 917 | switch (t2) | |||
| 918 | { | |||
| 919 | case EbtInt: | |||
| 920 | case EbtUInt: | |||
| 921 | return ImplicitTypeConversion::Right; | |||
| 922 | case EbtFloat: | |||
| 923 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 923, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 923 << ")"; } while (0); | |||
| 924 | break; | |||
| 925 | default: | |||
| 926 | return ImplicitTypeConversion::Invalid; | |||
| 927 | } | |||
| 928 | break; | |||
| 929 | default: | |||
| 930 | return ImplicitTypeConversion::Invalid; | |||
| 931 | } | |||
| 932 | return ImplicitTypeConversion::Invalid; | |||
| 933 | } | |||
| 934 | ||||
| 935 | bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op) | |||
| 936 | { | |||
| 937 | switch (conversion) | |||
| 938 | { | |||
| 939 | case sh::ImplicitTypeConversion::Same: | |||
| 940 | return true; | |||
| 941 | case sh::ImplicitTypeConversion::Left: | |||
| 942 | switch (op) | |||
| 943 | { | |||
| 944 | case EOpEqual: | |||
| 945 | case EOpNotEqual: | |||
| 946 | case EOpLessThan: | |||
| 947 | case EOpGreaterThan: | |||
| 948 | case EOpLessThanEqual: | |||
| 949 | case EOpGreaterThanEqual: | |||
| 950 | case EOpAdd: | |||
| 951 | case EOpSub: | |||
| 952 | case EOpMul: | |||
| 953 | case EOpDiv: | |||
| 954 | return true; | |||
| 955 | default: | |||
| 956 | break; | |||
| 957 | } | |||
| 958 | break; | |||
| 959 | case sh::ImplicitTypeConversion::Right: | |||
| 960 | switch (op) | |||
| 961 | { | |||
| 962 | case EOpAssign: | |||
| 963 | case EOpInitialize: | |||
| 964 | case EOpEqual: | |||
| 965 | case EOpNotEqual: | |||
| 966 | case EOpLessThan: | |||
| 967 | case EOpGreaterThan: | |||
| 968 | case EOpLessThanEqual: | |||
| 969 | case EOpGreaterThanEqual: | |||
| 970 | case EOpAdd: | |||
| 971 | case EOpSub: | |||
| 972 | case EOpMul: | |||
| 973 | case EOpDiv: | |||
| 974 | case EOpAddAssign: | |||
| 975 | case EOpSubAssign: | |||
| 976 | case EOpMulAssign: | |||
| 977 | case EOpDivAssign: | |||
| 978 | return true; | |||
| 979 | default: | |||
| 980 | break; | |||
| 981 | } | |||
| 982 | break; | |||
| 983 | case sh::ImplicitTypeConversion::Invalid: | |||
| 984 | break; | |||
| 985 | } | |||
| 986 | return false; | |||
| 987 | } | |||
| 988 | ||||
| 989 | bool IsPrecisionApplicableToType(TBasicType type) | |||
| 990 | { | |||
| 991 | switch (type) | |||
| 992 | { | |||
| 993 | case EbtInt: | |||
| 994 | case EbtUInt: | |||
| 995 | case EbtFloat: | |||
| 996 | // TODO: find all types where precision is applicable; for example samplers. | |||
| 997 | // http://anglebug.com/6132 | |||
| 998 | return true; | |||
| 999 | default: | |||
| 1000 | return false; | |||
| 1001 | } | |||
| 1002 | } | |||
| 1003 | ||||
| 1004 | bool IsRedeclarableBuiltIn(const ImmutableString &name) | |||
| 1005 | { | |||
| 1006 | return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_LastFragData" || | |||
| 1007 | name == "gl_PerVertex" || name == "gl_Position" || name == "gl_PointSize"; | |||
| 1008 | } | |||
| 1009 | ||||
| 1010 | size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName) | |||
| 1011 | { | |||
| 1012 | for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex) | |||
| 1013 | { | |||
| 1014 | if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0) | |||
| 1015 | { | |||
| 1016 | return fieldIndex; | |||
| 1017 | } | |||
| 1018 | } | |||
| 1019 | UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL ))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify () & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" , __FUNCTION__, 1019, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: " << __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp" << ":" << 1019 << ")"; } while (0); | |||
| 1020 | return 0; | |||
| 1021 | } | |||
| 1022 | ||||
| 1023 | } // namespace sh |