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