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