• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2013 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 // formatutils.cpp: Queries for GL image formats.
8 
9 #include "libANGLE/formatutils.h"
10 
11 #include "anglebase/no_destructor.h"
12 #include "common/mathutil.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/Framebuffer.h"
15 
16 using namespace angle;
17 
18 namespace gl
19 {
20 
21 // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the
22 // implementation can decide the true, sized, internal format. The ES2FormatMap determines the
23 // internal format for all valid format and type combinations.
24 GLenum GetSizedFormatInternal(GLenum format, GLenum type);
25 
26 namespace
27 {
28 using InternalFormatInfoMap =
29     std::unordered_map<GLenum, std::unordered_map<GLenum, InternalFormat>>;
30 
CheckedMathResult(const CheckedNumeric<GLuint> & value,GLuint * resultOut)31 bool CheckedMathResult(const CheckedNumeric<GLuint> &value, GLuint *resultOut)
32 {
33     if (!value.IsValid())
34     {
35         return false;
36     }
37     else
38     {
39         *resultOut = value.ValueOrDie();
40         return true;
41     }
42 }
43 
PackTypeInfo(GLuint bytes,bool specialized)44 constexpr uint32_t PackTypeInfo(GLuint bytes, bool specialized)
45 {
46     // static_assert within constexpr requires c++17
47     // static_assert(isPow2(bytes));
48     return bytes | (rx::Log2(bytes) << 8) | (specialized << 16);
49 }
50 
51 }  // anonymous namespace
52 
FormatType()53 FormatType::FormatType() : format(GL_NONE), type(GL_NONE) {}
54 
FormatType(GLenum format_,GLenum type_)55 FormatType::FormatType(GLenum format_, GLenum type_) : format(format_), type(type_) {}
56 
operator <(const FormatType & other) const57 bool FormatType::operator<(const FormatType &other) const
58 {
59     if (format != other.format)
60         return format < other.format;
61     return type < other.type;
62 }
63 
operator <(const Type & a,const Type & b)64 bool operator<(const Type &a, const Type &b)
65 {
66     return memcmp(&a, &b, sizeof(Type)) < 0;
67 }
68 
69 // Information about internal formats
AlwaysSupported(const Version &,const Extensions &)70 static bool AlwaysSupported(const Version &, const Extensions &)
71 {
72     return true;
73 }
74 
NeverSupported(const Version &,const Extensions &)75 static bool NeverSupported(const Version &, const Extensions &)
76 {
77     return false;
78 }
79 
80 template <GLuint minCoreGLMajorVersion, GLuint minCoreGLMinorVersion>
RequireES(const Version & clientVersion,const Extensions &)81 static bool RequireES(const Version &clientVersion, const Extensions &)
82 {
83     return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion);
84 }
85 
86 // Pointer to a boolean memeber of the Extensions struct
87 typedef bool(Extensions::*ExtensionBool);
88 
89 // Check support for a single extension
90 template <ExtensionBool bool1>
RequireExt(const Version &,const Extensions & extensions)91 static bool RequireExt(const Version &, const Extensions &extensions)
92 {
93     return extensions.*bool1;
94 }
95 
96 // Check for a minimum client version or a single extension
97 template <GLuint minCoreGLMajorVersion, GLuint minCoreGLMinorVersion, ExtensionBool bool1>
RequireESOrExt(const Version & clientVersion,const Extensions & extensions)98 static bool RequireESOrExt(const Version &clientVersion, const Extensions &extensions)
99 {
100     return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
101            extensions.*bool1;
102 }
103 
104 // Check for a minimum client version or two extensions
105 template <GLuint minCoreGLMajorVersion,
106           GLuint minCoreGLMinorVersion,
107           ExtensionBool bool1,
108           ExtensionBool bool2>
RequireESOrExtAndExt(const Version & clientVersion,const Extensions & extensions)109 static bool RequireESOrExtAndExt(const Version &clientVersion, const Extensions &extensions)
110 {
111     return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
112            (extensions.*bool1 && extensions.*bool2);
113 }
114 
115 // Check for a minimum client version or at least one of two extensions
116 template <GLuint minCoreGLMajorVersion,
117           GLuint minCoreGLMinorVersion,
118           ExtensionBool bool1,
119           ExtensionBool bool2>
RequireESOrExtOrExt(const Version & clientVersion,const Extensions & extensions)120 static bool RequireESOrExtOrExt(const Version &clientVersion, const Extensions &extensions)
121 {
122     return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
123            extensions.*bool1 || extensions.*bool2;
124 }
125 
126 // Check support for two extensions
127 template <ExtensionBool bool1, ExtensionBool bool2>
RequireExtAndExt(const Version &,const Extensions & extensions)128 static bool RequireExtAndExt(const Version &, const Extensions &extensions)
129 {
130     return extensions.*bool1 && extensions.*bool2;
131 }
132 
133 // Check support for either of two extensions
134 template <ExtensionBool bool1, ExtensionBool bool2>
RequireExtOrExt(const Version &,const Extensions & extensions)135 static bool RequireExtOrExt(const Version &, const Extensions &extensions)
136 {
137     return extensions.*bool1 || extensions.*bool2;
138 }
139 
140 // Check support for any of three extensions
141 template <ExtensionBool bool1, ExtensionBool bool2, ExtensionBool bool3>
RequireExtOrExtOrExt(const Version &,const Extensions & extensions)142 static bool RequireExtOrExtOrExt(const Version &, const Extensions &extensions)
143 {
144     return extensions.*bool1 || extensions.*bool2 || extensions.*bool3;
145 }
146 
147 // R8, RG8
SizedRGSupport(const Version & clientVersion,const Extensions & extensions)148 static bool SizedRGSupport(const Version &clientVersion, const Extensions &extensions)
149 {
150     return clientVersion >= Version(3, 0) || (extensions.textureStorage && extensions.textureRG);
151 }
152 
153 // R16F, RG16F with HALF_FLOAT_OES type
SizedHalfFloatOESRGSupport(const Version & clientVersion,const Extensions & extensions)154 static bool SizedHalfFloatOESRGSupport(const Version &clientVersion, const Extensions &extensions)
155 {
156     return extensions.textureStorage && extensions.textureHalfFloat && extensions.textureRG;
157 }
158 
SizedHalfFloatOESRGTextureAttachmentSupport(const Version & clientVersion,const Extensions & extensions)159 static bool SizedHalfFloatOESRGTextureAttachmentSupport(const Version &clientVersion,
160                                                         const Extensions &extensions)
161 {
162     return SizedHalfFloatOESRGSupport(clientVersion, extensions) && extensions.colorBufferHalfFloat;
163 }
164 
165 // R16F, RG16F with either HALF_FLOAT_OES or HALF_FLOAT types
SizedHalfFloatRGSupport(const Version & clientVersion,const Extensions & extensions)166 static bool SizedHalfFloatRGSupport(const Version &clientVersion, const Extensions &extensions)
167 {
168     // HALF_FLOAT
169     if (clientVersion >= Version(3, 0))
170     {
171         return true;
172     }
173     // HALF_FLOAT_OES
174     else
175     {
176         return SizedHalfFloatOESRGSupport(clientVersion, extensions);
177     }
178 }
179 
SizedHalfFloatRGTextureAttachmentSupport(const Version & clientVersion,const Extensions & extensions)180 static bool SizedHalfFloatRGTextureAttachmentSupport(const Version &clientVersion,
181                                                      const Extensions &extensions)
182 {
183     // HALF_FLOAT
184     if (clientVersion >= Version(3, 0))
185     {
186         return extensions.colorBufferFloat;
187     }
188     // HALF_FLOAT_OES
189     else
190     {
191         return SizedHalfFloatOESRGTextureAttachmentSupport(clientVersion, extensions);
192     }
193 }
194 
SizedHalfFloatRGRenderbufferSupport(const Version & clientVersion,const Extensions & extensions)195 static bool SizedHalfFloatRGRenderbufferSupport(const Version &clientVersion,
196                                                 const Extensions &extensions)
197 {
198     return (clientVersion >= Version(3, 0) ||
199             (extensions.textureHalfFloat && extensions.textureRG)) &&
200            (extensions.colorBufferFloat || extensions.colorBufferHalfFloat);
201 }
202 
203 // RGB16F, RGBA16F with HALF_FLOAT_OES type
SizedHalfFloatOESSupport(const Version & clientVersion,const Extensions & extensions)204 static bool SizedHalfFloatOESSupport(const Version &clientVersion, const Extensions &extensions)
205 {
206     return extensions.textureStorage && extensions.textureHalfFloat;
207 }
208 
SizedHalfFloatOESTextureAttachmentSupport(const Version & clientVersion,const Extensions & extensions)209 static bool SizedHalfFloatOESTextureAttachmentSupport(const Version &clientVersion,
210                                                       const Extensions &extensions)
211 {
212     return SizedHalfFloatOESSupport(clientVersion, extensions) && extensions.colorBufferHalfFloat;
213 }
214 
215 // RGB16F, RGBA16F with either HALF_FLOAT_OES or HALF_FLOAT types
SizedHalfFloatSupport(const Version & clientVersion,const Extensions & extensions)216 static bool SizedHalfFloatSupport(const Version &clientVersion, const Extensions &extensions)
217 {
218     // HALF_FLOAT
219     if (clientVersion >= Version(3, 0))
220     {
221         return true;
222     }
223     // HALF_FLOAT_OES
224     else
225     {
226         return SizedHalfFloatOESSupport(clientVersion, extensions);
227     }
228 }
229 
SizedHalfFloatFilterSupport(const Version & clientVersion,const Extensions & extensions)230 static bool SizedHalfFloatFilterSupport(const Version &clientVersion, const Extensions &extensions)
231 {
232     // HALF_FLOAT
233     if (clientVersion >= Version(3, 0))
234     {
235         return true;
236     }
237     // HALF_FLOAT_OES
238     else
239     {
240         return extensions.textureHalfFloatLinear;
241     }
242 }
243 
SizedHalfFloatRGBTextureAttachmentSupport(const Version & clientVersion,const Extensions & extensions)244 static bool SizedHalfFloatRGBTextureAttachmentSupport(const Version &clientVersion,
245                                                       const Extensions &extensions)
246 {
247     // HALF_FLOAT
248     if (clientVersion >= Version(3, 0))
249     {
250         // It is unclear how EXT_color_buffer_half_float applies to ES3.0 and above, however,
251         // dEQP GLES3 es3fFboColorbufferTests.cpp verifies that texture attachment of GL_RGB16F
252         // is possible, so assume that all GLES implementations support it.
253         return extensions.colorBufferHalfFloat;
254     }
255     // HALF_FLOAT_OES
256     else
257     {
258         return SizedHalfFloatOESTextureAttachmentSupport(clientVersion, extensions);
259     }
260 }
261 
SizedHalfFloatRGBRenderbufferSupport(const Version & clientVersion,const Extensions & extensions)262 static bool SizedHalfFloatRGBRenderbufferSupport(const Version &clientVersion,
263                                                  const Extensions &extensions)
264 {
265     return (clientVersion >= Version(3, 0) || extensions.textureHalfFloat) &&
266            extensions.colorBufferHalfFloat;
267 }
268 
SizedHalfFloatRGBATextureAttachmentSupport(const Version & clientVersion,const Extensions & extensions)269 static bool SizedHalfFloatRGBATextureAttachmentSupport(const Version &clientVersion,
270                                                        const Extensions &extensions)
271 {
272     // HALF_FLOAT
273     if (clientVersion >= Version(3, 0))
274     {
275         return extensions.colorBufferFloat;
276     }
277     // HALF_FLOAT_OES
278     else
279     {
280         return SizedHalfFloatOESTextureAttachmentSupport(clientVersion, extensions);
281     }
282 }
283 
SizedHalfFloatRGBARenderbufferSupport(const Version & clientVersion,const Extensions & extensions)284 static bool SizedHalfFloatRGBARenderbufferSupport(const Version &clientVersion,
285                                                   const Extensions &extensions)
286 {
287     return (clientVersion >= Version(3, 0) || extensions.textureHalfFloat) &&
288            (extensions.colorBufferFloat || extensions.colorBufferHalfFloat);
289 }
290 
291 // R32F, RG32F
SizedFloatRGSupport(const Version & clientVersion,const Extensions & extensions)292 static bool SizedFloatRGSupport(const Version &clientVersion, const Extensions &extensions)
293 {
294     return clientVersion >= Version(3, 0) ||
295            (extensions.textureStorage && extensions.textureFloat && extensions.textureRG);
296 }
297 
298 // RGB32F
SizedFloatRGBSupport(const Version & clientVersion,const Extensions & extensions)299 static bool SizedFloatRGBSupport(const Version &clientVersion, const Extensions &extensions)
300 {
301     return clientVersion >= Version(3, 0) ||
302            (extensions.textureStorage && extensions.textureFloat) || extensions.colorBufferFloatRGB;
303 }
304 
305 // RGBA32F
SizedFloatRGBASupport(const Version & clientVersion,const Extensions & extensions)306 static bool SizedFloatRGBASupport(const Version &clientVersion, const Extensions &extensions)
307 {
308     return clientVersion >= Version(3, 0) ||
309            (extensions.textureStorage && extensions.textureFloat) ||
310            extensions.colorBufferFloatRGBA;
311 }
312 
SizedFloatRGBARenderableSupport(const Version & clientVersion,const Extensions & extensions)313 static bool SizedFloatRGBARenderableSupport(const Version &clientVersion,
314                                             const Extensions &extensions)
315 {
316     // This logic is the same for both Renderbuffers and TextureAttachment.
317     return extensions.colorBufferFloatRGBA ||  // ES2
318            extensions.colorBufferFloat;        // ES3
319 }
320 
InternalFormat()321 InternalFormat::InternalFormat()
322     : internalFormat(GL_NONE),
323       sized(false),
324       sizedInternalFormat(GL_NONE),
325       redBits(0),
326       greenBits(0),
327       blueBits(0),
328       luminanceBits(0),
329       alphaBits(0),
330       sharedBits(0),
331       depthBits(0),
332       stencilBits(0),
333       pixelBytes(0),
334       componentCount(0),
335       compressed(false),
336       compressedBlockWidth(0),
337       compressedBlockHeight(0),
338       compressedBlockDepth(0),
339       format(GL_NONE),
340       type(GL_NONE),
341       componentType(GL_NONE),
342       colorEncoding(GL_NONE),
343       textureSupport(NeverSupported),
344       filterSupport(NeverSupported),
345       textureAttachmentSupport(NeverSupported),
346       renderbufferSupport(NeverSupported)
347 {}
348 
349 InternalFormat::InternalFormat(const InternalFormat &other) = default;
350 
isLUMA() const351 bool InternalFormat::isLUMA() const
352 {
353     return ((redBits + greenBits + blueBits + depthBits + stencilBits) == 0 &&
354             (luminanceBits + alphaBits) > 0);
355 }
356 
getReadPixelsFormat() const357 GLenum InternalFormat::getReadPixelsFormat() const
358 {
359     return format;
360 }
361 
getReadPixelsType(const Version & version) const362 GLenum InternalFormat::getReadPixelsType(const Version &version) const
363 {
364     switch (type)
365     {
366         case GL_HALF_FLOAT:
367         case GL_HALF_FLOAT_OES:
368             if (version < Version(3, 0))
369             {
370                 // The internal format may have a type of GL_HALF_FLOAT but when exposing this type
371                 // as the IMPLEMENTATION_READ_TYPE, only HALF_FLOAT_OES is allowed by
372                 // OES_texture_half_float.  HALF_FLOAT becomes core in ES3 and is acceptable to use
373                 // as an IMPLEMENTATION_READ_TYPE.
374                 return GL_HALF_FLOAT_OES;
375             }
376             else
377             {
378                 return GL_HALF_FLOAT;
379             }
380 
381         default:
382             return type;
383     }
384 }
385 
isRequiredRenderbufferFormat(const Version & version) const386 bool InternalFormat::isRequiredRenderbufferFormat(const Version &version) const
387 {
388     // GLES 3.0.5 section 4.4.2.2:
389     // "Implementations are required to support the same internal formats for renderbuffers as the
390     // required formats for textures enumerated in section 3.8.3.1, with the exception of the color
391     // formats labelled "texture-only"."
392     if (!sized || compressed)
393     {
394         return false;
395     }
396 
397     // Luma formats.
398     if (isLUMA())
399     {
400         return false;
401     }
402 
403     // Depth/stencil formats.
404     if (depthBits > 0 || stencilBits > 0)
405     {
406         // GLES 2.0.25 table 4.5.
407         // GLES 3.0.5 section 3.8.3.1.
408         // GLES 3.1 table 8.14.
409 
410         // Required formats in all versions.
411         switch (internalFormat)
412         {
413             case GL_DEPTH_COMPONENT16:
414             case GL_STENCIL_INDEX8:
415                 // Note that STENCIL_INDEX8 is not mentioned in GLES 3.0.5 section 3.8.3.1, but it
416                 // is in section 4.4.2.2.
417                 return true;
418             default:
419                 break;
420         }
421         if (version.major < 3)
422         {
423             return false;
424         }
425         // Required formats in GLES 3.0 and up.
426         switch (internalFormat)
427         {
428             case GL_DEPTH_COMPONENT32F:
429             case GL_DEPTH_COMPONENT24:
430             case GL_DEPTH32F_STENCIL8:
431             case GL_DEPTH24_STENCIL8:
432                 return true;
433             default:
434                 return false;
435         }
436     }
437 
438     // RGBA formats.
439     // GLES 2.0.25 table 4.5.
440     // GLES 3.0.5 section 3.8.3.1.
441     // GLES 3.1 table 8.13.
442 
443     // Required formats in all versions.
444     switch (internalFormat)
445     {
446         case GL_RGBA4:
447         case GL_RGB5_A1:
448         case GL_RGB565:
449             return true;
450         default:
451             break;
452     }
453     if (version.major < 3)
454     {
455         return false;
456     }
457 
458     if (format == GL_BGRA_EXT)
459     {
460         return false;
461     }
462 
463     switch (componentType)
464     {
465         case GL_SIGNED_NORMALIZED:
466         case GL_FLOAT:
467             return false;
468         case GL_UNSIGNED_INT:
469         case GL_INT:
470             // Integer RGB formats are not required renderbuffer formats.
471             if (alphaBits == 0 && blueBits != 0)
472             {
473                 return false;
474             }
475             // All integer R and RG formats are required.
476             // Integer RGBA formats including RGB10_A2_UI are required.
477             return true;
478         case GL_UNSIGNED_NORMALIZED:
479             if (internalFormat == GL_SRGB8)
480             {
481                 return false;
482             }
483             return true;
484         default:
485             UNREACHABLE();
486 #if !UNREACHABLE_IS_NORETURN
487             return false;
488 #endif
489     }
490 }
491 
isInt() const492 bool InternalFormat::isInt() const
493 {
494     return componentType == GL_INT || componentType == GL_UNSIGNED_INT;
495 }
496 
isDepthOrStencil() const497 bool InternalFormat::isDepthOrStencil() const
498 {
499     return depthBits != 0 || stencilBits != 0;
500 }
501 
Format(GLenum internalFormat)502 Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) {}
503 
Format(const InternalFormat & internalFormat)504 Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) {}
505 
Format(GLenum internalFormat,GLenum type)506 Format::Format(GLenum internalFormat, GLenum type)
507     : info(&GetInternalFormatInfo(internalFormat, type))
508 {}
509 
510 Format::Format(const Format &other) = default;
511 Format &Format::operator=(const Format &other) = default;
512 
valid() const513 bool Format::valid() const
514 {
515     return info->internalFormat != GL_NONE;
516 }
517 
518 // static
SameSized(const Format & a,const Format & b)519 bool Format::SameSized(const Format &a, const Format &b)
520 {
521     return a.info->sizedInternalFormat == b.info->sizedInternalFormat;
522 }
523 
EquivalentBlitInternalFormat(GLenum internalformat)524 static GLenum EquivalentBlitInternalFormat(GLenum internalformat)
525 {
526     // BlitFramebuffer works if the color channels are identically
527     // sized, even if there is a swizzle (for example, blitting from a
528     // multisampled RGBA8 renderbuffer to a BGRA8 texture). This could
529     // be expanded and/or autogenerated if that is found necessary.
530     if (internalformat == GL_BGRA8_EXT)
531         return GL_RGBA8;
532     return internalformat;
533 }
534 
535 // static
EquivalentForBlit(const Format & a,const Format & b)536 bool Format::EquivalentForBlit(const Format &a, const Format &b)
537 {
538     return (EquivalentBlitInternalFormat(a.info->sizedInternalFormat) ==
539             EquivalentBlitInternalFormat(b.info->sizedInternalFormat));
540 }
541 
542 // static
Invalid()543 Format Format::Invalid()
544 {
545     static Format invalid(GL_NONE, GL_NONE);
546     return invalid;
547 }
548 
operator <<(std::ostream & os,const Format & fmt)549 std::ostream &operator<<(std::ostream &os, const Format &fmt)
550 {
551     // TODO(ynovikov): return string representation when available
552     return FmtHex(os, fmt.info->sizedInternalFormat);
553 }
554 
operator ==(const InternalFormat & other) const555 bool InternalFormat::operator==(const InternalFormat &other) const
556 {
557     // We assume all internal formats are unique if they have the same internal format and type
558     return internalFormat == other.internalFormat && type == other.type;
559 }
560 
operator !=(const InternalFormat & other) const561 bool InternalFormat::operator!=(const InternalFormat &other) const
562 {
563     return !(*this == other);
564 }
565 
InsertFormatInfo(InternalFormatInfoMap * map,const InternalFormat & formatInfo)566 void InsertFormatInfo(InternalFormatInfoMap *map, const InternalFormat &formatInfo)
567 {
568     ASSERT(!formatInfo.sized || (*map).count(formatInfo.internalFormat) == 0);
569     ASSERT((*map)[formatInfo.internalFormat].count(formatInfo.type) == 0);
570     (*map)[formatInfo.internalFormat][formatInfo.type] = formatInfo;
571 }
572 
AddRGBAFormat(InternalFormatInfoMap * map,GLenum internalFormat,bool sized,GLuint red,GLuint green,GLuint blue,GLuint alpha,GLuint shared,GLenum format,GLenum type,GLenum componentType,bool srgb,InternalFormat::SupportCheckFunction textureSupport,InternalFormat::SupportCheckFunction filterSupport,InternalFormat::SupportCheckFunction textureAttachmentSupport,InternalFormat::SupportCheckFunction renderbufferSupport)573 void AddRGBAFormat(InternalFormatInfoMap *map,
574                    GLenum internalFormat,
575                    bool sized,
576                    GLuint red,
577                    GLuint green,
578                    GLuint blue,
579                    GLuint alpha,
580                    GLuint shared,
581                    GLenum format,
582                    GLenum type,
583                    GLenum componentType,
584                    bool srgb,
585                    InternalFormat::SupportCheckFunction textureSupport,
586                    InternalFormat::SupportCheckFunction filterSupport,
587                    InternalFormat::SupportCheckFunction textureAttachmentSupport,
588                    InternalFormat::SupportCheckFunction renderbufferSupport)
589 {
590     InternalFormat formatInfo;
591     formatInfo.internalFormat = internalFormat;
592     formatInfo.sized          = sized;
593     formatInfo.sizedInternalFormat =
594         sized ? internalFormat : GetSizedFormatInternal(internalFormat, type);
595     formatInfo.redBits    = red;
596     formatInfo.greenBits  = green;
597     formatInfo.blueBits   = blue;
598     formatInfo.alphaBits  = alpha;
599     formatInfo.sharedBits = shared;
600     formatInfo.pixelBytes = (red + green + blue + alpha + shared) / 8;
601     formatInfo.componentCount =
602         ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
603     formatInfo.format                   = format;
604     formatInfo.type                     = type;
605     formatInfo.componentType            = componentType;
606     formatInfo.colorEncoding            = (srgb ? GL_SRGB : GL_LINEAR);
607     formatInfo.textureSupport           = textureSupport;
608     formatInfo.filterSupport            = filterSupport;
609     formatInfo.textureAttachmentSupport = textureAttachmentSupport;
610     formatInfo.renderbufferSupport      = renderbufferSupport;
611 
612     InsertFormatInfo(map, formatInfo);
613 }
614 
AddLUMAFormat(InternalFormatInfoMap * map,GLenum internalFormat,bool sized,GLuint luminance,GLuint alpha,GLenum format,GLenum type,GLenum componentType,InternalFormat::SupportCheckFunction textureSupport,InternalFormat::SupportCheckFunction filterSupport,InternalFormat::SupportCheckFunction textureAttachmentSupport,InternalFormat::SupportCheckFunction renderbufferSupport)615 static void AddLUMAFormat(InternalFormatInfoMap *map,
616                           GLenum internalFormat,
617                           bool sized,
618                           GLuint luminance,
619                           GLuint alpha,
620                           GLenum format,
621                           GLenum type,
622                           GLenum componentType,
623                           InternalFormat::SupportCheckFunction textureSupport,
624                           InternalFormat::SupportCheckFunction filterSupport,
625                           InternalFormat::SupportCheckFunction textureAttachmentSupport,
626                           InternalFormat::SupportCheckFunction renderbufferSupport)
627 {
628     InternalFormat formatInfo;
629     formatInfo.internalFormat = internalFormat;
630     formatInfo.sized          = sized;
631     formatInfo.sizedInternalFormat =
632         sized ? internalFormat : GetSizedFormatInternal(internalFormat, type);
633     formatInfo.luminanceBits            = luminance;
634     formatInfo.alphaBits                = alpha;
635     formatInfo.pixelBytes               = (luminance + alpha) / 8;
636     formatInfo.componentCount           = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
637     formatInfo.format                   = format;
638     formatInfo.type                     = type;
639     formatInfo.componentType            = componentType;
640     formatInfo.colorEncoding            = GL_LINEAR;
641     formatInfo.textureSupport           = textureSupport;
642     formatInfo.filterSupport            = filterSupport;
643     formatInfo.textureAttachmentSupport = textureAttachmentSupport;
644     formatInfo.renderbufferSupport      = renderbufferSupport;
645 
646     InsertFormatInfo(map, formatInfo);
647 }
648 
AddDepthStencilFormat(InternalFormatInfoMap * map,GLenum internalFormat,bool sized,GLuint depthBits,GLuint stencilBits,GLuint unusedBits,GLenum format,GLenum type,GLenum componentType,InternalFormat::SupportCheckFunction textureSupport,InternalFormat::SupportCheckFunction filterSupport,InternalFormat::SupportCheckFunction textureAttachmentSupport,InternalFormat::SupportCheckFunction renderbufferSupport)649 void AddDepthStencilFormat(InternalFormatInfoMap *map,
650                            GLenum internalFormat,
651                            bool sized,
652                            GLuint depthBits,
653                            GLuint stencilBits,
654                            GLuint unusedBits,
655                            GLenum format,
656                            GLenum type,
657                            GLenum componentType,
658                            InternalFormat::SupportCheckFunction textureSupport,
659                            InternalFormat::SupportCheckFunction filterSupport,
660                            InternalFormat::SupportCheckFunction textureAttachmentSupport,
661                            InternalFormat::SupportCheckFunction renderbufferSupport)
662 {
663     InternalFormat formatInfo;
664     formatInfo.internalFormat = internalFormat;
665     formatInfo.sized          = sized;
666     formatInfo.sizedInternalFormat =
667         sized ? internalFormat : GetSizedFormatInternal(internalFormat, type);
668     formatInfo.depthBits                = depthBits;
669     formatInfo.stencilBits              = stencilBits;
670     formatInfo.pixelBytes               = (depthBits + stencilBits + unusedBits) / 8;
671     formatInfo.componentCount           = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
672     formatInfo.format                   = format;
673     formatInfo.type                     = type;
674     formatInfo.componentType            = componentType;
675     formatInfo.colorEncoding            = GL_LINEAR;
676     formatInfo.textureSupport           = textureSupport;
677     formatInfo.filterSupport            = filterSupport;
678     formatInfo.textureAttachmentSupport = textureAttachmentSupport;
679     formatInfo.renderbufferSupport      = renderbufferSupport;
680 
681     InsertFormatInfo(map, formatInfo);
682 }
683 
AddCompressedFormat(InternalFormatInfoMap * map,GLenum internalFormat,GLuint compressedBlockWidth,GLuint compressedBlockHeight,GLuint compressedBlockDepth,GLuint compressedBlockSize,GLuint componentCount,bool srgb,InternalFormat::SupportCheckFunction textureSupport,InternalFormat::SupportCheckFunction filterSupport,InternalFormat::SupportCheckFunction textureAttachmentSupport,InternalFormat::SupportCheckFunction renderbufferSupport)684 void AddCompressedFormat(InternalFormatInfoMap *map,
685                          GLenum internalFormat,
686                          GLuint compressedBlockWidth,
687                          GLuint compressedBlockHeight,
688                          GLuint compressedBlockDepth,
689                          GLuint compressedBlockSize,
690                          GLuint componentCount,
691                          bool srgb,
692                          InternalFormat::SupportCheckFunction textureSupport,
693                          InternalFormat::SupportCheckFunction filterSupport,
694                          InternalFormat::SupportCheckFunction textureAttachmentSupport,
695                          InternalFormat::SupportCheckFunction renderbufferSupport)
696 {
697     InternalFormat formatInfo;
698     formatInfo.internalFormat           = internalFormat;
699     formatInfo.sized                    = true;
700     formatInfo.sizedInternalFormat      = internalFormat;
701     formatInfo.compressedBlockWidth     = compressedBlockWidth;
702     formatInfo.compressedBlockHeight    = compressedBlockHeight;
703     formatInfo.compressedBlockDepth     = compressedBlockDepth;
704     formatInfo.pixelBytes               = compressedBlockSize / 8;
705     formatInfo.componentCount           = componentCount;
706     formatInfo.format                   = internalFormat;
707     formatInfo.type                     = GL_UNSIGNED_BYTE;
708     formatInfo.componentType            = GL_UNSIGNED_NORMALIZED;
709     formatInfo.colorEncoding            = (srgb ? GL_SRGB : GL_LINEAR);
710     formatInfo.compressed               = true;
711     formatInfo.textureSupport           = textureSupport;
712     formatInfo.filterSupport            = filterSupport;
713     formatInfo.textureAttachmentSupport = textureAttachmentSupport;
714     formatInfo.renderbufferSupport      = renderbufferSupport;
715 
716     InsertFormatInfo(map, formatInfo);
717 }
718 
719 // Notes:
720 // 1. "Texture supported" includes all the means by which texture can be created, however,
721 //    GL_EXT_texture_storage in ES2 is a special case, when only glTexStorage* is allowed.
722 //    The assumption is that ES2 validation will not check textureSupport for sized formats.
723 //
724 // 2. Sized half float types are a combination of GL_HALF_FLOAT and GL_HALF_FLOAT_OES support,
725 //    due to a limitation that only one type for sized formats is allowed.
726 //
727 // TODO(ynovikov): http://anglebug.com/2846 Verify support fields of BGRA, depth, stencil
728 // and compressed formats. Perform texturable check as part of filterable and attachment checks.
BuildInternalFormatInfoMap()729 static InternalFormatInfoMap BuildInternalFormatInfoMap()
730 {
731     InternalFormatInfoMap map;
732 
733     // From ES 3.0.1 spec, table 3.12
734     map[GL_NONE][GL_NONE] = InternalFormat();
735 
736     // clang-format off
737 
738     //                 | Internal format     |sized| R | G | B | A |S | Format         | Type                             | Component type        | SRGB | Texture supported                                | Filterable     | Texture attachment                               | Renderbuffer                                 |
739     AddRGBAFormat(&map, GL_R8,                true,  8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, SizedRGSupport,                                    AlwaysSupported, SizedRGSupport,                                    RequireESOrExt<3, 0, &Extensions::textureRG>  );
740     AddRGBAFormat(&map, GL_R8_SNORM,          true,  8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                           GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                                   AlwaysSupported, NeverSupported,                                    NeverSupported                                );
741     AddRGBAFormat(&map, GL_RG8,               true,  8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, SizedRGSupport,                                    AlwaysSupported, SizedRGSupport,                                    RequireESOrExt<3, 0, &Extensions::textureRG>  );
742     AddRGBAFormat(&map, GL_RG8_SNORM,         true,  8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                           GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                                   AlwaysSupported, NeverSupported,                                    NeverSupported                                );
743     AddRGBAFormat(&map, GL_RGB8,              true,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorage>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorage>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>  );
744     AddRGBAFormat(&map, GL_RGB8_SNORM,        true,  8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                           GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                                   AlwaysSupported, NeverSupported,                                    NeverSupported                                );
745     AddRGBAFormat(&map, GL_RGB565,            true,  5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,           GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorage>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorage>, RequireES<2, 0>                               );
746     AddRGBAFormat(&map, GL_RGBA4,             true,  4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,         GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorage>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorage>, RequireES<2, 0>                               );
747     AddRGBAFormat(&map, GL_RGB5_A1,           true,  5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,         GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorage>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorage>, RequireES<2, 0>                               );
748     AddRGBAFormat(&map, GL_RGBA8,             true,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorage>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorage>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>  );
749     AddRGBAFormat(&map, GL_RGBA8_SNORM,       true,  8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                           GL_SIGNED_NORMALIZED,   false, RequireES<3, 0>,                                   AlwaysSupported, NeverSupported,                                    NeverSupported                                );
750     AddRGBAFormat(&map, GL_RGB10_A2,          true, 10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,    GL_UNSIGNED_NORMALIZED, false, RequireES<3, 0>,                                   AlwaysSupported, RequireES<3, 0>,                                   RequireES<3, 0>                               );
751     AddRGBAFormat(&map, GL_RGB10_A2UI,        true, 10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV,    GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
752     AddRGBAFormat(&map, GL_SRGB8,             true,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, true,  RequireES<3, 0>,                                   AlwaysSupported, NeverSupported,                                    NeverSupported                                );
753     AddRGBAFormat(&map, GL_SRGB8_ALPHA8,      true,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, true,  RequireES<3, 0>,                                   AlwaysSupported, RequireES<3, 0>,                                   RequireESOrExt<3, 0, &Extensions::sRGB>       );
754     AddRGBAFormat(&map, GL_R11F_G11F_B10F,    true, 11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV,   GL_FLOAT,               false, RequireES<3, 0>,                                   AlwaysSupported, RequireExt<&Extensions::colorBufferFloat>,         RequireExt<&Extensions::colorBufferFloat>     );
755     AddRGBAFormat(&map, GL_RGB9_E5,           true,  9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,       GL_FLOAT,               false, RequireES<3, 0>,                                   AlwaysSupported, NeverSupported,                                    NeverSupported                                );
756     AddRGBAFormat(&map, GL_R8I,               true,  8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                           GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
757     AddRGBAFormat(&map, GL_R8UI,              true,  8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
758     AddRGBAFormat(&map, GL_R16I,              true, 16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                          GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
759     AddRGBAFormat(&map, GL_R16UI,             true, 16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,                 GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
760     AddRGBAFormat(&map, GL_R32I,              true, 32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                            GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
761     AddRGBAFormat(&map, GL_R32UI,             true, 32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                   GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
762     AddRGBAFormat(&map, GL_RG8I,              true,  8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                           GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
763     AddRGBAFormat(&map, GL_RG8UI,             true,  8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
764     AddRGBAFormat(&map, GL_RG16I,             true, 16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                          GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
765     AddRGBAFormat(&map, GL_RG16UI,            true, 16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,                 GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
766     AddRGBAFormat(&map, GL_RG32I,             true, 32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                            GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
767     AddRGBAFormat(&map, GL_RG32UI,            true, 32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                   GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
768     AddRGBAFormat(&map, GL_RGB8I,             true,  8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                           GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  NeverSupported,                                    NeverSupported                                );
769     AddRGBAFormat(&map, GL_RGB8UI,            true,  8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  NeverSupported,                                    NeverSupported                                );
770     AddRGBAFormat(&map, GL_RGB16I,            true, 16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                          GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  NeverSupported,                                    NeverSupported                                );
771     AddRGBAFormat(&map, GL_RGB16UI,           true, 16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,                 GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  NeverSupported,                                    NeverSupported                                );
772     AddRGBAFormat(&map, GL_RGB32I,            true, 32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                            GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  NeverSupported,                                    NeverSupported                                );
773     AddRGBAFormat(&map, GL_RGB32UI,           true, 32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                   GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  NeverSupported,                                    NeverSupported                                );
774     AddRGBAFormat(&map, GL_RGBA8I,            true,  8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                           GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
775     AddRGBAFormat(&map, GL_RGBA8UI,           true,  8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
776     AddRGBAFormat(&map, GL_RGBA16I,           true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                          GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
777     AddRGBAFormat(&map, GL_RGBA16UI,          true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
778     AddRGBAFormat(&map, GL_RGBA32I,           true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                            GL_INT,                 false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
779     AddRGBAFormat(&map, GL_RGBA32UI,          true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                   GL_UNSIGNED_INT,        false, RequireES<3, 0>,                                   NeverSupported,  RequireES<3, 0>,                                   RequireES<3, 0>                               );
780 
781     AddRGBAFormat(&map, GL_BGRA8_EXT,         true,  8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>,    AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888>,    RequireExt<&Extensions::textureFormatBGRA8888>);
782     AddRGBAFormat(&map, GL_BGRA4_ANGLEX,      true,  4,  4,  4,  4, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>,    AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888>,    RequireExt<&Extensions::textureFormatBGRA8888>);
783     AddRGBAFormat(&map, GL_BGR5_A1_ANGLEX,    true,  5,  5,  5,  1, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>,    AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888>,    RequireExt<&Extensions::textureFormatBGRA8888>);
784 
785     // Special format that is used for D3D textures that are used within ANGLE via the
786     // EGL_ANGLE_d3d_texture_client_buffer extension. We don't allow uploading texture images with
787     // this format, but textures in this format can be created from D3D textures, and filtering them
788     // and rendering to them is allowed.
789     AddRGBAFormat(&map, GL_BGRA8_SRGB_ANGLEX, true,  8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, true,  NeverSupported,                                    AlwaysSupported, AlwaysSupported,                                   AlwaysSupported                               );
790 
791     // Special format which is not really supported, so always false for all supports.
792     AddRGBAFormat(&map, GL_BGRX8_ANGLEX,      true,  8,  8,  8,  0, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, NeverSupported,                                    NeverSupported,  NeverSupported,                                    NeverSupported                                );
793     AddRGBAFormat(&map, GL_BGR565_ANGLEX,     true,  5,  6,  5,  1, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_5_6_5,           GL_UNSIGNED_NORMALIZED, false, NeverSupported,                                    NeverSupported,  NeverSupported,                                    NeverSupported                                );
794 
795     // Floating point formats
796     //                 | Internal format |sized| R | G | B | A |S | Format | Type             | Component type | SRGB | Texture supported         | Filterable                                 | Texture attachment                          | Renderbuffer                            |
797     // It's not possible to have two entries per sized format.
798     // E.g. for GL_RG16F, one with GL_HALF_FLOAT type and the other with GL_HALF_FLOAT_OES type.
799     // So, GL_HALF_FLOAT type formats conditions are merged with GL_HALF_FLOAT_OES type conditions.
800     AddRGBAFormat(&map, GL_R16F,          true, 16,  0,  0,  0, 0, GL_RED,  GL_HALF_FLOAT,     GL_FLOAT,        false, SizedHalfFloatRGSupport,    SizedHalfFloatFilterSupport,                 SizedHalfFloatRGTextureAttachmentSupport,     SizedHalfFloatRGRenderbufferSupport      );
801     AddRGBAFormat(&map, GL_RG16F,         true, 16, 16,  0,  0, 0, GL_RG,   GL_HALF_FLOAT,     GL_FLOAT,        false, SizedHalfFloatRGSupport,    SizedHalfFloatFilterSupport,                 SizedHalfFloatRGTextureAttachmentSupport,     SizedHalfFloatRGRenderbufferSupport      );
802     AddRGBAFormat(&map, GL_RGB16F,        true, 16, 16, 16,  0, 0, GL_RGB,  GL_HALF_FLOAT,     GL_FLOAT,        false, SizedHalfFloatSupport,      SizedHalfFloatFilterSupport,                 SizedHalfFloatRGBTextureAttachmentSupport,    SizedHalfFloatRGBRenderbufferSupport     );
803     AddRGBAFormat(&map, GL_RGBA16F,       true, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT,     GL_FLOAT,        false, SizedHalfFloatSupport,      SizedHalfFloatFilterSupport,                 SizedHalfFloatRGBATextureAttachmentSupport,   SizedHalfFloatRGBARenderbufferSupport    );
804     AddRGBAFormat(&map, GL_R32F,          true, 32,  0,  0,  0, 0, GL_RED,  GL_FLOAT,          GL_FLOAT,        false, SizedFloatRGSupport,        RequireExt<&Extensions::textureFloatLinear>, RequireExt<&Extensions::colorBufferFloat>,    RequireExt<&Extensions::colorBufferFloat>);
805     AddRGBAFormat(&map, GL_RG32F,         true, 32, 32,  0,  0, 0, GL_RG,   GL_FLOAT,          GL_FLOAT,        false, SizedFloatRGSupport,        RequireExt<&Extensions::textureFloatLinear>, RequireExt<&Extensions::colorBufferFloat>,    RequireExt<&Extensions::colorBufferFloat>);
806     AddRGBAFormat(&map, GL_RGB32F,        true, 32, 32, 32,  0, 0, GL_RGB,  GL_FLOAT,          GL_FLOAT,        false, SizedFloatRGBSupport,       RequireExt<&Extensions::textureFloatLinear>, RequireExt<&Extensions::colorBufferFloatRGB>, NeverSupported                           );
807     AddRGBAFormat(&map, GL_RGBA32F,       true, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT,          GL_FLOAT,        false, SizedFloatRGBASupport,      RequireExt<&Extensions::textureFloatLinear>, SizedFloatRGBARenderableSupport,              SizedFloatRGBARenderableSupport          );
808 
809     // ANGLE Depth stencil formats
810     //                         | Internal format         |sized| D |S | X | Format            | Type                             | Component type        | Texture supported                                                | Filterable                                      | Texture attachment                                                                   | Renderbuffer                                                                         |
811     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT16,     true, 16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                                   RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireES<1, 0>,                                RequireES<1, 0>                                                                       );
812     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT24,     true, 24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireES<3, 0>,                                                   RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>,                                                                   RequireESOrExt<3, 0, &Extensions::depth24OES>                                            );
813     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F,    true, 32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireES<3, 0>,                                                   RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>,                                                                   RequireES<3, 0>                                                                       );
814     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, true, 32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32>, AlwaysSupported, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32>);
815     AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8,      true, 24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>,              AlwaysSupported,                                  RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencil>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencil>);
816     AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8,     true, 32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               RequireES<3, 0>,                                                   AlwaysSupported,                                  RequireES<3, 0>,                                                                       RequireES<3, 0>                                                                       );
817     // STENCIL_INDEX8 is special-cased, see around the bottom of the list.
818 
819     // Luminance alpha formats
820     //                | Internal format           |sized| L | A | Format            | Type             | Component type        | Texture supported                                                           | Filterable                                     | Texture attachment | Renderbuffer |
821     AddLUMAFormat(&map, GL_ALPHA8_EXT,             true,  0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>,                                      AlwaysSupported,                                 NeverSupported,      NeverSupported);
822     AddLUMAFormat(&map, GL_LUMINANCE8_EXT,         true,  8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>,                                      AlwaysSupported,                                 NeverSupported,      NeverSupported);
823     AddLUMAFormat(&map, GL_LUMINANCE8_ALPHA8_EXT,  true,  8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>,                                      AlwaysSupported,                                 NeverSupported,      NeverSupported);
824     AddLUMAFormat(&map, GL_ALPHA16F_EXT,           true,  0, 16, GL_ALPHA,           GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,      NeverSupported);
825     AddLUMAFormat(&map, GL_LUMINANCE16F_EXT,       true, 16,  0, GL_LUMINANCE,       GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,      NeverSupported);
826     AddLUMAFormat(&map, GL_LUMINANCE_ALPHA16F_EXT, true, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,      NeverSupported);
827     AddLUMAFormat(&map, GL_ALPHA32F_EXT,           true,  0, 32, GL_ALPHA,           GL_FLOAT,          GL_FLOAT,               RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,      NeverSupported);
828     AddLUMAFormat(&map, GL_LUMINANCE32F_EXT,       true, 32,  0, GL_LUMINANCE,       GL_FLOAT,          GL_FLOAT,               RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,      NeverSupported);
829     AddLUMAFormat(&map, GL_LUMINANCE_ALPHA32F_EXT, true, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,          GL_FLOAT,               RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,      NeverSupported);
830 
831     // Compressed formats, From ES 3.0.1 spec, table 3.16
832     //                       | Internal format                             |W |H |D | BS |CC| SRGB | Texture supported                                                                                                      | Filterable     | Texture attachment | Renderbuffer |
833     AddCompressedFormat(&map, GL_COMPRESSED_R11_EAC,                        4, 4, 1,  64, 1, false, RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedEACR11UnsignedTexture>,              AlwaysSupported, NeverSupported,      NeverSupported);
834     AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_R11_EAC,                 4, 4, 1,  64, 1, false, RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedEACR11SignedTexture>,                AlwaysSupported, NeverSupported,      NeverSupported);
835     AddCompressedFormat(&map, GL_COMPRESSED_RG11_EAC,                       4, 4, 1, 128, 2, false, RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedEACRG11UnsignedTexture>,             AlwaysSupported, NeverSupported,      NeverSupported);
836     AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RG11_EAC,                4, 4, 1, 128, 2, false, RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedEACRG11SignedTexture>,               AlwaysSupported, NeverSupported,      NeverSupported);
837     AddCompressedFormat(&map, GL_COMPRESSED_RGB8_ETC2,                      4, 4, 1,  64, 3, false, RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedETC2RGB8Texture>,                    AlwaysSupported, NeverSupported,      NeverSupported);
838     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ETC2,                     4, 4, 1,  64, 3, true,  RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedETC2sRGB8Texture>,                   AlwaysSupported, NeverSupported,      NeverSupported);
839     AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  4, 4, 1,  64, 3, false, RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedETC2PunchthroughARGB8Texture>,       AlwaysSupported, NeverSupported,      NeverSupported);
840     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 4, 1,  64, 3, true,  RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedETC2PunchthroughAsRGB8AlphaTexture>, AlwaysSupported, NeverSupported,      NeverSupported);
841     AddCompressedFormat(&map, GL_COMPRESSED_RGBA8_ETC2_EAC,                 4, 4, 1, 128, 4, false, RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedETC2RGBA8Texture>,                   AlwaysSupported, NeverSupported,      NeverSupported);
842     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          4, 4, 1, 128, 4, true,  RequireESOrExtOrExt<3, 0, &Extensions::compressedTextureETC, &Extensions::compressedETC2sRGB8Alpha8Texture>,             AlwaysSupported, NeverSupported,      NeverSupported);
843 
844     // From GL_EXT_texture_compression_dxt1
845     //                       | Internal format                   |W |H |D | BS |CC| SRGB | Texture supported                                 | Filterable     | Texture attachment | Renderbuffer |
846     AddCompressedFormat(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    4, 4, 1,  64, 3, false, RequireExt<&Extensions::textureCompressionDXT1>,    AlwaysSupported, NeverSupported,      NeverSupported);
847     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   4, 4, 1,  64, 4, false, RequireExt<&Extensions::textureCompressionDXT1>,    AlwaysSupported, NeverSupported,      NeverSupported);
848 
849     // From GL_ANGLE_texture_compression_dxt3
850     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionDXT3>,    AlwaysSupported, NeverSupported,      NeverSupported);
851 
852     // From GL_ANGLE_texture_compression_dxt5
853     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionDXT5>,    AlwaysSupported, NeverSupported,      NeverSupported);
854 
855     // From GL_OES_compressed_ETC1_RGB8_texture
856     AddCompressedFormat(&map, GL_ETC1_RGB8_OES,                   4, 4, 1,  64, 3, false, RequireExt<&Extensions::compressedETC1RGB8Texture>, AlwaysSupported, NeverSupported,      NeverSupported);
857 
858     // From GL_EXT_texture_compression_s3tc_srgb
859     //                       | Internal format                       |W |H |D | BS |CC|SRGB | Texture supported                                 | Filterable     | Texture attachment | Renderbuffer |
860     AddCompressedFormat(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,       4, 4, 1,  64, 3, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, AlwaysSupported, NeverSupported,      NeverSupported);
861     AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 4, 4, 1,  64, 4, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, AlwaysSupported, NeverSupported,      NeverSupported);
862     AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, AlwaysSupported, NeverSupported,      NeverSupported);
863     AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, AlwaysSupported, NeverSupported,      NeverSupported);
864 
865     // From GL_KHR_texture_compression_astc_ldr and KHR_texture_compression_astc_hdr and GL_OES_texture_compression_astc
866     //                       | Internal format                          | W | H |D | BS |CC| SRGB | Texture supported                                    | Filterable     | Texture attachment | Renderbuffer |
867     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4_KHR,            4,  4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
868     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x4_KHR,            5,  4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
869     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5_KHR,            5,  5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
870     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x5_KHR,            6,  5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
871     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6_KHR,            6,  6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
872     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x5_KHR,            8,  5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
873     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x6_KHR,            8,  6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
874     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x8_KHR,            8,  8, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
875     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x5_KHR,          10,  5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
876     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x6_KHR,          10,  6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
877     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x8_KHR,          10,  8, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
878     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x10_KHR,         10, 10, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
879     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x10_KHR,         12, 10, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
880     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x12_KHR,         12, 12, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
881 
882     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,    4,  4, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
883     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,    5,  4, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
884     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,    5,  5, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
885     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,    6,  5, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
886     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,    6,  6, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
887     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,    8,  5, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
888     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,    8,  6, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
889     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,    8,  8, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
890     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,  10,  5, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
891     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,  10,  6, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
892     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,  10,  8, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
893     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 10, 10, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
894     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 12, 10, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
895     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 12, 12, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCLDRKHR>, AlwaysSupported, NeverSupported,      NeverSupported);
896 
897     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES,          3,  3, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
898     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES,          4,  3, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
899     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES,          4,  4, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
900     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES,          4,  4, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
901     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES,          5,  4, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
902     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES,          5,  5, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
903     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES,          5,  5, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
904     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES,          6,  5, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
905     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES,          6,  6, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
906     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES,          6,  6, 6, 128, 4, false, RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
907 
908     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES,  3,  3, 3, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
909     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES,  4,  3, 3, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
910     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES,  4,  4, 3, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
911     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES,  4,  4, 4, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
912     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES,  5,  4, 4, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
913     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES,  5,  5, 4, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
914     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES,  5,  5, 5, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
915     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES,  6,  5, 5, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
916     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES,  6,  6, 5, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
917     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES,  6,  6, 6, 128, 4, true,  RequireExt<&Extensions::textureCompressionASTCOES>,    AlwaysSupported, NeverSupported,      NeverSupported);
918 
919     // From EXT_texture_compression_bptc
920     //                       | Internal format                         | W | H |D | BS |CC| SRGB | Texture supported                              | Filterable     | Texture attachment | Renderbuffer |
921     AddCompressedFormat(&map, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,         4,  4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBPTC>, AlwaysSupported, NeverSupported,      NeverSupported);
922     AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,   4,  4, 1, 128, 4, true,  RequireExt<&Extensions::textureCompressionBPTC>, AlwaysSupported, NeverSupported,      NeverSupported);
923     AddCompressedFormat(&map, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT,   4,  4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBPTC>, AlwaysSupported, NeverSupported,      NeverSupported);
924     AddCompressedFormat(&map, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 4,  4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBPTC>, AlwaysSupported, NeverSupported,      NeverSupported);
925 
926     // For STENCIL_INDEX8 we chose a normalized component type for the following reasons:
927     // - Multisampled buffer are disallowed for non-normalized integer component types and we want to support it for STENCIL_INDEX8
928     // - All other stencil formats (all depth-stencil) are either float or normalized
929     // - It affects only validation of internalformat in RenderbufferStorageMultisample.
930     //                         | Internal format  |sized|D |S |X | Format    | Type            | Component type        | Texture supported | Filterable    | Texture attachment | Renderbuffer  |
931     AddDepthStencilFormat(&map, GL_STENCIL_INDEX8, true, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,    NeverSupported, RequireES<1, 0>,     RequireES<1, 0>);
932 
933     // From GL_ANGLE_lossy_etc_decode
934     //                       | Internal format                                                |W |H |D |BS |CC| SRGB | Texture supported                      | Filterable     | Texture attachment | Renderbuffer |
935     AddCompressedFormat(&map, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE,                                 4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyETCDecode>, AlwaysSupported, NeverSupported,      NeverSupported);
936     AddCompressedFormat(&map, GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE,                      4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyETCDecode>, AlwaysSupported, NeverSupported,      NeverSupported);
937     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE,                     4, 4, 1, 64, 3, true,  RequireExt<&Extensions::lossyETCDecode>, AlwaysSupported, NeverSupported,      NeverSupported);
938     AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE,  4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyETCDecode>, AlwaysSupported, NeverSupported,      NeverSupported);
939     AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, true,  RequireExt<&Extensions::lossyETCDecode>, AlwaysSupported, NeverSupported,      NeverSupported);
940 
941     // From GL_EXT_texture_norm16
942     //                 | Internal format    |sized| R | G | B | A |S | Format | Type             | Component type        | SRGB | Texture supported                     | Filterable     | Texture attachment                    | Renderbuffer                         |
943     AddRGBAFormat(&map, GL_R16_EXT,          true, 16,  0,  0,  0, 0, GL_RED,  GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>);
944     AddRGBAFormat(&map, GL_R16_SNORM_EXT,    true, 16,  0,  0,  0, 0, GL_RED,  GL_SHORT,          GL_SIGNED_NORMALIZED,   false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, NeverSupported,                         NeverSupported                        );
945     AddRGBAFormat(&map, GL_RG16_EXT,         true, 16, 16,  0,  0, 0, GL_RG,   GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>);
946     AddRGBAFormat(&map, GL_RG16_SNORM_EXT,   true, 16, 16,  0,  0, 0, GL_RG,   GL_SHORT,          GL_SIGNED_NORMALIZED,   false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, NeverSupported,                         NeverSupported                        );
947     AddRGBAFormat(&map, GL_RGB16_EXT,        true, 16, 16, 16,  0, 0, GL_RGB,  GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, NeverSupported,                         NeverSupported                        );
948     AddRGBAFormat(&map, GL_RGB16_SNORM_EXT,  true, 16, 16, 16,  0, 0, GL_RGB,  GL_SHORT,          GL_SIGNED_NORMALIZED,   false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, NeverSupported,                         NeverSupported                        );
949     AddRGBAFormat(&map, GL_RGBA16_EXT,       true, 16, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>);
950     AddRGBAFormat(&map, GL_RGBA16_SNORM_EXT, true, 16, 16, 16, 16, 0, GL_RGBA, GL_SHORT,          GL_SIGNED_NORMALIZED,   false, RequireExt<&Extensions::textureNorm16>, AlwaysSupported, NeverSupported,                         NeverSupported                        );
951 
952     // Unsized formats
953     //                 | Internal format  |sized | R | G | B | A |S | Format           | Type                          | Component type        | SRGB | Texture supported                             | Filterable     | Texture attachment                            | Renderbuffer |
954     AddRGBAFormat(&map, GL_RED,            false,  8,  0,  0,  0, 0, GL_RED,            GL_UNSIGNED_BYTE,               GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>,             AlwaysSupported, RequireExt<&Extensions::textureRG>,             NeverSupported);
955     AddRGBAFormat(&map, GL_RED,            false,  8,  0,  0,  0, 0, GL_RED,            GL_BYTE,                        GL_SIGNED_NORMALIZED,   false, NeverSupported,                                 NeverSupported,  NeverSupported,                                 NeverSupported);
956     AddRGBAFormat(&map, GL_RG,             false,  8,  8,  0,  0, 0, GL_RG,             GL_UNSIGNED_BYTE,               GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>,             AlwaysSupported, RequireExt<&Extensions::textureRG>,             NeverSupported);
957     AddRGBAFormat(&map, GL_RG,             false,  8,  8,  0,  0, 0, GL_RG,             GL_BYTE,                        GL_SIGNED_NORMALIZED,   false, NeverSupported,                                 NeverSupported,  NeverSupported,                                 NeverSupported);
958     AddRGBAFormat(&map, GL_RGB,            false,  8,  8,  8,  0, 0, GL_RGB,            GL_UNSIGNED_BYTE,               GL_UNSIGNED_NORMALIZED, false, AlwaysSupported,                                AlwaysSupported, RequireES<2, 0>,                                NeverSupported);
959     AddRGBAFormat(&map, GL_RGB,            false,  5,  6,  5,  0, 0, GL_RGB,            GL_UNSIGNED_SHORT_5_6_5,        GL_UNSIGNED_NORMALIZED, false, AlwaysSupported,                                AlwaysSupported, RequireES<2, 0>,                                NeverSupported);
960     AddRGBAFormat(&map, GL_RGB,            false,  8,  8,  8,  0, 0, GL_RGB,            GL_BYTE,                        GL_SIGNED_NORMALIZED,   false, NeverSupported,                                 NeverSupported,  NeverSupported,                                 NeverSupported);
961     AddRGBAFormat(&map, GL_RGBA,           false,  4,  4,  4,  4, 0, GL_RGBA,           GL_UNSIGNED_SHORT_4_4_4_4,      GL_UNSIGNED_NORMALIZED, false, AlwaysSupported,                                AlwaysSupported, RequireES<2, 0>,                                NeverSupported);
962     AddRGBAFormat(&map, GL_RGBA,           false,  5,  5,  5,  1, 0, GL_RGBA,           GL_UNSIGNED_SHORT_5_5_5_1,      GL_UNSIGNED_NORMALIZED, false, AlwaysSupported,                                AlwaysSupported, RequireES<2, 0>,                                NeverSupported);
963     AddRGBAFormat(&map, GL_RGBA,           false,  8,  8,  8,  8, 0, GL_RGBA,           GL_UNSIGNED_BYTE,               GL_UNSIGNED_NORMALIZED, false, AlwaysSupported,                                AlwaysSupported, RequireES<2, 0>,                                NeverSupported);
964     AddRGBAFormat(&map, GL_RGBA,           false, 10, 10, 10,  2, 0, GL_RGBA,           GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported,                                 NeverSupported,  NeverSupported,                                 NeverSupported);
965     AddRGBAFormat(&map, GL_RGBA,           false,  8,  8,  8,  8, 0, GL_RGBA,           GL_BYTE,                        GL_SIGNED_NORMALIZED,   false, NeverSupported,                                 NeverSupported,  NeverSupported,                                 NeverSupported);
966     AddRGBAFormat(&map, GL_SRGB,           false,  8,  8,  8,  0, 0, GL_SRGB,           GL_UNSIGNED_BYTE,               GL_UNSIGNED_NORMALIZED, true,  RequireExt<&Extensions::sRGB>,                  AlwaysSupported, NeverSupported,                                 NeverSupported);
967     AddRGBAFormat(&map, GL_SRGB_ALPHA_EXT, false,  8,  8,  8,  8, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE,               GL_UNSIGNED_NORMALIZED, true,  RequireExt<&Extensions::sRGB>,                  AlwaysSupported, RequireExt<&Extensions::sRGB>,                  NeverSupported);
968     AddRGBAFormat(&map, GL_BGRA_EXT,       false,  8,  8,  8,  8, 0, GL_BGRA_EXT,       GL_UNSIGNED_BYTE,               GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888>, NeverSupported);
969 
970     // Unsized integer formats
971     //                 |Internal format |sized | R | G | B | A |S | Format         | Type                          | Component type | SRGB | Texture supported | Filterable    | Texture attachment | Renderbuffer |
972     AddRGBAFormat(&map, GL_RED_INTEGER,  false,  8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                        GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
973     AddRGBAFormat(&map, GL_RED_INTEGER,  false,  8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,               GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
974     AddRGBAFormat(&map, GL_RED_INTEGER,  false, 16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                       GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
975     AddRGBAFormat(&map, GL_RED_INTEGER,  false, 16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,              GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
976     AddRGBAFormat(&map, GL_RED_INTEGER,  false, 32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                         GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
977     AddRGBAFormat(&map, GL_RED_INTEGER,  false, 32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
978     AddRGBAFormat(&map, GL_RG_INTEGER,   false,  8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                        GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
979     AddRGBAFormat(&map, GL_RG_INTEGER,   false,  8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,               GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
980     AddRGBAFormat(&map, GL_RG_INTEGER,   false, 16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                       GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
981     AddRGBAFormat(&map, GL_RG_INTEGER,   false, 16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,              GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
982     AddRGBAFormat(&map, GL_RG_INTEGER,   false, 32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                         GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
983     AddRGBAFormat(&map, GL_RG_INTEGER,   false, 32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
984     AddRGBAFormat(&map, GL_RGB_INTEGER,  false,  8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                        GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
985     AddRGBAFormat(&map, GL_RGB_INTEGER,  false,  8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,               GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
986     AddRGBAFormat(&map, GL_RGB_INTEGER,  false, 16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                       GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
987     AddRGBAFormat(&map, GL_RGB_INTEGER,  false, 16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,              GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
988     AddRGBAFormat(&map, GL_RGB_INTEGER,  false, 32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                         GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
989     AddRGBAFormat(&map, GL_RGB_INTEGER,  false, 32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
990     AddRGBAFormat(&map, GL_RGBA_INTEGER, false,  8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                        GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
991     AddRGBAFormat(&map, GL_RGBA_INTEGER, false,  8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,               GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
992     AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                       GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
993     AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,              GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
994     AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                         GL_INT,          false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
995     AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
996     AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3, 0>,    NeverSupported, NeverSupported,      NeverSupported);
997 
998     // Unsized floating point formats
999     //                 |Internal format |sized | R | G | B | A |S | Format | Type                           | Comp    | SRGB | Texture supported                                                      | Filterable                                     | Texture attachment                                                                  | Renderbuffer |
1000     AddRGBAFormat(&map, GL_RED,          false, 16,  0,  0,  0, 0, GL_RED,  GL_HALF_FLOAT,                   GL_FLOAT, false, NeverSupported,                                                          NeverSupported,                                  NeverSupported,                                                                       NeverSupported);
1001     AddRGBAFormat(&map, GL_RG,           false, 16, 16,  0,  0, 0, GL_RG,   GL_HALF_FLOAT,                   GL_FLOAT, false, NeverSupported,                                                          NeverSupported,                                  NeverSupported,                                                                       NeverSupported);
1002     AddRGBAFormat(&map, GL_RGB,          false, 16, 16, 16,  0, 0, GL_RGB,  GL_HALF_FLOAT,                   GL_FLOAT, false, NeverSupported,                                                          NeverSupported,                                  NeverSupported,                                                                       NeverSupported);
1003     AddRGBAFormat(&map, GL_RGBA,         false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT,                   GL_FLOAT, false, NeverSupported,                                                          NeverSupported,                                  NeverSupported,                                                                       NeverSupported);
1004     AddRGBAFormat(&map, GL_RED,          false, 16,  0,  0,  0, 0, GL_RED,  GL_HALF_FLOAT_OES,               GL_FLOAT, false, RequireExtAndExt<&Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,                                                                       NeverSupported);
1005     AddRGBAFormat(&map, GL_RG,           false, 16, 16,  0,  0, 0, GL_RG,   GL_HALF_FLOAT_OES,               GL_FLOAT, false, RequireExtAndExt<&Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,                                                                       NeverSupported);
1006     AddRGBAFormat(&map, GL_RGB,          false, 16, 16, 16,  0, 0, GL_RGB,  GL_HALF_FLOAT_OES,               GL_FLOAT, false, RequireExt<&Extensions::textureHalfFloat>,                               RequireExt<&Extensions::textureHalfFloatLinear>, RequireExtAndExt<&Extensions::colorBufferHalfFloat, &Extensions::webglCompatibility>, NeverSupported);
1007     AddRGBAFormat(&map, GL_RGBA,         false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT_OES,               GL_FLOAT, false, RequireExt<&Extensions::textureHalfFloat>,                               RequireExt<&Extensions::textureHalfFloatLinear>, RequireExt<&Extensions::colorBufferHalfFloat>,                                        NeverSupported);
1008     AddRGBAFormat(&map, GL_RED,          false, 32,  0,  0,  0, 0, GL_RED,  GL_FLOAT,                        GL_FLOAT, false, RequireExtAndExt<&Extensions::textureFloat, &Extensions::textureRG>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,                                                                       NeverSupported);
1009     AddRGBAFormat(&map, GL_RG,           false, 32, 32,  0,  0, 0, GL_RG,   GL_FLOAT,                        GL_FLOAT, false, RequireExtAndExt<&Extensions::textureFloat, &Extensions::textureRG>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,                                                                       NeverSupported);
1010     AddRGBAFormat(&map, GL_RGB,          false, 32, 32, 32,  0, 0, GL_RGB,  GL_FLOAT,                        GL_FLOAT, false, RequireExt<&Extensions::textureFloat>,                                   RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,                                                                       NeverSupported);
1011     AddRGBAFormat(&map, GL_RGB,          false,  9,  9,  9,  0, 5, GL_RGB,  GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT, false, NeverSupported,                                                          NeverSupported,                                  NeverSupported,                                                                       NeverSupported);
1012     AddRGBAFormat(&map, GL_RGB,          false, 11, 11, 10,  0, 0, GL_RGB,  GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, NeverSupported,                                                          NeverSupported,                                  NeverSupported,                                                                       NeverSupported);
1013     AddRGBAFormat(&map, GL_RGBA,         false, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT,                        GL_FLOAT, false, RequireExt<&Extensions::textureFloat>,                                   RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,                                                                       NeverSupported);
1014 
1015     // Unsized luminance alpha formats
1016     //                 | Internal format   |sized | L | A | Format            | Type             | Component type        | Texture supported                        | Filterable                                     | Texture attachment | Renderbuffer |
1017     AddLUMAFormat(&map, GL_ALPHA,           false,  0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, AlwaysSupported,                           AlwaysSupported,                                 NeverSupported,      NeverSupported);
1018     AddLUMAFormat(&map, GL_LUMINANCE,       false,  8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, AlwaysSupported,                           AlwaysSupported,                                 NeverSupported,      NeverSupported);
1019     AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false,  8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,  GL_UNSIGNED_NORMALIZED, AlwaysSupported,                           AlwaysSupported,                                 NeverSupported,      NeverSupported);
1020     AddLUMAFormat(&map, GL_ALPHA,           false,  0, 16, GL_ALPHA,           GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExt<&Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,      NeverSupported);
1021     AddLUMAFormat(&map, GL_LUMINANCE,       false, 16,  0, GL_LUMINANCE,       GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExt<&Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,      NeverSupported);
1022     AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT,               RequireExt<&Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>, NeverSupported,      NeverSupported);
1023     AddLUMAFormat(&map, GL_ALPHA,           false,  0, 32, GL_ALPHA,           GL_FLOAT,          GL_FLOAT,               RequireExt<&Extensions::textureFloat>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,      NeverSupported);
1024     AddLUMAFormat(&map, GL_LUMINANCE,       false, 32,  0, GL_LUMINANCE,       GL_FLOAT,          GL_FLOAT,               RequireExt<&Extensions::textureFloat>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,      NeverSupported);
1025     AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,          GL_FLOAT,               RequireExt<&Extensions::textureFloat>,     RequireExt<&Extensions::textureFloatLinear>,     NeverSupported,      NeverSupported);
1026 
1027     // Unsized depth stencil formats
1028     //                         | Internal format   |sized | D |S | X | Format            | Type                             | Component type        | Texture supported                                    | Filterable     | Texture attachment                                   | Renderbuffer                                        |
1029     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                       AlwaysSupported, RequireES<1, 0>,                                       RequireES<1, 0>                                      );
1030     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                       AlwaysSupported, RequireES<1, 0>,                                       RequireES<1, 0>                                      );
1031     AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireES<1, 0>,                                       AlwaysSupported, RequireES<1, 0>,                                       RequireES<1, 0>                                      );
1032     AddDepthStencilFormat(&map, GL_DEPTH_STENCIL,   false, 24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>);
1033     AddDepthStencilFormat(&map, GL_DEPTH_STENCIL,   false, 32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>);
1034     AddDepthStencilFormat(&map, GL_STENCIL,         false,  0, 8,  0, GL_STENCIL,         GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, RequireES<1, 0>,                                       NeverSupported , RequireES<1, 0>,                                       RequireES<1, 0>                                      );
1035     // clang-format on
1036 
1037     return map;
1038 }
1039 
GetInternalFormatMap()1040 static const InternalFormatInfoMap &GetInternalFormatMap()
1041 {
1042     static const angle::base::NoDestructor<InternalFormatInfoMap> formatMap(
1043         BuildInternalFormatInfoMap());
1044     return *formatMap;
1045 }
1046 
BuildAllSizedInternalFormatSet()1047 static FormatSet BuildAllSizedInternalFormatSet()
1048 {
1049     FormatSet result;
1050 
1051     for (const auto &internalFormat : GetInternalFormatMap())
1052     {
1053         for (const auto &type : internalFormat.second)
1054         {
1055             if (type.second.sized)
1056             {
1057                 // TODO(jmadill): Fix this hack.
1058                 if (internalFormat.first == GL_BGR565_ANGLEX)
1059                     continue;
1060 
1061                 result.insert(internalFormat.first);
1062             }
1063         }
1064     }
1065 
1066     return result;
1067 }
1068 
GetPackedTypeInfo(GLenum type)1069 uint32_t GetPackedTypeInfo(GLenum type)
1070 {
1071     switch (type)
1072     {
1073         case GL_UNSIGNED_BYTE:
1074         case GL_BYTE:
1075         {
1076             static constexpr uint32_t kPacked = PackTypeInfo(1, false);
1077             return kPacked;
1078         }
1079         case GL_UNSIGNED_SHORT:
1080         case GL_SHORT:
1081         case GL_HALF_FLOAT:
1082         case GL_HALF_FLOAT_OES:
1083         {
1084             static constexpr uint32_t kPacked = PackTypeInfo(2, false);
1085             return kPacked;
1086         }
1087         case GL_UNSIGNED_INT:
1088         case GL_INT:
1089         case GL_FLOAT:
1090         {
1091             static constexpr uint32_t kPacked = PackTypeInfo(4, false);
1092             return kPacked;
1093         }
1094         case GL_UNSIGNED_SHORT_5_6_5:
1095         case GL_UNSIGNED_SHORT_4_4_4_4:
1096         case GL_UNSIGNED_SHORT_5_5_5_1:
1097         case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
1098         case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
1099         {
1100             static constexpr uint32_t kPacked = PackTypeInfo(2, true);
1101             return kPacked;
1102         }
1103         case GL_UNSIGNED_INT_2_10_10_10_REV:
1104         case GL_UNSIGNED_INT_24_8:
1105         case GL_UNSIGNED_INT_10F_11F_11F_REV:
1106         case GL_UNSIGNED_INT_5_9_9_9_REV:
1107         {
1108             ASSERT(GL_UNSIGNED_INT_24_8_OES == GL_UNSIGNED_INT_24_8);
1109             static constexpr uint32_t kPacked = PackTypeInfo(4, true);
1110             return kPacked;
1111         }
1112         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1113         {
1114             static constexpr uint32_t kPacked = PackTypeInfo(8, true);
1115             return kPacked;
1116         }
1117         default:
1118         {
1119             return 0;
1120         }
1121     }
1122 }
1123 
GetSizedInternalFormatInfo(GLenum internalFormat)1124 const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat)
1125 {
1126     static const InternalFormat defaultInternalFormat;
1127     const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
1128     auto iter                              = formatMap.find(internalFormat);
1129 
1130     // Sized internal formats only have one type per entry
1131     if (iter == formatMap.end() || iter->second.size() != 1)
1132     {
1133         return defaultInternalFormat;
1134     }
1135 
1136     const InternalFormat &internalFormatInfo = iter->second.begin()->second;
1137     if (!internalFormatInfo.sized)
1138     {
1139         return defaultInternalFormat;
1140     }
1141 
1142     return internalFormatInfo;
1143 }
1144 
GetInternalFormatInfo(GLenum internalFormat,GLenum type)1145 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type)
1146 {
1147     static const InternalFormat defaultInternalFormat;
1148     const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
1149 
1150     auto internalFormatIter = formatMap.find(internalFormat);
1151     if (internalFormatIter == formatMap.end())
1152     {
1153         return defaultInternalFormat;
1154     }
1155 
1156     // If the internal format is sized, simply return it without the type check.
1157     if (internalFormatIter->second.size() == 1 && internalFormatIter->second.begin()->second.sized)
1158     {
1159         return internalFormatIter->second.begin()->second;
1160     }
1161 
1162     auto typeIter = internalFormatIter->second.find(type);
1163     if (typeIter == internalFormatIter->second.end())
1164     {
1165         return defaultInternalFormat;
1166     }
1167 
1168     return typeIter->second;
1169 }
1170 
computePixelBytes(GLenum formatType) const1171 GLuint InternalFormat::computePixelBytes(GLenum formatType) const
1172 {
1173     const auto &typeInfo = GetTypeInfo(formatType);
1174     GLuint components    = typeInfo.specialInterpretation ? 1u : componentCount;
1175     return components * typeInfo.bytes;
1176 }
1177 
computeRowPitch(GLenum formatType,GLsizei width,GLint alignment,GLint rowLength,GLuint * resultOut) const1178 bool InternalFormat::computeRowPitch(GLenum formatType,
1179                                      GLsizei width,
1180                                      GLint alignment,
1181                                      GLint rowLength,
1182                                      GLuint *resultOut) const
1183 {
1184     // Compressed images do not use pack/unpack parameters.
1185     if (compressed)
1186     {
1187         ASSERT(rowLength == 0);
1188         return computeCompressedImageSize(Extents(width, 1, 1), resultOut);
1189     }
1190 
1191     CheckedNumeric<GLuint> checkedWidth(rowLength > 0 ? rowLength : width);
1192     CheckedNumeric<GLuint> checkedRowBytes = checkedWidth * computePixelBytes(formatType);
1193 
1194     ASSERT(alignment > 0 && isPow2(alignment));
1195     CheckedNumeric<GLuint> checkedAlignment(alignment);
1196     auto aligned = rx::roundUp(checkedRowBytes, checkedAlignment);
1197     return CheckedMathResult(aligned, resultOut);
1198 }
1199 
computeDepthPitch(GLsizei height,GLint imageHeight,GLuint rowPitch,GLuint * resultOut) const1200 bool InternalFormat::computeDepthPitch(GLsizei height,
1201                                        GLint imageHeight,
1202                                        GLuint rowPitch,
1203                                        GLuint *resultOut) const
1204 {
1205     GLuint rows =
1206         (imageHeight > 0 ? static_cast<GLuint>(imageHeight) : static_cast<GLuint>(height));
1207     CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
1208 
1209     return CheckedMathResult(checkedRowPitch * rows, resultOut);
1210 }
1211 
computeDepthPitch(GLenum formatType,GLsizei width,GLsizei height,GLint alignment,GLint rowLength,GLint imageHeight,GLuint * resultOut) const1212 bool InternalFormat::computeDepthPitch(GLenum formatType,
1213                                        GLsizei width,
1214                                        GLsizei height,
1215                                        GLint alignment,
1216                                        GLint rowLength,
1217                                        GLint imageHeight,
1218                                        GLuint *resultOut) const
1219 {
1220     GLuint rowPitch = 0;
1221     if (!computeRowPitch(formatType, width, alignment, rowLength, &rowPitch))
1222     {
1223         return false;
1224     }
1225     return computeDepthPitch(height, imageHeight, rowPitch, resultOut);
1226 }
1227 
computeCompressedImageSize(const Extents & size,GLuint * resultOut) const1228 bool InternalFormat::computeCompressedImageSize(const Extents &size, GLuint *resultOut) const
1229 {
1230     CheckedNumeric<GLuint> checkedWidth(size.width);
1231     CheckedNumeric<GLuint> checkedHeight(size.height);
1232     CheckedNumeric<GLuint> checkedDepth(size.depth);
1233     CheckedNumeric<GLuint> checkedBlockWidth(compressedBlockWidth);
1234     CheckedNumeric<GLuint> checkedBlockHeight(compressedBlockHeight);
1235 
1236     ASSERT(compressed);
1237     auto numBlocksWide = (checkedWidth + checkedBlockWidth - 1u) / checkedBlockWidth;
1238     auto numBlocksHigh = (checkedHeight + checkedBlockHeight - 1u) / checkedBlockHeight;
1239     auto bytes         = numBlocksWide * numBlocksHigh * pixelBytes * checkedDepth;
1240     return CheckedMathResult(bytes, resultOut);
1241 }
1242 
computeSkipBytes(GLenum formatType,GLuint rowPitch,GLuint depthPitch,const PixelStoreStateBase & state,bool is3D,GLuint * resultOut) const1243 bool InternalFormat::computeSkipBytes(GLenum formatType,
1244                                       GLuint rowPitch,
1245                                       GLuint depthPitch,
1246                                       const PixelStoreStateBase &state,
1247                                       bool is3D,
1248                                       GLuint *resultOut) const
1249 {
1250     CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
1251     CheckedNumeric<GLuint> checkedDepthPitch(depthPitch);
1252     CheckedNumeric<GLuint> checkedSkipImages(static_cast<GLuint>(state.skipImages));
1253     CheckedNumeric<GLuint> checkedSkipRows(static_cast<GLuint>(state.skipRows));
1254     CheckedNumeric<GLuint> checkedSkipPixels(static_cast<GLuint>(state.skipPixels));
1255     CheckedNumeric<GLuint> checkedPixelBytes(computePixelBytes(formatType));
1256     auto checkedSkipImagesBytes = checkedSkipImages * checkedDepthPitch;
1257     if (!is3D)
1258     {
1259         checkedSkipImagesBytes = 0;
1260     }
1261     auto skipBytes = checkedSkipImagesBytes + checkedSkipRows * checkedRowPitch +
1262                      checkedSkipPixels * checkedPixelBytes;
1263     return CheckedMathResult(skipBytes, resultOut);
1264 }
1265 
computePackUnpackEndByte(GLenum formatType,const Extents & size,const PixelStoreStateBase & state,bool is3D,GLuint * resultOut) const1266 bool InternalFormat::computePackUnpackEndByte(GLenum formatType,
1267                                               const Extents &size,
1268                                               const PixelStoreStateBase &state,
1269                                               bool is3D,
1270                                               GLuint *resultOut) const
1271 {
1272     GLuint rowPitch = 0;
1273     if (!computeRowPitch(formatType, size.width, state.alignment, state.rowLength, &rowPitch))
1274     {
1275         return false;
1276     }
1277 
1278     GLuint depthPitch = 0;
1279     if (is3D && !computeDepthPitch(size.height, state.imageHeight, rowPitch, &depthPitch))
1280     {
1281         return false;
1282     }
1283 
1284     CheckedNumeric<GLuint> checkedCopyBytes(0);
1285     if (compressed)
1286     {
1287         GLuint copyBytes = 0;
1288         if (!computeCompressedImageSize(size, &copyBytes))
1289         {
1290             return false;
1291         }
1292         checkedCopyBytes = copyBytes;
1293     }
1294     else if (size.height != 0 && (!is3D || size.depth != 0))
1295     {
1296         CheckedNumeric<GLuint> bytes = computePixelBytes(formatType);
1297         checkedCopyBytes += size.width * bytes;
1298 
1299         CheckedNumeric<GLuint> heightMinusOne = size.height - 1;
1300         checkedCopyBytes += heightMinusOne * rowPitch;
1301 
1302         if (is3D)
1303         {
1304             CheckedNumeric<GLuint> depthMinusOne = size.depth - 1;
1305             checkedCopyBytes += depthMinusOne * depthPitch;
1306         }
1307     }
1308 
1309     GLuint skipBytes = 0;
1310     if (!computeSkipBytes(formatType, rowPitch, depthPitch, state, is3D, &skipBytes))
1311     {
1312         return false;
1313     }
1314 
1315     CheckedNumeric<GLuint> endByte = checkedCopyBytes + CheckedNumeric<GLuint>(skipBytes);
1316 
1317     return CheckedMathResult(endByte, resultOut);
1318 }
1319 
GetUnsizedFormat(GLenum internalFormat)1320 GLenum GetUnsizedFormat(GLenum internalFormat)
1321 {
1322     auto sizedFormatInfo = GetSizedInternalFormatInfo(internalFormat);
1323     if (sizedFormatInfo.internalFormat != GL_NONE)
1324     {
1325         return sizedFormatInfo.format;
1326     }
1327 
1328     return internalFormat;
1329 }
1330 
GetAllSizedInternalFormats()1331 const FormatSet &GetAllSizedInternalFormats()
1332 {
1333     static angle::base::NoDestructor<FormatSet> formatSet(BuildAllSizedInternalFormatSet());
1334     return *formatSet;
1335 }
1336 
GetAttributeType(GLenum enumValue)1337 AttributeType GetAttributeType(GLenum enumValue)
1338 {
1339     switch (enumValue)
1340     {
1341         case GL_FLOAT:
1342             return ATTRIBUTE_FLOAT;
1343         case GL_FLOAT_VEC2:
1344             return ATTRIBUTE_VEC2;
1345         case GL_FLOAT_VEC3:
1346             return ATTRIBUTE_VEC3;
1347         case GL_FLOAT_VEC4:
1348             return ATTRIBUTE_VEC4;
1349         case GL_INT:
1350             return ATTRIBUTE_INT;
1351         case GL_INT_VEC2:
1352             return ATTRIBUTE_IVEC2;
1353         case GL_INT_VEC3:
1354             return ATTRIBUTE_IVEC3;
1355         case GL_INT_VEC4:
1356             return ATTRIBUTE_IVEC4;
1357         case GL_UNSIGNED_INT:
1358             return ATTRIBUTE_UINT;
1359         case GL_UNSIGNED_INT_VEC2:
1360             return ATTRIBUTE_UVEC2;
1361         case GL_UNSIGNED_INT_VEC3:
1362             return ATTRIBUTE_UVEC3;
1363         case GL_UNSIGNED_INT_VEC4:
1364             return ATTRIBUTE_UVEC4;
1365         case GL_FLOAT_MAT2:
1366             return ATTRIBUTE_MAT2;
1367         case GL_FLOAT_MAT3:
1368             return ATTRIBUTE_MAT3;
1369         case GL_FLOAT_MAT4:
1370             return ATTRIBUTE_MAT4;
1371         case GL_FLOAT_MAT2x3:
1372             return ATTRIBUTE_MAT2x3;
1373         case GL_FLOAT_MAT2x4:
1374             return ATTRIBUTE_MAT2x4;
1375         case GL_FLOAT_MAT3x2:
1376             return ATTRIBUTE_MAT3x2;
1377         case GL_FLOAT_MAT3x4:
1378             return ATTRIBUTE_MAT3x4;
1379         case GL_FLOAT_MAT4x2:
1380             return ATTRIBUTE_MAT4x2;
1381         case GL_FLOAT_MAT4x3:
1382             return ATTRIBUTE_MAT4x3;
1383         default:
1384             UNREACHABLE();
1385 #if !UNREACHABLE_IS_NORETURN
1386             return ATTRIBUTE_FLOAT;
1387 #endif
1388     }
1389 }
1390 
GetVertexFormatID(VertexAttribType type,GLboolean normalized,GLuint components,bool pureInteger)1391 angle::FormatID GetVertexFormatID(VertexAttribType type,
1392                                   GLboolean normalized,
1393                                   GLuint components,
1394                                   bool pureInteger)
1395 {
1396     switch (type)
1397     {
1398         case VertexAttribType::Byte:
1399             switch (components)
1400             {
1401                 case 1:
1402                     if (pureInteger)
1403                         return angle::FormatID::R8_SINT;
1404                     if (normalized)
1405                         return angle::FormatID::R8_SNORM;
1406                     return angle::FormatID::R8_SSCALED;
1407                 case 2:
1408                     if (pureInteger)
1409                         return angle::FormatID::R8G8_SINT;
1410                     if (normalized)
1411                         return angle::FormatID::R8G8_SNORM;
1412                     return angle::FormatID::R8G8_SSCALED;
1413                 case 3:
1414                     if (pureInteger)
1415                         return angle::FormatID::R8G8B8_SINT;
1416                     if (normalized)
1417                         return angle::FormatID::R8G8B8_SNORM;
1418                     return angle::FormatID::R8G8B8_SSCALED;
1419                 case 4:
1420                     if (pureInteger)
1421                         return angle::FormatID::R8G8B8A8_SINT;
1422                     if (normalized)
1423                         return angle::FormatID::R8G8B8A8_SNORM;
1424                     return angle::FormatID::R8G8B8A8_SSCALED;
1425                 default:
1426                     UNREACHABLE();
1427 #if !UNREACHABLE_IS_NORETURN
1428                     return angle::FormatID::NONE;
1429 #endif
1430             }
1431         case VertexAttribType::UnsignedByte:
1432             switch (components)
1433             {
1434                 case 1:
1435                     if (pureInteger)
1436                         return angle::FormatID::R8_UINT;
1437                     if (normalized)
1438                         return angle::FormatID::R8_UNORM;
1439                     return angle::FormatID::R8_USCALED;
1440                 case 2:
1441                     if (pureInteger)
1442                         return angle::FormatID::R8G8_UINT;
1443                     if (normalized)
1444                         return angle::FormatID::R8G8_UNORM;
1445                     return angle::FormatID::R8G8_USCALED;
1446                 case 3:
1447                     if (pureInteger)
1448                         return angle::FormatID::R8G8B8_UINT;
1449                     if (normalized)
1450                         return angle::FormatID::R8G8B8_UNORM;
1451                     return angle::FormatID::R8G8B8_USCALED;
1452                 case 4:
1453                     if (pureInteger)
1454                         return angle::FormatID::R8G8B8A8_UINT;
1455                     if (normalized)
1456                         return angle::FormatID::R8G8B8A8_UNORM;
1457                     return angle::FormatID::R8G8B8A8_USCALED;
1458                 default:
1459                     UNREACHABLE();
1460 #if !UNREACHABLE_IS_NORETURN
1461                     return angle::FormatID::NONE;
1462 #endif
1463             }
1464         case VertexAttribType::Short:
1465             switch (components)
1466             {
1467                 case 1:
1468                     if (pureInteger)
1469                         return angle::FormatID::R16_SINT;
1470                     if (normalized)
1471                         return angle::FormatID::R16_SNORM;
1472                     return angle::FormatID::R16_SSCALED;
1473                 case 2:
1474                     if (pureInteger)
1475                         return angle::FormatID::R16G16_SINT;
1476                     if (normalized)
1477                         return angle::FormatID::R16G16_SNORM;
1478                     return angle::FormatID::R16G16_SSCALED;
1479                 case 3:
1480                     if (pureInteger)
1481                         return angle::FormatID::R16G16B16_SINT;
1482                     if (normalized)
1483                         return angle::FormatID::R16G16B16_SNORM;
1484                     return angle::FormatID::R16G16B16_SSCALED;
1485                 case 4:
1486                     if (pureInteger)
1487                         return angle::FormatID::R16G16B16A16_SINT;
1488                     if (normalized)
1489                         return angle::FormatID::R16G16B16A16_SNORM;
1490                     return angle::FormatID::R16G16B16A16_SSCALED;
1491                 default:
1492                     UNREACHABLE();
1493 #if !UNREACHABLE_IS_NORETURN
1494                     return angle::FormatID::NONE;
1495 #endif
1496             }
1497         case VertexAttribType::UnsignedShort:
1498             switch (components)
1499             {
1500                 case 1:
1501                     if (pureInteger)
1502                         return angle::FormatID::R16_UINT;
1503                     if (normalized)
1504                         return angle::FormatID::R16_UNORM;
1505                     return angle::FormatID::R16_USCALED;
1506                 case 2:
1507                     if (pureInteger)
1508                         return angle::FormatID::R16G16_UINT;
1509                     if (normalized)
1510                         return angle::FormatID::R16G16_UNORM;
1511                     return angle::FormatID::R16G16_USCALED;
1512                 case 3:
1513                     if (pureInteger)
1514                         return angle::FormatID::R16G16B16_UINT;
1515                     if (normalized)
1516                         return angle::FormatID::R16G16B16_UNORM;
1517                     return angle::FormatID::R16G16B16_USCALED;
1518                 case 4:
1519                     if (pureInteger)
1520                         return angle::FormatID::R16G16B16A16_UINT;
1521                     if (normalized)
1522                         return angle::FormatID::R16G16B16A16_UNORM;
1523                     return angle::FormatID::R16G16B16A16_USCALED;
1524                 default:
1525                     UNREACHABLE();
1526 #if !UNREACHABLE_IS_NORETURN
1527                     return angle::FormatID::NONE;
1528 #endif
1529             }
1530         case VertexAttribType::Int:
1531             switch (components)
1532             {
1533                 case 1:
1534                     if (pureInteger)
1535                         return angle::FormatID::R32_SINT;
1536                     if (normalized)
1537                         return angle::FormatID::R32_SNORM;
1538                     return angle::FormatID::R32_SSCALED;
1539                 case 2:
1540                     if (pureInteger)
1541                         return angle::FormatID::R32G32_SINT;
1542                     if (normalized)
1543                         return angle::FormatID::R32G32_SNORM;
1544                     return angle::FormatID::R32G32_SSCALED;
1545                 case 3:
1546                     if (pureInteger)
1547                         return angle::FormatID::R32G32B32_SINT;
1548                     if (normalized)
1549                         return angle::FormatID::R32G32B32_SNORM;
1550                     return angle::FormatID::R32G32B32_SSCALED;
1551                 case 4:
1552                     if (pureInteger)
1553                         return angle::FormatID::R32G32B32A32_SINT;
1554                     if (normalized)
1555                         return angle::FormatID::R32G32B32A32_SNORM;
1556                     return angle::FormatID::R32G32B32A32_SSCALED;
1557                 default:
1558                     UNREACHABLE();
1559 #if !UNREACHABLE_IS_NORETURN
1560                     return angle::FormatID::NONE;
1561 #endif
1562             }
1563         case VertexAttribType::UnsignedInt:
1564             switch (components)
1565             {
1566                 case 1:
1567                     if (pureInteger)
1568                         return angle::FormatID::R32_UINT;
1569                     if (normalized)
1570                         return angle::FormatID::R32_UNORM;
1571                     return angle::FormatID::R32_USCALED;
1572                 case 2:
1573                     if (pureInteger)
1574                         return angle::FormatID::R32G32_UINT;
1575                     if (normalized)
1576                         return angle::FormatID::R32G32_UNORM;
1577                     return angle::FormatID::R32G32_USCALED;
1578                 case 3:
1579                     if (pureInteger)
1580                         return angle::FormatID::R32G32B32_UINT;
1581                     if (normalized)
1582                         return angle::FormatID::R32G32B32_UNORM;
1583                     return angle::FormatID::R32G32B32_USCALED;
1584                 case 4:
1585                     if (pureInteger)
1586                         return angle::FormatID::R32G32B32A32_UINT;
1587                     if (normalized)
1588                         return angle::FormatID::R32G32B32A32_UNORM;
1589                     return angle::FormatID::R32G32B32A32_USCALED;
1590                 default:
1591                     UNREACHABLE();
1592 #if !UNREACHABLE_IS_NORETURN
1593                     return angle::FormatID::NONE;
1594 #endif
1595             }
1596         case VertexAttribType::Float:
1597             switch (components)
1598             {
1599                 case 1:
1600                     return angle::FormatID::R32_FLOAT;
1601                 case 2:
1602                     return angle::FormatID::R32G32_FLOAT;
1603                 case 3:
1604                     return angle::FormatID::R32G32B32_FLOAT;
1605                 case 4:
1606                     return angle::FormatID::R32G32B32A32_FLOAT;
1607                 default:
1608                     UNREACHABLE();
1609 #if !UNREACHABLE_IS_NORETURN
1610                     return angle::FormatID::NONE;
1611 #endif
1612             }
1613         case VertexAttribType::HalfFloat:
1614             switch (components)
1615             {
1616                 case 1:
1617                     return angle::FormatID::R16_FLOAT;
1618                 case 2:
1619                     return angle::FormatID::R16G16_FLOAT;
1620                 case 3:
1621                     return angle::FormatID::R16G16B16_FLOAT;
1622                 case 4:
1623                     return angle::FormatID::R16G16B16A16_FLOAT;
1624                 default:
1625                     UNREACHABLE();
1626 #if !UNREACHABLE_IS_NORETURN
1627                     return angle::FormatID::NONE;
1628 #endif
1629             }
1630         case VertexAttribType::Fixed:
1631             switch (components)
1632             {
1633                 case 1:
1634                     return angle::FormatID::R32_FIXED;
1635                 case 2:
1636                     return angle::FormatID::R32G32_FIXED;
1637                 case 3:
1638                     return angle::FormatID::R32G32B32_FIXED;
1639                 case 4:
1640                     return angle::FormatID::R32G32B32A32_FIXED;
1641                 default:
1642                     UNREACHABLE();
1643 #if !UNREACHABLE_IS_NORETURN
1644                     return angle::FormatID::NONE;
1645 #endif
1646             }
1647         case VertexAttribType::Int2101010:
1648             if (pureInteger)
1649                 return angle::FormatID::R10G10B10A2_SINT;
1650             if (normalized)
1651                 return angle::FormatID::R10G10B10A2_SNORM;
1652             return angle::FormatID::R10G10B10A2_SSCALED;
1653         case VertexAttribType::UnsignedInt2101010:
1654             if (pureInteger)
1655                 return angle::FormatID::R10G10B10A2_UINT;
1656             if (normalized)
1657                 return angle::FormatID::R10G10B10A2_UNORM;
1658             return angle::FormatID::R10G10B10A2_USCALED;
1659         default:
1660             UNREACHABLE();
1661 #if !UNREACHABLE_IS_NORETURN
1662             return angle::FormatID::NONE;
1663 #endif
1664     }
1665 }
1666 
GetVertexFormatID(const VertexAttribute & attrib,VertexAttribType currentValueType)1667 angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType)
1668 {
1669     if (!attrib.enabled)
1670     {
1671         return GetCurrentValueFormatID(currentValueType);
1672     }
1673     return attrib.format->id;
1674 }
1675 
GetCurrentValueFormatID(VertexAttribType currentValueType)1676 angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType)
1677 {
1678     switch (currentValueType)
1679     {
1680         case VertexAttribType::Float:
1681             return angle::FormatID::R32G32B32A32_FLOAT;
1682         case VertexAttribType::Int:
1683             return angle::FormatID::R32G32B32A32_SINT;
1684         case VertexAttribType::UnsignedInt:
1685             return angle::FormatID::R32G32B32A32_UINT;
1686         default:
1687             UNREACHABLE();
1688             return angle::FormatID::NONE;
1689     }
1690 }
1691 
GetVertexFormatFromID(angle::FormatID vertexFormatID)1692 const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID)
1693 {
1694     switch (vertexFormatID)
1695     {
1696         case angle::FormatID::R8_SSCALED:
1697         {
1698             static const VertexFormat format(GL_BYTE, GL_FALSE, 1, false);
1699             return format;
1700         }
1701         case angle::FormatID::R8_SNORM:
1702         {
1703             static const VertexFormat format(GL_BYTE, GL_TRUE, 1, false);
1704             return format;
1705         }
1706         case angle::FormatID::R8G8_SSCALED:
1707         {
1708             static const VertexFormat format(GL_BYTE, GL_FALSE, 2, false);
1709             return format;
1710         }
1711         case angle::FormatID::R8G8_SNORM:
1712         {
1713             static const VertexFormat format(GL_BYTE, GL_TRUE, 2, false);
1714             return format;
1715         }
1716         case angle::FormatID::R8G8B8_SSCALED:
1717         {
1718             static const VertexFormat format(GL_BYTE, GL_FALSE, 3, false);
1719             return format;
1720         }
1721         case angle::FormatID::R8G8B8_SNORM:
1722         {
1723             static const VertexFormat format(GL_BYTE, GL_TRUE, 3, false);
1724             return format;
1725         }
1726         case angle::FormatID::R8G8B8A8_SSCALED:
1727         {
1728             static const VertexFormat format(GL_BYTE, GL_FALSE, 4, false);
1729             return format;
1730         }
1731         case angle::FormatID::R8G8B8A8_SNORM:
1732         {
1733             static const VertexFormat format(GL_BYTE, GL_TRUE, 4, false);
1734             return format;
1735         }
1736         case angle::FormatID::R8_USCALED:
1737         {
1738             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, false);
1739             return format;
1740         }
1741         case angle::FormatID::R8_UNORM:
1742         {
1743             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 1, false);
1744             return format;
1745         }
1746         case angle::FormatID::R8G8_USCALED:
1747         {
1748             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, false);
1749             return format;
1750         }
1751         case angle::FormatID::R8G8_UNORM:
1752         {
1753             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 2, false);
1754             return format;
1755         }
1756         case angle::FormatID::R8G8B8_USCALED:
1757         {
1758             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, false);
1759             return format;
1760         }
1761         case angle::FormatID::R8G8B8_UNORM:
1762         {
1763             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 3, false);
1764             return format;
1765         }
1766         case angle::FormatID::R8G8B8A8_USCALED:
1767         {
1768             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, false);
1769             return format;
1770         }
1771         case angle::FormatID::R8G8B8A8_UNORM:
1772         {
1773             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 4, false);
1774             return format;
1775         }
1776         case angle::FormatID::R16_SSCALED:
1777         {
1778             static const VertexFormat format(GL_SHORT, GL_FALSE, 1, false);
1779             return format;
1780         }
1781         case angle::FormatID::R16_SNORM:
1782         {
1783             static const VertexFormat format(GL_SHORT, GL_TRUE, 1, false);
1784             return format;
1785         }
1786         case angle::FormatID::R16G16_SSCALED:
1787         {
1788             static const VertexFormat format(GL_SHORT, GL_FALSE, 2, false);
1789             return format;
1790         }
1791         case angle::FormatID::R16G16_SNORM:
1792         {
1793             static const VertexFormat format(GL_SHORT, GL_TRUE, 2, false);
1794             return format;
1795         }
1796         case angle::FormatID::R16G16B16_SSCALED:
1797         {
1798             static const VertexFormat format(GL_SHORT, GL_FALSE, 3, false);
1799             return format;
1800         }
1801         case angle::FormatID::R16G16B16_SNORM:
1802         {
1803             static const VertexFormat format(GL_SHORT, GL_TRUE, 3, false);
1804             return format;
1805         }
1806         case angle::FormatID::R16G16B16A16_SSCALED:
1807         {
1808             static const VertexFormat format(GL_SHORT, GL_FALSE, 4, false);
1809             return format;
1810         }
1811         case angle::FormatID::R16G16B16A16_SNORM:
1812         {
1813             static const VertexFormat format(GL_SHORT, GL_TRUE, 4, false);
1814             return format;
1815         }
1816         case angle::FormatID::R16_USCALED:
1817         {
1818             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, false);
1819             return format;
1820         }
1821         case angle::FormatID::R16_UNORM:
1822         {
1823             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 1, false);
1824             return format;
1825         }
1826         case angle::FormatID::R16G16_USCALED:
1827         {
1828             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, false);
1829             return format;
1830         }
1831         case angle::FormatID::R16G16_UNORM:
1832         {
1833             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 2, false);
1834             return format;
1835         }
1836         case angle::FormatID::R16G16B16_USCALED:
1837         {
1838             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, false);
1839             return format;
1840         }
1841         case angle::FormatID::R16G16B16_UNORM:
1842         {
1843             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 3, false);
1844             return format;
1845         }
1846         case angle::FormatID::R16G16B16A16_USCALED:
1847         {
1848             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, false);
1849             return format;
1850         }
1851         case angle::FormatID::R16G16B16A16_UNORM:
1852         {
1853             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 4, false);
1854             return format;
1855         }
1856         case angle::FormatID::R32_SSCALED:
1857         {
1858             static const VertexFormat format(GL_INT, GL_FALSE, 1, false);
1859             return format;
1860         }
1861         case angle::FormatID::R32_SNORM:
1862         {
1863             static const VertexFormat format(GL_INT, GL_TRUE, 1, false);
1864             return format;
1865         }
1866         case angle::FormatID::R32G32_SSCALED:
1867         {
1868             static const VertexFormat format(GL_INT, GL_FALSE, 2, false);
1869             return format;
1870         }
1871         case angle::FormatID::R32G32_SNORM:
1872         {
1873             static const VertexFormat format(GL_INT, GL_TRUE, 2, false);
1874             return format;
1875         }
1876         case angle::FormatID::R32G32B32_SSCALED:
1877         {
1878             static const VertexFormat format(GL_INT, GL_FALSE, 3, false);
1879             return format;
1880         }
1881         case angle::FormatID::R32G32B32_SNORM:
1882         {
1883             static const VertexFormat format(GL_INT, GL_TRUE, 3, false);
1884             return format;
1885         }
1886         case angle::FormatID::R32G32B32A32_SSCALED:
1887         {
1888             static const VertexFormat format(GL_INT, GL_FALSE, 4, false);
1889             return format;
1890         }
1891         case angle::FormatID::R32G32B32A32_SNORM:
1892         {
1893             static const VertexFormat format(GL_INT, GL_TRUE, 4, false);
1894             return format;
1895         }
1896         case angle::FormatID::R32_USCALED:
1897         {
1898             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, false);
1899             return format;
1900         }
1901         case angle::FormatID::R32_UNORM:
1902         {
1903             static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 1, false);
1904             return format;
1905         }
1906         case angle::FormatID::R32G32_USCALED:
1907         {
1908             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, false);
1909             return format;
1910         }
1911         case angle::FormatID::R32G32_UNORM:
1912         {
1913             static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 2, false);
1914             return format;
1915         }
1916         case angle::FormatID::R32G32B32_USCALED:
1917         {
1918             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, false);
1919             return format;
1920         }
1921         case angle::FormatID::R32G32B32_UNORM:
1922         {
1923             static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 3, false);
1924             return format;
1925         }
1926         case angle::FormatID::R32G32B32A32_USCALED:
1927         {
1928             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, false);
1929             return format;
1930         }
1931         case angle::FormatID::R32G32B32A32_UNORM:
1932         {
1933             static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 4, false);
1934             return format;
1935         }
1936         case angle::FormatID::R8_SINT:
1937         {
1938             static const VertexFormat format(GL_BYTE, GL_FALSE, 1, true);
1939             return format;
1940         }
1941         case angle::FormatID::R8G8_SINT:
1942         {
1943             static const VertexFormat format(GL_BYTE, GL_FALSE, 2, true);
1944             return format;
1945         }
1946         case angle::FormatID::R8G8B8_SINT:
1947         {
1948             static const VertexFormat format(GL_BYTE, GL_FALSE, 3, true);
1949             return format;
1950         }
1951         case angle::FormatID::R8G8B8A8_SINT:
1952         {
1953             static const VertexFormat format(GL_BYTE, GL_FALSE, 4, true);
1954             return format;
1955         }
1956         case angle::FormatID::R8_UINT:
1957         {
1958             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, true);
1959             return format;
1960         }
1961         case angle::FormatID::R8G8_UINT:
1962         {
1963             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, true);
1964             return format;
1965         }
1966         case angle::FormatID::R8G8B8_UINT:
1967         {
1968             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, true);
1969             return format;
1970         }
1971         case angle::FormatID::R8G8B8A8_UINT:
1972         {
1973             static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, true);
1974             return format;
1975         }
1976         case angle::FormatID::R16_SINT:
1977         {
1978             static const VertexFormat format(GL_SHORT, GL_FALSE, 1, true);
1979             return format;
1980         }
1981         case angle::FormatID::R16G16_SINT:
1982         {
1983             static const VertexFormat format(GL_SHORT, GL_FALSE, 2, true);
1984             return format;
1985         }
1986         case angle::FormatID::R16G16B16_SINT:
1987         {
1988             static const VertexFormat format(GL_SHORT, GL_FALSE, 3, true);
1989             return format;
1990         }
1991         case angle::FormatID::R16G16B16A16_SINT:
1992         {
1993             static const VertexFormat format(GL_SHORT, GL_FALSE, 4, true);
1994             return format;
1995         }
1996         case angle::FormatID::R16_UINT:
1997         {
1998             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, true);
1999             return format;
2000         }
2001         case angle::FormatID::R16G16_UINT:
2002         {
2003             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, true);
2004             return format;
2005         }
2006         case angle::FormatID::R16G16B16_UINT:
2007         {
2008             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, true);
2009             return format;
2010         }
2011         case angle::FormatID::R16G16B16A16_UINT:
2012         {
2013             static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, true);
2014             return format;
2015         }
2016         case angle::FormatID::R32_SINT:
2017         {
2018             static const VertexFormat format(GL_INT, GL_FALSE, 1, true);
2019             return format;
2020         }
2021         case angle::FormatID::R32G32_SINT:
2022         {
2023             static const VertexFormat format(GL_INT, GL_FALSE, 2, true);
2024             return format;
2025         }
2026         case angle::FormatID::R32G32B32_SINT:
2027         {
2028             static const VertexFormat format(GL_INT, GL_FALSE, 3, true);
2029             return format;
2030         }
2031         case angle::FormatID::R32G32B32A32_SINT:
2032         {
2033             static const VertexFormat format(GL_INT, GL_FALSE, 4, true);
2034             return format;
2035         }
2036         case angle::FormatID::R32_UINT:
2037         {
2038             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, true);
2039             return format;
2040         }
2041         case angle::FormatID::R32G32_UINT:
2042         {
2043             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, true);
2044             return format;
2045         }
2046         case angle::FormatID::R32G32B32_UINT:
2047         {
2048             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, true);
2049             return format;
2050         }
2051         case angle::FormatID::R32G32B32A32_UINT:
2052         {
2053             static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, true);
2054             return format;
2055         }
2056         case angle::FormatID::R32_FIXED:
2057         {
2058             static const VertexFormat format(GL_FIXED, GL_FALSE, 1, false);
2059             return format;
2060         }
2061         case angle::FormatID::R32G32_FIXED:
2062         {
2063             static const VertexFormat format(GL_FIXED, GL_FALSE, 2, false);
2064             return format;
2065         }
2066         case angle::FormatID::R32G32B32_FIXED:
2067         {
2068             static const VertexFormat format(GL_FIXED, GL_FALSE, 3, false);
2069             return format;
2070         }
2071         case angle::FormatID::R32G32B32A32_FIXED:
2072         {
2073             static const VertexFormat format(GL_FIXED, GL_FALSE, 4, false);
2074             return format;
2075         }
2076         case angle::FormatID::R16_FLOAT:
2077         {
2078             static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 1, false);
2079             return format;
2080         }
2081         case angle::FormatID::R16G16_FLOAT:
2082         {
2083             static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 2, false);
2084             return format;
2085         }
2086         case angle::FormatID::R16G16B16_FLOAT:
2087         {
2088             static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 3, false);
2089             return format;
2090         }
2091         case angle::FormatID::R16G16B16A16_FLOAT:
2092         {
2093             static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 4, false);
2094             return format;
2095         }
2096         case angle::FormatID::R32_FLOAT:
2097         {
2098             static const VertexFormat format(GL_FLOAT, GL_FALSE, 1, false);
2099             return format;
2100         }
2101         case angle::FormatID::R32G32_FLOAT:
2102         {
2103             static const VertexFormat format(GL_FLOAT, GL_FALSE, 2, false);
2104             return format;
2105         }
2106         case angle::FormatID::R32G32B32_FLOAT:
2107         {
2108             static const VertexFormat format(GL_FLOAT, GL_FALSE, 3, false);
2109             return format;
2110         }
2111         case angle::FormatID::R32G32B32A32_FLOAT:
2112         {
2113             static const VertexFormat format(GL_FLOAT, GL_FALSE, 4, false);
2114             return format;
2115         }
2116         case angle::FormatID::R10G10B10A2_SSCALED:
2117         {
2118             static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, false);
2119             return format;
2120         }
2121         case angle::FormatID::R10G10B10A2_USCALED:
2122         {
2123             static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, false);
2124             return format;
2125         }
2126         case angle::FormatID::R10G10B10A2_SNORM:
2127         {
2128             static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_TRUE, 4, false);
2129             return format;
2130         }
2131         case angle::FormatID::R10G10B10A2_UNORM:
2132         {
2133             static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, false);
2134             return format;
2135         }
2136         case angle::FormatID::R10G10B10A2_SINT:
2137         {
2138             static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, true);
2139             return format;
2140         }
2141         case angle::FormatID::R10G10B10A2_UINT:
2142         {
2143             static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, true);
2144             return format;
2145         }
2146         default:
2147         {
2148             static const VertexFormat format(GL_NONE, GL_FALSE, 0, false);
2149             return format;
2150         }
2151     }
2152 }
2153 
GetVertexFormatSize(angle::FormatID vertexFormatID)2154 size_t GetVertexFormatSize(angle::FormatID vertexFormatID)
2155 {
2156     switch (vertexFormatID)
2157     {
2158         case angle::FormatID::R8_SSCALED:
2159         case angle::FormatID::R8_SNORM:
2160         case angle::FormatID::R8_USCALED:
2161         case angle::FormatID::R8_UNORM:
2162         case angle::FormatID::R8_SINT:
2163         case angle::FormatID::R8_UINT:
2164             return 1;
2165 
2166         case angle::FormatID::R8G8_SSCALED:
2167         case angle::FormatID::R8G8_SNORM:
2168         case angle::FormatID::R8G8_USCALED:
2169         case angle::FormatID::R8G8_UNORM:
2170         case angle::FormatID::R8G8_SINT:
2171         case angle::FormatID::R8G8_UINT:
2172         case angle::FormatID::R16_SSCALED:
2173         case angle::FormatID::R16_SNORM:
2174         case angle::FormatID::R16_USCALED:
2175         case angle::FormatID::R16_UNORM:
2176         case angle::FormatID::R16_SINT:
2177         case angle::FormatID::R16_UINT:
2178         case angle::FormatID::R16_FLOAT:
2179             return 2;
2180 
2181         case angle::FormatID::R8G8B8_SSCALED:
2182         case angle::FormatID::R8G8B8_SNORM:
2183         case angle::FormatID::R8G8B8_USCALED:
2184         case angle::FormatID::R8G8B8_UNORM:
2185         case angle::FormatID::R8G8B8_SINT:
2186         case angle::FormatID::R8G8B8_UINT:
2187             return 3;
2188 
2189         case angle::FormatID::R8G8B8A8_SSCALED:
2190         case angle::FormatID::R8G8B8A8_SNORM:
2191         case angle::FormatID::R8G8B8A8_USCALED:
2192         case angle::FormatID::R8G8B8A8_UNORM:
2193         case angle::FormatID::R8G8B8A8_SINT:
2194         case angle::FormatID::R8G8B8A8_UINT:
2195         case angle::FormatID::R16G16_SSCALED:
2196         case angle::FormatID::R16G16_SNORM:
2197         case angle::FormatID::R16G16_USCALED:
2198         case angle::FormatID::R16G16_UNORM:
2199         case angle::FormatID::R16G16_SINT:
2200         case angle::FormatID::R16G16_UINT:
2201         case angle::FormatID::R32_SSCALED:
2202         case angle::FormatID::R32_SNORM:
2203         case angle::FormatID::R32_USCALED:
2204         case angle::FormatID::R32_UNORM:
2205         case angle::FormatID::R32_SINT:
2206         case angle::FormatID::R32_UINT:
2207         case angle::FormatID::R16G16_FLOAT:
2208         case angle::FormatID::R32_FIXED:
2209         case angle::FormatID::R32_FLOAT:
2210         case angle::FormatID::R10G10B10A2_SSCALED:
2211         case angle::FormatID::R10G10B10A2_USCALED:
2212         case angle::FormatID::R10G10B10A2_SNORM:
2213         case angle::FormatID::R10G10B10A2_UNORM:
2214         case angle::FormatID::R10G10B10A2_SINT:
2215         case angle::FormatID::R10G10B10A2_UINT:
2216             return 4;
2217 
2218         case angle::FormatID::R16G16B16_SSCALED:
2219         case angle::FormatID::R16G16B16_SNORM:
2220         case angle::FormatID::R16G16B16_USCALED:
2221         case angle::FormatID::R16G16B16_UNORM:
2222         case angle::FormatID::R16G16B16_SINT:
2223         case angle::FormatID::R16G16B16_UINT:
2224         case angle::FormatID::R16G16B16_FLOAT:
2225             return 6;
2226 
2227         case angle::FormatID::R16G16B16A16_SSCALED:
2228         case angle::FormatID::R16G16B16A16_SNORM:
2229         case angle::FormatID::R16G16B16A16_USCALED:
2230         case angle::FormatID::R16G16B16A16_UNORM:
2231         case angle::FormatID::R16G16B16A16_SINT:
2232         case angle::FormatID::R16G16B16A16_UINT:
2233         case angle::FormatID::R32G32_SSCALED:
2234         case angle::FormatID::R32G32_SNORM:
2235         case angle::FormatID::R32G32_USCALED:
2236         case angle::FormatID::R32G32_UNORM:
2237         case angle::FormatID::R32G32_SINT:
2238         case angle::FormatID::R32G32_UINT:
2239         case angle::FormatID::R16G16B16A16_FLOAT:
2240         case angle::FormatID::R32G32_FIXED:
2241         case angle::FormatID::R32G32_FLOAT:
2242             return 8;
2243 
2244         case angle::FormatID::R32G32B32_SSCALED:
2245         case angle::FormatID::R32G32B32_SNORM:
2246         case angle::FormatID::R32G32B32_USCALED:
2247         case angle::FormatID::R32G32B32_UNORM:
2248         case angle::FormatID::R32G32B32_SINT:
2249         case angle::FormatID::R32G32B32_UINT:
2250         case angle::FormatID::R32G32B32_FIXED:
2251         case angle::FormatID::R32G32B32_FLOAT:
2252             return 12;
2253 
2254         case angle::FormatID::R32G32B32A32_SSCALED:
2255         case angle::FormatID::R32G32B32A32_SNORM:
2256         case angle::FormatID::R32G32B32A32_USCALED:
2257         case angle::FormatID::R32G32B32A32_UNORM:
2258         case angle::FormatID::R32G32B32A32_SINT:
2259         case angle::FormatID::R32G32B32A32_UINT:
2260         case angle::FormatID::R32G32B32A32_FIXED:
2261         case angle::FormatID::R32G32B32A32_FLOAT:
2262             return 16;
2263 
2264         case angle::FormatID::NONE:
2265         default:
2266             UNREACHABLE();
2267 #if !UNREACHABLE_IS_NORETURN
2268             return 0;
2269 #endif
2270     }
2271 }
2272 
ValidES3InternalFormat(GLenum internalFormat)2273 bool ValidES3InternalFormat(GLenum internalFormat)
2274 {
2275     const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
2276     return internalFormat != GL_NONE && formatMap.find(internalFormat) != formatMap.end();
2277 }
2278 
VertexFormat(GLenum typeIn,GLboolean normalizedIn,GLuint componentsIn,bool pureIntegerIn)2279 VertexFormat::VertexFormat(GLenum typeIn,
2280                            GLboolean normalizedIn,
2281                            GLuint componentsIn,
2282                            bool pureIntegerIn)
2283     : type(typeIn), normalized(normalizedIn), components(componentsIn), pureInteger(pureIntegerIn)
2284 {
2285     // float -> !normalized
2286     ASSERT(!(type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_FIXED) ||
2287            normalized == GL_FALSE);
2288 }
2289 }  // namespace gl
2290