1 //
2 // Copyright (c) 2014 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 #include "libANGLE/Caps.h"
8 
9 #include "common/debug.h"
10 #include "common/angleutils.h"
11 
12 #include "libANGLE/formatutils.h"
13 
14 #include "angle_gl.h"
15 
16 #include <algorithm>
17 #include <sstream>
18 
InsertExtensionString(const std::string & extension,bool supported,std::vector<std::string> * extensionVector)19 static void InsertExtensionString(const std::string &extension, bool supported, std::vector<std::string> *extensionVector)
20 {
21     if (supported)
22     {
23         extensionVector->push_back(extension);
24     }
25 }
26 
27 namespace gl
28 {
29 
TextureCaps()30 TextureCaps::TextureCaps()
31     : texturable(false),
32       filterable(false),
33       renderable(false),
34       sampleCounts()
35 {
36 }
37 
38 TextureCaps::TextureCaps(const TextureCaps &other) = default;
39 
40 TextureCaps::~TextureCaps() = default;
41 
getMaxSamples() const42 GLuint TextureCaps::getMaxSamples() const
43 {
44     return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
45 }
46 
getNearestSamples(GLuint requestedSamples) const47 GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
48 {
49     if (requestedSamples == 0)
50     {
51         return 0;
52     }
53 
54     for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++)
55     {
56         GLuint samples = *i;
57         if (samples >= requestedSamples)
58         {
59             return samples;
60         }
61     }
62 
63     return 0;
64 }
65 
GenerateMinimumTextureCaps(GLenum sizedInternalFormat,const Version & clientVersion,const Extensions & extensions)66 TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat,
67                                        const Version &clientVersion,
68                                        const Extensions &extensions)
69 {
70     TextureCaps caps;
71 
72     const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
73     caps.texturable = internalFormatInfo.textureSupport(clientVersion, extensions);
74     caps.renderable = internalFormatInfo.renderSupport(clientVersion, extensions);
75     caps.filterable = internalFormatInfo.filterSupport(clientVersion, extensions);
76 
77     caps.sampleCounts.insert(0);
78     if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion))
79     {
80         if ((clientVersion.major >= 3 && clientVersion.minor >= 1) ||
81             (clientVersion.major >= 3 && internalFormatInfo.componentType != GL_UNSIGNED_INT &&
82              internalFormatInfo.componentType != GL_INT))
83         {
84             caps.sampleCounts.insert(4);
85         }
86     }
87 
88     return caps;
89 }
90 
TextureCapsMap()91 TextureCapsMap::TextureCapsMap()
92 {
93 }
94 
~TextureCapsMap()95 TextureCapsMap::~TextureCapsMap()
96 {
97 }
98 
insert(GLenum internalFormat,const TextureCaps & caps)99 void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
100 {
101     angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat);
102     get(formatID)              = caps;
103 }
104 
clear()105 void TextureCapsMap::clear()
106 {
107     mFormatData.fill(TextureCaps());
108 }
109 
get(GLenum internalFormat) const110 const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
111 {
112     angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat);
113     return get(formatID);
114 }
115 
get(angle::Format::ID formatID) const116 const TextureCaps &TextureCapsMap::get(angle::Format::ID formatID) const
117 {
118     return mFormatData[static_cast<size_t>(formatID)];
119 }
120 
get(angle::Format::ID formatID)121 TextureCaps &TextureCapsMap::get(angle::Format::ID formatID)
122 {
123     return mFormatData[static_cast<size_t>(formatID)];
124 }
125 
set(angle::Format::ID formatID,const TextureCaps & caps)126 void TextureCapsMap::set(angle::Format::ID formatID, const TextureCaps &caps)
127 {
128     get(formatID) = caps;
129 }
130 
InitMinimumTextureCapsMap(const Version & clientVersion,const Extensions & extensions,TextureCapsMap * capsMap)131 void InitMinimumTextureCapsMap(const Version &clientVersion,
132                                const Extensions &extensions,
133                                TextureCapsMap *capsMap)
134 {
135     for (GLenum internalFormat : GetAllSizedInternalFormats())
136     {
137         capsMap->insert(internalFormat,
138                         GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions));
139     }
140 }
141 
Extensions()142 Extensions::Extensions()
143     : elementIndexUint(false),
144       packedDepthStencil(false),
145       getProgramBinary(false),
146       rgb8rgba8(false),
147       textureFormatBGRA8888(false),
148       readFormatBGRA(false),
149       pixelBufferObject(false),
150       mapBuffer(false),
151       mapBufferRange(false),
152       colorBufferHalfFloat(false),
153       textureHalfFloat(false),
154       textureHalfFloatLinear(false),
155       textureFloat(false),
156       textureFloatLinear(false),
157       textureRG(false),
158       textureCompressionDXT1(false),
159       textureCompressionDXT3(false),
160       textureCompressionDXT5(false),
161       textureCompressionS3TCsRGB(false),
162       textureCompressionASTCHDR(false),
163       textureCompressionASTCLDR(false),
164       compressedETC1RGB8Texture(false),
165       sRGB(false),
166       depthTextures(false),
167       depth32(false),
168       textureStorage(false),
169       textureNPOT(false),
170       drawBuffers(false),
171       textureFilterAnisotropic(false),
172       maxTextureAnisotropy(0.0f),
173       occlusionQueryBoolean(false),
174       fence(false),
175       disjointTimerQuery(false),
176       queryCounterBitsTimeElapsed(0),
177       queryCounterBitsTimestamp(0),
178       robustness(false),
179       robustBufferAccessBehavior(false),
180       blendMinMax(false),
181       framebufferBlit(false),
182       framebufferMultisample(false),
183       instancedArrays(false),
184       packReverseRowOrder(false),
185       standardDerivatives(false),
186       shaderTextureLOD(false),
187       fragDepth(false),
188       multiview(false),
189       maxViews(1u),
190       textureUsage(false),
191       translatedShaderSource(false),
192       fboRenderMipmap(false),
193       discardFramebuffer(false),
194       debugMarker(false),
195       eglImage(false),
196       eglImageExternal(false),
197       eglImageExternalEssl3(false),
198       eglStreamConsumerExternal(false),
199       unpackSubimage(false),
200       packSubimage(false),
201       vertexArrayObject(false),
202       debug(false),
203       maxDebugMessageLength(0),
204       maxDebugLoggedMessages(0),
205       maxDebugGroupStackDepth(0),
206       maxLabelLength(0),
207       noError(false),
208       lossyETCDecode(false),
209       bindUniformLocation(false),
210       syncQuery(false),
211       copyTexture(false),
212       copyCompressedTexture(false),
213       webglCompatibility(false),
214       requestExtension(false),
215       bindGeneratesResource(false),
216       robustClientMemory(false),
217       textureSRGBDecode(false),
218       sRGBWriteControl(false),
219       colorBufferFloatRGB(false),
220       colorBufferFloatRGBA(false),
221       colorBufferFloat(false),
222       multisampleCompatibility(false),
223       framebufferMixedSamples(false),
224       textureNorm16(false),
225       pathRendering(false),
226       surfacelessContext(false),
227       clientArrays(false),
228       robustResourceInitialization(false),
229       programCacheControl(false),
230       textureRectangle(false),
231       geometryShader(false),
232       maxGeometryOutputVertices(0),
233       maxGeometryShaderInvocations(0)
234 {
235 }
236 
getStrings() const237 std::vector<std::string> Extensions::getStrings() const
238 {
239     std::vector<std::string> extensionStrings;
240 
241     for (const auto &extensionInfo : GetExtensionInfoMap())
242     {
243         if (this->*(extensionInfo.second.ExtensionsMember))
244         {
245             extensionStrings.push_back(extensionInfo.first);
246         }
247     }
248 
249     return extensionStrings;
250 }
251 
Limitations()252 Limitations::Limitations()
253     : noFrontFacingSupport(false),
254       noSampleAlphaToCoverageSupport(false),
255       attributeZeroRequiresZeroDivisorInEXT(false),
256       noSeparateStencilRefsAndMasks(false),
257       shadersRequireIndexedLoopValidation(false),
258       noSimultaneousConstantColorAndAlphaBlendFunc(false)
259 {
260 }
261 
GetFormatSupportBase(const TextureCapsMap & textureCaps,const GLenum * requiredFormats,size_t requiredFormatsSize,bool requiresTexturing,bool requiresFiltering,bool requiresRendering)262 static bool GetFormatSupportBase(const TextureCapsMap &textureCaps,
263                                  const GLenum *requiredFormats,
264                                  size_t requiredFormatsSize,
265                                  bool requiresTexturing,
266                                  bool requiresFiltering,
267                                  bool requiresRendering)
268 {
269     for (size_t i = 0; i < requiredFormatsSize; i++)
270     {
271         const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
272 
273         if (requiresTexturing && !cap.texturable)
274         {
275             return false;
276         }
277 
278         if (requiresFiltering && !cap.filterable)
279         {
280             return false;
281         }
282 
283         if (requiresRendering && !cap.renderable)
284         {
285             return false;
286         }
287     }
288 
289     return true;
290 }
291 
292 template <size_t N>
GetFormatSupport(const TextureCapsMap & textureCaps,const GLenum (& requiredFormats)[N],bool requiresTexturing,bool requiresFiltering,bool requiresRendering)293 static bool GetFormatSupport(const TextureCapsMap &textureCaps,
294                              const GLenum (&requiredFormats)[N],
295                              bool requiresTexturing,
296                              bool requiresFiltering,
297                              bool requiresRendering)
298 {
299     return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing,
300                                 requiresFiltering, requiresRendering);
301 }
302 
303 // Check for GL_OES_packed_depth_stencil
DeterminePackedDepthStencilSupport(const TextureCapsMap & textureCaps)304 static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps)
305 {
306     constexpr GLenum requiredFormats[] = {
307         GL_DEPTH24_STENCIL8,
308     };
309 
310     return GetFormatSupport(textureCaps, requiredFormats, false, false, true);
311 }
312 
313 // Checks for GL_OES_rgb8_rgba8 support
DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap & textureCaps)314 static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps)
315 {
316     constexpr GLenum requiredFormats[] = {
317         GL_RGB8, GL_RGBA8,
318     };
319 
320     return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
321 }
322 
323 // Checks for GL_EXT_texture_format_BGRA8888 support
DetermineBGRA8TextureSupport(const TextureCapsMap & textureCaps)324 static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
325 {
326     constexpr GLenum requiredFormats[] = {
327         GL_BGRA8_EXT,
328     };
329 
330     return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
331 }
332 
333 // Checks for GL_OES_color_buffer_half_float support
DetermineColorBufferHalfFloatSupport(const TextureCapsMap & textureCaps)334 static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps)
335 {
336     constexpr GLenum requiredFormats[] = {
337         GL_RGBA16F, GL_RGB16F, GL_RG16F, GL_R16F,
338     };
339 
340     return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
341 }
342 
343 // Checks for GL_OES_texture_half_float support
DetermineHalfFloatTextureSupport(const TextureCapsMap & textureCaps)344 static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
345 {
346     constexpr GLenum requiredFormats[] = {
347         GL_RGB16F, GL_RGBA16F,
348     };
349 
350     return GetFormatSupport(textureCaps, requiredFormats, true, false, false);
351 }
352 
353 // Checks for GL_OES_texture_half_float_linear support
DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap & textureCaps)354 static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps)
355 {
356     constexpr GLenum requiredFormats[] = {
357         GL_RGB16F, GL_RGBA16F,
358     };
359 
360     return DetermineHalfFloatTextureSupport(textureCaps) &&
361            GetFormatSupport(textureCaps, requiredFormats, true, true, false);
362 }
363 
364 // Checks for GL_OES_texture_float support
DetermineFloatTextureSupport(const TextureCapsMap & textureCaps)365 static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
366 {
367     constexpr GLenum requiredFormats[] = {
368         GL_RGB32F, GL_RGBA32F,
369     };
370 
371     return GetFormatSupport(textureCaps, requiredFormats, true, false, false);
372 }
373 
374 // Checks for GL_OES_texture_float_linear support
DetermineFloatTextureFilteringSupport(const TextureCapsMap & textureCaps)375 static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps)
376 {
377     constexpr GLenum requiredFormats[] = {
378         GL_RGB32F, GL_RGBA32F,
379     };
380 
381     return DetermineFloatTextureSupport(textureCaps) &&
382            GetFormatSupport(textureCaps, requiredFormats, true, true, false);
383 }
384 
385 // Checks for GL_EXT_texture_rg support
DetermineRGHalfFloatTextureSupport(const TextureCapsMap & textureCaps)386 static bool DetermineRGHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
387 {
388     constexpr GLenum requiredFormats[] = {
389         GL_R16F, GL_RG16F,
390     };
391     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
392 }
393 
DetermineRGFloatTextureSupport(const TextureCapsMap & textureCaps)394 static bool DetermineRGFloatTextureSupport(const TextureCapsMap &textureCaps)
395 {
396     constexpr GLenum requiredFormats[] = {
397         GL_R32F, GL_RG32F,
398     };
399     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
400 }
401 
DetermineRGTextureSupport(const TextureCapsMap & textureCaps,bool checkHalfFloatFormats,bool checkFloatFormats)402 static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, bool checkHalfFloatFormats, bool checkFloatFormats)
403 {
404     if (checkHalfFloatFormats && !DetermineRGHalfFloatTextureSupport(textureCaps))
405     {
406         return false;
407     }
408 
409     if (checkFloatFormats && !DetermineRGFloatTextureSupport(textureCaps))
410     {
411         return false;
412     }
413 
414     constexpr GLenum requiredFormats[] = {
415         GL_R8, GL_RG8,
416     };
417     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
418 }
419 
420 // Check for GL_EXT_texture_compression_dxt1
DetermineDXT1TextureSupport(const TextureCapsMap & textureCaps)421 static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
422 {
423     constexpr GLenum requiredFormats[] = {
424         GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
425     };
426 
427     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
428 }
429 
430 // Check for GL_ANGLE_texture_compression_dxt3
DetermineDXT3TextureSupport(const TextureCapsMap & textureCaps)431 static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
432 {
433     constexpr GLenum requiredFormats[] = {
434         GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
435     };
436 
437     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
438 }
439 
440 // Check for GL_ANGLE_texture_compression_dxt5
DetermineDXT5TextureSupport(const TextureCapsMap & textureCaps)441 static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
442 {
443     constexpr GLenum requiredFormats[] = {
444         GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
445     };
446 
447     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
448 }
449 
450 // Check for GL_EXT_texture_compression_s3tc_srgb
DetermineS3TCsRGBTextureSupport(const TextureCapsMap & textureCaps)451 static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps)
452 {
453     constexpr GLenum requiredFormats[] = {
454         GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
455         GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
456     };
457 
458     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
459 }
460 
461 // Check for GL_KHR_texture_compression_astc_hdr and GL_KHR_texture_compression_astc_ldr
DetermineASTCTextureSupport(const TextureCapsMap & textureCaps)462 static bool DetermineASTCTextureSupport(const TextureCapsMap &textureCaps)
463 {
464     constexpr GLenum requiredFormats[] = {
465         GL_COMPRESSED_RGBA_ASTC_4x4_KHR,           GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
466         GL_COMPRESSED_RGBA_ASTC_5x5_KHR,           GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
467         GL_COMPRESSED_RGBA_ASTC_6x6_KHR,           GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
468         GL_COMPRESSED_RGBA_ASTC_8x6_KHR,           GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
469         GL_COMPRESSED_RGBA_ASTC_10x5_KHR,          GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
470         GL_COMPRESSED_RGBA_ASTC_10x8_KHR,          GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
471         GL_COMPRESSED_RGBA_ASTC_12x10_KHR,         GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
472         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
473         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
474         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
475         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
476         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
477         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
478         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
479     };
480 
481     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
482 }
483 
484 // Check for GL_ETC1_RGB8_OES
DetermineETC1RGB8TextureSupport(const TextureCapsMap & textureCaps)485 static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps)
486 {
487     constexpr GLenum requiredFormats[] = {
488         GL_ETC1_RGB8_OES,
489     };
490 
491     return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
492 }
493 
494 // Check for GL_ANGLE_texture_compression_dxt5
DetermineSRGBTextureSupport(const TextureCapsMap & textureCaps)495 static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
496 {
497     constexpr GLenum requiredFilterFormats[] = {
498         GL_SRGB8, GL_SRGB8_ALPHA8,
499     };
500 
501     constexpr GLenum requiredRenderFormats[] = {
502         GL_SRGB8_ALPHA8,
503     };
504 
505     return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) &&
506            GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true);
507 }
508 
509 // Check for GL_ANGLE_depth_texture
DetermineDepthTextureSupport(const TextureCapsMap & textureCaps)510 static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps)
511 {
512     constexpr GLenum requiredFormats[] = {
513         GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32_OES, GL_DEPTH24_STENCIL8_OES,
514     };
515 
516     return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
517 }
518 
519 // Check for GL_OES_depth32
DetermineDepth32Support(const TextureCapsMap & textureCaps)520 static bool DetermineDepth32Support(const TextureCapsMap &textureCaps)
521 {
522     constexpr GLenum requiredFormats[] = {
523         GL_DEPTH_COMPONENT32_OES,
524     };
525 
526     return GetFormatSupport(textureCaps, requiredFormats, false, false, true);
527 }
528 
529 // Check for GL_CHROMIUM_color_buffer_float_rgb
DetermineColorBufferFloatRGBSupport(const TextureCapsMap & textureCaps)530 static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps)
531 {
532     constexpr GLenum requiredFormats[] = {
533         GL_RGB32F,
534     };
535 
536     return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
537 }
538 
539 // Check for GL_CHROMIUM_color_buffer_float_rgba
DetermineColorBufferFloatRGBASupport(const TextureCapsMap & textureCaps)540 static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps)
541 {
542     constexpr GLenum requiredFormats[] = {
543         GL_RGBA32F,
544     };
545 
546     return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
547 }
548 
549 // Check for GL_EXT_color_buffer_float
DetermineColorBufferFloatSupport(const TextureCapsMap & textureCaps)550 static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
551 {
552     constexpr GLenum requiredFormats[] = {
553         GL_R16F, GL_RG16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_RGBA32F, GL_R11F_G11F_B10F,
554     };
555 
556     return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
557 }
558 
559 // Check for GL_EXT_texture_norm16
DetermineTextureNorm16Support(const TextureCapsMap & textureCaps)560 static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps)
561 {
562     constexpr GLenum requiredFilterFormats[] = {
563         GL_R16_EXT,       GL_RG16_EXT,       GL_RGB16_EXT,       GL_RGBA16_EXT,
564         GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT,
565     };
566 
567     constexpr GLenum requiredRenderFormats[] = {
568         GL_R16_EXT, GL_RG16_EXT, GL_RGBA16_EXT,
569     };
570 
571     return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) &&
572            GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true);
573 }
574 
setTextureExtensionSupport(const TextureCapsMap & textureCaps)575 void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
576 {
577     packedDepthStencil = DeterminePackedDepthStencilSupport(textureCaps);
578     rgb8rgba8 = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
579     textureFormatBGRA8888 = DetermineBGRA8TextureSupport(textureCaps);
580     colorBufferHalfFloat      = DetermineColorBufferHalfFloatSupport(textureCaps);
581     textureHalfFloat = DetermineHalfFloatTextureSupport(textureCaps);
582     textureHalfFloatLinear = DetermineHalfFloatTextureFilteringSupport(textureCaps);
583     textureFloat = DetermineFloatTextureSupport(textureCaps);
584     textureFloatLinear = DetermineFloatTextureFilteringSupport(textureCaps);
585     textureRG = DetermineRGTextureSupport(textureCaps, textureHalfFloat, textureFloat);
586     textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps);
587     textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps);
588     textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps);
589     textureCompressionS3TCsRGB = DetermineS3TCsRGBTextureSupport(textureCaps);
590     textureCompressionASTCHDR = DetermineASTCTextureSupport(textureCaps);
591     textureCompressionASTCLDR = textureCompressionASTCHDR;
592     compressedETC1RGB8Texture = DetermineETC1RGB8TextureSupport(textureCaps);
593     sRGB = DetermineSRGBTextureSupport(textureCaps);
594     depthTextures = DetermineDepthTextureSupport(textureCaps);
595     depth32                   = DetermineDepth32Support(textureCaps);
596     colorBufferFloatRGB        = DetermineColorBufferFloatRGBSupport(textureCaps);
597     colorBufferFloatRGBA       = DetermineColorBufferFloatRGBASupport(textureCaps);
598     colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps);
599     textureNorm16             = DetermineTextureNorm16Support(textureCaps);
600 }
601 
GetExtensionInfoMap()602 const ExtensionInfoMap &GetExtensionInfoMap()
603 {
604     auto buildExtensionInfoMap = []() {
605         auto enableableExtension = [](ExtensionInfo::ExtensionBool member) {
606             ExtensionInfo info;
607             info.Requestable      = true;
608             info.ExtensionsMember = member;
609             return info;
610         };
611 
612         auto esOnlyExtension = [](ExtensionInfo::ExtensionBool member) {
613             ExtensionInfo info;
614             info.ExtensionsMember = member;
615             return info;
616         };
617 
618         // clang-format off
619         ExtensionInfoMap map;
620         map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUint);
621         map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencil);
622         map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinary);
623         map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8rgba8);
624         map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888);
625         map["GL_EXT_read_format_bgra"] = esOnlyExtension(&Extensions::readFormatBGRA);
626         map["GL_NV_pixel_buffer_object"] = enableableExtension(&Extensions::pixelBufferObject);
627         map["GL_OES_mapbuffer"] = enableableExtension(&Extensions::mapBuffer);
628         map["GL_EXT_map_buffer_range"] = enableableExtension(&Extensions::mapBufferRange);
629         map["GL_EXT_color_buffer_half_float"] = enableableExtension(&Extensions::colorBufferHalfFloat);
630         map["GL_OES_texture_half_float"] = enableableExtension(&Extensions::textureHalfFloat);
631         map["GL_OES_texture_half_float_linear"] = enableableExtension(&Extensions::textureHalfFloatLinear);
632         map["GL_OES_texture_float"] = enableableExtension(&Extensions::textureFloat);
633         map["GL_OES_texture_float_linear"] = enableableExtension(&Extensions::textureFloatLinear);
634         map["GL_EXT_texture_rg"] = enableableExtension(&Extensions::textureRG);
635         map["GL_EXT_texture_compression_dxt1"] = enableableExtension(&Extensions::textureCompressionDXT1);
636         map["GL_ANGLE_texture_compression_dxt3"] = enableableExtension(&Extensions::textureCompressionDXT3);
637         map["GL_ANGLE_texture_compression_dxt5"] = enableableExtension(&Extensions::textureCompressionDXT5);
638         map["GL_EXT_texture_compression_s3tc_srgb"] = enableableExtension(&Extensions::textureCompressionS3TCsRGB);
639         map["GL_KHR_texture_compression_astc_hdr"] = enableableExtension(&Extensions::textureCompressionASTCHDR);
640         map["GL_KHR_texture_compression_astc_ldr"] = enableableExtension(&Extensions::textureCompressionASTCLDR);
641         map["GL_OES_compressed_ETC1_RGB8_texture"] = enableableExtension(&Extensions::compressedETC1RGB8Texture);
642         map["GL_EXT_sRGB"] = enableableExtension(&Extensions::sRGB);
643         map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextures);
644         map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32);
645         map["GL_EXT_texture_storage"] = esOnlyExtension(&Extensions::textureStorage);
646         map["GL_OES_texture_npot"] = enableableExtension(&Extensions::textureNPOT);
647         map["GL_EXT_draw_buffers"] = enableableExtension(&Extensions::drawBuffers);
648         map["GL_EXT_texture_filter_anisotropic"] = enableableExtension(&Extensions::textureFilterAnisotropic);
649         map["GL_EXT_occlusion_query_boolean"] = enableableExtension(&Extensions::occlusionQueryBoolean);
650         map["GL_NV_fence"] = esOnlyExtension(&Extensions::fence);
651         map["GL_EXT_disjoint_timer_query"] = enableableExtension(&Extensions::disjointTimerQuery);
652         map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustness);
653         map["GL_KHR_robust_buffer_access_behavior"] = esOnlyExtension(&Extensions::robustBufferAccessBehavior);
654         map["GL_EXT_blend_minmax"] = enableableExtension(&Extensions::blendMinMax);
655         map["GL_ANGLE_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlit);
656         map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisample);
657         map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArrays);
658         map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrder);
659         map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivatives);
660         map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLOD);
661         map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepth);
662         map["GL_ANGLE_multiview"] = enableableExtension(&Extensions::multiview);
663         map["GL_ANGLE_texture_usage"] = enableableExtension(&Extensions::textureUsage);
664         map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSource);
665         map["GL_OES_fbo_render_mipmap"] = enableableExtension(&Extensions::fboRenderMipmap);
666         map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebuffer);
667         map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarker);
668         map["GL_OES_EGL_image"] = esOnlyExtension(&Extensions::eglImage);
669         map["GL_OES_EGL_image_external"] = esOnlyExtension(&Extensions::eglImageExternal);
670         map["GL_OES_EGL_image_external_essl3"] = esOnlyExtension(&Extensions::eglImageExternalEssl3);
671         map["GL_NV_EGL_stream_consumer_external"] = esOnlyExtension(&Extensions::eglStreamConsumerExternal);
672         map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage);
673         map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage);
674         map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloat);
675         map["GL_OES_vertex_array_object"] = esOnlyExtension(&Extensions::vertexArrayObject);
676         map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug);
677         // TODO(jmadill): Enable this when complete.
678         //map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noError);
679         map["GL_ANGLE_lossy_etc_decode"] = enableableExtension(&Extensions::lossyETCDecode);
680         map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocation);
681         map["GL_CHROMIUM_sync_query"] = enableableExtension(&Extensions::syncQuery);
682         map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture);
683         map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTexture);
684         map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility);
685         map["GL_ANGLE_request_extension"] = esOnlyExtension(&Extensions::requestExtension);
686         map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource);
687         map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory);
688         map["GL_EXT_texture_sRGB_decode"] = esOnlyExtension(&Extensions::textureSRGBDecode);
689         map["GL_EXT_sRGB_write_control"] = esOnlyExtension(&Extensions::sRGBWriteControl);
690         map["GL_CHROMIUM_color_buffer_float_rgb"] = enableableExtension(&Extensions::colorBufferFloatRGB);
691         map["GL_CHROMIUM_color_buffer_float_rgba"] = enableableExtension(&Extensions::colorBufferFloatRGBA);
692         map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibility);
693         map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples);
694         map["GL_EXT_texture_norm16"] = esOnlyExtension(&Extensions::textureNorm16);
695         map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering);
696         map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContext);
697         map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays);
698         map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization);
699         map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControl);
700         map["GL_ANGLE_texture_rectangle"] = enableableExtension(&Extensions::textureRectangle);
701         map["GL_EXT_geometry_shader"] = enableableExtension(&Extensions::geometryShader);
702         // clang-format on
703 
704         return map;
705     };
706 
707     static const ExtensionInfoMap extensionInfo = buildExtensionInfoMap();
708     return extensionInfo;
709 }
710 
TypePrecision()711 TypePrecision::TypePrecision() : range({{0, 0}}), precision(0)
712 {
713 }
714 
715 TypePrecision::TypePrecision(const TypePrecision &other) = default;
716 
setIEEEFloat()717 void TypePrecision::setIEEEFloat()
718 {
719     range     = {{127, 127}};
720     precision = 23;
721 }
722 
setTwosComplementInt(unsigned int bits)723 void TypePrecision::setTwosComplementInt(unsigned int bits)
724 {
725     range     = {{static_cast<GLint>(bits) - 1, static_cast<GLint>(bits) - 2}};
726     precision = 0;
727 }
728 
setSimulatedFloat(unsigned int r,unsigned int p)729 void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p)
730 {
731     range     = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
732     precision = static_cast<GLint>(p);
733 }
734 
setSimulatedInt(unsigned int r)735 void TypePrecision::setSimulatedInt(unsigned int r)
736 {
737     range     = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
738     precision = 0;
739 }
740 
get(GLint * returnRange,GLint * returnPrecision) const741 void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const
742 {
743     std::copy(range.begin(), range.end(), returnRange);
744     *returnPrecision = precision;
745 }
746 
Caps()747 Caps::Caps()
748     : maxElementIndex(0),
749       max3DTextureSize(0),
750       max2DTextureSize(0),
751       maxRectangleTextureSize(0),
752       maxArrayTextureLayers(0),
753       maxLODBias(0),
754       maxCubeMapTextureSize(0),
755       maxRenderbufferSize(0),
756       minAliasedPointSize(0),
757       maxAliasedPointSize(0),
758       minAliasedLineWidth(0),
759       maxAliasedLineWidth(0),
760 
761       // Table 20.40
762       maxDrawBuffers(0),
763       maxFramebufferWidth(0),
764       maxFramebufferHeight(0),
765       maxFramebufferSamples(0),
766       maxColorAttachments(0),
767       maxViewportWidth(0),
768       maxViewportHeight(0),
769       maxSampleMaskWords(0),
770       maxColorTextureSamples(0),
771       maxDepthTextureSamples(0),
772       maxIntegerSamples(0),
773       maxServerWaitTimeout(0),
774 
775       // Table 20.41
776       maxVertexAttribRelativeOffset(0),
777       maxVertexAttribBindings(0),
778       maxVertexAttribStride(0),
779       maxElementsIndices(0),
780       maxElementsVertices(0),
781 
782       // Table 20.43
783       maxVertexAttributes(0),
784       maxVertexUniformComponents(0),
785       maxVertexUniformVectors(0),
786       maxVertexUniformBlocks(0),
787       maxVertexOutputComponents(0),
788       maxVertexTextureImageUnits(0),
789       maxVertexAtomicCounterBuffers(0),
790       maxVertexAtomicCounters(0),
791       maxVertexImageUniforms(0),
792       maxVertexShaderStorageBlocks(0),
793 
794       // Table 20.44
795       maxFragmentUniformComponents(0),
796       maxFragmentUniformVectors(0),
797       maxFragmentUniformBlocks(0),
798       maxFragmentInputComponents(0),
799       maxTextureImageUnits(0),
800       maxFragmentAtomicCounterBuffers(0),
801       maxFragmentAtomicCounters(0),
802       maxFragmentImageUniforms(0),
803       maxFragmentShaderStorageBlocks(0),
804       minProgramTextureGatherOffset(0),
805       maxProgramTextureGatherOffset(0),
806       minProgramTexelOffset(0),
807       maxProgramTexelOffset(0),
808 
809       // Table 20.45
810       maxComputeWorkGroupInvocations(0),
811       maxComputeUniformBlocks(0),
812       maxComputeTextureImageUnits(0),
813       maxComputeSharedMemorySize(0),
814       maxComputeUniformComponents(0),
815       maxComputeAtomicCounterBuffers(0),
816       maxComputeAtomicCounters(0),
817       maxComputeImageUniforms(0),
818       maxCombinedComputeUniformComponents(0),
819       maxComputeShaderStorageBlocks(0),
820 
821       // Table 20.46
822       maxUniformBufferBindings(0),
823       maxUniformBlockSize(0),
824       uniformBufferOffsetAlignment(0),
825       maxCombinedUniformBlocks(0),
826       maxCombinedVertexUniformComponents(0),
827       maxCombinedFragmentUniformComponents(0),
828       maxVaryingComponents(0),
829       maxVaryingVectors(0),
830       maxCombinedTextureImageUnits(0),
831       maxCombinedShaderOutputResources(0),
832 
833       // Table 20.47
834       maxUniformLocations(0),
835       maxAtomicCounterBufferBindings(0),
836       maxAtomicCounterBufferSize(0),
837       maxCombinedAtomicCounterBuffers(0),
838       maxCombinedAtomicCounters(0),
839       maxImageUnits(0),
840       maxCombinedImageUniforms(0),
841       maxShaderStorageBufferBindings(0),
842       maxShaderStorageBlockSize(0),
843       maxCombinedShaderStorageBlocks(0),
844       shaderStorageBufferOffsetAlignment(0),
845 
846       // Table 20.48
847       maxTransformFeedbackInterleavedComponents(0),
848       maxTransformFeedbackSeparateAttributes(0),
849       maxTransformFeedbackSeparateComponents(0),
850 
851       // Table 20.49
852       maxSamples(0)
853 {
854     for (size_t i = 0; i < 3; ++i)
855     {
856         maxComputeWorkGroupCount[i] = 0;
857         maxComputeWorkGroupSize[i]  = 0;
858     }
859 }
860 
861 Caps::Caps(const Caps &other) = default;
862 Caps::~Caps()                 = default;
863 
GenerateMinimumCaps(const Version & clientVersion,const Extensions & extensions)864 Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions)
865 {
866     Caps caps;
867 
868     if (clientVersion >= Version(2, 0))
869     {
870         // Table 6.18
871         caps.max2DTextureSize      = 64;
872         caps.maxCubeMapTextureSize = 16;
873         caps.maxViewportWidth      = caps.max2DTextureSize;
874         caps.maxViewportHeight     = caps.max2DTextureSize;
875         caps.minAliasedPointSize   = 1;
876         caps.maxAliasedPointSize   = 1;
877         caps.minAliasedLineWidth   = 1;
878         caps.maxAliasedLineWidth   = 1;
879 
880         // Table 6.19
881         caps.vertexHighpFloat.setSimulatedFloat(62, 16);
882         caps.vertexMediumpFloat.setSimulatedFloat(14, 10);
883         caps.vertexLowpFloat.setSimulatedFloat(1, 8);
884         caps.vertexHighpInt.setSimulatedInt(16);
885         caps.vertexMediumpInt.setSimulatedInt(10);
886         caps.vertexLowpInt.setSimulatedInt(8);
887         caps.fragmentHighpFloat.setSimulatedFloat(62, 16);
888         caps.fragmentMediumpFloat.setSimulatedFloat(14, 10);
889         caps.fragmentLowpFloat.setSimulatedFloat(1, 8);
890         caps.fragmentHighpInt.setSimulatedInt(16);
891         caps.fragmentMediumpInt.setSimulatedInt(10);
892         caps.fragmentLowpInt.setSimulatedInt(8);
893 
894         // Table 6.20
895         caps.maxVertexAttributes          = 8;
896         caps.maxVertexUniformVectors      = 128;
897         caps.maxVaryingVectors            = 8;
898         caps.maxCombinedTextureImageUnits = 8;
899         caps.maxTextureImageUnits         = 8;
900         caps.maxFragmentUniformVectors    = 16;
901         caps.maxRenderbufferSize          = 1;
902     }
903 
904     if (clientVersion >= Version(3, 0))
905     {
906         // Table 6.28
907         caps.maxElementIndex       = (1 << 24) - 1;
908         caps.max3DTextureSize      = 256;
909         caps.max2DTextureSize      = 2048;
910         caps.maxArrayTextureLayers = 256;
911         caps.maxLODBias            = 2.0f;
912         caps.maxCubeMapTextureSize = 2048;
913         caps.maxRenderbufferSize   = 2048;
914         caps.maxDrawBuffers        = 4;
915         caps.maxColorAttachments   = 4;
916         caps.maxViewportWidth      = caps.max2DTextureSize;
917         caps.maxViewportHeight     = caps.max2DTextureSize;
918 
919         // Table 6.29
920         caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC);
921         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC);
922         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC);
923         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
924         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2);
925         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2);
926         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
927         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
928         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
929         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
930         caps.vertexHighpFloat.setIEEEFloat();
931         caps.vertexHighpInt.setTwosComplementInt(32);
932         caps.vertexMediumpInt.setTwosComplementInt(16);
933         caps.vertexLowpInt.setTwosComplementInt(8);
934         caps.fragmentHighpFloat.setIEEEFloat();
935         caps.fragmentHighpInt.setSimulatedInt(32);
936         caps.fragmentMediumpInt.setTwosComplementInt(16);
937         caps.fragmentLowpInt.setTwosComplementInt(8);
938         caps.maxServerWaitTimeout = 0;
939 
940         // Table 6.31
941         caps.maxVertexAttributes        = 16;
942         caps.maxVertexUniformComponents = 1024;
943         caps.maxVertexUniformVectors    = 256;
944         caps.maxVertexUniformBlocks     = 12;
945         caps.maxVertexOutputComponents  = 64;
946         caps.maxVertexTextureImageUnits = 16;
947 
948         // Table 6.32
949         caps.maxFragmentUniformComponents = 896;
950         caps.maxFragmentUniformVectors    = 224;
951         caps.maxFragmentUniformBlocks     = 12;
952         caps.maxFragmentInputComponents   = 60;
953         caps.maxTextureImageUnits         = 16;
954         caps.minProgramTexelOffset        = -8;
955         caps.maxProgramTexelOffset        = 7;
956 
957         // Table 6.33
958         caps.maxUniformBufferBindings     = 24;
959         caps.maxUniformBlockSize          = 16384;
960         caps.uniformBufferOffsetAlignment = 256;
961         caps.maxCombinedUniformBlocks     = 24;
962         caps.maxCombinedVertexUniformComponents =
963             caps.maxVertexUniformBlocks * (caps.maxUniformBlockSize / 4) +
964             caps.maxVertexUniformComponents;
965         caps.maxCombinedFragmentUniformComponents =
966             caps.maxFragmentUniformBlocks * (caps.maxUniformBlockSize / 4) +
967             caps.maxFragmentUniformComponents;
968         caps.maxVaryingComponents         = 60;
969         caps.maxVaryingVectors            = 15;
970         caps.maxCombinedTextureImageUnits = 32;
971 
972         // Table 6.34
973         caps.maxTransformFeedbackInterleavedComponents = 64;
974         caps.maxTransformFeedbackSeparateAttributes    = 4;
975         caps.maxTransformFeedbackSeparateComponents    = 4;
976 
977         // Table 3.35
978         caps.maxSamples = 4;
979     }
980 
981     if (clientVersion >= Version(3, 1))
982     {
983         // Table 20.40
984         caps.maxFramebufferWidth    = 2048;
985         caps.maxFramebufferHeight   = 2048;
986         caps.maxFramebufferSamples  = 4;
987         caps.maxSampleMaskWords     = 1;
988         caps.maxColorTextureSamples = 1;
989         caps.maxDepthTextureSamples = 1;
990         caps.maxIntegerSamples      = 1;
991 
992         // Table 20.41
993         caps.maxVertexAttribRelativeOffset = 2047;
994         caps.maxVertexAttribBindings       = 16;
995         caps.maxVertexAttribStride         = 2048;
996 
997         // Table 20.43
998         caps.maxVertexAtomicCounterBuffers = 0;
999         caps.maxVertexAtomicCounters       = 0;
1000         caps.maxVertexImageUniforms        = 0;
1001         caps.maxVertexShaderStorageBlocks  = 0;
1002 
1003         // Table 20.44
1004         caps.maxFragmentUniformComponents    = 1024;
1005         caps.maxFragmentUniformVectors       = 256;
1006         caps.maxFragmentAtomicCounterBuffers = 0;
1007         caps.maxFragmentAtomicCounters       = 0;
1008         caps.maxFragmentImageUniforms        = 0;
1009         caps.maxFragmentShaderStorageBlocks  = 0;
1010         caps.minProgramTextureGatherOffset   = 0;
1011         caps.maxProgramTextureGatherOffset   = 0;
1012 
1013         // Table 20.45
1014         caps.maxComputeWorkGroupCount       = {{65535, 65535, 65535}};
1015         caps.maxComputeWorkGroupSize        = {{128, 128, 64}};
1016         caps.maxComputeWorkGroupInvocations = 12;
1017         caps.maxComputeUniformBlocks        = 12;
1018         caps.maxComputeTextureImageUnits    = 16;
1019         caps.maxComputeSharedMemorySize     = 16384;
1020         caps.maxComputeUniformComponents    = 1024;
1021         caps.maxComputeAtomicCounterBuffers = 1;
1022         caps.maxComputeAtomicCounters       = 8;
1023         caps.maxComputeImageUniforms        = 4;
1024         caps.maxCombinedComputeUniformComponents =
1025             caps.maxComputeUniformBlocks * static_cast<GLuint>(caps.maxUniformBlockSize / 4) +
1026             caps.maxComputeUniformComponents;
1027         caps.maxComputeShaderStorageBlocks = 4;
1028 
1029         // Table 20.46
1030         caps.maxUniformBufferBindings = 36;
1031         caps.maxCombinedFragmentUniformComponents =
1032             caps.maxFragmentUniformBlocks * (caps.maxUniformBlockSize / 4) +
1033             caps.maxFragmentUniformComponents;
1034         caps.maxCombinedTextureImageUnits     = 48;
1035         caps.maxCombinedShaderOutputResources = 4;
1036 
1037         // Table 20.47
1038         caps.maxUniformLocations                = 1024;
1039         caps.maxAtomicCounterBufferBindings     = 1;
1040         caps.maxAtomicCounterBufferSize         = 32;
1041         caps.maxCombinedAtomicCounterBuffers    = 1;
1042         caps.maxCombinedAtomicCounters          = 8;
1043         caps.maxImageUnits                      = 4;
1044         caps.maxCombinedImageUniforms           = 4;
1045         caps.maxShaderStorageBufferBindings     = 4;
1046         caps.maxShaderStorageBlockSize          = 1 << 27;
1047         caps.maxCombinedShaderStorageBlocks     = 4;
1048         caps.shaderStorageBufferOffsetAlignment = 256;
1049     }
1050 
1051     if (extensions.textureRectangle)
1052     {
1053         caps.maxRectangleTextureSize = 64;
1054     }
1055 
1056     return caps;
1057 }
1058 }
1059 
1060 namespace egl
1061 {
1062 
Caps()1063 Caps::Caps()
1064     : textureNPOT(false)
1065 {
1066 }
1067 
DisplayExtensions()1068 DisplayExtensions::DisplayExtensions()
1069     : createContextRobustness(false),
1070       d3dShareHandleClientBuffer(false),
1071       d3dTextureClientBuffer(false),
1072       surfaceD3DTexture2DShareHandle(false),
1073       querySurfacePointer(false),
1074       windowFixedSize(false),
1075       keyedMutex(false),
1076       surfaceOrientation(false),
1077       postSubBuffer(false),
1078       createContext(false),
1079       deviceQuery(false),
1080       image(false),
1081       imageBase(false),
1082       imagePixmap(false),
1083       glTexture2DImage(false),
1084       glTextureCubemapImage(false),
1085       glTexture3DImage(false),
1086       glRenderbufferImage(false),
1087       getAllProcAddresses(false),
1088       flexibleSurfaceCompatibility(false),
1089       directComposition(false),
1090       createContextNoError(false),
1091       stream(false),
1092       streamConsumerGLTexture(false),
1093       streamConsumerGLTextureYUV(false),
1094       streamProducerD3DTextureNV12(false),
1095       createContextWebGLCompatibility(false),
1096       createContextBindGeneratesResource(false),
1097       getSyncValues(false),
1098       swapBuffersWithDamage(false),
1099       pixelFormatFloat(false),
1100       surfacelessContext(false),
1101       displayTextureShareGroup(false),
1102       createContextClientArrays(false),
1103       programCacheControl(false),
1104       robustResourceInitialization(false)
1105 {
1106 }
1107 
getStrings() const1108 std::vector<std::string> DisplayExtensions::getStrings() const
1109 {
1110     std::vector<std::string> extensionStrings;
1111 
1112     // clang-format off
1113     //                   | Extension name                                       | Supported flag                    | Output vector   |
1114     InsertExtensionString("EGL_EXT_create_context_robustness",                   createContextRobustness,            &extensionStrings);
1115     InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer",            d3dShareHandleClientBuffer,         &extensionStrings);
1116     InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer",                 d3dTextureClientBuffer,             &extensionStrings);
1117     InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle",       surfaceD3DTexture2DShareHandle,     &extensionStrings);
1118     InsertExtensionString("EGL_ANGLE_query_surface_pointer",                     querySurfacePointer,                &extensionStrings);
1119     InsertExtensionString("EGL_ANGLE_window_fixed_size",                         windowFixedSize,                    &extensionStrings);
1120     InsertExtensionString("EGL_ANGLE_keyed_mutex",                               keyedMutex,                         &extensionStrings);
1121     InsertExtensionString("EGL_ANGLE_surface_orientation",                       surfaceOrientation,                 &extensionStrings);
1122     InsertExtensionString("EGL_ANGLE_direct_composition",                        directComposition,                  &extensionStrings);
1123     InsertExtensionString("EGL_NV_post_sub_buffer",                              postSubBuffer,                      &extensionStrings);
1124     InsertExtensionString("EGL_KHR_create_context",                              createContext,                      &extensionStrings);
1125     InsertExtensionString("EGL_EXT_device_query",                                deviceQuery,                        &extensionStrings);
1126     InsertExtensionString("EGL_KHR_image",                                       image,                              &extensionStrings);
1127     InsertExtensionString("EGL_KHR_image_base",                                  imageBase,                          &extensionStrings);
1128     InsertExtensionString("EGL_KHR_image_pixmap",                                imagePixmap,                        &extensionStrings);
1129     InsertExtensionString("EGL_KHR_gl_texture_2D_image",                         glTexture2DImage,                   &extensionStrings);
1130     InsertExtensionString("EGL_KHR_gl_texture_cubemap_image",                    glTextureCubemapImage,              &extensionStrings);
1131     InsertExtensionString("EGL_KHR_gl_texture_3D_image",                         glTexture3DImage,                   &extensionStrings);
1132     InsertExtensionString("EGL_KHR_gl_renderbuffer_image",                       glRenderbufferImage,                &extensionStrings);
1133     InsertExtensionString("EGL_KHR_get_all_proc_addresses",                      getAllProcAddresses,                &extensionStrings);
1134     InsertExtensionString("EGL_KHR_stream",                                      stream,                             &extensionStrings);
1135     InsertExtensionString("EGL_KHR_stream_consumer_gltexture",                   streamConsumerGLTexture,            &extensionStrings);
1136     InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv",                streamConsumerGLTextureYUV,         &extensionStrings);
1137     InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility",            flexibleSurfaceCompatibility,       &extensionStrings);
1138     InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture_nv12",          streamProducerD3DTextureNV12,       &extensionStrings);
1139     InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility",        createContextWebGLCompatibility,    &extensionStrings);
1140     InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings);
1141     InsertExtensionString("EGL_CHROMIUM_sync_control",                           getSyncValues,                      &extensionStrings);
1142     InsertExtensionString("EGL_EXT_swap_buffers_with_damage",                    swapBuffersWithDamage,              &extensionStrings);
1143     InsertExtensionString("EGL_EXT_pixel_format_float",                          pixelFormatFloat,                   &extensionStrings);
1144     InsertExtensionString("EGL_KHR_surfaceless_context",                         surfacelessContext,                 &extensionStrings);
1145     InsertExtensionString("EGL_ANGLE_display_texture_share_group",               displayTextureShareGroup,           &extensionStrings);
1146     InsertExtensionString("EGL_ANGLE_create_context_client_arrays",              createContextClientArrays,          &extensionStrings);
1147     InsertExtensionString("EGL_ANGLE_program_cache_control",                     programCacheControl,                &extensionStrings);
1148     InsertExtensionString("EGL_ANGLE_robust_resource_initialization",            robustResourceInitialization,       &extensionStrings);
1149     // TODO(jmadill): Enable this when complete.
1150     //InsertExtensionString("KHR_create_context_no_error",                       createContextNoError,               &extensionStrings);
1151     // clang-format on
1152 
1153     return extensionStrings;
1154 }
1155 
DeviceExtensions()1156 DeviceExtensions::DeviceExtensions()
1157     : deviceD3D(false)
1158 {
1159 }
1160 
getStrings() const1161 std::vector<std::string> DeviceExtensions::getStrings() const
1162 {
1163     std::vector<std::string> extensionStrings;
1164 
1165     //                   | Extension name                                 | Supported flag                | Output vector   |
1166     InsertExtensionString("EGL_ANGLE_device_d3d",                          deviceD3D,                      &extensionStrings);
1167 
1168     return extensionStrings;
1169 }
1170 
ClientExtensions()1171 ClientExtensions::ClientExtensions()
1172     : clientExtensions(false),
1173       platformBase(false),
1174       platformDevice(false),
1175       platformANGLE(false),
1176       platformANGLED3D(false),
1177       platformANGLEOpenGL(false),
1178       platformANGLEVulkan(false),
1179       deviceCreation(false),
1180       deviceCreationD3D11(false),
1181       x11Visual(false),
1182       experimentalPresentPath(false),
1183       clientGetAllProcAddresses(false)
1184 {
1185 }
1186 
1187 ClientExtensions::ClientExtensions(const ClientExtensions &other) = default;
1188 
getStrings() const1189 std::vector<std::string> ClientExtensions::getStrings() const
1190 {
1191     std::vector<std::string> extensionStrings;
1192 
1193     // clang-format off
1194     //                   | Extension name                         | Supported flag           | Output vector   |
1195     InsertExtensionString("EGL_EXT_client_extensions",             clientExtensions,          &extensionStrings);
1196     InsertExtensionString("EGL_EXT_platform_base",                 platformBase,              &extensionStrings);
1197     InsertExtensionString("EGL_EXT_platform_device",               platformDevice,            &extensionStrings);
1198     InsertExtensionString("EGL_ANGLE_platform_angle",              platformANGLE,             &extensionStrings);
1199     InsertExtensionString("EGL_ANGLE_platform_angle_d3d",          platformANGLED3D,          &extensionStrings);
1200     InsertExtensionString("EGL_ANGLE_platform_angle_opengl",       platformANGLEOpenGL,       &extensionStrings);
1201     InsertExtensionString("EGL_ANGLE_platform_angle_null",         platformANGLENULL,         &extensionStrings);
1202     InsertExtensionString("EGL_ANGLE_platform_angle_vulkan",       platformANGLEVulkan,       &extensionStrings);
1203     InsertExtensionString("EGL_ANGLE_device_creation",             deviceCreation,            &extensionStrings);
1204     InsertExtensionString("EGL_ANGLE_device_creation_d3d11",       deviceCreationD3D11,       &extensionStrings);
1205     InsertExtensionString("EGL_ANGLE_x11_visual",                  x11Visual,                 &extensionStrings);
1206     InsertExtensionString("EGL_ANGLE_experimental_present_path",   experimentalPresentPath,   &extensionStrings);
1207     InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings);
1208     // clang-format on
1209 
1210     return extensionStrings;
1211 }
1212 
1213 }  // namespace egl
1214