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