diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /gfx/angle/checkout/src/libANGLE/formatutils.h | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/formatutils.h')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/formatutils.h | 577 |
1 files changed, 577 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/formatutils.h b/gfx/angle/checkout/src/libANGLE/formatutils.h new file mode 100644 index 0000000000..64cc42ec1f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/formatutils.h @@ -0,0 +1,577 @@ +// +// Copyright 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// formatutils.h: Queries for GL image formats. + +#ifndef LIBANGLE_FORMATUTILS_H_ +#define LIBANGLE_FORMATUTILS_H_ + +#include <stdint.h> +#include <cstddef> +#include <ostream> + +#include "angle_gl.h" +#include "common/android_util.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Config.h" +#include "libANGLE/Error.h" +#include "libANGLE/Version.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/angletypes.h" + +namespace gl +{ +struct VertexAttribute; + +struct FormatType final +{ + FormatType(); + FormatType(GLenum format_, GLenum type_); + FormatType(const FormatType &other) = default; + FormatType &operator=(const FormatType &other) = default; + + bool operator<(const FormatType &other) const; + + GLenum format; + GLenum type; +}; + +struct Type +{ + Type() : bytes(0), bytesShift(0), specialInterpretation(0) {} + + explicit Type(uint32_t packedTypeInfo) + : bytes(packedTypeInfo & 0xff), + bytesShift((packedTypeInfo >> 8) & 0xff), + specialInterpretation((packedTypeInfo >> 16) & 1) + {} + + GLuint bytes; + GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a + // more optimal way + bool specialInterpretation; +}; + +uint32_t GetPackedTypeInfo(GLenum type); + +ANGLE_INLINE GLenum GetNonLinearFormat(const GLenum format) +{ + switch (format) + { + case GL_BGRA8_EXT: + return GL_BGRA8_SRGB_ANGLEX; + case GL_RGBA8: + return GL_SRGB8_ALPHA8; + case GL_RGB8: + case GL_BGRX8_ANGLEX: + case GL_RGBX8_ANGLE: + return GL_SRGB8; + case GL_RGBA16F: + return GL_RGBA16F; + default: + return GL_NONE; + } +} + +ANGLE_INLINE bool ColorspaceFormatOverride(const EGLenum colorspace, GLenum *rendertargetformat) +{ + // Override the rendertargetformat based on colorpsace + switch (colorspace) + { + case EGL_GL_COLORSPACE_LINEAR: // linear colorspace no translation needed + case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT: // linear colorspace no translation needed + case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT: // linear colorspace no translation needed + case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT: // App, not the HW, will specify the + // transfer function + case EGL_GL_COLORSPACE_SCRGB_EXT: // App, not the HW, will specify the transfer function + // No translation + return true; + case EGL_GL_COLORSPACE_SRGB_KHR: + case EGL_GL_COLORSPACE_DISPLAY_P3_EXT: + { + GLenum nonLinearFormat = GetNonLinearFormat(*rendertargetformat); + if (nonLinearFormat != GL_NONE) + { + *rendertargetformat = nonLinearFormat; + return true; + } + else + { + return false; + } + } + break; + default: + UNREACHABLE(); + return false; + } +} + +ANGLE_INLINE const Type GetTypeInfo(GLenum type) +{ + return Type(GetPackedTypeInfo(type)); +} + +// This helpers use tricks based on the assumption that the type has certain values. +static_assert(static_cast<GLuint>(DrawElementsType::UnsignedByte) == 0, "Please update this code."); +static_assert(static_cast<GLuint>(DrawElementsType::UnsignedShort) == 1, + "Please update this code."); +static_assert(static_cast<GLuint>(DrawElementsType::UnsignedInt) == 2, "Please update this code."); +ANGLE_INLINE GLuint GetDrawElementsTypeSize(DrawElementsType type) +{ + return (1 << static_cast<GLuint>(type)); +} + +ANGLE_INLINE GLuint GetDrawElementsTypeShift(DrawElementsType type) +{ + return static_cast<GLuint>(type); +} + +// Information about an OpenGL internal format. Can be keyed on the internalFormat and type +// members. +struct InternalFormat +{ + InternalFormat(); + InternalFormat(const InternalFormat &other); + InternalFormat &operator=(const InternalFormat &other); + + GLuint computePixelBytes(GLenum formatType) const; + + [[nodiscard]] bool computeBufferRowLength(uint32_t width, uint32_t *resultOut) const; + [[nodiscard]] bool computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const; + + [[nodiscard]] bool computeRowPitch(GLenum formatType, + GLsizei width, + GLint alignment, + GLint rowLength, + GLuint *resultOut) const; + [[nodiscard]] bool computeDepthPitch(GLsizei height, + GLint imageHeight, + GLuint rowPitch, + GLuint *resultOut) const; + [[nodiscard]] bool computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight, + GLuint *resultOut) const; + + [[nodiscard]] bool computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const; + + [[nodiscard]] bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const; + + [[nodiscard]] std::pair<GLuint, GLuint> getCompressedImageMinBlocks() const; + + [[nodiscard]] bool computeSkipBytes(GLenum formatType, + GLuint rowPitch, + GLuint depthPitch, + const PixelStoreStateBase &state, + bool is3D, + GLuint *resultOut) const; + + [[nodiscard]] bool computePackUnpackEndByte(GLenum formatType, + const Extents &size, + const PixelStoreStateBase &state, + bool is3D, + GLuint *resultOut) const; + + bool isLUMA() const; + GLenum getReadPixelsFormat(const Extensions &extensions) const; + GLenum getReadPixelsType(const Version &version) const; + + // Support upload a portion of image? + bool supportSubImage() const; + + ANGLE_INLINE bool isChannelSizeCompatible(GLuint redSize, + GLuint greenSize, + GLuint blueSize, + GLuint alphaSize) const + { + // We only check for equality in all channel sizes + return ((redSize == redBits) && (greenSize == greenBits) && (blueSize == blueBits) && + (alphaSize == alphaBits)); + } + + // Return true if the format is a required renderbuffer format in the given version of the core + // spec. Note that it isn't always clear whether all the rules that apply to core required + // renderbuffer formats also apply to additional formats added by extensions. Because of this + // extension formats are conservatively not included. + bool isRequiredRenderbufferFormat(const Version &version) const; + + bool isInt() const; + bool isDepthOrStencil() const; + + bool operator==(const InternalFormat &other) const; + bool operator!=(const InternalFormat &other) const; + + GLenum internalFormat; + + bool sized; + GLenum sizedInternalFormat; + + GLuint redBits; + GLuint greenBits; + GLuint blueBits; + + GLuint luminanceBits; + + GLuint alphaBits; + GLuint sharedBits; + + GLuint depthBits; + GLuint stencilBits; + + GLuint pixelBytes; + + GLuint componentCount; + + bool compressed; + GLuint compressedBlockWidth; + GLuint compressedBlockHeight; + GLuint compressedBlockDepth; + + bool paletted; + GLuint paletteBits; + + GLenum format; + GLenum type; + + GLenum componentType; + GLenum colorEncoding; + + typedef bool (*SupportCheckFunction)(const Version &, const Extensions &); + SupportCheckFunction textureSupport; + SupportCheckFunction filterSupport; + SupportCheckFunction textureAttachmentSupport; // glFramebufferTexture2D + SupportCheckFunction renderbufferSupport; // glFramebufferRenderbuffer + SupportCheckFunction blendSupport; +}; + +// A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or +// unsized internal format and type. +// TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object. +struct Format +{ + // Sized types only. + explicit Format(GLenum internalFormat); + + // Sized or unsized types. + explicit Format(const InternalFormat &internalFormat); + Format(GLenum internalFormat, GLenum type); + + Format(const Format &other); + Format &operator=(const Format &other); + + bool valid() const; + + static Format Invalid(); + static bool SameSized(const Format &a, const Format &b); + static bool EquivalentForBlit(const Format &a, const Format &b); + + friend std::ostream &operator<<(std::ostream &os, const Format &fmt); + + // This is the sized info. + const InternalFormat *info; +}; + +const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat); +const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type); + +// Strip sizing information from an internal format. Doesn't necessarily validate that the internal +// format is valid. +GLenum GetUnsizedFormat(GLenum internalFormat); + +// Return whether the compressed format requires whole image/mip level to be uploaded to texture. +bool CompressedFormatRequiresWholeImage(GLenum internalFormat); + +// In support of GetImage, check for LUMA formats and override with real format +void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType); + +typedef std::set<GLenum> FormatSet; +const FormatSet &GetAllSizedInternalFormats(); + +typedef angle::HashMap<GLenum, angle::HashMap<GLenum, InternalFormat>> InternalFormatInfoMap; +const InternalFormatInfoMap &GetInternalFormatMap(); + +int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap); + +GLenum GetConfigColorBufferFormat(const egl::Config *config); +GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config); + +ANGLE_INLINE int GetNativeVisualID(const InternalFormat &internalFormat) +{ + int nativeVisualId = 0; +#if defined(ANGLE_PLATFORM_ANDROID) + nativeVisualId = + angle::android::GLInternalFormatToNativePixelFormat(internalFormat.internalFormat); +#endif +#if defined(ANGLE_PLATFORM_LINUX) && defined(ANGLE_USES_GBM) + nativeVisualId = angle::GLInternalFormatToGbmFourCCFormat(internalFormat.internalFormat); +#endif + + return nativeVisualId; +} + +// From the ESSL 3.00.4 spec: +// Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned +// integers and integer vectors. Vertex shader inputs cannot be arrays or structures. + +enum AttributeType +{ + ATTRIBUTE_FLOAT, + ATTRIBUTE_VEC2, + ATTRIBUTE_VEC3, + ATTRIBUTE_VEC4, + ATTRIBUTE_INT, + ATTRIBUTE_IVEC2, + ATTRIBUTE_IVEC3, + ATTRIBUTE_IVEC4, + ATTRIBUTE_UINT, + ATTRIBUTE_UVEC2, + ATTRIBUTE_UVEC3, + ATTRIBUTE_UVEC4, + ATTRIBUTE_MAT2, + ATTRIBUTE_MAT3, + ATTRIBUTE_MAT4, + ATTRIBUTE_MAT2x3, + ATTRIBUTE_MAT2x4, + ATTRIBUTE_MAT3x2, + ATTRIBUTE_MAT3x4, + ATTRIBUTE_MAT4x2, + ATTRIBUTE_MAT4x3, +}; + +AttributeType GetAttributeType(GLenum enumValue); + +typedef std::vector<angle::FormatID> InputLayout; + +struct VertexFormat : private angle::NonCopyable +{ + VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn); + + GLenum type; + GLboolean normalized; + GLuint components; + bool pureInteger; +}; + +angle::FormatID GetVertexFormatID(VertexAttribType type, + GLboolean normalized, + GLuint components, + bool pureInteger); + +angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType); +angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType); +const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID); +size_t GetVertexFormatSize(angle::FormatID vertexFormatID); +angle::FormatID ConvertFormatSignedness(const angle::Format &format); + +ANGLE_INLINE bool IsS3TCFormat(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsRGTCFormat(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RED_RGTC1_EXT: + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsBPTCFormat(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsASTC2DFormat(const GLenum format) +{ + if ((format >= GL_COMPRESSED_RGBA_ASTC_4x4_KHR && + format <= GL_COMPRESSED_RGBA_ASTC_12x12_KHR) || + (format >= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR && + format <= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR)) + { + return true; + } + return false; +} + +ANGLE_INLINE bool IsETC1Format(const GLenum format) +{ + switch (format) + { + case GL_ETC1_RGB8_OES: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsETC2EACFormat(const GLenum format) +{ + // ES 3.1, Table 8.19 + switch (format) + { + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsPVRTC1Format(const GLenum format) +{ + switch (format) + { + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: + case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: + return true; + + default: + return false; + } +} + +ANGLE_INLINE bool IsBGRAFormat(const GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_BGRA8_EXT: + case GL_BGRA4_ANGLEX: + case GL_BGR5_A1_ANGLEX: + case GL_BGRA8_SRGB_ANGLEX: + case GL_BGRX8_ANGLEX: + case GL_RGBX8_ANGLE: + case GL_BGR565_ANGLEX: + case GL_BGR10_A2_ANGLEX: + return true; + + default: + return false; + } +} + +// Check if an internal format is ever valid in ES3. Makes no checks about support for a specific +// context. +bool ValidES3InternalFormat(GLenum internalFormat); + +// Implemented in format_map_autogen.cpp +bool ValidES3Format(GLenum format); +bool ValidES3Type(GLenum type); +bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat); + +// Implemented in format_map_desktop.cpp +bool ValidDesktopFormat(GLenum format); +bool ValidDesktopType(GLenum type); +bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat); + +// Implemented in es3_copy_conversion_table_autogen.cpp +bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat); + +ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type) +{ + if (pureInteger) + { + switch (type) + { + case VertexAttribType::Byte: + case VertexAttribType::Short: + case VertexAttribType::Int: + return ComponentType::Int; + + case VertexAttribType::UnsignedByte: + case VertexAttribType::UnsignedShort: + case VertexAttribType::UnsignedInt: + return ComponentType::UnsignedInt; + + default: + UNREACHABLE(); + return ComponentType::NoType; + } + } + else + { + return ComponentType::Float; + } +} + +constexpr std::size_t kMaxYuvPlaneCount = 3; +template <typename T> +using YuvPlaneArray = std::array<T, kMaxYuvPlaneCount>; + +struct YuvFormatInfo +{ + // Sized types only. + YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent); + + GLenum glInternalFormat; + uint32_t planeCount; + YuvPlaneArray<uint32_t> planeBpp; + YuvPlaneArray<Extents> planeExtent; + YuvPlaneArray<uint32_t> planePitch; + YuvPlaneArray<uint32_t> planeSize; + YuvPlaneArray<uint32_t> planeOffset; +}; + +bool IsYuvFormat(GLenum format); +uint32_t GetPlaneCount(GLenum format); +uint32_t GetYPlaneBpp(GLenum format); +uint32_t GetChromaPlaneBpp(GLenum format); +void GetSubSampleFactor(GLenum format, + int *horizontalSubsampleFactor, + int *verticalSubsampleFactor); +} // namespace gl + +#endif // LIBANGLE_FORMATUTILS_H_ |