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