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