// // Copyright 2002 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. // // utilities.h: Conversion functions and other utility routines. #ifndef COMMON_UTILITIES_H_ #define COMMON_UTILITIES_H_ #ifdef UNSAFE_BUFFERS_BUILD # pragma allow_unsafe_buffers #endif #include #include #include #include #include #include #include #include "angle_gl.h" #include "common/PackedEnums.h" #include "common/mathutil.h" #include "common/platform.h" namespace sh { struct ShaderVariable; } namespace gl { int VariableComponentCount(GLenum type); GLenum VariableComponentType(GLenum type); size_t VariableComponentSize(GLenum type); size_t VariableInternalSize(GLenum type); size_t VariableExternalSize(GLenum type); int VariableRowCount(GLenum type); int VariableColumnCount(GLenum type); bool IsSamplerType(GLenum type); bool IsSamplerCubeType(GLenum type); bool IsSamplerYUVType(GLenum type); bool IsImageType(GLenum type); bool IsImage2DType(GLenum type); bool IsAtomicCounterType(GLenum type); bool IsOpaqueType(GLenum type); bool IsMatrixType(GLenum type); bool IsFloatScalarAndVectorType(GLenum type); bool IsFloatVectorType(GLenum type); GLenum TransposeMatrixType(GLenum type); int VariableRegisterCount(GLenum type); int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix); int MatrixComponentCount(GLenum type, bool isRowMajorMatrix); int VariableSortOrder(GLenum type); GLenum VariableBoolVectorType(GLenum type); std::string GetGLSLTypeString(GLenum type); int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize); // Parse the base resource name and array indices. Returns the base name of the resource. // If the provided name doesn't index an array, the outSubscripts vector will be empty. // If the provided name indexes an array, the outSubscripts vector will contain indices with // outermost array indices in the back. If an array index is invalid, GL_INVALID_INDEX is added to // outSubscripts. std::string ParseResourceName(const std::string &name, std::vector *outSubscripts); bool IsBuiltInName(const char *name); ANGLE_INLINE bool IsBuiltInName(const std::string &name) { return IsBuiltInName(name.c_str()); } // Strips only the last array index from a resource name. std::string StripLastArrayIndex(const std::string &name); bool SamplerNameContainsNonZeroArrayElement(const std::string &name); // Find the range of index values in the provided indices pointer. Primitive restart indices are // only counted in the range if primitive restart is disabled. IndexRange ComputeIndexRange(DrawElementsType indexType, const GLvoid *indices, size_t count, bool primitiveRestartEnabled); // Get the primitive restart index value for the given index type. GLuint GetPrimitiveRestartIndex(DrawElementsType indexType); // Get the primitive restart index value with the given C++ type. template constexpr T GetPrimitiveRestartIndexFromType() { return std::numeric_limits::max(); } static_assert(GetPrimitiveRestartIndexFromType() == 0xFF, "verify restart index for uint8_t values"); static_assert(GetPrimitiveRestartIndexFromType() == 0xFFFF, "verify restart index for uint8_t values"); static_assert(GetPrimitiveRestartIndexFromType() == 0xFFFFFFFF, "verify restart index for uint8_t values"); bool IsTriangleMode(PrimitiveMode drawMode); bool IsPolygonMode(PrimitiveMode mode); namespace priv { extern const angle::PackedEnumMap gLineModes; } // namespace priv ANGLE_INLINE bool IsLineMode(PrimitiveMode primitiveMode) { return priv::gLineModes[primitiveMode]; } bool IsIntegerFormat(GLenum unsizedFormat); // Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently // perform overflow checks. unsigned int ArraySizeProduct(const std::vector &arraySizes); // Returns the product of the sizes in the vector except for the outermost dimension, or 1 if the // vector is empty. unsigned int InnerArraySizeProduct(const std::vector &arraySizes); // Returns the outermost array dimension, or 1 if the vector is empty. unsigned int OutermostArraySize(const std::vector &arraySizes); // Return the array index at the end of name, and write the length of name before the final array // index into nameLengthWithoutArrayIndexOut. In case name doesn't include an array index, return // GL_INVALID_INDEX and write the length of the original string. unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut); enum class SamplerFormat : uint8_t { Float = 0, Unsigned = 1, Signed = 2, Shadow = 3, InvalidEnum = 4, EnumCount = 4, }; struct UniformTypeInfo final : angle::NonCopyable { inline constexpr UniformTypeInfo(GLenum type, GLenum componentType, GLenum textureType, GLenum transposedMatrixType, GLenum boolVectorType, SamplerFormat samplerFormat, int rowCount, int columnCount, int componentCount, size_t componentSize, size_t internalSize, size_t externalSize, bool isSampler, bool isMatrixType, bool isImageType); GLenum type; GLenum componentType; GLenum textureType; GLenum transposedMatrixType; GLenum boolVectorType; SamplerFormat samplerFormat; int rowCount; int columnCount; int componentCount; size_t componentSize; size_t internalSize; size_t externalSize; bool isSampler; bool isMatrixType; bool isImageType; }; inline constexpr UniformTypeInfo::UniformTypeInfo(GLenum type, GLenum componentType, GLenum textureType, GLenum transposedMatrixType, GLenum boolVectorType, SamplerFormat samplerFormat, int rowCount, int columnCount, int componentCount, size_t componentSize, size_t internalSize, size_t externalSize, bool isSampler, bool isMatrixType, bool isImageType) : type(type), componentType(componentType), textureType(textureType), transposedMatrixType(transposedMatrixType), boolVectorType(boolVectorType), samplerFormat(samplerFormat), rowCount(rowCount), columnCount(columnCount), componentCount(componentCount), componentSize(componentSize), internalSize(internalSize), externalSize(externalSize), isSampler(isSampler), isMatrixType(isMatrixType), isImageType(isImageType) {} struct UniformTypeIndex { uint16_t value; }; const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType); UniformTypeIndex GetUniformTypeIndex(GLenum uniformType); const char *GetGenericErrorMessage(GLenum error); unsigned int ElementTypeSize(GLenum elementType); bool IsMipmapFiltered(GLenum minFilterMode); template T GetClampedVertexCount(size_t vertexCount) { static constexpr size_t kMax = static_cast(std::numeric_limits::max()); return static_cast(vertexCount > kMax ? kMax : vertexCount); } enum class PipelineType { GraphicsPipeline = 0, ComputePipeline = 1, }; PipelineType GetPipelineType(ShaderType shaderType); // For use with KHR_debug. const char *GetDebugMessageSourceString(GLenum source); const char *GetDebugMessageTypeString(GLenum type); const char *GetDebugMessageSeverityString(GLenum severity); // For use with EXT_texture_sRGB_decode // A texture may be forced to skip decoding to a linear colorspace even if its format // is in sRGB colorspace. // // Default - decode data according to the image's format's colorspace // Skip - data is not decoded during sampling enum class SrgbDecode { Default = 0, Skip }; // For use with EXT_texture_format_sRGB_override // A texture may be forced to decode data to linear colorspace even if its format // is in linear colorspace. // // Default - decode data according to the image's format's colorspace // SRGB - data will be decoded to linear colorspace irrespective of texture's format enum class SrgbOverride { Default = 0, SRGB }; // For use with EXT_sRGB_write_control // A framebuffer may be forced to not encode data to sRGB colorspace even if its format // is in sRGB colorspace. // // Default - encode data according to the image's format's colorspace // Linear - data will not be encoded into sRGB colorspace enum class SrgbWriteControlMode { Default = 0, Linear = 1 }; // For use with EXT_YUV_target // A sampler of external YUV textures may either implicitly perform RGB conversion (regular // samplerExternalOES) or skip the conversion and sample raw YUV values (__samplerExternal2DY2Y). enum class YuvSamplingMode { Default = 0, Y2Y = 1 }; ShaderType GetShaderTypeFromBitfield(size_t singleShaderType); GLbitfield GetBitfieldFromShaderType(ShaderType shaderType); bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType); // Given a set of shader stages, returns the last vertex processing stage. This is the stage that // interfaces the fragment shader. ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes); } // namespace gl namespace egl { // For use with EGL_EXT_image_gl_colorspace // An EGLImage can be created with attributes that override the color space of underlying image data // when rendering to the image, or sampling from the image. The possible values are - // Default - EGLImage source's colorspace should be preserved // sRGB - EGLImage targets will assume sRGB colorspace // Linear - EGLImage targets will assume linear colorspace enum class ImageColorspace { Default = 0, SRGB, Linear }; static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR; static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR; bool IsCubeMapTextureTarget(EGLenum target); size_t CubeMapTextureTargetToLayerIndex(EGLenum target); EGLenum LayerIndexToCubeMapTextureTarget(size_t index); bool IsTextureTarget(EGLenum target); bool IsRenderbufferTarget(EGLenum target); bool IsExternalImageTarget(EGLenum target); const char *GetGenericErrorMessage(EGLint error); } // namespace egl namespace egl_gl { GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer); } namespace gl_egl { EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType); EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle); } // namespace gl_egl namespace angle { // All state that modify attachment's colorspace struct ColorspaceState { public: ColorspaceState() { reset(); } void reset() { hasStaticTexelFetchAccess = false; srgbDecode = gl::SrgbDecode::Default; srgbOverride = gl::SrgbOverride::Default; srgbWriteControl = gl::SrgbWriteControlMode::Default; eglImageColorspace = egl::ImageColorspace::Default; } // States that affect read operations bool hasStaticTexelFetchAccess; gl::SrgbDecode srgbDecode; gl::SrgbOverride srgbOverride; // States that affect write operations gl::SrgbWriteControlMode srgbWriteControl; // States that affect both read and write operations egl::ImageColorspace eglImageColorspace; }; template constexpr size_t ConstStrLen(T s) { if (s == nullptr) { return 0; } return std::char_traits::length(s); } bool IsDrawEntryPoint(EntryPoint entryPoint); bool IsDispatchEntryPoint(EntryPoint entryPoint); bool IsClearEntryPoint(EntryPoint entryPoint); bool IsQueryEntryPoint(EntryPoint entryPoint); template void FillWithNullptr(T *array) { // std::array::fill(nullptr) yields unoptimized, unrolled loop over array items memset(array->data(), 0, array->size() * sizeof(*array->data())); // sanity check for non-0 nullptr ASSERT(array->data()[0] == nullptr); } } // namespace angle void writeFile(const char *path, std::string_view content); // Get the underlying type. Useful for indexing into arrays with enum values by avoiding the clutter // of the extraneous static_cast<>() calls. // https://stackoverflow.com/a/8357462 template constexpr typename std::underlying_type::type ToUnderlying(E e) noexcept { return static_cast::type>(e); } #endif // COMMON_UTILITIES_H_