Caps.cpp (63665B)
1 // 2 // Copyright 2014 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 "libANGLE/Caps.h" 8 9 #include "common/angleutils.h" 10 #include "common/debug.h" 11 12 #include "libANGLE/formatutils.h" 13 14 #include "angle_gl.h" 15 16 #include <algorithm> 17 #include <sstream> 18 19 static void InsertExtensionString(const std::string &extension, 20 bool supported, 21 std::vector<std::string> *extensionVector) 22 { 23 if (supported) 24 { 25 extensionVector->push_back(extension); 26 } 27 } 28 29 namespace gl 30 { 31 32 TextureCaps::TextureCaps() = default; 33 34 TextureCaps::TextureCaps(const TextureCaps &other) = default; 35 36 TextureCaps &TextureCaps::operator=(const TextureCaps &other) = default; 37 38 TextureCaps::~TextureCaps() = default; 39 40 GLuint TextureCaps::getMaxSamples() const 41 { 42 return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0; 43 } 44 45 GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const 46 { 47 if (requestedSamples == 0) 48 { 49 return 0; 50 } 51 52 for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++) 53 { 54 GLuint samples = *i; 55 if (samples >= requestedSamples) 56 { 57 return samples; 58 } 59 } 60 61 return 0; 62 } 63 64 TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat, 65 const Version &clientVersion, 66 const Extensions &extensions) 67 { 68 TextureCaps caps; 69 70 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat); 71 caps.texturable = internalFormatInfo.textureSupport(clientVersion, extensions); 72 caps.filterable = internalFormatInfo.filterSupport(clientVersion, extensions); 73 caps.textureAttachment = internalFormatInfo.textureAttachmentSupport(clientVersion, extensions); 74 caps.renderbuffer = internalFormatInfo.renderbufferSupport(clientVersion, extensions); 75 caps.blendable = internalFormatInfo.blendSupport(clientVersion, extensions); 76 77 caps.sampleCounts.insert(0); 78 if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion)) 79 { 80 if ((clientVersion.major >= 3 && clientVersion.minor >= 1) || 81 (clientVersion.major >= 3 && !internalFormatInfo.isInt())) 82 { 83 caps.sampleCounts.insert(4); 84 } 85 } 86 87 return caps; 88 } 89 90 TextureCapsMap::TextureCapsMap() {} 91 92 TextureCapsMap::~TextureCapsMap() {} 93 94 void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps) 95 { 96 angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat); 97 get(formatID) = caps; 98 } 99 100 void TextureCapsMap::clear() 101 { 102 mFormatData.fill(TextureCaps()); 103 } 104 105 const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const 106 { 107 angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat); 108 return get(formatID); 109 } 110 111 const TextureCaps &TextureCapsMap::get(angle::FormatID formatID) const 112 { 113 return mFormatData[formatID]; 114 } 115 116 TextureCaps &TextureCapsMap::get(angle::FormatID formatID) 117 { 118 return mFormatData[formatID]; 119 } 120 121 void TextureCapsMap::set(angle::FormatID formatID, const TextureCaps &caps) 122 { 123 get(formatID) = caps; 124 } 125 126 void InitMinimumTextureCapsMap(const Version &clientVersion, 127 const Extensions &extensions, 128 TextureCapsMap *capsMap) 129 { 130 for (GLenum internalFormat : GetAllSizedInternalFormats()) 131 { 132 capsMap->insert(internalFormat, 133 GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions)); 134 } 135 } 136 137 Extensions::Extensions() = default; 138 139 Extensions::Extensions(const Extensions &other) = default; 140 141 Extensions &Extensions::operator=(const Extensions &other) = default; 142 143 std::vector<std::string> Extensions::getStrings() const 144 { 145 std::vector<std::string> extensionStrings; 146 147 for (const auto &extensionInfo : GetExtensionInfoMap()) 148 { 149 if (this->*(extensionInfo.second.ExtensionsMember)) 150 { 151 extensionStrings.push_back(extensionInfo.first); 152 } 153 } 154 155 return extensionStrings; 156 } 157 158 Limitations::Limitations() = default; 159 Limitations::Limitations(const Limitations &other) = default; 160 161 Limitations &Limitations::operator=(const Limitations &other) = default; 162 163 static bool GetFormatSupportBase(const TextureCapsMap &textureCaps, 164 const GLenum *requiredFormats, 165 size_t requiredFormatsSize, 166 bool requiresTexturing, 167 bool requiresFiltering, 168 bool requiresAttachingTexture, 169 bool requiresRenderbufferSupport, 170 bool requiresBlending) 171 { 172 for (size_t i = 0; i < requiredFormatsSize; i++) 173 { 174 const TextureCaps &cap = textureCaps.get(requiredFormats[i]); 175 if (requiresTexturing && !cap.texturable) 176 { 177 return false; 178 } 179 180 if (requiresFiltering && !cap.filterable) 181 { 182 return false; 183 } 184 185 if (requiresAttachingTexture && !cap.textureAttachment) 186 { 187 return false; 188 } 189 190 if (requiresRenderbufferSupport && !cap.renderbuffer) 191 { 192 return false; 193 } 194 195 if (requiresBlending && !cap.blendable) 196 { 197 return false; 198 } 199 } 200 201 return true; 202 } 203 204 template <size_t N> 205 static bool GetFormatSupport(const TextureCapsMap &textureCaps, 206 const GLenum (&requiredFormats)[N], 207 bool requiresTexturing, 208 bool requiresFiltering, 209 bool requiresAttachingTexture, 210 bool requiresRenderbufferSupport, 211 bool requiresBlending) 212 { 213 return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing, 214 requiresFiltering, requiresAttachingTexture, 215 requiresRenderbufferSupport, requiresBlending); 216 } 217 218 // Check for GL_OES_packed_depth_stencil support 219 static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps) 220 { 221 constexpr GLenum requiredFormats[] = { 222 GL_DEPTH24_STENCIL8, 223 }; 224 225 return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false); 226 } 227 228 // Checks for GL_NV_read_depth support 229 static bool DetermineReadDepthSupport(const TextureCapsMap &textureCaps) 230 { 231 constexpr GLenum requiredFormats[] = { 232 GL_DEPTH_COMPONENT16, 233 }; 234 235 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); 236 } 237 238 // Checks for GL_NV_read_stencil support 239 static bool DetermineReadStencilSupport(const TextureCapsMap &textureCaps) 240 { 241 constexpr GLenum requiredFormats[] = { 242 GL_STENCIL_INDEX8, 243 }; 244 245 return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false); 246 } 247 248 // Checks for GL_NV_depth_buffer_float2 support 249 static bool DetermineDepthBufferFloat2Support(const TextureCapsMap &textureCaps) 250 { 251 constexpr GLenum requiredFormats[] = { 252 GL_DEPTH_COMPONENT32F, 253 GL_DEPTH32F_STENCIL8, 254 }; 255 256 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); 257 } 258 259 // Checks for GL_OES_rgb8_rgba8 support 260 static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps) 261 { 262 constexpr GLenum requiredFormats[] = { 263 GL_RGB8, 264 GL_RGBA8, 265 }; 266 267 return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false); 268 } 269 270 // Checks for GL_EXT_texture_format_BGRA8888 support 271 static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps) 272 { 273 constexpr GLenum requiredFormats[] = { 274 GL_BGRA8_EXT, 275 }; 276 277 return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false); 278 } 279 280 // Checks for GL_EXT_read_format_bgra support 281 static bool DetermineBGRAReadFormatSupport(const TextureCapsMap &textureCaps) 282 { 283 constexpr GLenum requiredFormats[] = { 284 GL_BGRA8_EXT, 285 // TODO(http://anglebug.com/4302): GL_EXT_read_format_bgra specifies 2 more types, which are 286 // currently ignored. The equivalent formats would be: GL_BGRA4_ANGLEX, GL_BGR5_A1_ANGLEX 287 }; 288 289 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false); 290 } 291 292 // Checks for GL_OES_color_buffer_half_float support 293 static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps) 294 { 295 // EXT_color_buffer_half_float issue #2 states that an implementation doesn't need to support 296 // rendering to any of the formats but is expected to be able to render to at least one. WebGL 297 // requires that at least RGBA16F is renderable so we make the same requirement. 298 constexpr GLenum requiredFormats[] = { 299 GL_RGBA16F, 300 }; 301 302 return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false); 303 } 304 305 // Checks for GL_OES_texture_half_float support 306 static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps) 307 { 308 constexpr GLenum requiredFormats[] = { 309 GL_RGBA16F, GL_RGB16F, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT, GL_ALPHA16F_EXT, 310 }; 311 312 return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false); 313 } 314 315 // Checks for GL_OES_texture_half_float_linear support 316 static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps, 317 bool checkLegacyFormats) 318 { 319 constexpr GLenum requiredFormats[] = {GL_RGBA16F, GL_RGB16F}; 320 // If GL_OES_texture_half_float is present, this extension must also support legacy formats 321 // introduced by that extension 322 constexpr GLenum requiredFormatsES2[] = {GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT, 323 GL_ALPHA16F_EXT}; 324 325 if (checkLegacyFormats && 326 !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false)) 327 { 328 return false; 329 } 330 331 return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false); 332 } 333 334 // Checks for GL_OES_texture_float support 335 static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps) 336 { 337 constexpr GLenum requiredFormats[] = { 338 GL_RGBA32F, GL_RGB32F, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE32F_EXT, GL_ALPHA32F_EXT, 339 }; 340 341 return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false); 342 } 343 344 // Checks for GL_OES_texture_float_linear support 345 static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps, 346 bool checkLegacyFormats) 347 { 348 constexpr GLenum requiredFormats[] = { 349 GL_RGBA32F, 350 GL_RGB32F, 351 }; 352 // If GL_OES_texture_float is present, this extension must also support legacy formats 353 // introduced by that extension 354 constexpr GLenum requiredFormatsES2[] = { 355 GL_LUMINANCE_ALPHA32F_EXT, 356 GL_LUMINANCE32F_EXT, 357 GL_ALPHA32F_EXT, 358 }; 359 360 if (checkLegacyFormats && 361 !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false)) 362 { 363 return false; 364 } 365 366 return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false); 367 } 368 369 // Checks for GL_EXT_texture_rg support 370 static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, 371 bool checkHalfFloatFormats, 372 bool checkFloatFormats) 373 { 374 constexpr GLenum requiredFormats[] = { 375 GL_R8, 376 GL_RG8, 377 }; 378 constexpr GLenum requiredHalfFloatFormats[] = { 379 GL_R16F, 380 GL_RG16F, 381 }; 382 constexpr GLenum requiredFloatFormats[] = { 383 GL_R32F, 384 GL_RG32F, 385 }; 386 387 if (checkHalfFloatFormats && 388 !GetFormatSupport(textureCaps, requiredHalfFloatFormats, true, false, false, false, false)) 389 { 390 return false; 391 } 392 393 if (checkFloatFormats && 394 !GetFormatSupport(textureCaps, requiredFloatFormats, true, false, false, false, false)) 395 { 396 return false; 397 } 398 399 return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false); 400 } 401 402 static bool DetermineTextureFormat2101010Support(const TextureCapsMap &textureCaps) 403 { 404 // GL_EXT_texture_type_2_10_10_10_REV specifies both RGBA and RGB support whereas desktop GL 405 // only specifies RGBA support, so check both RGBA and RGB before marking as supported. 406 constexpr GLenum requiredFormats[] = { 407 GL_RGB10_A2, 408 GL_RGB10_UNORM_ANGLEX, 409 }; 410 411 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 412 } 413 414 // Check for GL_EXT_texture_compression_dxt1 support 415 static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps) 416 { 417 constexpr GLenum requiredFormats[] = { 418 GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 419 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 420 }; 421 422 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 423 } 424 425 // Check for GL_ANGLE_texture_compression_dxt3 support 426 static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps) 427 { 428 constexpr GLenum requiredFormats[] = { 429 GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 430 }; 431 432 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 433 } 434 435 // Check for GL_ANGLE_texture_compression_dxt5 support 436 static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps) 437 { 438 constexpr GLenum requiredFormats[] = { 439 GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, 440 }; 441 442 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 443 } 444 445 // Check for GL_EXT_texture_compression_s3tc_srgb support 446 static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps) 447 { 448 constexpr GLenum requiredFormats[] = { 449 GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 450 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 451 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 452 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 453 }; 454 455 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 456 } 457 458 // Check for GL_KHR_texture_compression_astc_ldr support 459 static bool DetermineASTCLDRTextureSupport(const TextureCapsMap &textureCaps) 460 { 461 constexpr GLenum requiredFormats[] = { 462 GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 463 GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 464 GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 465 GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 466 GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 467 GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 468 GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 469 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 470 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 471 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 472 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 473 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 474 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 475 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 476 }; 477 478 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 479 } 480 481 // Check for GL_OES_texture_compression_astc support 482 static bool DetermineASTCOESTExtureSupport(const TextureCapsMap &textureCaps) 483 { 484 if (!DetermineASTCLDRTextureSupport(textureCaps)) 485 { 486 return false; 487 } 488 489 // The OES version of the extension also requires the 3D ASTC formats 490 constexpr GLenum requiredFormats[] = { 491 GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, 492 GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, 493 GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, 494 GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, 495 GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, 496 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, 497 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, 498 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, 499 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, 500 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, 501 }; 502 503 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 504 } 505 506 // Check for GL_ETC1_RGB8_OES support 507 static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps) 508 { 509 constexpr GLenum requiredFormats[] = { 510 GL_ETC1_RGB8_OES, 511 }; 512 513 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 514 } 515 516 // Check for OES_compressed_ETC2_RGB8_texture support 517 static bool DetermineETC2RGB8TextureSupport(const TextureCapsMap &textureCaps) 518 { 519 constexpr GLenum requiredFormats[] = { 520 GL_COMPRESSED_RGB8_ETC2, 521 }; 522 523 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 524 } 525 526 // Check for OES_compressed_ETC2_sRGB8_texture support 527 static bool DetermineETC2sRGB8TextureSupport(const TextureCapsMap &textureCaps) 528 { 529 constexpr GLenum requiredFormats[] = { 530 GL_COMPRESSED_SRGB8_ETC2, 531 }; 532 533 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 534 } 535 536 // Check for OES_compressed_ETC2_punchthroughA_RGBA8_texture support 537 static bool DetermineETC2PunchthroughARGB8TextureSupport(const TextureCapsMap &textureCaps) 538 { 539 constexpr GLenum requiredFormats[] = { 540 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 541 }; 542 543 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 544 } 545 546 // Check for OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture support 547 static bool DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(const TextureCapsMap &textureCaps) 548 { 549 constexpr GLenum requiredFormats[] = { 550 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 551 }; 552 553 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 554 } 555 556 // Check for OES_compressed_ETC2_RGBA8_texture support 557 static bool DetermineETC2RGBA8TextureSupport(const TextureCapsMap &textureCaps) 558 { 559 constexpr GLenum requiredFormats[] = { 560 GL_COMPRESSED_RGBA8_ETC2_EAC, 561 }; 562 563 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 564 } 565 566 // Check for OES_compressed_ETC2_sRGB8_alpha8_texture support 567 static bool DetermineETC2sRGB8Alpha8TextureSupport(const TextureCapsMap &textureCaps) 568 { 569 constexpr GLenum requiredFormats[] = { 570 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 571 }; 572 573 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 574 } 575 576 // Check for OES_compressed_EAC_R11_unsigned_texture support 577 static bool DetermineEACR11UnsignedTextureSupport(const TextureCapsMap &textureCaps) 578 { 579 constexpr GLenum requiredFormats[] = { 580 GL_COMPRESSED_R11_EAC, 581 }; 582 583 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 584 } 585 586 // Check for OES_compressed_EAC_R11_signed_texture support 587 static bool DetermineEACR11SignedTextureSupport(const TextureCapsMap &textureCaps) 588 { 589 constexpr GLenum requiredFormats[] = { 590 GL_COMPRESSED_SIGNED_R11_EAC, 591 }; 592 593 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 594 } 595 596 // Check for OES_compressed_EAC_RG11_unsigned_texture support 597 static bool DetermineEACRG11UnsignedTextureSupport(const TextureCapsMap &textureCaps) 598 { 599 constexpr GLenum requiredFormats[] = { 600 GL_COMPRESSED_RG11_EAC, 601 }; 602 603 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 604 } 605 606 // Check for OES_compressed_EAC_RG11_signed_texture support 607 static bool DetermineEACRG11SignedTextureSupport(const TextureCapsMap &textureCaps) 608 { 609 constexpr GLenum requiredFormats[] = { 610 GL_COMPRESSED_SIGNED_RG11_EAC, 611 }; 612 613 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 614 } 615 616 // Check for GL_EXT_sRGB support 617 static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps) 618 { 619 constexpr GLenum requiredFilterFormats[] = { 620 GL_SRGB8, 621 GL_SRGB8_ALPHA8, 622 }; 623 624 constexpr GLenum requiredRenderFormats[] = { 625 GL_SRGB8_ALPHA8, 626 }; 627 628 return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) && 629 GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false); 630 } 631 632 // Check for GL_EXT_texture_sRGB_R8 support 633 static bool DetermineSRGBR8TextureSupport(const TextureCapsMap &textureCaps) 634 { 635 constexpr GLenum requiredFilterFormats[] = {GL_SR8_EXT}; 636 637 return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false); 638 } 639 640 // Check for GL_EXT_texture_sRGB_RG8 support 641 static bool DetermineSRGBRG8TextureSupport(const TextureCapsMap &textureCaps) 642 { 643 constexpr GLenum requiredFilterFormats[] = {GL_SRG8_EXT}; 644 645 return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false); 646 } 647 648 // Check for GL_ANGLE_depth_texture support 649 static bool DetermineDepthTextureANGLESupport(const TextureCapsMap &textureCaps) 650 { 651 constexpr GLenum requiredFormats[] = { 652 GL_DEPTH_COMPONENT16, 653 #if !defined(ANGLE_PLATFORM_IOS) && \ 654 (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64)) 655 // anglebug.com/6082 656 // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES 657 // because it is not supported on iOS. 658 // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac. 659 GL_DEPTH_COMPONENT32_OES, 660 #endif 661 GL_DEPTH24_STENCIL8_OES, 662 }; 663 664 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); 665 } 666 667 // Check for GL_OES_depth_texture support 668 static bool DetermineDepthTextureOESSupport(const TextureCapsMap &textureCaps) 669 { 670 constexpr GLenum requiredFormats[] = { 671 GL_DEPTH_COMPONENT16, 672 #if !defined(ANGLE_PLATFORM_IOS) && \ 673 (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64)) 674 // anglebug.com/6082 675 // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES 676 // because it is not supported on iOS. 677 // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac. 678 GL_DEPTH_COMPONENT32_OES, 679 #endif 680 }; 681 682 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false); 683 } 684 685 // Check for GL_OES_depth24 686 static bool DetermineDepth24OESSupport(const TextureCapsMap &textureCaps) 687 { 688 constexpr GLenum requiredFormats[] = { 689 GL_DEPTH_COMPONENT24_OES, 690 }; 691 692 return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false); 693 } 694 695 // Check for GL_OES_depth32 support 696 static bool DetermineDepth32Support(const TextureCapsMap &textureCaps) 697 { 698 constexpr GLenum requiredFormats[] = { 699 GL_DEPTH_COMPONENT32_OES, 700 }; 701 702 return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false); 703 } 704 705 // Check for GL_CHROMIUM_color_buffer_float_rgb support 706 static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps) 707 { 708 constexpr GLenum requiredFormats[] = { 709 GL_RGB32F, 710 }; 711 712 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false); 713 } 714 715 // Check for GL_CHROMIUM_color_buffer_float_rgba support 716 static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps) 717 { 718 constexpr GLenum requiredFormats[] = { 719 GL_RGBA32F, 720 }; 721 722 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false); 723 } 724 725 // Check for GL_EXT_color_buffer_float support 726 static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps) 727 { 728 constexpr GLenum nonBlendableFormats[] = { 729 GL_R32F, 730 GL_RG32F, 731 GL_RGBA32F, 732 }; 733 734 constexpr GLenum blendableFormats[] = { 735 GL_R16F, 736 GL_RG16F, 737 GL_RGBA16F, 738 GL_R11F_G11F_B10F, 739 }; 740 741 return GetFormatSupport(textureCaps, nonBlendableFormats, true, false, true, true, false) && 742 GetFormatSupport(textureCaps, blendableFormats, true, false, true, true, true); 743 } 744 745 // Check for GL_EXT_float_blend support 746 static bool DetermineFloatBlendSupport(const TextureCapsMap &textureCaps) 747 { 748 constexpr GLenum requiredFormats[] = { 749 GL_R32F, 750 GL_RG32F, 751 GL_RGBA32F, 752 }; 753 754 return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, true); 755 } 756 757 // Check for GL_EXT_texture_norm16 support 758 static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps) 759 { 760 constexpr GLenum requiredFilterFormats[] = { 761 GL_R16_EXT, GL_RG16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT, 762 GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT, 763 }; 764 765 constexpr GLenum requiredRenderFormats[] = { 766 GL_R16_EXT, 767 GL_RG16_EXT, 768 GL_RGBA16_EXT, 769 }; 770 771 return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) && 772 GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false); 773 } 774 775 // Check for EXT_texture_compression_rgtc support 776 static bool DetermineRGTCTextureSupport(const TextureCapsMap &textureCaps) 777 { 778 constexpr GLenum requiredFormats[] = { 779 GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, 780 GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT}; 781 782 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 783 } 784 785 // Check for EXT_texture_compression_bptc support 786 static bool DetermineBPTCTextureSupport(const TextureCapsMap &textureCaps) 787 { 788 constexpr GLenum requiredFormats[] = { 789 GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 790 GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT}; 791 792 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 793 } 794 795 // Check for GL_IMG_texture_compression_pvrtc support 796 static bool DeterminePVRTCTextureSupport(const TextureCapsMap &textureCaps) 797 { 798 constexpr GLenum requiredFormats[] = { 799 GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 800 GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}; 801 802 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 803 } 804 805 // Check for GL_EXT_pvrtc_sRGB support 806 static bool DeterminePVRTCsRGBTextureSupport(const TextureCapsMap &textureCaps) 807 { 808 constexpr GLenum requiredFormats[] = { 809 GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, 810 GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT}; 811 812 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 813 } 814 815 bool DetermineCompressedTextureETCSupport(const TextureCapsMap &textureCaps) 816 { 817 constexpr GLenum requiredFormats[] = {GL_COMPRESSED_R11_EAC, 818 GL_COMPRESSED_SIGNED_R11_EAC, 819 GL_COMPRESSED_RG11_EAC, 820 GL_COMPRESSED_SIGNED_RG11_EAC, 821 GL_COMPRESSED_RGB8_ETC2, 822 GL_COMPRESSED_SRGB8_ETC2, 823 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 824 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 825 GL_COMPRESSED_RGBA8_ETC2_EAC, 826 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}; 827 828 return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false); 829 } 830 831 // Checks for GL_OES_texture_stencil8 support 832 static bool DetermineStencilIndex8Support(const TextureCapsMap &textureCaps) 833 { 834 constexpr GLenum requiredFormats[] = { 835 GL_STENCIL_INDEX8, 836 }; 837 838 return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false); 839 } 840 841 void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps) 842 { 843 // TODO(ynovikov): rgb8Rgba8OES, colorBufferHalfFloatEXT, textureHalfFloatOES, 844 // textureHalfFloatLinearOES, textureFloatOES, textureFloatLinearOES, textureRgEXT, sRGB, 845 // colorBufferFloatRgbCHROMIUM, colorBufferFloatRgbaCHROMIUM and colorBufferFloatEXT were 846 // verified. Verify the rest. 847 packedDepthStencilOES = DeterminePackedDepthStencilSupport(textureCaps); 848 rgb8Rgba8OES = DetermineRGB8AndRGBA8TextureSupport(textureCaps); 849 readDepthNV = DetermineReadDepthSupport(textureCaps); 850 readStencilNV = DetermineReadStencilSupport(textureCaps); 851 depthBufferFloat2NV = DetermineDepthBufferFloat2Support(textureCaps); 852 textureFormatBGRA8888EXT = DetermineBGRA8TextureSupport(textureCaps); 853 readFormatBgraEXT = DetermineBGRAReadFormatSupport(textureCaps); 854 textureHalfFloatOES = DetermineHalfFloatTextureSupport(textureCaps); 855 textureHalfFloatLinearOES = 856 DetermineHalfFloatTextureFilteringSupport(textureCaps, textureHalfFloatOES); 857 textureFloatOES = DetermineFloatTextureSupport(textureCaps); 858 textureFloatLinearOES = DetermineFloatTextureFilteringSupport(textureCaps, textureFloatOES); 859 textureRgEXT = DetermineRGTextureSupport(textureCaps, textureHalfFloatOES, textureFloatOES); 860 colorBufferHalfFloatEXT = 861 textureHalfFloatOES && DetermineColorBufferHalfFloatSupport(textureCaps); 862 textureType2101010REVEXT = DetermineTextureFormat2101010Support(textureCaps); 863 textureCompressionDxt1EXT = DetermineDXT1TextureSupport(textureCaps); 864 textureCompressionDxt3ANGLE = DetermineDXT3TextureSupport(textureCaps); 865 textureCompressionDxt5ANGLE = DetermineDXT5TextureSupport(textureCaps); 866 textureCompressionS3tcSrgbEXT = DetermineS3TCsRGBTextureSupport(textureCaps); 867 textureCompressionAstcLdrKHR = DetermineASTCLDRTextureSupport(textureCaps); 868 textureCompressionAstcOES = DetermineASTCOESTExtureSupport(textureCaps); 869 compressedETC1RGB8TextureOES = DetermineETC1RGB8TextureSupport(textureCaps); 870 compressedETC2RGB8TextureOES = DetermineETC2RGB8TextureSupport(textureCaps); 871 compressedETC2SRGB8TextureOES = DetermineETC2sRGB8TextureSupport(textureCaps); 872 compressedETC2PunchthroughARGBA8TextureOES = 873 DetermineETC2PunchthroughARGB8TextureSupport(textureCaps); 874 compressedETC2PunchthroughASRGB8AlphaTextureOES = 875 DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(textureCaps); 876 compressedETC2RGBA8TextureOES = DetermineETC2RGBA8TextureSupport(textureCaps); 877 compressedETC2SRGB8Alpha8TextureOES = DetermineETC2sRGB8Alpha8TextureSupport(textureCaps); 878 compressedEACR11UnsignedTextureOES = DetermineEACR11UnsignedTextureSupport(textureCaps); 879 compressedEACR11SignedTextureOES = DetermineEACR11SignedTextureSupport(textureCaps); 880 compressedEACRG11UnsignedTextureOES = DetermineEACRG11UnsignedTextureSupport(textureCaps); 881 compressedEACRG11SignedTextureOES = DetermineEACRG11SignedTextureSupport(textureCaps); 882 sRGBEXT = DetermineSRGBTextureSupport(textureCaps); 883 textureSRGBR8EXT = DetermineSRGBR8TextureSupport(textureCaps); 884 textureSRGBRG8EXT = DetermineSRGBRG8TextureSupport(textureCaps); 885 depthTextureANGLE = DetermineDepthTextureANGLESupport(textureCaps); 886 depthTextureOES = DetermineDepthTextureOESSupport(textureCaps); 887 depth24OES = DetermineDepth24OESSupport(textureCaps); 888 depth32OES = DetermineDepth32Support(textureCaps); 889 colorBufferFloatRgbCHROMIUM = DetermineColorBufferFloatRGBSupport(textureCaps); 890 colorBufferFloatRgbaCHROMIUM = DetermineColorBufferFloatRGBASupport(textureCaps); 891 colorBufferFloatEXT = DetermineColorBufferFloatSupport(textureCaps); 892 floatBlendEXT = DetermineFloatBlendSupport(textureCaps); 893 textureNorm16EXT = DetermineTextureNorm16Support(textureCaps); 894 textureCompressionRgtcEXT = DetermineRGTCTextureSupport(textureCaps); 895 textureCompressionBptcEXT = DetermineBPTCTextureSupport(textureCaps); 896 textureCompressionPvrtcIMG = DeterminePVRTCTextureSupport(textureCaps); 897 pvrtcSRGBEXT = DeterminePVRTCsRGBTextureSupport(textureCaps); 898 textureStencil8OES = DetermineStencilIndex8Support(textureCaps); 899 } 900 901 TypePrecision::TypePrecision() = default; 902 903 TypePrecision::TypePrecision(const TypePrecision &other) = default; 904 905 TypePrecision &TypePrecision::operator=(const TypePrecision &other) = default; 906 907 void TypePrecision::setIEEEFloat() 908 { 909 range = {{127, 127}}; 910 precision = 23; 911 } 912 913 void TypePrecision::setIEEEHalfFloat() 914 { 915 range = {{15, 15}}; 916 precision = 10; 917 } 918 919 void TypePrecision::setTwosComplementInt(unsigned int bits) 920 { 921 range = {{static_cast<GLint>(bits) - 1, static_cast<GLint>(bits) - 2}}; 922 precision = 0; 923 } 924 925 void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p) 926 { 927 range = {{static_cast<GLint>(r), static_cast<GLint>(r)}}; 928 precision = static_cast<GLint>(p); 929 } 930 931 void TypePrecision::setSimulatedInt(unsigned int r) 932 { 933 range = {{static_cast<GLint>(r), static_cast<GLint>(r)}}; 934 precision = 0; 935 } 936 937 void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const 938 { 939 std::copy(range.begin(), range.end(), returnRange); 940 *returnPrecision = precision; 941 } 942 943 Caps::Caps() = default; 944 Caps::Caps(const Caps &other) = default; 945 Caps::~Caps() = default; 946 Caps &Caps::operator=(const Caps &other) = default; 947 948 Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions) 949 { 950 Caps caps; 951 952 // GLES1 emulation (Minimums taken from Table 6.20 / 6.22 (ES 1.1 spec)) 953 if (clientVersion < Version(2, 0)) 954 { 955 caps.maxMultitextureUnits = 2; 956 caps.maxLights = 8; 957 caps.maxClipPlanes = 1; 958 959 caps.maxModelviewMatrixStackDepth = 16; 960 caps.maxProjectionMatrixStackDepth = 2; 961 caps.maxTextureMatrixStackDepth = 2; 962 963 caps.minSmoothPointSize = 1.0f; 964 caps.maxSmoothPointSize = 1.0f; 965 } 966 967 if (clientVersion >= Version(2, 0)) 968 { 969 // Table 6.18 970 caps.max2DTextureSize = 64; 971 caps.maxCubeMapTextureSize = 16; 972 caps.maxViewportWidth = caps.max2DTextureSize; 973 caps.maxViewportHeight = caps.max2DTextureSize; 974 caps.minAliasedPointSize = 1; 975 caps.maxAliasedPointSize = 1; 976 caps.minAliasedLineWidth = 1; 977 caps.maxAliasedLineWidth = 1; 978 979 // Table 6.19 980 caps.vertexHighpFloat.setSimulatedFloat(62, 16); 981 caps.vertexMediumpFloat.setSimulatedFloat(14, 10); 982 caps.vertexLowpFloat.setSimulatedFloat(1, 8); 983 caps.vertexHighpInt.setSimulatedInt(16); 984 caps.vertexMediumpInt.setSimulatedInt(10); 985 caps.vertexLowpInt.setSimulatedInt(8); 986 caps.fragmentHighpFloat.setSimulatedFloat(62, 16); 987 caps.fragmentMediumpFloat.setSimulatedFloat(14, 10); 988 caps.fragmentLowpFloat.setSimulatedFloat(1, 8); 989 caps.fragmentHighpInt.setSimulatedInt(16); 990 caps.fragmentMediumpInt.setSimulatedInt(10); 991 caps.fragmentLowpInt.setSimulatedInt(8); 992 993 // Table 6.20 994 caps.maxVertexAttributes = 8; 995 caps.maxVertexUniformVectors = 128; 996 caps.maxVaryingVectors = 8; 997 caps.maxCombinedTextureImageUnits = 8; 998 caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 8; 999 caps.maxFragmentUniformVectors = 16; 1000 caps.maxRenderbufferSize = 1; 1001 1002 // Table 3.35 1003 caps.maxSamples = 4; 1004 } 1005 1006 if (clientVersion >= Version(3, 0)) 1007 { 1008 // Table 6.28 1009 caps.maxElementIndex = (1 << 24) - 1; 1010 caps.max3DTextureSize = 256; 1011 caps.max2DTextureSize = 2048; 1012 caps.maxArrayTextureLayers = 256; 1013 caps.maxLODBias = 2.0f; 1014 caps.maxCubeMapTextureSize = 2048; 1015 caps.maxRenderbufferSize = 2048; 1016 caps.maxDrawBuffers = 4; 1017 caps.maxColorAttachments = 4; 1018 caps.maxViewportWidth = caps.max2DTextureSize; 1019 caps.maxViewportHeight = caps.max2DTextureSize; 1020 1021 // Table 6.29 1022 caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC); 1023 caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC); 1024 caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC); 1025 caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC); 1026 caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2); 1027 caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2); 1028 caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2); 1029 caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2); 1030 caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC); 1031 caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); 1032 caps.vertexHighpFloat.setIEEEFloat(); 1033 caps.vertexHighpInt.setTwosComplementInt(32); 1034 caps.vertexMediumpInt.setTwosComplementInt(16); 1035 caps.vertexLowpInt.setTwosComplementInt(8); 1036 caps.fragmentHighpFloat.setIEEEFloat(); 1037 caps.fragmentHighpInt.setSimulatedInt(32); 1038 caps.fragmentMediumpInt.setTwosComplementInt(16); 1039 caps.fragmentLowpInt.setTwosComplementInt(8); 1040 caps.maxServerWaitTimeout = 0; 1041 1042 // Table 6.31 1043 caps.maxVertexAttributes = 16; 1044 caps.maxShaderUniformComponents[ShaderType::Vertex] = 1024; 1045 caps.maxVertexUniformVectors = 256; 1046 caps.maxShaderUniformBlocks[ShaderType::Vertex] = limits::kMinimumShaderUniformBlocks; 1047 caps.maxVertexOutputComponents = limits::kMinimumVertexOutputComponents; 1048 caps.maxShaderTextureImageUnits[ShaderType::Vertex] = 16; 1049 1050 // Table 6.32 1051 caps.maxShaderUniformComponents[ShaderType::Fragment] = 896; 1052 caps.maxFragmentUniformVectors = 224; 1053 caps.maxShaderUniformBlocks[ShaderType::Fragment] = limits::kMinimumShaderUniformBlocks; 1054 caps.maxFragmentInputComponents = 60; 1055 caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 16; 1056 caps.minProgramTexelOffset = -8; 1057 caps.maxProgramTexelOffset = 7; 1058 1059 // Table 6.33 1060 caps.maxUniformBufferBindings = 24; 1061 caps.maxUniformBlockSize = 16384; 1062 caps.uniformBufferOffsetAlignment = 256; 1063 caps.maxCombinedUniformBlocks = 24; 1064 caps.maxVaryingComponents = 60; 1065 caps.maxVaryingVectors = 15; 1066 caps.maxCombinedTextureImageUnits = 32; 1067 1068 // Table 6.34 1069 caps.maxTransformFeedbackInterleavedComponents = 64; 1070 caps.maxTransformFeedbackSeparateAttributes = 4; 1071 caps.maxTransformFeedbackSeparateComponents = 4; 1072 } 1073 1074 if (clientVersion >= Version(3, 1)) 1075 { 1076 // Table 20.40 1077 caps.maxFramebufferWidth = 2048; 1078 caps.maxFramebufferHeight = 2048; 1079 caps.maxFramebufferSamples = 4; 1080 caps.maxSampleMaskWords = 1; 1081 caps.maxColorTextureSamples = 1; 1082 caps.maxDepthTextureSamples = 1; 1083 caps.maxIntegerSamples = 1; 1084 1085 // Table 20.41 1086 caps.maxVertexAttribRelativeOffset = 2047; 1087 caps.maxVertexAttribBindings = 16; 1088 caps.maxVertexAttribStride = 2048; 1089 1090 // Table 20.43 1091 caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex] = 0; 1092 caps.maxShaderAtomicCounters[ShaderType::Vertex] = 0; 1093 caps.maxShaderImageUniforms[ShaderType::Vertex] = 0; 1094 caps.maxShaderStorageBlocks[ShaderType::Vertex] = 0; 1095 1096 // Table 20.44 1097 caps.maxShaderUniformComponents[ShaderType::Fragment] = 1024; 1098 caps.maxFragmentUniformVectors = 256; 1099 caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment] = 0; 1100 caps.maxShaderAtomicCounters[ShaderType::Fragment] = 0; 1101 caps.maxShaderImageUniforms[ShaderType::Fragment] = 0; 1102 caps.maxShaderStorageBlocks[ShaderType::Fragment] = 0; 1103 caps.minProgramTextureGatherOffset = 0; 1104 caps.maxProgramTextureGatherOffset = 0; 1105 1106 // Table 20.45 1107 caps.maxComputeWorkGroupCount = {{65535, 65535, 65535}}; 1108 caps.maxComputeWorkGroupSize = {{128, 128, 64}}; 1109 caps.maxComputeWorkGroupInvocations = 12; 1110 caps.maxShaderUniformBlocks[ShaderType::Compute] = limits::kMinimumShaderUniformBlocks; 1111 caps.maxShaderTextureImageUnits[ShaderType::Compute] = 16; 1112 caps.maxComputeSharedMemorySize = 16384; 1113 caps.maxShaderUniformComponents[ShaderType::Compute] = 1024; 1114 caps.maxShaderAtomicCounterBuffers[ShaderType::Compute] = 1; 1115 caps.maxShaderAtomicCounters[ShaderType::Compute] = 8; 1116 caps.maxShaderImageUniforms[ShaderType::Compute] = 4; 1117 caps.maxShaderStorageBlocks[ShaderType::Compute] = 4; 1118 1119 // Table 20.46 1120 caps.maxUniformBufferBindings = 36; 1121 caps.maxCombinedTextureImageUnits = 48; 1122 caps.maxCombinedShaderOutputResources = 4; 1123 1124 // Table 20.47 1125 caps.maxUniformLocations = 1024; 1126 caps.maxAtomicCounterBufferBindings = 1; 1127 caps.maxAtomicCounterBufferSize = 32; 1128 caps.maxCombinedAtomicCounterBuffers = 1; 1129 caps.maxCombinedAtomicCounters = 8; 1130 caps.maxImageUnits = 4; 1131 caps.maxCombinedImageUniforms = 4; 1132 caps.maxShaderStorageBufferBindings = 4; 1133 caps.maxShaderStorageBlockSize = 1 << 27; 1134 caps.maxCombinedShaderStorageBlocks = 4; 1135 caps.shaderStorageBufferOffsetAlignment = 256; 1136 } 1137 1138 if (extensions.textureRectangleANGLE) 1139 { 1140 caps.maxRectangleTextureSize = 64; 1141 } 1142 1143 if (extensions.geometryShaderAny()) 1144 { 1145 // Table 20.40 (GL_EXT_geometry_shader) 1146 caps.maxFramebufferLayers = 256; 1147 caps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT; 1148 1149 // Table 20.43gs (GL_EXT_geometry_shader) 1150 caps.maxShaderUniformComponents[ShaderType::Geometry] = 1024; 1151 caps.maxShaderUniformBlocks[ShaderType::Geometry] = limits::kMinimumShaderUniformBlocks; 1152 caps.maxGeometryInputComponents = 64; 1153 caps.maxGeometryOutputComponents = 64; 1154 caps.maxGeometryOutputVertices = 256; 1155 caps.maxGeometryTotalOutputComponents = 1024; 1156 caps.maxShaderTextureImageUnits[ShaderType::Geometry] = 16; 1157 caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry] = 0; 1158 caps.maxShaderAtomicCounters[ShaderType::Geometry] = 0; 1159 caps.maxShaderStorageBlocks[ShaderType::Geometry] = 0; 1160 caps.maxGeometryShaderInvocations = 32; 1161 1162 // Table 20.46 (GL_EXT_geometry_shader) 1163 caps.maxShaderImageUniforms[ShaderType::Geometry] = 0; 1164 1165 // Table 20.46 (GL_EXT_geometry_shader) 1166 caps.maxUniformBufferBindings = 48; 1167 caps.maxCombinedUniformBlocks = 36; 1168 caps.maxCombinedTextureImageUnits = 64; 1169 } 1170 1171 if (extensions.tessellationShaderEXT) 1172 { 1173 // Table 20.43 "Implementation Dependent Tessellation Shader Limits" 1174 caps.maxTessControlInputComponents = 64; 1175 caps.maxTessControlOutputComponents = 64; 1176 caps.maxShaderTextureImageUnits[ShaderType::TessControl] = 16; 1177 caps.maxShaderUniformComponents[ShaderType::TessControl] = 1024; 1178 caps.maxTessControlTotalOutputComponents = 2048; 1179 caps.maxShaderImageUniforms[ShaderType::TessControl] = 0; 1180 caps.maxShaderAtomicCounters[ShaderType::TessControl] = 0; 1181 caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl] = 0; 1182 1183 caps.maxTessPatchComponents = 120; 1184 caps.maxPatchVertices = 32; 1185 caps.maxTessGenLevel = 64; 1186 1187 caps.maxTessEvaluationInputComponents = 64; 1188 caps.maxTessEvaluationOutputComponents = 64; 1189 caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation] = 16; 1190 caps.maxShaderUniformComponents[ShaderType::TessEvaluation] = 1024; 1191 caps.maxShaderImageUniforms[ShaderType::TessEvaluation] = 0; 1192 caps.maxShaderAtomicCounters[ShaderType::TessEvaluation] = 0; 1193 caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation] = 0; 1194 1195 // Table 20.46 "Implementation Dependent Aggregate Shader Limits" 1196 caps.maxUniformBufferBindings = 72; 1197 caps.maxCombinedUniformBlocks = 60; 1198 caps.maxCombinedTextureImageUnits = 96; 1199 } 1200 1201 for (ShaderType shaderType : AllShaderTypes()) 1202 { 1203 caps.maxCombinedShaderUniformComponents[shaderType] = 1204 caps.maxShaderUniformBlocks[shaderType] * 1205 static_cast<GLuint>(caps.maxUniformBlockSize / 4) + 1206 caps.maxShaderUniformComponents[shaderType]; 1207 } 1208 1209 return caps; 1210 } 1211 } // namespace gl 1212 1213 namespace egl 1214 { 1215 1216 Caps::Caps() = default; 1217 1218 DisplayExtensions::DisplayExtensions() = default; 1219 1220 std::vector<std::string> DisplayExtensions::getStrings() const 1221 { 1222 std::vector<std::string> extensionStrings; 1223 1224 // clang-format off 1225 // | Extension name | Supported flag | Output vector | 1226 InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings); 1227 InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings); 1228 InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer", d3dTextureClientBuffer, &extensionStrings); 1229 InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings); 1230 InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); 1231 InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); 1232 InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings); 1233 InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings); 1234 InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings); 1235 InsertExtensionString("EGL_ANGLE_windows_ui_composition", windowsUIComposition, &extensionStrings); 1236 InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings); 1237 InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); 1238 InsertExtensionString("EGL_KHR_image", image, &extensionStrings); 1239 InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings); 1240 InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings); 1241 InsertExtensionString("EGL_EXT_image_gl_colorspace", imageGlColorspace, &extensionStrings); 1242 InsertExtensionString("EGL_KHR_gl_colorspace", glColorspace, &extensionStrings); 1243 InsertExtensionString("EGL_EXT_gl_colorspace_scrgb", glColorspaceScrgb, &extensionStrings); 1244 InsertExtensionString("EGL_EXT_gl_colorspace_scrgb_linear", glColorspaceScrgbLinear, &extensionStrings); 1245 InsertExtensionString("EGL_EXT_gl_colorspace_display_p3", glColorspaceDisplayP3, &extensionStrings); 1246 InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_linear", glColorspaceDisplayP3Linear, &extensionStrings); 1247 InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_passthrough", glColorspaceDisplayP3Passthrough, &extensionStrings); 1248 InsertExtensionString("EGL_ANGLE_colorspace_attribute_passthrough", eglColorspaceAttributePassthroughANGLE, &extensionStrings); 1249 InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings); 1250 InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings); 1251 InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings); 1252 InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings); 1253 InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings); 1254 InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings); 1255 InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings); 1256 InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings); 1257 InsertExtensionString("EGL_KHR_fence_sync", fenceSync, &extensionStrings); 1258 InsertExtensionString("EGL_KHR_wait_sync", waitSync, &extensionStrings); 1259 InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings); 1260 InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings); 1261 InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings); 1262 InsertExtensionString("EGL_CHROMIUM_sync_control", syncControlCHROMIUM, &extensionStrings); 1263 InsertExtensionString("EGL_ANGLE_sync_control_rate", syncControlRateANGLE, &extensionStrings); 1264 InsertExtensionString("EGL_KHR_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings); 1265 InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings); 1266 InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings); 1267 InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings); 1268 InsertExtensionString("EGL_ANGLE_display_semaphore_share_group", displaySemaphoreShareGroup, &extensionStrings); 1269 InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &extensionStrings); 1270 InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControlANGLE, &extensionStrings); 1271 InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitializationANGLE, &extensionStrings); 1272 InsertExtensionString("EGL_ANGLE_iosurface_client_buffer", iosurfaceClientBuffer, &extensionStrings); 1273 InsertExtensionString("EGL_ANGLE_metal_texture_client_buffer", mtlTextureClientBuffer, &extensionStrings); 1274 InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled", createContextExtensionsEnabled, &extensionStrings); 1275 InsertExtensionString("EGL_ANDROID_presentation_time", presentationTime, &extensionStrings); 1276 InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings); 1277 InsertExtensionString("EGL_ANDROID_framebuffer_target", framebufferTargetANDROID, &extensionStrings); 1278 InsertExtensionString("EGL_ANDROID_image_native_buffer", imageNativeBuffer, &extensionStrings); 1279 InsertExtensionString("EGL_ANDROID_get_frame_timestamps", getFrameTimestamps, &extensionStrings); 1280 InsertExtensionString("EGL_ANGLE_timestamp_surface_attribute", timestampSurfaceAttributeANGLE, &extensionStrings); 1281 InsertExtensionString("EGL_ANDROID_recordable", recordable, &extensionStrings); 1282 InsertExtensionString("EGL_ANGLE_power_preference", powerPreference, &extensionStrings); 1283 InsertExtensionString("EGL_ANGLE_image_d3d11_texture", imageD3D11Texture, &extensionStrings); 1284 InsertExtensionString("EGL_ANDROID_create_native_client_buffer", createNativeClientBufferANDROID, &extensionStrings); 1285 InsertExtensionString("EGL_ANDROID_get_native_client_buffer", getNativeClientBufferANDROID, &extensionStrings); 1286 InsertExtensionString("EGL_ANDROID_native_fence_sync", nativeFenceSyncANDROID, &extensionStrings); 1287 InsertExtensionString("EGL_ANGLE_create_context_backwards_compatible", createContextBackwardsCompatible, &extensionStrings); 1288 InsertExtensionString("EGL_KHR_no_config_context", noConfigContext, &extensionStrings); 1289 InsertExtensionString("EGL_IMG_context_priority", contextPriority, &extensionStrings); 1290 InsertExtensionString("EGL_KHR_create_context_no_error", createContextNoError, &extensionStrings); 1291 InsertExtensionString("EGL_EXT_image_dma_buf_import", imageDmaBufImportEXT, &extensionStrings); 1292 InsertExtensionString("EGL_EXT_image_dma_buf_import_modifiers", imageDmaBufImportModifiersEXT, &extensionStrings); 1293 InsertExtensionString("EGL_NOK_texture_from_pixmap", textureFromPixmapNOK, &extensionStrings); 1294 InsertExtensionString("EGL_NV_robustness_video_memory_purge", robustnessVideoMemoryPurgeNV, &extensionStrings); 1295 InsertExtensionString("EGL_KHR_reusable_sync", reusableSyncKHR, &extensionStrings); 1296 InsertExtensionString("EGL_ANGLE_external_context_and_surface", externalContextAndSurface, &extensionStrings); 1297 InsertExtensionString("EGL_EXT_buffer_age", bufferAgeEXT, &extensionStrings); 1298 InsertExtensionString("EGL_KHR_mutable_render_buffer", mutableRenderBufferKHR, &extensionStrings); 1299 InsertExtensionString("EGL_EXT_protected_content", protectedContentEXT, &extensionStrings); 1300 InsertExtensionString("EGL_ANGLE_create_surface_swap_interval", createSurfaceSwapIntervalANGLE, &extensionStrings); 1301 InsertExtensionString("EGL_ANGLE_context_virtualization", contextVirtualizationANGLE, &extensionStrings); 1302 InsertExtensionString("EGL_KHR_lock_surface3", lockSurface3KHR, &extensionStrings); 1303 InsertExtensionString("EGL_ANGLE_vulkan_image", vulkanImageANGLE, &extensionStrings); 1304 InsertExtensionString("EGL_ANGLE_metal_create_context_ownership_identity", metalCreateContextOwnershipIdentityANGLE, &extensionStrings); 1305 InsertExtensionString("EGL_KHR_partial_update", partialUpdateKHR, &extensionStrings); 1306 InsertExtensionString("EGL_ANGLE_metal_shared_event_sync", mtlSyncSharedEventANGLE, &extensionStrings); 1307 // clang-format on 1308 1309 return extensionStrings; 1310 } 1311 1312 DeviceExtensions::DeviceExtensions() = default; 1313 1314 std::vector<std::string> DeviceExtensions::getStrings() const 1315 { 1316 std::vector<std::string> extensionStrings; 1317 1318 // clang-format off 1319 // | Extension name | Supported flag | Output vector | 1320 InsertExtensionString("EGL_ANGLE_device_d3d", deviceD3D, &extensionStrings); 1321 InsertExtensionString("EGL_ANGLE_device_cgl", deviceCGL, &extensionStrings); 1322 InsertExtensionString("EGL_ANGLE_device_eagl", deviceEAGL, &extensionStrings); 1323 InsertExtensionString("EGL_ANGLE_device_metal", deviceMetal, &extensionStrings); 1324 InsertExtensionString("EGL_ANGLE_device_vulkan", deviceVulkan, &extensionStrings); 1325 1326 // clang-format on 1327 1328 return extensionStrings; 1329 } 1330 1331 ClientExtensions::ClientExtensions() = default; 1332 ClientExtensions::ClientExtensions(const ClientExtensions &other) = default; 1333 1334 std::vector<std::string> ClientExtensions::getStrings() const 1335 { 1336 std::vector<std::string> extensionStrings; 1337 1338 // clang-format off 1339 // | Extension name | Supported flag | Output vector | 1340 InsertExtensionString("EGL_EXT_client_extensions", clientExtensions, &extensionStrings); 1341 InsertExtensionString("EGL_EXT_device_query", deviceQueryEXT, &extensionStrings); 1342 InsertExtensionString("EGL_EXT_platform_base", platformBase, &extensionStrings); 1343 InsertExtensionString("EGL_EXT_platform_device", platformDevice, &extensionStrings); 1344 InsertExtensionString("EGL_KHR_platform_gbm", platformGbmKHR, &extensionStrings); 1345 InsertExtensionString("EGL_EXT_platform_wayland", platformWaylandEXT, &extensionStrings); 1346 InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings); 1347 InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings); 1348 InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12", platformANGLED3D11ON12, &extensionStrings); 1349 InsertExtensionString("EGL_ANGLE_platform_angle_device_type_egl_angle", platformANGLEDeviceTypeEGLANGLE, &extensionStrings); 1350 InsertExtensionString("EGL_ANGLE_platform_angle_device_type_swiftshader", platformANGLEDeviceTypeSwiftShader, &extensionStrings); 1351 InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings); 1352 InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings); 1353 InsertExtensionString("EGL_ANGLE_platform_angle_vulkan", platformANGLEVulkan, &extensionStrings); 1354 InsertExtensionString("EGL_ANGLE_platform_angle_metal", platformANGLEMetal, &extensionStrings); 1355 InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_eagl", platformANGLEDeviceContextVolatileEagl, &extensionStrings); 1356 InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_cgl", platformANGLEDeviceContextVolatileCgl, &extensionStrings); 1357 InsertExtensionString("EGL_ANGLE_platform_angle_device_id", platformANGLEDeviceId, &extensionStrings); 1358 InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings); 1359 InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings); 1360 InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings); 1361 InsertExtensionString("EGL_ANGLE_experimental_present_path", experimentalPresentPath, &extensionStrings); 1362 InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings); 1363 InsertExtensionString("EGL_KHR_debug", debug, &extensionStrings); 1364 InsertExtensionString("EGL_ANGLE_feature_control", featureControlANGLE, &extensionStrings); 1365 InsertExtensionString("EGL_ANGLE_display_power_preference", displayPowerPreferenceANGLE, &extensionStrings); 1366 // clang-format on 1367 1368 return extensionStrings; 1369 } 1370 1371 } // namespace egl