1 //
2 // Copyright 2012 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 // renderergl_utils.cpp: Conversion functions and other utility routines
8 // specific to the OpenGL renderer.
9
10 #include "libANGLE/renderer/gl/renderergl_utils.h"
11
12 #include <array>
13 #include <limits>
14
15 #include "common/android_util.h"
16 #include "common/mathutil.h"
17 #include "common/platform.h"
18 #include "common/string_utils.h"
19 #include "gpu_info_util/SystemInfo.h"
20 #include "libANGLE/Buffer.h"
21 #include "libANGLE/Caps.h"
22 #include "libANGLE/Context.h"
23 #include "libANGLE/formatutils.h"
24 #include "libANGLE/queryconversions.h"
25 #include "libANGLE/renderer/driver_utils.h"
26 #include "libANGLE/renderer/gl/ContextGL.h"
27 #include "libANGLE/renderer/gl/FenceNVGL.h"
28 #include "libANGLE/renderer/gl/FunctionsGL.h"
29 #include "libANGLE/renderer/gl/QueryGL.h"
30 #include "libANGLE/renderer/gl/formatutilsgl.h"
31 #include "platform/autogen/FeaturesGL_autogen.h"
32 #include "platform/autogen/FrontendFeatures_autogen.h"
33
34 #include <EGL/eglext.h>
35 #include <algorithm>
36 #include <sstream>
37
38 using angle::CheckedNumeric;
39
40 namespace rx
41 {
42
43 namespace
44 {
45
GetString(const FunctionsGL * functions,GLenum name)46 const char *GetString(const FunctionsGL *functions, GLenum name)
47 {
48 const char *cStr = reinterpret_cast<const char *>(functions->getString(name));
49 if (cStr == nullptr)
50 {
51 return "";
52 }
53 return cStr;
54 }
55
IsMesa(const FunctionsGL * functions,std::array<int,3> * version)56 bool IsMesa(const FunctionsGL *functions, std::array<int, 3> *version)
57 {
58 ASSERT(version);
59
60 std::string nativeVersionString(GetString(functions, GL_VERSION));
61 size_t pos = nativeVersionString.find("Mesa");
62 if (pos == std::string::npos)
63 {
64 return false;
65 }
66
67 int *data = version->data();
68 data[0] = data[1] = data[2] = 0;
69 std::sscanf(nativeVersionString.c_str() + pos, "Mesa %d.%d.%d", data, data + 1, data + 2);
70
71 return true;
72 }
73
getAdrenoNumber(const FunctionsGL * functions)74 int getAdrenoNumber(const FunctionsGL *functions)
75 {
76 static int number = -1;
77 if (number == -1)
78 {
79 const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
80 if (std::sscanf(nativeGLRenderer, "Adreno (TM) %d", &number) < 1 &&
81 std::sscanf(nativeGLRenderer, "FD%d", &number) < 1)
82 {
83 number = 0;
84 }
85 }
86 return number;
87 }
88
GetQualcommVersion(const FunctionsGL * functions)89 int GetQualcommVersion(const FunctionsGL *functions)
90 {
91 static int version = -1;
92 if (version == -1)
93 {
94 const std::string nativeVersionString(GetString(functions, GL_VERSION));
95 const size_t pos = nativeVersionString.find("V@");
96 if (pos == std::string::npos ||
97 std::sscanf(nativeVersionString.c_str() + pos, "V@%d", &version) < 1)
98 {
99 version = 0;
100 }
101 }
102 return version;
103 }
104
getMaliTNumber(const FunctionsGL * functions)105 int getMaliTNumber(const FunctionsGL *functions)
106 {
107 static int number = -1;
108 if (number == -1)
109 {
110 const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
111 if (std::sscanf(nativeGLRenderer, "Mali-T%d", &number) < 1)
112 {
113 number = 0;
114 }
115 }
116 return number;
117 }
118
getMaliGNumber(const FunctionsGL * functions)119 int getMaliGNumber(const FunctionsGL *functions)
120 {
121 static int number = -1;
122 if (number == -1)
123 {
124 const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
125 if (std::sscanf(nativeGLRenderer, "Mali-G%d", &number) < 1)
126 {
127 number = 0;
128 }
129 }
130 return number;
131 }
132
IsAdreno3xx(const FunctionsGL * functions)133 bool IsAdreno3xx(const FunctionsGL *functions)
134 {
135 int number = getAdrenoNumber(functions);
136 return number != 0 && number >= 300 && number < 400;
137 }
138
IsAdreno42xOr3xx(const FunctionsGL * functions)139 bool IsAdreno42xOr3xx(const FunctionsGL *functions)
140 {
141 int number = getAdrenoNumber(functions);
142 return number != 0 && getAdrenoNumber(functions) < 430;
143 }
144
IsAdreno4xx(const FunctionsGL * functions)145 bool IsAdreno4xx(const FunctionsGL *functions)
146 {
147 int number = getAdrenoNumber(functions);
148 return number != 0 && number >= 400 && number < 500;
149 }
150
IsAdreno5xxOrOlder(const FunctionsGL * functions)151 bool IsAdreno5xxOrOlder(const FunctionsGL *functions)
152 {
153 int number = getAdrenoNumber(functions);
154 return number != 0 && number < 600;
155 }
156
IsAdreno5xx(const FunctionsGL * functions)157 bool IsAdreno5xx(const FunctionsGL *functions)
158 {
159 int number = getAdrenoNumber(functions);
160 return number != 0 && number >= 500 && number < 600;
161 }
162
IsMaliT8xxOrOlder(const FunctionsGL * functions)163 bool IsMaliT8xxOrOlder(const FunctionsGL *functions)
164 {
165 int number = getMaliTNumber(functions);
166 return number != 0 && number < 900;
167 }
168
IsMaliG31OrOlder(const FunctionsGL * functions)169 bool IsMaliG31OrOlder(const FunctionsGL *functions)
170 {
171 int number = getMaliGNumber(functions);
172 return number != 0 && number <= 31;
173 }
174
IsMaliG72OrG76OrG51(const FunctionsGL * functions)175 bool IsMaliG72OrG76OrG51(const FunctionsGL *functions)
176 {
177 int number = getMaliGNumber(functions);
178 return number == 72 || number == 76 || number == 51;
179 }
180
IsMaliValhall(const FunctionsGL * functions)181 bool IsMaliValhall(const FunctionsGL *functions)
182 {
183 int number = getMaliGNumber(functions);
184 return number == 57 || number == 77 || number == 68 || number == 78 || number == 310 ||
185 number == 510 || number == 610 || number == 710 || number == 615 || number == 715;
186 }
187
IsPixel7OrPixel8(const FunctionsGL * functions)188 bool IsPixel7OrPixel8(const FunctionsGL *functions)
189 {
190 int number = getMaliGNumber(functions);
191 return number == 710 || number == 715;
192 }
193
IsAndroidEmulator(const FunctionsGL * functions)194 [[maybe_unused]] bool IsAndroidEmulator(const FunctionsGL *functions)
195 {
196 constexpr char androidEmulator[] = "Android Emulator";
197 const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
198 return angle::BeginsWith(nativeGLRenderer, androidEmulator);
199 }
200
IsPowerVrRogue(const FunctionsGL * functions)201 bool IsPowerVrRogue(const FunctionsGL *functions)
202 {
203 constexpr char powerVRRogue[] = "PowerVR Rogue";
204 const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
205 return angle::BeginsWith(nativeGLRenderer, powerVRRogue);
206 }
207
208 } // namespace
209
SwapControlData()210 SwapControlData::SwapControlData()
211 : targetSwapInterval(0), maxSwapInterval(-1), currentSwapInterval(-1)
212 {}
213
GetVendorID(const FunctionsGL * functions)214 VendorID GetVendorID(const FunctionsGL *functions)
215 {
216 std::string nativeVendorString(GetString(functions, GL_VENDOR));
217 // Concatenate GL_RENDERER to the string being checked because some vendors put their names in
218 // GL_RENDERER
219 nativeVendorString += " ";
220 nativeVendorString += GetString(functions, GL_RENDERER);
221
222 if (nativeVendorString.find("NVIDIA") != std::string::npos)
223 {
224 return VENDOR_ID_NVIDIA;
225 }
226 else if (nativeVendorString.find("ATI") != std::string::npos ||
227 nativeVendorString.find("AMD") != std::string::npos ||
228 nativeVendorString.find("Radeon") != std::string::npos)
229 {
230 return VENDOR_ID_AMD;
231 }
232 else if (nativeVendorString.find("Qualcomm") != std::string::npos)
233 {
234 return VENDOR_ID_QUALCOMM;
235 }
236 else if (nativeVendorString.find("Intel") != std::string::npos)
237 {
238 return VENDOR_ID_INTEL;
239 }
240 else if (nativeVendorString.find("Imagination") != std::string::npos)
241 {
242 return VENDOR_ID_POWERVR;
243 }
244 else if (nativeVendorString.find("Vivante") != std::string::npos)
245 {
246 return VENDOR_ID_VIVANTE;
247 }
248 else if (nativeVendorString.find("Mali") != std::string::npos)
249 {
250 return VENDOR_ID_ARM;
251 }
252 else
253 {
254 return VENDOR_ID_UNKNOWN;
255 }
256 }
257
GetDeviceID(const FunctionsGL * functions)258 uint32_t GetDeviceID(const FunctionsGL *functions)
259 {
260 std::string nativeRendererString(GetString(functions, GL_RENDERER));
261 constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
262 {"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
263 {"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
264 {"Adreno (TM) 540", ANDROID_DEVICE_ID_PIXEL2},
265 };
266
267 for (const auto &knownDeviceID : kKnownDeviceIDs)
268 {
269 if (nativeRendererString.find(knownDeviceID.first) != std::string::npos)
270 {
271 return knownDeviceID.second;
272 }
273 }
274
275 return 0;
276 }
277
GetShaderOutputType(const FunctionsGL * functions)278 ShShaderOutput GetShaderOutputType(const FunctionsGL *functions)
279 {
280 ASSERT(functions);
281
282 if (functions->standard == STANDARD_GL_DESKTOP)
283 {
284 // GLSL outputs
285 if (functions->isAtLeastGL(gl::Version(4, 5)))
286 {
287 return SH_GLSL_450_CORE_OUTPUT;
288 }
289 else if (functions->isAtLeastGL(gl::Version(4, 4)))
290 {
291 return SH_GLSL_440_CORE_OUTPUT;
292 }
293 else if (functions->isAtLeastGL(gl::Version(4, 3)))
294 {
295 return SH_GLSL_430_CORE_OUTPUT;
296 }
297 else if (functions->isAtLeastGL(gl::Version(4, 2)))
298 {
299 return SH_GLSL_420_CORE_OUTPUT;
300 }
301 else if (functions->isAtLeastGL(gl::Version(4, 1)))
302 {
303 return SH_GLSL_410_CORE_OUTPUT;
304 }
305 else if (functions->isAtLeastGL(gl::Version(4, 0)))
306 {
307 return SH_GLSL_400_CORE_OUTPUT;
308 }
309 else if (functions->isAtLeastGL(gl::Version(3, 3)))
310 {
311 return SH_GLSL_330_CORE_OUTPUT;
312 }
313 else if (functions->isAtLeastGL(gl::Version(3, 2)))
314 {
315 return SH_GLSL_150_CORE_OUTPUT;
316 }
317 else if (functions->isAtLeastGL(gl::Version(3, 1)))
318 {
319 return SH_GLSL_140_OUTPUT;
320 }
321 else if (functions->isAtLeastGL(gl::Version(3, 0)))
322 {
323 return SH_GLSL_130_OUTPUT;
324 }
325 else
326 {
327 return SH_GLSL_COMPATIBILITY_OUTPUT;
328 }
329 }
330 else if (functions->standard == STANDARD_GL_ES)
331 {
332 // ESSL outputs
333 return SH_ESSL_OUTPUT;
334 }
335 else
336 {
337 UNREACHABLE();
338 return ShShaderOutput(0);
339 }
340 }
341
342 namespace nativegl_gl
343 {
344
MeetsRequirements(const FunctionsGL * functions,const nativegl::SupportRequirement & requirements)345 static bool MeetsRequirements(const FunctionsGL *functions,
346 const nativegl::SupportRequirement &requirements)
347 {
348 bool hasRequiredExtensions = false;
349 for (const std::vector<std::string> &exts : requirements.requiredExtensions)
350 {
351 bool hasAllExtensionsInSet = true;
352 for (const std::string &extension : exts)
353 {
354 if (!functions->hasExtension(extension))
355 {
356 hasAllExtensionsInSet = false;
357 break;
358 }
359 }
360 if (hasAllExtensionsInSet)
361 {
362 hasRequiredExtensions = true;
363 break;
364 }
365 }
366 if (!requirements.requiredExtensions.empty() && !hasRequiredExtensions)
367 {
368 return false;
369 }
370
371 if (functions->version >= requirements.version)
372 {
373 return true;
374 }
375 else if (!requirements.versionExtensions.empty())
376 {
377 for (const std::string &extension : requirements.versionExtensions)
378 {
379 if (!functions->hasExtension(extension))
380 {
381 return false;
382 }
383 }
384 return true;
385 }
386 else
387 {
388 return false;
389 }
390 }
391
CheckSizedInternalFormatTextureRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)392 static bool CheckSizedInternalFormatTextureRenderability(const FunctionsGL *functions,
393 const angle::FeaturesGL &features,
394 GLenum internalFormat)
395 {
396 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
397 ASSERT(formatInfo.sized);
398
399 // Query the current texture so it can be rebound afterwards
400 GLint oldTextureBinding = 0;
401 functions->getIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding);
402
403 // Create a small texture with the same format and type that gl::Texture would use
404 GLuint texture = 0;
405 functions->genTextures(1, &texture);
406 functions->bindTexture(GL_TEXTURE_2D, texture);
407
408 // Nearest filter needed for framebuffer completeness on some drivers.
409 functions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
410
411 nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
412 functions, features, formatInfo.internalFormat, formatInfo.format, formatInfo.type);
413 constexpr GLsizei kTextureSize = 16;
414 functions->texImage2D(GL_TEXTURE_2D, 0, texImageFormat.internalFormat, kTextureSize,
415 kTextureSize, 0, texImageFormat.format, texImageFormat.type, nullptr);
416
417 // Query the current framebuffer so it can be rebound afterwards
418 GLint oldFramebufferBinding = 0;
419 functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
420
421 // Bind the texture to the framebuffer and check renderability
422 GLuint fbo = 0;
423 functions->genFramebuffers(1, &fbo);
424 functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
425 functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
426 0);
427
428 bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
429
430 // Delete the framebuffer and restore the previous binding
431 functions->deleteFramebuffers(1, &fbo);
432 functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
433
434 // Delete the texture and restore the previous binding
435 functions->deleteTextures(1, &texture);
436 functions->bindTexture(GL_TEXTURE_2D, static_cast<GLuint>(oldTextureBinding));
437
438 if (!supported)
439 {
440 ANGLE_GL_CLEAR_ERRORS(functions);
441 }
442
443 ASSERT(functions->getError() == GL_NO_ERROR);
444 return supported;
445 }
446
CheckInternalFormatRenderbufferRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)447 static bool CheckInternalFormatRenderbufferRenderability(const FunctionsGL *functions,
448 const angle::FeaturesGL &features,
449 GLenum internalFormat)
450 {
451 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
452 ASSERT(formatInfo.sized);
453
454 // Query the current renderbuffer so it can be rebound afterwards
455 GLint oldRenderbufferBinding = 0;
456 functions->getIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderbufferBinding);
457
458 // Create a small renderbuffer with the same format and type that gl::Renderbuffer would use
459 GLuint renderbuffer = 0;
460 functions->genRenderbuffers(1, &renderbuffer);
461 functions->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
462
463 nativegl::RenderbufferFormat renderbufferFormat =
464 nativegl::GetRenderbufferFormat(functions, features, formatInfo.internalFormat);
465 constexpr GLsizei kRenderbufferSize = 16;
466 functions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
467 kRenderbufferSize, kRenderbufferSize);
468
469 // Query the current framebuffer so it can be rebound afterwards
470 GLint oldFramebufferBinding = 0;
471 functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
472
473 // Bind the texture to the framebuffer and check renderability
474 GLuint fbo = 0;
475 functions->genFramebuffers(1, &fbo);
476 functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
477 functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
478 renderbuffer);
479
480 bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
481
482 // Delete the framebuffer and restore the previous binding
483 functions->deleteFramebuffers(1, &fbo);
484 functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
485
486 // Delete the renderbuffer and restore the previous binding
487 functions->deleteRenderbuffers(1, &renderbuffer);
488 functions->bindRenderbuffer(GL_RENDERBUFFER, static_cast<GLuint>(oldRenderbufferBinding));
489
490 if (!supported)
491 {
492 ANGLE_GL_CLEAR_ERRORS(functions);
493 }
494
495 ASSERT(functions->getError() == GL_NO_ERROR);
496 return supported;
497 }
498
LimitVersion(gl::Version * curVersion,const gl::Version & maxVersion)499 static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
500 {
501 if (*curVersion >= maxVersion)
502 {
503 *curVersion = maxVersion;
504 }
505 }
506
GenerateTextureFormatCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat,gl::Version * maxSupportedESVersion)507 static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
508 const angle::FeaturesGL &features,
509 GLenum internalFormat,
510 gl::Version *maxSupportedESVersion)
511 {
512 ASSERT(functions->getError() == GL_NO_ERROR);
513
514 gl::TextureCaps textureCaps;
515
516 const nativegl::InternalFormat &formatInfo =
517 nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
518 textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture);
519 textureCaps.filterable =
520 textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter);
521 textureCaps.textureAttachment = MeetsRequirements(functions, formatInfo.textureAttachment);
522 textureCaps.renderbuffer = MeetsRequirements(functions, formatInfo.renderbuffer);
523 textureCaps.blendable = textureCaps.renderbuffer || textureCaps.textureAttachment;
524
525 // Do extra renderability validation for some formats.
526 if (internalFormat == GL_R16F || internalFormat == GL_RG16F || internalFormat == GL_RGB16F)
527 {
528 // SupportRequirement can't currently express a condition of the form (version && extension)
529 // || other extensions, so do the (version && extension) part here.
530 if (functions->isAtLeastGLES(gl::Version(3, 0)) &&
531 functions->hasGLESExtension("GL_EXT_color_buffer_half_float"))
532 {
533 textureCaps.textureAttachment = true;
534 textureCaps.renderbuffer = true;
535 }
536 }
537
538 // We require GL_RGBA16F is renderable to expose EXT_color_buffer_half_float but we can't know
539 // if the format is supported unless we try to create a framebuffer.
540 // Renderability of signed normalized formats is optional on desktop GL.
541 if (internalFormat == GL_RGBA16F ||
542 (functions->standard == STANDARD_GL_DESKTOP &&
543 (internalFormat == GL_R8_SNORM || internalFormat == GL_R16_SNORM ||
544 internalFormat == GL_RG8_SNORM || internalFormat == GL_RG16_SNORM ||
545 internalFormat == GL_RGBA8_SNORM || internalFormat == GL_RGBA16_SNORM)))
546 {
547 if (textureCaps.textureAttachment)
548 {
549 textureCaps.textureAttachment =
550 CheckSizedInternalFormatTextureRenderability(functions, features, internalFormat);
551 }
552 if (textureCaps.renderbuffer)
553 {
554 textureCaps.renderbuffer =
555 CheckInternalFormatRenderbufferRenderability(functions, features, internalFormat);
556 }
557 }
558
559 // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
560 // extension GL_ARB_internalformat_query
561 if (textureCaps.renderbuffer && functions->getInternalformativ)
562 {
563 GLenum queryInternalFormat = internalFormat;
564
565 if (internalFormat == GL_BGRA8_EXT || internalFormat == GL_BGRA_EXT)
566 {
567 // Querying GL_NUM_SAMPLE_COUNTS for GL_BGRA8_EXT generates an INVALID_ENUM on some
568 // drivers. It seems however that allocating a multisampled renderbuffer of this format
569 // succeeds. To avoid breaking multisampling for this format, query the supported sample
570 // counts for GL_RGBA8 instead.
571 queryInternalFormat = GL_RGBA8;
572 }
573
574 ANGLE_GL_CLEAR_ERRORS(functions);
575 GLint numSamples = 0;
576 functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_NUM_SAMPLE_COUNTS,
577 1, &numSamples);
578 GLenum error = functions->getError();
579 if (error != GL_NO_ERROR)
580 {
581 ERR() << "glGetInternalformativ generated error " << gl::FmtHex(error) << " for format "
582 << gl::FmtHex(queryInternalFormat) << ". Skipping multisample checks.";
583 numSamples = 0;
584 }
585
586 if (numSamples > 0)
587 {
588 std::vector<GLint> samples(numSamples);
589 functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_SAMPLES,
590 static_cast<GLsizei>(samples.size()), &samples[0]);
591
592 for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
593 {
594 if (features.limitMaxMSAASamplesTo4.enabled && samples[sampleIndex] > 4)
595 {
596 continue;
597 }
598
599 // Some NVIDIA drivers expose multisampling modes implemented as a combination of
600 // multisampling and supersampling. These are non-conformant and should not be
601 // exposed through ANGLE. Query which formats are conformant from the driver if
602 // supported.
603 GLint conformant = GL_TRUE;
604 if (functions->getInternalformatSampleivNV)
605 {
606 ASSERT(functions->getError() == GL_NO_ERROR);
607 functions->getInternalformatSampleivNV(GL_RENDERBUFFER, queryInternalFormat,
608 samples[sampleIndex], GL_CONFORMANT_NV,
609 1, &conformant);
610 // getInternalFormatSampleivNV does not work for all formats on NVIDIA Shield TV
611 // drivers. Assume that formats with large sample counts are non-conformant in
612 // case the query generates an error.
613 if (functions->getError() != GL_NO_ERROR)
614 {
615 conformant = (samples[sampleIndex] <= 8) ? GL_TRUE : GL_FALSE;
616 }
617 }
618 if (conformant == GL_TRUE)
619 {
620 textureCaps.sampleCounts.insert(samples[sampleIndex]);
621 }
622 }
623 }
624 }
625
626 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers in these
627 // required formats with up to the value of MAX_SAMPLES multisamples, with the exception of
628 // signed and unsigned integer formats."
629 const gl::InternalFormat &glFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
630 if (textureCaps.renderbuffer && !glFormatInfo.isInt() &&
631 glFormatInfo.isRequiredRenderbufferFormat(gl::Version(3, 0)) &&
632 textureCaps.getMaxSamples() < 4)
633 {
634 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
635 }
636
637 ASSERT(functions->getError() == GL_NO_ERROR);
638 return textureCaps;
639 }
640
QuerySingleGLInt(const FunctionsGL * functions,GLenum name)641 static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
642 {
643 GLint result = 0;
644 functions->getIntegerv(name, &result);
645 return result;
646 }
647
QuerySingleIndexGLInt(const FunctionsGL * functions,GLenum name,GLuint index)648 static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index)
649 {
650 GLint result;
651 functions->getIntegeri_v(name, index, &result);
652 return result;
653 }
654
QueryGLIntRange(const FunctionsGL * functions,GLenum name,size_t index)655 static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
656 {
657 GLint result[2] = {};
658 functions->getIntegerv(name, result);
659 return result[index];
660 }
661
QuerySingleGLInt64(const FunctionsGL * functions,GLenum name)662 static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
663 {
664 // Fall back to 32-bit int if 64-bit query is not available. This can become relevant for some
665 // caps that are defined as 64-bit values in core spec, but were introduced earlier in
666 // extensions as 32-bit. Triggered in some cases by RenderDoc's emulated OpenGL driver.
667 if (!functions->getInteger64v)
668 {
669 GLint result = 0;
670 functions->getIntegerv(name, &result);
671 return static_cast<GLint64>(result);
672 }
673 else
674 {
675 GLint64 result = 0;
676 functions->getInteger64v(name, &result);
677 return result;
678 }
679 }
680
QuerySingleGLFloat(const FunctionsGL * functions,GLenum name)681 static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
682 {
683 GLfloat result = 0.0f;
684 functions->getFloatv(name, &result);
685 return result;
686 }
687
QueryGLFloatRange(const FunctionsGL * functions,GLenum name,size_t index)688 static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
689 {
690 GLfloat result[2] = {};
691 functions->getFloatv(name, result);
692 return result[index];
693 }
694
QueryTypePrecision(const FunctionsGL * functions,GLenum shaderType,GLenum precisionType)695 static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions,
696 GLenum shaderType,
697 GLenum precisionType)
698 {
699 gl::TypePrecision precision;
700 functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range.data(),
701 &precision.precision);
702 return precision;
703 }
704
QueryQueryValue(const FunctionsGL * functions,GLenum target,GLenum name)705 static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name)
706 {
707 GLint result;
708 functions->getQueryiv(target, name, &result);
709 return result;
710 }
711
CapCombinedLimitToESShaders(GLint * combinedLimit,gl::ShaderMap<GLint> & perShaderLimit)712 void CapCombinedLimitToESShaders(GLint *combinedLimit, gl::ShaderMap<GLint> &perShaderLimit)
713 {
714 GLint combinedESLimit = 0;
715 for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
716 {
717 combinedESLimit += perShaderLimit[shaderType];
718 }
719
720 *combinedLimit = std::min(*combinedLimit, combinedESLimit);
721 }
722
GenerateCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,gl::Caps * caps,gl::TextureCapsMap * textureCapsMap,gl::Extensions * extensions,gl::Limitations * limitations,gl::Version * maxSupportedESVersion,MultiviewImplementationTypeGL * multiviewImplementationType,ShPixelLocalStorageOptions * plsOptions)723 void GenerateCaps(const FunctionsGL *functions,
724 const angle::FeaturesGL &features,
725 gl::Caps *caps,
726 gl::TextureCapsMap *textureCapsMap,
727 gl::Extensions *extensions,
728 gl::Limitations *limitations,
729 gl::Version *maxSupportedESVersion,
730 MultiviewImplementationTypeGL *multiviewImplementationType,
731 ShPixelLocalStorageOptions *plsOptions)
732 {
733 // Start by assuming ES3.1 support and work down
734 *maxSupportedESVersion = gl::Version(3, 1);
735
736 // Texture format support checks
737 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
738 for (GLenum internalFormat : allFormats)
739 {
740 gl::TextureCaps textureCaps =
741 GenerateTextureFormatCaps(functions, features, internalFormat, maxSupportedESVersion);
742 textureCapsMap->insert(internalFormat, textureCaps);
743 }
744
745 // Table 6.28, implementation dependent values
746 if (functions->isAtLeastGL(gl::Version(4, 3)) ||
747 functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
748 functions->isAtLeastGLES(gl::Version(3, 0)))
749 {
750 caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
751
752 // Work around the null driver limitations.
753 if (caps->maxElementIndex == 0)
754 {
755 caps->maxElementIndex = 0xFFFF;
756 }
757 }
758 else
759 {
760 // Doesn't affect ES3 support, can use a pre-defined limit
761 caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
762 }
763
764 if (features.limitWebglMaxTextureSizeTo4096.enabled)
765 {
766 limitations->webGLTextureSizeLimit = 4096;
767 }
768 else if (features.limitWebglMaxTextureSizeTo8192.enabled)
769 {
770 limitations->webGLTextureSizeLimit = 8192;
771 }
772
773 GLint max3dArrayTextureSizeLimit = std::numeric_limits<GLint>::max();
774 if (features.limitMax3dArrayTextureSizeTo1024.enabled)
775 {
776 max3dArrayTextureSizeLimit = 1024;
777 }
778
779 if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
780 functions->hasGLESExtension("GL_OES_texture_3D"))
781 {
782 caps->max3DTextureSize = std::min(
783 {QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE), max3dArrayTextureSizeLimit});
784 }
785 else
786 {
787 // Can't support ES3 without 3D textures
788 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
789 }
790
791 caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE); // GL 1.0 / ES 2.0
792 caps->maxCubeMapTextureSize =
793 QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE); // GL 1.3 / ES 2.0
794
795 if (functions->isAtLeastGL(gl::Version(3, 0)) ||
796 functions->hasGLExtension("GL_EXT_texture_array") ||
797 functions->isAtLeastGLES(gl::Version(3, 0)))
798 {
799 caps->maxArrayTextureLayers = std::min(
800 {QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS), max3dArrayTextureSizeLimit});
801 }
802 else
803 {
804 // Can't support ES3 without array textures
805 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
806 }
807
808 if (functions->isAtLeastGL(gl::Version(1, 5)) ||
809 functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
810 functions->isAtLeastGLES(gl::Version(3, 0)))
811 {
812 caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
813 }
814 else
815 {
816 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
817 }
818
819 if (functions->isAtLeastGL(gl::Version(3, 0)) ||
820 functions->hasGLExtension("GL_EXT_framebuffer_object") ||
821 functions->isAtLeastGLES(gl::Version(3, 0)))
822 {
823 caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
824 caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
825 }
826 else if (functions->isAtLeastGLES(gl::Version(2, 0)))
827 {
828 caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
829 caps->maxColorAttachments = 1;
830 }
831 else
832 {
833 // Can't support ES2 without framebuffers and renderbuffers
834 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
835 }
836
837 if (functions->isAtLeastGL(gl::Version(2, 0)) ||
838 functions->hasGLExtension("ARB_draw_buffers") ||
839 functions->isAtLeastGLES(gl::Version(3, 0)) ||
840 functions->hasGLESExtension("GL_EXT_draw_buffers"))
841 {
842 caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
843 }
844 else
845 {
846 // Framebuffer is required to have at least one drawbuffer even if the extension is not
847 // supported
848 caps->maxDrawBuffers = 1;
849 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
850 }
851
852 caps->maxViewportWidth =
853 QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0); // GL 1.0 / ES 2.0
854 caps->maxViewportHeight =
855 QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1); // GL 1.0 / ES 2.0
856
857 if (functions->standard == STANDARD_GL_DESKTOP &&
858 (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
859 {
860 // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query. Use
861 // GL_POINT_SIZE_RANGE instead.
862 caps->minAliasedPointSize =
863 std::max(1.0f, QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0));
864 caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1);
865 }
866 else
867 {
868 caps->minAliasedPointSize =
869 std::max(1.0f, QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0));
870 caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
871 }
872
873 caps->minAliasedLineWidth =
874 QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0); // GL 1.2 / ES 2.0
875 caps->maxAliasedLineWidth =
876 QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1); // GL 1.2 / ES 2.0
877
878 // Table 6.29, implementation dependent values (cont.)
879 if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
880 {
881 caps->maxElementsIndices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
882 caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
883 }
884 else
885 {
886 // Doesn't impact supported version
887 }
888
889 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
890 functions->hasGLExtension("GL_ARB_get_program_binary") ||
891 functions->isAtLeastGLES(gl::Version(3, 0)) ||
892 functions->hasGLESExtension("GL_OES_get_program_binary"))
893 {
894 // Able to support the GL_PROGRAM_BINARY_ANGLE format as long as another program binary
895 // format is available.
896 GLint numBinaryFormats = QuerySingleGLInt(functions, GL_NUM_PROGRAM_BINARY_FORMATS_OES);
897 if (numBinaryFormats > 0)
898 {
899 caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
900 }
901 }
902 else
903 {
904 // Doesn't impact supported version
905 }
906
907 // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or
908 // GL_ARB_ES2_compatibility exists
909 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
910 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
911 functions->isAtLeastGLES(gl::Version(2, 0)))
912 {
913 caps->vertexHighpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
914 caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
915 caps->vertexLowpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
916 caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
917 caps->fragmentMediumpFloat =
918 QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
919 caps->fragmentLowpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
920 caps->vertexHighpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
921 caps->vertexMediumpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
922 caps->vertexLowpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
923 caps->fragmentHighpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
924 caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
925 caps->fragmentLowpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);
926 }
927 else
928 {
929 // Doesn't impact supported version, set some default values
930 caps->vertexHighpFloat.setIEEEFloat();
931 caps->vertexMediumpFloat.setIEEEFloat();
932 caps->vertexLowpFloat.setIEEEFloat();
933 caps->fragmentHighpFloat.setIEEEFloat();
934 caps->fragmentMediumpFloat.setIEEEFloat();
935 caps->fragmentLowpFloat.setIEEEFloat();
936 caps->vertexHighpInt.setTwosComplementInt(32);
937 caps->vertexMediumpInt.setTwosComplementInt(32);
938 caps->vertexLowpInt.setTwosComplementInt(32);
939 caps->fragmentHighpInt.setTwosComplementInt(32);
940 caps->fragmentMediumpInt.setTwosComplementInt(32);
941 caps->fragmentLowpInt.setTwosComplementInt(32);
942 }
943
944 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
945 functions->isAtLeastGLES(gl::Version(3, 0)))
946 {
947 // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is returned.
948 caps->maxServerWaitTimeout =
949 std::max<GLint64>(QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT), 0);
950 }
951 else
952 {
953 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
954 }
955
956 // Table 6.31, implementation dependent vertex shader limits
957 if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
958 {
959 caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
960 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
961 QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
962 caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
963 QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
964 }
965 else
966 {
967 // Can't support ES2 version without these caps
968 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
969 }
970
971 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
972 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
973 functions->isAtLeastGLES(gl::Version(2, 0)))
974 {
975 caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
976 caps->maxFragmentUniformVectors =
977 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
978 }
979 else
980 {
981 // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
982 caps->maxVertexUniformVectors =
983 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] / 4;
984 // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
985 caps->maxFragmentUniformVectors =
986 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] / 4;
987 }
988
989 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
990 {
991 caps->maxVertexOutputComponents =
992 QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
993 }
994 else
995 {
996 // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
997 // safe limit instead of limiting the supported ES version.
998 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
999 }
1000
1001 // Table 6.32, implementation dependent fragment shader limits
1002 if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
1003 {
1004 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1005 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
1006 caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
1007 QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
1008 }
1009 else
1010 {
1011 // Can't support ES2 version without these caps
1012 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
1013 }
1014
1015 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
1016 {
1017 caps->maxFragmentInputComponents =
1018 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
1019 }
1020 else
1021 {
1022 // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
1023 // safe limit instead of limiting the supported ES version.
1024 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1025 }
1026
1027 if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)))
1028 {
1029 caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
1030 caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
1031 }
1032 else
1033 {
1034 // Can't support ES3 without texel offset, could possibly be emulated in the shader
1035 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1036 }
1037
1038 // Table 6.33, implementation dependent aggregate shader limits
1039 if (functions->isAtLeastGL(gl::Version(3, 1)) ||
1040 functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
1041 functions->isAtLeastGLES(gl::Version(3, 0)))
1042 {
1043 caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
1044 QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
1045 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
1046 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
1047 caps->maxUniformBufferBindings =
1048 QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
1049 caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
1050 caps->uniformBufferOffsetAlignment =
1051 QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
1052 caps->maxCombinedUniformBlocks =
1053 QuerySingleGLInt(functions, GL_MAX_COMBINED_UNIFORM_BLOCKS);
1054 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] =
1055 QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
1056 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] =
1057 QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
1058
1059 // Clamp the maxUniformBlockSize to 64KB (majority of devices support up to this size
1060 // currently), some drivers expose an excessively large value.
1061 caps->maxUniformBlockSize = std::min<GLint64>(0x10000, caps->maxUniformBlockSize);
1062 }
1063 else
1064 {
1065 // Can't support ES3 without uniform blocks
1066 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1067 }
1068
1069 if (functions->isAtLeastGL(gl::Version(3, 2)) &&
1070 (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
1071 {
1072 caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
1073 }
1074 else if (functions->isAtLeastGL(gl::Version(3, 0)) ||
1075 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
1076 functions->isAtLeastGLES(gl::Version(2, 0)))
1077 {
1078 caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
1079 }
1080 else if (functions->isAtLeastGL(gl::Version(2, 0)))
1081 {
1082 caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS);
1083 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1084 }
1085 else
1086 {
1087 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
1088 }
1089
1090 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
1091 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
1092 functions->isAtLeastGLES(gl::Version(2, 0)))
1093 {
1094 caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
1095 }
1096 else
1097 {
1098 // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
1099 caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
1100 }
1101
1102 // Determine the max combined texture image units by adding the vertex and fragment limits. If
1103 // the real cap is queried, it would contain the limits for shader types that are not available
1104 // to ES.
1105 caps->maxCombinedTextureImageUnits =
1106 QuerySingleGLInt(functions, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
1107
1108 // Table 6.34, implementation dependent transform feedback limits
1109 if (functions->isAtLeastGL(gl::Version(4, 0)) ||
1110 functions->hasGLExtension("GL_ARB_transform_feedback2") ||
1111 functions->isAtLeastGLES(gl::Version(3, 0)))
1112 {
1113 caps->maxTransformFeedbackInterleavedComponents =
1114 QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
1115 caps->maxTransformFeedbackSeparateAttributes =
1116 QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
1117 caps->maxTransformFeedbackSeparateComponents =
1118 QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
1119 }
1120 else
1121 {
1122 // Can't support ES3 without transform feedback
1123 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1124 }
1125
1126 GLint sampleCountLimit = std::numeric_limits<GLint>::max();
1127 if (features.limitMaxMSAASamplesTo4.enabled)
1128 {
1129 sampleCountLimit = 4;
1130 }
1131
1132 // Table 6.35, Framebuffer Dependent Values
1133 if (functions->isAtLeastGL(gl::Version(3, 0)) ||
1134 functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
1135 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1136 functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
1137 {
1138 caps->maxSamples = std::min(QuerySingleGLInt(functions, GL_MAX_SAMPLES), sampleCountLimit);
1139 }
1140 else
1141 {
1142 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1143 }
1144
1145 // Non-constant sampler array indexing is required for OpenGL ES 2 and OpenGL ES after 3.2.
1146 // However having it available on OpenGL ES 2 is a specification bug, and using this
1147 // indexing in WebGL is undefined. Requiring this feature would break WebGL 1 for some users
1148 // so we don't check for it. (it is present with ESSL 100, ESSL >= 320, GLSL >= 400 and
1149 // GL_ARB_gpu_shader5)
1150
1151 // Check if sampler objects are supported
1152 if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
1153 !functions->hasGLExtension("GL_ARB_sampler_objects") &&
1154 !functions->isAtLeastGLES(gl::Version(3, 0)))
1155 {
1156 // Can't support ES3 without sampler objects
1157 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1158 }
1159
1160 // Can't support ES3 without texture swizzling
1161 if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
1162 !functions->hasGLExtension("GL_ARB_texture_swizzle") &&
1163 !functions->hasGLExtension("GL_EXT_texture_swizzle") &&
1164 !functions->isAtLeastGLES(gl::Version(3, 0)))
1165 {
1166 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1167
1168 // Texture swizzling is required to work around the luminance texture format not being
1169 // present in the core profile
1170 if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT)
1171 {
1172 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
1173 }
1174 }
1175
1176 // Can't support ES3 without the GLSL packing builtins. We have a workaround for all
1177 // desktop OpenGL versions starting from 3.3 with the bit packing extension.
1178 if (!functions->isAtLeastGL(gl::Version(4, 2)) &&
1179 !(functions->isAtLeastGL(gl::Version(3, 2)) &&
1180 functions->hasGLExtension("GL_ARB_shader_bit_encoding")) &&
1181 !functions->hasGLExtension("GL_ARB_shading_language_packing") &&
1182 !functions->isAtLeastGLES(gl::Version(3, 0)))
1183 {
1184 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1185 }
1186
1187 // ES3 needs to support explicit layout location qualifiers, while it might be possible to
1188 // fake them in our side, we currently don't support that.
1189 if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
1190 !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
1191 !functions->isAtLeastGLES(gl::Version(3, 0)))
1192 {
1193 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1194 }
1195
1196 if (!functions->isAtLeastGL(gl::Version(4, 3)) &&
1197 !functions->hasGLExtension("GL_ARB_stencil_texturing") &&
1198 !functions->isAtLeastGLES(gl::Version(3, 1)))
1199 {
1200 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1201 }
1202
1203 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1204 functions->hasGLExtension("GL_ARB_framebuffer_no_attachments"))
1205 {
1206 caps->maxFramebufferWidth = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
1207 caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
1208 caps->maxFramebufferSamples =
1209 std::min(QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES), sampleCountLimit);
1210 }
1211 else
1212 {
1213 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1214 }
1215
1216 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1217 functions->hasGLExtension("GL_ARB_texture_multisample"))
1218 {
1219 caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
1220 caps->maxColorTextureSamples =
1221 std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
1222 caps->maxDepthTextureSamples =
1223 std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
1224 caps->maxIntegerSamples =
1225 std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
1226 }
1227 else
1228 {
1229 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1230 }
1231
1232 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1233 functions->hasGLExtension("GL_ARB_vertex_attrib_binding"))
1234 {
1235 caps->maxVertexAttribRelativeOffset =
1236 QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
1237 caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS);
1238
1239 // OpenGL 4.3 has no limit on maximum value of stride.
1240 // [OpenGL 4.3 (Core Profile) - February 14, 2013] Chapter 10.3.1 Page 298
1241 if (features.emulateMaxVertexAttribStride.enabled ||
1242 (functions->standard == STANDARD_GL_DESKTOP && functions->version == gl::Version(4, 3)))
1243 {
1244 caps->maxVertexAttribStride = 2048;
1245 }
1246 else
1247 {
1248 caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
1249 }
1250 }
1251 else
1252 {
1253 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1254 // Set maxVertexAttribBindings anyway, a number of places assume this value is at least as
1255 // much as maxVertexAttributes.
1256 caps->maxVertexAttribBindings = caps->maxVertexAttributes;
1257 }
1258
1259 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1260 functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
1261 {
1262 caps->maxCombinedShaderOutputResources =
1263 QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
1264 caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] =
1265 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
1266 caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
1267 QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
1268 caps->maxShaderStorageBufferBindings =
1269 QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
1270 caps->maxShaderStorageBlockSize =
1271 QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
1272 caps->maxCombinedShaderStorageBlocks =
1273 QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
1274 caps->shaderStorageBufferOffsetAlignment =
1275 QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
1276 }
1277 else
1278 {
1279 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1280 }
1281
1282 if (nativegl::SupportsCompute(functions))
1283 {
1284 for (GLuint index = 0u; index < 3u; ++index)
1285 {
1286 caps->maxComputeWorkGroupCount[index] =
1287 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);
1288
1289 caps->maxComputeWorkGroupSize[index] =
1290 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
1291 }
1292 caps->maxComputeWorkGroupInvocations =
1293 QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
1294 caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
1295 QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS);
1296 caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
1297 QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS);
1298 caps->maxComputeSharedMemorySize =
1299 QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
1300 caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
1301 QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
1302 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
1303 QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
1304 caps->maxShaderAtomicCounters[gl::ShaderType::Compute] =
1305 QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS);
1306 caps->maxShaderImageUniforms[gl::ShaderType::Compute] =
1307 QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
1308 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Compute] =
1309 QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS);
1310 caps->maxShaderStorageBlocks[gl::ShaderType::Compute] =
1311 QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS);
1312 }
1313 else
1314 {
1315 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1316 }
1317
1318 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1319 functions->hasGLExtension("GL_ARB_explicit_uniform_location"))
1320 {
1321 caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS);
1322 }
1323 else
1324 {
1325 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1326 }
1327
1328 if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1329 functions->hasGLExtension("GL_ARB_texture_gather"))
1330 {
1331 caps->minProgramTextureGatherOffset =
1332 QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET);
1333 caps->maxProgramTextureGatherOffset =
1334 QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET);
1335 }
1336 else
1337 {
1338 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1339 }
1340
1341 if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1342 functions->hasGLExtension("GL_ARB_shader_image_load_store"))
1343 {
1344 caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
1345 QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS);
1346 caps->maxShaderImageUniforms[gl::ShaderType::Fragment] =
1347 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
1348 caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS);
1349 caps->maxCombinedImageUniforms =
1350 QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS);
1351 if (features.forceMaxCombinedShaderOutputResources.enabled)
1352 {
1353 caps->maxCombinedShaderOutputResources = caps->maxCombinedImageUniforms +
1354 caps->maxCombinedShaderStorageBlocks +
1355 caps->maxColorAttachments;
1356 }
1357 }
1358 else
1359 {
1360 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1361 }
1362
1363 if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1364 functions->hasGLExtension("GL_ARB_shader_atomic_counters"))
1365 {
1366 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
1367 QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS);
1368 caps->maxShaderAtomicCounters[gl::ShaderType::Vertex] =
1369 QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS);
1370 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
1371 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS);
1372 caps->maxShaderAtomicCounters[gl::ShaderType::Fragment] =
1373 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS);
1374 caps->maxAtomicCounterBufferBindings =
1375 QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
1376 caps->maxAtomicCounterBufferSize =
1377 QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE);
1378 caps->maxCombinedAtomicCounterBuffers =
1379 QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS);
1380 caps->maxCombinedAtomicCounters =
1381 QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS);
1382 }
1383 else
1384 {
1385 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1386 }
1387
1388 // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time
1389 // if the max uniform vectors is too large. Artificially limit the maximum until the test is
1390 // updated.
1391 caps->maxVertexUniformVectors = std::min(1024, caps->maxVertexUniformVectors);
1392 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
1393 std::min(caps->maxVertexUniformVectors * 4,
1394 caps->maxShaderUniformComponents[gl::ShaderType::Vertex]);
1395 caps->maxFragmentUniformVectors = std::min(1024, caps->maxFragmentUniformVectors);
1396 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1397 std::min(caps->maxFragmentUniformVectors * 4,
1398 caps->maxShaderUniformComponents[gl::ShaderType::Fragment]);
1399
1400 // If it is not possible to support reading buffer data back, a shadow copy of the buffers must
1401 // be held. This disallows writing to buffers indirectly through transform feedback, thus
1402 // disallowing ES3.
1403 if (!CanMapBufferForRead(functions))
1404 {
1405 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1406 }
1407
1408 // GL_OES_texture_cube_map_array
1409 if (functions->isAtLeastGL(gl::Version(4, 0)) ||
1410 functions->hasGLESExtension("GL_OES_texture_cube_map_array") ||
1411 functions->hasGLESExtension("GL_EXT_texture_cube_map_array") ||
1412 functions->hasGLExtension("GL_ARB_texture_cube_map_array") ||
1413 functions->isAtLeastGLES(gl::Version(3, 2)))
1414 {
1415 extensions->textureCubeMapArrayOES = true;
1416 extensions->textureCubeMapArrayEXT = true;
1417 }
1418 else
1419 {
1420 // Can't support ES3.2 without cube map array textures
1421 LimitVersion(maxSupportedESVersion, gl::Version(3, 1));
1422 }
1423
1424 if (!nativegl::SupportsVertexArrayObjects(functions) ||
1425 features.syncAllVertexArraysToDefault.enabled)
1426 {
1427 // ES 3.1 vertex bindings are not emulated on the default vertex array
1428 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1429 }
1430
1431 // Extension support
1432 extensions->setTextureExtensionSupport(*textureCapsMap);
1433
1434 // Expose this extension only when we support the formats or we're running on top of a native
1435 // ES driver.
1436 extensions->textureCompressionAstcLdrKHR =
1437 extensions->textureCompressionAstcLdrKHR &&
1438 (features.allowAstcFormats.enabled || functions->standard == STANDARD_GL_ES);
1439 extensions->textureCompressionAstcHdrKHR =
1440 extensions->textureCompressionAstcLdrKHR &&
1441 functions->hasExtension("GL_KHR_texture_compression_astc_hdr");
1442 extensions->textureCompressionAstcSliced3dKHR =
1443 (extensions->textureCompressionAstcLdrKHR &&
1444 functions->hasExtension("GL_KHR_texture_compression_astc_sliced_3d")) ||
1445 extensions->textureCompressionAstcHdrKHR;
1446 extensions->elementIndexUintOES = functions->standard == STANDARD_GL_DESKTOP ||
1447 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1448 functions->hasGLESExtension("GL_OES_element_index_uint");
1449 extensions->getProgramBinaryOES = caps->programBinaryFormats.size() > 0;
1450 extensions->readFormatBgraEXT = functions->isAtLeastGL(gl::Version(1, 2)) ||
1451 functions->hasGLExtension("GL_EXT_bgra") ||
1452 functions->hasGLESExtension("GL_EXT_read_format_bgra");
1453 extensions->pixelBufferObjectNV = functions->isAtLeastGL(gl::Version(2, 1)) ||
1454 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1455 functions->hasGLExtension("GL_ARB_pixel_buffer_object") ||
1456 functions->hasGLExtension("GL_EXT_pixel_buffer_object") ||
1457 functions->hasGLESExtension("GL_NV_pixel_buffer_object");
1458 extensions->syncARB = nativegl::SupportsFenceSync(functions);
1459 extensions->mapbufferOES = functions->isAtLeastGL(gl::Version(1, 5)) ||
1460 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1461 functions->hasGLESExtension("GL_OES_mapbuffer");
1462 extensions->mapBufferRangeEXT = functions->isAtLeastGL(gl::Version(3, 0)) ||
1463 functions->hasGLExtension("GL_ARB_map_buffer_range") ||
1464 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1465 functions->hasGLESExtension("GL_EXT_map_buffer_range");
1466 extensions->textureNpotOES = functions->standard == STANDARD_GL_DESKTOP ||
1467 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1468 functions->hasGLESExtension("GL_OES_texture_npot");
1469 // Note that we could emulate EXT_draw_buffers on ES 3.0's core functionality.
1470 extensions->drawBuffersEXT = functions->isAtLeastGL(gl::Version(2, 0)) ||
1471 functions->hasGLExtension("ARB_draw_buffers") ||
1472 functions->hasGLESExtension("GL_EXT_draw_buffers");
1473 extensions->drawBuffersIndexedEXT =
1474 !features.disableDrawBuffersIndexed.enabled &&
1475 (functions->isAtLeastGL(gl::Version(4, 0)) ||
1476 (functions->hasGLExtension("GL_EXT_draw_buffers2") &&
1477 functions->hasGLExtension("GL_ARB_draw_buffers_blend")) ||
1478 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1479 functions->hasGLESExtension("GL_OES_draw_buffers_indexed") ||
1480 functions->hasGLESExtension("GL_EXT_draw_buffers_indexed"));
1481 extensions->drawBuffersIndexedOES = extensions->drawBuffersIndexedEXT;
1482 extensions->textureStorageEXT = functions->standard == STANDARD_GL_DESKTOP ||
1483 functions->hasGLESExtension("GL_EXT_texture_storage");
1484 extensions->textureFilterAnisotropicEXT =
1485 functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") ||
1486 functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic");
1487 extensions->occlusionQueryBooleanEXT = nativegl::SupportsOcclusionQueries(functions);
1488 caps->maxTextureAnisotropy =
1489 extensions->textureFilterAnisotropicEXT
1490 ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
1491 : 0.0f;
1492 extensions->fenceNV = FenceNVGL::Supported(functions) || FenceNVSyncGL::Supported(functions);
1493 extensions->blendMinmaxEXT = functions->isAtLeastGL(gl::Version(1, 5)) ||
1494 functions->hasGLExtension("GL_EXT_blend_minmax") ||
1495 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1496 functions->hasGLESExtension("GL_EXT_blend_minmax");
1497 extensions->framebufferBlitNV = functions->isAtLeastGL(gl::Version(3, 0)) ||
1498 functions->hasGLExtension("GL_EXT_framebuffer_blit") ||
1499 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1500 functions->hasGLESExtension("GL_NV_framebuffer_blit");
1501 extensions->framebufferBlitANGLE =
1502 extensions->framebufferBlitNV || functions->hasGLESExtension("GL_ANGLE_framebuffer_blit");
1503 extensions->framebufferMultisampleANGLE =
1504 extensions->framebufferBlitANGLE && caps->maxSamples > 0;
1505 extensions->multisampledRenderToTextureEXT =
1506 !features.disableMultisampledRenderToTexture.enabled &&
1507 (functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture") ||
1508 functions->hasGLESExtension("GL_IMG_multisampled_render_to_texture"));
1509 extensions->multisampledRenderToTexture2EXT =
1510 !features.disableMultisampledRenderToTexture.enabled &&
1511 extensions->multisampledRenderToTextureEXT &&
1512 functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture2");
1513 extensions->standardDerivativesOES = functions->isAtLeastGL(gl::Version(2, 0)) ||
1514 functions->hasGLExtension("GL_ARB_fragment_shader") ||
1515 functions->hasGLESExtension("GL_OES_standard_derivatives");
1516 extensions->shaderTextureLodEXT = functions->isAtLeastGL(gl::Version(3, 0)) ||
1517 functions->hasGLExtension("GL_ARB_shader_texture_lod") ||
1518 functions->hasGLESExtension("GL_EXT_shader_texture_lod");
1519 extensions->fragDepthEXT = functions->standard == STANDARD_GL_DESKTOP ||
1520 functions->hasGLESExtension("GL_EXT_frag_depth");
1521 extensions->conservativeDepthEXT = functions->isAtLeastGL(gl::Version(4, 2)) ||
1522 functions->hasGLExtension("GL_ARB_conservative_depth") ||
1523 functions->hasGLESExtension("GL_EXT_conservative_depth");
1524 extensions->depthClampEXT = functions->isAtLeastGL(gl::Version(3, 2)) ||
1525 functions->hasGLExtension("GL_ARB_depth_clamp") ||
1526 functions->hasGLESExtension("GL_EXT_depth_clamp");
1527 extensions->polygonOffsetClampEXT = functions->hasExtension("GL_EXT_polygon_offset_clamp");
1528
1529 if (functions->standard == STANDARD_GL_DESKTOP)
1530 {
1531 extensions->polygonModeNV = true;
1532 }
1533 else if (functions->hasGLESExtension("GL_NV_polygon_mode"))
1534 {
1535 // Some drivers expose the extension string without supporting its caps.
1536 ANGLE_GL_CLEAR_ERRORS(functions);
1537 functions->isEnabled(GL_POLYGON_OFFSET_LINE_NV);
1538 if (functions->getError() != GL_NO_ERROR)
1539 {
1540 WARN() << "Not enabling GL_NV_polygon_mode because "
1541 "its native driver support is incomplete.";
1542 }
1543 else
1544 {
1545 extensions->polygonModeNV = true;
1546 }
1547 }
1548 extensions->polygonModeANGLE = extensions->polygonModeNV;
1549
1550 // This functionality is provided by Shader Model 5 and should be available in GLSL 4.00
1551 // or even in older versions with GL_ARB_sample_shading and GL_ARB_gpu_shader5. However,
1552 // some OpenGL implementations (e.g., macOS) that do not support higher context versions
1553 // do not pass the tests so GLSL 4.20 is required here.
1554 extensions->sampleVariablesOES = functions->isAtLeastGL(gl::Version(4, 2)) ||
1555 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1556 functions->hasGLESExtension("GL_OES_sample_variables");
1557 // Some drivers do not support sample qualifiers in ESSL 3.00, so ESSL 3.10 is required on ES.
1558 extensions->shaderMultisampleInterpolationOES =
1559 functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1560 (functions->isAtLeastGLES(gl::Version(3, 1)) &&
1561 functions->hasGLESExtension("GL_OES_shader_multisample_interpolation"));
1562 if (extensions->shaderMultisampleInterpolationOES)
1563 {
1564 caps->minInterpolationOffset =
1565 QuerySingleGLFloat(functions, GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES);
1566 caps->maxInterpolationOffset =
1567 QuerySingleGLFloat(functions, GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES);
1568 caps->subPixelInterpolationOffsetBits =
1569 QuerySingleGLInt(functions, GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES);
1570 }
1571
1572 // Support video texture extension on non Android backends.
1573 // TODO(crbug.com/776222): support Android and Apple devices.
1574 extensions->videoTextureWEBGL = !IsAndroid() && !IsApple();
1575
1576 if (functions->hasGLExtension("GL_ARB_shader_viewport_layer_array") ||
1577 functions->hasGLExtension("GL_NV_viewport_array2"))
1578 {
1579 extensions->multiviewOVR = true;
1580 extensions->multiview2OVR = true;
1581 // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256.
1582 const int maxLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
1583 // GL_MAX_VIEWPORTS is guaranteed to be at least 16.
1584 const int maxViewports = QuerySingleGLInt(functions, GL_MAX_VIEWPORTS);
1585 caps->maxViews = static_cast<GLuint>(std::min(maxLayers, maxViewports));
1586 *multiviewImplementationType = MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2;
1587 }
1588
1589 extensions->fboRenderMipmapOES = functions->isAtLeastGL(gl::Version(3, 0)) ||
1590 functions->hasGLExtension("GL_EXT_framebuffer_object") ||
1591 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1592 functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
1593
1594 extensions->textureBorderClampEXT =
1595 !features.disableTextureClampToBorder.enabled &&
1596 (functions->standard == STANDARD_GL_DESKTOP ||
1597 functions->hasGLESExtension("GL_EXT_texture_border_clamp") ||
1598 functions->hasGLESExtension("GL_OES_texture_border_clamp") ||
1599 functions->hasGLESExtension("GL_NV_texture_border_clamp"));
1600 extensions->textureBorderClampOES = extensions->textureBorderClampEXT;
1601
1602 // This functionality is supported on macOS but the extension
1603 // strings are not listed there for historical reasons.
1604 extensions->textureMirrorClampToEdgeEXT =
1605 !features.disableTextureMirrorClampToEdge.enabled &&
1606 (IsMac() || functions->isAtLeastGL(gl::Version(4, 4)) ||
1607 functions->hasGLExtension("GL_ARB_texture_mirror_clamp_to_edge") ||
1608 functions->hasGLExtension("GL_EXT_texture_mirror_clamp") ||
1609 functions->hasGLExtension("GL_ATI_texture_mirror_once") ||
1610 functions->hasGLESExtension("GL_EXT_texture_mirror_clamp_to_edge"));
1611
1612 extensions->textureShadowLodEXT = functions->hasExtension("GL_EXT_texture_shadow_lod");
1613
1614 extensions->multiDrawIndirectEXT = true;
1615 extensions->instancedArraysANGLE = functions->isAtLeastGL(gl::Version(3, 1)) ||
1616 (functions->hasGLExtension("GL_ARB_instanced_arrays") &&
1617 (functions->hasGLExtension("GL_ARB_draw_instanced") ||
1618 functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
1619 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1620 functions->hasGLESExtension("GL_EXT_instanced_arrays");
1621 extensions->instancedArraysEXT = extensions->instancedArraysANGLE;
1622 extensions->unpackSubimageEXT = functions->standard == STANDARD_GL_DESKTOP ||
1623 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1624 functions->hasGLESExtension("GL_EXT_unpack_subimage");
1625 // Some drivers do not support this extension in ESSL 3.00, so ESSL 3.10 is required on ES.
1626 extensions->shaderNoperspectiveInterpolationNV =
1627 functions->isAtLeastGL(gl::Version(3, 0)) ||
1628 (functions->isAtLeastGLES(gl::Version(3, 1)) &&
1629 functions->hasGLESExtension("GL_NV_shader_noperspective_interpolation"));
1630 extensions->packSubimageNV = functions->standard == STANDARD_GL_DESKTOP ||
1631 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1632 functions->hasGLESExtension("GL_NV_pack_subimage");
1633 extensions->vertexArrayObjectOES = functions->isAtLeastGL(gl::Version(3, 0)) ||
1634 functions->hasGLExtension("GL_ARB_vertex_array_object") ||
1635 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1636 functions->hasGLESExtension("GL_OES_vertex_array_object");
1637 extensions->debugMarkerEXT = functions->isAtLeastGL(gl::Version(4, 3)) ||
1638 functions->hasGLExtension("GL_KHR_debug") ||
1639 functions->hasGLExtension("GL_EXT_debug_marker") ||
1640 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1641 functions->hasGLESExtension("GL_KHR_debug") ||
1642 functions->hasGLESExtension("GL_EXT_debug_marker");
1643 extensions->EGLImageOES = functions->hasGLESExtension("GL_OES_EGL_image");
1644 extensions->EGLImageExternalOES = functions->hasGLESExtension("GL_OES_EGL_image_external");
1645 extensions->EGLImageExternalWrapModesEXT =
1646 functions->hasExtension("GL_EXT_EGL_image_external_wrap_modes");
1647 extensions->EGLImageExternalEssl3OES =
1648 functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
1649 extensions->EGLImageArrayEXT = functions->hasGLESExtension("GL_EXT_EGL_image_array");
1650
1651 extensions->EGLSyncOES = functions->hasGLESExtension("GL_OES_EGL_sync");
1652
1653 if (!features.disableTimestampQueries.enabled &&
1654 (functions->isAtLeastGL(gl::Version(3, 3)) ||
1655 functions->hasGLExtension("GL_ARB_timer_query") ||
1656 functions->hasGLESExtension("GL_EXT_disjoint_timer_query")))
1657 {
1658 extensions->disjointTimerQueryEXT = true;
1659
1660 // If we can't query the counter bits, leave them at 0.
1661 if (!features.queryCounterBitsGeneratesErrors.enabled)
1662 {
1663 caps->queryCounterBitsTimeElapsed =
1664 QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
1665 caps->queryCounterBitsTimestamp =
1666 QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
1667 }
1668 }
1669
1670 // the EXT_multisample_compatibility is written against ES3.1 but can apply
1671 // to earlier versions so therefore we're only checking for the extension string
1672 // and not the specific GLES version.
1673 extensions->multisampleCompatibilityEXT =
1674 functions->isAtLeastGL(gl::Version(1, 3)) ||
1675 functions->hasGLESExtension("GL_EXT_multisample_compatibility");
1676
1677 extensions->framebufferMixedSamplesCHROMIUM =
1678 functions->hasGLExtension("GL_NV_framebuffer_mixed_samples") ||
1679 functions->hasGLESExtension("GL_NV_framebuffer_mixed_samples");
1680
1681 extensions->robustnessEXT = functions->isAtLeastGL(gl::Version(4, 5)) ||
1682 functions->hasGLExtension("GL_KHR_robustness") ||
1683 functions->hasGLExtension("GL_ARB_robustness") ||
1684 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1685 functions->hasGLESExtension("GL_KHR_robustness") ||
1686 functions->hasGLESExtension("GL_EXT_robustness");
1687 extensions->robustnessKHR = functions->isAtLeastGL(gl::Version(4, 5)) ||
1688 functions->hasGLExtension("GL_KHR_robustness") ||
1689 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1690 functions->hasGLESExtension("GL_KHR_robustness");
1691
1692 extensions->robustBufferAccessBehaviorKHR =
1693 extensions->robustnessEXT &&
1694 (functions->hasGLExtension("GL_ARB_robust_buffer_access_behavior") ||
1695 functions->hasGLESExtension("GL_KHR_robust_buffer_access_behavior"));
1696
1697 extensions->stencilTexturingANGLE = functions->isAtLeastGL(gl::Version(4, 3)) ||
1698 functions->hasGLExtension("GL_ARB_stencil_texturing") ||
1699 functions->isAtLeastGLES(gl::Version(3, 1));
1700
1701 if (features.supportsShaderFramebufferFetchEXT.enabled && extensions->drawBuffersIndexedAny())
1702 {
1703 // We can support PLS natively, probably in tiled memory.
1704 extensions->shaderPixelLocalStorageANGLE = true;
1705 extensions->shaderPixelLocalStorageCoherentANGLE = true;
1706 plsOptions->type = ShPixelLocalStorageType::FramebufferFetch;
1707 plsOptions->fragmentSyncType = ShFragmentSynchronizationType::Automatic;
1708 }
1709 else
1710 {
1711 bool hasFragmentShaderImageLoadStore = false;
1712 if (functions->isAtLeastGL(gl::Version(4, 2)) ||
1713 functions->hasGLExtension("GL_ARB_shader_image_load_store"))
1714 {
1715 // [ANGLE_shader_pixel_local_storage] "New Implementation Dependent State":
1716 // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE must be at least 4.
1717 //
1718 // MAX_FRAGMENT_IMAGE_UNIFORMS is at least 8 on Desktop Core and ARB.
1719 hasFragmentShaderImageLoadStore = true;
1720 }
1721 else if (functions->isAtLeastGLES(gl::Version(3, 1)))
1722 {
1723 // [ANGLE_shader_pixel_local_storage] "New Implementation Dependent State":
1724 // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE must be at least 4.
1725 //
1726 // ES 3.1, Table 20.44: MAX_FRAGMENT_IMAGE_UNIFORMS can be 0.
1727 hasFragmentShaderImageLoadStore =
1728 caps->maxShaderImageUniforms[gl::ShaderType::Fragment] >= 4;
1729 }
1730 if (hasFragmentShaderImageLoadStore &&
1731 (features.supportsFragmentShaderInterlockNV.enabled ||
1732 features.supportsFragmentShaderOrderingINTEL.enabled ||
1733 features.supportsFragmentShaderInterlockARB.enabled))
1734 {
1735 // If shader image load/store can be coherent, prefer it over
1736 // EXT_shader_framebuffer_fetch_non_coherent.
1737 extensions->shaderPixelLocalStorageANGLE = true;
1738 extensions->shaderPixelLocalStorageCoherentANGLE = true;
1739 plsOptions->type = ShPixelLocalStorageType::ImageLoadStore;
1740 // Prefer vendor-specific extensions first. The PixelLocalStorageTest.Coherency test
1741 // doesn't always pass on Intel when we use the ARB extension.
1742 if (features.supportsFragmentShaderInterlockNV.enabled)
1743 {
1744 plsOptions->fragmentSyncType =
1745 ShFragmentSynchronizationType::FragmentShaderInterlock_NV_GL;
1746 }
1747 else if (features.supportsFragmentShaderOrderingINTEL.enabled)
1748 {
1749 plsOptions->fragmentSyncType =
1750 ShFragmentSynchronizationType::FragmentShaderOrdering_INTEL_GL;
1751 }
1752 else
1753 {
1754 ASSERT(features.supportsFragmentShaderInterlockARB.enabled);
1755 plsOptions->fragmentSyncType =
1756 ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL;
1757 }
1758 // OpenGL ES only allows read/write access to "r32*" images.
1759 plsOptions->supportsNativeRGBA8ImageFormats =
1760 functions->standard != StandardGL::STANDARD_GL_ES;
1761 }
1762 else if (features.supportsShaderFramebufferFetchNonCoherentEXT.enabled)
1763 {
1764 extensions->shaderPixelLocalStorageANGLE = true;
1765 plsOptions->type = ShPixelLocalStorageType::FramebufferFetch;
1766 }
1767 else if (hasFragmentShaderImageLoadStore)
1768 {
1769 extensions->shaderPixelLocalStorageANGLE = true;
1770 plsOptions->type = ShPixelLocalStorageType::ImageLoadStore;
1771 // OpenGL ES only allows read/write access to "r32*" images.
1772 plsOptions->supportsNativeRGBA8ImageFormats =
1773 functions->standard != StandardGL::STANDARD_GL_ES;
1774 }
1775 }
1776
1777 // EXT_shader_framebuffer_fetch.
1778 if (features.supportsShaderFramebufferFetchEXT.enabled)
1779 {
1780 extensions->shaderFramebufferFetchEXT = true;
1781 }
1782
1783 // TODO(http://anglebug.com/42266350): Support ARM_shader_framebuffer_fetch
1784
1785 // EXT_shader_framebuffer_fetch_non_coherent.
1786 if (features.supportsShaderFramebufferFetchNonCoherentEXT.enabled)
1787 {
1788 extensions->shaderFramebufferFetchNonCoherentEXT = true;
1789 }
1790
1791 extensions->copyTextureCHROMIUM = true;
1792 extensions->syncQueryCHROMIUM = SyncQueryGL::IsSupported(functions);
1793
1794 // Note that OES_texture_storage_multisample_2d_array support could be extended down to GL 3.2
1795 // if we emulated texStorage* API on top of texImage*.
1796 extensions->textureStorageMultisample2dArrayOES =
1797 functions->isAtLeastGL(gl::Version(4, 3)) ||
1798 functions->hasGLExtension("GL_ARB_texture_storage_multisample") ||
1799 functions->hasGLESExtension("GL_OES_texture_storage_multisample_2d_array");
1800
1801 extensions->multiviewMultisampleANGLE = extensions->textureStorageMultisample2dArrayOES &&
1802 (extensions->multiviewOVR || extensions->multiview2OVR);
1803
1804 extensions->textureMultisampleANGLE = functions->isAtLeastGL(gl::Version(3, 2)) ||
1805 functions->hasGLExtension("GL_ARB_texture_multisample") ||
1806 functions->isAtLeastGLES(gl::Version(3, 1));
1807
1808 extensions->textureSRGBDecodeEXT = functions->hasGLExtension("GL_EXT_texture_sRGB_decode") ||
1809 functions->hasGLESExtension("GL_EXT_texture_sRGB_decode");
1810
1811 // ANGLE treats ETC1 as ETC2 for ES 3.0 and higher because it becomes a core format, and they
1812 // are backwards compatible.
1813 extensions->compressedETC1RGB8SubTextureEXT =
1814 extensions->compressedETC2RGB8TextureOES || functions->isAtLeastGLES(gl::Version(3, 0)) ||
1815 functions->hasGLESExtension("GL_EXT_compressed_ETC1_RGB8_sub_texture");
1816
1817 #if ANGLE_ENABLE_CGL
1818 VendorID vendor = GetVendorID(functions);
1819 if ((IsAMD(vendor) || IsIntel(vendor)) && *maxSupportedESVersion >= gl::Version(3, 0))
1820 {
1821 // Apple Intel/AMD drivers do not correctly use the TEXTURE_SRGB_DECODE property of
1822 // sampler states. Disable this extension when we would advertise any ES version
1823 // that has samplers.
1824 extensions->textureSRGBDecodeEXT = false;
1825 }
1826 #endif
1827
1828 extensions->sRGBWriteControlEXT = !features.srgbBlendingBroken.enabled &&
1829 (functions->isAtLeastGL(gl::Version(3, 0)) ||
1830 functions->hasGLExtension("GL_EXT_framebuffer_sRGB") ||
1831 functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
1832 functions->hasGLESExtension("GL_EXT_sRGB_write_control"));
1833
1834 if (features.bgraTexImageFormatsBroken.enabled)
1835 {
1836 extensions->textureFormatBGRA8888EXT = false;
1837 }
1838
1839 // EXT_discard_framebuffer can be implemented as long as glDiscardFramebufferEXT or
1840 // glInvalidateFramebuffer is available
1841 extensions->discardFramebufferEXT = functions->isAtLeastGL(gl::Version(4, 3)) ||
1842 functions->hasGLExtension("GL_ARB_invalidate_subdata") ||
1843 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1844 functions->hasGLESExtension("GL_EXT_discard_framebuffer") ||
1845 functions->hasGLESExtension("GL_ARB_invalidate_subdata");
1846
1847 extensions->translatedShaderSourceANGLE = true;
1848
1849 if (functions->isAtLeastGL(gl::Version(3, 1)) ||
1850 functions->hasGLExtension("GL_ARB_texture_rectangle"))
1851 {
1852 extensions->textureRectangleANGLE = true;
1853 caps->maxRectangleTextureSize =
1854 QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE);
1855 }
1856
1857 // OpenGL 4.3 (and above) and OpenGL ES 3.2 can support all features and constants defined in
1858 // GL_EXT_geometry_shader.
1859 bool hasCoreGSSupport =
1860 functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2));
1861 // OpenGL 4.0 adds the support for instanced geometry shader
1862 // GL_ARB_shader_atomic_counters adds atomic counters to geometry shader
1863 // GL_ARB_shader_storage_buffer_object adds shader storage buffers to geometry shader
1864 // GL_ARB_shader_image_load_store adds images to geometry shader
1865 bool hasInstancedGSSupport = functions->isAtLeastGL(gl::Version(4, 0)) &&
1866 functions->hasGLExtension("GL_ARB_shader_atomic_counters") &&
1867 functions->hasGLExtension("GL_ARB_shader_storage_buffer_object") &&
1868 functions->hasGLExtension("GL_ARB_shader_image_load_store");
1869 if (hasCoreGSSupport || functions->hasGLESExtension("GL_OES_geometry_shader") ||
1870 functions->hasGLESExtension("GL_EXT_geometry_shader") || hasInstancedGSSupport)
1871 {
1872 extensions->geometryShaderEXT = functions->hasGLESExtension("GL_EXT_geometry_shader") ||
1873 hasCoreGSSupport || hasInstancedGSSupport;
1874 extensions->geometryShaderOES = functions->hasGLESExtension("GL_OES_geometry_shader") ||
1875 hasCoreGSSupport || hasInstancedGSSupport;
1876
1877 caps->maxFramebufferLayers = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_LAYERS_EXT);
1878
1879 // GL_PROVOKING_VERTEX isn't a valid return value of GL_LAYER_PROVOKING_VERTEX_EXT in
1880 // GL_EXT_geometry_shader SPEC, however it is legal in desktop OpenGL, which means the value
1881 // follows the one set by glProvokingVertex.
1882 // [OpenGL 4.3] Chapter 11.3.4.6
1883 // The vertex conventions followed for gl_Layer and gl_ViewportIndex may be determined by
1884 // calling GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and
1885 // VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the value returned is
1886 // PROVOKING_VERTEX, then vertex selection follows the convention specified by
1887 // ProvokingVertex.
1888 caps->layerProvokingVertex = QuerySingleGLInt(functions, GL_LAYER_PROVOKING_VERTEX_EXT);
1889 if (caps->layerProvokingVertex == GL_PROVOKING_VERTEX)
1890 {
1891 // We should use GL_LAST_VERTEX_CONVENTION_EXT instead because desktop OpenGL SPEC
1892 // requires the initial value of provoking vertex mode is LAST_VERTEX_CONVENTION.
1893 // [OpenGL 4.3] Chapter 13.4
1894 // The initial value of the provoking vertex mode is LAST_VERTEX_CONVENTION.
1895 caps->layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1896 }
1897
1898 caps->maxShaderUniformComponents[gl::ShaderType::Geometry] =
1899 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1900 caps->maxShaderUniformBlocks[gl::ShaderType::Geometry] =
1901 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT);
1902 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Geometry] =
1903 QuerySingleGLInt(functions, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1904 caps->maxGeometryInputComponents =
1905 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT);
1906 caps->maxGeometryOutputComponents =
1907 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT);
1908 caps->maxGeometryOutputVertices =
1909 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT);
1910 caps->maxGeometryTotalOutputComponents =
1911 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT);
1912 caps->maxGeometryShaderInvocations =
1913 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT);
1914 caps->maxShaderTextureImageUnits[gl::ShaderType::Geometry] =
1915 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
1916 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
1917 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT);
1918 caps->maxShaderAtomicCounters[gl::ShaderType::Geometry] =
1919 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT);
1920 caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
1921 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT);
1922 caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
1923 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT);
1924 }
1925
1926 // The real combined caps contain limits for shader types that are not available to ES, so limit
1927 // the caps to the sum of vertex+fragment+geometry shader caps.
1928 CapCombinedLimitToESShaders(&caps->maxCombinedUniformBlocks, caps->maxShaderUniformBlocks);
1929 CapCombinedLimitToESShaders(&caps->maxCombinedTextureImageUnits,
1930 caps->maxShaderTextureImageUnits);
1931 CapCombinedLimitToESShaders(&caps->maxCombinedShaderStorageBlocks,
1932 caps->maxShaderStorageBlocks);
1933 CapCombinedLimitToESShaders(&caps->maxCombinedImageUniforms, caps->maxShaderImageUniforms);
1934 CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounterBuffers,
1935 caps->maxShaderAtomicCounterBuffers);
1936 CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounters, caps->maxShaderAtomicCounters);
1937
1938 // EXT_blend_func_extended is not implemented on top of ARB_blend_func_extended
1939 // because the latter does not support fragment shader output layout qualifiers.
1940 extensions->blendFuncExtendedEXT = !features.disableBlendFuncExtended.enabled &&
1941 (functions->isAtLeastGL(gl::Version(3, 3)) ||
1942 functions->hasGLESExtension("GL_EXT_blend_func_extended"));
1943 if (extensions->blendFuncExtendedEXT)
1944 {
1945 // TODO(http://anglebug.com/40644593): Support greater values of
1946 // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT queried from the driver. See comments in ProgramGL.cpp
1947 // for more information about this limitation.
1948 caps->maxDualSourceDrawBuffers = 1;
1949 }
1950
1951 // EXT_float_blend
1952 // Assume all desktop driver supports this by default.
1953 extensions->floatBlendEXT = functions->standard == STANDARD_GL_DESKTOP ||
1954 functions->hasGLESExtension("GL_EXT_float_blend") ||
1955 functions->isAtLeastGLES(gl::Version(3, 2));
1956
1957 // ANGLE_base_vertex_base_instance
1958 extensions->baseVertexBaseInstanceANGLE =
1959 !features.disableBaseInstanceVertex.enabled &&
1960 (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1961 functions->hasGLESExtension("GL_OES_draw_elements_base_vertex") ||
1962 functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex"));
1963
1964 // EXT_base_instance
1965 extensions->baseInstanceEXT =
1966 !features.disableBaseInstanceVertex.enabled &&
1967 (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1968 functions->hasGLESExtension("GL_OES_draw_elements_base_vertex") ||
1969 functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex") ||
1970 functions->hasGLESExtension("GL_EXT_base_instance"));
1971
1972 // ANGLE_base_vertex_base_instance_shader_builtin
1973 extensions->baseVertexBaseInstanceShaderBuiltinANGLE = extensions->baseVertexBaseInstanceANGLE;
1974
1975 // OES_draw_elements_base_vertex
1976 extensions->drawElementsBaseVertexOES =
1977 functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1978 functions->hasGLESExtension("GL_OES_draw_elements_base_vertex");
1979
1980 // EXT_draw_elements_base_vertex
1981 extensions->drawElementsBaseVertexEXT =
1982 functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1983 functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex");
1984
1985 // ANGLE_compressed_texture_etc
1986 // Expose this extension only when we support the formats or we're running on top of a native
1987 // ES driver.
1988 extensions->compressedTextureEtcANGLE =
1989 (features.allowETCFormats.enabled || functions->standard == STANDARD_GL_ES) &&
1990 gl::DetermineCompressedTextureETCSupport(*textureCapsMap);
1991
1992 // When running on top of desktop OpenGL drivers and allow_etc_formats feature is not enabled,
1993 // mark ETC1 as emulated to hide it from WebGL clients.
1994 limitations->emulatedEtc1 =
1995 !features.allowETCFormats.enabled && functions->standard == STANDARD_GL_DESKTOP;
1996
1997 // To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
1998 // if those formats are not available.
1999 if (features.unsizedSRGBReadPixelsDoesntTransform.enabled &&
2000 !functions->isAtLeastGLES(gl::Version(3, 0)))
2001 {
2002 extensions->sRGBEXT = false;
2003 }
2004
2005 extensions->provokingVertexANGLE = functions->hasGLExtension("GL_ARB_provoking_vertex") ||
2006 functions->hasGLExtension("GL_EXT_provoking_vertex") ||
2007 functions->isAtLeastGL(gl::Version(3, 2));
2008
2009 extensions->textureExternalUpdateANGLE = true;
2010 extensions->texture3DOES = functions->isAtLeastGL(gl::Version(1, 2)) ||
2011 functions->isAtLeastGLES(gl::Version(3, 0)) ||
2012 functions->hasGLESExtension("GL_OES_texture_3D");
2013
2014 extensions->memoryObjectEXT = functions->hasGLExtension("GL_EXT_memory_object") ||
2015 functions->hasGLESExtension("GL_EXT_memory_object");
2016 extensions->semaphoreEXT = functions->hasGLExtension("GL_EXT_semaphore") ||
2017 functions->hasGLESExtension("GL_EXT_semaphore");
2018 extensions->memoryObjectFdEXT = functions->hasGLExtension("GL_EXT_memory_object_fd") ||
2019 functions->hasGLESExtension("GL_EXT_memory_object_fd");
2020 extensions->semaphoreFdEXT = !features.disableSemaphoreFd.enabled &&
2021 (functions->hasGLExtension("GL_EXT_semaphore_fd") ||
2022 functions->hasGLESExtension("GL_EXT_semaphore_fd"));
2023 extensions->gpuShader5EXT = functions->isAtLeastGL(gl::Version(4, 0)) ||
2024 functions->isAtLeastGLES(gl::Version(3, 2)) ||
2025 functions->hasGLExtension("GL_ARB_gpu_shader5") ||
2026 functions->hasGLESExtension("GL_EXT_gpu_shader5") ||
2027 functions->hasGLESExtension("GL_OES_gpu_shader5");
2028 extensions->gpuShader5OES = extensions->gpuShader5EXT;
2029 extensions->shaderIoBlocksOES = functions->isAtLeastGL(gl::Version(3, 2)) ||
2030 functions->isAtLeastGLES(gl::Version(3, 2)) ||
2031 functions->hasGLESExtension("GL_OES_shader_io_blocks") ||
2032 functions->hasGLESExtension("GL_EXT_shader_io_blocks");
2033 extensions->shaderIoBlocksEXT = extensions->shaderIoBlocksOES;
2034
2035 extensions->shadowSamplersEXT = functions->isAtLeastGL(gl::Version(2, 0)) ||
2036 functions->isAtLeastGLES(gl::Version(3, 0)) ||
2037 functions->hasGLESExtension("GL_EXT_shadow_samplers");
2038
2039 if (!features.disableClipControl.enabled)
2040 {
2041 extensions->clipControlEXT = functions->isAtLeastGL(gl::Version(4, 5)) ||
2042 functions->hasGLExtension("GL_ARB_clip_control") ||
2043 functions->hasGLESExtension("GL_EXT_clip_control");
2044 }
2045
2046 if (features.disableRenderSnorm.enabled)
2047 {
2048 extensions->renderSnormEXT = false;
2049 }
2050
2051 constexpr uint32_t kRequiredClipDistances = 8;
2052 constexpr uint32_t kRequiredCullDistances = 8;
2053 constexpr uint32_t kRequiredCombinedClipAndCullDistances = 8;
2054
2055 // GL_APPLE_clip_distance cannot be implemented on top of GL_EXT_clip_cull_distance,
2056 // so require either native support or desktop GL.
2057 extensions->clipDistanceAPPLE = functions->isAtLeastGL(gl::Version(3, 0)) ||
2058 functions->hasGLESExtension("GL_APPLE_clip_distance");
2059 if (extensions->clipDistanceAPPLE)
2060 {
2061 caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_APPLE);
2062
2063 if (caps->maxClipDistances < kRequiredClipDistances)
2064 {
2065 WARN() << "Disabling GL_APPLE_clip_distance because only " << caps->maxClipDistances
2066 << " clip distances are supported by the driver.";
2067 extensions->clipDistanceAPPLE = false;
2068 }
2069 }
2070
2071 // GL_EXT_clip_cull_distance spec requires shader interface blocks to support
2072 // built-in array redeclarations on OpenGL ES.
2073 extensions->clipCullDistanceEXT =
2074 functions->isAtLeastGL(gl::Version(4, 5)) ||
2075 (functions->isAtLeastGL(gl::Version(3, 0)) &&
2076 functions->hasGLExtension("GL_ARB_cull_distance")) ||
2077 (extensions->shaderIoBlocksEXT && functions->hasGLESExtension("GL_EXT_clip_cull_distance"));
2078 if (extensions->clipCullDistanceEXT)
2079 {
2080 caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_EXT);
2081 caps->maxCullDistances = QuerySingleGLInt(functions, GL_MAX_CULL_DISTANCES_EXT);
2082 caps->maxCombinedClipAndCullDistances =
2083 QuerySingleGLInt(functions, GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT);
2084
2085 if (caps->maxClipDistances < kRequiredClipDistances ||
2086 caps->maxCullDistances < kRequiredCullDistances ||
2087 caps->maxCombinedClipAndCullDistances < kRequiredCombinedClipAndCullDistances)
2088 {
2089 WARN() << "Disabling GL_EXT_clip_cull_distance because only " << caps->maxClipDistances
2090 << " clip distances, " << caps->maxCullDistances << " cull distances and "
2091 << caps->maxCombinedClipAndCullDistances
2092 << " combined clip/cull distances are supported by the driver.";
2093 extensions->clipCullDistanceEXT = false;
2094 }
2095 }
2096
2097 // Same as GL_EXT_clip_cull_distance but with cull distance support being optional.
2098 extensions->clipCullDistanceANGLE =
2099 (functions->isAtLeastGL(gl::Version(3, 0)) || extensions->clipCullDistanceEXT) &&
2100 caps->maxClipDistances >= kRequiredClipDistances;
2101 ASSERT(!extensions->clipCullDistanceANGLE || caps->maxClipDistances > 0);
2102
2103 // GL_OES_shader_image_atomic
2104 //
2105 // Note that imageAtomicExchange() is allowed to accept float textures (of r32f format) in this
2106 // extension, but that's not supported by ARB_shader_image_load_store which this extension is
2107 // based on, neither in the spec it was merged into it. This support was only added to desktop
2108 // GLSL in version 4.5
2109 if (functions->isAtLeastGL(gl::Version(4, 5)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
2110 functions->hasGLESExtension("GL_OES_shader_image_atomic"))
2111 {
2112 extensions->shaderImageAtomicOES = true;
2113 }
2114
2115 // GL_OES_texture_buffer
2116 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
2117 functions->hasGLESExtension("GL_OES_texture_buffer") ||
2118 functions->hasGLESExtension("GL_EXT_texture_buffer") ||
2119 functions->hasGLExtension("GL_ARB_texture_buffer_object"))
2120 {
2121 caps->maxTextureBufferSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_BUFFER_SIZE);
2122 caps->textureBufferOffsetAlignment =
2123 QuerySingleGLInt(functions, GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT);
2124 extensions->textureBufferOES = true;
2125 extensions->textureBufferEXT = true;
2126 }
2127 else
2128 {
2129 // Can't support ES3.2 without texture buffer objects
2130 LimitVersion(maxSupportedESVersion, gl::Version(3, 1));
2131 }
2132
2133 extensions->YUVTargetEXT = functions->hasGLESExtension("GL_EXT_YUV_target");
2134
2135 // GL_MESA_framebuffer_flip_y
2136 extensions->framebufferFlipYMESA = functions->hasGLESExtension("GL_MESA_framebuffer_flip_y") ||
2137 functions->hasGLExtension("GL_MESA_framebuffer_flip_y");
2138
2139 // GL_KHR_parallel_shader_compile
2140 extensions->parallelShaderCompileKHR = !features.disableNativeParallelCompile.enabled &&
2141 (functions->maxShaderCompilerThreadsKHR != nullptr ||
2142 functions->maxShaderCompilerThreadsARB != nullptr);
2143
2144 // GL_ANGLE_logic_op
2145 extensions->logicOpANGLE = functions->isAtLeastGL(gl::Version(2, 0));
2146
2147 // GL_EXT_clear_texture
2148 extensions->clearTextureEXT = functions->isAtLeastGL(gl::Version(4, 4)) ||
2149 functions->hasGLESExtension("GL_EXT_clear_texture") ||
2150 functions->hasGLExtension("GL_ARB_clear_texture");
2151
2152 // GL_QCOM_tiled_rendering
2153 extensions->tiledRenderingQCOM = !features.disableTiledRendering.enabled &&
2154 functions->hasGLESExtension("GL_QCOM_tiled_rendering");
2155
2156 extensions->blendEquationAdvancedKHR =
2157 !features.disableBlendEquationAdvanced.enabled &&
2158 (functions->hasGLExtension("GL_NV_blend_equation_advanced") ||
2159 functions->hasGLExtension("GL_KHR_blend_equation_advanced") ||
2160 functions->isAtLeastGLES(gl::Version(3, 2)) ||
2161 functions->hasGLESExtension("GL_KHR_blend_equation_advanced"));
2162 extensions->blendEquationAdvancedCoherentKHR =
2163 !features.disableBlendEquationAdvanced.enabled &&
2164 (functions->hasGLExtension("GL_NV_blend_equation_advanced_coherent") ||
2165 functions->hasGLExtension("GL_KHR_blend_equation_advanced_coherent") ||
2166 functions->isAtLeastGLES(gl::Version(3, 2)) ||
2167 functions->hasGLESExtension("GL_KHR_blend_equation_advanced_coherent"));
2168
2169 // PVRTC1 textures must be squares on Apple platforms.
2170 if (IsApple())
2171 {
2172 limitations->squarePvrtc1 = true;
2173 }
2174
2175 // Check if the driver clamps constant blend color
2176 if (IsQualcomm(GetVendorID(functions)))
2177 {
2178 // Backup current state
2179 float oldColor[4];
2180 functions->getFloatv(GL_BLEND_COLOR, oldColor);
2181
2182 // Probe clamping
2183 float color[4];
2184 functions->blendColor(2.0, 0.0, 0.0, 0.0);
2185 functions->getFloatv(GL_BLEND_COLOR, color);
2186 limitations->noUnclampedBlendColor = color[0] == 1.0;
2187
2188 // Restore previous state
2189 functions->blendColor(oldColor[0], oldColor[1], oldColor[2], oldColor[3]);
2190 }
2191 }
2192
GetSystemInfoVendorIDAndDeviceID(const FunctionsGL * functions,angle::SystemInfo * outSystemInfo,angle::VendorID * outVendor,angle::DeviceID * outDevice)2193 bool GetSystemInfoVendorIDAndDeviceID(const FunctionsGL *functions,
2194 angle::SystemInfo *outSystemInfo,
2195 angle::VendorID *outVendor,
2196 angle::DeviceID *outDevice)
2197 {
2198 // Get vendor from GL itself, so on multi-GPU systems the correct GPU is selected.
2199 *outVendor = GetVendorID(functions);
2200 *outDevice = 0;
2201
2202 // Gather additional information from the system to detect multi-GPU scenarios. Do not collect
2203 // system info on Android as it may use Vulkan which can crash on older devices. All the system
2204 // info we need is available in the version and renderer strings on Android.
2205 bool isGetSystemInfoSuccess = !IsAndroid() && angle::GetSystemInfo(outSystemInfo);
2206
2207 // Get the device id from system info, corresponding to the vendor of the active GPU.
2208 if (isGetSystemInfoSuccess && !outSystemInfo->gpus.empty())
2209 {
2210 if (*outVendor == VENDOR_ID_UNKNOWN)
2211 {
2212 // If vendor ID is unknown, take the best estimate of the active GPU. Chances are there
2213 // is only one GPU anyway.
2214 *outVendor = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].vendorId;
2215 *outDevice = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].deviceId;
2216 }
2217 else
2218 {
2219 for (const angle::GPUDeviceInfo &gpu : outSystemInfo->gpus)
2220 {
2221 if (*outVendor == gpu.vendorId)
2222 {
2223 // Note that deviceId may not necessarily have been possible to retrieve.
2224 *outDevice = gpu.deviceId;
2225 break;
2226 }
2227 }
2228 }
2229 }
2230 else
2231 {
2232 // If system info is not available, attempt to deduce the device from GL itself.
2233 *outDevice = GetDeviceID(functions);
2234 }
2235
2236 return isGetSystemInfoSuccess;
2237 }
2238
Has9thGenIntelGPU(const angle::SystemInfo & systemInfo)2239 bool Has9thGenIntelGPU(const angle::SystemInfo &systemInfo)
2240 {
2241 for (const angle::GPUDeviceInfo &deviceInfo : systemInfo.gpus)
2242 {
2243 if (IsIntel(deviceInfo.vendorId) && Is9thGenIntel(deviceInfo.deviceId))
2244 {
2245 return true;
2246 }
2247 }
2248
2249 return false;
2250 }
2251
InitializeFeatures(const FunctionsGL * functions,angle::FeaturesGL * features)2252 void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features)
2253 {
2254 angle::VendorID vendor;
2255 angle::DeviceID device;
2256 angle::SystemInfo systemInfo;
2257
2258 bool isGetSystemInfoSuccess =
2259 GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);
2260
2261 bool isAMD = IsAMD(vendor);
2262 bool isApple = IsAppleGPU(vendor);
2263 bool isIntel = IsIntel(vendor);
2264 bool isNvidia = IsNvidia(vendor);
2265 bool isQualcomm = IsQualcomm(vendor);
2266 bool isVMWare = IsVMWare(vendor);
2267 bool hasAMD = systemInfo.hasAMDGPU();
2268 bool isMali = IsARM(vendor);
2269
2270 std::array<int, 3> mesaVersion = {0, 0, 0};
2271 bool isMesa = IsMesa(functions, &mesaVersion);
2272
2273 int qualcommVersion = -1;
2274 if (!isMesa && isQualcomm)
2275 {
2276 qualcommVersion = GetQualcommVersion(functions);
2277 }
2278
2279 // Don't use 1-bit alpha formats on desktop GL with AMD drivers.
2280 ANGLE_FEATURE_CONDITION(features, avoid1BitAlphaTextureFormats,
2281 functions->standard == STANDARD_GL_DESKTOP && isAMD);
2282
2283 ANGLE_FEATURE_CONDITION(features, RGBA4IsNotSupportedForColorRendering,
2284 functions->standard == STANDARD_GL_DESKTOP && isIntel);
2285
2286 // Although "Sandy Bridge", "Ivy Bridge", and "Haswell" may support GL_ARB_ES3_compatibility
2287 // extension, ETC2/EAC formats are emulated there. Newer Intel GPUs support them natively.
2288 ANGLE_FEATURE_CONDITION(
2289 features, allowETCFormats,
2290 isIntel && !IsSandyBridge(device) && !IsIvyBridge(device) && !IsHaswell(device));
2291
2292 // Mesa always exposes ASTC extension but only Intel Gen9, Gen11, and Gen12 have hardware
2293 // support for it. Newer Intel GPUs (Gen12.5+) do not support ASTC.
2294 ANGLE_FEATURE_CONDITION(features, allowAstcFormats,
2295 !isMesa || isIntel && (Is9thGenIntel(device) || IsGeminiLake(device) ||
2296 IsCoffeeLake(device) || Is11thGenIntel(device) ||
2297 Is12thGenIntel(device)));
2298
2299 // Ported from gpu_driver_bug_list.json (#183)
2300 ANGLE_FEATURE_CONDITION(features, emulateAbsIntFunction, IsApple() && isIntel);
2301
2302 ANGLE_FEATURE_CONDITION(features, addAndTrueToLoopCondition, IsApple() && isIntel);
2303
2304 // Ported from gpu_driver_bug_list.json (#191)
2305 ANGLE_FEATURE_CONDITION(
2306 features, emulateIsnanFloat,
2307 isIntel && IsApple() && IsSkylake(device) && GetMacOSVersion() < OSVersion(10, 13, 2));
2308
2309 // https://anglebug.com/42266803
2310 ANGLE_FEATURE_CONDITION(features, clearsWithGapsNeedFlush,
2311 !isMesa && isQualcomm && qualcommVersion < 490);
2312
2313 ANGLE_FEATURE_CONDITION(features, doesSRGBClearsOnLinearFramebufferAttachments,
2314 isIntel || isAMD);
2315
2316 ANGLE_FEATURE_CONDITION(features, emulateMaxVertexAttribStride,
2317 IsLinux() && functions->standard == STANDARD_GL_DESKTOP && isAMD);
2318 ANGLE_FEATURE_CONDITION(
2319 features, useUnusedBlocksWithStandardOrSharedLayout,
2320 (IsApple() && functions->standard == STANDARD_GL_DESKTOP) || (IsLinux() && isAMD));
2321
2322 // Ported from gpu_driver_bug_list.json (#187)
2323 ANGLE_FEATURE_CONDITION(features, doWhileGLSLCausesGPUHang,
2324 IsApple() && functions->standard == STANDARD_GL_DESKTOP &&
2325 GetMacOSVersion() < OSVersion(10, 11, 0));
2326
2327 // Ported from gpu_driver_bug_list.json (#211)
2328 ANGLE_FEATURE_CONDITION(features, rewriteFloatUnaryMinusOperator,
2329 IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 12, 0));
2330
2331 ANGLE_FEATURE_CONDITION(features, vertexIDDoesNotIncludeBaseVertex, IsApple() && isAMD);
2332
2333 // Triggers a bug on Marshmallow Adreno (4xx?) driver.
2334 // http://anglebug.com/40096454
2335 ANGLE_FEATURE_CONDITION(features, dontInitializeUninitializedLocals, !isMesa && isQualcomm);
2336
2337 ANGLE_FEATURE_CONDITION(features, finishDoesNotCauseQueriesToBeAvailable,
2338 functions->standard == STANDARD_GL_DESKTOP && isNvidia);
2339
2340 // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
2341 ANGLE_FEATURE_CONDITION(features, alwaysCallUseProgramAfterLink, true);
2342
2343 ANGLE_FEATURE_CONDITION(features, unpackOverlappingRowsSeparatelyUnpackBuffer, isNvidia);
2344 ANGLE_FEATURE_CONDITION(features, packOverlappingRowsSeparatelyPackBuffer, isNvidia);
2345
2346 ANGLE_FEATURE_CONDITION(features, initializeCurrentVertexAttributes, isNvidia);
2347
2348 ANGLE_FEATURE_CONDITION(features, unpackLastRowSeparatelyForPaddingInclusion,
2349 IsApple() || isNvidia);
2350 ANGLE_FEATURE_CONDITION(features, packLastRowSeparatelyForPaddingInclusion,
2351 IsApple() || isNvidia);
2352
2353 ANGLE_FEATURE_CONDITION(features, removeInvariantAndCentroidForESSL3,
2354 functions->isAtMostGL(gl::Version(4, 1)) ||
2355 (functions->standard == STANDARD_GL_DESKTOP && isAMD));
2356
2357 // TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
2358 // 364 are known to be affected, at least up to 375.
2359 ANGLE_FEATURE_CONDITION(features, emulateAtan2Float, isNvidia);
2360
2361 ANGLE_FEATURE_CONDITION(features, reapplyUBOBindingsAfterUsingBinaryProgram,
2362 isAMD || IsAndroid());
2363
2364 // TODO(oetuaho): Make this specific to the affected driver versions. Versions at least up to
2365 // 390 are known to be affected. Versions after that are expected not to be affected.
2366 ANGLE_FEATURE_CONDITION(features, clampFragDepth, isNvidia);
2367
2368 // TODO(oetuaho): Make this specific to the affected driver versions. Versions since 397.31 are
2369 // not affected.
2370 ANGLE_FEATURE_CONDITION(features, rewriteRepeatedAssignToSwizzled, isNvidia);
2371
2372 // TODO(jmadill): Narrow workaround range for specific devices.
2373
2374 ANGLE_FEATURE_CONDITION(features, clampPointSize, IsAndroid() || isNvidia);
2375
2376 // Ported from gpu_driver_bug_list.json (#246, #258)
2377 ANGLE_FEATURE_CONDITION(features, dontUseLoopsToInitializeVariables,
2378 (!isMesa && isQualcomm) || (isIntel && IsApple()));
2379
2380 // Intel macOS condition ported from gpu_driver_bug_list.json (#327)
2381 ANGLE_FEATURE_CONDITION(features, disableBlendFuncExtended,
2382 IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 14, 0));
2383
2384 ANGLE_FEATURE_CONDITION(features, avoidBindFragDataLocation, !isMesa && isQualcomm);
2385
2386 ANGLE_FEATURE_CONDITION(features, unsizedSRGBReadPixelsDoesntTransform, !isMesa && isQualcomm);
2387
2388 ANGLE_FEATURE_CONDITION(features, queryCounterBitsGeneratesErrors, IsNexus5X(vendor, device));
2389
2390 bool isAndroidLessThan14 = IsAndroid() && GetAndroidSDKVersion() < 34;
2391 bool isAndroidAtLeast14 = IsAndroid() && GetAndroidSDKVersion() >= 34;
2392 bool isIntelLinuxLessThanKernelVersion5 =
2393 isIntel && IsLinux() && GetLinuxOSVersion() < OSVersion(5, 0, 0);
2394 ANGLE_FEATURE_CONDITION(features, limitWebglMaxTextureSizeTo4096,
2395 isAndroidLessThan14 || isIntelLinuxLessThanKernelVersion5);
2396 ANGLE_FEATURE_CONDITION(features, limitWebglMaxTextureSizeTo8192, isAndroidAtLeast14);
2397 // On Apple switchable graphics, GL_MAX_SAMPLES may differ between the GPUs.
2398 // 4 is a lowest common denominator that is always supported.
2399 ANGLE_FEATURE_CONDITION(features, limitMaxMSAASamplesTo4,
2400 IsAndroid() || (IsApple() && (isIntel || isAMD || isNvidia)));
2401 ANGLE_FEATURE_CONDITION(features, limitMax3dArrayTextureSizeTo1024,
2402 isIntelLinuxLessThanKernelVersion5);
2403
2404 ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, IsApple());
2405
2406 // NVidia and PowerVR Rogue report MAX_COMBINED_SHADER_OUTPUT_RESOURCES incorrectly.
2407 // Force it to the sum of all sublimits.
2408 ANGLE_FEATURE_CONDITION(features, forceMaxCombinedShaderOutputResources,
2409 isNvidia || IsPowerVrRogue(functions));
2410
2411 // The WebGL conformance/uniforms/out-of-bounds-uniform-array-access test has been seen to fail
2412 // on AMD and Android devices.
2413 // This test is also flaky on Linux Nvidia. So we just turn it on everywhere and don't rely on
2414 // driver since security is important.
2415 ANGLE_FEATURE_CONDITION(
2416 features, clampArrayAccess,
2417 IsAndroid() || isAMD || !functions->hasExtension("GL_KHR_robust_buffer_access_behavior"));
2418
2419 ANGLE_FEATURE_CONDITION(features, resetTexImage2DBaseLevel,
2420 IsApple() && isIntel && GetMacOSVersion() >= OSVersion(10, 12, 4));
2421
2422 ANGLE_FEATURE_CONDITION(features, clearToZeroOrOneBroken,
2423 IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 12, 6));
2424
2425 ANGLE_FEATURE_CONDITION(features, adjustSrcDstRegionForBlitFramebuffer,
2426 IsLinux() || (IsAndroid() && isNvidia) || (IsWindows() && isNvidia) ||
2427 (IsApple() && functions->standard == STANDARD_GL_ES));
2428
2429 ANGLE_FEATURE_CONDITION(features, clipSrcRegionForBlitFramebuffer,
2430 IsApple() || (IsLinux() && isAMD));
2431
2432 ANGLE_FEATURE_CONDITION(features, RGBDXT1TexturesSampleZeroAlpha, IsApple());
2433
2434 ANGLE_FEATURE_CONDITION(features, unfoldShortCircuits, IsApple());
2435
2436 ANGLE_FEATURE_CONDITION(features, emulatePrimitiveRestartFixedIndex,
2437 functions->standard == STANDARD_GL_DESKTOP &&
2438 functions->isAtLeastGL(gl::Version(3, 1)) &&
2439 !functions->isAtLeastGL(gl::Version(4, 3)));
2440 ANGLE_FEATURE_CONDITION(
2441 features, setPrimitiveRestartFixedIndexForDrawArrays,
2442 features->emulatePrimitiveRestartFixedIndex.enabled && IsApple() && isIntel);
2443
2444 ANGLE_FEATURE_CONDITION(features, removeDynamicIndexingOfSwizzledVector,
2445 IsApple() || IsAndroid() || IsWindows());
2446
2447 // Ported from gpu_driver_bug_list.json (#89)
2448 ANGLE_FEATURE_CONDITION(features, regenerateStructNames, IsApple());
2449
2450 // Ported from gpu_driver_bug_list.json (#184)
2451 ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, IsApple() && isIntel);
2452
2453 // Workaround for the widespread OpenGL ES driver implementaion bug
2454 ANGLE_FEATURE_CONDITION(features, readPixelsUsingImplementationColorReadFormatForNorm16,
2455 !isIntel && functions->standard == STANDARD_GL_ES &&
2456 functions->isAtLeastGLES(gl::Version(3, 1)) &&
2457 functions->hasGLESExtension("GL_EXT_texture_norm16"));
2458
2459 // anglebug.com/40644715
2460 ANGLE_FEATURE_CONDITION(features, flushBeforeDeleteTextureIfCopiedTo, IsApple() && isIntel);
2461
2462 // anglebug.com/40096480
2463 // Seems to affect both Intel and AMD GPUs. Enable workaround for all GPUs on macOS.
2464 ANGLE_FEATURE_CONDITION(features, rewriteRowMajorMatrices,
2465 // IsApple() && functions->standard == STANDARD_GL_DESKTOP);
2466 // TODO(anglebug.com/40096480): diagnose crashes with this workaround.
2467 false);
2468
2469 ANGLE_FEATURE_CONDITION(features, disableDrawBuffersIndexed, IsWindows() && isAMD);
2470
2471 ANGLE_FEATURE_CONDITION(
2472 features, disableSemaphoreFd,
2473 IsLinux() && isAMD && isMesa && mesaVersion < (std::array<int, 3>{19, 3, 5}));
2474
2475 ANGLE_FEATURE_CONDITION(
2476 features, disableTimestampQueries,
2477 (IsLinux() && isVMWare) || (IsAndroid() && isNvidia) ||
2478 (IsAndroid() && GetAndroidSDKVersion() < 27 && IsAdreno5xxOrOlder(functions)) ||
2479 (!isMesa && IsMaliT8xxOrOlder(functions)) || (!isMesa && IsMaliG31OrOlder(functions)));
2480
2481 ANGLE_FEATURE_CONDITION(features, decodeEncodeSRGBForGenerateMipmap, IsApple());
2482
2483 // anglebug.com/42263273
2484 // The (redundant) explicit exclusion of Windows AMD is because the workaround fails
2485 // Texture2DRGTest.TextureRGUNormTest on that platform, and the test is skipped. If
2486 // you'd like to enable the workaround on Windows AMD, please fix the test first.
2487 ANGLE_FEATURE_CONDITION(
2488 features, emulateCopyTexImage2DFromRenderbuffers,
2489 IsApple() && functions->standard == STANDARD_GL_ES && !(isAMD && IsWindows()));
2490
2491 // anglebug.com/40096747
2492 // Replace copyTexImage2D with texImage2D + copyTexSubImage2D to bypass driver bug.
2493 ANGLE_FEATURE_CONDITION(features, emulateCopyTexImage2D, isApple);
2494
2495 // Don't attempt to use the discrete GPU on NVIDIA-based MacBook Pros, since the
2496 // driver is unstable in this situation.
2497 //
2498 // Note that this feature is only set here in order to advertise this workaround
2499 // externally. GPU switching support must be enabled or disabled early, during display
2500 // initialization, before these features are set up.
2501 bool isDualGPUMacWithNVIDIA = false;
2502 if (IsApple() && functions->standard == STANDARD_GL_DESKTOP)
2503 {
2504 if (isGetSystemInfoSuccess)
2505 {
2506 // The full system information must be queried to see whether it's a dual-GPU
2507 // NVIDIA MacBook Pro since it's likely that the integrated GPU will be active
2508 // when these features are initialized.
2509 isDualGPUMacWithNVIDIA = systemInfo.isMacSwitchable && systemInfo.hasNVIDIAGPU();
2510 }
2511 }
2512 ANGLE_FEATURE_CONDITION(features, disableGPUSwitchingSupport, isDualGPUMacWithNVIDIA);
2513
2514 // Workaround issue in NVIDIA GL driver on Linux when TSAN is enabled
2515 // http://crbug.com/1094869
2516 bool isTSANBuild = false;
2517 #ifdef THREAD_SANITIZER
2518 isTSANBuild = true;
2519 #endif
2520 ANGLE_FEATURE_CONDITION(features, disableNativeParallelCompile,
2521 isTSANBuild && IsLinux() && isNvidia);
2522
2523 // anglebug.com/40096712
2524 ANGLE_FEATURE_CONDITION(features, emulatePackSkipRowsAndPackSkipPixels, IsApple());
2525
2526 // http://crbug.com/1042393
2527 // XWayland defaults to a 1hz refresh rate when the "surface is not visible", which sometimes
2528 // causes issues in Chrome. To get around this, default to a 30Hz refresh rate if we see bogus
2529 // from the driver.
2530 ANGLE_FEATURE_CONDITION(features, clampMscRate, IsLinux() && IsWayland());
2531
2532 ANGLE_FEATURE_CONDITION(features, bindTransformFeedbackBufferBeforeBindBufferRange, IsApple());
2533
2534 // http://crbug.com/1137851
2535 // Speculative fix for above issue, users can enable it via flags.
2536 // http://crbug.com/1187475
2537 // Disable on Mesa 20 / Intel
2538 ANGLE_FEATURE_CONDITION(features, disableSyncControlSupport,
2539 IsLinux() && isIntel && isMesa && mesaVersion[0] == 20);
2540
2541 ANGLE_FEATURE_CONDITION(features, keepBufferShadowCopy, !CanMapBufferForRead(functions));
2542
2543 ANGLE_FEATURE_CONDITION(features, setZeroLevelBeforeGenerateMipmap, IsApple());
2544
2545 ANGLE_FEATURE_CONDITION(features, promotePackedFormatsTo8BitPerChannel, IsApple() && hasAMD);
2546
2547 // crbug.com/1171371
2548 // If output variable gl_FragColor is written by fragment shader, it may cause context lost with
2549 // Adreno 42x and 3xx.
2550 ANGLE_FEATURE_CONDITION(features, initFragmentOutputVariables, IsAdreno42xOr3xx(functions));
2551
2552 // http://crbug.com/1144207
2553 // The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
2554 // now.
2555 ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithOffset,
2556 IsApple() && IsIntel(vendor) && !IsHaswell(device));
2557 ANGLE_FEATURE_CONDITION(features, syncAllVertexArraysToDefault,
2558 !nativegl::SupportsVertexArrayObjects(functions));
2559
2560 // NVIDIA OpenGL ES emulated profile cannot handle client arrays
2561 ANGLE_FEATURE_CONDITION(features, syncDefaultVertexArraysToDefault,
2562 nativegl::CanUseDefaultVertexArrayObject(functions) && !isNvidia);
2563
2564 // http://crbug.com/1181193
2565 // On desktop Linux/AMD when using the amdgpu drivers, the precise kernel and DRM version are
2566 // leaked via GL_RENDERER. We workaround this too improve user security.
2567 ANGLE_FEATURE_CONDITION(features, sanitizeAMDGPURendererString, IsLinux() && hasAMD);
2568
2569 // http://crbug.com/1187513
2570 // Imagination drivers are buggy with context switching. It needs to unbind fbo before context
2571 // switching to workadround the driver issues.
2572 ANGLE_FEATURE_CONDITION(features, unbindFBOBeforeSwitchingContext, IsPowerVR(vendor));
2573
2574 // http://crbug.com/1181068 and http://crbug.com/783979
2575 ANGLE_FEATURE_CONDITION(features, flushOnFramebufferChange,
2576 IsApple() && Has9thGenIntelGPU(systemInfo));
2577
2578 // Disable GL_EXT_multisampled_render_to_texture on a bunch of different configurations:
2579
2580 // http://crbug.com/490379
2581 // http://crbug.com/767913
2582 bool isAdreno4xxOnAndroidLessThan51 =
2583 IsAndroid() && IsAdreno4xx(functions) && GetAndroidSDKVersion() < 22;
2584
2585 // http://crbug.com/612474
2586 bool isAdreno4xxOnAndroid70 =
2587 IsAndroid() && IsAdreno4xx(functions) && GetAndroidSDKVersion() == 24;
2588 bool isAdreno5xxOnAndroidLessThan70 =
2589 IsAndroid() && IsAdreno5xx(functions) && GetAndroidSDKVersion() < 24;
2590
2591 // http://crbug.com/663811
2592 bool isAdreno5xxOnAndroid71 =
2593 IsAndroid() && IsAdreno5xx(functions) && GetAndroidSDKVersion() == 25;
2594
2595 // http://crbug.com/594016
2596 bool isLinuxVivante = IsLinux() && IsVivante(device);
2597
2598 // http://anglebug.com/42266736
2599 bool isWindowsNVIDIA = IsWindows() && IsNvidia(vendor);
2600
2601 // Temporarily disable on all of Android. http://crbug.com/1417485
2602 ANGLE_FEATURE_CONDITION(features, disableMultisampledRenderToTexture,
2603 isAdreno4xxOnAndroidLessThan51 || isAdreno4xxOnAndroid70 ||
2604 isAdreno5xxOnAndroidLessThan70 || isAdreno5xxOnAndroid71 ||
2605 isLinuxVivante || isWindowsNVIDIA);
2606
2607 // http://crbug.com/1181068
2608 ANGLE_FEATURE_CONDITION(features, uploadTextureDataInChunks, IsApple());
2609
2610 // https://crbug.com/1060012
2611 ANGLE_FEATURE_CONDITION(features, emulateImmutableCompressedTexture3D, isQualcomm);
2612
2613 // https://crbug.com/1300575
2614 ANGLE_FEATURE_CONDITION(features, emulateRGB10, functions->standard == STANDARD_GL_DESKTOP);
2615
2616 // https://anglebug.com/42264072
2617 ANGLE_FEATURE_CONDITION(features, alwaysUnbindFramebufferTexture2D,
2618 isNvidia && (IsWindows() || IsLinux()));
2619
2620 // https://anglebug.com/42265877
2621 ANGLE_FEATURE_CONDITION(features, disableTextureClampToBorder, false);
2622
2623 // https://anglebug.com/42265995
2624 ANGLE_FEATURE_CONDITION(features, passHighpToPackUnormSnormBuiltins, isQualcomm);
2625
2626 // https://anglebug.com/42266348
2627 ANGLE_FEATURE_CONDITION(features, emulateClipDistanceState, isQualcomm);
2628
2629 // https://anglebug.com/42266817
2630 ANGLE_FEATURE_CONDITION(features, emulateClipOrigin,
2631 !isMesa && isQualcomm && qualcommVersion < 490 &&
2632 functions->hasGLESExtension("GL_EXT_clip_control"));
2633
2634 // https://anglebug.com/42266740
2635 ANGLE_FEATURE_CONDITION(features, explicitFragmentLocations, isQualcomm);
2636
2637 // Desktop GLSL-only fragment synchronization extensions. These are injected internally by the
2638 // compiler to make pixel local storage coherent.
2639 // https://anglebug.com/40096838
2640 ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderInterlockNV,
2641 functions->isAtLeastGL(gl::Version(4, 3)) &&
2642 functions->hasGLExtension("GL_NV_fragment_shader_interlock"));
2643 ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderOrderingINTEL,
2644 functions->isAtLeastGL(gl::Version(4, 4)) &&
2645 functions->hasGLExtension("GL_INTEL_fragment_shader_ordering"));
2646 ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderInterlockARB,
2647 functions->isAtLeastGL(gl::Version(4, 5)) &&
2648 functions->hasGLExtension("GL_ARB_fragment_shader_interlock"));
2649
2650 // EXT_shader_framebuffer_fetch
2651 ANGLE_FEATURE_CONDITION(features, supportsShaderFramebufferFetchEXT,
2652 functions->hasGLESExtension("GL_EXT_shader_framebuffer_fetch"));
2653
2654 // EXT_shader_framebuffer_fetch_non_coherent
2655 ANGLE_FEATURE_CONDITION(
2656 features, supportsShaderFramebufferFetchNonCoherentEXT,
2657 functions->hasGLESExtension("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2658
2659 // https://crbug.com/1356053
2660 ANGLE_FEATURE_CONDITION(features, bindCompleteFramebufferForTimerQueries, isMali);
2661
2662 // https://crbug.com/40264674
2663 ANGLE_FEATURE_CONDITION(features, disableClipControl, IsMaliG72OrG76OrG51(functions));
2664
2665 // https://anglebug.com/42266811
2666 ANGLE_FEATURE_CONDITION(features, resyncDepthRangeOnClipControl, !isMesa && isQualcomm);
2667
2668 // https://anglebug.com/42266745
2669 ANGLE_FEATURE_CONDITION(features, disableRenderSnorm,
2670 isMesa && (mesaVersion < (std::array<int, 3>{21, 3, 0}) ||
2671 (mesaVersion < (std::array<int, 3>{23, 3, 0}) &&
2672 functions->standard == STANDARD_GL_ES)));
2673
2674 // https://anglebug.com/42266748
2675 ANGLE_FEATURE_CONDITION(features, disableTextureMirrorClampToEdge,
2676 functions->standard == STANDARD_GL_ES && isMesa &&
2677 mesaVersion < (std::array<int, 3>{23, 1, 7}));
2678
2679 // http://anglebug.com/42266610
2680 ANGLE_FEATURE_CONDITION(features, disableBaseInstanceVertex, IsMaliValhall(functions));
2681
2682 // Mali: http://crbug.com/40063287
2683 // Nvidia: http://crbug.com/328015191
2684 ANGLE_FEATURE_CONDITION(features, scalarizeVecAndMatConstructorArgs, isMali || isNvidia);
2685
2686 // http://crbug.com/40066076
2687 ANGLE_FEATURE_CONDITION(features, ensureNonEmptyBufferIsBoundForDraw, IsApple() || IsAndroid());
2688
2689 // https://anglebug.com/42266857
2690 ANGLE_FEATURE_CONDITION(features, preTransformTextureCubeGradDerivatives, isApple);
2691
2692 // https://crbug.com/40279678
2693 ANGLE_FEATURE_CONDITION(features, useIntermediateTextureForGenerateMipmap,
2694 IsPixel7OrPixel8(functions));
2695
2696 // SRGB blending does not appear to work correctly on the Nexus 5 + other QC devices. Writing to
2697 // an SRGB framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same
2698 // value. Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
2699 ANGLE_FEATURE_CONDITION(features, srgbBlendingBroken, IsQualcomm(vendor));
2700
2701 // BGRA formats do not appear to be accepted by the qualcomm driver despite the extension being
2702 // exposed.
2703 ANGLE_FEATURE_CONDITION(features, bgraTexImageFormatsBroken, IsQualcomm(vendor));
2704
2705 // https://github.com/flutter/flutter/issues/47164
2706 // https://github.com/flutter/flutter/issues/47804
2707 // Some devices expose the QCOM tiled memory extension string but don't actually provide the
2708 // start and end tiling functions.
2709 bool missingTilingEntryPoints = functions->hasGLESExtension("GL_QCOM_tiled_rendering") &&
2710 (!functions->startTilingQCOM || !functions->endTilingQCOM);
2711
2712 // http://skbug.com/9491: Nexus5 produces rendering artifacts when we use QCOM_tiled_rendering.
2713 ANGLE_FEATURE_CONDITION(features, disableTiledRendering,
2714 missingTilingEntryPoints || IsAdreno3xx(functions));
2715
2716 // Intel desktop GL drivers fail many Skia blend tests.
2717 // Block on older Qualcomm and ARM, following Skia's blocklists.
2718 ANGLE_FEATURE_CONDITION(
2719 features, disableBlendEquationAdvanced,
2720 (isIntel && IsWindows()) || IsAdreno4xx(functions) || IsAdreno5xx(functions) || isMali);
2721 }
2722
InitializeFrontendFeatures(const FunctionsGL * functions,angle::FrontendFeatures * features)2723 void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
2724 {
2725 VendorID vendor = GetVendorID(functions);
2726 bool isQualcomm = IsQualcomm(vendor);
2727
2728 std::array<int, 3> mesaVersion = {0, 0, 0};
2729 bool isMesa = IsMesa(functions, &mesaVersion);
2730
2731 ANGLE_FEATURE_CONDITION(features, disableProgramCachingForTransformFeedback,
2732 !isMesa && isQualcomm);
2733 // https://crbug.com/480992
2734 // Disable shader program cache to workaround PowerVR Rogue issues.
2735 ANGLE_FEATURE_CONDITION(features, disableProgramBinary, IsPowerVrRogue(functions));
2736
2737 // The compile and link jobs need a context, and previous experiments showed setting up temp
2738 // contexts in threads for the sake of program link triggers too many driver bugs. See
2739 // https://chromium-review.googlesource.com/c/angle/angle/+/4774785 for context.
2740 //
2741 // As a result, the compile and link jobs are done in the same thread as the call. If the
2742 // native driver supports parallel compile/link, it's still done internally by the driver, and
2743 // ANGLE supports delaying post-compile and post-link operations until that is done.
2744 ANGLE_FEATURE_CONDITION(features, compileJobIsThreadSafe, false);
2745 ANGLE_FEATURE_CONDITION(features, linkJobIsThreadSafe, false);
2746
2747 ANGLE_FEATURE_CONDITION(features, cacheCompiledShader, true);
2748 }
2749
ReInitializeFeaturesAtGPUSwitch(const FunctionsGL * functions,angle::FeaturesGL * features)2750 void ReInitializeFeaturesAtGPUSwitch(const FunctionsGL *functions, angle::FeaturesGL *features)
2751 {
2752 angle::VendorID vendor;
2753 angle::DeviceID device;
2754 angle::SystemInfo systemInfo;
2755
2756 GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);
2757
2758 // http://crbug.com/1144207
2759 // The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
2760 // now.
2761 // We need to reinitialize this feature when switching between buggy and non-buggy GPUs.
2762 ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithOffset,
2763 IsApple() && IsIntel(vendor) && !IsHaswell(device));
2764 }
2765
2766 } // namespace nativegl_gl
2767
2768 namespace nativegl
2769 {
2770
SupportsVertexArrayObjects(const FunctionsGL * functions)2771 bool SupportsVertexArrayObjects(const FunctionsGL *functions)
2772 {
2773 return functions->isAtLeastGLES(gl::Version(3, 0)) ||
2774 functions->hasGLESExtension("GL_OES_vertex_array_object") ||
2775 functions->isAtLeastGL(gl::Version(3, 0)) ||
2776 functions->hasGLExtension("GL_ARB_vertex_array_object");
2777 }
2778
CanUseDefaultVertexArrayObject(const FunctionsGL * functions)2779 bool CanUseDefaultVertexArrayObject(const FunctionsGL *functions)
2780 {
2781 return (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0;
2782 }
2783
CanUseClientSideArrays(const FunctionsGL * functions,GLuint vao)2784 bool CanUseClientSideArrays(const FunctionsGL *functions, GLuint vao)
2785 {
2786 // Can use client arrays on GLES or GL compatability profile only on the default VAO
2787 return CanUseDefaultVertexArrayObject(functions) && vao == 0;
2788 }
2789
SupportsCompute(const FunctionsGL * functions)2790 bool SupportsCompute(const FunctionsGL *functions)
2791 {
2792 // OpenGL 4.2 is required for GL_ARB_compute_shader, some platform drivers have the extension,
2793 // but their maximum supported GL versions are less than 4.2. Explicitly limit the minimum
2794 // GL version to 4.2.
2795 return (functions->isAtLeastGL(gl::Version(4, 3)) ||
2796 functions->isAtLeastGLES(gl::Version(3, 1)) ||
2797 (functions->isAtLeastGL(gl::Version(4, 2)) &&
2798 functions->hasGLExtension("GL_ARB_compute_shader") &&
2799 functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")));
2800 }
2801
SupportsFenceSync(const FunctionsGL * functions)2802 bool SupportsFenceSync(const FunctionsGL *functions)
2803 {
2804 return functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
2805 functions->isAtLeastGLES(gl::Version(3, 0));
2806 }
2807
SupportsOcclusionQueries(const FunctionsGL * functions)2808 bool SupportsOcclusionQueries(const FunctionsGL *functions)
2809 {
2810 return functions->isAtLeastGL(gl::Version(1, 5)) ||
2811 functions->hasGLExtension("GL_ARB_occlusion_query2") ||
2812 functions->isAtLeastGLES(gl::Version(3, 0)) ||
2813 functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
2814 }
2815
SupportsNativeRendering(const FunctionsGL * functions,gl::TextureType type,GLenum internalFormat)2816 bool SupportsNativeRendering(const FunctionsGL *functions,
2817 gl::TextureType type,
2818 GLenum internalFormat)
2819 {
2820 // Some desktop drivers allow rendering to formats that are not required by the spec, this is
2821 // exposed through the GL_FRAMEBUFFER_RENDERABLE query.
2822 bool hasInternalFormatQuery = functions->isAtLeastGL(gl::Version(4, 3)) ||
2823 functions->hasGLExtension("GL_ARB_internalformat_query2");
2824
2825 // Some Intel drivers have a bug that returns GL_FULL_SUPPORT when asked if they support
2826 // rendering to compressed texture formats yet return framebuffer incomplete when attempting to
2827 // render to the format. Skip any native queries for compressed formats.
2828 const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
2829
2830 if (hasInternalFormatQuery && !internalFormatInfo.compressed)
2831 {
2832 GLint framebufferRenderable = GL_NONE;
2833 functions->getInternalformativ(ToGLenum(type), internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
2834 &framebufferRenderable);
2835 return framebufferRenderable != GL_NONE;
2836 }
2837 else
2838 {
2839 const nativegl::InternalFormat &nativeInfo =
2840 nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
2841 return nativegl_gl::MeetsRequirements(functions, nativeInfo.textureAttachment);
2842 }
2843 }
2844
SupportsTexImage(gl::TextureType type)2845 bool SupportsTexImage(gl::TextureType type)
2846 {
2847 switch (type)
2848 {
2849 // Multi-sample texture types only support TexStorage data upload
2850 case gl::TextureType::_2DMultisample:
2851 case gl::TextureType::_2DMultisampleArray:
2852 return false;
2853
2854 default:
2855 return true;
2856 }
2857 }
2858
UseTexImage2D(gl::TextureType textureType)2859 bool UseTexImage2D(gl::TextureType textureType)
2860 {
2861 return textureType == gl::TextureType::_2D || textureType == gl::TextureType::CubeMap ||
2862 textureType == gl::TextureType::Rectangle ||
2863 textureType == gl::TextureType::_2DMultisample ||
2864 textureType == gl::TextureType::External || textureType == gl::TextureType::VideoImage;
2865 }
2866
UseTexImage3D(gl::TextureType textureType)2867 bool UseTexImage3D(gl::TextureType textureType)
2868 {
2869 return textureType == gl::TextureType::_2DArray || textureType == gl::TextureType::_3D ||
2870 textureType == gl::TextureType::_2DMultisampleArray ||
2871 textureType == gl::TextureType::CubeMapArray;
2872 }
2873
GetTextureBindingQuery(gl::TextureType textureType)2874 GLenum GetTextureBindingQuery(gl::TextureType textureType)
2875 {
2876 switch (textureType)
2877 {
2878 case gl::TextureType::_2D:
2879 return GL_TEXTURE_BINDING_2D;
2880 case gl::TextureType::_2DArray:
2881 return GL_TEXTURE_BINDING_2D_ARRAY;
2882 case gl::TextureType::_2DMultisample:
2883 return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
2884 case gl::TextureType::_2DMultisampleArray:
2885 return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
2886 case gl::TextureType::_3D:
2887 return GL_TEXTURE_BINDING_3D;
2888 case gl::TextureType::External:
2889 return GL_TEXTURE_BINDING_EXTERNAL_OES;
2890 case gl::TextureType::Rectangle:
2891 return GL_TEXTURE_BINDING_RECTANGLE;
2892 case gl::TextureType::CubeMap:
2893 return GL_TEXTURE_BINDING_CUBE_MAP;
2894 case gl::TextureType::CubeMapArray:
2895 return GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES;
2896 case gl::TextureType::Buffer:
2897 return GL_TEXTURE_BINDING_BUFFER;
2898 default:
2899 UNREACHABLE();
2900 return 0;
2901 }
2902 }
2903
GetTextureBindingTarget(gl::TextureType textureType)2904 GLenum GetTextureBindingTarget(gl::TextureType textureType)
2905 {
2906 return ToGLenum(GetNativeTextureType(textureType));
2907 }
2908
GetTextureBindingTarget(gl::TextureTarget textureTarget)2909 GLenum GetTextureBindingTarget(gl::TextureTarget textureTarget)
2910 {
2911 return ToGLenum(GetNativeTextureTarget(textureTarget));
2912 }
2913
GetBufferBindingQuery(gl::BufferBinding bufferBinding)2914 GLenum GetBufferBindingQuery(gl::BufferBinding bufferBinding)
2915 {
2916 switch (bufferBinding)
2917 {
2918 case gl::BufferBinding::Array:
2919 return GL_ARRAY_BUFFER_BINDING;
2920 case gl::BufferBinding::AtomicCounter:
2921 return GL_ATOMIC_COUNTER_BUFFER_BINDING;
2922 case gl::BufferBinding::CopyRead:
2923 return GL_COPY_READ_BUFFER_BINDING;
2924 case gl::BufferBinding::CopyWrite:
2925 return GL_COPY_WRITE_BUFFER_BINDING;
2926 case gl::BufferBinding::DispatchIndirect:
2927 return GL_DISPATCH_INDIRECT_BUFFER_BINDING;
2928 case gl::BufferBinding::DrawIndirect:
2929 return GL_DRAW_INDIRECT_BUFFER_BINDING;
2930 case gl::BufferBinding::ElementArray:
2931 return GL_ELEMENT_ARRAY_BUFFER_BINDING;
2932 case gl::BufferBinding::PixelPack:
2933 return GL_PIXEL_PACK_BUFFER_BINDING;
2934 case gl::BufferBinding::PixelUnpack:
2935 return GL_PIXEL_UNPACK_BUFFER_BINDING;
2936 case gl::BufferBinding::ShaderStorage:
2937 return GL_SHADER_STORAGE_BUFFER_BINDING;
2938 case gl::BufferBinding::TransformFeedback:
2939 return GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
2940 case gl::BufferBinding::Uniform:
2941 return GL_UNIFORM_BUFFER_BINDING;
2942 case gl::BufferBinding::Texture:
2943 return GL_TEXTURE_BUFFER_BINDING;
2944 default:
2945 UNREACHABLE();
2946 return 0;
2947 }
2948 }
2949
GetBufferBindingString(gl::BufferBinding bufferBinding)2950 std::string GetBufferBindingString(gl::BufferBinding bufferBinding)
2951 {
2952 std::ostringstream os;
2953 os << bufferBinding << "_BINDING";
2954 return os.str();
2955 }
2956
GetNativeTextureType(gl::TextureType type)2957 gl::TextureType GetNativeTextureType(gl::TextureType type)
2958 {
2959 // VideoImage texture type is a WebGL type. It doesn't have
2960 // directly mapping type in native OpenGL/OpenGLES.
2961 // Actually, it will be translated to different texture type
2962 // (TEXTURE2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE)
2963 // based on OS and other conditions.
2964 // This will introduce problem that binding VideoImage may
2965 // unbind native image implicitly. Please make sure state
2966 // manager is aware of this implicit unbind behaviour.
2967 if (type != gl::TextureType::VideoImage)
2968 {
2969 return type;
2970 }
2971
2972 // TODO(http://anglebug.com/42262534): need to figure out rectangle texture and
2973 // external image when these backend are implemented.
2974 return gl::TextureType::_2D;
2975 }
2976
GetNativeTextureTarget(gl::TextureTarget target)2977 gl::TextureTarget GetNativeTextureTarget(gl::TextureTarget target)
2978 {
2979 // VideoImage texture type is a WebGL type. It doesn't have
2980 // directly mapping type in native OpenGL/OpenGLES.
2981 // Actually, it will be translated to different texture target
2982 // (TEXTURE2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE)
2983 // based on OS and other conditions.
2984 // This will introduce problem that binding VideoImage may
2985 // unbind native image implicitly. Please make sure state
2986 // manager is aware of this implicit unbind behaviour.
2987 if (target != gl::TextureTarget::VideoImage)
2988 {
2989 return target;
2990 }
2991
2992 // TODO(http://anglebug.com/42262534): need to figure out rectangle texture and
2993 // external image when these backend are implemented.
2994 return gl::TextureTarget::_2D;
2995 }
2996
2997 } // namespace nativegl
2998
GetFunctionsGL(const gl::Context * context)2999 const FunctionsGL *GetFunctionsGL(const gl::Context *context)
3000 {
3001 return GetImplAs<ContextGL>(context)->getFunctions();
3002 }
3003
GetStateManagerGL(const gl::Context * context)3004 StateManagerGL *GetStateManagerGL(const gl::Context *context)
3005 {
3006 return GetImplAs<ContextGL>(context)->getStateManager();
3007 }
3008
GetBlitGL(const gl::Context * context)3009 BlitGL *GetBlitGL(const gl::Context *context)
3010 {
3011 return GetImplAs<ContextGL>(context)->getBlitter();
3012 }
3013
GetMultiviewClearer(const gl::Context * context)3014 ClearMultiviewGL *GetMultiviewClearer(const gl::Context *context)
3015 {
3016 return GetImplAs<ContextGL>(context)->getMultiviewClearer();
3017 }
3018
GetFeaturesGL(const gl::Context * context)3019 const angle::FeaturesGL &GetFeaturesGL(const gl::Context *context)
3020 {
3021 return GetImplAs<ContextGL>(context)->getFeaturesGL();
3022 }
3023
ClearErrors(const FunctionsGL * functions,const char * file,const char * function,unsigned int line)3024 void ClearErrors(const FunctionsGL *functions,
3025 const char *file,
3026 const char *function,
3027 unsigned int line)
3028 {
3029 GLenum error = functions->getError();
3030 while (error != GL_NO_ERROR)
3031 {
3032 INFO() << "Preexisting GL error " << gl::FmtHex(error) << " as of " << file << ", "
3033 << function << ":" << line << ". ";
3034
3035 // Skip GL_CONTEXT_LOST errors, they will be generated continuously and result in an
3036 // infinite loop.
3037 if (error == GL_CONTEXT_LOST)
3038 {
3039 return;
3040 }
3041
3042 error = functions->getError();
3043 }
3044 }
3045
ClearErrors(const gl::Context * context,const char * file,const char * function,unsigned int line)3046 void ClearErrors(const gl::Context *context,
3047 const char *file,
3048 const char *function,
3049 unsigned int line)
3050 {
3051 const FunctionsGL *functions = GetFunctionsGL(context);
3052 ClearErrors(functions, file, function, line);
3053 }
3054
CheckError(const gl::Context * context,const char * call,const char * file,const char * function,unsigned int line)3055 angle::Result CheckError(const gl::Context *context,
3056 const char *call,
3057 const char *file,
3058 const char *function,
3059 unsigned int line)
3060 {
3061 return HandleError(context, GetFunctionsGL(context)->getError(), call, file, function, line);
3062 }
3063
HandleError(const gl::Context * context,GLenum error,const char * call,const char * file,const char * function,unsigned int line)3064 angle::Result HandleError(const gl::Context *context,
3065 GLenum error,
3066 const char *call,
3067 const char *file,
3068 const char *function,
3069 unsigned int line)
3070 {
3071 const FunctionsGL *functions = GetFunctionsGL(context);
3072 if (ANGLE_UNLIKELY(error != GL_NO_ERROR))
3073 {
3074 ContextGL *contextGL = GetImplAs<ContextGL>(context);
3075 contextGL->handleError(error, "Unexpected driver error.", file, function, line);
3076 ERR() << "GL call " << call << " generated error " << gl::FmtHex(error) << " in " << file
3077 << ", " << function << ":" << line << ". ";
3078
3079 // Check that only one GL error was generated, ClearErrors should have been called first.
3080 // Skip GL_CONTEXT_LOST errors, they will be generated continuously and result in an
3081 // infinite loop.
3082 GLenum nextError = functions->getError();
3083 while (nextError != GL_NO_ERROR && nextError != GL_CONTEXT_LOST)
3084 {
3085 ERR() << "Additional GL error " << gl::FmtHex(nextError) << " generated.";
3086 nextError = functions->getError();
3087 }
3088
3089 return angle::Result::Stop;
3090 }
3091
3092 return angle::Result::Continue;
3093 }
3094
CanMapBufferForRead(const FunctionsGL * functions)3095 bool CanMapBufferForRead(const FunctionsGL *functions)
3096 {
3097 return (functions->mapBufferRange != nullptr) ||
3098 (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP);
3099 }
3100
MapBufferRangeWithFallback(const FunctionsGL * functions,GLenum target,size_t offset,size_t length,GLbitfield access)3101 uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
3102 GLenum target,
3103 size_t offset,
3104 size_t length,
3105 GLbitfield access)
3106 {
3107 if (functions->mapBufferRange != nullptr)
3108 {
3109 return static_cast<uint8_t *>(functions->mapBufferRange(target, offset, length, access));
3110 }
3111 else if (functions->mapBuffer != nullptr &&
3112 (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT))
3113 {
3114 // Only the read and write bits are supported
3115 ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0);
3116
3117 GLenum accessEnum = 0;
3118 if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
3119 {
3120 accessEnum = GL_READ_WRITE;
3121 }
3122 else if (access == GL_MAP_READ_BIT)
3123 {
3124 accessEnum = GL_READ_ONLY;
3125 }
3126 else if (access == GL_MAP_WRITE_BIT)
3127 {
3128 accessEnum = GL_WRITE_ONLY;
3129 }
3130 else
3131 {
3132 UNREACHABLE();
3133 return nullptr;
3134 }
3135
3136 return static_cast<uint8_t *>(functions->mapBuffer(target, accessEnum)) + offset;
3137 }
3138 else
3139 {
3140 // No options available
3141 UNREACHABLE();
3142 return nullptr;
3143 }
3144 }
3145
ShouldApplyLastRowPaddingWorkaround(ContextGL * contextGL,const gl::Extents & size,const gl::PixelStoreStateBase & state,const gl::Buffer * pixelBuffer,GLenum format,GLenum type,bool is3D,const void * pixels,bool * shouldApplyOut)3146 angle::Result ShouldApplyLastRowPaddingWorkaround(ContextGL *contextGL,
3147 const gl::Extents &size,
3148 const gl::PixelStoreStateBase &state,
3149 const gl::Buffer *pixelBuffer,
3150 GLenum format,
3151 GLenum type,
3152 bool is3D,
3153 const void *pixels,
3154 bool *shouldApplyOut)
3155 {
3156 if (pixelBuffer == nullptr)
3157 {
3158 *shouldApplyOut = false;
3159 return angle::Result::Continue;
3160 }
3161
3162 // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
3163 // last byte read or written. If it is past the end of the buffer, we will need to use the
3164 // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.
3165
3166 const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
3167 GLuint endByte = 0;
3168 ANGLE_CHECK_GL_MATH(contextGL,
3169 glFormat.computePackUnpackEndByte(type, size, state, is3D, &endByte));
3170 GLuint rowPitch = 0;
3171 ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, size.width, state.alignment,
3172 state.rowLength, &rowPitch));
3173
3174 CheckedNumeric<size_t> checkedPixelBytes = glFormat.computePixelBytes(type);
3175 CheckedNumeric<size_t> checkedEndByte =
3176 angle::CheckedNumeric<size_t>(endByte) + reinterpret_cast<intptr_t>(pixels);
3177
3178 // At this point checkedEndByte is the actual last byte read.
3179 // The driver adds an extra row padding (if any), mimic it.
3180 ANGLE_CHECK_GL_MATH(contextGL, checkedPixelBytes.IsValid());
3181 if (static_cast<size_t>(checkedPixelBytes.ValueOrDie()) * size.width < rowPitch)
3182 {
3183 checkedEndByte += rowPitch - checkedPixelBytes * size.width;
3184 }
3185
3186 ANGLE_CHECK_GL_MATH(contextGL, checkedEndByte.IsValid());
3187
3188 *shouldApplyOut = checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
3189 return angle::Result::Continue;
3190 }
3191
GenerateContextCreationToTry(EGLint requestedType,bool isMesaGLX)3192 std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
3193 {
3194 using Type = ContextCreationTry::Type;
3195 constexpr EGLint kPlatformOpenGL = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
3196 constexpr EGLint kPlatformOpenGLES = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
3197
3198 std::vector<ContextCreationTry> contextsToTry;
3199
3200 if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE || requestedType == kPlatformOpenGL)
3201 {
3202 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 5));
3203 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 4));
3204 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 3));
3205 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 2));
3206 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 1));
3207 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 0));
3208 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 3));
3209 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 2));
3210 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 3));
3211
3212 // On Mesa, do not try to create OpenGL context versions between 3.0 and
3213 // 3.2 because of compatibility problems. See crbug.com/659030
3214 if (!isMesaGLX)
3215 {
3216 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 2));
3217 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 1));
3218 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 0));
3219 }
3220
3221 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 1));
3222 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 0));
3223 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 5));
3224 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 4));
3225 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 3));
3226 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 2));
3227 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 1));
3228 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 0));
3229 }
3230
3231 if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE ||
3232 requestedType == kPlatformOpenGLES)
3233 {
3234 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 2));
3235 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 1));
3236 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 0));
3237 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(2, 0));
3238 }
3239
3240 return contextsToTry;
3241 }
3242
GetRendererString(const FunctionsGL * functions)3243 std::string GetRendererString(const FunctionsGL *functions)
3244 {
3245 return GetString(functions, GL_RENDERER);
3246 }
3247
GetVendorString(const FunctionsGL * functions)3248 std::string GetVendorString(const FunctionsGL *functions)
3249 {
3250 return GetString(functions, GL_VENDOR);
3251 }
3252
GetVersionString(const FunctionsGL * functions)3253 std::string GetVersionString(const FunctionsGL *functions)
3254 {
3255 return GetString(functions, GL_VERSION);
3256 }
3257
3258 } // namespace rx
3259