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