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