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 <limits>
13
14 #include "common/mathutil.h"
15 #include "common/platform.h"
16 #include "libANGLE/Buffer.h"
17 #include "libANGLE/Caps.h"
18 #include "libANGLE/Context.h"
19 #include "libANGLE/formatutils.h"
20 #include "libANGLE/queryconversions.h"
21 #include "libANGLE/renderer/gl/ContextGL.h"
22 #include "libANGLE/renderer/gl/FenceNVGL.h"
23 #include "libANGLE/renderer/gl/FunctionsGL.h"
24 #include "libANGLE/renderer/gl/QueryGL.h"
25 #include "libANGLE/renderer/gl/formatutilsgl.h"
26 #include "platform/FeaturesGL.h"
27 #include "platform/FrontendFeatures.h"
28
29 #include <EGL/eglext.h>
30 #include <algorithm>
31 #include <sstream>
32
33 using angle::CheckedNumeric;
34
35 namespace rx
36 {
GetVendorID(const FunctionsGL * functions)37 VendorID GetVendorID(const FunctionsGL *functions)
38 {
39 std::string nativeVendorString(reinterpret_cast<const char *>(functions->getString(GL_VENDOR)));
40 if (nativeVendorString.find("Intel") != std::string::npos)
41 {
42 return VENDOR_ID_INTEL;
43 }
44 else if (nativeVendorString.find("NVIDIA") != std::string::npos)
45 {
46 return VENDOR_ID_NVIDIA;
47 }
48 else if (nativeVendorString.find("ATI") != std::string::npos ||
49 nativeVendorString.find("AMD") != std::string::npos)
50 {
51 return VENDOR_ID_AMD;
52 }
53 else if (nativeVendorString.find("Qualcomm") != std::string::npos)
54 {
55 return VENDOR_ID_QUALCOMM;
56 }
57 else
58 {
59 return VENDOR_ID_UNKNOWN;
60 }
61 }
62
GetDeviceID(const FunctionsGL * functions)63 uint32_t GetDeviceID(const FunctionsGL *functions)
64 {
65 std::string nativeRendererString(
66 reinterpret_cast<const char *>(functions->getString(GL_RENDERER)));
67 constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
68 {"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
69 {"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
70 {"Adreno (TM) 540", ANDROID_DEVICE_ID_PIXEL2},
71 };
72
73 for (const auto &knownDeviceID : kKnownDeviceIDs)
74 {
75 if (nativeRendererString.find(knownDeviceID.first) != std::string::npos)
76 {
77 return knownDeviceID.second;
78 }
79 }
80
81 return 0;
82 }
83
84 namespace nativegl_gl
85 {
86
MeetsRequirements(const FunctionsGL * functions,const nativegl::SupportRequirement & requirements)87 static bool MeetsRequirements(const FunctionsGL *functions,
88 const nativegl::SupportRequirement &requirements)
89 {
90 bool hasRequiredExtensions = false;
91 for (const std::vector<std::string> &exts : requirements.requiredExtensions)
92 {
93 bool hasAllExtensionsInSet = true;
94 for (const std::string &extension : exts)
95 {
96 if (!functions->hasExtension(extension))
97 {
98 hasAllExtensionsInSet = false;
99 break;
100 }
101 }
102 if (hasAllExtensionsInSet)
103 {
104 hasRequiredExtensions = true;
105 break;
106 }
107 }
108 if (!requirements.requiredExtensions.empty() && !hasRequiredExtensions)
109 {
110 return false;
111 }
112
113 if (functions->version >= requirements.version)
114 {
115 return true;
116 }
117 else if (!requirements.versionExtensions.empty())
118 {
119 for (const std::string &extension : requirements.versionExtensions)
120 {
121 if (!functions->hasExtension(extension))
122 {
123 return false;
124 }
125 }
126 return true;
127 }
128 else
129 {
130 return false;
131 }
132 }
133
CheckSizedInternalFormatTextureRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)134 static bool CheckSizedInternalFormatTextureRenderability(const FunctionsGL *functions,
135 const angle::FeaturesGL &features,
136 GLenum internalFormat)
137 {
138 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
139 ASSERT(formatInfo.sized);
140
141 // Query the current texture so it can be rebound afterwards
142 GLint oldTextureBinding = 0;
143 functions->getIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding);
144
145 // Create a small texture with the same format and type that gl::Texture would use
146 GLuint texture = 0;
147 functions->genTextures(1, &texture);
148 functions->bindTexture(GL_TEXTURE_2D, texture);
149
150 // Nearest filter needed for framebuffer completeness on some drivers.
151 functions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
152
153 nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
154 functions, features, formatInfo.internalFormat, formatInfo.format, formatInfo.type);
155 constexpr GLsizei kTextureSize = 16;
156 functions->texImage2D(GL_TEXTURE_2D, 0, texImageFormat.internalFormat, kTextureSize,
157 kTextureSize, 0, texImageFormat.format, texImageFormat.type, nullptr);
158
159 // Query the current framebuffer so it can be rebound afterwards
160 GLint oldFramebufferBinding = 0;
161 functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
162
163 // Bind the texture to the framebuffer and check renderability
164 GLuint fbo = 0;
165 functions->genFramebuffers(1, &fbo);
166 functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
167 functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
168 0);
169
170 bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
171
172 // Delete the framebuffer and restore the previous binding
173 functions->deleteFramebuffers(1, &fbo);
174 functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
175
176 // Delete the texture and restore the previous binding
177 functions->deleteTextures(1, &texture);
178 functions->bindTexture(GL_TEXTURE_2D, static_cast<GLuint>(oldTextureBinding));
179
180 return supported;
181 }
182
CheckInternalFormatRenderbufferRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)183 static bool CheckInternalFormatRenderbufferRenderability(const FunctionsGL *functions,
184 const angle::FeaturesGL &features,
185 GLenum internalFormat)
186 {
187 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
188 ASSERT(formatInfo.sized);
189
190 // Query the current renderbuffer so it can be rebound afterwards
191 GLint oldRenderbufferBinding = 0;
192 functions->getIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderbufferBinding);
193
194 // Create a small renderbuffer with the same format and type that gl::Renderbuffer would use
195 GLuint renderbuffer = 0;
196 functions->genRenderbuffers(1, &renderbuffer);
197 functions->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
198
199 nativegl::RenderbufferFormat renderbufferFormat =
200 nativegl::GetRenderbufferFormat(functions, features, formatInfo.internalFormat);
201 constexpr GLsizei kRenderbufferSize = 16;
202 functions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
203 kRenderbufferSize, kRenderbufferSize);
204
205 // Query the current framebuffer so it can be rebound afterwards
206 GLint oldFramebufferBinding = 0;
207 functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
208
209 // Bind the texture to the framebuffer and check renderability
210 GLuint fbo = 0;
211 functions->genFramebuffers(1, &fbo);
212 functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
213 functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
214 renderbuffer);
215
216 bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
217
218 // Delete the framebuffer and restore the previous binding
219 functions->deleteFramebuffers(1, &fbo);
220 functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
221
222 // Delete the renderbuffer and restore the previous binding
223 functions->deleteRenderbuffers(1, &renderbuffer);
224 functions->bindRenderbuffer(GL_RENDERBUFFER, static_cast<GLuint>(oldRenderbufferBinding));
225
226 return supported;
227 }
228
GenerateTextureFormatCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)229 static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
230 const angle::FeaturesGL &features,
231 GLenum internalFormat)
232 {
233 ASSERT(functions->getError() == GL_NO_ERROR);
234
235 gl::TextureCaps textureCaps;
236
237 const nativegl::InternalFormat &formatInfo =
238 nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
239 textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture);
240 textureCaps.filterable =
241 textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter);
242 textureCaps.textureAttachment = MeetsRequirements(functions, formatInfo.textureAttachment);
243 textureCaps.renderbuffer = MeetsRequirements(functions, formatInfo.renderbuffer);
244
245 // Do extra renderability validation for some formats.
246 // We require GL_RGBA16F is renderable to expose EXT_color_buffer_half_float but we can't know
247 // if the format is supported unless we try to create a framebuffer.
248 if (internalFormat == GL_RGBA16F)
249 {
250 if (textureCaps.textureAttachment)
251 {
252 textureCaps.textureAttachment =
253 CheckSizedInternalFormatTextureRenderability(functions, features, internalFormat);
254 }
255 if (textureCaps.renderbuffer)
256 {
257 textureCaps.renderbuffer =
258 CheckInternalFormatRenderbufferRenderability(functions, features, internalFormat);
259 }
260 }
261
262 // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
263 // extension GL_ARB_internalformat_query
264 if (textureCaps.renderbuffer && functions->getInternalformativ)
265 {
266 GLenum queryInternalFormat = internalFormat;
267
268 if (internalFormat == GL_BGRA8_EXT)
269 {
270 // Querying GL_NUM_SAMPLE_COUNTS for GL_BGRA8_EXT generates an INVALID_ENUM on some
271 // drivers. It seems however that allocating a multisampled renderbuffer of this format
272 // succeeds. To avoid breaking multisampling for this format, query the supported sample
273 // counts for GL_RGBA8 instead.
274 queryInternalFormat = GL_RGBA8;
275 }
276
277 GLint numSamples = 0;
278 functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_NUM_SAMPLE_COUNTS,
279 1, &numSamples);
280
281 if (numSamples > 0)
282 {
283 std::vector<GLint> samples(numSamples);
284 functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_SAMPLES,
285 static_cast<GLsizei>(samples.size()), &samples[0]);
286
287 if (internalFormat == GL_STENCIL_INDEX8)
288 {
289 // The query below does generates an error with STENCIL_INDEX8 on NVIDIA driver
290 // 382.33. So for now we assume that the same sampling modes are conformant for
291 // STENCIL_INDEX8 as for DEPTH24_STENCIL8. Clean this up once the driver is fixed.
292 // http://anglebug.com/2059
293 queryInternalFormat = GL_DEPTH24_STENCIL8;
294 }
295 for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
296 {
297 if (features.limitMaxMSAASamplesTo4.enabled && samples[sampleIndex] > 4)
298 {
299 continue;
300 }
301
302 // Some NVIDIA drivers expose multisampling modes implemented as a combination of
303 // multisampling and supersampling. These are non-conformant and should not be
304 // exposed through ANGLE. Query which formats are conformant from the driver if
305 // supported.
306 GLint conformant = GL_TRUE;
307 if (functions->getInternalformatSampleivNV)
308 {
309 ASSERT(functions->getError() == GL_NO_ERROR);
310 functions->getInternalformatSampleivNV(GL_RENDERBUFFER, queryInternalFormat,
311 samples[sampleIndex], GL_CONFORMANT_NV,
312 1, &conformant);
313 // getInternalFormatSampleivNV does not work for all formats on NVIDIA Shield TV
314 // drivers. Assume that formats with large sample counts are non-conformant in
315 // case the query generates an error.
316 if (functions->getError() != GL_NO_ERROR)
317 {
318 conformant = (samples[sampleIndex] <= 8) ? GL_TRUE : GL_FALSE;
319 }
320 }
321 if (conformant == GL_TRUE)
322 {
323 textureCaps.sampleCounts.insert(samples[sampleIndex]);
324 }
325 }
326 }
327 }
328
329 ASSERT(functions->getError() == GL_NO_ERROR);
330 return textureCaps;
331 }
332
QuerySingleGLInt(const FunctionsGL * functions,GLenum name)333 static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
334 {
335 GLint result = 0;
336 functions->getIntegerv(name, &result);
337 return result;
338 }
339
QuerySingleIndexGLInt(const FunctionsGL * functions,GLenum name,GLuint index)340 static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index)
341 {
342 GLint result;
343 functions->getIntegeri_v(name, index, &result);
344 return result;
345 }
346
QueryGLIntRange(const FunctionsGL * functions,GLenum name,size_t index)347 static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
348 {
349 GLint result[2] = {};
350 functions->getIntegerv(name, result);
351 return result[index];
352 }
353
QuerySingleGLInt64(const FunctionsGL * functions,GLenum name)354 static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
355 {
356 // Fall back to 32-bit int if 64-bit query is not available. This can become relevant for some
357 // caps that are defined as 64-bit values in core spec, but were introduced earlier in
358 // extensions as 32-bit. Triggered in some cases by RenderDoc's emulated OpenGL driver.
359 if (!functions->getInteger64v)
360 {
361 GLint result = 0;
362 functions->getIntegerv(name, &result);
363 return static_cast<GLint64>(result);
364 }
365 else
366 {
367 GLint64 result = 0;
368 functions->getInteger64v(name, &result);
369 return result;
370 }
371 }
372
QuerySingleGLFloat(const FunctionsGL * functions,GLenum name)373 static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
374 {
375 GLfloat result = 0.0f;
376 functions->getFloatv(name, &result);
377 return result;
378 }
379
QueryGLFloatRange(const FunctionsGL * functions,GLenum name,size_t index)380 static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
381 {
382 GLfloat result[2] = {};
383 functions->getFloatv(name, result);
384 return result[index];
385 }
386
QueryTypePrecision(const FunctionsGL * functions,GLenum shaderType,GLenum precisionType)387 static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions,
388 GLenum shaderType,
389 GLenum precisionType)
390 {
391 gl::TypePrecision precision;
392 functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range.data(),
393 &precision.precision);
394 return precision;
395 }
396
QueryQueryValue(const FunctionsGL * functions,GLenum target,GLenum name)397 static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name)
398 {
399 GLint result;
400 functions->getQueryiv(target, name, &result);
401 return result;
402 }
403
LimitVersion(gl::Version * curVersion,const gl::Version & maxVersion)404 static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
405 {
406 if (*curVersion >= maxVersion)
407 {
408 *curVersion = maxVersion;
409 }
410 }
411
CapCombinedLimitToESShaders(GLuint * combinedLimit,gl::ShaderMap<GLuint> & perShaderLimit)412 void CapCombinedLimitToESShaders(GLuint *combinedLimit, gl::ShaderMap<GLuint> &perShaderLimit)
413 {
414 GLuint combinedESLimit = 0;
415 for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
416 {
417 combinedESLimit += perShaderLimit[shaderType];
418 }
419
420 *combinedLimit = std::min(*combinedLimit, combinedESLimit);
421 }
422
GenerateCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,gl::Caps * caps,gl::TextureCapsMap * textureCapsMap,gl::Extensions * extensions,gl::Version * maxSupportedESVersion,MultiviewImplementationTypeGL * multiviewImplementationType)423 void GenerateCaps(const FunctionsGL *functions,
424 const angle::FeaturesGL &features,
425 gl::Caps *caps,
426 gl::TextureCapsMap *textureCapsMap,
427 gl::Extensions *extensions,
428 gl::Version *maxSupportedESVersion,
429 MultiviewImplementationTypeGL *multiviewImplementationType)
430 {
431 // Texture format support checks
432 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
433 for (GLenum internalFormat : allFormats)
434 {
435 gl::TextureCaps textureCaps =
436 GenerateTextureFormatCaps(functions, features, internalFormat);
437 textureCapsMap->insert(internalFormat, textureCaps);
438
439 if (gl::GetSizedInternalFormatInfo(internalFormat).compressed)
440 {
441 caps->compressedTextureFormats.push_back(internalFormat);
442 }
443 }
444
445 // Start by assuming ES3.1 support and work down
446 *maxSupportedESVersion = gl::Version(3, 1);
447
448 // Table 6.28, implementation dependent values
449 if (functions->isAtLeastGL(gl::Version(4, 3)) ||
450 functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
451 functions->isAtLeastGLES(gl::Version(3, 0)))
452 {
453 caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
454
455 // Work around the null driver limitations.
456 if (caps->maxElementIndex == 0)
457 {
458 caps->maxElementIndex = 0xFFFF;
459 }
460 }
461 else
462 {
463 // Doesn't affect ES3 support, can use a pre-defined limit
464 caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
465 }
466
467 GLint textureSizeLimit = std::numeric_limits<GLint>::max();
468 if (features.limitMaxTextureSizeTo4096.enabled)
469 {
470 textureSizeLimit = 4096;
471 }
472
473 GLint max3dArrayTextureSizeLimit = std::numeric_limits<GLint>::max();
474 if (features.limitMax3dArrayTextureSizeTo1024.enabled)
475 {
476 max3dArrayTextureSizeLimit = 1024;
477 }
478
479 if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
480 functions->hasGLESExtension("GL_OES_texture_3D"))
481 {
482 caps->max3DTextureSize = std::min({QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE),
483 textureSizeLimit, max3dArrayTextureSizeLimit});
484 }
485 else
486 {
487 // Can't support ES3 without 3D textures
488 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
489 }
490
491 caps->max2DTextureSize = std::min(QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE),
492 textureSizeLimit); // GL 1.0 / ES 2.0
493 caps->maxCubeMapTextureSize =
494 std::min(QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE),
495 textureSizeLimit); // GL 1.3 / ES 2.0
496
497 if (functions->isAtLeastGL(gl::Version(3, 0)) ||
498 functions->hasGLExtension("GL_EXT_texture_array") ||
499 functions->isAtLeastGLES(gl::Version(3, 0)))
500 {
501 caps->maxArrayTextureLayers =
502 std::min({QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS), textureSizeLimit,
503 max3dArrayTextureSizeLimit});
504 }
505 else
506 {
507 // Can't support ES3 without array textures
508 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
509 }
510
511 if (functions->isAtLeastGL(gl::Version(1, 5)) ||
512 functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
513 functions->isAtLeastGLES(gl::Version(3, 0)))
514 {
515 caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
516 }
517 else
518 {
519 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
520 }
521
522 if (functions->isAtLeastGL(gl::Version(3, 0)) ||
523 functions->hasGLExtension("GL_EXT_framebuffer_object") ||
524 functions->isAtLeastGLES(gl::Version(2, 0)))
525 {
526 caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
527 caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
528 }
529 else
530 {
531 // Can't support ES2 without framebuffers and renderbuffers
532 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
533 }
534
535 if (functions->isAtLeastGL(gl::Version(2, 0)) ||
536 functions->hasGLExtension("ARB_draw_buffers") ||
537 functions->isAtLeastGLES(gl::Version(3, 0)) ||
538 functions->hasGLESExtension("GL_EXT_draw_buffers"))
539 {
540 caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
541 }
542 else
543 {
544 // Framebuffer is required to have at least one drawbuffer even if the extension is not
545 // supported
546 caps->maxDrawBuffers = 1;
547 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
548 }
549
550 caps->maxViewportWidth =
551 QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0); // GL 1.0 / ES 2.0
552 caps->maxViewportHeight =
553 QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1); // GL 1.0 / ES 2.0
554
555 if (functions->standard == STANDARD_GL_DESKTOP &&
556 (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
557 {
558 // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query. Use
559 // GL_POINT_SIZE_RANGE instead.
560 caps->minAliasedPointSize =
561 std::max(1.0f, QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0));
562 caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1);
563 }
564 else
565 {
566 caps->minAliasedPointSize =
567 std::max(1.0f, QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0));
568 caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
569 }
570
571 caps->minAliasedLineWidth =
572 QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0); // GL 1.2 / ES 2.0
573 caps->maxAliasedLineWidth =
574 QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1); // GL 1.2 / ES 2.0
575
576 // Table 6.29, implementation dependent values (cont.)
577 if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
578 {
579 caps->maxElementsIndices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
580 caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
581 }
582 else
583 {
584 // Doesn't impact supported version
585 }
586
587 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
588 functions->hasGLExtension("GL_ARB_get_program_binary") ||
589 functions->isAtLeastGLES(gl::Version(3, 0)) ||
590 functions->hasGLESExtension("GL_OES_get_program_binary"))
591 {
592 // Able to support the GL_PROGRAM_BINARY_ANGLE format as long as another program binary
593 // format is available.
594 GLint numBinaryFormats = QuerySingleGLInt(functions, GL_NUM_PROGRAM_BINARY_FORMATS_OES);
595 if (numBinaryFormats > 0)
596 {
597 caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
598 }
599 }
600 else
601 {
602 // Doesn't impact supported version
603 }
604
605 // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or
606 // GL_ARB_ES2_compatibility exists
607 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
608 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
609 functions->isAtLeastGLES(gl::Version(2, 0)))
610 {
611 caps->vertexHighpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
612 caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
613 caps->vertexLowpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
614 caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
615 caps->fragmentMediumpFloat =
616 QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
617 caps->fragmentLowpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
618 caps->vertexHighpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
619 caps->vertexMediumpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
620 caps->vertexLowpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
621 caps->fragmentHighpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
622 caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
623 caps->fragmentLowpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);
624 }
625 else
626 {
627 // Doesn't impact supported version, set some default values
628 caps->vertexHighpFloat.setIEEEFloat();
629 caps->vertexMediumpFloat.setIEEEFloat();
630 caps->vertexLowpFloat.setIEEEFloat();
631 caps->fragmentHighpFloat.setIEEEFloat();
632 caps->fragmentMediumpFloat.setIEEEFloat();
633 caps->fragmentLowpFloat.setIEEEFloat();
634 caps->vertexHighpInt.setTwosComplementInt(32);
635 caps->vertexMediumpInt.setTwosComplementInt(32);
636 caps->vertexLowpInt.setTwosComplementInt(32);
637 caps->fragmentHighpInt.setTwosComplementInt(32);
638 caps->fragmentMediumpInt.setTwosComplementInt(32);
639 caps->fragmentLowpInt.setTwosComplementInt(32);
640 }
641
642 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
643 functions->isAtLeastGLES(gl::Version(3, 0)))
644 {
645 // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is returned.
646 caps->maxServerWaitTimeout =
647 std::max<GLint64>(QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT), 0);
648 }
649 else
650 {
651 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
652 }
653
654 // Table 6.31, implementation dependent vertex shader limits
655 if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
656 {
657 caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
658 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
659 QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
660 caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
661 QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
662 }
663 else
664 {
665 // Can't support ES2 version without these caps
666 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
667 }
668
669 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
670 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
671 functions->isAtLeastGLES(gl::Version(2, 0)))
672 {
673 caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
674 caps->maxFragmentUniformVectors =
675 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
676 }
677 else
678 {
679 // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
680 caps->maxVertexUniformVectors =
681 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] / 4;
682 // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
683 caps->maxFragmentUniformVectors =
684 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] / 4;
685 }
686
687 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
688 {
689 caps->maxVertexOutputComponents =
690 QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
691 }
692 else
693 {
694 // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
695 // safe limit instead of limiting the supported ES version.
696 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
697 }
698
699 // Table 6.32, implementation dependent fragment shader limits
700 if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
701 {
702 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
703 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
704 caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
705 QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
706 }
707 else
708 {
709 // Can't support ES2 version without these caps
710 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
711 }
712
713 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
714 {
715 caps->maxFragmentInputComponents =
716 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
717 }
718 else
719 {
720 // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
721 // safe limit instead of limiting the supported ES version.
722 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
723 }
724
725 if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)))
726 {
727 caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
728 caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
729 }
730 else
731 {
732 // Can't support ES3 without texel offset, could possibly be emulated in the shader
733 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
734 }
735
736 // Table 6.33, implementation dependent aggregate shader limits
737 if (functions->isAtLeastGL(gl::Version(3, 1)) ||
738 functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
739 functions->isAtLeastGLES(gl::Version(3, 0)))
740 {
741 caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
742 QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
743 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
744 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
745 caps->maxUniformBufferBindings =
746 QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
747 caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
748 caps->uniformBufferOffsetAlignment =
749 QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
750 caps->maxCombinedUniformBlocks =
751 QuerySingleGLInt(functions, GL_MAX_COMBINED_UNIFORM_BLOCKS);
752 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] =
753 QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
754 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] =
755 QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
756 }
757 else
758 {
759 // Can't support ES3 without uniform blocks
760 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
761 }
762
763 if (functions->isAtLeastGL(gl::Version(3, 2)) &&
764 (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
765 {
766 caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
767 }
768 else if (functions->isAtLeastGL(gl::Version(3, 0)) ||
769 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
770 functions->isAtLeastGLES(gl::Version(2, 0)))
771 {
772 caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
773 }
774 else if (functions->isAtLeastGL(gl::Version(2, 0)))
775 {
776 caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS);
777 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
778 }
779 else
780 {
781 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
782 }
783
784 if (functions->isAtLeastGL(gl::Version(4, 1)) ||
785 functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
786 functions->isAtLeastGLES(gl::Version(2, 0)))
787 {
788 caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
789 }
790 else
791 {
792 // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
793 caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
794 }
795
796 // Determine the max combined texture image units by adding the vertex and fragment limits. If
797 // the real cap is queried, it would contain the limits for shader types that are not available
798 // to ES.
799 caps->maxCombinedTextureImageUnits =
800 QuerySingleGLInt(functions, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
801
802 // Table 6.34, implementation dependent transform feedback limits
803 if (functions->isAtLeastGL(gl::Version(4, 0)) ||
804 functions->hasGLExtension("GL_ARB_transform_feedback2") ||
805 functions->isAtLeastGLES(gl::Version(3, 0)))
806 {
807 caps->maxTransformFeedbackInterleavedComponents =
808 QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
809 caps->maxTransformFeedbackSeparateAttributes =
810 QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
811 caps->maxTransformFeedbackSeparateComponents =
812 QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
813 }
814 else
815 {
816 // Can't support ES3 without transform feedback
817 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
818 }
819
820 GLint sampleCountLimit = std::numeric_limits<GLint>::max();
821 if (features.limitMaxMSAASamplesTo4.enabled)
822 {
823 sampleCountLimit = 4;
824 }
825
826 // Table 6.35, Framebuffer Dependent Values
827 if (functions->isAtLeastGL(gl::Version(3, 0)) ||
828 functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
829 functions->isAtLeastGLES(gl::Version(3, 0)) ||
830 functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
831 {
832 caps->maxSamples = std::min(QuerySingleGLInt(functions, GL_MAX_SAMPLES), sampleCountLimit);
833 }
834 else
835 {
836 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
837 }
838
839 // Non-constant sampler array indexing is required for OpenGL ES 2 and OpenGL ES after 3.2.
840 // However having it available on OpenGL ES 2 is a specification bug, and using this
841 // indexing in WebGL is undefined. Requiring this feature would break WebGL 1 for some users
842 // so we don't check for it. (it is present with ESSL 100, ESSL >= 320, GLSL >= 400 and
843 // GL_ARB_gpu_shader5)
844
845 // Check if sampler objects are supported
846 if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
847 !functions->hasGLExtension("GL_ARB_sampler_objects") &&
848 !functions->isAtLeastGLES(gl::Version(3, 0)))
849 {
850 // Can't support ES3 without sampler objects
851 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
852 }
853
854 // Can't support ES3 without texture swizzling
855 if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
856 !functions->hasGLExtension("GL_ARB_texture_swizzle") &&
857 !functions->hasGLExtension("GL_EXT_texture_swizzle") &&
858 !functions->isAtLeastGLES(gl::Version(3, 0)))
859 {
860 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
861
862 // Texture swizzling is required to work around the luminance texture format not being
863 // present in the core profile
864 if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT)
865 {
866 LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
867 }
868 }
869
870 // Can't support ES3 without the GLSL packing builtins. We have a workaround for all
871 // desktop OpenGL versions starting from 3.3 with the bit packing extension.
872 if (!functions->isAtLeastGL(gl::Version(4, 2)) &&
873 !(functions->isAtLeastGL(gl::Version(3, 2)) &&
874 functions->hasGLExtension("GL_ARB_shader_bit_encoding")) &&
875 !functions->hasGLExtension("GL_ARB_shading_language_packing") &&
876 !functions->isAtLeastGLES(gl::Version(3, 0)))
877 {
878 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
879 }
880
881 // ES3 needs to support explicit layout location qualifiers, while it might be possible to
882 // fake them in our side, we currently don't support that.
883 if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
884 !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
885 !functions->isAtLeastGLES(gl::Version(3, 0)))
886 {
887 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
888 }
889
890 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
891 functions->hasGLExtension("GL_ARB_framebuffer_no_attachments"))
892 {
893 caps->maxFramebufferWidth = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
894 caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
895 caps->maxFramebufferSamples =
896 std::min(QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES), sampleCountLimit);
897 }
898 else
899 {
900 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
901 }
902
903 if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
904 functions->hasGLExtension("GL_ARB_texture_multisample"))
905 {
906 caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
907 caps->maxColorTextureSamples =
908 std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
909 caps->maxDepthTextureSamples =
910 std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
911 caps->maxIntegerSamples =
912 std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
913 }
914 else
915 {
916 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
917 }
918
919 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
920 functions->hasGLExtension("GL_ARB_vertex_attrib_binding"))
921 {
922 caps->maxVertexAttribRelativeOffset =
923 QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
924 caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS);
925
926 // OpenGL 4.3 has no limit on maximum value of stride.
927 // [OpenGL 4.3 (Core Profile) - February 14, 2013] Chapter 10.3.1 Page 298
928 if (features.emulateMaxVertexAttribStride.enabled ||
929 (functions->standard == STANDARD_GL_DESKTOP && functions->version == gl::Version(4, 3)))
930 {
931 caps->maxVertexAttribStride = 2048;
932 }
933 else
934 {
935 caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
936 }
937 }
938 else
939 {
940 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
941 }
942
943 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
944 functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
945 {
946 caps->maxCombinedShaderOutputResources =
947 QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
948 caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] =
949 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
950 caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
951 QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
952 caps->maxShaderStorageBufferBindings =
953 QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
954 caps->maxShaderStorageBlockSize =
955 QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
956 caps->maxCombinedShaderStorageBlocks =
957 QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
958 caps->shaderStorageBufferOffsetAlignment =
959 QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
960 }
961 else
962 {
963 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
964 }
965
966 // OpenGL 4.2 is required for GL_ARB_compute_shader, some platform drivers have the extension,
967 // but their maximum supported GL versions are less than 4.2. Explicitly limit the minimum
968 // GL version to 4.2.
969 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
970 (functions->isAtLeastGL(gl::Version(4, 2)) &&
971 functions->hasGLExtension("GL_ARB_compute_shader") &&
972 functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")))
973 {
974 for (GLuint index = 0u; index < 3u; ++index)
975 {
976 caps->maxComputeWorkGroupCount[index] =
977 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);
978
979 caps->maxComputeWorkGroupSize[index] =
980 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
981 }
982 caps->maxComputeWorkGroupInvocations =
983 QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
984 caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
985 QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS);
986 caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
987 QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS);
988 caps->maxComputeSharedMemorySize =
989 QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
990 caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
991 QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
992 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
993 QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
994 caps->maxShaderAtomicCounters[gl::ShaderType::Compute] =
995 QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS);
996 caps->maxShaderImageUniforms[gl::ShaderType::Compute] =
997 QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
998 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Compute] =
999 QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS);
1000 caps->maxShaderStorageBlocks[gl::ShaderType::Compute] =
1001 QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS);
1002 }
1003 else
1004 {
1005 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1006 }
1007
1008 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1009 functions->hasGLExtension("GL_ARB_explicit_uniform_location"))
1010 {
1011 caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS);
1012 }
1013 else
1014 {
1015 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1016 }
1017
1018 if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1019 functions->hasGLExtension("GL_ARB_texture_gather"))
1020 {
1021 caps->minProgramTextureGatherOffset =
1022 QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET);
1023 caps->maxProgramTextureGatherOffset =
1024 QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET);
1025 }
1026 else
1027 {
1028 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1029 }
1030
1031 if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1032 functions->hasGLExtension("GL_ARB_shader_image_load_store"))
1033 {
1034 caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
1035 QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS);
1036 caps->maxShaderImageUniforms[gl::ShaderType::Fragment] =
1037 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
1038 caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS);
1039 caps->maxCombinedImageUniforms =
1040 QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS);
1041 }
1042 else
1043 {
1044 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1045 }
1046
1047 if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1048 functions->hasGLExtension("GL_ARB_shader_atomic_counters"))
1049 {
1050 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
1051 QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS);
1052 caps->maxShaderAtomicCounters[gl::ShaderType::Vertex] =
1053 QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS);
1054 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
1055 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS);
1056 caps->maxShaderAtomicCounters[gl::ShaderType::Fragment] =
1057 QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS);
1058 caps->maxAtomicCounterBufferBindings =
1059 QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
1060 caps->maxAtomicCounterBufferSize =
1061 QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE);
1062 caps->maxCombinedAtomicCounterBuffers =
1063 QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS);
1064 caps->maxCombinedAtomicCounters =
1065 QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS);
1066 }
1067 else
1068 {
1069 LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1070 }
1071
1072 // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time
1073 // if the max uniform vectors is too large. Artificially limit the maximum until the test is
1074 // updated.
1075 caps->maxVertexUniformVectors = std::min(1024u, caps->maxVertexUniformVectors);
1076 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
1077 std::min(caps->maxVertexUniformVectors * 4,
1078 caps->maxShaderUniformComponents[gl::ShaderType::Vertex]);
1079 caps->maxFragmentUniformVectors = std::min(1024u, caps->maxFragmentUniformVectors);
1080 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1081 std::min(caps->maxFragmentUniformVectors * 4,
1082 caps->maxShaderUniformComponents[gl::ShaderType::Fragment]);
1083
1084 // If it is not possible to support reading buffer data back, a shadow copy of the buffers must
1085 // be held. This disallows writing to buffers indirectly through transform feedback, thus
1086 // disallowing ES3.
1087 if (!CanMapBufferForRead(functions))
1088 {
1089 LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1090 }
1091
1092 // Extension support
1093 extensions->setTextureExtensionSupport(*textureCapsMap);
1094 extensions->textureCompressionASTCHDRKHR =
1095 extensions->textureCompressionASTCLDRKHR &&
1096 functions->hasGLESExtension("GL_KHR_texture_compression_astc_hdr");
1097 extensions->elementIndexUint = functions->standard == STANDARD_GL_DESKTOP ||
1098 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1099 functions->hasGLESExtension("GL_OES_element_index_uint");
1100 extensions->getProgramBinary = caps->programBinaryFormats.size() > 0;
1101 extensions->readFormatBGRA = functions->isAtLeastGL(gl::Version(1, 2)) ||
1102 functions->hasGLExtension("GL_EXT_bgra") ||
1103 functions->hasGLESExtension("GL_EXT_read_format_bgra");
1104 extensions->mapBuffer = functions->isAtLeastGL(gl::Version(1, 5)) ||
1105 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1106 functions->hasGLESExtension("GL_OES_mapbuffer");
1107 extensions->mapBufferRange = functions->isAtLeastGL(gl::Version(3, 0)) ||
1108 functions->hasGLExtension("GL_ARB_map_buffer_range") ||
1109 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1110 functions->hasGLESExtension("GL_EXT_map_buffer_range");
1111 extensions->textureNPOT = functions->standard == STANDARD_GL_DESKTOP ||
1112 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1113 functions->hasGLESExtension("GL_OES_texture_npot");
1114 // TODO(jmadill): Investigate emulating EXT_draw_buffers on ES 3.0's core functionality.
1115 extensions->drawBuffers = functions->isAtLeastGL(gl::Version(2, 0)) ||
1116 functions->hasGLExtension("ARB_draw_buffers") ||
1117 functions->hasGLESExtension("GL_EXT_draw_buffers");
1118 extensions->textureStorage = functions->standard == STANDARD_GL_DESKTOP ||
1119 functions->hasGLESExtension("GL_EXT_texture_storage");
1120 extensions->textureFilterAnisotropic =
1121 functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") ||
1122 functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic");
1123 extensions->occlusionQueryBoolean = nativegl::SupportsOcclusionQueries(functions);
1124 extensions->maxTextureAnisotropy =
1125 extensions->textureFilterAnisotropic
1126 ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
1127 : 0.0f;
1128 extensions->fence = FenceNVGL::Supported(functions) || FenceNVSyncGL::Supported(functions);
1129 extensions->blendMinMax = functions->isAtLeastGL(gl::Version(1, 5)) ||
1130 functions->hasGLExtension("GL_EXT_blend_minmax") ||
1131 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1132 functions->hasGLESExtension("GL_EXT_blend_minmax");
1133 extensions->framebufferBlit = (functions->blitFramebuffer != nullptr);
1134 extensions->framebufferMultisample = caps->maxSamples > 0;
1135 extensions->standardDerivatives = functions->isAtLeastGL(gl::Version(2, 0)) ||
1136 functions->hasGLExtension("GL_ARB_fragment_shader") ||
1137 functions->hasGLESExtension("GL_OES_standard_derivatives");
1138 extensions->shaderTextureLOD = functions->isAtLeastGL(gl::Version(3, 0)) ||
1139 functions->hasGLExtension("GL_ARB_shader_texture_lod") ||
1140 functions->hasGLESExtension("GL_EXT_shader_texture_lod");
1141 extensions->fragDepth = functions->standard == STANDARD_GL_DESKTOP ||
1142 functions->hasGLESExtension("GL_EXT_frag_depth");
1143
1144 if (functions->hasGLExtension("GL_ARB_shader_viewport_layer_array") ||
1145 functions->hasGLExtension("GL_NV_viewport_array2"))
1146 {
1147 extensions->multiview = true;
1148 extensions->multiview2 = true;
1149 // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256.
1150 const int maxLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
1151 // GL_MAX_VIEWPORTS is guaranteed to be at least 16.
1152 const int maxViewports = QuerySingleGLInt(functions, GL_MAX_VIEWPORTS);
1153 extensions->maxViews = static_cast<GLuint>(
1154 std::min(static_cast<int>(gl::IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS),
1155 std::min(maxLayers, maxViewports)));
1156 *multiviewImplementationType = MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2;
1157 }
1158
1159 extensions->fboRenderMipmap = functions->isAtLeastGL(gl::Version(3, 0)) ||
1160 functions->hasGLExtension("GL_EXT_framebuffer_object") ||
1161 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1162 functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
1163 extensions->textureBorderClamp = functions->standard == STANDARD_GL_DESKTOP ||
1164 functions->hasGLESExtension("GL_OES_texture_border_clamp") ||
1165 functions->hasGLESExtension("GL_EXT_texture_border_clamp") ||
1166 functions->hasGLESExtension("GL_NV_texture_border_clamp");
1167 extensions->instancedArraysANGLE = functions->isAtLeastGL(gl::Version(3, 1)) ||
1168 (functions->hasGLExtension("GL_ARB_instanced_arrays") &&
1169 (functions->hasGLExtension("GL_ARB_draw_instanced") ||
1170 functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
1171 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1172 functions->hasGLESExtension("GL_EXT_instanced_arrays");
1173 extensions->instancedArraysEXT = extensions->instancedArraysANGLE;
1174 extensions->unpackSubimage = functions->standard == STANDARD_GL_DESKTOP ||
1175 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1176 functions->hasGLESExtension("GL_EXT_unpack_subimage");
1177 extensions->packSubimage = functions->standard == STANDARD_GL_DESKTOP ||
1178 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1179 functions->hasGLESExtension("GL_NV_pack_subimage");
1180 extensions->vertexArrayObject = functions->isAtLeastGL(gl::Version(3, 0)) ||
1181 functions->hasGLExtension("GL_ARB_vertex_array_object") ||
1182 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1183 functions->hasGLESExtension("GL_OES_vertex_array_object");
1184 extensions->debugMarker = functions->isAtLeastGL(gl::Version(4, 3)) ||
1185 functions->hasGLExtension("GL_KHR_debug") ||
1186 functions->hasGLExtension("GL_EXT_debug_marker") ||
1187 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1188 functions->hasGLESExtension("GL_KHR_debug") ||
1189 functions->hasGLESExtension("GL_EXT_debug_marker");
1190 extensions->eglImage = functions->hasGLESExtension("GL_OES_EGL_image");
1191 extensions->eglImageExternal = functions->hasGLESExtension("GL_OES_EGL_image_external");
1192 extensions->eglImageExternalEssl3 =
1193 functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
1194
1195 extensions->eglSync = functions->hasGLESExtension("GL_OES_EGL_sync");
1196
1197 if (functions->isAtLeastGL(gl::Version(3, 3)) ||
1198 functions->hasGLExtension("GL_ARB_timer_query") ||
1199 functions->hasGLESExtension("GL_EXT_disjoint_timer_query"))
1200 {
1201 extensions->disjointTimerQuery = true;
1202
1203 // If we can't query the counter bits, leave them at 0.
1204 if (!features.queryCounterBitsGeneratesErrors.enabled)
1205 {
1206 extensions->queryCounterBitsTimeElapsed =
1207 QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
1208 extensions->queryCounterBitsTimestamp =
1209 QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
1210 }
1211 }
1212
1213 // the EXT_multisample_compatibility is written against ES3.1 but can apply
1214 // to earlier versions so therefore we're only checking for the extension string
1215 // and not the specific GLES version.
1216 extensions->multisampleCompatibility =
1217 functions->isAtLeastGL(gl::Version(1, 3)) ||
1218 functions->hasGLESExtension("GL_EXT_multisample_compatibility");
1219
1220 extensions->framebufferMixedSamples =
1221 functions->hasGLExtension("GL_NV_framebuffer_mixed_samples") ||
1222 functions->hasGLESExtension("GL_NV_framebuffer_mixed_samples");
1223
1224 extensions->robustness = functions->isAtLeastGL(gl::Version(4, 5)) ||
1225 functions->hasGLExtension("GL_KHR_robustness") ||
1226 functions->hasGLExtension("GL_ARB_robustness") ||
1227 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1228 functions->hasGLESExtension("GL_KHR_robustness") ||
1229 functions->hasGLESExtension("GL_EXT_robustness");
1230
1231 extensions->robustBufferAccessBehavior =
1232 extensions->robustness &&
1233 (functions->hasGLExtension("GL_ARB_robust_buffer_access_behavior") ||
1234 functions->hasGLESExtension("GL_KHR_robust_buffer_access_behavior"));
1235
1236 extensions->copyTexture = true;
1237 extensions->syncQuery = SyncQueryGL::IsSupported(functions);
1238
1239 // Note that OES_texture_storage_multisample_2d_array support could be extended down to GL 3.2
1240 // if we emulated texStorage* API on top of texImage*.
1241 extensions->textureStorageMultisample2DArray =
1242 functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 2));
1243
1244 extensions->multiviewMultisample = extensions->textureStorageMultisample2DArray &&
1245 (extensions->multiview || extensions->multiview2);
1246
1247 extensions->textureMultisample = functions->isAtLeastGL(gl::Version(3, 2)) ||
1248 functions->hasGLExtension("GL_ARB_texture_multisample");
1249
1250 // NV_path_rendering
1251 // We also need interface query which is available in
1252 // >= 4.3 core or ARB_interface_query or >= GLES 3.1
1253 const bool canEnableGLPathRendering =
1254 functions->hasGLExtension("GL_NV_path_rendering") &&
1255 (functions->hasGLExtension("GL_ARB_program_interface_query") ||
1256 functions->isAtLeastGL(gl::Version(4, 3)));
1257
1258 const bool canEnableESPathRendering = functions->hasGLESExtension("GL_NV_path_rendering") &&
1259 functions->isAtLeastGLES(gl::Version(3, 1));
1260
1261 extensions->pathRendering = canEnableGLPathRendering || canEnableESPathRendering;
1262
1263 extensions->textureSRGBDecode = functions->hasGLExtension("GL_EXT_texture_sRGB_decode") ||
1264 functions->hasGLESExtension("GL_EXT_texture_sRGB_decode");
1265
1266 #if defined(ANGLE_PLATFORM_APPLE)
1267 VendorID vendor = GetVendorID(functions);
1268 if ((IsAMD(vendor) || IsIntel(vendor)) && *maxSupportedESVersion >= gl::Version(3, 0))
1269 {
1270 // Apple Intel/AMD drivers do not correctly use the TEXTURE_SRGB_DECODE property of sampler
1271 // states. Disable this extension when we would advertise any ES version that has samplers.
1272 extensions->textureSRGBDecode = false;
1273 }
1274 #endif
1275
1276 extensions->sRGBWriteControl = functions->isAtLeastGL(gl::Version(3, 0)) ||
1277 functions->hasGLExtension("GL_EXT_framebuffer_sRGB") ||
1278 functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
1279 functions->hasGLESExtension("GL_EXT_sRGB_write_control");
1280
1281 #if defined(ANGLE_PLATFORM_ANDROID)
1282 // SRGB blending does not appear to work correctly on the Nexus 5. Writing to an SRGB
1283 // framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same value.
1284 // Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
1285 extensions->sRGBWriteControl = false;
1286
1287 // BGRA formats do not appear to be accepted by the Nexus 5X driver dispite the extension being
1288 // exposed.
1289 extensions->textureFormatBGRA8888 = false;
1290 #endif
1291
1292 // EXT_discard_framebuffer can be implemented as long as glDiscardFramebufferEXT or
1293 // glInvalidateFramebuffer is available
1294 extensions->discardFramebuffer = functions->isAtLeastGL(gl::Version(4, 3)) ||
1295 functions->hasGLExtension("GL_ARB_invalidate_subdata") ||
1296 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1297 functions->hasGLESExtension("GL_EXT_discard_framebuffer") ||
1298 functions->hasGLESExtension("GL_ARB_invalidate_subdata");
1299
1300 extensions->translatedShaderSource = true;
1301
1302 if (functions->isAtLeastGL(gl::Version(3, 1)) ||
1303 functions->hasGLExtension("GL_ARB_texture_rectangle"))
1304 {
1305 extensions->textureRectangle = true;
1306 caps->maxRectangleTextureSize = std::min(
1307 QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE), textureSizeLimit);
1308 }
1309
1310 // OpenGL 4.3 (and above) can support all features and constants defined in
1311 // GL_EXT_geometry_shader.
1312 if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1313 functions->hasGLESExtension("GL_OES_geometry_shader") ||
1314 functions->hasGLESExtension("GL_EXT_geometry_shader") ||
1315 // OpenGL 4.0 adds the support for instanced geometry shader
1316 // GL_ARB_shader_atomic_counters adds atomic counters to geometry shader
1317 // GL_ARB_shader_storage_buffer_object adds shader storage buffers to geometry shader
1318 // GL_ARB_shader_image_load_store adds images to geometry shader
1319 (functions->isAtLeastGL(gl::Version(4, 0)) &&
1320 functions->hasGLExtension("GL_ARB_shader_atomic_counters") &&
1321 functions->hasGLExtension("GL_ARB_shader_storage_buffer_object") &&
1322 functions->hasGLExtension("GL_ARB_shader_image_load_store")))
1323 {
1324 extensions->geometryShader = true;
1325
1326 caps->maxFramebufferLayers = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_LAYERS_EXT);
1327
1328 // GL_PROVOKING_VERTEX isn't a valid return value of GL_LAYER_PROVOKING_VERTEX_EXT in
1329 // GL_EXT_geometry_shader SPEC, however it is legal in desktop OpenGL, which means the value
1330 // follows the one set by glProvokingVertex.
1331 // [OpenGL 4.3] Chapter 11.3.4.6
1332 // The vertex conventions followed for gl_Layer and gl_ViewportIndex may be determined by
1333 // calling GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and
1334 // VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the value returned is
1335 // PROVOKING_VERTEX, then vertex selection follows the convention specified by
1336 // ProvokingVertex.
1337 caps->layerProvokingVertex = QuerySingleGLInt(functions, GL_LAYER_PROVOKING_VERTEX_EXT);
1338 if (caps->layerProvokingVertex == GL_PROVOKING_VERTEX)
1339 {
1340 // We should use GL_LAST_VERTEX_CONVENTION_EXT instead because desktop OpenGL SPEC
1341 // requires the initial value of provoking vertex mode is LAST_VERTEX_CONVENTION.
1342 // [OpenGL 4.3] Chapter 13.4
1343 // The initial value of the provoking vertex mode is LAST_VERTEX_CONVENTION.
1344 caps->layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1345 }
1346
1347 caps->maxShaderUniformComponents[gl::ShaderType::Geometry] =
1348 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1349 caps->maxShaderUniformBlocks[gl::ShaderType::Geometry] =
1350 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT);
1351 caps->maxCombinedShaderUniformComponents[gl::ShaderType::Geometry] =
1352 QuerySingleGLInt(functions, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1353 caps->maxGeometryInputComponents =
1354 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT);
1355 caps->maxGeometryOutputComponents =
1356 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT);
1357 caps->maxGeometryOutputVertices =
1358 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT);
1359 caps->maxGeometryTotalOutputComponents =
1360 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT);
1361 caps->maxGeometryShaderInvocations =
1362 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT);
1363 caps->maxShaderTextureImageUnits[gl::ShaderType::Geometry] =
1364 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
1365 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
1366 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT);
1367 caps->maxShaderAtomicCounters[gl::ShaderType::Geometry] =
1368 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT);
1369 caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
1370 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT);
1371 caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
1372 QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT);
1373 }
1374
1375 // The real combined caps contain limits for shader types that are not available to ES, so limit
1376 // the caps to the sum of vertex+fragment+geometry shader caps.
1377 CapCombinedLimitToESShaders(&caps->maxCombinedUniformBlocks, caps->maxShaderUniformBlocks);
1378 CapCombinedLimitToESShaders(&caps->maxCombinedTextureImageUnits,
1379 caps->maxShaderTextureImageUnits);
1380 CapCombinedLimitToESShaders(&caps->maxCombinedShaderStorageBlocks,
1381 caps->maxShaderStorageBlocks);
1382 CapCombinedLimitToESShaders(&caps->maxCombinedImageUniforms, caps->maxShaderImageUniforms);
1383 CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounterBuffers,
1384 caps->maxShaderAtomicCounterBuffers);
1385 CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounters, caps->maxShaderAtomicCounters);
1386
1387 // EXT_blend_func_extended.
1388 // Note that this could be implemented also on top of native EXT_blend_func_extended, but it's
1389 // currently not fully implemented.
1390 extensions->blendFuncExtended = !features.disableBlendFuncExtended.enabled &&
1391 functions->standard == STANDARD_GL_DESKTOP &&
1392 functions->hasGLExtension("GL_ARB_blend_func_extended");
1393 if (extensions->blendFuncExtended)
1394 {
1395 // TODO(http://anglebug.com/1085): Support greater values of
1396 // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT queried from the driver. See comments in ProgramGL.cpp
1397 // for more information about this limitation.
1398 extensions->maxDualSourceDrawBuffers = 1;
1399 }
1400
1401 // EXT_float_blend
1402 // Assume all desktop driver supports this by default.
1403 extensions->floatBlend = functions->standard == STANDARD_GL_DESKTOP ||
1404 functions->hasGLESExtension("GL_EXT_float_blend");
1405
1406 // GL_CHROMIUM_compressed_texture_etc
1407 // Expose this extension only when we support the formats or we're running on top of a native
1408 // ES driver.
1409 extensions->compressedTextureETC = functions->standard == STANDARD_GL_ES &&
1410 gl::DetermineCompressedTextureETCSupport(*textureCapsMap);
1411
1412 // To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
1413 // if those formats are not available.
1414 if (features.unsizedsRGBReadPixelsDoesntTransform.enabled &&
1415 !functions->isAtLeastGLES(gl::Version(3, 0)))
1416 {
1417 extensions->sRGB = false;
1418 }
1419
1420 extensions->provokingVertex = functions->hasGLExtension("GL_ARB_provoking_vertex") ||
1421 functions->hasGLExtension("GL_EXT_provoking_vertex") ||
1422 functions->isAtLeastGL(gl::Version(3, 2));
1423
1424 extensions->textureExternalUpdateANGLE = true;
1425 extensions->texture3DOES = functions->isAtLeastGL(gl::Version(1, 2)) ||
1426 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1427 functions->hasGLESExtension("GL_OES_texture_3D");
1428
1429 extensions->memoryObject = functions->hasGLExtension("GL_EXT_memory_object") ||
1430 functions->hasGLESExtension("GL_EXT_memory_object");
1431 extensions->semaphore = functions->hasGLExtension("GL_EXT_semaphore") ||
1432 functions->hasGLESExtension("GL_EXT_semaphore");
1433 extensions->memoryObjectFd = functions->hasGLExtension("GL_EXT_memory_object_fd") ||
1434 functions->hasGLESExtension("GL_EXT_memory_object_fd");
1435 extensions->semaphoreFd = functions->hasGLExtension("GL_EXT_semaphore_fd") ||
1436 functions->hasGLESExtension("GL_EXT_semaphore_fd");
1437 }
1438
InitializeFeatures(const FunctionsGL * functions,angle::FeaturesGL * features)1439 void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features)
1440 {
1441 VendorID vendor = GetVendorID(functions);
1442 uint32_t device = GetDeviceID(functions);
1443
1444 // Don't use 1-bit alpha formats on desktop GL with AMD or Intel drivers.
1445 features->avoid1BitAlphaTextureFormats.enabled =
1446 functions->standard == STANDARD_GL_DESKTOP && (IsAMD(vendor));
1447
1448 features->rgba4IsNotSupportedForColorRendering.enabled =
1449 functions->standard == STANDARD_GL_DESKTOP && IsIntel(vendor);
1450
1451 features->emulateAbsIntFunction.enabled = IsIntel(vendor);
1452
1453 features->addAndTrueToLoopCondition.enabled = IsIntel(vendor);
1454
1455 features->emulateIsnanFloat.enabled = IsIntel(vendor);
1456
1457 features->doesSRGBClearsOnLinearFramebufferAttachments.enabled =
1458 functions->standard == STANDARD_GL_DESKTOP && (IsIntel(vendor) || IsAMD(vendor));
1459
1460 features->emulateMaxVertexAttribStride.enabled =
1461 IsLinux() && functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor);
1462 features->useUnusedBlocksWithStandardOrSharedLayout.enabled = IsLinux() && IsAMD(vendor);
1463
1464 features->doWhileGLSLCausesGPUHang.enabled = IsApple();
1465 features->useUnusedBlocksWithStandardOrSharedLayout.enabled = IsApple();
1466 features->rewriteFloatUnaryMinusOperator.enabled = IsApple() && IsIntel(vendor);
1467
1468 // Triggers a bug on Marshmallow Adreno (4xx?) driver.
1469 // http://anglebug.com/2046
1470 features->dontInitializeUninitializedLocals.enabled = IsAndroid() && IsQualcomm(vendor);
1471
1472 features->finishDoesNotCauseQueriesToBeAvailable.enabled =
1473 functions->standard == STANDARD_GL_DESKTOP && IsNvidia(vendor);
1474
1475 // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
1476 features->alwaysCallUseProgramAfterLink.enabled = true;
1477
1478 features->unpackOverlappingRowsSeparatelyUnpackBuffer.enabled = IsNvidia(vendor);
1479 features->packOverlappingRowsSeparatelyPackBuffer.enabled = IsNvidia(vendor);
1480
1481 features->initializeCurrentVertexAttributes.enabled = IsNvidia(vendor);
1482
1483 features->unpackLastRowSeparatelyForPaddingInclusion.enabled = IsApple() || IsNvidia(vendor);
1484 features->packLastRowSeparatelyForPaddingInclusion.enabled = IsApple() || IsNvidia(vendor);
1485
1486 features->removeInvariantAndCentroidForESSL3.enabled =
1487 functions->isAtMostGL(gl::Version(4, 1)) ||
1488 (functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor));
1489
1490 // TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
1491 // 364 are known to be affected, at least up to 375.
1492 features->emulateAtan2Float.enabled = IsNvidia(vendor);
1493
1494 features->reapplyUBOBindingsAfterUsingBinaryProgram.enabled = IsAMD(vendor);
1495
1496 features->rewriteVectorScalarArithmetic.enabled = IsNvidia(vendor);
1497
1498 // TODO(oetuaho): Make this specific to the affected driver versions. Versions at least up to
1499 // 390 are known to be affected. Versions after that are expected not to be affected.
1500 features->clampFragDepth.enabled = IsNvidia(vendor);
1501
1502 // TODO(oetuaho): Make this specific to the affected driver versions. Versions since 397.31 are
1503 // not affected.
1504 features->rewriteRepeatedAssignToSwizzled.enabled = IsNvidia(vendor);
1505
1506 // TODO(jmadill): Narrow workaround range for specific devices.
1507 features->reapplyUBOBindingsAfterUsingBinaryProgram.enabled = IsAndroid();
1508
1509 features->clampPointSize.enabled = IsAndroid() || IsNvidia(vendor);
1510
1511 features->dontUseLoopsToInitializeVariables.enabled = IsAndroid() && !IsNvidia(vendor);
1512
1513 features->disableBlendFuncExtended.enabled = IsAMD(vendor) || IsIntel(vendor);
1514
1515 features->unsizedsRGBReadPixelsDoesntTransform.enabled = IsAndroid() && IsQualcomm(vendor);
1516
1517 features->queryCounterBitsGeneratesErrors.enabled = IsNexus5X(vendor, device);
1518
1519 features->dontRelinkProgramsInParallel.enabled =
1520 IsAndroid() || (IsWindows() && IsIntel(vendor));
1521
1522 // TODO(jie.a.chen@intel.com): Clean up the bugs.
1523 // anglebug.com/3031
1524 // crbug.com/922936
1525 features->disableWorkerContexts.enabled =
1526 (IsWindows() && (IsIntel(vendor) || IsAMD(vendor))) || (IsLinux() && IsNvidia(vendor));
1527
1528 features->limitMaxTextureSizeTo4096.enabled = IsAndroid() || (IsIntel(vendor) && IsLinux());
1529 features->limitMaxMSAASamplesTo4.enabled = IsAndroid();
1530 features->limitMax3dArrayTextureSizeTo1024.enabled = IsIntel(vendor) && IsLinux();
1531
1532 features->allowClearForRobustResourceInit.enabled = IsApple();
1533
1534 // The WebGL conformance/uniforms/out-of-bounds-uniform-array-access test has been seen to fail
1535 // on AMD and Android devices.
1536 features->clampArrayAccess.enabled = IsAndroid() || IsAMD(vendor);
1537
1538 features->resetTexImage2DBaseLevel.enabled =
1539 IsApple() && IsIntel(vendor) && GetMacOSVersion() >= OSVersion(10, 12, 4);
1540
1541 features->clearToZeroOrOneBroken.enabled =
1542 IsApple() && IsIntel(vendor) && GetMacOSVersion() < OSVersion(10, 12, 6);
1543
1544 features->adjustSrcDstRegionBlitFramebuffer.enabled =
1545 IsLinux() || (IsAndroid() && IsNvidia(vendor)) || (IsWindows() && IsNvidia(vendor));
1546
1547 features->clipSrcRegionBlitFramebuffer.enabled = IsApple();
1548 }
1549
InitializeFrontendFeatures(const FunctionsGL * functions,angle::FrontendFeatures * features)1550 void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
1551 {
1552 VendorID vendor = GetVendorID(functions);
1553
1554 features->disableProgramCachingForTransformFeedback.enabled = IsAndroid() && IsQualcomm(vendor);
1555 features->syncFramebufferBindingsOnTexImage.enabled = IsWindows() && IsIntel(vendor);
1556 }
1557
1558 } // namespace nativegl_gl
1559
1560 namespace nativegl
1561 {
SupportsFenceSync(const FunctionsGL * functions)1562 bool SupportsFenceSync(const FunctionsGL *functions)
1563 {
1564 return functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
1565 functions->isAtLeastGLES(gl::Version(3, 0));
1566 }
1567
SupportsOcclusionQueries(const FunctionsGL * functions)1568 bool SupportsOcclusionQueries(const FunctionsGL *functions)
1569 {
1570 return functions->isAtLeastGL(gl::Version(1, 5)) ||
1571 functions->hasGLExtension("GL_ARB_occlusion_query2") ||
1572 functions->isAtLeastGLES(gl::Version(3, 0)) ||
1573 functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
1574 }
1575
SupportsNativeRendering(const FunctionsGL * functions,gl::TextureType type,GLenum internalFormat)1576 bool SupportsNativeRendering(const FunctionsGL *functions,
1577 gl::TextureType type,
1578 GLenum internalFormat)
1579 {
1580 // Some desktop drivers allow rendering to formats that are not required by the spec, this is
1581 // exposed through the GL_FRAMEBUFFER_RENDERABLE query.
1582 bool hasInternalFormatQuery = functions->isAtLeastGL(gl::Version(4, 3)) ||
1583 functions->hasGLExtension("GL_ARB_internalformat_query2");
1584
1585 // Some Intel drivers have a bug that returns GL_FULL_SUPPORT when asked if they support
1586 // rendering to compressed texture formats yet return framebuffer incomplete when attempting to
1587 // render to the format. Skip any native queries for compressed formats.
1588 const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
1589
1590 if (hasInternalFormatQuery && !internalFormatInfo.compressed)
1591 {
1592 GLint framebufferRenderable = GL_NONE;
1593 functions->getInternalformativ(ToGLenum(type), internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
1594 &framebufferRenderable);
1595 return framebufferRenderable != GL_NONE;
1596 }
1597 else
1598 {
1599 const nativegl::InternalFormat &nativeInfo =
1600 nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
1601 return nativegl_gl::MeetsRequirements(functions, nativeInfo.textureAttachment);
1602 }
1603 }
1604
SupportsTexImage(gl::TextureType type)1605 bool SupportsTexImage(gl::TextureType type)
1606 {
1607 switch (type)
1608 {
1609 // Multi-sample texture types only support TexStorage data upload
1610 case gl::TextureType::_2DMultisample:
1611 case gl::TextureType::_2DMultisampleArray:
1612 return false;
1613
1614 default:
1615 return true;
1616 }
1617 }
1618
UseTexImage2D(gl::TextureType textureType)1619 bool UseTexImage2D(gl::TextureType textureType)
1620 {
1621 return textureType == gl::TextureType::_2D || textureType == gl::TextureType::CubeMap ||
1622 textureType == gl::TextureType::Rectangle ||
1623 textureType == gl::TextureType::_2DMultisample ||
1624 textureType == gl::TextureType::External;
1625 }
1626
UseTexImage3D(gl::TextureType textureType)1627 bool UseTexImage3D(gl::TextureType textureType)
1628 {
1629 return textureType == gl::TextureType::_2DArray || textureType == gl::TextureType::_3D ||
1630 textureType == gl::TextureType::_2DMultisampleArray;
1631 }
1632
GetTextureBindingQuery(gl::TextureType textureType)1633 GLenum GetTextureBindingQuery(gl::TextureType textureType)
1634 {
1635 switch (textureType)
1636 {
1637 case gl::TextureType::_2D:
1638 return GL_TEXTURE_BINDING_2D;
1639 case gl::TextureType::_2DArray:
1640 return GL_TEXTURE_BINDING_2D_ARRAY;
1641 case gl::TextureType::_2DMultisample:
1642 return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
1643 case gl::TextureType::_2DMultisampleArray:
1644 return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
1645 case gl::TextureType::_3D:
1646 return GL_TEXTURE_BINDING_3D;
1647 case gl::TextureType::External:
1648 return GL_TEXTURE_BINDING_EXTERNAL_OES;
1649 case gl::TextureType::Rectangle:
1650 return GL_TEXTURE_BINDING_RECTANGLE;
1651 case gl::TextureType::CubeMap:
1652 return GL_TEXTURE_BINDING_CUBE_MAP;
1653 default:
1654 UNREACHABLE();
1655 return 0;
1656 }
1657 }
1658
1659 } // namespace nativegl
1660
GetFunctionsGL(const gl::Context * context)1661 const FunctionsGL *GetFunctionsGL(const gl::Context *context)
1662 {
1663 return GetImplAs<ContextGL>(context)->getFunctions();
1664 }
1665
GetStateManagerGL(const gl::Context * context)1666 StateManagerGL *GetStateManagerGL(const gl::Context *context)
1667 {
1668 return GetImplAs<ContextGL>(context)->getStateManager();
1669 }
1670
GetBlitGL(const gl::Context * context)1671 BlitGL *GetBlitGL(const gl::Context *context)
1672 {
1673 return GetImplAs<ContextGL>(context)->getBlitter();
1674 }
1675
GetMultiviewClearer(const gl::Context * context)1676 ClearMultiviewGL *GetMultiviewClearer(const gl::Context *context)
1677 {
1678 return GetImplAs<ContextGL>(context)->getMultiviewClearer();
1679 }
1680
GetFeaturesGL(const gl::Context * context)1681 const angle::FeaturesGL &GetFeaturesGL(const gl::Context *context)
1682 {
1683 return GetImplAs<ContextGL>(context)->getFeaturesGL();
1684 }
1685
CanMapBufferForRead(const FunctionsGL * functions)1686 bool CanMapBufferForRead(const FunctionsGL *functions)
1687 {
1688 return (functions->mapBufferRange != nullptr) ||
1689 (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP);
1690 }
1691
MapBufferRangeWithFallback(const FunctionsGL * functions,GLenum target,size_t offset,size_t length,GLbitfield access)1692 uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
1693 GLenum target,
1694 size_t offset,
1695 size_t length,
1696 GLbitfield access)
1697 {
1698 if (functions->mapBufferRange != nullptr)
1699 {
1700 return static_cast<uint8_t *>(functions->mapBufferRange(target, offset, length, access));
1701 }
1702 else if (functions->mapBuffer != nullptr &&
1703 (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT))
1704 {
1705 // Only the read and write bits are supported
1706 ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0);
1707
1708 GLenum accessEnum = 0;
1709 if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
1710 {
1711 accessEnum = GL_READ_WRITE;
1712 }
1713 else if (access == GL_MAP_READ_BIT)
1714 {
1715 accessEnum = GL_READ_ONLY;
1716 }
1717 else if (access == GL_MAP_WRITE_BIT)
1718 {
1719 accessEnum = GL_WRITE_ONLY;
1720 }
1721 else
1722 {
1723 UNREACHABLE();
1724 return nullptr;
1725 }
1726
1727 return static_cast<uint8_t *>(functions->mapBuffer(target, accessEnum)) + offset;
1728 }
1729 else
1730 {
1731 // No options available
1732 UNREACHABLE();
1733 return nullptr;
1734 }
1735 }
1736
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)1737 angle::Result ShouldApplyLastRowPaddingWorkaround(ContextGL *contextGL,
1738 const gl::Extents &size,
1739 const gl::PixelStoreStateBase &state,
1740 const gl::Buffer *pixelBuffer,
1741 GLenum format,
1742 GLenum type,
1743 bool is3D,
1744 const void *pixels,
1745 bool *shouldApplyOut)
1746 {
1747 if (pixelBuffer == nullptr)
1748 {
1749 *shouldApplyOut = false;
1750 return angle::Result::Continue;
1751 }
1752
1753 // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
1754 // last byte read or written. If it is past the end of the buffer, we will need to use the
1755 // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.
1756
1757 const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
1758 GLuint endByte = 0;
1759 ANGLE_CHECK_GL_MATH(contextGL,
1760 glFormat.computePackUnpackEndByte(type, size, state, is3D, &endByte));
1761 GLuint rowPitch = 0;
1762 ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, size.width, state.alignment,
1763 state.rowLength, &rowPitch));
1764
1765 CheckedNumeric<size_t> checkedPixelBytes = glFormat.computePixelBytes(type);
1766 CheckedNumeric<size_t> checkedEndByte =
1767 angle::CheckedNumeric<size_t>(endByte) + reinterpret_cast<intptr_t>(pixels);
1768
1769 // At this point checkedEndByte is the actual last byte read.
1770 // The driver adds an extra row padding (if any), mimic it.
1771 ANGLE_CHECK_GL_MATH(contextGL, checkedPixelBytes.IsValid());
1772 if (checkedPixelBytes.ValueOrDie() * size.width < rowPitch)
1773 {
1774 checkedEndByte += rowPitch - checkedPixelBytes * size.width;
1775 }
1776
1777 ANGLE_CHECK_GL_MATH(contextGL, checkedEndByte.IsValid());
1778
1779 *shouldApplyOut = checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
1780 return angle::Result::Continue;
1781 }
1782
GenerateContextCreationToTry(EGLint requestedType,bool isMesaGLX)1783 std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
1784 {
1785 using Type = ContextCreationTry::Type;
1786 constexpr EGLint kPlatformOpenGL = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
1787 constexpr EGLint kPlatformOpenGLES = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
1788
1789 std::vector<ContextCreationTry> contextsToTry;
1790
1791 if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE || requestedType == kPlatformOpenGL)
1792 {
1793 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 5));
1794 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 4));
1795 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 3));
1796 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 2));
1797 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 1));
1798 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 0));
1799 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 3));
1800 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 2));
1801 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 3));
1802
1803 // On Mesa, do not try to create OpenGL context versions between 3.0 and
1804 // 3.2 because of compatibility problems. See crbug.com/659030
1805 if (!isMesaGLX)
1806 {
1807 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 2));
1808 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 1));
1809 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 0));
1810 }
1811
1812 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 1));
1813 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 0));
1814 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 5));
1815 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 4));
1816 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 3));
1817 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 2));
1818 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 1));
1819 contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 0));
1820 }
1821
1822 if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE ||
1823 requestedType == kPlatformOpenGLES)
1824 {
1825 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 2));
1826 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 1));
1827 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 0));
1828 contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(2, 0));
1829 }
1830
1831 return contextsToTry;
1832 }
1833 } // namespace rx
1834