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