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