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.h: Queries for GL image formats.
8
9 #ifndef LIBANGLE_FORMATUTILS_H_
10 #define LIBANGLE_FORMATUTILS_H_
11
12 #include <stdint.h>
13 #include <cstddef>
14 #include <ostream>
15
16 #include "angle_gl.h"
17 #include "common/android_util.h"
18 #include "common/hash_containers.h"
19 #include "libANGLE/Caps.h"
20 #include "libANGLE/Config.h"
21 #include "libANGLE/Error.h"
22 #include "libANGLE/Version.h"
23 #include "libANGLE/VertexAttribute.h"
24 #include "libANGLE/angletypes.h"
25
26 namespace gl
27 {
28 struct VertexAttribute;
29
30 struct FormatType final
31 {
32 FormatType();
33 FormatType(GLenum format_, GLenum type_);
34 FormatType(const FormatType &other) = default;
35 FormatType &operator=(const FormatType &other) = default;
36
37 bool operator<(const FormatType &other) const;
38
39 GLenum format;
40 GLenum type;
41 };
42
43 struct Type
44 {
TypeType45 Type() : bytes(0), bytesShift(0), specialInterpretation(0) {}
46
TypeType47 explicit Type(uint32_t packedTypeInfo)
48 : bytes(packedTypeInfo & 0xff),
49 bytesShift((packedTypeInfo >> 8) & 0xff),
50 specialInterpretation((packedTypeInfo >> 16) & 1)
51 {}
52
53 GLuint bytes;
54 GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a
55 // more optimal way
56 bool specialInterpretation;
57 };
58
59 uint32_t GetPackedTypeInfo(GLenum type);
60
GetNonLinearFormat(const GLenum format)61 ANGLE_INLINE GLenum GetNonLinearFormat(const GLenum format)
62 {
63 switch (format)
64 {
65 case GL_BGRA8_EXT:
66 return GL_BGRA8_SRGB_ANGLEX;
67 case GL_RGBA8:
68 return GL_SRGB8_ALPHA8;
69 case GL_RGB8:
70 return GL_SRGB8;
71 case GL_BGRX8_ANGLEX:
72 return GL_BGRX8_SRGB_ANGLEX;
73 case GL_RGBX8_ANGLE:
74 return GL_RGBX8_SRGB_ANGLEX;
75 case GL_RGBA16F:
76 return GL_RGBA16F;
77 case GL_RGB10_A2_EXT:
78 return GL_RGB10_A2_EXT;
79 case GL_SRGB8:
80 case GL_SRGB8_ALPHA8:
81 case GL_SRGB_ALPHA_EXT:
82 case GL_SRGB_EXT:
83 return format;
84 default:
85 return GL_NONE;
86 }
87 }
88
GetLinearFormat(const GLenum format)89 ANGLE_INLINE GLenum GetLinearFormat(const GLenum format)
90 {
91 switch (format)
92 {
93 case GL_BGRA8_SRGB_ANGLEX:
94 return GL_BGRA8_EXT;
95 case GL_SRGB8_ALPHA8:
96 return GL_RGBA8;
97 case GL_SRGB8:
98 return GL_RGB8;
99 case GL_BGRX8_SRGB_ANGLEX:
100 return GL_BGRX8_ANGLEX;
101 case GL_RGBX8_SRGB_ANGLEX:
102 return GL_RGBX8_ANGLE;
103 default:
104 return format;
105 }
106 }
107
ColorspaceFormatOverride(const EGLenum colorspace,GLenum * rendertargetformat)108 ANGLE_INLINE bool ColorspaceFormatOverride(const EGLenum colorspace, GLenum *rendertargetformat)
109 {
110 // Override the rendertargetformat based on colorpsace
111 switch (colorspace)
112 {
113 case EGL_GL_COLORSPACE_LINEAR: // linear colorspace no translation needed
114 case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT: // linear colorspace no translation needed
115 case EGL_GL_COLORSPACE_BT2020_LINEAR_EXT: // linear colorspace no translation needed
116 case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT: // linear colorspace no translation needed
117 *rendertargetformat = GetLinearFormat(*rendertargetformat);
118 return true;
119 case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT: // App, not the HW, will specify the
120 // transfer function
121 case EGL_GL_COLORSPACE_SCRGB_EXT: // App, not the HW, will specify the transfer function
122 // No translation
123 return true;
124 case EGL_GL_COLORSPACE_SRGB_KHR:
125 case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
126 case EGL_GL_COLORSPACE_BT2020_HLG_EXT:
127 case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
128 {
129 GLenum nonLinearFormat = GetNonLinearFormat(*rendertargetformat);
130 if (nonLinearFormat != GL_NONE)
131 {
132 *rendertargetformat = nonLinearFormat;
133 return true;
134 }
135 else
136 {
137 return false;
138 }
139 }
140 break;
141 default:
142 UNREACHABLE();
143 return false;
144 }
145 }
146
GetTypeInfo(GLenum type)147 ANGLE_INLINE const Type GetTypeInfo(GLenum type)
148 {
149 return Type(GetPackedTypeInfo(type));
150 }
151
152 // This helpers use tricks based on the assumption that the type has certain values.
153 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedByte) == 0, "Please update this code.");
154 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedShort) == 1,
155 "Please update this code.");
156 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedInt) == 2, "Please update this code.");
GetDrawElementsTypeSize(DrawElementsType type)157 ANGLE_INLINE GLuint GetDrawElementsTypeSize(DrawElementsType type)
158 {
159 return (1 << static_cast<GLuint>(type));
160 }
161
GetDrawElementsTypeShift(DrawElementsType type)162 ANGLE_INLINE GLuint GetDrawElementsTypeShift(DrawElementsType type)
163 {
164 return static_cast<GLuint>(type);
165 }
166
167 // Information about an OpenGL internal format. Can be keyed on the internalFormat and type
168 // members.
169 struct InternalFormat
170 {
171 InternalFormat();
172 InternalFormat(const InternalFormat &other);
173 InternalFormat &operator=(const InternalFormat &other);
174
175 GLuint computePixelBytes(GLenum formatType) const;
176
177 [[nodiscard]] bool computeBufferRowLength(uint32_t width, uint32_t *resultOut) const;
178 [[nodiscard]] bool computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const;
179
180 [[nodiscard]] bool computeRowPitch(GLenum formatType,
181 GLsizei width,
182 GLint alignment,
183 GLint rowLength,
184 GLuint *resultOut) const;
185 [[nodiscard]] bool computeDepthPitch(GLsizei height,
186 GLint imageHeight,
187 GLuint rowPitch,
188 GLuint *resultOut) const;
189 [[nodiscard]] bool computeDepthPitch(GLenum formatType,
190 GLsizei width,
191 GLsizei height,
192 GLint alignment,
193 GLint rowLength,
194 GLint imageHeight,
195 GLuint *resultOut) const;
196
197 [[nodiscard]] bool computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const;
198
199 [[nodiscard]] bool computeCompressedImageRowPitch(GLsizei width, GLuint *resultOut) const;
200
201 [[nodiscard]] bool computeCompressedImageDepthPitch(GLsizei height,
202 GLuint rowPitch,
203 GLuint *resultOut) const;
204
205 [[nodiscard]] bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const;
206
207 [[nodiscard]] std::pair<GLuint, GLuint> getCompressedImageMinBlocks() const;
208
209 [[nodiscard]] bool computeSkipBytes(GLenum formatType,
210 GLuint rowPitch,
211 GLuint depthPitch,
212 const PixelStoreStateBase &state,
213 bool is3D,
214 GLuint *resultOut) const;
215
216 [[nodiscard]] bool computePackUnpackEndByte(GLenum formatType,
217 const Extents &size,
218 const PixelStoreStateBase &state,
219 bool is3D,
220 GLuint *resultOut) const;
221
222 bool isLUMA() const;
223 GLenum getReadPixelsFormat(const Extensions &extensions) const;
224 GLenum getReadPixelsType(const Version &version) const;
225
226 // Support upload a portion of image?
227 bool supportSubImage() const;
228
isChannelSizeCompatibleInternalFormat229 ANGLE_INLINE bool isChannelSizeCompatible(GLuint redSize,
230 GLuint greenSize,
231 GLuint blueSize,
232 GLuint alphaSize) const
233 {
234 // We only check for equality in all channel sizes
235 return ((redSize == redBits) && (greenSize == greenBits) && (blueSize == blueBits) &&
236 (alphaSize == alphaBits));
237 }
238
239 // Return true if the format is a required renderbuffer format in the given version of the core
240 // spec. Note that it isn't always clear whether all the rules that apply to core required
241 // renderbuffer formats also apply to additional formats added by extensions. Because of this
242 // extension formats are conservatively not included.
243 bool isRequiredRenderbufferFormat(const Version &version) const;
244
245 bool isInt() const;
246 bool isDepthOrStencil() const;
247
248 GLuint getEGLConfigBufferSize() const;
249
250 bool operator==(const InternalFormat &other) const;
251 bool operator!=(const InternalFormat &other) const;
252
253 GLenum internalFormat;
254
255 bool sized;
256 GLenum sizedInternalFormat;
257
258 GLuint redBits;
259 GLuint greenBits;
260 GLuint blueBits;
261
262 GLuint luminanceBits;
263
264 GLuint alphaBits;
265 GLuint sharedBits;
266
267 GLuint depthBits;
268 GLuint stencilBits;
269
270 GLuint pixelBytes;
271
272 GLuint componentCount;
273
274 bool compressed;
275 GLuint compressedBlockWidth;
276 GLuint compressedBlockHeight;
277 GLuint compressedBlockDepth;
278
279 bool paletted;
280 GLuint paletteBits;
281
282 GLenum format;
283 GLenum type;
284
285 GLenum componentType;
286 GLenum colorEncoding;
287
288 typedef bool (*SupportCheckFunction)(const Version &, const Extensions &);
289 SupportCheckFunction textureSupport;
290 SupportCheckFunction filterSupport;
291 SupportCheckFunction textureAttachmentSupport; // glFramebufferTexture2D
292 SupportCheckFunction renderbufferSupport; // glFramebufferRenderbuffer
293 SupportCheckFunction blendSupport;
294 };
295
296 // A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or
297 // unsized internal format and type.
298 // TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object.
299 struct Format
300 {
301 // Sized types only.
302 explicit Format(GLenum internalFormat);
303
304 // Sized or unsized types.
FormatFormat305 explicit Format(const InternalFormat &internalFormat) : info(&internalFormat) {}
306
307 Format(GLenum internalFormat, GLenum type);
308
309 Format(const Format &other) = default;
310 Format &operator=(const Format &other) = default;
311
312 bool valid() const;
313
314 static Format Invalid();
315 static bool SameSized(const Format &a, const Format &b);
316 static bool EquivalentForBlit(const Format &a, const Format &b);
317
318 friend std::ostream &operator<<(std::ostream &os, const Format &fmt);
319
320 // This is the sized info.
321 const InternalFormat *info;
322 };
323
324 const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat);
325 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type);
326
327 // Strip sizing information from an internal format. Doesn't necessarily validate that the internal
328 // format is valid.
329 GLenum GetUnsizedFormat(GLenum internalFormat);
330
331 // Return whether the compressed format requires whole image/mip level to be uploaded to texture.
332 bool CompressedFormatRequiresWholeImage(GLenum internalFormat);
333
334 // In support of GetImage, check for LUMA formats and override with real format
335 void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType);
336
337 typedef std::set<GLenum> FormatSet;
338 const FormatSet &GetAllSizedInternalFormats();
339
340 typedef angle::HashMap<GLenum, angle::HashMap<GLenum, InternalFormat>> InternalFormatInfoMap;
341 const InternalFormatInfoMap &GetInternalFormatMap();
342
343 int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap);
344
345 GLenum GetConfigColorBufferFormat(const egl::Config *config);
346 GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config);
347
GetNativeVisualID(const InternalFormat & internalFormat)348 ANGLE_INLINE int GetNativeVisualID(const InternalFormat &internalFormat)
349 {
350 int nativeVisualId = 0;
351 #if defined(ANGLE_PLATFORM_ANDROID)
352 nativeVisualId =
353 angle::android::GLInternalFormatToNativePixelFormat(internalFormat.internalFormat);
354 #endif
355 #if defined(ANGLE_PLATFORM_LINUX) && defined(ANGLE_USES_GBM)
356 nativeVisualId = angle::GLInternalFormatToGbmFourCCFormat(internalFormat.internalFormat);
357 #endif
358
359 return nativeVisualId;
360 }
361
362 // From the ESSL 3.00.4 spec:
363 // Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned
364 // integers and integer vectors. Vertex shader inputs cannot be arrays or structures.
365
366 enum AttributeType
367 {
368 ATTRIBUTE_FLOAT,
369 ATTRIBUTE_VEC2,
370 ATTRIBUTE_VEC3,
371 ATTRIBUTE_VEC4,
372 ATTRIBUTE_INT,
373 ATTRIBUTE_IVEC2,
374 ATTRIBUTE_IVEC3,
375 ATTRIBUTE_IVEC4,
376 ATTRIBUTE_UINT,
377 ATTRIBUTE_UVEC2,
378 ATTRIBUTE_UVEC3,
379 ATTRIBUTE_UVEC4,
380 ATTRIBUTE_MAT2,
381 ATTRIBUTE_MAT3,
382 ATTRIBUTE_MAT4,
383 ATTRIBUTE_MAT2x3,
384 ATTRIBUTE_MAT2x4,
385 ATTRIBUTE_MAT3x2,
386 ATTRIBUTE_MAT3x4,
387 ATTRIBUTE_MAT4x2,
388 ATTRIBUTE_MAT4x3,
389 };
390
391 AttributeType GetAttributeType(GLenum enumValue);
392
393 typedef std::vector<angle::FormatID> InputLayout;
394
395 struct VertexFormat : private angle::NonCopyable
396 {
397 VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn);
398
399 GLenum type;
400 GLboolean normalized;
401 GLuint components;
402 bool pureInteger;
403 };
404
405 constexpr uint32_t kVertexFormatCount = static_cast<uint32_t>(VertexAttribType::EnumCount);
406 extern const angle::FormatID kVertexFormatPureInteger[kVertexFormatCount][4];
407 extern const angle::FormatID kVertexFormatNormalized[kVertexFormatCount][4];
408 extern const angle::FormatID kVertexFormatScaled[kVertexFormatCount][4];
409
GetVertexFormatID(VertexAttribType type,GLboolean normalized,GLuint components,bool pureInteger)410 ANGLE_INLINE angle::FormatID GetVertexFormatID(VertexAttribType type,
411 GLboolean normalized,
412 GLuint components,
413 bool pureInteger)
414 {
415 ASSERT(components >= 1 && components <= 4);
416
417 angle::FormatID result;
418 int index = static_cast<int>(type);
419 if (pureInteger)
420 {
421 result = kVertexFormatPureInteger[index][components - 1];
422 }
423 else if (normalized)
424 {
425 result = kVertexFormatNormalized[index][components - 1];
426 }
427 else
428 {
429 result = kVertexFormatScaled[index][components - 1];
430 }
431
432 ASSERT(result != angle::FormatID::NONE);
433 return result;
434 }
435
436 angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType);
437 angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType);
438 const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID);
439 size_t GetVertexFormatSize(angle::FormatID vertexFormatID);
440 angle::FormatID ConvertFormatSignedness(const angle::Format &format);
441
IsS3TCFormat(const GLenum format)442 ANGLE_INLINE bool IsS3TCFormat(const GLenum format)
443 {
444 switch (format)
445 {
446 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
447 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
448 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
449 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
450 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
451 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
452 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
453 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
454 return true;
455
456 default:
457 return false;
458 }
459 }
460
IsRGTCFormat(const GLenum format)461 ANGLE_INLINE bool IsRGTCFormat(const GLenum format)
462 {
463 switch (format)
464 {
465 case GL_COMPRESSED_RED_RGTC1_EXT:
466 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
467 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
468 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
469 return true;
470
471 default:
472 return false;
473 }
474 }
475
IsBPTCFormat(const GLenum format)476 ANGLE_INLINE bool IsBPTCFormat(const GLenum format)
477 {
478 switch (format)
479 {
480 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
481 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
482 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
483 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
484 return true;
485
486 default:
487 return false;
488 }
489 }
490
IsASTC2DFormat(const GLenum format)491 ANGLE_INLINE bool IsASTC2DFormat(const GLenum format)
492 {
493 if ((format >= GL_COMPRESSED_RGBA_ASTC_4x4_KHR &&
494 format <= GL_COMPRESSED_RGBA_ASTC_12x12_KHR) ||
495 (format >= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR &&
496 format <= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR))
497 {
498 return true;
499 }
500 return false;
501 }
502
IsETC1Format(const GLenum format)503 ANGLE_INLINE bool IsETC1Format(const GLenum format)
504 {
505 switch (format)
506 {
507 case GL_ETC1_RGB8_OES:
508 return true;
509
510 default:
511 return false;
512 }
513 }
514
IsETC2EACFormat(const GLenum format)515 ANGLE_INLINE bool IsETC2EACFormat(const GLenum format)
516 {
517 // ES 3.1, Table 8.19
518 switch (format)
519 {
520 case GL_COMPRESSED_R11_EAC:
521 case GL_COMPRESSED_SIGNED_R11_EAC:
522 case GL_COMPRESSED_RG11_EAC:
523 case GL_COMPRESSED_SIGNED_RG11_EAC:
524 case GL_COMPRESSED_RGB8_ETC2:
525 case GL_COMPRESSED_SRGB8_ETC2:
526 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
527 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
528 case GL_COMPRESSED_RGBA8_ETC2_EAC:
529 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
530 return true;
531
532 default:
533 return false;
534 }
535 }
536
IsPVRTC1Format(const GLenum format)537 ANGLE_INLINE constexpr bool IsPVRTC1Format(const GLenum format)
538 {
539 // This function is called for all compressed texture uploads. The expression below generates
540 // fewer instructions than a regular switch statement. Two groups of four consecutive values,
541 // each group starts with two least significant bits unset.
542 return ((format & ~3) == GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG) ||
543 ((format & ~3) == GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT);
544 }
545 static_assert(IsPVRTC1Format(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG), "0x8C00");
546 static_assert(IsPVRTC1Format(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG), "0x8C01");
547 static_assert(IsPVRTC1Format(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG), "0x8C02");
548 static_assert(IsPVRTC1Format(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG), "0x8C03");
549 static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT), "0x8A54");
550 static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT), "0x8A55");
551 static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT), "0x8A56");
552 static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT), "0x8A57");
553 static_assert(!IsPVRTC1Format(0x8BFF) && !IsPVRTC1Format(0x8C04), "invalid");
554 static_assert(!IsPVRTC1Format(0x8A53) && !IsPVRTC1Format(0x8A58), "invalid");
555
IsBGRAFormat(const GLenum internalFormat)556 ANGLE_INLINE bool IsBGRAFormat(const GLenum internalFormat)
557 {
558 switch (internalFormat)
559 {
560 case GL_BGRA8_EXT:
561 case GL_BGRA4_ANGLEX:
562 case GL_BGR5_A1_ANGLEX:
563 case GL_BGRA8_SRGB_ANGLEX:
564 case GL_BGRX8_ANGLEX:
565 case GL_BGR565_ANGLEX:
566 case GL_BGR10_A2_ANGLEX:
567 return true;
568
569 default:
570 return false;
571 }
572 }
573
574 // Check if an internal format is ever valid in ES3. Makes no checks about support for a specific
575 // context.
576 bool ValidES3InternalFormat(GLenum internalFormat);
577
578 // Implemented in format_map_autogen.cpp
579 bool ValidES3Format(GLenum format);
580 bool ValidES3Type(GLenum type);
581 bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat);
582
583 // Implemented in es3_copy_conversion_table_autogen.cpp
584 bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat);
585
GetVertexAttributeComponentType(bool pureInteger,VertexAttribType type)586 ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type)
587 {
588 if (pureInteger)
589 {
590 switch (type)
591 {
592 case VertexAttribType::Byte:
593 case VertexAttribType::Short:
594 case VertexAttribType::Int:
595 return ComponentType::Int;
596
597 case VertexAttribType::UnsignedByte:
598 case VertexAttribType::UnsignedShort:
599 case VertexAttribType::UnsignedInt:
600 return ComponentType::UnsignedInt;
601
602 default:
603 UNREACHABLE();
604 return ComponentType::NoType;
605 }
606 }
607 else
608 {
609 return ComponentType::Float;
610 }
611 }
612
613 constexpr std::size_t kMaxYuvPlaneCount = 3;
614 template <typename T>
615 using YuvPlaneArray = std::array<T, kMaxYuvPlaneCount>;
616
617 struct YuvFormatInfo
618 {
619 // Sized types only.
620 YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent);
621
622 GLenum glInternalFormat;
623 uint32_t planeCount;
624 YuvPlaneArray<uint32_t> planeBpp;
625 YuvPlaneArray<Extents> planeExtent;
626 YuvPlaneArray<uint32_t> planePitch;
627 YuvPlaneArray<uint32_t> planeSize;
628 YuvPlaneArray<uint32_t> planeOffset;
629 };
630
631 bool IsYuvFormat(GLenum format);
632 uint32_t GetPlaneCount(GLenum format);
633 uint32_t GetYPlaneBpp(GLenum format);
634 uint32_t GetChromaPlaneBpp(GLenum format);
635 void GetSubSampleFactor(GLenum format,
636 int *horizontalSubsampleFactor,
637 int *verticalSubsampleFactor);
638 } // namespace gl
639
640 #endif // LIBANGLE_FORMATUTILS_H_
641