• 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 "libANGLE/Buffer.h"
18 #include "libANGLE/Caps.h"
19 #include "libANGLE/Context.h"
20 #include "libANGLE/formatutils.h"
21 #include "libANGLE/queryconversions.h"
22 #include "libANGLE/renderer/gl/ContextGL.h"
23 #include "libANGLE/renderer/gl/FenceNVGL.h"
24 #include "libANGLE/renderer/gl/FunctionsGL.h"
25 #include "libANGLE/renderer/gl/QueryGL.h"
26 #include "libANGLE/renderer/gl/formatutilsgl.h"
27 #include "platform/FeaturesGL.h"
28 #include "platform/FrontendFeatures.h"
29 
30 #include <EGL/eglext.h>
31 #include <algorithm>
32 #include <sstream>
33 
34 using angle::CheckedNumeric;
35 
36 namespace rx
37 {
38 
GetVendorID(const FunctionsGL * functions)39 VendorID GetVendorID(const FunctionsGL *functions)
40 {
41     std::string nativeVendorString(reinterpret_cast<const char *>(functions->getString(GL_VENDOR)));
42     // Concatenate GL_RENDERER to the string being checked because some vendors put their names in
43     // GL_RENDERER
44     nativeVendorString +=
45         " " + std::string(reinterpret_cast<const char *>(functions->getString(GL_RENDERER)));
46     if (nativeVendorString.find("NVIDIA") != std::string::npos)
47     {
48         return VENDOR_ID_NVIDIA;
49     }
50     else if (nativeVendorString.find("ATI") != std::string::npos ||
51              nativeVendorString.find("AMD") != std::string::npos)
52     {
53         return VENDOR_ID_AMD;
54     }
55     else if (nativeVendorString.find("Qualcomm") != std::string::npos)
56     {
57         return VENDOR_ID_QUALCOMM;
58     }
59     else if (nativeVendorString.find("Intel") != std::string::npos)
60     {
61         return VENDOR_ID_INTEL;
62     }
63     else
64     {
65         return VENDOR_ID_UNKNOWN;
66     }
67 }
68 
GetDeviceID(const FunctionsGL * functions)69 uint32_t GetDeviceID(const FunctionsGL *functions)
70 {
71     std::string nativeRendererString(
72         reinterpret_cast<const char *>(functions->getString(GL_RENDERER)));
73     constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
74         {"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
75         {"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
76         {"Adreno (TM) 540", ANDROID_DEVICE_ID_PIXEL2},
77     };
78 
79     for (const auto &knownDeviceID : kKnownDeviceIDs)
80     {
81         if (nativeRendererString.find(knownDeviceID.first) != std::string::npos)
82         {
83             return knownDeviceID.second;
84         }
85     }
86 
87     return 0;
88 }
89 
IsMesa(const FunctionsGL * functions,std::array<int,3> * version)90 bool IsMesa(const FunctionsGL *functions, std::array<int, 3> *version)
91 {
92     ASSERT(version);
93 
94     if (functions->standard != STANDARD_GL_DESKTOP)
95     {
96         return false;
97     }
98 
99     std::string nativeVersionString(
100         reinterpret_cast<const char *>(functions->getString(GL_VERSION)));
101     size_t pos = nativeVersionString.find("Mesa");
102     if (pos == std::string::npos)
103     {
104         return false;
105     }
106 
107     int *data = version->data();
108     data[0] = data[1] = data[2] = 0;
109     std::sscanf(nativeVersionString.c_str() + pos, "Mesa %d.%d.%d", data, data + 1, data + 2);
110 
111     return true;
112 }
113 
114 namespace nativegl_gl
115 {
116 
MeetsRequirements(const FunctionsGL * functions,const nativegl::SupportRequirement & requirements)117 static bool MeetsRequirements(const FunctionsGL *functions,
118                               const nativegl::SupportRequirement &requirements)
119 {
120     bool hasRequiredExtensions = false;
121     for (const std::vector<std::string> &exts : requirements.requiredExtensions)
122     {
123         bool hasAllExtensionsInSet = true;
124         for (const std::string &extension : exts)
125         {
126             if (!functions->hasExtension(extension))
127             {
128                 hasAllExtensionsInSet = false;
129                 break;
130             }
131         }
132         if (hasAllExtensionsInSet)
133         {
134             hasRequiredExtensions = true;
135             break;
136         }
137     }
138     if (!requirements.requiredExtensions.empty() && !hasRequiredExtensions)
139     {
140         return false;
141     }
142 
143     if (functions->version >= requirements.version)
144     {
145         return true;
146     }
147     else if (!requirements.versionExtensions.empty())
148     {
149         for (const std::string &extension : requirements.versionExtensions)
150         {
151             if (!functions->hasExtension(extension))
152             {
153                 return false;
154             }
155         }
156         return true;
157     }
158     else
159     {
160         return false;
161     }
162 }
163 
CheckSizedInternalFormatTextureRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)164 static bool CheckSizedInternalFormatTextureRenderability(const FunctionsGL *functions,
165                                                          const angle::FeaturesGL &features,
166                                                          GLenum internalFormat)
167 {
168     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
169     ASSERT(formatInfo.sized);
170 
171     // Query the current texture so it can be rebound afterwards
172     GLint oldTextureBinding = 0;
173     functions->getIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding);
174 
175     // Create a small texture with the same format and type that gl::Texture would use
176     GLuint texture = 0;
177     functions->genTextures(1, &texture);
178     functions->bindTexture(GL_TEXTURE_2D, texture);
179 
180     // Nearest filter needed for framebuffer completeness on some drivers.
181     functions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
182 
183     nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
184         functions, features, formatInfo.internalFormat, formatInfo.format, formatInfo.type);
185     constexpr GLsizei kTextureSize = 16;
186     functions->texImage2D(GL_TEXTURE_2D, 0, texImageFormat.internalFormat, kTextureSize,
187                           kTextureSize, 0, texImageFormat.format, texImageFormat.type, nullptr);
188 
189     // Query the current framebuffer so it can be rebound afterwards
190     GLint oldFramebufferBinding = 0;
191     functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
192 
193     // Bind the texture to the framebuffer and check renderability
194     GLuint fbo = 0;
195     functions->genFramebuffers(1, &fbo);
196     functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
197     functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
198                                     0);
199 
200     bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
201 
202     // Delete the framebuffer and restore the previous binding
203     functions->deleteFramebuffers(1, &fbo);
204     functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
205 
206     // Delete the texture and restore the previous binding
207     functions->deleteTextures(1, &texture);
208     functions->bindTexture(GL_TEXTURE_2D, static_cast<GLuint>(oldTextureBinding));
209 
210     return supported;
211 }
212 
CheckInternalFormatRenderbufferRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)213 static bool CheckInternalFormatRenderbufferRenderability(const FunctionsGL *functions,
214                                                          const angle::FeaturesGL &features,
215                                                          GLenum internalFormat)
216 {
217     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
218     ASSERT(formatInfo.sized);
219 
220     // Query the current renderbuffer so it can be rebound afterwards
221     GLint oldRenderbufferBinding = 0;
222     functions->getIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderbufferBinding);
223 
224     // Create a small renderbuffer with the same format and type that gl::Renderbuffer would use
225     GLuint renderbuffer = 0;
226     functions->genRenderbuffers(1, &renderbuffer);
227     functions->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
228 
229     nativegl::RenderbufferFormat renderbufferFormat =
230         nativegl::GetRenderbufferFormat(functions, features, formatInfo.internalFormat);
231     constexpr GLsizei kRenderbufferSize = 16;
232     functions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
233                                    kRenderbufferSize, kRenderbufferSize);
234 
235     // Query the current framebuffer so it can be rebound afterwards
236     GLint oldFramebufferBinding = 0;
237     functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
238 
239     // Bind the texture to the framebuffer and check renderability
240     GLuint fbo = 0;
241     functions->genFramebuffers(1, &fbo);
242     functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
243     functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
244                                        renderbuffer);
245 
246     bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
247 
248     // Delete the framebuffer and restore the previous binding
249     functions->deleteFramebuffers(1, &fbo);
250     functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
251 
252     // Delete the renderbuffer and restore the previous binding
253     functions->deleteRenderbuffers(1, &renderbuffer);
254     functions->bindRenderbuffer(GL_RENDERBUFFER, static_cast<GLuint>(oldRenderbufferBinding));
255 
256     return supported;
257 }
258 
LimitVersion(gl::Version * curVersion,const gl::Version & maxVersion)259 static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
260 {
261     if (*curVersion >= maxVersion)
262     {
263         *curVersion = maxVersion;
264     }
265 }
266 
GenerateTextureFormatCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat,gl::Version * maxSupportedESVersion)267 static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
268                                                  const angle::FeaturesGL &features,
269                                                  GLenum internalFormat,
270                                                  gl::Version *maxSupportedESVersion)
271 {
272     ASSERT(functions->getError() == GL_NO_ERROR);
273 
274     gl::TextureCaps textureCaps;
275 
276     const nativegl::InternalFormat &formatInfo =
277         nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
278     textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture);
279     textureCaps.filterable =
280         textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter);
281     textureCaps.textureAttachment = MeetsRequirements(functions, formatInfo.textureAttachment);
282     textureCaps.renderbuffer      = MeetsRequirements(functions, formatInfo.renderbuffer);
283     textureCaps.blendable         = textureCaps.renderbuffer || textureCaps.textureAttachment;
284 
285     // Do extra renderability validation for some formats.
286     // We require GL_RGBA16F is renderable to expose EXT_color_buffer_half_float but we can't know
287     // if the format is supported unless we try to create a framebuffer.
288     if (internalFormat == GL_RGBA16F)
289     {
290         if (textureCaps.textureAttachment)
291         {
292             textureCaps.textureAttachment =
293                 CheckSizedInternalFormatTextureRenderability(functions, features, internalFormat);
294         }
295         if (textureCaps.renderbuffer)
296         {
297             textureCaps.renderbuffer =
298                 CheckInternalFormatRenderbufferRenderability(functions, features, internalFormat);
299         }
300     }
301 
302     // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
303     // extension GL_ARB_internalformat_query
304     if (textureCaps.renderbuffer && functions->getInternalformativ)
305     {
306         GLenum queryInternalFormat = internalFormat;
307 
308         if (internalFormat == GL_BGRA8_EXT)
309         {
310             // Querying GL_NUM_SAMPLE_COUNTS for GL_BGRA8_EXT generates an INVALID_ENUM on some
311             // drivers.  It seems however that allocating a multisampled renderbuffer of this format
312             // succeeds. To avoid breaking multisampling for this format, query the supported sample
313             // counts for GL_RGBA8 instead.
314             queryInternalFormat = GL_RGBA8;
315         }
316 
317         GLint numSamples = 0;
318         functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_NUM_SAMPLE_COUNTS,
319                                        1, &numSamples);
320 
321         if (numSamples > 0)
322         {
323             std::vector<GLint> samples(numSamples);
324             functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_SAMPLES,
325                                            static_cast<GLsizei>(samples.size()), &samples[0]);
326 
327             if (internalFormat == GL_STENCIL_INDEX8)
328             {
329                 // The query below does generates an error with STENCIL_INDEX8 on NVIDIA driver
330                 // 382.33. So for now we assume that the same sampling modes are conformant for
331                 // STENCIL_INDEX8 as for DEPTH24_STENCIL8. Clean this up once the driver is fixed.
332                 // http://anglebug.com/2059
333                 queryInternalFormat = GL_DEPTH24_STENCIL8;
334             }
335             for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
336             {
337                 if (features.limitMaxMSAASamplesTo4.enabled && samples[sampleIndex] > 4)
338                 {
339                     continue;
340                 }
341 
342                 // Some NVIDIA drivers expose multisampling modes implemented as a combination of
343                 // multisampling and supersampling. These are non-conformant and should not be
344                 // exposed through ANGLE. Query which formats are conformant from the driver if
345                 // supported.
346                 GLint conformant = GL_TRUE;
347                 if (functions->getInternalformatSampleivNV)
348                 {
349                     ASSERT(functions->getError() == GL_NO_ERROR);
350                     functions->getInternalformatSampleivNV(GL_RENDERBUFFER, queryInternalFormat,
351                                                            samples[sampleIndex], GL_CONFORMANT_NV,
352                                                            1, &conformant);
353                     // getInternalFormatSampleivNV does not work for all formats on NVIDIA Shield TV
354                     // drivers. Assume that formats with large sample counts are non-conformant in
355                     // case the query generates an error.
356                     if (functions->getError() != GL_NO_ERROR)
357                     {
358                         conformant = (samples[sampleIndex] <= 8) ? GL_TRUE : GL_FALSE;
359                     }
360                 }
361                 if (conformant == GL_TRUE)
362                 {
363                     textureCaps.sampleCounts.insert(samples[sampleIndex]);
364                 }
365             }
366         }
367     }
368 
369     // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers in these
370     // required formats with up to the value of MAX_SAMPLES multisamples, with the exception of
371     // signed and unsigned integer formats."
372     const gl::InternalFormat &glFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
373     if (textureCaps.renderbuffer && !glFormatInfo.isInt() &&
374         glFormatInfo.isRequiredRenderbufferFormat(gl::Version(3, 0)) &&
375         textureCaps.getMaxSamples() < 4)
376     {
377         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
378     }
379 
380     ASSERT(functions->getError() == GL_NO_ERROR);
381     return textureCaps;
382 }
383 
QuerySingleGLInt(const FunctionsGL * functions,GLenum name)384 static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
385 {
386     GLint result = 0;
387     functions->getIntegerv(name, &result);
388     return result;
389 }
390 
QuerySingleIndexGLInt(const FunctionsGL * functions,GLenum name,GLuint index)391 static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index)
392 {
393     GLint result;
394     functions->getIntegeri_v(name, index, &result);
395     return result;
396 }
397 
QueryGLIntRange(const FunctionsGL * functions,GLenum name,size_t index)398 static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
399 {
400     GLint result[2] = {};
401     functions->getIntegerv(name, result);
402     return result[index];
403 }
404 
QuerySingleGLInt64(const FunctionsGL * functions,GLenum name)405 static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
406 {
407     // Fall back to 32-bit int if 64-bit query is not available. This can become relevant for some
408     // caps that are defined as 64-bit values in core spec, but were introduced earlier in
409     // extensions as 32-bit. Triggered in some cases by RenderDoc's emulated OpenGL driver.
410     if (!functions->getInteger64v)
411     {
412         GLint result = 0;
413         functions->getIntegerv(name, &result);
414         return static_cast<GLint64>(result);
415     }
416     else
417     {
418         GLint64 result = 0;
419         functions->getInteger64v(name, &result);
420         return result;
421     }
422 }
423 
QuerySingleGLFloat(const FunctionsGL * functions,GLenum name)424 static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
425 {
426     GLfloat result = 0.0f;
427     functions->getFloatv(name, &result);
428     return result;
429 }
430 
QueryGLFloatRange(const FunctionsGL * functions,GLenum name,size_t index)431 static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
432 {
433     GLfloat result[2] = {};
434     functions->getFloatv(name, result);
435     return result[index];
436 }
437 
QueryTypePrecision(const FunctionsGL * functions,GLenum shaderType,GLenum precisionType)438 static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions,
439                                             GLenum shaderType,
440                                             GLenum precisionType)
441 {
442     gl::TypePrecision precision;
443     functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range.data(),
444                                         &precision.precision);
445     return precision;
446 }
447 
QueryQueryValue(const FunctionsGL * functions,GLenum target,GLenum name)448 static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name)
449 {
450     GLint result;
451     functions->getQueryiv(target, name, &result);
452     return result;
453 }
454 
CapCombinedLimitToESShaders(GLint * combinedLimit,gl::ShaderMap<GLint> & perShaderLimit)455 void CapCombinedLimitToESShaders(GLint *combinedLimit, gl::ShaderMap<GLint> &perShaderLimit)
456 {
457     GLint combinedESLimit = 0;
458     for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
459     {
460         combinedESLimit += perShaderLimit[shaderType];
461     }
462 
463     *combinedLimit = std::min(*combinedLimit, combinedESLimit);
464 }
465 
GenerateCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,gl::Caps * caps,gl::TextureCapsMap * textureCapsMap,gl::Extensions * extensions,gl::Version * maxSupportedESVersion,MultiviewImplementationTypeGL * multiviewImplementationType)466 void GenerateCaps(const FunctionsGL *functions,
467                   const angle::FeaturesGL &features,
468                   gl::Caps *caps,
469                   gl::TextureCapsMap *textureCapsMap,
470                   gl::Extensions *extensions,
471                   gl::Version *maxSupportedESVersion,
472                   MultiviewImplementationTypeGL *multiviewImplementationType)
473 {
474     // Start by assuming ES3.1 support and work down
475     *maxSupportedESVersion = gl::Version(3, 1);
476 
477     // Texture format support checks
478     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
479     for (GLenum internalFormat : allFormats)
480     {
481         gl::TextureCaps textureCaps =
482             GenerateTextureFormatCaps(functions, features, internalFormat, maxSupportedESVersion);
483         textureCapsMap->insert(internalFormat, textureCaps);
484 
485         if (gl::GetSizedInternalFormatInfo(internalFormat).compressed)
486         {
487             caps->compressedTextureFormats.push_back(internalFormat);
488         }
489     }
490 
491     // Table 6.28, implementation dependent values
492     if (functions->isAtLeastGL(gl::Version(4, 3)) ||
493         functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
494         functions->isAtLeastGLES(gl::Version(3, 0)))
495     {
496         caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
497 
498         // Work around the null driver limitations.
499         if (caps->maxElementIndex == 0)
500         {
501             caps->maxElementIndex = 0xFFFF;
502         }
503     }
504     else
505     {
506         // Doesn't affect ES3 support, can use a pre-defined limit
507         caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
508     }
509 
510     GLint textureSizeLimit = std::numeric_limits<GLint>::max();
511     if (features.limitMaxTextureSizeTo4096.enabled)
512     {
513         textureSizeLimit = 4096;
514     }
515 
516     GLint max3dArrayTextureSizeLimit = std::numeric_limits<GLint>::max();
517     if (features.limitMax3dArrayTextureSizeTo1024.enabled)
518     {
519         max3dArrayTextureSizeLimit = 1024;
520     }
521 
522     if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
523         functions->hasGLESExtension("GL_OES_texture_3D"))
524     {
525         caps->max3DTextureSize = std::min({QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE),
526                                            textureSizeLimit, max3dArrayTextureSizeLimit});
527     }
528     else
529     {
530         // Can't support ES3 without 3D textures
531         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
532     }
533 
534     caps->max2DTextureSize = std::min(QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE),
535                                       textureSizeLimit);  // GL 1.0 / ES 2.0
536     caps->maxCubeMapTextureSize =
537         std::min(QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE),
538                  textureSizeLimit);  // GL 1.3 / ES 2.0
539 
540     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
541         functions->hasGLExtension("GL_EXT_texture_array") ||
542         functions->isAtLeastGLES(gl::Version(3, 0)))
543     {
544         caps->maxArrayTextureLayers =
545             std::min({QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS), textureSizeLimit,
546                       max3dArrayTextureSizeLimit});
547     }
548     else
549     {
550         // Can't support ES3 without array textures
551         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
552     }
553 
554     if (functions->isAtLeastGL(gl::Version(1, 5)) ||
555         functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
556         functions->isAtLeastGLES(gl::Version(3, 0)))
557     {
558         caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
559     }
560     else
561     {
562         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
563     }
564 
565     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
566         functions->hasGLExtension("GL_EXT_framebuffer_object") ||
567         functions->isAtLeastGLES(gl::Version(2, 0)))
568     {
569         caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
570         caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
571     }
572     else
573     {
574         // Can't support ES2 without framebuffers and renderbuffers
575         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
576     }
577 
578     if (functions->isAtLeastGL(gl::Version(2, 0)) ||
579         functions->hasGLExtension("ARB_draw_buffers") ||
580         functions->isAtLeastGLES(gl::Version(3, 0)) ||
581         functions->hasGLESExtension("GL_EXT_draw_buffers"))
582     {
583         caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
584     }
585     else
586     {
587         // Framebuffer is required to have at least one drawbuffer even if the extension is not
588         // supported
589         caps->maxDrawBuffers = 1;
590         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
591     }
592 
593     caps->maxViewportWidth =
594         QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0);  // GL 1.0 / ES 2.0
595     caps->maxViewportHeight =
596         QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1);  // GL 1.0 / ES 2.0
597 
598     if (functions->standard == STANDARD_GL_DESKTOP &&
599         (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
600     {
601         // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query.  Use
602         // GL_POINT_SIZE_RANGE instead.
603         caps->minAliasedPointSize =
604             std::max(1.0f, QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0));
605         caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1);
606     }
607     else
608     {
609         caps->minAliasedPointSize =
610             std::max(1.0f, QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0));
611         caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
612     }
613 
614     caps->minAliasedLineWidth =
615         QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0);  // GL 1.2 / ES 2.0
616     caps->maxAliasedLineWidth =
617         QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1);  // GL 1.2 / ES 2.0
618 
619     // Table 6.29, implementation dependent values (cont.)
620     if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
621     {
622         caps->maxElementsIndices  = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
623         caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
624     }
625     else
626     {
627         // Doesn't impact supported version
628     }
629 
630     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
631         functions->hasGLExtension("GL_ARB_get_program_binary") ||
632         functions->isAtLeastGLES(gl::Version(3, 0)) ||
633         functions->hasGLESExtension("GL_OES_get_program_binary"))
634     {
635         // Able to support the GL_PROGRAM_BINARY_ANGLE format as long as another program binary
636         // format is available.
637         GLint numBinaryFormats = QuerySingleGLInt(functions, GL_NUM_PROGRAM_BINARY_FORMATS_OES);
638         if (numBinaryFormats > 0)
639         {
640             caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
641         }
642     }
643     else
644     {
645         // Doesn't impact supported version
646     }
647 
648     // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or
649     // GL_ARB_ES2_compatibility exists
650     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
651         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
652         functions->isAtLeastGLES(gl::Version(2, 0)))
653     {
654         caps->vertexHighpFloat   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
655         caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
656         caps->vertexLowpFloat    = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
657         caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
658         caps->fragmentMediumpFloat =
659             QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
660         caps->fragmentLowpFloat  = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
661         caps->vertexHighpInt     = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
662         caps->vertexMediumpInt   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
663         caps->vertexLowpInt      = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
664         caps->fragmentHighpInt   = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
665         caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
666         caps->fragmentLowpInt    = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);
667     }
668     else
669     {
670         // Doesn't impact supported version, set some default values
671         caps->vertexHighpFloat.setIEEEFloat();
672         caps->vertexMediumpFloat.setIEEEFloat();
673         caps->vertexLowpFloat.setIEEEFloat();
674         caps->fragmentHighpFloat.setIEEEFloat();
675         caps->fragmentMediumpFloat.setIEEEFloat();
676         caps->fragmentLowpFloat.setIEEEFloat();
677         caps->vertexHighpInt.setTwosComplementInt(32);
678         caps->vertexMediumpInt.setTwosComplementInt(32);
679         caps->vertexLowpInt.setTwosComplementInt(32);
680         caps->fragmentHighpInt.setTwosComplementInt(32);
681         caps->fragmentMediumpInt.setTwosComplementInt(32);
682         caps->fragmentLowpInt.setTwosComplementInt(32);
683     }
684 
685     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
686         functions->isAtLeastGLES(gl::Version(3, 0)))
687     {
688         // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is returned.
689         caps->maxServerWaitTimeout =
690             std::max<GLint64>(QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT), 0);
691     }
692     else
693     {
694         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
695     }
696 
697     // Table 6.31, implementation dependent vertex shader limits
698     if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
699     {
700         caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
701         caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
702             QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
703         caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
704             QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
705     }
706     else
707     {
708         // Can't support ES2 version without these caps
709         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
710     }
711 
712     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
713         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
714         functions->isAtLeastGLES(gl::Version(2, 0)))
715     {
716         caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
717         caps->maxFragmentUniformVectors =
718             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
719     }
720     else
721     {
722         // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
723         caps->maxVertexUniformVectors =
724             caps->maxShaderUniformComponents[gl::ShaderType::Vertex] / 4;
725         // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
726         caps->maxFragmentUniformVectors =
727             caps->maxShaderUniformComponents[gl::ShaderType::Fragment] / 4;
728     }
729 
730     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
731     {
732         caps->maxVertexOutputComponents =
733             QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
734     }
735     else
736     {
737         // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
738         // safe limit instead of limiting the supported ES version.
739         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
740     }
741 
742     // Table 6.32, implementation dependent fragment shader limits
743     if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
744     {
745         caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
746             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
747         caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
748             QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
749     }
750     else
751     {
752         // Can't support ES2 version without these caps
753         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
754     }
755 
756     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
757     {
758         caps->maxFragmentInputComponents =
759             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
760     }
761     else
762     {
763         // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
764         // safe limit instead of limiting the supported ES version.
765         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
766     }
767 
768     if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)))
769     {
770         caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
771         caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
772     }
773     else
774     {
775         // Can't support ES3 without texel offset, could possibly be emulated in the shader
776         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
777     }
778 
779     // Table 6.33, implementation dependent aggregate shader limits
780     if (functions->isAtLeastGL(gl::Version(3, 1)) ||
781         functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
782         functions->isAtLeastGLES(gl::Version(3, 0)))
783     {
784         caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
785             QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
786         caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
787             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
788         caps->maxUniformBufferBindings =
789             QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
790         caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
791         caps->uniformBufferOffsetAlignment =
792             QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
793         caps->maxCombinedUniformBlocks =
794             QuerySingleGLInt(functions, GL_MAX_COMBINED_UNIFORM_BLOCKS);
795         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] =
796             QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
797         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] =
798             QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
799     }
800     else
801     {
802         // Can't support ES3 without uniform blocks
803         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
804     }
805 
806     if (functions->isAtLeastGL(gl::Version(3, 2)) &&
807         (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
808     {
809         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
810     }
811     else if (functions->isAtLeastGL(gl::Version(3, 0)) ||
812              functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
813              functions->isAtLeastGLES(gl::Version(2, 0)))
814     {
815         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
816     }
817     else if (functions->isAtLeastGL(gl::Version(2, 0)))
818     {
819         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS);
820         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
821     }
822     else
823     {
824         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
825     }
826 
827     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
828         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
829         functions->isAtLeastGLES(gl::Version(2, 0)))
830     {
831         caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
832     }
833     else
834     {
835         // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
836         caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
837     }
838 
839     // Determine the max combined texture image units by adding the vertex and fragment limits.  If
840     // the real cap is queried, it would contain the limits for shader types that are not available
841     // to ES.
842     caps->maxCombinedTextureImageUnits =
843         QuerySingleGLInt(functions, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
844 
845     // Table 6.34, implementation dependent transform feedback limits
846     if (functions->isAtLeastGL(gl::Version(4, 0)) ||
847         functions->hasGLExtension("GL_ARB_transform_feedback2") ||
848         functions->isAtLeastGLES(gl::Version(3, 0)))
849     {
850         caps->maxTransformFeedbackInterleavedComponents =
851             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
852         caps->maxTransformFeedbackSeparateAttributes =
853             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
854         caps->maxTransformFeedbackSeparateComponents =
855             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
856     }
857     else
858     {
859         // Can't support ES3 without transform feedback
860         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
861     }
862 
863     GLint sampleCountLimit = std::numeric_limits<GLint>::max();
864     if (features.limitMaxMSAASamplesTo4.enabled)
865     {
866         sampleCountLimit = 4;
867     }
868 
869     // Table 6.35, Framebuffer Dependent Values
870     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
871         functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
872         functions->isAtLeastGLES(gl::Version(3, 0)) ||
873         functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
874     {
875         caps->maxSamples = std::min(QuerySingleGLInt(functions, GL_MAX_SAMPLES), sampleCountLimit);
876     }
877     else
878     {
879         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
880     }
881 
882     // Non-constant sampler array indexing is required for OpenGL ES 2 and OpenGL ES after 3.2.
883     // However having it available on OpenGL ES 2 is a specification bug, and using this
884     // indexing in WebGL is undefined. Requiring this feature would break WebGL 1 for some users
885     // so we don't check for it. (it is present with ESSL 100, ESSL >= 320, GLSL >= 400 and
886     // GL_ARB_gpu_shader5)
887 
888     // Check if sampler objects are supported
889     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
890         !functions->hasGLExtension("GL_ARB_sampler_objects") &&
891         !functions->isAtLeastGLES(gl::Version(3, 0)))
892     {
893         // Can't support ES3 without sampler objects
894         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
895     }
896 
897     // Can't support ES3 without texture swizzling
898     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
899         !functions->hasGLExtension("GL_ARB_texture_swizzle") &&
900         !functions->hasGLExtension("GL_EXT_texture_swizzle") &&
901         !functions->isAtLeastGLES(gl::Version(3, 0)))
902     {
903         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
904 
905         // Texture swizzling is required to work around the luminance texture format not being
906         // present in the core profile
907         if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT)
908         {
909             LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
910         }
911     }
912 
913     // Can't support ES3 without the GLSL packing builtins. We have a workaround for all
914     // desktop OpenGL versions starting from 3.3 with the bit packing extension.
915     if (!functions->isAtLeastGL(gl::Version(4, 2)) &&
916         !(functions->isAtLeastGL(gl::Version(3, 2)) &&
917           functions->hasGLExtension("GL_ARB_shader_bit_encoding")) &&
918         !functions->hasGLExtension("GL_ARB_shading_language_packing") &&
919         !functions->isAtLeastGLES(gl::Version(3, 0)))
920     {
921         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
922     }
923 
924     // ES3 needs to support explicit layout location qualifiers, while it might be possible to
925     // fake them in our side, we currently don't support that.
926     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
927         !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
928         !functions->isAtLeastGLES(gl::Version(3, 0)))
929     {
930         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
931     }
932 
933     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
934         functions->hasGLExtension("GL_ARB_framebuffer_no_attachments"))
935     {
936         caps->maxFramebufferWidth  = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
937         caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
938         caps->maxFramebufferSamples =
939             std::min(QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES), sampleCountLimit);
940     }
941     else
942     {
943         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
944     }
945 
946     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
947         functions->hasGLExtension("GL_ARB_texture_multisample"))
948     {
949         caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
950         caps->maxColorTextureSamples =
951             std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
952         caps->maxDepthTextureSamples =
953             std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
954         caps->maxIntegerSamples =
955             std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
956     }
957     else
958     {
959         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
960     }
961 
962     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
963         functions->hasGLExtension("GL_ARB_vertex_attrib_binding"))
964     {
965         caps->maxVertexAttribRelativeOffset =
966             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
967         caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS);
968 
969         // OpenGL 4.3 has no limit on maximum value of stride.
970         // [OpenGL 4.3 (Core Profile) - February 14, 2013] Chapter 10.3.1 Page 298
971         if (features.emulateMaxVertexAttribStride.enabled ||
972             (functions->standard == STANDARD_GL_DESKTOP && functions->version == gl::Version(4, 3)))
973         {
974             caps->maxVertexAttribStride = 2048;
975         }
976         else
977         {
978             caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
979         }
980     }
981     else
982     {
983         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
984     }
985 
986     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
987         functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
988     {
989         caps->maxCombinedShaderOutputResources =
990             QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
991         caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] =
992             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
993         caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
994             QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
995         caps->maxShaderStorageBufferBindings =
996             QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
997         caps->maxShaderStorageBlockSize =
998             QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
999         caps->maxCombinedShaderStorageBlocks =
1000             QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
1001         caps->shaderStorageBufferOffsetAlignment =
1002             QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
1003     }
1004     else
1005     {
1006         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1007     }
1008 
1009     if (nativegl::SupportsCompute(functions))
1010     {
1011         for (GLuint index = 0u; index < 3u; ++index)
1012         {
1013             caps->maxComputeWorkGroupCount[index] =
1014                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);
1015 
1016             caps->maxComputeWorkGroupSize[index] =
1017                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
1018         }
1019         caps->maxComputeWorkGroupInvocations =
1020             QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
1021         caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
1022             QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS);
1023         caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
1024             QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS);
1025         caps->maxComputeSharedMemorySize =
1026             QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
1027         caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
1028             QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
1029         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
1030             QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
1031         caps->maxShaderAtomicCounters[gl::ShaderType::Compute] =
1032             QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS);
1033         caps->maxShaderImageUniforms[gl::ShaderType::Compute] =
1034             QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
1035         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Compute] =
1036             QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS);
1037         caps->maxShaderStorageBlocks[gl::ShaderType::Compute] =
1038             QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS);
1039     }
1040     else
1041     {
1042         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1043     }
1044 
1045     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1046         functions->hasGLExtension("GL_ARB_explicit_uniform_location"))
1047     {
1048         caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS);
1049     }
1050     else
1051     {
1052         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1053     }
1054 
1055     if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1056         functions->hasGLExtension("GL_ARB_texture_gather"))
1057     {
1058         caps->minProgramTextureGatherOffset =
1059             QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET);
1060         caps->maxProgramTextureGatherOffset =
1061             QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET);
1062     }
1063     else
1064     {
1065         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1066     }
1067 
1068     if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1069         functions->hasGLExtension("GL_ARB_shader_image_load_store"))
1070     {
1071         caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
1072             QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS);
1073         caps->maxShaderImageUniforms[gl::ShaderType::Fragment] =
1074             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
1075         caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS);
1076         caps->maxCombinedImageUniforms =
1077             QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS);
1078     }
1079     else
1080     {
1081         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1082     }
1083 
1084     if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1085         functions->hasGLExtension("GL_ARB_shader_atomic_counters"))
1086     {
1087         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
1088             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS);
1089         caps->maxShaderAtomicCounters[gl::ShaderType::Vertex] =
1090             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS);
1091         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
1092             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS);
1093         caps->maxShaderAtomicCounters[gl::ShaderType::Fragment] =
1094             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS);
1095         caps->maxAtomicCounterBufferBindings =
1096             QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
1097         caps->maxAtomicCounterBufferSize =
1098             QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE);
1099         caps->maxCombinedAtomicCounterBuffers =
1100             QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS);
1101         caps->maxCombinedAtomicCounters =
1102             QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS);
1103     }
1104     else
1105     {
1106         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1107     }
1108 
1109     // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time
1110     // if the max uniform vectors is too large.  Artificially limit the maximum until the test is
1111     // updated.
1112     caps->maxVertexUniformVectors = std::min(1024, caps->maxVertexUniformVectors);
1113     caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
1114         std::min(caps->maxVertexUniformVectors * 4,
1115                  caps->maxShaderUniformComponents[gl::ShaderType::Vertex]);
1116     caps->maxFragmentUniformVectors = std::min(1024, caps->maxFragmentUniformVectors);
1117     caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1118         std::min(caps->maxFragmentUniformVectors * 4,
1119                  caps->maxShaderUniformComponents[gl::ShaderType::Fragment]);
1120 
1121     // If it is not possible to support reading buffer data back, a shadow copy of the buffers must
1122     // be held. This disallows writing to buffers indirectly through transform feedback, thus
1123     // disallowing ES3.
1124     if (!CanMapBufferForRead(functions))
1125     {
1126         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1127     }
1128 
1129     // Extension support
1130     extensions->setTextureExtensionSupport(*textureCapsMap);
1131     extensions->textureCompressionASTCHDRKHR =
1132         extensions->textureCompressionASTCLDRKHR &&
1133         functions->hasExtension("GL_KHR_texture_compression_astc_hdr");
1134     extensions->textureCompressionSliced3dASTCKHR =
1135         (extensions->textureCompressionASTCLDRKHR &&
1136          functions->hasExtension("GL_KHR_texture_compression_astc_sliced_3d")) ||
1137         extensions->textureCompressionASTCHDRKHR;
1138     extensions->elementIndexUintOES = functions->standard == STANDARD_GL_DESKTOP ||
1139                                       functions->isAtLeastGLES(gl::Version(3, 0)) ||
1140                                       functions->hasGLESExtension("GL_OES_element_index_uint");
1141     extensions->getProgramBinaryOES = caps->programBinaryFormats.size() > 0;
1142     extensions->readFormatBGRA      = functions->isAtLeastGL(gl::Version(1, 2)) ||
1143                                  functions->hasGLExtension("GL_EXT_bgra") ||
1144                                  functions->hasGLESExtension("GL_EXT_read_format_bgra");
1145     extensions->pixelBufferObjectNV = functions->isAtLeastGL(gl::Version(2, 1)) ||
1146                                       functions->isAtLeastGLES(gl::Version(3, 0)) ||
1147                                       functions->hasGLExtension("GL_ARB_pixel_buffer_object") ||
1148                                       functions->hasGLExtension("GL_EXT_pixel_buffer_object") ||
1149                                       functions->hasGLESExtension("GL_NV_pixel_buffer_object");
1150     extensions->glSyncARB    = nativegl::SupportsFenceSync(functions);
1151     extensions->mapBufferOES = functions->isAtLeastGL(gl::Version(1, 5)) ||
1152                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
1153                                functions->hasGLESExtension("GL_OES_mapbuffer");
1154     extensions->mapBufferRange = functions->isAtLeastGL(gl::Version(3, 0)) ||
1155                                  functions->hasGLExtension("GL_ARB_map_buffer_range") ||
1156                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1157                                  functions->hasGLESExtension("GL_EXT_map_buffer_range");
1158     extensions->textureNPOTOES = functions->standard == STANDARD_GL_DESKTOP ||
1159                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1160                                  functions->hasGLESExtension("GL_OES_texture_npot");
1161     // TODO(jmadill): Investigate emulating EXT_draw_buffers on ES 3.0's core functionality.
1162     extensions->drawBuffers = functions->isAtLeastGL(gl::Version(2, 0)) ||
1163                               functions->hasGLExtension("ARB_draw_buffers") ||
1164                               functions->hasGLESExtension("GL_EXT_draw_buffers");
1165     extensions->textureStorage = functions->standard == STANDARD_GL_DESKTOP ||
1166                                  functions->hasGLESExtension("GL_EXT_texture_storage");
1167     extensions->textureFilterAnisotropic =
1168         functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") ||
1169         functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic");
1170     extensions->occlusionQueryBoolean = nativegl::SupportsOcclusionQueries(functions);
1171     extensions->maxTextureAnisotropy =
1172         extensions->textureFilterAnisotropic
1173             ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
1174             : 0.0f;
1175     extensions->fenceNV = FenceNVGL::Supported(functions) || FenceNVSyncGL::Supported(functions);
1176     extensions->blendMinMax = functions->isAtLeastGL(gl::Version(1, 5)) ||
1177                               functions->hasGLExtension("GL_EXT_blend_minmax") ||
1178                               functions->isAtLeastGLES(gl::Version(3, 0)) ||
1179                               functions->hasGLESExtension("GL_EXT_blend_minmax");
1180     extensions->framebufferBlit        = (functions->blitFramebuffer != nullptr);
1181     extensions->framebufferMultisample = caps->maxSamples > 0;
1182     extensions->standardDerivativesOES = functions->isAtLeastGL(gl::Version(2, 0)) ||
1183                                          functions->hasGLExtension("GL_ARB_fragment_shader") ||
1184                                          functions->hasGLESExtension("GL_OES_standard_derivatives");
1185     extensions->shaderTextureLOD = functions->isAtLeastGL(gl::Version(3, 0)) ||
1186                                    functions->hasGLExtension("GL_ARB_shader_texture_lod") ||
1187                                    functions->hasGLESExtension("GL_EXT_shader_texture_lod");
1188     extensions->fragDepth = functions->standard == STANDARD_GL_DESKTOP ||
1189                             functions->hasGLESExtension("GL_EXT_frag_depth");
1190 
1191     // Support video texture extension on non Android backends.
1192     // TODO(crbug.com/776222): support Android and Apple devices.
1193     extensions->webglVideoTexture = !IsAndroid() && !IsApple();
1194 
1195     if (functions->hasGLExtension("GL_ARB_shader_viewport_layer_array") ||
1196         functions->hasGLExtension("GL_NV_viewport_array2"))
1197     {
1198         extensions->multiview  = true;
1199         extensions->multiview2 = true;
1200         // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256.
1201         const int maxLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
1202         // GL_MAX_VIEWPORTS is guaranteed to be at least 16.
1203         const int maxViewports = QuerySingleGLInt(functions, GL_MAX_VIEWPORTS);
1204         extensions->maxViews   = static_cast<GLuint>(
1205             std::min(static_cast<int>(gl::IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS),
1206                      std::min(maxLayers, maxViewports)));
1207         *multiviewImplementationType = MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2;
1208     }
1209 
1210     extensions->fboRenderMipmapOES = functions->isAtLeastGL(gl::Version(3, 0)) ||
1211                                      functions->hasGLExtension("GL_EXT_framebuffer_object") ||
1212                                      functions->isAtLeastGLES(gl::Version(3, 0)) ||
1213                                      functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
1214     extensions->textureBorderClampOES =
1215         functions->standard == STANDARD_GL_DESKTOP ||
1216         functions->hasGLESExtension("GL_OES_texture_border_clamp") ||
1217         functions->hasGLESExtension("GL_EXT_texture_border_clamp") ||
1218         functions->hasGLESExtension("GL_NV_texture_border_clamp");
1219     extensions->instancedArraysANGLE = functions->isAtLeastGL(gl::Version(3, 1)) ||
1220                                        (functions->hasGLExtension("GL_ARB_instanced_arrays") &&
1221                                         (functions->hasGLExtension("GL_ARB_draw_instanced") ||
1222                                          functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
1223                                        functions->isAtLeastGLES(gl::Version(3, 0)) ||
1224                                        functions->hasGLESExtension("GL_EXT_instanced_arrays");
1225     extensions->instancedArraysEXT = extensions->instancedArraysANGLE;
1226     extensions->unpackSubimage     = functions->standard == STANDARD_GL_DESKTOP ||
1227                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1228                                  functions->hasGLESExtension("GL_EXT_unpack_subimage");
1229     extensions->noperspectiveInterpolationNV = functions->isAtLeastGL(gl::Version(3, 0));
1230     extensions->packSubimage                 = functions->standard == STANDARD_GL_DESKTOP ||
1231                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
1232                                functions->hasGLESExtension("GL_NV_pack_subimage");
1233     extensions->vertexArrayObjectOES = functions->isAtLeastGL(gl::Version(3, 0)) ||
1234                                        functions->hasGLExtension("GL_ARB_vertex_array_object") ||
1235                                        functions->isAtLeastGLES(gl::Version(3, 0)) ||
1236                                        functions->hasGLESExtension("GL_OES_vertex_array_object");
1237     extensions->debugMarker = functions->isAtLeastGL(gl::Version(4, 3)) ||
1238                               functions->hasGLExtension("GL_KHR_debug") ||
1239                               functions->hasGLExtension("GL_EXT_debug_marker") ||
1240                               functions->isAtLeastGLES(gl::Version(3, 2)) ||
1241                               functions->hasGLESExtension("GL_KHR_debug") ||
1242                               functions->hasGLESExtension("GL_EXT_debug_marker");
1243     extensions->eglImageOES         = functions->hasGLESExtension("GL_OES_EGL_image");
1244     extensions->eglImageExternalOES = functions->hasGLESExtension("GL_OES_EGL_image_external");
1245     extensions->eglImageExternalWrapModesEXT =
1246         functions->hasExtension("GL_EXT_EGL_image_external_wrap_modes");
1247     extensions->eglImageExternalEssl3OES =
1248         functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
1249 
1250     extensions->eglSyncOES = functions->hasGLESExtension("GL_OES_EGL_sync");
1251 
1252     if (functions->isAtLeastGL(gl::Version(3, 3)) ||
1253         functions->hasGLExtension("GL_ARB_timer_query") ||
1254         functions->hasGLESExtension("GL_EXT_disjoint_timer_query"))
1255     {
1256         extensions->disjointTimerQuery = true;
1257 
1258         // If we can't query the counter bits, leave them at 0.
1259         if (!features.queryCounterBitsGeneratesErrors.enabled)
1260         {
1261             extensions->queryCounterBitsTimeElapsed =
1262                 QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
1263             extensions->queryCounterBitsTimestamp =
1264                 QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
1265         }
1266     }
1267 
1268     // the EXT_multisample_compatibility is written against ES3.1 but can apply
1269     // to earlier versions so therefore we're only checking for the extension string
1270     // and not the specific GLES version.
1271     extensions->multisampleCompatibility =
1272         functions->isAtLeastGL(gl::Version(1, 3)) ||
1273         functions->hasGLESExtension("GL_EXT_multisample_compatibility");
1274 
1275     extensions->framebufferMixedSamples =
1276         functions->hasGLExtension("GL_NV_framebuffer_mixed_samples") ||
1277         functions->hasGLESExtension("GL_NV_framebuffer_mixed_samples");
1278 
1279     extensions->robustness = functions->isAtLeastGL(gl::Version(4, 5)) ||
1280                              functions->hasGLExtension("GL_KHR_robustness") ||
1281                              functions->hasGLExtension("GL_ARB_robustness") ||
1282                              functions->isAtLeastGLES(gl::Version(3, 2)) ||
1283                              functions->hasGLESExtension("GL_KHR_robustness") ||
1284                              functions->hasGLESExtension("GL_EXT_robustness");
1285 
1286     extensions->robustBufferAccessBehavior =
1287         extensions->robustness &&
1288         (functions->hasGLExtension("GL_ARB_robust_buffer_access_behavior") ||
1289          functions->hasGLESExtension("GL_KHR_robust_buffer_access_behavior"));
1290 
1291     extensions->copyTexture = true;
1292     extensions->syncQuery   = SyncQueryGL::IsSupported(functions);
1293 
1294     // Note that OES_texture_storage_multisample_2d_array support could be extended down to GL 3.2
1295     // if we emulated texStorage* API on top of texImage*.
1296     extensions->textureStorageMultisample2DArrayOES =
1297         functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 2));
1298 
1299     extensions->multiviewMultisample = extensions->textureStorageMultisample2DArrayOES &&
1300                                        (extensions->multiview || extensions->multiview2);
1301 
1302     extensions->textureMultisample = functions->isAtLeastGL(gl::Version(3, 2)) ||
1303                                      functions->hasGLExtension("GL_ARB_texture_multisample");
1304 
1305     extensions->textureSRGBDecode = functions->hasGLExtension("GL_EXT_texture_sRGB_decode") ||
1306                                     functions->hasGLESExtension("GL_EXT_texture_sRGB_decode");
1307 
1308     // ANGLE treats ETC1 as ETC2 for ES 3.0 and higher because it becomes a core format, and they
1309     // are backwards compatible.
1310     extensions->compressedETC1RGB8SubTexture =
1311         functions->isAtLeastGLES(gl::Version(3, 0)) ||
1312         functions->hasGLESExtension("GL_EXT_compressed_ETC1_RGB8_sub_texture");
1313 
1314 #if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
1315     VendorID vendor = GetVendorID(functions);
1316     if ((IsAMD(vendor) || IsIntel(vendor)) && *maxSupportedESVersion >= gl::Version(3, 0))
1317     {
1318         // Apple Intel/AMD drivers do not correctly use the TEXTURE_SRGB_DECODE property of sampler
1319         // states.  Disable this extension when we would advertise any ES version that has samplers.
1320         extensions->textureSRGBDecode = false;
1321     }
1322 #endif
1323 
1324     extensions->sRGBWriteControl = functions->isAtLeastGL(gl::Version(3, 0)) ||
1325                                    functions->hasGLExtension("GL_EXT_framebuffer_sRGB") ||
1326                                    functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
1327                                    functions->hasGLESExtension("GL_EXT_sRGB_write_control");
1328 
1329 #if defined(ANGLE_PLATFORM_ANDROID)
1330     // SRGB blending does not appear to work correctly on the Nexus 5. Writing to an SRGB
1331     // framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same value.
1332     // Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
1333     extensions->sRGBWriteControl = false;
1334 
1335     // BGRA formats do not appear to be accepted by the Nexus 5X driver dispite the extension being
1336     // exposed.
1337     extensions->textureFormatBGRA8888 = false;
1338 #endif
1339 
1340     // EXT_discard_framebuffer can be implemented as long as glDiscardFramebufferEXT or
1341     // glInvalidateFramebuffer is available
1342     extensions->discardFramebuffer = functions->isAtLeastGL(gl::Version(4, 3)) ||
1343                                      functions->hasGLExtension("GL_ARB_invalidate_subdata") ||
1344                                      functions->isAtLeastGLES(gl::Version(3, 0)) ||
1345                                      functions->hasGLESExtension("GL_EXT_discard_framebuffer") ||
1346                                      functions->hasGLESExtension("GL_ARB_invalidate_subdata");
1347 
1348     extensions->translatedShaderSource = true;
1349 
1350     if (functions->isAtLeastGL(gl::Version(3, 1)) ||
1351         functions->hasGLExtension("GL_ARB_texture_rectangle"))
1352     {
1353         extensions->textureRectangle  = true;
1354         caps->maxRectangleTextureSize = std::min(
1355             QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE), textureSizeLimit);
1356     }
1357 
1358     // OpenGL 4.3 (and above) can support all features and constants defined in
1359     // GL_EXT_geometry_shader.
1360     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1361         functions->hasGLESExtension("GL_OES_geometry_shader") ||
1362         functions->hasGLESExtension("GL_EXT_geometry_shader") ||
1363         // OpenGL 4.0 adds the support for instanced geometry shader
1364         // GL_ARB_shader_atomic_counters adds atomic counters to geometry shader
1365         // GL_ARB_shader_storage_buffer_object adds shader storage buffers to geometry shader
1366         // GL_ARB_shader_image_load_store adds images to geometry shader
1367         (functions->isAtLeastGL(gl::Version(4, 0)) &&
1368          functions->hasGLExtension("GL_ARB_shader_atomic_counters") &&
1369          functions->hasGLExtension("GL_ARB_shader_storage_buffer_object") &&
1370          functions->hasGLExtension("GL_ARB_shader_image_load_store")))
1371     {
1372         extensions->geometryShader = true;
1373 
1374         caps->maxFramebufferLayers = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_LAYERS_EXT);
1375 
1376         // GL_PROVOKING_VERTEX isn't a valid return value of GL_LAYER_PROVOKING_VERTEX_EXT in
1377         // GL_EXT_geometry_shader SPEC, however it is legal in desktop OpenGL, which means the value
1378         // follows the one set by glProvokingVertex.
1379         // [OpenGL 4.3] Chapter 11.3.4.6
1380         // The vertex conventions followed for gl_Layer and gl_ViewportIndex may be determined by
1381         // calling GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and
1382         // VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the value returned is
1383         // PROVOKING_VERTEX, then vertex selection follows the convention specified by
1384         // ProvokingVertex.
1385         caps->layerProvokingVertex = QuerySingleGLInt(functions, GL_LAYER_PROVOKING_VERTEX_EXT);
1386         if (caps->layerProvokingVertex == GL_PROVOKING_VERTEX)
1387         {
1388             // We should use GL_LAST_VERTEX_CONVENTION_EXT instead because desktop OpenGL SPEC
1389             // requires the initial value of provoking vertex mode is LAST_VERTEX_CONVENTION.
1390             // [OpenGL 4.3] Chapter 13.4
1391             // The initial value of the provoking vertex mode is LAST_VERTEX_CONVENTION.
1392             caps->layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1393         }
1394 
1395         caps->maxShaderUniformComponents[gl::ShaderType::Geometry] =
1396             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1397         caps->maxShaderUniformBlocks[gl::ShaderType::Geometry] =
1398             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT);
1399         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Geometry] =
1400             QuerySingleGLInt(functions, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1401         caps->maxGeometryInputComponents =
1402             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT);
1403         caps->maxGeometryOutputComponents =
1404             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT);
1405         caps->maxGeometryOutputVertices =
1406             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT);
1407         caps->maxGeometryTotalOutputComponents =
1408             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT);
1409         caps->maxGeometryShaderInvocations =
1410             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT);
1411         caps->maxShaderTextureImageUnits[gl::ShaderType::Geometry] =
1412             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
1413         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
1414             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT);
1415         caps->maxShaderAtomicCounters[gl::ShaderType::Geometry] =
1416             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT);
1417         caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
1418             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT);
1419         caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
1420             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT);
1421     }
1422 
1423     // The real combined caps contain limits for shader types that are not available to ES, so limit
1424     // the caps to the sum of vertex+fragment+geometry shader caps.
1425     CapCombinedLimitToESShaders(&caps->maxCombinedUniformBlocks, caps->maxShaderUniformBlocks);
1426     CapCombinedLimitToESShaders(&caps->maxCombinedTextureImageUnits,
1427                                 caps->maxShaderTextureImageUnits);
1428     CapCombinedLimitToESShaders(&caps->maxCombinedShaderStorageBlocks,
1429                                 caps->maxShaderStorageBlocks);
1430     CapCombinedLimitToESShaders(&caps->maxCombinedImageUniforms, caps->maxShaderImageUniforms);
1431     CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounterBuffers,
1432                                 caps->maxShaderAtomicCounterBuffers);
1433     CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounters, caps->maxShaderAtomicCounters);
1434 
1435     // EXT_blend_func_extended.
1436     // Note that this could be implemented also on top of native EXT_blend_func_extended, but it's
1437     // currently not fully implemented.
1438     extensions->blendFuncExtended = !features.disableBlendFuncExtended.enabled &&
1439                                     functions->standard == STANDARD_GL_DESKTOP &&
1440                                     functions->hasGLExtension("GL_ARB_blend_func_extended");
1441     if (extensions->blendFuncExtended)
1442     {
1443         // TODO(http://anglebug.com/1085): Support greater values of
1444         // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT queried from the driver. See comments in ProgramGL.cpp
1445         // for more information about this limitation.
1446         extensions->maxDualSourceDrawBuffers = 1;
1447     }
1448 
1449     // EXT_float_blend
1450     // Assume all desktop driver supports this by default.
1451     extensions->floatBlend = functions->standard == STANDARD_GL_DESKTOP ||
1452                              functions->hasGLESExtension("GL_EXT_float_blend");
1453 
1454     // ANGLE_base_vertex_base_instance
1455     extensions->baseVertexBaseInstance =
1456         functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1457         functions->hasGLESExtension("GL_OES_draw_elements_base_vertex") ||
1458         functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex");
1459 
1460     // OES_draw_elements_base_vertex
1461     extensions->drawElementsBaseVertexOES =
1462         functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1463         functions->hasGLESExtension("GL_OES_draw_elements_base_vertex");
1464 
1465     // EXT_draw_elements_base_vertex
1466     extensions->drawElementsBaseVertexEXT =
1467         functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1468         functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex");
1469 
1470     // ANGLE_compressed_texture_etc
1471     // Expose this extension only when we support the formats or we're running on top of a native
1472     // ES driver.
1473     extensions->compressedTextureETC = functions->standard == STANDARD_GL_ES &&
1474                                        gl::DetermineCompressedTextureETCSupport(*textureCapsMap);
1475 
1476     // To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
1477     // if those formats are not available.
1478     if (features.unsizedsRGBReadPixelsDoesntTransform.enabled &&
1479         !functions->isAtLeastGLES(gl::Version(3, 0)))
1480     {
1481         extensions->sRGB = false;
1482     }
1483 
1484     extensions->provokingVertex = functions->hasGLExtension("GL_ARB_provoking_vertex") ||
1485                                   functions->hasGLExtension("GL_EXT_provoking_vertex") ||
1486                                   functions->isAtLeastGL(gl::Version(3, 2));
1487 
1488     extensions->textureExternalUpdateANGLE = true;
1489     extensions->texture3DOES               = functions->isAtLeastGL(gl::Version(1, 2)) ||
1490                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
1491                                functions->hasGLESExtension("GL_OES_texture_3D");
1492 
1493     extensions->memoryObject = functions->hasGLExtension("GL_EXT_memory_object") ||
1494                                functions->hasGLESExtension("GL_EXT_memory_object");
1495     extensions->semaphore = functions->hasGLExtension("GL_EXT_semaphore") ||
1496                             functions->hasGLESExtension("GL_EXT_semaphore");
1497     extensions->memoryObjectFd = functions->hasGLExtension("GL_EXT_memory_object_fd") ||
1498                                  functions->hasGLESExtension("GL_EXT_memory_object_fd");
1499     extensions->semaphoreFd = !features.disableSemaphoreFd.enabled &&
1500                               (functions->hasGLExtension("GL_EXT_semaphore_fd") ||
1501                                functions->hasGLESExtension("GL_EXT_semaphore_fd"));
1502     extensions->gpuShader5EXT = functions->isAtLeastGL(gl::Version(4, 0)) ||
1503                                 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1504                                 functions->hasGLExtension("GL_ARB_gpu_shader5") ||
1505                                 functions->hasGLESExtension("GL_EXT_gpu_shader5");
1506 }
1507 
InitializeFeatures(const FunctionsGL * functions,angle::FeaturesGL * features)1508 void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features)
1509 {
1510     VendorID vendor = GetVendorID(functions);
1511     uint32_t device = GetDeviceID(functions);
1512     bool isAMD      = IsAMD(vendor);
1513     bool isIntel    = IsIntel(vendor);
1514     bool isNvidia   = IsNvidia(vendor);
1515     bool isQualcomm = IsQualcomm(vendor);
1516 
1517     std::array<int, 3> mesaVersion = {0, 0, 0};
1518     bool isMesa                    = IsMesa(functions, &mesaVersion);
1519 
1520     // Don't use 1-bit alpha formats on desktop GL with AMD drivers.
1521     ANGLE_FEATURE_CONDITION(features, avoid1BitAlphaTextureFormats,
1522                             functions->standard == STANDARD_GL_DESKTOP && isAMD);
1523 
1524     ANGLE_FEATURE_CONDITION(features, rgba4IsNotSupportedForColorRendering,
1525                             functions->standard == STANDARD_GL_DESKTOP && isIntel);
1526 
1527     // Ported from gpu_driver_bug_list.json (#183)
1528     ANGLE_FEATURE_CONDITION(features, emulateAbsIntFunction, IsApple() && isIntel);
1529 
1530     ANGLE_FEATURE_CONDITION(features, addAndTrueToLoopCondition, IsApple() && isIntel);
1531 
1532     // Ported from gpu_driver_bug_list.json (#191)
1533     ANGLE_FEATURE_CONDITION(
1534         features, emulateIsnanFloat,
1535         isIntel && IsApple() && IsSkylake(device) && GetMacOSVersion() < OSVersion(10, 13, 2));
1536 
1537     ANGLE_FEATURE_CONDITION(features, doesSRGBClearsOnLinearFramebufferAttachments,
1538                             functions->standard == STANDARD_GL_DESKTOP && (isIntel || isAMD));
1539 
1540     ANGLE_FEATURE_CONDITION(features, emulateMaxVertexAttribStride,
1541                             IsLinux() && functions->standard == STANDARD_GL_DESKTOP && isAMD);
1542     ANGLE_FEATURE_CONDITION(
1543         features, useUnusedBlocksWithStandardOrSharedLayout,
1544         (IsApple() && functions->standard == STANDARD_GL_DESKTOP) || (IsLinux() && isAMD));
1545 
1546     // Ported from gpu_driver_bug_list.json (#187)
1547     ANGLE_FEATURE_CONDITION(features, doWhileGLSLCausesGPUHang,
1548                             IsApple() && functions->standard == STANDARD_GL_DESKTOP &&
1549                                 GetMacOSVersion() < OSVersion(10, 11, 0));
1550 
1551     // Ported from gpu_driver_bug_list.json (#211)
1552     ANGLE_FEATURE_CONDITION(features, rewriteFloatUnaryMinusOperator,
1553                             IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 12, 0));
1554 
1555     ANGLE_FEATURE_CONDITION(features, addBaseVertexToVertexID, IsApple() && isAMD);
1556 
1557     // Triggers a bug on Marshmallow Adreno (4xx?) driver.
1558     // http://anglebug.com/2046
1559     ANGLE_FEATURE_CONDITION(features, dontInitializeUninitializedLocals, IsAndroid() && isQualcomm);
1560 
1561     ANGLE_FEATURE_CONDITION(features, finishDoesNotCauseQueriesToBeAvailable,
1562                             functions->standard == STANDARD_GL_DESKTOP && isNvidia);
1563 
1564     // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
1565     ANGLE_FEATURE_CONDITION(features, alwaysCallUseProgramAfterLink, true);
1566 
1567     ANGLE_FEATURE_CONDITION(features, unpackOverlappingRowsSeparatelyUnpackBuffer, isNvidia);
1568     ANGLE_FEATURE_CONDITION(features, packOverlappingRowsSeparatelyPackBuffer, isNvidia);
1569 
1570     ANGLE_FEATURE_CONDITION(features, initializeCurrentVertexAttributes, isNvidia);
1571 
1572     ANGLE_FEATURE_CONDITION(features, unpackLastRowSeparatelyForPaddingInclusion,
1573                             IsApple() || isNvidia);
1574     ANGLE_FEATURE_CONDITION(features, packLastRowSeparatelyForPaddingInclusion,
1575                             IsApple() || isNvidia);
1576 
1577     ANGLE_FEATURE_CONDITION(features, removeInvariantAndCentroidForESSL3,
1578                             functions->isAtMostGL(gl::Version(4, 1)) ||
1579                                 (functions->standard == STANDARD_GL_DESKTOP && isAMD));
1580 
1581     // TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
1582     // 364 are known to be affected, at least up to 375.
1583     ANGLE_FEATURE_CONDITION(features, emulateAtan2Float, isNvidia);
1584 
1585     ANGLE_FEATURE_CONDITION(features, reapplyUBOBindingsAfterUsingBinaryProgram,
1586                             isAMD || IsAndroid());
1587 
1588     ANGLE_FEATURE_CONDITION(features, rewriteVectorScalarArithmetic, isNvidia);
1589 
1590     // TODO(oetuaho): Make this specific to the affected driver versions. Versions at least up to
1591     // 390 are known to be affected. Versions after that are expected not to be affected.
1592     ANGLE_FEATURE_CONDITION(features, clampFragDepth, isNvidia);
1593 
1594     // TODO(oetuaho): Make this specific to the affected driver versions. Versions since 397.31 are
1595     // not affected.
1596     ANGLE_FEATURE_CONDITION(features, rewriteRepeatedAssignToSwizzled, isNvidia);
1597 
1598     // TODO(jmadill): Narrow workaround range for specific devices.
1599 
1600     ANGLE_FEATURE_CONDITION(features, clampPointSize, IsAndroid() || isNvidia);
1601 
1602     // Ported from gpu_driver_bug_list.json (#246, #258)
1603     ANGLE_FEATURE_CONDITION(features, dontUseLoopsToInitializeVariables,
1604                             (IsAndroid() && isQualcomm) || (isIntel && IsApple()));
1605 
1606     ANGLE_FEATURE_CONDITION(features, disableBlendFuncExtended, isAMD || isIntel);
1607 
1608     ANGLE_FEATURE_CONDITION(features, unsizedsRGBReadPixelsDoesntTransform,
1609                             IsAndroid() && isQualcomm);
1610 
1611     ANGLE_FEATURE_CONDITION(features, queryCounterBitsGeneratesErrors, IsNexus5X(vendor, device));
1612 
1613     ANGLE_FEATURE_CONDITION(features, dontRelinkProgramsInParallel,
1614                             IsAndroid() || (IsWindows() && isIntel));
1615 
1616     // TODO(jie.a.chen@intel.com): Clean up the bugs.
1617     // anglebug.com/3031
1618     // crbug.com/922936
1619     ANGLE_FEATURE_CONDITION(features, disableWorkerContexts,
1620                             (IsWindows() && (isIntel || isAMD)) || (IsLinux() && isNvidia));
1621 
1622     bool limitMaxTextureSize = isIntel && IsLinux() && GetLinuxOSVersion() < OSVersion(5, 0, 0);
1623     ANGLE_FEATURE_CONDITION(features, limitMaxTextureSizeTo4096,
1624                             IsAndroid() || limitMaxTextureSize);
1625     // On Apple switchable graphics, GL_MAX_SAMPLES may differ between the GPUs.
1626     // 4 is a lowest common denominator that is always supported.
1627     ANGLE_FEATURE_CONDITION(features, limitMaxMSAASamplesTo4,
1628                             IsAndroid() || (IsApple() && (isIntel || isAMD || isNvidia)));
1629     ANGLE_FEATURE_CONDITION(features, limitMax3dArrayTextureSizeTo1024, limitMaxTextureSize);
1630 
1631     ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, IsApple());
1632 
1633     // The WebGL conformance/uniforms/out-of-bounds-uniform-array-access test has been seen to fail
1634     // on AMD and Android devices.
1635     // This test is also flaky on Linux Nvidia. So we just turn it on everywhere and don't rely on
1636     // driver since security is important.
1637     ANGLE_FEATURE_CONDITION(
1638         features, clampArrayAccess,
1639         IsAndroid() || isAMD || !functions->hasExtension("GL_KHR_robust_buffer_access_behavior"));
1640 
1641     ANGLE_FEATURE_CONDITION(features, resetTexImage2DBaseLevel,
1642                             IsApple() && isIntel && GetMacOSVersion() >= OSVersion(10, 12, 4));
1643 
1644     ANGLE_FEATURE_CONDITION(features, clearToZeroOrOneBroken,
1645                             IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 12, 6));
1646 
1647     ANGLE_FEATURE_CONDITION(features, adjustSrcDstRegionBlitFramebuffer,
1648                             IsLinux() || (IsAndroid() && isNvidia) || (IsWindows() && isNvidia));
1649 
1650     ANGLE_FEATURE_CONDITION(features, clipSrcRegionBlitFramebuffer,
1651                             IsApple() || (IsLinux() && isAMD));
1652 
1653     ANGLE_FEATURE_CONDITION(features, resettingTexturesGeneratesErrors,
1654                             IsApple() || (IsWindows() && isAMD));
1655 
1656     ANGLE_FEATURE_CONDITION(features, rgbDXT1TexturesSampleZeroAlpha, IsApple());
1657 
1658     ANGLE_FEATURE_CONDITION(features, unfoldShortCircuits, IsApple());
1659 
1660     ANGLE_FEATURE_CONDITION(features, emulatePrimitiveRestartFixedIndex,
1661                             functions->standard == STANDARD_GL_DESKTOP &&
1662                                 functions->isAtLeastGL(gl::Version(3, 1)) &&
1663                                 !functions->isAtLeastGL(gl::Version(4, 3)));
1664     ANGLE_FEATURE_CONDITION(
1665         features, setPrimitiveRestartFixedIndexForDrawArrays,
1666         features->emulatePrimitiveRestartFixedIndex.enabled && IsApple() && isIntel);
1667 
1668     ANGLE_FEATURE_CONDITION(features, removeDynamicIndexingOfSwizzledVector,
1669                             IsApple() || IsAndroid() || IsWindows());
1670 
1671     // Ported from gpu_driver_bug_list.json (#89)
1672     ANGLE_FEATURE_CONDITION(features, regenerateStructNames,
1673                             IsApple() && functions->standard == STANDARD_GL_DESKTOP);
1674 
1675     // Ported from gpu_driver_bug_list.json (#184)
1676     ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, IsApple() && isIntel);
1677 
1678     // Workaround for the widespread OpenGL ES driver implementaion bug
1679     ANGLE_FEATURE_CONDITION(features, readPixelsUsingImplementationColorReadFormatForNorm16,
1680                             functions->standard == STANDARD_GL_ES &&
1681                                 functions->isAtLeastGLES(gl::Version(3, 1)) &&
1682                                 functions->hasGLESExtension("GL_EXT_texture_norm16"));
1683 
1684     // anglebug.com/4267
1685     ANGLE_FEATURE_CONDITION(features, flushBeforeDeleteTextureIfCopiedTo, IsApple() && isIntel);
1686 
1687     // anglebug.com/2273
1688     // Seems to affect both Intel and AMD GPUs. Enable workaround for all GPUs on macOS.
1689     ANGLE_FEATURE_CONDITION(features, rewriteRowMajorMatrices,
1690                             // IsApple() && functions->standard == STANDARD_GL_DESKTOP);
1691                             // TODO(anglebug.com/2273): diagnose crashes with this workaround.
1692                             false);
1693 
1694     // Workaround for incorrect sampling from DXT1 sRGB textures in Intel OpenGL on Windows.
1695     ANGLE_FEATURE_CONDITION(features, avoidDXT1sRGBTextureFormat, IsWindows() && isIntel);
1696 
1697     ANGLE_FEATURE_CONDITION(
1698         features, disableSemaphoreFd,
1699         IsLinux() && isAMD && isMesa && mesaVersion < (std::array<int, 3>{19, 3, 5}));
1700 }
1701 
InitializeFrontendFeatures(const FunctionsGL * functions,angle::FrontendFeatures * features)1702 void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
1703 {
1704     VendorID vendor = GetVendorID(functions);
1705     bool isIntel    = IsIntel(vendor);
1706     bool isQualcomm = IsQualcomm(vendor);
1707 
1708     ANGLE_FEATURE_CONDITION(features, disableProgramCachingForTransformFeedback,
1709                             IsAndroid() && isQualcomm);
1710     ANGLE_FEATURE_CONDITION(features, syncFramebufferBindingsOnTexImage, IsWindows() && isIntel);
1711 }
1712 
1713 }  // namespace nativegl_gl
1714 
1715 namespace nativegl
1716 {
SupportsCompute(const FunctionsGL * functions)1717 bool SupportsCompute(const FunctionsGL *functions)
1718 {
1719     // OpenGL 4.2 is required for GL_ARB_compute_shader, some platform drivers have the extension,
1720     // but their maximum supported GL versions are less than 4.2. Explicitly limit the minimum
1721     // GL version to 4.2.
1722     return (functions->isAtLeastGL(gl::Version(4, 3)) ||
1723             functions->isAtLeastGLES(gl::Version(3, 1)) ||
1724             (functions->isAtLeastGL(gl::Version(4, 2)) &&
1725              functions->hasGLExtension("GL_ARB_compute_shader") &&
1726              functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")));
1727 }
1728 
SupportsFenceSync(const FunctionsGL * functions)1729 bool SupportsFenceSync(const FunctionsGL *functions)
1730 {
1731     return functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
1732            functions->isAtLeastGLES(gl::Version(3, 0));
1733 }
1734 
SupportsOcclusionQueries(const FunctionsGL * functions)1735 bool SupportsOcclusionQueries(const FunctionsGL *functions)
1736 {
1737     return functions->isAtLeastGL(gl::Version(1, 5)) ||
1738            functions->hasGLExtension("GL_ARB_occlusion_query2") ||
1739            functions->isAtLeastGLES(gl::Version(3, 0)) ||
1740            functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
1741 }
1742 
SupportsNativeRendering(const FunctionsGL * functions,gl::TextureType type,GLenum internalFormat)1743 bool SupportsNativeRendering(const FunctionsGL *functions,
1744                              gl::TextureType type,
1745                              GLenum internalFormat)
1746 {
1747     // Some desktop drivers allow rendering to formats that are not required by the spec, this is
1748     // exposed through the GL_FRAMEBUFFER_RENDERABLE query.
1749     bool hasInternalFormatQuery = functions->isAtLeastGL(gl::Version(4, 3)) ||
1750                                   functions->hasGLExtension("GL_ARB_internalformat_query2");
1751 
1752     // Some Intel drivers have a bug that returns GL_FULL_SUPPORT when asked if they support
1753     // rendering to compressed texture formats yet return framebuffer incomplete when attempting to
1754     // render to the format.  Skip any native queries for compressed formats.
1755     const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
1756 
1757     if (hasInternalFormatQuery && !internalFormatInfo.compressed)
1758     {
1759         GLint framebufferRenderable = GL_NONE;
1760         functions->getInternalformativ(ToGLenum(type), internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
1761                                        &framebufferRenderable);
1762         return framebufferRenderable != GL_NONE;
1763     }
1764     else
1765     {
1766         const nativegl::InternalFormat &nativeInfo =
1767             nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
1768         return nativegl_gl::MeetsRequirements(functions, nativeInfo.textureAttachment);
1769     }
1770 }
1771 
SupportsTexImage(gl::TextureType type)1772 bool SupportsTexImage(gl::TextureType type)
1773 {
1774     switch (type)
1775     {
1776             // Multi-sample texture types only support TexStorage data upload
1777         case gl::TextureType::_2DMultisample:
1778         case gl::TextureType::_2DMultisampleArray:
1779             return false;
1780 
1781         default:
1782             return true;
1783     }
1784 }
1785 
UseTexImage2D(gl::TextureType textureType)1786 bool UseTexImage2D(gl::TextureType textureType)
1787 {
1788     return textureType == gl::TextureType::_2D || textureType == gl::TextureType::CubeMap ||
1789            textureType == gl::TextureType::Rectangle ||
1790            textureType == gl::TextureType::_2DMultisample ||
1791            textureType == gl::TextureType::External || textureType == gl::TextureType::VideoImage;
1792 }
1793 
UseTexImage3D(gl::TextureType textureType)1794 bool UseTexImage3D(gl::TextureType textureType)
1795 {
1796     return textureType == gl::TextureType::_2DArray || textureType == gl::TextureType::_3D ||
1797            textureType == gl::TextureType::_2DMultisampleArray;
1798 }
1799 
GetTextureBindingQuery(gl::TextureType textureType)1800 GLenum GetTextureBindingQuery(gl::TextureType textureType)
1801 {
1802     switch (textureType)
1803     {
1804         case gl::TextureType::_2D:
1805             return GL_TEXTURE_BINDING_2D;
1806         case gl::TextureType::_2DArray:
1807             return GL_TEXTURE_BINDING_2D_ARRAY;
1808         case gl::TextureType::_2DMultisample:
1809             return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
1810         case gl::TextureType::_2DMultisampleArray:
1811             return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
1812         case gl::TextureType::_3D:
1813             return GL_TEXTURE_BINDING_3D;
1814         case gl::TextureType::External:
1815             return GL_TEXTURE_BINDING_EXTERNAL_OES;
1816         case gl::TextureType::Rectangle:
1817             return GL_TEXTURE_BINDING_RECTANGLE;
1818         case gl::TextureType::CubeMap:
1819             return GL_TEXTURE_BINDING_CUBE_MAP;
1820         default:
1821             UNREACHABLE();
1822             return 0;
1823     }
1824 }
1825 
GetTextureBindingTarget(gl::TextureType textureType)1826 GLenum GetTextureBindingTarget(gl::TextureType textureType)
1827 {
1828     return ToGLenum(GetNativeTextureType(textureType));
1829 }
1830 
GetTextureBindingTarget(gl::TextureTarget textureTarget)1831 GLenum GetTextureBindingTarget(gl::TextureTarget textureTarget)
1832 {
1833     return ToGLenum(GetNativeTextureTarget(textureTarget));
1834 }
1835 
GetBufferBindingQuery(gl::BufferBinding bufferBinding)1836 GLenum GetBufferBindingQuery(gl::BufferBinding bufferBinding)
1837 {
1838     switch (bufferBinding)
1839     {
1840         case gl::BufferBinding::Array:
1841             return GL_ARRAY_BUFFER_BINDING;
1842         case gl::BufferBinding::AtomicCounter:
1843             return GL_ATOMIC_COUNTER_BUFFER_BINDING;
1844         case gl::BufferBinding::CopyRead:
1845             return GL_COPY_READ_BUFFER_BINDING;
1846         case gl::BufferBinding::CopyWrite:
1847             return GL_COPY_WRITE_BUFFER_BINDING;
1848         case gl::BufferBinding::DispatchIndirect:
1849             return GL_DISPATCH_INDIRECT_BUFFER_BINDING;
1850         case gl::BufferBinding::DrawIndirect:
1851             return GL_DRAW_INDIRECT_BUFFER_BINDING;
1852         case gl::BufferBinding::ElementArray:
1853             return GL_ELEMENT_ARRAY_BUFFER_BINDING;
1854         case gl::BufferBinding::PixelPack:
1855             return GL_PIXEL_PACK_BUFFER_BINDING;
1856         case gl::BufferBinding::PixelUnpack:
1857             return GL_PIXEL_UNPACK_BUFFER_BINDING;
1858         case gl::BufferBinding::ShaderStorage:
1859             return GL_SHADER_STORAGE_BUFFER_BINDING;
1860         case gl::BufferBinding::TransformFeedback:
1861             return GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
1862         case gl::BufferBinding::Uniform:
1863             return GL_UNIFORM_BUFFER_BINDING;
1864         default:
1865             UNREACHABLE();
1866             return 0;
1867     }
1868 }
1869 
GetBufferBindingString(gl::BufferBinding bufferBinding)1870 std::string GetBufferBindingString(gl::BufferBinding bufferBinding)
1871 {
1872     std::ostringstream os;
1873     os << bufferBinding << "_BINDING";
1874     return os.str();
1875 }
1876 
GetNativeTextureType(gl::TextureType type)1877 gl::TextureType GetNativeTextureType(gl::TextureType type)
1878 {
1879     // VideoImage texture type is a WebGL type. It doesn't have
1880     // directly mapping type in native OpenGL/OpenGLES.
1881     // Actually, it will be translated to different texture type
1882     // (TEXTURE2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE)
1883     // based on OS and other conditions.
1884     // This will introduce problem that binding VideoImage may
1885     // unbind native image implicitly. Please make sure state
1886     // manager is aware of this implicit unbind behaviour.
1887     if (type != gl::TextureType::VideoImage)
1888     {
1889         return type;
1890     }
1891 
1892     // TODO(http://anglebug.com/3889): need to figure out rectangle texture and
1893     // external image when these backend are implemented.
1894     return gl::TextureType::_2D;
1895 }
1896 
GetNativeTextureTarget(gl::TextureTarget target)1897 gl::TextureTarget GetNativeTextureTarget(gl::TextureTarget target)
1898 {
1899     // VideoImage texture type is a WebGL type. It doesn't have
1900     // directly mapping type in native OpenGL/OpenGLES.
1901     // Actually, it will be translated to different texture target
1902     // (TEXTURE2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE)
1903     // based on OS and other conditions.
1904     // This will introduce problem that binding VideoImage may
1905     // unbind native image implicitly. Please make sure state
1906     // manager is aware of this implicit unbind behaviour.
1907     if (target != gl::TextureTarget::VideoImage)
1908     {
1909         return target;
1910     }
1911 
1912     // TODO(http://anglebug.com/3889): need to figure out rectangle texture and
1913     // external image when these backend are implemented.
1914     return gl::TextureTarget::_2D;
1915 }
1916 
1917 }  // namespace nativegl
1918 
GetFunctionsGL(const gl::Context * context)1919 const FunctionsGL *GetFunctionsGL(const gl::Context *context)
1920 {
1921     return GetImplAs<ContextGL>(context)->getFunctions();
1922 }
1923 
GetStateManagerGL(const gl::Context * context)1924 StateManagerGL *GetStateManagerGL(const gl::Context *context)
1925 {
1926     return GetImplAs<ContextGL>(context)->getStateManager();
1927 }
1928 
GetBlitGL(const gl::Context * context)1929 BlitGL *GetBlitGL(const gl::Context *context)
1930 {
1931     return GetImplAs<ContextGL>(context)->getBlitter();
1932 }
1933 
GetMultiviewClearer(const gl::Context * context)1934 ClearMultiviewGL *GetMultiviewClearer(const gl::Context *context)
1935 {
1936     return GetImplAs<ContextGL>(context)->getMultiviewClearer();
1937 }
1938 
GetFeaturesGL(const gl::Context * context)1939 const angle::FeaturesGL &GetFeaturesGL(const gl::Context *context)
1940 {
1941     return GetImplAs<ContextGL>(context)->getFeaturesGL();
1942 }
1943 
ClearErrors(const gl::Context * context,const char * file,const char * function,unsigned int line)1944 void ClearErrors(const gl::Context *context,
1945                  const char *file,
1946                  const char *function,
1947                  unsigned int line)
1948 {
1949     const FunctionsGL *functions = GetFunctionsGL(context);
1950 
1951     GLenum error = functions->getError();
1952     while (error != GL_NO_ERROR)
1953     {
1954         ERR() << "Preexisting GL error " << gl::FmtHex(error) << " as of " << file << ", "
1955               << function << ":" << line << ". ";
1956         error = functions->getError();
1957     }
1958 }
1959 
CheckError(const gl::Context * context,const char * call,const char * file,const char * function,unsigned int line)1960 angle::Result CheckError(const gl::Context *context,
1961                          const char *call,
1962                          const char *file,
1963                          const char *function,
1964                          unsigned int line)
1965 {
1966     const FunctionsGL *functions = GetFunctionsGL(context);
1967 
1968     GLenum error = functions->getError();
1969     if (ANGLE_UNLIKELY(error != GL_NO_ERROR))
1970     {
1971         ContextGL *contextGL = GetImplAs<ContextGL>(context);
1972         contextGL->handleError(error, "Unexpected driver error.", file, function, line);
1973         ERR() << "GL call " << call << " generated error " << gl::FmtHex(error) << " in " << file
1974               << ", " << function << ":" << line << ". ";
1975 
1976         // Check that only one GL error was generated, ClearErrors should have been called first.
1977         // Skip GL_CONTEXT_LOST errors, they will be generated continuously and result in an
1978         // infinite loop.
1979         GLenum nextError = functions->getError();
1980         while (nextError != GL_NO_ERROR && nextError != GL_CONTEXT_LOST)
1981         {
1982             ERR() << "Additional GL error " << gl::FmtHex(nextError) << " generated.";
1983             nextError = functions->getError();
1984         }
1985 
1986         return angle::Result::Stop;
1987     }
1988 
1989     return angle::Result::Continue;
1990 }
1991 
CanMapBufferForRead(const FunctionsGL * functions)1992 bool CanMapBufferForRead(const FunctionsGL *functions)
1993 {
1994     return (functions->mapBufferRange != nullptr) ||
1995            (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP);
1996 }
1997 
MapBufferRangeWithFallback(const FunctionsGL * functions,GLenum target,size_t offset,size_t length,GLbitfield access)1998 uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
1999                                     GLenum target,
2000                                     size_t offset,
2001                                     size_t length,
2002                                     GLbitfield access)
2003 {
2004     if (functions->mapBufferRange != nullptr)
2005     {
2006         return static_cast<uint8_t *>(functions->mapBufferRange(target, offset, length, access));
2007     }
2008     else if (functions->mapBuffer != nullptr &&
2009              (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT))
2010     {
2011         // Only the read and write bits are supported
2012         ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0);
2013 
2014         GLenum accessEnum = 0;
2015         if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
2016         {
2017             accessEnum = GL_READ_WRITE;
2018         }
2019         else if (access == GL_MAP_READ_BIT)
2020         {
2021             accessEnum = GL_READ_ONLY;
2022         }
2023         else if (access == GL_MAP_WRITE_BIT)
2024         {
2025             accessEnum = GL_WRITE_ONLY;
2026         }
2027         else
2028         {
2029             UNREACHABLE();
2030             return nullptr;
2031         }
2032 
2033         return static_cast<uint8_t *>(functions->mapBuffer(target, accessEnum)) + offset;
2034     }
2035     else
2036     {
2037         // No options available
2038         UNREACHABLE();
2039         return nullptr;
2040     }
2041 }
2042 
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)2043 angle::Result ShouldApplyLastRowPaddingWorkaround(ContextGL *contextGL,
2044                                                   const gl::Extents &size,
2045                                                   const gl::PixelStoreStateBase &state,
2046                                                   const gl::Buffer *pixelBuffer,
2047                                                   GLenum format,
2048                                                   GLenum type,
2049                                                   bool is3D,
2050                                                   const void *pixels,
2051                                                   bool *shouldApplyOut)
2052 {
2053     if (pixelBuffer == nullptr)
2054     {
2055         *shouldApplyOut = false;
2056         return angle::Result::Continue;
2057     }
2058 
2059     // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
2060     // last byte read or written. If it is past the end of the buffer, we will need to use the
2061     // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.
2062 
2063     const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
2064     GLuint endByte                     = 0;
2065     ANGLE_CHECK_GL_MATH(contextGL,
2066                         glFormat.computePackUnpackEndByte(type, size, state, is3D, &endByte));
2067     GLuint rowPitch = 0;
2068     ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, size.width, state.alignment,
2069                                                             state.rowLength, &rowPitch));
2070 
2071     CheckedNumeric<size_t> checkedPixelBytes = glFormat.computePixelBytes(type);
2072     CheckedNumeric<size_t> checkedEndByte =
2073         angle::CheckedNumeric<size_t>(endByte) + reinterpret_cast<intptr_t>(pixels);
2074 
2075     // At this point checkedEndByte is the actual last byte read.
2076     // The driver adds an extra row padding (if any), mimic it.
2077     ANGLE_CHECK_GL_MATH(contextGL, checkedPixelBytes.IsValid());
2078     if (checkedPixelBytes.ValueOrDie() * size.width < rowPitch)
2079     {
2080         checkedEndByte += rowPitch - checkedPixelBytes * size.width;
2081     }
2082 
2083     ANGLE_CHECK_GL_MATH(contextGL, checkedEndByte.IsValid());
2084 
2085     *shouldApplyOut = checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
2086     return angle::Result::Continue;
2087 }
2088 
GenerateContextCreationToTry(EGLint requestedType,bool isMesaGLX)2089 std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
2090 {
2091     using Type                         = ContextCreationTry::Type;
2092     constexpr EGLint kPlatformOpenGL   = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
2093     constexpr EGLint kPlatformOpenGLES = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
2094 
2095     std::vector<ContextCreationTry> contextsToTry;
2096 
2097     if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE || requestedType == kPlatformOpenGL)
2098     {
2099         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 5));
2100         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 4));
2101         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 3));
2102         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 2));
2103         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 1));
2104         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 0));
2105         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 3));
2106         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 2));
2107         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 3));
2108 
2109         // On Mesa, do not try to create OpenGL context versions between 3.0 and
2110         // 3.2 because of compatibility problems. See crbug.com/659030
2111         if (!isMesaGLX)
2112         {
2113             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 2));
2114             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 1));
2115             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 0));
2116         }
2117 
2118         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 1));
2119         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 0));
2120         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 5));
2121         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 4));
2122         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 3));
2123         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 2));
2124         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 1));
2125         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 0));
2126     }
2127 
2128     if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE ||
2129         requestedType == kPlatformOpenGLES)
2130     {
2131         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 2));
2132         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 1));
2133         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 0));
2134         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(2, 0));
2135     }
2136 
2137     return contextsToTry;
2138 }
2139 }  // namespace rx
2140