From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- gfx/angle/checkout/src/common/CircularBuffer.h | 175 + gfx/angle/checkout/src/common/Color.h | 104 + gfx/angle/checkout/src/common/Color.inc | 69 + gfx/angle/checkout/src/common/FastVector.h | 891 +++++ gfx/angle/checkout/src/common/FixedVector.h | 353 ++ gfx/angle/checkout/src/common/Float16ToFloat32.cpp | 300 ++ gfx/angle/checkout/src/common/MemoryBuffer.cpp | 179 + gfx/angle/checkout/src/common/MemoryBuffer.h | 93 + gfx/angle/checkout/src/common/Optional.h | 74 + .../checkout/src/common/PackedEGLEnums_autogen.cpp | 452 +++ .../checkout/src/common/PackedEGLEnums_autogen.h | 144 + gfx/angle/checkout/src/common/PackedEnums.cpp | 673 ++++ gfx/angle/checkout/src/common/PackedEnums.h | 859 +++++ .../checkout/src/common/PackedGLEnums_autogen.cpp | 2449 ++++++++++++++ .../checkout/src/common/PackedGLEnums_autogen.h | 610 ++++ gfx/angle/checkout/src/common/PoolAlloc.cpp | 487 +++ gfx/angle/checkout/src/common/PoolAlloc.h | 181 + gfx/angle/checkout/src/common/Spinlock.h | 71 + gfx/angle/checkout/src/common/SynchronizedValue.h | 540 +++ gfx/angle/checkout/src/common/aligned_memory.cpp | 64 + gfx/angle/checkout/src/common/aligned_memory.h | 23 + gfx/angle/checkout/src/common/android_util.cpp | 424 +++ gfx/angle/checkout/src/common/android_util.h | 59 + gfx/angle/checkout/src/common/angle_version.h | 28 + .../checkout/src/common/angle_version_info.cpp | 40 + gfx/angle/checkout/src/common/angle_version_info.h | 20 + gfx/angle/checkout/src/common/angleutils.cpp | 156 + gfx/angle/checkout/src/common/angleutils.h | 601 ++++ .../checkout/src/common/apple_platform_utils.h | 90 + gfx/angle/checkout/src/common/bitset_utils.h | 1106 +++++++ gfx/angle/checkout/src/common/debug.cpp | 349 ++ gfx/angle/checkout/src/common/debug.h | 468 +++ .../src/common/entry_points_enum_autogen.cpp | 3454 ++++++++++++++++++++ .../src/common/entry_points_enum_autogen.h | 1736 ++++++++++ gfx/angle/checkout/src/common/event_tracer.cpp | 53 + gfx/angle/checkout/src/common/event_tracer.h | 26 + gfx/angle/checkout/src/common/hash_utils.h | 39 + gfx/angle/checkout/src/common/mathutil.cpp | 83 + gfx/angle/checkout/src/common/mathutil.h | 1482 +++++++++ gfx/angle/checkout/src/common/matrix_utils.cpp | 285 ++ gfx/angle/checkout/src/common/matrix_utils.h | 424 +++ gfx/angle/checkout/src/common/platform.h | 209 ++ gfx/angle/checkout/src/common/spirv/spirv_types.h | 133 + gfx/angle/checkout/src/common/string_utils.cpp | 357 ++ gfx/angle/checkout/src/common/string_utils.h | 125 + gfx/angle/checkout/src/common/system_utils.cpp | 267 ++ gfx/angle/checkout/src/common/system_utils.h | 224 ++ .../checkout/src/common/system_utils_apple.cpp | 59 + .../checkout/src/common/system_utils_linux.cpp | 55 + gfx/angle/checkout/src/common/system_utils_mac.cpp | 28 + .../checkout/src/common/system_utils_posix.cpp | 470 +++ gfx/angle/checkout/src/common/system_utils_win.cpp | 264 ++ .../checkout/src/common/system_utils_win32.cpp | 235 ++ .../third_party/base/anglebase/base_export.h | 13 + .../base/anglebase/containers/mru_cache.h | 275 ++ .../common/third_party/base/anglebase/logging.h | 26 + .../src/common/third_party/base/anglebase/macros.h | 17 + .../third_party/base/anglebase/no_destructor.h | 106 + .../base/anglebase/numerics/checked_math.h | 384 +++ .../base/anglebase/numerics/checked_math_impl.h | 641 ++++ .../base/anglebase/numerics/clamped_math.h | 270 ++ .../base/anglebase/numerics/clamped_math_impl.h | 368 +++ .../base/anglebase/numerics/math_constants.h | 20 + .../third_party/base/anglebase/numerics/ranges.h | 39 + .../base/anglebase/numerics/safe_conversions.h | 403 +++ .../anglebase/numerics/safe_conversions_arm_impl.h | 60 + .../anglebase/numerics/safe_conversions_impl.h | 893 +++++ .../base/anglebase/numerics/safe_math.h | 12 + .../base/anglebase/numerics/safe_math_arm_impl.h | 131 + .../anglebase/numerics/safe_math_clang_gcc_impl.h | 182 ++ .../anglebase/numerics/safe_math_shared_impl.h | 227 ++ .../src/common/third_party/base/anglebase/sha1.cc | 245 ++ .../src/common/third_party/base/anglebase/sha1.h | 36 + .../third_party/base/anglebase/sys_byteorder.h | 49 + .../common/third_party/smhasher/src/PMurHash.cpp | 339 ++ .../src/common/third_party/smhasher/src/PMurHash.h | 57 + .../src/common/third_party/xxhash/xxhash.c | 1030 ++++++ .../src/common/third_party/xxhash/xxhash.h | 341 ++ gfx/angle/checkout/src/common/tls.cpp | 156 + gfx/angle/checkout/src/common/tls.h | 54 + .../src/common/uniform_type_info_autogen.cpp | 378 +++ gfx/angle/checkout/src/common/utilities.cpp | 1509 +++++++++ gfx/angle/checkout/src/common/utilities.h | 336 ++ gfx/angle/checkout/src/common/vector_utils.h | 523 +++ .../src/common/vulkan/libvulkan_loader.cpp | 57 + .../checkout/src/common/vulkan/libvulkan_loader.h | 23 + .../common/vulkan/vk_google_filtering_precision.h | 57 + gfx/angle/checkout/src/common/vulkan/vk_headers.h | 163 + .../checkout/src/common/vulkan/vulkan_icd.cpp | 349 ++ gfx/angle/checkout/src/common/vulkan/vulkan_icd.h | 72 + 90 files changed, 31981 insertions(+) create mode 100644 gfx/angle/checkout/src/common/CircularBuffer.h create mode 100644 gfx/angle/checkout/src/common/Color.h create mode 100644 gfx/angle/checkout/src/common/Color.inc create mode 100644 gfx/angle/checkout/src/common/FastVector.h create mode 100644 gfx/angle/checkout/src/common/FixedVector.h create mode 100644 gfx/angle/checkout/src/common/Float16ToFloat32.cpp create mode 100644 gfx/angle/checkout/src/common/MemoryBuffer.cpp create mode 100644 gfx/angle/checkout/src/common/MemoryBuffer.h create mode 100644 gfx/angle/checkout/src/common/Optional.h create mode 100644 gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp create mode 100644 gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h create mode 100644 gfx/angle/checkout/src/common/PackedEnums.cpp create mode 100644 gfx/angle/checkout/src/common/PackedEnums.h create mode 100644 gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp create mode 100644 gfx/angle/checkout/src/common/PackedGLEnums_autogen.h create mode 100644 gfx/angle/checkout/src/common/PoolAlloc.cpp create mode 100644 gfx/angle/checkout/src/common/PoolAlloc.h create mode 100644 gfx/angle/checkout/src/common/Spinlock.h create mode 100644 gfx/angle/checkout/src/common/SynchronizedValue.h create mode 100644 gfx/angle/checkout/src/common/aligned_memory.cpp create mode 100644 gfx/angle/checkout/src/common/aligned_memory.h create mode 100644 gfx/angle/checkout/src/common/android_util.cpp create mode 100644 gfx/angle/checkout/src/common/android_util.h create mode 100644 gfx/angle/checkout/src/common/angle_version.h create mode 100644 gfx/angle/checkout/src/common/angle_version_info.cpp create mode 100644 gfx/angle/checkout/src/common/angle_version_info.h create mode 100644 gfx/angle/checkout/src/common/angleutils.cpp create mode 100644 gfx/angle/checkout/src/common/angleutils.h create mode 100644 gfx/angle/checkout/src/common/apple_platform_utils.h create mode 100644 gfx/angle/checkout/src/common/bitset_utils.h create mode 100644 gfx/angle/checkout/src/common/debug.cpp create mode 100644 gfx/angle/checkout/src/common/debug.h create mode 100644 gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp create mode 100644 gfx/angle/checkout/src/common/entry_points_enum_autogen.h create mode 100644 gfx/angle/checkout/src/common/event_tracer.cpp create mode 100644 gfx/angle/checkout/src/common/event_tracer.h create mode 100644 gfx/angle/checkout/src/common/hash_utils.h create mode 100644 gfx/angle/checkout/src/common/mathutil.cpp create mode 100644 gfx/angle/checkout/src/common/mathutil.h create mode 100644 gfx/angle/checkout/src/common/matrix_utils.cpp create mode 100644 gfx/angle/checkout/src/common/matrix_utils.h create mode 100644 gfx/angle/checkout/src/common/platform.h create mode 100644 gfx/angle/checkout/src/common/spirv/spirv_types.h create mode 100644 gfx/angle/checkout/src/common/string_utils.cpp create mode 100644 gfx/angle/checkout/src/common/string_utils.h create mode 100644 gfx/angle/checkout/src/common/system_utils.cpp create mode 100644 gfx/angle/checkout/src/common/system_utils.h create mode 100644 gfx/angle/checkout/src/common/system_utils_apple.cpp create mode 100644 gfx/angle/checkout/src/common/system_utils_linux.cpp create mode 100644 gfx/angle/checkout/src/common/system_utils_mac.cpp create mode 100644 gfx/angle/checkout/src/common/system_utils_posix.cpp create mode 100644 gfx/angle/checkout/src/common/system_utils_win.cpp create mode 100644 gfx/angle/checkout/src/common/system_utils_win32.cpp create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math_impl.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math_impl.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/math_constants.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/ranges.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_arm_impl.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_arm_impl.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_clang_gcc_impl.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_shared_impl.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.cc create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.h create mode 100644 gfx/angle/checkout/src/common/third_party/base/anglebase/sys_byteorder.h create mode 100644 gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.cpp create mode 100644 gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.h create mode 100644 gfx/angle/checkout/src/common/third_party/xxhash/xxhash.c create mode 100644 gfx/angle/checkout/src/common/third_party/xxhash/xxhash.h create mode 100644 gfx/angle/checkout/src/common/tls.cpp create mode 100644 gfx/angle/checkout/src/common/tls.h create mode 100644 gfx/angle/checkout/src/common/uniform_type_info_autogen.cpp create mode 100644 gfx/angle/checkout/src/common/utilities.cpp create mode 100644 gfx/angle/checkout/src/common/utilities.h create mode 100644 gfx/angle/checkout/src/common/vector_utils.h create mode 100644 gfx/angle/checkout/src/common/vulkan/libvulkan_loader.cpp create mode 100644 gfx/angle/checkout/src/common/vulkan/libvulkan_loader.h create mode 100644 gfx/angle/checkout/src/common/vulkan/vk_google_filtering_precision.h create mode 100644 gfx/angle/checkout/src/common/vulkan/vk_headers.h create mode 100644 gfx/angle/checkout/src/common/vulkan/vulkan_icd.cpp create mode 100644 gfx/angle/checkout/src/common/vulkan/vulkan_icd.h (limited to 'gfx/angle/checkout/src/common') diff --git a/gfx/angle/checkout/src/common/CircularBuffer.h b/gfx/angle/checkout/src/common/CircularBuffer.h new file mode 100644 index 0000000000..3ff5f14d1b --- /dev/null +++ b/gfx/angle/checkout/src/common/CircularBuffer.h @@ -0,0 +1,175 @@ +// +// Copyright 2021 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. +// +// CircularBuffer.h: +// An array class with an index that loops through the elements. +// + +#ifndef COMMON_CIRCULARBUFFER_H_ +#define COMMON_CIRCULARBUFFER_H_ + +#include "common/debug.h" + +#include +#include + +namespace angle +{ +template > +class CircularBuffer final +{ + public: + using value_type = typename Storage::value_type; + using size_type = typename Storage::size_type; + using reference = typename Storage::reference; + using const_reference = typename Storage::const_reference; + using pointer = typename Storage::pointer; + using const_pointer = typename Storage::const_pointer; + using iterator = typename Storage::iterator; + using const_iterator = typename Storage::const_iterator; + + CircularBuffer(); + CircularBuffer(const value_type &value); + + CircularBuffer(const CircularBuffer &other); + CircularBuffer(CircularBuffer &&other); + + CircularBuffer &operator=(const CircularBuffer &other); + CircularBuffer &operator=(CircularBuffer &&other); + + ~CircularBuffer(); + + // begin() and end() are used to iterate over all elements regardless of the current position of + // the front of the buffer. Useful for initialization and clean up, as otherwise only the front + // element is expected to be accessed. + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + size_type size() const; + + reference front(); + const_reference front() const; + + void swap(CircularBuffer &other); + + // Move the front forward to the next index, looping back to the beginning if the end of the + // array is reached. + void next(); + + private: + Storage mData; + size_type mFrontIndex; +}; + +template +CircularBuffer::CircularBuffer() : mFrontIndex(0) +{} + +template +CircularBuffer::CircularBuffer(const value_type &value) : CircularBuffer() +{ + std::fill(begin(), end(), value); +} + +template +CircularBuffer::CircularBuffer(const CircularBuffer &other) +{ + *this = other; +} + +template +CircularBuffer::CircularBuffer(CircularBuffer &&other) + : CircularBuffer() +{ + swap(other); +} + +template +CircularBuffer &CircularBuffer::operator=( + const CircularBuffer &other) +{ + std::copy(other.begin(), other.end(), begin()); + mFrontIndex = other.mFrontIndex; + return *this; +} + +template +CircularBuffer &CircularBuffer::operator=( + CircularBuffer &&other) +{ + swap(other); + return *this; +} + +template +CircularBuffer::~CircularBuffer() = default; + +template +ANGLE_INLINE typename CircularBuffer::iterator CircularBuffer::begin() +{ + return mData.begin(); +} + +template +ANGLE_INLINE typename CircularBuffer::const_iterator +CircularBuffer::begin() const +{ + return mData.begin(); +} + +template +ANGLE_INLINE typename CircularBuffer::iterator CircularBuffer::end() +{ + return mData.end(); +} + +template +ANGLE_INLINE typename CircularBuffer::const_iterator +CircularBuffer::end() const +{ + return mData.end(); +} + +template +ANGLE_INLINE typename CircularBuffer::size_type CircularBuffer::size() + const +{ + return N; +} + +template +ANGLE_INLINE typename CircularBuffer::reference +CircularBuffer::front() +{ + ASSERT(mFrontIndex < size()); + return mData[mFrontIndex]; +} + +template +ANGLE_INLINE typename CircularBuffer::const_reference +CircularBuffer::front() const +{ + ASSERT(mFrontIndex < size()); + return mData[mFrontIndex]; +} + +template +void CircularBuffer::swap(CircularBuffer &other) +{ + std::swap(mData, other.mData); + std::swap(mFrontIndex, other.mFrontIndex); +} + +template +void CircularBuffer::next() +{ + mFrontIndex = (mFrontIndex + 1) % size(); +} +} // namespace angle + +#endif // COMMON_CIRCULARBUFFER_H_ diff --git a/gfx/angle/checkout/src/common/Color.h b/gfx/angle/checkout/src/common/Color.h new file mode 100644 index 0000000000..b228d8e8c5 --- /dev/null +++ b/gfx/angle/checkout/src/common/Color.h @@ -0,0 +1,104 @@ +// +// Copyright 2016 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. +// + +// Color.h : Defines the Color type used throughout the ANGLE libraries + +#ifndef COMMON_COLOR_H_ +#define COMMON_COLOR_H_ + +#include + +namespace angle +{ + +template +struct Color +{ + Color(); + constexpr Color(T r, T g, T b, T a); + + const T *data() const { return &red; } + T *ptr() { return &red; } + + static Color fromData(const T *data) { return Color(data[0], data[1], data[2], data[3]); } + void writeData(T *data) const + { + data[0] = red; + data[1] = green; + data[2] = blue; + data[3] = alpha; + } + + T red; + T green; + T blue; + T alpha; +}; + +template +bool operator==(const Color &a, const Color &b); + +template +bool operator!=(const Color &a, const Color &b); + +typedef Color ColorF; +typedef Color ColorI; +typedef Color ColorUI; + +struct ColorGeneric +{ + inline ColorGeneric(); + inline ColorGeneric(const ColorF &color); + inline ColorGeneric(const ColorI &color); + inline ColorGeneric(const ColorUI &color); + + enum class Type : uint8_t + { + Float = 0, + Int = 1, + UInt = 2 + }; + + union + { + ColorF colorF; + ColorI colorI; + ColorUI colorUI; + }; + + Type type; +}; + +inline bool operator==(const ColorGeneric &a, const ColorGeneric &b); + +inline bool operator!=(const ColorGeneric &a, const ColorGeneric &b); + +struct DepthStencil +{ + DepthStencil() : depth(0), stencil(0) {} + + // Double is needed to represent the 32-bit integer range of GL_DEPTH_COMPONENT32. + double depth; + uint32_t stencil; +}; +} // namespace angle + +// TODO: Move this fully into the angle namespace +namespace gl +{ + +template +using Color = angle::Color; +using ColorF = angle::ColorF; +using ColorI = angle::ColorI; +using ColorUI = angle::ColorUI; +using ColorGeneric = angle::ColorGeneric; + +} // namespace gl + +#include "Color.inc" + +#endif // COMMON_COLOR_H_ diff --git a/gfx/angle/checkout/src/common/Color.inc b/gfx/angle/checkout/src/common/Color.inc new file mode 100644 index 0000000000..0e1445111b --- /dev/null +++ b/gfx/angle/checkout/src/common/Color.inc @@ -0,0 +1,69 @@ +// +// Copyright 2016 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. +// + +// Color.inc : Inline definitions of some functions from Color.h + +namespace angle +{ + +template +Color::Color() : Color(0, 0, 0, 0) +{ +} + +template +constexpr Color::Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a) +{ +} + +template +bool operator==(const Color &a, const Color &b) +{ + return a.red == b.red && + a.green == b.green && + a.blue == b.blue && + a.alpha == b.alpha; +} + +template +bool operator!=(const Color &a, const Color &b) +{ + return !(a == b); +} + + +ColorGeneric::ColorGeneric() : colorF(), type(Type::Float) {} + +ColorGeneric::ColorGeneric(const ColorF &color) : colorF(color), type(Type::Float) {} + +ColorGeneric::ColorGeneric(const ColorI &color) : colorI(color), type(Type::Int) {} + +ColorGeneric::ColorGeneric(const ColorUI &color) : colorUI(color), type(Type::UInt) {} + +bool operator==(const ColorGeneric &a, const ColorGeneric &b) +{ + if (a.type != b.type) + { + return false; + } + switch (a.type) + { + default: + case ColorGeneric::Type::Float: + return a.colorF == b.colorF; + case ColorGeneric::Type::Int: + return a.colorI == b.colorI; + case ColorGeneric::Type::UInt: + return a.colorUI == b.colorUI; + } +} + +bool operator!=(const ColorGeneric &a, const ColorGeneric &b) +{ + return !(a == b); +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/FastVector.h b/gfx/angle/checkout/src/common/FastVector.h new file mode 100644 index 0000000000..6991adf715 --- /dev/null +++ b/gfx/angle/checkout/src/common/FastVector.h @@ -0,0 +1,891 @@ +// +// Copyright 2018 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. +// +// FastVector.h: +// A vector class with a initial fixed size and variable growth. +// Based on FixedVector. +// + +#ifndef COMMON_FASTVECTOR_H_ +#define COMMON_FASTVECTOR_H_ + +#include "bitset_utils.h" +#include "common/debug.h" + +#include +#include +#include +#include + +namespace angle +{ + +template +class WrapIter +{ + public: + typedef Iter iterator_type; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::iterator_category iterator_category; + + WrapIter() : mIter() {} + WrapIter(const Iter &iter) : mIter(iter) {} + ~WrapIter() = default; + + WrapIter &operator=(const WrapIter &x) + { + mIter = x.mIter; + return *this; + } + + bool operator==(const WrapIter &x) const { return mIter == x.mIter; } + bool operator!=(const WrapIter &x) const { return mIter != x.mIter; } + bool operator<(const WrapIter &x) const { return mIter < x.mIter; } + bool operator<=(const WrapIter &x) const { return mIter <= x.mIter; } + bool operator>(const WrapIter &x) const { return mIter > x.mIter; } + bool operator>=(const WrapIter &x) const { return mIter >= x.mIter; } + + WrapIter &operator++() + { + mIter++; + return *this; + } + + WrapIter operator++(int) + { + WrapIter tmp(mIter); + mIter++; + return tmp; + } + + WrapIter operator+(difference_type n) + { + WrapIter tmp(mIter); + tmp.mIter += n; + return tmp; + } + + WrapIter operator-(difference_type n) + { + WrapIter tmp(mIter); + tmp.mIter -= n; + return tmp; + } + + difference_type operator-(const WrapIter &x) const { return mIter - x.mIter; } + + iterator_type operator->() const { return mIter; } + + reference operator*() const { return *mIter; } + + private: + iterator_type mIter; +}; + +template > +class FastVector final +{ + public: + using value_type = typename Storage::value_type; + using size_type = typename Storage::size_type; + using reference = typename Storage::reference; + using const_reference = typename Storage::const_reference; + using pointer = typename Storage::pointer; + using const_pointer = typename Storage::const_pointer; + using iterator = WrapIter; + using const_iterator = WrapIter; + + FastVector(); + FastVector(size_type count, const value_type &value); + FastVector(size_type count); + + FastVector(const FastVector &other); + FastVector(FastVector &&other); + FastVector(std::initializer_list init); + + template ::value, bool> = true> + FastVector(InputIt first, InputIt last); + + FastVector &operator=(const FastVector &other); + FastVector &operator=(FastVector &&other); + FastVector &operator=(std::initializer_list init); + + ~FastVector(); + + reference at(size_type pos); + const_reference at(size_type pos) const; + + reference operator[](size_type pos); + const_reference operator[](size_type pos) const; + + pointer data(); + const_pointer data() const; + + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + bool empty() const; + size_type size() const; + + void clear(); + + void push_back(const value_type &value); + void push_back(value_type &&value); + + template + void emplace_back(Args &&...args); + + void pop_back(); + + reference front(); + const_reference front() const; + + reference back(); + const_reference back() const; + + void swap(FastVector &other); + + void resize(size_type count); + void resize(size_type count, const value_type &value); + + void reserve(size_type count); + + // Specialty function that removes a known element and might shuffle the list. + void remove_and_permute(const value_type &element); + void remove_and_permute(iterator pos); + + private: + void assign_from_initializer_list(std::initializer_list init); + void ensure_capacity(size_t capacity); + bool uses_fixed_storage() const; + + Storage mFixedStorage; + pointer mData = mFixedStorage.data(); + size_type mSize = 0; + size_type mReservedSize = N; +}; + +template +bool operator==(const FastVector &a, const FastVector &b) +{ + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); +} + +template +bool operator!=(const FastVector &a, const FastVector &b) +{ + return !(a == b); +} + +template +ANGLE_INLINE bool FastVector::uses_fixed_storage() const +{ + return mData == mFixedStorage.data(); +} + +template +FastVector::FastVector() +{} + +template +FastVector::FastVector(size_type count, const value_type &value) +{ + ensure_capacity(count); + mSize = count; + std::fill(begin(), end(), value); +} + +template +FastVector::FastVector(size_type count) +{ + ensure_capacity(count); + mSize = count; +} + +template +FastVector::FastVector(const FastVector &other) + : FastVector(other.begin(), other.end()) +{} + +template +FastVector::FastVector(FastVector &&other) : FastVector() +{ + swap(other); +} + +template +FastVector::FastVector(std::initializer_list init) +{ + assign_from_initializer_list(init); +} + +template +template ::value, bool>> +FastVector::FastVector(InputIt first, InputIt last) +{ + size_t newSize = last - first; + ensure_capacity(newSize); + mSize = newSize; + std::copy(first, last, begin()); +} + +template +FastVector &FastVector::operator=( + const FastVector &other) +{ + ensure_capacity(other.mSize); + mSize = other.mSize; + std::copy(other.begin(), other.end(), begin()); + return *this; +} + +template +FastVector &FastVector::operator=(FastVector &&other) +{ + swap(other); + return *this; +} + +template +FastVector &FastVector::operator=( + std::initializer_list init) +{ + assign_from_initializer_list(init); + return *this; +} + +template +FastVector::~FastVector() +{ + clear(); + if (!uses_fixed_storage()) + { + delete[] mData; + } +} + +template +typename FastVector::reference FastVector::at(size_type pos) +{ + ASSERT(pos < mSize); + return mData[pos]; +} + +template +typename FastVector::const_reference FastVector::at( + size_type pos) const +{ + ASSERT(pos < mSize); + return mData[pos]; +} + +template +ANGLE_INLINE typename FastVector::reference FastVector::operator[]( + size_type pos) +{ + ASSERT(pos < mSize); + return mData[pos]; +} + +template +ANGLE_INLINE typename FastVector::const_reference +FastVector::operator[](size_type pos) const +{ + ASSERT(pos < mSize); + return mData[pos]; +} + +template +ANGLE_INLINE typename FastVector::const_pointer +angle::FastVector::data() const +{ + return mData; +} + +template +ANGLE_INLINE typename FastVector::pointer angle::FastVector::data() +{ + return mData; +} + +template +ANGLE_INLINE typename FastVector::iterator FastVector::begin() +{ + return mData; +} + +template +ANGLE_INLINE typename FastVector::const_iterator FastVector::begin() + const +{ + return mData; +} + +template +ANGLE_INLINE typename FastVector::iterator FastVector::end() +{ + return mData + mSize; +} + +template +ANGLE_INLINE typename FastVector::const_iterator FastVector::end() + const +{ + return mData + mSize; +} + +template +ANGLE_INLINE bool FastVector::empty() const +{ + return mSize == 0; +} + +template +ANGLE_INLINE typename FastVector::size_type FastVector::size() const +{ + return mSize; +} + +template +void FastVector::clear() +{ + resize(0); +} + +template +ANGLE_INLINE void FastVector::push_back(const value_type &value) +{ + if (mSize == mReservedSize) + ensure_capacity(mSize + 1); + mData[mSize++] = value; +} + +template +ANGLE_INLINE void FastVector::push_back(value_type &&value) +{ + emplace_back(std::move(value)); +} + +template +template +ANGLE_INLINE void FastVector::emplace_back(Args &&...args) +{ + if (mSize == mReservedSize) + ensure_capacity(mSize + 1); + mData[mSize++] = std::move(T(std::forward(args)...)); +} + +template +ANGLE_INLINE void FastVector::pop_back() +{ + ASSERT(mSize > 0); + mSize--; +} + +template +ANGLE_INLINE typename FastVector::reference FastVector::front() +{ + ASSERT(mSize > 0); + return mData[0]; +} + +template +ANGLE_INLINE typename FastVector::const_reference FastVector::front() + const +{ + ASSERT(mSize > 0); + return mData[0]; +} + +template +ANGLE_INLINE typename FastVector::reference FastVector::back() +{ + ASSERT(mSize > 0); + return mData[mSize - 1]; +} + +template +ANGLE_INLINE typename FastVector::const_reference FastVector::back() + const +{ + ASSERT(mSize > 0); + return mData[mSize - 1]; +} + +template +void FastVector::swap(FastVector &other) +{ + std::swap(mSize, other.mSize); + + pointer tempData = other.mData; + if (uses_fixed_storage()) + other.mData = other.mFixedStorage.data(); + else + other.mData = mData; + if (tempData == other.mFixedStorage.data()) + mData = mFixedStorage.data(); + else + mData = tempData; + std::swap(mReservedSize, other.mReservedSize); + + if (uses_fixed_storage() || other.uses_fixed_storage()) + std::swap(mFixedStorage, other.mFixedStorage); +} + +template +void FastVector::resize(size_type count) +{ + if (count > mSize) + { + ensure_capacity(count); + } + mSize = count; +} + +template +void FastVector::resize(size_type count, const value_type &value) +{ + if (count > mSize) + { + ensure_capacity(count); + std::fill(mData + mSize, mData + count, value); + } + mSize = count; +} + +template +void FastVector::reserve(size_type count) +{ + ensure_capacity(count); +} + +template +void FastVector::assign_from_initializer_list(std::initializer_list init) +{ + ensure_capacity(init.size()); + mSize = init.size(); + size_t index = 0; + for (auto &value : init) + { + mData[index++] = value; + } +} + +template +ANGLE_INLINE void FastVector::remove_and_permute(const value_type &element) +{ + size_t len = mSize - 1; + for (size_t index = 0; index < len; ++index) + { + if (mData[index] == element) + { + mData[index] = std::move(mData[len]); + break; + } + } + pop_back(); +} + +template +ANGLE_INLINE void FastVector::remove_and_permute(iterator pos) +{ + ASSERT(pos >= begin()); + ASSERT(pos < end()); + size_t len = mSize - 1; + *pos = std::move(mData[len]); + pop_back(); +} + +template +void FastVector::ensure_capacity(size_t capacity) +{ + // We have a minimum capacity of N. + if (mReservedSize < capacity) + { + ASSERT(capacity > N); + size_type newSize = std::max(mReservedSize, N); + while (newSize < capacity) + { + newSize *= 2; + } + + pointer newData = new value_type[newSize]; + + if (mSize > 0) + { + std::move(begin(), end(), newData); + } + + if (!uses_fixed_storage()) + { + delete[] mData; + } + + mData = newData; + mReservedSize = newSize; + } +} + +template +class FastMap final +{ + public: + FastMap() {} + ~FastMap() {} + + Value &operator[](uint32_t key) + { + if (mData.size() <= key) + { + mData.resize(key + 1, {}); + } + return mData[key]; + } + + const Value &operator[](uint32_t key) const + { + ASSERT(key < mData.size()); + return mData[key]; + } + + void clear() { mData.clear(); } + + bool empty() const { return mData.empty(); } + size_t size() const { return mData.size(); } + + const Value *data() const { return mData.data(); } + + bool operator==(const FastMap &other) const + { + return (size() == other.size()) && + (memcmp(data(), other.data(), size() * sizeof(Value)) == 0); + } + + private: + FastVector mData; +}; + +template +class FlatUnorderedMap final +{ + public: + using Pair = std::pair; + using Storage = FastVector; + using iterator = typename Storage::iterator; + using const_iterator = typename Storage::const_iterator; + + FlatUnorderedMap() = default; + ~FlatUnorderedMap() = default; + + iterator begin() { return mData.begin(); } + const_iterator begin() const { return mData.begin(); } + iterator end() { return mData.end(); } + const_iterator end() const { return mData.end(); } + + iterator find(const Key &key) + { + for (auto it = mData.begin(); it != mData.end(); ++it) + { + if (it->first == key) + { + return it; + } + } + return mData.end(); + } + + const_iterator find(const Key &key) const + { + for (auto it = mData.begin(); it != mData.end(); ++it) + { + if (it->first == key) + { + return it; + } + } + return mData.end(); + } + + Value &operator[](const Key &key) + { + iterator it = find(key); + if (it != end()) + { + return it->second; + } + + mData.push_back(Pair(key, {})); + return mData.back().second; + } + + void insert(Pair pair) + { + ASSERT(!contains(pair.first)); + mData.push_back(std::move(pair)); + } + + void insert(const Key &key, Value value) { insert(Pair(key, value)); } + + void erase(iterator pos) { mData.remove_and_permute(pos); } + + bool contains(const Key &key) const { return find(key) != end(); } + + void clear() { mData.clear(); } + + bool get(const Key &key, Value *value) const + { + auto it = find(key); + if (it != end()) + { + *value = it->second; + return true; + } + return false; + } + + bool empty() const { return mData.empty(); } + size_t size() const { return mData.size(); } + + private: + FastVector mData; +}; + +template +class FlatUnorderedSet final +{ + public: + using Storage = FastVector; + using iterator = typename Storage::iterator; + using const_iterator = typename Storage::const_iterator; + + FlatUnorderedSet() = default; + ~FlatUnorderedSet() = default; + + iterator begin() { return mData.begin(); } + const_iterator begin() const { return mData.begin(); } + iterator end() { return mData.end(); } + const_iterator end() const { return mData.end(); } + + iterator find(const T &value) + { + for (auto it = mData.begin(); it != mData.end(); ++it) + { + if (*it == value) + { + return it; + } + } + return mData.end(); + } + + const_iterator find(const T &value) const + { + for (auto it = mData.begin(); it != mData.end(); ++it) + { + if (*it == value) + { + return it; + } + } + return mData.end(); + } + + bool empty() const { return mData.empty(); } + + void insert(const T &value) + { + ASSERT(!contains(value)); + mData.push_back(value); + } + + void erase(const T &value) + { + ASSERT(contains(value)); + mData.remove_and_permute(value); + } + + void remove(const T &value) { erase(value); } + + bool contains(const T &value) const { return find(value) != end(); } + + void clear() { mData.clear(); } + + bool operator==(const FlatUnorderedSet &other) const { return mData == other.mData; } + + private: + Storage mData; +}; + +class FastIntegerSet final +{ + public: + static constexpr size_t kWindowSize = 64; + static constexpr size_t kOneLessThanKWindowSize = kWindowSize - 1; + static constexpr size_t kShiftForDivision = + static_cast(rx::Log2(static_cast(kWindowSize))); + using KeyBitSet = angle::BitSet64; + + ANGLE_INLINE FastIntegerSet(); + ANGLE_INLINE ~FastIntegerSet(); + + ANGLE_INLINE void ensureCapacity(size_t size) + { + if (capacity() <= size) + { + reserve(size * 2); + } + } + + ANGLE_INLINE void insert(uint64_t key) + { + size_t sizedKey = static_cast(key); + + ASSERT(!contains(sizedKey)); + ensureCapacity(sizedKey); + ASSERT(capacity() > sizedKey); + + size_t index = sizedKey >> kShiftForDivision; + size_t offset = sizedKey & kOneLessThanKWindowSize; + + mKeyData[index].set(offset, true); + } + + ANGLE_INLINE bool contains(uint64_t key) const + { + size_t sizedKey = static_cast(key); + + size_t index = sizedKey >> kShiftForDivision; + size_t offset = sizedKey & kOneLessThanKWindowSize; + + return (sizedKey < capacity()) && (mKeyData[index].test(offset)); + } + + ANGLE_INLINE void clear() + { + for (KeyBitSet &it : mKeyData) + { + it.reset(); + } + } + + ANGLE_INLINE bool empty() const + { + for (const KeyBitSet &it : mKeyData) + { + if (it.any()) + { + return false; + } + } + return true; + } + + ANGLE_INLINE size_t size() const + { + size_t valid_entries = 0; + for (const KeyBitSet &it : mKeyData) + { + valid_entries += it.count(); + } + return valid_entries; + } + + private: + ANGLE_INLINE size_t capacity() const { return kWindowSize * mKeyData.size(); } + + ANGLE_INLINE void reserve(size_t newSize) + { + size_t alignedSize = rx::roundUpPow2(newSize, kWindowSize); + size_t count = alignedSize >> kShiftForDivision; + + mKeyData.resize(count, KeyBitSet::Zero()); + } + + std::vector mKeyData; +}; + +// This is needed to accommodate the chromium style guide error - +// [chromium-style] Complex constructor has an inlined body. +ANGLE_INLINE FastIntegerSet::FastIntegerSet() {} +ANGLE_INLINE FastIntegerSet::~FastIntegerSet() {} + +template +class FastIntegerMap final +{ + public: + FastIntegerMap() {} + ~FastIntegerMap() {} + + ANGLE_INLINE void ensureCapacity(size_t size) + { + // Ensure key set has capacity + mKeySet.ensureCapacity(size); + + // Ensure value vector has capacity + ensureCapacityImpl(size); + } + + ANGLE_INLINE void insert(uint64_t key, Value value) + { + // Insert key + ASSERT(!mKeySet.contains(key)); + mKeySet.insert(key); + + // Insert value + size_t sizedKey = static_cast(key); + ensureCapacityImpl(sizedKey); + ASSERT(capacity() > sizedKey); + mValueData[sizedKey] = value; + } + + ANGLE_INLINE bool contains(uint64_t key) const { return mKeySet.contains(key); } + + ANGLE_INLINE bool get(uint64_t key, Value *out) const + { + if (!mKeySet.contains(key)) + { + return false; + } + + size_t sizedKey = static_cast(key); + *out = mValueData[sizedKey]; + return true; + } + + ANGLE_INLINE void clear() { mKeySet.clear(); } + + ANGLE_INLINE bool empty() const { return mKeySet.empty(); } + + ANGLE_INLINE size_t size() const { return mKeySet.size(); } + + private: + ANGLE_INLINE size_t capacity() const { return mValueData.size(); } + + ANGLE_INLINE void ensureCapacityImpl(size_t size) + { + if (capacity() <= size) + { + reserve(size * 2); + } + } + + ANGLE_INLINE void reserve(size_t newSize) + { + size_t alignedSize = rx::roundUpPow2(newSize, FastIntegerSet::kWindowSize); + mValueData.resize(alignedSize); + } + + FastIntegerSet mKeySet; + std::vector mValueData; +}; +} // namespace angle + +#endif // COMMON_FASTVECTOR_H_ diff --git a/gfx/angle/checkout/src/common/FixedVector.h b/gfx/angle/checkout/src/common/FixedVector.h new file mode 100644 index 0000000000..bff87fc969 --- /dev/null +++ b/gfx/angle/checkout/src/common/FixedVector.h @@ -0,0 +1,353 @@ +// +// Copyright 2018 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. +// +// FixedVector.h: +// A vector class with a maximum size and fixed storage. +// + +#ifndef COMMON_FIXEDVECTOR_H_ +#define COMMON_FIXEDVECTOR_H_ + +#include "common/debug.h" + +#include +#include +#include + +namespace angle +{ +template > +class FixedVector final +{ + public: + using value_type = typename Storage::value_type; + using size_type = typename Storage::size_type; + using reference = typename Storage::reference; + using const_reference = typename Storage::const_reference; + using pointer = typename Storage::pointer; + using const_pointer = typename Storage::const_pointer; + using iterator = typename Storage::iterator; + using const_iterator = typename Storage::const_iterator; + using reverse_iterator = typename Storage::reverse_iterator; + using const_reverse_iterator = typename Storage::const_reverse_iterator; + + FixedVector(); + FixedVector(size_type count, const value_type &value); + FixedVector(size_type count); + + FixedVector(const FixedVector &other); + FixedVector(FixedVector &&other); + FixedVector(std::initializer_list init); + + FixedVector &operator=(const FixedVector &other); + FixedVector &operator=(FixedVector &&other); + FixedVector &operator=(std::initializer_list init); + + ~FixedVector(); + + reference at(size_type pos); + const_reference at(size_type pos) const; + + reference operator[](size_type pos); + const_reference operator[](size_type pos) const; + + pointer data(); + const_pointer data() const; + + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + bool empty() const; + size_type size() const; + static constexpr size_type max_size(); + + void clear(); + + void push_back(const value_type &value); + void push_back(value_type &&value); + + template + void emplace_back(Args &&... args); + + void pop_back(); + reference back(); + const_reference back() const; + + void swap(FixedVector &other); + + void resize(size_type count); + void resize(size_type count, const value_type &value); + + bool full() const; + + private: + void assign_from_initializer_list(std::initializer_list init); + + Storage mStorage; + size_type mSize = 0; +}; + +template +bool operator==(const FixedVector &a, const FixedVector &b) +{ + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); +} + +template +bool operator!=(const FixedVector &a, const FixedVector &b) +{ + return !(a == b); +} + +template +FixedVector::FixedVector() = default; + +template +FixedVector::FixedVector(size_type count, const value_type &value) : mSize(count) +{ + ASSERT(count <= N); + std::fill(mStorage.begin(), mStorage.begin() + count, value); +} + +template +FixedVector::FixedVector(size_type count) : mSize(count) +{ + ASSERT(count <= N); +} + +template +FixedVector::FixedVector(const FixedVector &other) = default; + +template +FixedVector::FixedVector(FixedVector &&other) = default; + +template +FixedVector::FixedVector(std::initializer_list init) +{ + ASSERT(init.size() <= N); + assign_from_initializer_list(init); +} + +template +FixedVector &FixedVector::operator=( + const FixedVector &other) = default; + +template +FixedVector &FixedVector::operator=( + FixedVector &&other) = default; + +template +FixedVector &FixedVector::operator=( + std::initializer_list init) +{ + clear(); + ASSERT(init.size() <= N); + assign_from_initializer_list(init); + return this; +} + +template +FixedVector::~FixedVector() +{ + clear(); +} + +template +typename FixedVector::reference FixedVector::at(size_type pos) +{ + ASSERT(pos < N); + return mStorage.at(pos); +} + +template +typename FixedVector::const_reference FixedVector::at( + size_type pos) const +{ + ASSERT(pos < N); + return mStorage.at(pos); +} + +template +typename FixedVector::reference FixedVector::operator[](size_type pos) +{ + ASSERT(pos < N); + return mStorage[pos]; +} + +template +typename FixedVector::const_reference FixedVector::operator[]( + size_type pos) const +{ + ASSERT(pos < N); + return mStorage[pos]; +} + +template +typename FixedVector::const_pointer angle::FixedVector::data() const +{ + return mStorage.data(); +} + +template +typename FixedVector::pointer angle::FixedVector::data() +{ + return mStorage.data(); +} + +template +typename FixedVector::iterator FixedVector::begin() +{ + return mStorage.begin(); +} + +template +typename FixedVector::const_iterator FixedVector::begin() const +{ + return mStorage.begin(); +} + +template +typename FixedVector::iterator FixedVector::end() +{ + return mStorage.begin() + mSize; +} + +template +typename FixedVector::const_iterator FixedVector::end() const +{ + return mStorage.begin() + mSize; +} + +template +bool FixedVector::empty() const +{ + return mSize == 0; +} + +template +typename FixedVector::size_type FixedVector::size() const +{ + return mSize; +} + +template +constexpr typename FixedVector::size_type FixedVector::max_size() +{ + return N; +} + +template +void FixedVector::clear() +{ + resize(0); +} + +template +void FixedVector::push_back(const value_type &value) +{ + ASSERT(mSize < N); + mStorage[mSize] = value; + mSize++; +} + +template +void FixedVector::push_back(value_type &&value) +{ + ASSERT(mSize < N); + mStorage[mSize] = std::move(value); + mSize++; +} + +template +template +void FixedVector::emplace_back(Args &&... args) +{ + ASSERT(mSize < N); + new (&mStorage[mSize]) T{std::forward(args)...}; + mSize++; +} + +template +void FixedVector::pop_back() +{ + ASSERT(mSize > 0); + mSize--; +} + +template +typename FixedVector::reference FixedVector::back() +{ + ASSERT(mSize > 0); + return mStorage[mSize - 1]; +} + +template +typename FixedVector::const_reference FixedVector::back() const +{ + ASSERT(mSize > 0); + return mStorage[mSize - 1]; +} + +template +void FixedVector::swap(FixedVector &other) +{ + std::swap(mSize, other.mSize); + std::swap(mStorage, other.mStorage); +} + +template +void FixedVector::resize(size_type count) +{ + ASSERT(count <= N); + while (mSize > count) + { + mSize--; + mStorage[mSize] = value_type(); + } + while (mSize < count) + { + mStorage[mSize] = value_type(); + mSize++; + } +} + +template +void FixedVector::resize(size_type count, const value_type &value) +{ + ASSERT(count <= N); + while (mSize > count) + { + mSize--; + mStorage[mSize] = value_type(); + } + while (mSize < count) + { + mStorage[mSize] = value; + mSize++; + } +} + +template +void FixedVector::assign_from_initializer_list( + std::initializer_list init) +{ + for (auto element : init) + { + mStorage[mSize] = std::move(element); + mSize++; + } +} + +template +bool FixedVector::full() const +{ + return (mSize == N); +} +} // namespace angle + +#endif // COMMON_FIXEDVECTOR_H_ diff --git a/gfx/angle/checkout/src/common/Float16ToFloat32.cpp b/gfx/angle/checkout/src/common/Float16ToFloat32.cpp new file mode 100644 index 0000000000..f9dfe23307 --- /dev/null +++ b/gfx/angle/checkout/src/common/Float16ToFloat32.cpp @@ -0,0 +1,300 @@ +// +// Copyright 2012 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. +// + +// This file is automatically generated. + +#include "common/mathutil.h" + +namespace gl +{ + +const static unsigned g_mantissa[2048] = { + 0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34a00000, 0x34c00000, 0x34e00000, + 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000, + 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35a00000, 0x35a80000, 0x35b00000, 0x35b80000, + 0x35c00000, 0x35c80000, 0x35d00000, 0x35d80000, 0x35e00000, 0x35e80000, 0x35f00000, 0x35f80000, + 0x36000000, 0x36040000, 0x36080000, 0x360c0000, 0x36100000, 0x36140000, 0x36180000, 0x361c0000, + 0x36200000, 0x36240000, 0x36280000, 0x362c0000, 0x36300000, 0x36340000, 0x36380000, 0x363c0000, + 0x36400000, 0x36440000, 0x36480000, 0x364c0000, 0x36500000, 0x36540000, 0x36580000, 0x365c0000, + 0x36600000, 0x36640000, 0x36680000, 0x366c0000, 0x36700000, 0x36740000, 0x36780000, 0x367c0000, + 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368a0000, 0x368c0000, 0x368e0000, + 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369a0000, 0x369c0000, 0x369e0000, + 0x36a00000, 0x36a20000, 0x36a40000, 0x36a60000, 0x36a80000, 0x36aa0000, 0x36ac0000, 0x36ae0000, + 0x36b00000, 0x36b20000, 0x36b40000, 0x36b60000, 0x36b80000, 0x36ba0000, 0x36bc0000, 0x36be0000, + 0x36c00000, 0x36c20000, 0x36c40000, 0x36c60000, 0x36c80000, 0x36ca0000, 0x36cc0000, 0x36ce0000, + 0x36d00000, 0x36d20000, 0x36d40000, 0x36d60000, 0x36d80000, 0x36da0000, 0x36dc0000, 0x36de0000, + 0x36e00000, 0x36e20000, 0x36e40000, 0x36e60000, 0x36e80000, 0x36ea0000, 0x36ec0000, 0x36ee0000, + 0x36f00000, 0x36f20000, 0x36f40000, 0x36f60000, 0x36f80000, 0x36fa0000, 0x36fc0000, 0x36fe0000, + 0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, + 0x37080000, 0x37090000, 0x370a0000, 0x370b0000, 0x370c0000, 0x370d0000, 0x370e0000, 0x370f0000, + 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, + 0x37180000, 0x37190000, 0x371a0000, 0x371b0000, 0x371c0000, 0x371d0000, 0x371e0000, 0x371f0000, + 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, + 0x37280000, 0x37290000, 0x372a0000, 0x372b0000, 0x372c0000, 0x372d0000, 0x372e0000, 0x372f0000, + 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, + 0x37380000, 0x37390000, 0x373a0000, 0x373b0000, 0x373c0000, 0x373d0000, 0x373e0000, 0x373f0000, + 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, + 0x37480000, 0x37490000, 0x374a0000, 0x374b0000, 0x374c0000, 0x374d0000, 0x374e0000, 0x374f0000, + 0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, + 0x37580000, 0x37590000, 0x375a0000, 0x375b0000, 0x375c0000, 0x375d0000, 0x375e0000, 0x375f0000, + 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, + 0x37680000, 0x37690000, 0x376a0000, 0x376b0000, 0x376c0000, 0x376d0000, 0x376e0000, 0x376f0000, + 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, + 0x37780000, 0x37790000, 0x377a0000, 0x377b0000, 0x377c0000, 0x377d0000, 0x377e0000, 0x377f0000, + 0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, + 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000, + 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378a0000, 0x378a8000, 0x378b0000, 0x378b8000, + 0x378c0000, 0x378c8000, 0x378d0000, 0x378d8000, 0x378e0000, 0x378e8000, 0x378f0000, 0x378f8000, + 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, + 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000, + 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379a0000, 0x379a8000, 0x379b0000, 0x379b8000, + 0x379c0000, 0x379c8000, 0x379d0000, 0x379d8000, 0x379e0000, 0x379e8000, 0x379f0000, 0x379f8000, + 0x37a00000, 0x37a08000, 0x37a10000, 0x37a18000, 0x37a20000, 0x37a28000, 0x37a30000, 0x37a38000, + 0x37a40000, 0x37a48000, 0x37a50000, 0x37a58000, 0x37a60000, 0x37a68000, 0x37a70000, 0x37a78000, + 0x37a80000, 0x37a88000, 0x37a90000, 0x37a98000, 0x37aa0000, 0x37aa8000, 0x37ab0000, 0x37ab8000, + 0x37ac0000, 0x37ac8000, 0x37ad0000, 0x37ad8000, 0x37ae0000, 0x37ae8000, 0x37af0000, 0x37af8000, + 0x37b00000, 0x37b08000, 0x37b10000, 0x37b18000, 0x37b20000, 0x37b28000, 0x37b30000, 0x37b38000, + 0x37b40000, 0x37b48000, 0x37b50000, 0x37b58000, 0x37b60000, 0x37b68000, 0x37b70000, 0x37b78000, + 0x37b80000, 0x37b88000, 0x37b90000, 0x37b98000, 0x37ba0000, 0x37ba8000, 0x37bb0000, 0x37bb8000, + 0x37bc0000, 0x37bc8000, 0x37bd0000, 0x37bd8000, 0x37be0000, 0x37be8000, 0x37bf0000, 0x37bf8000, + 0x37c00000, 0x37c08000, 0x37c10000, 0x37c18000, 0x37c20000, 0x37c28000, 0x37c30000, 0x37c38000, + 0x37c40000, 0x37c48000, 0x37c50000, 0x37c58000, 0x37c60000, 0x37c68000, 0x37c70000, 0x37c78000, + 0x37c80000, 0x37c88000, 0x37c90000, 0x37c98000, 0x37ca0000, 0x37ca8000, 0x37cb0000, 0x37cb8000, + 0x37cc0000, 0x37cc8000, 0x37cd0000, 0x37cd8000, 0x37ce0000, 0x37ce8000, 0x37cf0000, 0x37cf8000, + 0x37d00000, 0x37d08000, 0x37d10000, 0x37d18000, 0x37d20000, 0x37d28000, 0x37d30000, 0x37d38000, + 0x37d40000, 0x37d48000, 0x37d50000, 0x37d58000, 0x37d60000, 0x37d68000, 0x37d70000, 0x37d78000, + 0x37d80000, 0x37d88000, 0x37d90000, 0x37d98000, 0x37da0000, 0x37da8000, 0x37db0000, 0x37db8000, + 0x37dc0000, 0x37dc8000, 0x37dd0000, 0x37dd8000, 0x37de0000, 0x37de8000, 0x37df0000, 0x37df8000, + 0x37e00000, 0x37e08000, 0x37e10000, 0x37e18000, 0x37e20000, 0x37e28000, 0x37e30000, 0x37e38000, + 0x37e40000, 0x37e48000, 0x37e50000, 0x37e58000, 0x37e60000, 0x37e68000, 0x37e70000, 0x37e78000, + 0x37e80000, 0x37e88000, 0x37e90000, 0x37e98000, 0x37ea0000, 0x37ea8000, 0x37eb0000, 0x37eb8000, + 0x37ec0000, 0x37ec8000, 0x37ed0000, 0x37ed8000, 0x37ee0000, 0x37ee8000, 0x37ef0000, 0x37ef8000, + 0x37f00000, 0x37f08000, 0x37f10000, 0x37f18000, 0x37f20000, 0x37f28000, 0x37f30000, 0x37f38000, + 0x37f40000, 0x37f48000, 0x37f50000, 0x37f58000, 0x37f60000, 0x37f68000, 0x37f70000, 0x37f78000, + 0x37f80000, 0x37f88000, 0x37f90000, 0x37f98000, 0x37fa0000, 0x37fa8000, 0x37fb0000, 0x37fb8000, + 0x37fc0000, 0x37fc8000, 0x37fd0000, 0x37fd8000, 0x37fe0000, 0x37fe8000, 0x37ff0000, 0x37ff8000, + 0x38000000, 0x38004000, 0x38008000, 0x3800c000, 0x38010000, 0x38014000, 0x38018000, 0x3801c000, + 0x38020000, 0x38024000, 0x38028000, 0x3802c000, 0x38030000, 0x38034000, 0x38038000, 0x3803c000, + 0x38040000, 0x38044000, 0x38048000, 0x3804c000, 0x38050000, 0x38054000, 0x38058000, 0x3805c000, + 0x38060000, 0x38064000, 0x38068000, 0x3806c000, 0x38070000, 0x38074000, 0x38078000, 0x3807c000, + 0x38080000, 0x38084000, 0x38088000, 0x3808c000, 0x38090000, 0x38094000, 0x38098000, 0x3809c000, + 0x380a0000, 0x380a4000, 0x380a8000, 0x380ac000, 0x380b0000, 0x380b4000, 0x380b8000, 0x380bc000, + 0x380c0000, 0x380c4000, 0x380c8000, 0x380cc000, 0x380d0000, 0x380d4000, 0x380d8000, 0x380dc000, + 0x380e0000, 0x380e4000, 0x380e8000, 0x380ec000, 0x380f0000, 0x380f4000, 0x380f8000, 0x380fc000, + 0x38100000, 0x38104000, 0x38108000, 0x3810c000, 0x38110000, 0x38114000, 0x38118000, 0x3811c000, + 0x38120000, 0x38124000, 0x38128000, 0x3812c000, 0x38130000, 0x38134000, 0x38138000, 0x3813c000, + 0x38140000, 0x38144000, 0x38148000, 0x3814c000, 0x38150000, 0x38154000, 0x38158000, 0x3815c000, + 0x38160000, 0x38164000, 0x38168000, 0x3816c000, 0x38170000, 0x38174000, 0x38178000, 0x3817c000, + 0x38180000, 0x38184000, 0x38188000, 0x3818c000, 0x38190000, 0x38194000, 0x38198000, 0x3819c000, + 0x381a0000, 0x381a4000, 0x381a8000, 0x381ac000, 0x381b0000, 0x381b4000, 0x381b8000, 0x381bc000, + 0x381c0000, 0x381c4000, 0x381c8000, 0x381cc000, 0x381d0000, 0x381d4000, 0x381d8000, 0x381dc000, + 0x381e0000, 0x381e4000, 0x381e8000, 0x381ec000, 0x381f0000, 0x381f4000, 0x381f8000, 0x381fc000, + 0x38200000, 0x38204000, 0x38208000, 0x3820c000, 0x38210000, 0x38214000, 0x38218000, 0x3821c000, + 0x38220000, 0x38224000, 0x38228000, 0x3822c000, 0x38230000, 0x38234000, 0x38238000, 0x3823c000, + 0x38240000, 0x38244000, 0x38248000, 0x3824c000, 0x38250000, 0x38254000, 0x38258000, 0x3825c000, + 0x38260000, 0x38264000, 0x38268000, 0x3826c000, 0x38270000, 0x38274000, 0x38278000, 0x3827c000, + 0x38280000, 0x38284000, 0x38288000, 0x3828c000, 0x38290000, 0x38294000, 0x38298000, 0x3829c000, + 0x382a0000, 0x382a4000, 0x382a8000, 0x382ac000, 0x382b0000, 0x382b4000, 0x382b8000, 0x382bc000, + 0x382c0000, 0x382c4000, 0x382c8000, 0x382cc000, 0x382d0000, 0x382d4000, 0x382d8000, 0x382dc000, + 0x382e0000, 0x382e4000, 0x382e8000, 0x382ec000, 0x382f0000, 0x382f4000, 0x382f8000, 0x382fc000, + 0x38300000, 0x38304000, 0x38308000, 0x3830c000, 0x38310000, 0x38314000, 0x38318000, 0x3831c000, + 0x38320000, 0x38324000, 0x38328000, 0x3832c000, 0x38330000, 0x38334000, 0x38338000, 0x3833c000, + 0x38340000, 0x38344000, 0x38348000, 0x3834c000, 0x38350000, 0x38354000, 0x38358000, 0x3835c000, + 0x38360000, 0x38364000, 0x38368000, 0x3836c000, 0x38370000, 0x38374000, 0x38378000, 0x3837c000, + 0x38380000, 0x38384000, 0x38388000, 0x3838c000, 0x38390000, 0x38394000, 0x38398000, 0x3839c000, + 0x383a0000, 0x383a4000, 0x383a8000, 0x383ac000, 0x383b0000, 0x383b4000, 0x383b8000, 0x383bc000, + 0x383c0000, 0x383c4000, 0x383c8000, 0x383cc000, 0x383d0000, 0x383d4000, 0x383d8000, 0x383dc000, + 0x383e0000, 0x383e4000, 0x383e8000, 0x383ec000, 0x383f0000, 0x383f4000, 0x383f8000, 0x383fc000, + 0x38400000, 0x38404000, 0x38408000, 0x3840c000, 0x38410000, 0x38414000, 0x38418000, 0x3841c000, + 0x38420000, 0x38424000, 0x38428000, 0x3842c000, 0x38430000, 0x38434000, 0x38438000, 0x3843c000, + 0x38440000, 0x38444000, 0x38448000, 0x3844c000, 0x38450000, 0x38454000, 0x38458000, 0x3845c000, + 0x38460000, 0x38464000, 0x38468000, 0x3846c000, 0x38470000, 0x38474000, 0x38478000, 0x3847c000, + 0x38480000, 0x38484000, 0x38488000, 0x3848c000, 0x38490000, 0x38494000, 0x38498000, 0x3849c000, + 0x384a0000, 0x384a4000, 0x384a8000, 0x384ac000, 0x384b0000, 0x384b4000, 0x384b8000, 0x384bc000, + 0x384c0000, 0x384c4000, 0x384c8000, 0x384cc000, 0x384d0000, 0x384d4000, 0x384d8000, 0x384dc000, + 0x384e0000, 0x384e4000, 0x384e8000, 0x384ec000, 0x384f0000, 0x384f4000, 0x384f8000, 0x384fc000, + 0x38500000, 0x38504000, 0x38508000, 0x3850c000, 0x38510000, 0x38514000, 0x38518000, 0x3851c000, + 0x38520000, 0x38524000, 0x38528000, 0x3852c000, 0x38530000, 0x38534000, 0x38538000, 0x3853c000, + 0x38540000, 0x38544000, 0x38548000, 0x3854c000, 0x38550000, 0x38554000, 0x38558000, 0x3855c000, + 0x38560000, 0x38564000, 0x38568000, 0x3856c000, 0x38570000, 0x38574000, 0x38578000, 0x3857c000, + 0x38580000, 0x38584000, 0x38588000, 0x3858c000, 0x38590000, 0x38594000, 0x38598000, 0x3859c000, + 0x385a0000, 0x385a4000, 0x385a8000, 0x385ac000, 0x385b0000, 0x385b4000, 0x385b8000, 0x385bc000, + 0x385c0000, 0x385c4000, 0x385c8000, 0x385cc000, 0x385d0000, 0x385d4000, 0x385d8000, 0x385dc000, + 0x385e0000, 0x385e4000, 0x385e8000, 0x385ec000, 0x385f0000, 0x385f4000, 0x385f8000, 0x385fc000, + 0x38600000, 0x38604000, 0x38608000, 0x3860c000, 0x38610000, 0x38614000, 0x38618000, 0x3861c000, + 0x38620000, 0x38624000, 0x38628000, 0x3862c000, 0x38630000, 0x38634000, 0x38638000, 0x3863c000, + 0x38640000, 0x38644000, 0x38648000, 0x3864c000, 0x38650000, 0x38654000, 0x38658000, 0x3865c000, + 0x38660000, 0x38664000, 0x38668000, 0x3866c000, 0x38670000, 0x38674000, 0x38678000, 0x3867c000, + 0x38680000, 0x38684000, 0x38688000, 0x3868c000, 0x38690000, 0x38694000, 0x38698000, 0x3869c000, + 0x386a0000, 0x386a4000, 0x386a8000, 0x386ac000, 0x386b0000, 0x386b4000, 0x386b8000, 0x386bc000, + 0x386c0000, 0x386c4000, 0x386c8000, 0x386cc000, 0x386d0000, 0x386d4000, 0x386d8000, 0x386dc000, + 0x386e0000, 0x386e4000, 0x386e8000, 0x386ec000, 0x386f0000, 0x386f4000, 0x386f8000, 0x386fc000, + 0x38700000, 0x38704000, 0x38708000, 0x3870c000, 0x38710000, 0x38714000, 0x38718000, 0x3871c000, + 0x38720000, 0x38724000, 0x38728000, 0x3872c000, 0x38730000, 0x38734000, 0x38738000, 0x3873c000, + 0x38740000, 0x38744000, 0x38748000, 0x3874c000, 0x38750000, 0x38754000, 0x38758000, 0x3875c000, + 0x38760000, 0x38764000, 0x38768000, 0x3876c000, 0x38770000, 0x38774000, 0x38778000, 0x3877c000, + 0x38780000, 0x38784000, 0x38788000, 0x3878c000, 0x38790000, 0x38794000, 0x38798000, 0x3879c000, + 0x387a0000, 0x387a4000, 0x387a8000, 0x387ac000, 0x387b0000, 0x387b4000, 0x387b8000, 0x387bc000, + 0x387c0000, 0x387c4000, 0x387c8000, 0x387cc000, 0x387d0000, 0x387d4000, 0x387d8000, 0x387dc000, + 0x387e0000, 0x387e4000, 0x387e8000, 0x387ec000, 0x387f0000, 0x387f4000, 0x387f8000, 0x387fc000, + 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800a000, 0x3800c000, 0x3800e000, + 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801a000, 0x3801c000, 0x3801e000, + 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802a000, 0x3802c000, 0x3802e000, + 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803a000, 0x3803c000, 0x3803e000, + 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804a000, 0x3804c000, 0x3804e000, + 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805a000, 0x3805c000, 0x3805e000, + 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806a000, 0x3806c000, 0x3806e000, + 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807a000, 0x3807c000, 0x3807e000, + 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808a000, 0x3808c000, 0x3808e000, + 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809a000, 0x3809c000, 0x3809e000, + 0x380a0000, 0x380a2000, 0x380a4000, 0x380a6000, 0x380a8000, 0x380aa000, 0x380ac000, 0x380ae000, + 0x380b0000, 0x380b2000, 0x380b4000, 0x380b6000, 0x380b8000, 0x380ba000, 0x380bc000, 0x380be000, + 0x380c0000, 0x380c2000, 0x380c4000, 0x380c6000, 0x380c8000, 0x380ca000, 0x380cc000, 0x380ce000, + 0x380d0000, 0x380d2000, 0x380d4000, 0x380d6000, 0x380d8000, 0x380da000, 0x380dc000, 0x380de000, + 0x380e0000, 0x380e2000, 0x380e4000, 0x380e6000, 0x380e8000, 0x380ea000, 0x380ec000, 0x380ee000, + 0x380f0000, 0x380f2000, 0x380f4000, 0x380f6000, 0x380f8000, 0x380fa000, 0x380fc000, 0x380fe000, + 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810a000, 0x3810c000, 0x3810e000, + 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811a000, 0x3811c000, 0x3811e000, + 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812a000, 0x3812c000, 0x3812e000, + 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813a000, 0x3813c000, 0x3813e000, + 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814a000, 0x3814c000, 0x3814e000, + 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815a000, 0x3815c000, 0x3815e000, + 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816a000, 0x3816c000, 0x3816e000, + 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817a000, 0x3817c000, 0x3817e000, + 0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818a000, 0x3818c000, 0x3818e000, + 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819a000, 0x3819c000, 0x3819e000, + 0x381a0000, 0x381a2000, 0x381a4000, 0x381a6000, 0x381a8000, 0x381aa000, 0x381ac000, 0x381ae000, + 0x381b0000, 0x381b2000, 0x381b4000, 0x381b6000, 0x381b8000, 0x381ba000, 0x381bc000, 0x381be000, + 0x381c0000, 0x381c2000, 0x381c4000, 0x381c6000, 0x381c8000, 0x381ca000, 0x381cc000, 0x381ce000, + 0x381d0000, 0x381d2000, 0x381d4000, 0x381d6000, 0x381d8000, 0x381da000, 0x381dc000, 0x381de000, + 0x381e0000, 0x381e2000, 0x381e4000, 0x381e6000, 0x381e8000, 0x381ea000, 0x381ec000, 0x381ee000, + 0x381f0000, 0x381f2000, 0x381f4000, 0x381f6000, 0x381f8000, 0x381fa000, 0x381fc000, 0x381fe000, + 0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820a000, 0x3820c000, 0x3820e000, + 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821a000, 0x3821c000, 0x3821e000, + 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822a000, 0x3822c000, 0x3822e000, + 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823a000, 0x3823c000, 0x3823e000, + 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824a000, 0x3824c000, 0x3824e000, + 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825a000, 0x3825c000, 0x3825e000, + 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826a000, 0x3826c000, 0x3826e000, + 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827a000, 0x3827c000, 0x3827e000, + 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828a000, 0x3828c000, 0x3828e000, + 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829a000, 0x3829c000, 0x3829e000, + 0x382a0000, 0x382a2000, 0x382a4000, 0x382a6000, 0x382a8000, 0x382aa000, 0x382ac000, 0x382ae000, + 0x382b0000, 0x382b2000, 0x382b4000, 0x382b6000, 0x382b8000, 0x382ba000, 0x382bc000, 0x382be000, + 0x382c0000, 0x382c2000, 0x382c4000, 0x382c6000, 0x382c8000, 0x382ca000, 0x382cc000, 0x382ce000, + 0x382d0000, 0x382d2000, 0x382d4000, 0x382d6000, 0x382d8000, 0x382da000, 0x382dc000, 0x382de000, + 0x382e0000, 0x382e2000, 0x382e4000, 0x382e6000, 0x382e8000, 0x382ea000, 0x382ec000, 0x382ee000, + 0x382f0000, 0x382f2000, 0x382f4000, 0x382f6000, 0x382f8000, 0x382fa000, 0x382fc000, 0x382fe000, + 0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830a000, 0x3830c000, 0x3830e000, + 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831a000, 0x3831c000, 0x3831e000, + 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832a000, 0x3832c000, 0x3832e000, + 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833a000, 0x3833c000, 0x3833e000, + 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834a000, 0x3834c000, 0x3834e000, + 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835a000, 0x3835c000, 0x3835e000, + 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836a000, 0x3836c000, 0x3836e000, + 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837a000, 0x3837c000, 0x3837e000, + 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838a000, 0x3838c000, 0x3838e000, + 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839a000, 0x3839c000, 0x3839e000, + 0x383a0000, 0x383a2000, 0x383a4000, 0x383a6000, 0x383a8000, 0x383aa000, 0x383ac000, 0x383ae000, + 0x383b0000, 0x383b2000, 0x383b4000, 0x383b6000, 0x383b8000, 0x383ba000, 0x383bc000, 0x383be000, + 0x383c0000, 0x383c2000, 0x383c4000, 0x383c6000, 0x383c8000, 0x383ca000, 0x383cc000, 0x383ce000, + 0x383d0000, 0x383d2000, 0x383d4000, 0x383d6000, 0x383d8000, 0x383da000, 0x383dc000, 0x383de000, + 0x383e0000, 0x383e2000, 0x383e4000, 0x383e6000, 0x383e8000, 0x383ea000, 0x383ec000, 0x383ee000, + 0x383f0000, 0x383f2000, 0x383f4000, 0x383f6000, 0x383f8000, 0x383fa000, 0x383fc000, 0x383fe000, + 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840a000, 0x3840c000, 0x3840e000, + 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841a000, 0x3841c000, 0x3841e000, + 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842a000, 0x3842c000, 0x3842e000, + 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843a000, 0x3843c000, 0x3843e000, + 0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844a000, 0x3844c000, 0x3844e000, + 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845a000, 0x3845c000, 0x3845e000, + 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846a000, 0x3846c000, 0x3846e000, + 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847a000, 0x3847c000, 0x3847e000, + 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848a000, 0x3848c000, 0x3848e000, + 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849a000, 0x3849c000, 0x3849e000, + 0x384a0000, 0x384a2000, 0x384a4000, 0x384a6000, 0x384a8000, 0x384aa000, 0x384ac000, 0x384ae000, + 0x384b0000, 0x384b2000, 0x384b4000, 0x384b6000, 0x384b8000, 0x384ba000, 0x384bc000, 0x384be000, + 0x384c0000, 0x384c2000, 0x384c4000, 0x384c6000, 0x384c8000, 0x384ca000, 0x384cc000, 0x384ce000, + 0x384d0000, 0x384d2000, 0x384d4000, 0x384d6000, 0x384d8000, 0x384da000, 0x384dc000, 0x384de000, + 0x384e0000, 0x384e2000, 0x384e4000, 0x384e6000, 0x384e8000, 0x384ea000, 0x384ec000, 0x384ee000, + 0x384f0000, 0x384f2000, 0x384f4000, 0x384f6000, 0x384f8000, 0x384fa000, 0x384fc000, 0x384fe000, + 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850a000, 0x3850c000, 0x3850e000, + 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851a000, 0x3851c000, 0x3851e000, + 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852a000, 0x3852c000, 0x3852e000, + 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853a000, 0x3853c000, 0x3853e000, + 0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854a000, 0x3854c000, 0x3854e000, + 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855a000, 0x3855c000, 0x3855e000, + 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856a000, 0x3856c000, 0x3856e000, + 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857a000, 0x3857c000, 0x3857e000, + 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858a000, 0x3858c000, 0x3858e000, + 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859a000, 0x3859c000, 0x3859e000, + 0x385a0000, 0x385a2000, 0x385a4000, 0x385a6000, 0x385a8000, 0x385aa000, 0x385ac000, 0x385ae000, + 0x385b0000, 0x385b2000, 0x385b4000, 0x385b6000, 0x385b8000, 0x385ba000, 0x385bc000, 0x385be000, + 0x385c0000, 0x385c2000, 0x385c4000, 0x385c6000, 0x385c8000, 0x385ca000, 0x385cc000, 0x385ce000, + 0x385d0000, 0x385d2000, 0x385d4000, 0x385d6000, 0x385d8000, 0x385da000, 0x385dc000, 0x385de000, + 0x385e0000, 0x385e2000, 0x385e4000, 0x385e6000, 0x385e8000, 0x385ea000, 0x385ec000, 0x385ee000, + 0x385f0000, 0x385f2000, 0x385f4000, 0x385f6000, 0x385f8000, 0x385fa000, 0x385fc000, 0x385fe000, + 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860a000, 0x3860c000, 0x3860e000, + 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861a000, 0x3861c000, 0x3861e000, + 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862a000, 0x3862c000, 0x3862e000, + 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863a000, 0x3863c000, 0x3863e000, + 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864a000, 0x3864c000, 0x3864e000, + 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865a000, 0x3865c000, 0x3865e000, + 0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866a000, 0x3866c000, 0x3866e000, + 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867a000, 0x3867c000, 0x3867e000, + 0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868a000, 0x3868c000, 0x3868e000, + 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869a000, 0x3869c000, 0x3869e000, + 0x386a0000, 0x386a2000, 0x386a4000, 0x386a6000, 0x386a8000, 0x386aa000, 0x386ac000, 0x386ae000, + 0x386b0000, 0x386b2000, 0x386b4000, 0x386b6000, 0x386b8000, 0x386ba000, 0x386bc000, 0x386be000, + 0x386c0000, 0x386c2000, 0x386c4000, 0x386c6000, 0x386c8000, 0x386ca000, 0x386cc000, 0x386ce000, + 0x386d0000, 0x386d2000, 0x386d4000, 0x386d6000, 0x386d8000, 0x386da000, 0x386dc000, 0x386de000, + 0x386e0000, 0x386e2000, 0x386e4000, 0x386e6000, 0x386e8000, 0x386ea000, 0x386ec000, 0x386ee000, + 0x386f0000, 0x386f2000, 0x386f4000, 0x386f6000, 0x386f8000, 0x386fa000, 0x386fc000, 0x386fe000, + 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870a000, 0x3870c000, 0x3870e000, + 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871a000, 0x3871c000, 0x3871e000, + 0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872a000, 0x3872c000, 0x3872e000, + 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873a000, 0x3873c000, 0x3873e000, + 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874a000, 0x3874c000, 0x3874e000, + 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875a000, 0x3875c000, 0x3875e000, + 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876a000, 0x3876c000, 0x3876e000, + 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877a000, 0x3877c000, 0x3877e000, + 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878a000, 0x3878c000, 0x3878e000, + 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879a000, 0x3879c000, 0x3879e000, + 0x387a0000, 0x387a2000, 0x387a4000, 0x387a6000, 0x387a8000, 0x387aa000, 0x387ac000, 0x387ae000, + 0x387b0000, 0x387b2000, 0x387b4000, 0x387b6000, 0x387b8000, 0x387ba000, 0x387bc000, 0x387be000, + 0x387c0000, 0x387c2000, 0x387c4000, 0x387c6000, 0x387c8000, 0x387ca000, 0x387cc000, 0x387ce000, + 0x387d0000, 0x387d2000, 0x387d4000, 0x387d6000, 0x387d8000, 0x387da000, 0x387dc000, 0x387de000, + 0x387e0000, 0x387e2000, 0x387e4000, 0x387e6000, 0x387e8000, 0x387ea000, 0x387ec000, 0x387ee000, + 0x387f0000, 0x387f2000, 0x387f4000, 0x387f6000, 0x387f8000, 0x387fa000, 0x387fc000, 0x387fe000, +}; + +const static unsigned g_exponent[64] = { + 0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, + 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000, + 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0a000000, 0x0a800000, 0x0b000000, 0x0b800000, + 0x0c000000, 0x0c800000, 0x0d000000, 0x0d800000, 0x0e000000, 0x0e800000, 0x0f000000, 0x47800000, + 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, + 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000, + 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8a000000, 0x8a800000, 0x8b000000, 0x8b800000, + 0x8c000000, 0x8c800000, 0x8d000000, 0x8d800000, 0x8e000000, 0x8e800000, 0x8f000000, 0xc7800000, +}; + +const static unsigned g_offset[64] = { + 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, +}; + +float float16ToFloat32(unsigned short h) +{ + unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10]; + return bitCast(i32); +} +} // namespace gl diff --git a/gfx/angle/checkout/src/common/MemoryBuffer.cpp b/gfx/angle/checkout/src/common/MemoryBuffer.cpp new file mode 100644 index 0000000000..aadffe8bbe --- /dev/null +++ b/gfx/angle/checkout/src/common/MemoryBuffer.cpp @@ -0,0 +1,179 @@ +// +// Copyright 2014 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. +// + +#include "common/MemoryBuffer.h" + +#include +#include + +#include "common/debug.h" + +namespace angle +{ + +// MemoryBuffer implementation. +MemoryBuffer::~MemoryBuffer() +{ + if (mData) + { + free(mData); + mData = nullptr; + } +} + +bool MemoryBuffer::resize(size_t size) +{ + if (size == 0) + { + if (mData) + { + free(mData); + mData = nullptr; + } + mSize = 0; + return true; + } + + if (size == mSize) + { + return true; + } + + // Only reallocate if the size has changed. + uint8_t *newMemory = static_cast(malloc(sizeof(uint8_t) * size)); + if (newMemory == nullptr) + { + return false; + } + + if (mData) + { + // Copy the intersection of the old data and the new data + std::copy(mData, mData + std::min(mSize, size), newMemory); + free(mData); + } + + mData = newMemory; + mSize = size; + + return true; +} + +void MemoryBuffer::fill(uint8_t datum) +{ + if (!empty()) + { + std::fill(mData, mData + mSize, datum); + } +} + +MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) : MemoryBuffer() +{ + *this = std::move(other); +} + +MemoryBuffer &MemoryBuffer::operator=(MemoryBuffer &&other) +{ + std::swap(mSize, other.mSize); + std::swap(mData, other.mData); + return *this; +} + +namespace +{ +static constexpr uint32_t kDefaultScratchBufferLifetime = 1000u; + +} // anonymous namespace + +// ScratchBuffer implementation. +ScratchBuffer::ScratchBuffer() : ScratchBuffer(kDefaultScratchBufferLifetime) {} + +ScratchBuffer::ScratchBuffer(uint32_t lifetime) : mLifetime(lifetime), mResetCounter(lifetime) {} + +ScratchBuffer::~ScratchBuffer() {} + +ScratchBuffer::ScratchBuffer(ScratchBuffer &&other) +{ + *this = std::move(other); +} + +ScratchBuffer &ScratchBuffer::operator=(ScratchBuffer &&other) +{ + std::swap(mLifetime, other.mLifetime); + std::swap(mResetCounter, other.mResetCounter); + std::swap(mScratchMemory, other.mScratchMemory); + return *this; +} + +bool ScratchBuffer::get(size_t requestedSize, MemoryBuffer **memoryBufferOut) +{ + return getImpl(requestedSize, memoryBufferOut, Optional::Invalid()); +} + +bool ScratchBuffer::getInitialized(size_t requestedSize, + MemoryBuffer **memoryBufferOut, + uint8_t initValue) +{ + return getImpl(requestedSize, memoryBufferOut, Optional(initValue)); +} + +bool ScratchBuffer::getImpl(size_t requestedSize, + MemoryBuffer **memoryBufferOut, + Optional initValue) +{ + if (mScratchMemory.size() == requestedSize) + { + mResetCounter = mLifetime; + *memoryBufferOut = &mScratchMemory; + return true; + } + + if (mScratchMemory.size() > requestedSize) + { + tick(); + } + + if (mScratchMemory.size() < requestedSize) + { + if (!mScratchMemory.resize(requestedSize)) + { + return false; + } + mResetCounter = mLifetime; + if (initValue.valid()) + { + mScratchMemory.fill(initValue.value()); + } + } + + ASSERT(mScratchMemory.size() >= requestedSize); + + *memoryBufferOut = &mScratchMemory; + return true; +} + +void ScratchBuffer::tick() +{ + if (mResetCounter > 0) + { + --mResetCounter; + if (mResetCounter == 0) + { + clear(); + } + } +} + +void ScratchBuffer::clear() +{ + mResetCounter = mLifetime; + if (mScratchMemory.size() > 0) + { + mScratchMemory.clear(); + } +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/MemoryBuffer.h b/gfx/angle/checkout/src/common/MemoryBuffer.h new file mode 100644 index 0000000000..bcd3aab7a9 --- /dev/null +++ b/gfx/angle/checkout/src/common/MemoryBuffer.h @@ -0,0 +1,93 @@ +// +// Copyright 2014 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. +// + +#ifndef COMMON_MEMORYBUFFER_H_ +#define COMMON_MEMORYBUFFER_H_ + +#include "common/Optional.h" +#include "common/angleutils.h" +#include "common/debug.h" + +#include +#include + +namespace angle +{ + +class MemoryBuffer final : NonCopyable +{ + public: + MemoryBuffer() = default; + ~MemoryBuffer(); + + MemoryBuffer(MemoryBuffer &&other); + MemoryBuffer &operator=(MemoryBuffer &&other); + + [[nodiscard]] bool resize(size_t size); + void clear() { (void)resize(0); } + size_t size() const { return mSize; } + bool empty() const { return mSize == 0; } + + const uint8_t *data() const { return mData; } + uint8_t *data() + { + ASSERT(mData); + return mData; + } + + uint8_t &operator[](size_t pos) + { + ASSERT(pos < mSize); + return mData[pos]; + } + const uint8_t &operator[](size_t pos) const + { + ASSERT(pos < mSize); + return mData[pos]; + } + + void fill(uint8_t datum); + + private: + size_t mSize = 0; + uint8_t *mData = nullptr; +}; + +class ScratchBuffer final : NonCopyable +{ + public: + // If we request a scratch buffer requesting a smaller size this many times, release and + // recreate the scratch buffer. This ensures we don't have a degenerate case where we are stuck + // hogging memory. + ScratchBuffer(); + ScratchBuffer(uint32_t lifetime); + ~ScratchBuffer(); + + ScratchBuffer(ScratchBuffer &&other); + ScratchBuffer &operator=(ScratchBuffer &&other); + + // Returns true with a memory buffer of the requested size, or false on failure. + bool get(size_t requestedSize, MemoryBuffer **memoryBufferOut); + + // Same as get, but ensures new values are initialized to a fixed constant. + bool getInitialized(size_t requestedSize, MemoryBuffer **memoryBufferOut, uint8_t initValue); + + // Ticks the release counter for the scratch buffer. Also done implicitly in get(). + void tick(); + + void clear(); + + private: + bool getImpl(size_t requestedSize, MemoryBuffer **memoryBufferOut, Optional initValue); + + uint32_t mLifetime; + uint32_t mResetCounter; + MemoryBuffer mScratchMemory; +}; + +} // namespace angle + +#endif // COMMON_MEMORYBUFFER_H_ diff --git a/gfx/angle/checkout/src/common/Optional.h b/gfx/angle/checkout/src/common/Optional.h new file mode 100644 index 0000000000..46c65dde4e --- /dev/null +++ b/gfx/angle/checkout/src/common/Optional.h @@ -0,0 +1,74 @@ +// +// Copyright 2015 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. +// +// Optional.h: +// Represents a type that may be invalid, similar to std::optional. +// + +#ifndef COMMON_OPTIONAL_H_ +#define COMMON_OPTIONAL_H_ + +#include + +template +struct Optional +{ + Optional() : mValid(false), mValue(T()) {} + + Optional(const T &valueIn) : mValid(true), mValue(valueIn) {} + + Optional(const Optional &other) : mValid(other.mValid), mValue(other.mValue) {} + + Optional &operator=(const Optional &other) + { + this->mValid = other.mValid; + this->mValue = other.mValue; + return *this; + } + + Optional &operator=(const T &value) + { + mValue = value; + mValid = true; + return *this; + } + + Optional &operator=(T &&value) + { + mValue = std::move(value); + mValid = true; + return *this; + } + + void reset() { mValid = false; } + T &&release() + { + mValid = false; + return std::move(mValue); + } + + static Optional Invalid() { return Optional(); } + + bool valid() const { return mValid; } + T &value() { return mValue; } + const T &value() const { return mValue; } + + bool operator==(const Optional &other) const + { + return ((mValid == other.mValid) && (!mValid || (mValue == other.mValue))); + } + + bool operator!=(const Optional &other) const { return !(*this == other); } + + bool operator==(const T &value) const { return mValid && (mValue == value); } + + bool operator!=(const T &value) const { return !(*this == value); } + + private: + bool mValid; + T mValue; +}; + +#endif // COMMON_OPTIONAL_H_ diff --git a/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp new file mode 100644 index 0000000000..738254bd18 --- /dev/null +++ b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp @@ -0,0 +1,452 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_packed_gl_enums.py using data from packed_egl_enums.json. +// +// Copyright 2017 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. +// +// PackedEGLEnums_autogen.cpp: +// Implements ANGLE-specific enums classes for EGLenums and functions operating +// on them. + +#include "common/PackedEGLEnums_autogen.h" +#include "common/debug.h" + +namespace egl +{ + +template <> +ColorSpace FromEGLenum(EGLenum from) +{ + switch (from) + { + case EGL_COLORSPACE_sRGB: + return ColorSpace::sRGB; + case EGL_COLORSPACE_LINEAR: + return ColorSpace::Linear; + default: + return ColorSpace::InvalidEnum; + } +} + +EGLenum ToEGLenum(ColorSpace from) +{ + switch (from) + { + case ColorSpace::sRGB: + return EGL_COLORSPACE_sRGB; + case ColorSpace::Linear: + return EGL_COLORSPACE_LINEAR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ColorSpace value) +{ + switch (value) + { + case ColorSpace::sRGB: + os << "EGL_COLORSPACE_sRGB"; + break; + case ColorSpace::Linear: + os << "EGL_COLORSPACE_LINEAR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +CompositorTiming FromEGLenum(EGLenum from) +{ + switch (from) + { + case EGL_COMPOSITE_DEADLINE_ANDROID: + return CompositorTiming::CompositeDeadline; + case EGL_COMPOSITE_INTERVAL_ANDROID: + return CompositorTiming::CompositInterval; + case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID: + return CompositorTiming::CompositToPresentLatency; + default: + return CompositorTiming::InvalidEnum; + } +} + +EGLenum ToEGLenum(CompositorTiming from) +{ + switch (from) + { + case CompositorTiming::CompositeDeadline: + return EGL_COMPOSITE_DEADLINE_ANDROID; + case CompositorTiming::CompositInterval: + return EGL_COMPOSITE_INTERVAL_ANDROID; + case CompositorTiming::CompositToPresentLatency: + return EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, CompositorTiming value) +{ + switch (value) + { + case CompositorTiming::CompositeDeadline: + os << "EGL_COMPOSITE_DEADLINE_ANDROID"; + break; + case CompositorTiming::CompositInterval: + os << "EGL_COMPOSITE_INTERVAL_ANDROID"; + break; + case CompositorTiming::CompositToPresentLatency: + os << "EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ContextPriority FromEGLenum(EGLenum from) +{ + switch (from) + { + case EGL_CONTEXT_PRIORITY_LOW_IMG: + return ContextPriority::Low; + case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: + return ContextPriority::Medium; + case EGL_CONTEXT_PRIORITY_HIGH_IMG: + return ContextPriority::High; + default: + return ContextPriority::InvalidEnum; + } +} + +EGLenum ToEGLenum(ContextPriority from) +{ + switch (from) + { + case ContextPriority::Low: + return EGL_CONTEXT_PRIORITY_LOW_IMG; + case ContextPriority::Medium: + return EGL_CONTEXT_PRIORITY_MEDIUM_IMG; + case ContextPriority::High: + return EGL_CONTEXT_PRIORITY_HIGH_IMG; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ContextPriority value) +{ + switch (value) + { + case ContextPriority::Low: + os << "EGL_CONTEXT_PRIORITY_LOW_IMG"; + break; + case ContextPriority::Medium: + os << "EGL_CONTEXT_PRIORITY_MEDIUM_IMG"; + break; + case ContextPriority::High: + os << "EGL_CONTEXT_PRIORITY_HIGH_IMG"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +MessageType FromEGLenum(EGLenum from) +{ + switch (from) + { + case EGL_DEBUG_MSG_CRITICAL_KHR: + return MessageType::Critical; + case EGL_DEBUG_MSG_ERROR_KHR: + return MessageType::Error; + case EGL_DEBUG_MSG_WARN_KHR: + return MessageType::Warn; + case EGL_DEBUG_MSG_INFO_KHR: + return MessageType::Info; + default: + return MessageType::InvalidEnum; + } +} + +EGLenum ToEGLenum(MessageType from) +{ + switch (from) + { + case MessageType::Critical: + return EGL_DEBUG_MSG_CRITICAL_KHR; + case MessageType::Error: + return EGL_DEBUG_MSG_ERROR_KHR; + case MessageType::Warn: + return EGL_DEBUG_MSG_WARN_KHR; + case MessageType::Info: + return EGL_DEBUG_MSG_INFO_KHR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, MessageType value) +{ + switch (value) + { + case MessageType::Critical: + os << "EGL_DEBUG_MSG_CRITICAL_KHR"; + break; + case MessageType::Error: + os << "EGL_DEBUG_MSG_ERROR_KHR"; + break; + case MessageType::Warn: + os << "EGL_DEBUG_MSG_WARN_KHR"; + break; + case MessageType::Info: + os << "EGL_DEBUG_MSG_INFO_KHR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ObjectType FromEGLenum(EGLenum from) +{ + switch (from) + { + case EGL_OBJECT_THREAD_KHR: + return ObjectType::Thread; + case EGL_OBJECT_DISPLAY_KHR: + return ObjectType::Display; + case EGL_OBJECT_CONTEXT_KHR: + return ObjectType::Context; + case EGL_OBJECT_SURFACE_KHR: + return ObjectType::Surface; + case EGL_OBJECT_IMAGE_KHR: + return ObjectType::Image; + case EGL_OBJECT_SYNC_KHR: + return ObjectType::Sync; + case EGL_OBJECT_STREAM_KHR: + return ObjectType::Stream; + default: + return ObjectType::InvalidEnum; + } +} + +EGLenum ToEGLenum(ObjectType from) +{ + switch (from) + { + case ObjectType::Thread: + return EGL_OBJECT_THREAD_KHR; + case ObjectType::Display: + return EGL_OBJECT_DISPLAY_KHR; + case ObjectType::Context: + return EGL_OBJECT_CONTEXT_KHR; + case ObjectType::Surface: + return EGL_OBJECT_SURFACE_KHR; + case ObjectType::Image: + return EGL_OBJECT_IMAGE_KHR; + case ObjectType::Sync: + return EGL_OBJECT_SYNC_KHR; + case ObjectType::Stream: + return EGL_OBJECT_STREAM_KHR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ObjectType value) +{ + switch (value) + { + case ObjectType::Thread: + os << "EGL_OBJECT_THREAD_KHR"; + break; + case ObjectType::Display: + os << "EGL_OBJECT_DISPLAY_KHR"; + break; + case ObjectType::Context: + os << "EGL_OBJECT_CONTEXT_KHR"; + break; + case ObjectType::Surface: + os << "EGL_OBJECT_SURFACE_KHR"; + break; + case ObjectType::Image: + os << "EGL_OBJECT_IMAGE_KHR"; + break; + case ObjectType::Sync: + os << "EGL_OBJECT_SYNC_KHR"; + break; + case ObjectType::Stream: + os << "EGL_OBJECT_STREAM_KHR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureFormat FromEGLenum(EGLenum from) +{ + switch (from) + { + case EGL_NO_TEXTURE: + return TextureFormat::NoTexture; + case EGL_TEXTURE_RGB: + return TextureFormat::RGB; + case EGL_TEXTURE_RGBA: + return TextureFormat::RGBA; + default: + return TextureFormat::InvalidEnum; + } +} + +EGLenum ToEGLenum(TextureFormat from) +{ + switch (from) + { + case TextureFormat::NoTexture: + return EGL_NO_TEXTURE; + case TextureFormat::RGB: + return EGL_TEXTURE_RGB; + case TextureFormat::RGBA: + return EGL_TEXTURE_RGBA; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureFormat value) +{ + switch (value) + { + case TextureFormat::NoTexture: + os << "EGL_NO_TEXTURE"; + break; + case TextureFormat::RGB: + os << "EGL_TEXTURE_RGB"; + break; + case TextureFormat::RGBA: + os << "EGL_TEXTURE_RGBA"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +Timestamp FromEGLenum(EGLenum from) +{ + switch (from) + { + case EGL_REQUESTED_PRESENT_TIME_ANDROID: + return Timestamp::RequestedPresentTime; + case EGL_RENDERING_COMPLETE_TIME_ANDROID: + return Timestamp::RenderingCompleteTime; + case EGL_COMPOSITION_LATCH_TIME_ANDROID: + return Timestamp::CompositionLatchTime; + case EGL_FIRST_COMPOSITION_START_TIME_ANDROID: + return Timestamp::FirstCompositionStartTime; + case EGL_LAST_COMPOSITION_START_TIME_ANDROID: + return Timestamp::LastCompositionStartTime; + case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID: + return Timestamp::FirstCompositionGPUFinishedTime; + case EGL_DISPLAY_PRESENT_TIME_ANDROID: + return Timestamp::DisplayPresentTime; + case EGL_DEQUEUE_READY_TIME_ANDROID: + return Timestamp::DequeueReadyTime; + case EGL_READS_DONE_TIME_ANDROID: + return Timestamp::ReadsDoneTime; + default: + return Timestamp::InvalidEnum; + } +} + +EGLenum ToEGLenum(Timestamp from) +{ + switch (from) + { + case Timestamp::RequestedPresentTime: + return EGL_REQUESTED_PRESENT_TIME_ANDROID; + case Timestamp::RenderingCompleteTime: + return EGL_RENDERING_COMPLETE_TIME_ANDROID; + case Timestamp::CompositionLatchTime: + return EGL_COMPOSITION_LATCH_TIME_ANDROID; + case Timestamp::FirstCompositionStartTime: + return EGL_FIRST_COMPOSITION_START_TIME_ANDROID; + case Timestamp::LastCompositionStartTime: + return EGL_LAST_COMPOSITION_START_TIME_ANDROID; + case Timestamp::FirstCompositionGPUFinishedTime: + return EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID; + case Timestamp::DisplayPresentTime: + return EGL_DISPLAY_PRESENT_TIME_ANDROID; + case Timestamp::DequeueReadyTime: + return EGL_DEQUEUE_READY_TIME_ANDROID; + case Timestamp::ReadsDoneTime: + return EGL_READS_DONE_TIME_ANDROID; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, Timestamp value) +{ + switch (value) + { + case Timestamp::RequestedPresentTime: + os << "EGL_REQUESTED_PRESENT_TIME_ANDROID"; + break; + case Timestamp::RenderingCompleteTime: + os << "EGL_RENDERING_COMPLETE_TIME_ANDROID"; + break; + case Timestamp::CompositionLatchTime: + os << "EGL_COMPOSITION_LATCH_TIME_ANDROID"; + break; + case Timestamp::FirstCompositionStartTime: + os << "EGL_FIRST_COMPOSITION_START_TIME_ANDROID"; + break; + case Timestamp::LastCompositionStartTime: + os << "EGL_LAST_COMPOSITION_START_TIME_ANDROID"; + break; + case Timestamp::FirstCompositionGPUFinishedTime: + os << "EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID"; + break; + case Timestamp::DisplayPresentTime: + os << "EGL_DISPLAY_PRESENT_TIME_ANDROID"; + break; + case Timestamp::DequeueReadyTime: + os << "EGL_DEQUEUE_READY_TIME_ANDROID"; + break; + case Timestamp::ReadsDoneTime: + os << "EGL_READS_DONE_TIME_ANDROID"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +} // namespace egl diff --git a/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h new file mode 100644 index 0000000000..7794e8509e --- /dev/null +++ b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h @@ -0,0 +1,144 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_packed_gl_enums.py using data from packed_egl_enums.json. +// +// Copyright 2017 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. +// +// PackedEGLEnums_autogen.h: +// Declares ANGLE-specific enums classes for EGLenums and functions operating +// on them. + +#ifndef COMMON_PACKEDEGLENUMS_AUTOGEN_H_ +#define COMMON_PACKEDEGLENUMS_AUTOGEN_H_ + +#include +#include + +#include +#include + +namespace egl +{ + +template +Enum FromEGLenum(EGLenum from); + +enum class ColorSpace : uint8_t +{ + sRGB = 0, + Linear = 1, + + InvalidEnum = 2, + EnumCount = 2, +}; + +template <> +ColorSpace FromEGLenum(EGLenum from); +EGLenum ToEGLenum(ColorSpace from); +std::ostream &operator<<(std::ostream &os, ColorSpace value); + +enum class CompositorTiming : uint8_t +{ + CompositeDeadline = 0, + CompositInterval = 1, + CompositToPresentLatency = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +CompositorTiming FromEGLenum(EGLenum from); +EGLenum ToEGLenum(CompositorTiming from); +std::ostream &operator<<(std::ostream &os, CompositorTiming value); + +enum class ContextPriority : uint8_t +{ + Low = 0, + Medium = 1, + High = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +ContextPriority FromEGLenum(EGLenum from); +EGLenum ToEGLenum(ContextPriority from); +std::ostream &operator<<(std::ostream &os, ContextPriority value); + +enum class MessageType : uint8_t +{ + Critical = 0, + Error = 1, + Warn = 2, + Info = 3, + + InvalidEnum = 4, + EnumCount = 4, +}; + +template <> +MessageType FromEGLenum(EGLenum from); +EGLenum ToEGLenum(MessageType from); +std::ostream &operator<<(std::ostream &os, MessageType value); + +enum class ObjectType : uint8_t +{ + Thread = 0, + Display = 1, + Context = 2, + Surface = 3, + Image = 4, + Sync = 5, + Stream = 6, + + InvalidEnum = 7, + EnumCount = 7, +}; + +template <> +ObjectType FromEGLenum(EGLenum from); +EGLenum ToEGLenum(ObjectType from); +std::ostream &operator<<(std::ostream &os, ObjectType value); + +enum class TextureFormat : uint8_t +{ + NoTexture = 0, + RGB = 1, + RGBA = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +TextureFormat FromEGLenum(EGLenum from); +EGLenum ToEGLenum(TextureFormat from); +std::ostream &operator<<(std::ostream &os, TextureFormat value); + +enum class Timestamp : uint8_t +{ + RequestedPresentTime = 0, + RenderingCompleteTime = 1, + CompositionLatchTime = 2, + FirstCompositionStartTime = 3, + LastCompositionStartTime = 4, + FirstCompositionGPUFinishedTime = 5, + DisplayPresentTime = 6, + DequeueReadyTime = 7, + ReadsDoneTime = 8, + + InvalidEnum = 9, + EnumCount = 9, +}; + +template <> +Timestamp FromEGLenum(EGLenum from); +EGLenum ToEGLenum(Timestamp from); +std::ostream &operator<<(std::ostream &os, Timestamp value); + +} // namespace egl + +#endif // COMMON_PACKEDEGLENUMS_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/common/PackedEnums.cpp b/gfx/angle/checkout/src/common/PackedEnums.cpp new file mode 100644 index 0000000000..e13a502a42 --- /dev/null +++ b/gfx/angle/checkout/src/common/PackedEnums.cpp @@ -0,0 +1,673 @@ +// Copyright 2018 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. +// +// PackedGLEnums.cpp: +// Declares ANGLE-specific enums classes for GLEnum and functions operating +// on them. + +#include "common/PackedEnums.h" + +#include "common/utilities.h" + +namespace gl +{ + +TextureType TextureTargetToType(TextureTarget target) +{ + switch (target) + { + case TextureTarget::CubeMapNegativeX: + case TextureTarget::CubeMapNegativeY: + case TextureTarget::CubeMapNegativeZ: + case TextureTarget::CubeMapPositiveX: + case TextureTarget::CubeMapPositiveY: + case TextureTarget::CubeMapPositiveZ: + return TextureType::CubeMap; + case TextureTarget::CubeMapArray: + return TextureType::CubeMapArray; + case TextureTarget::External: + return TextureType::External; + case TextureTarget::Rectangle: + return TextureType::Rectangle; + case TextureTarget::_2D: + return TextureType::_2D; + case TextureTarget::_2DArray: + return TextureType::_2DArray; + case TextureTarget::_2DMultisample: + return TextureType::_2DMultisample; + case TextureTarget::_2DMultisampleArray: + return TextureType::_2DMultisampleArray; + case TextureTarget::_3D: + return TextureType::_3D; + case TextureTarget::VideoImage: + return TextureType::VideoImage; + case TextureTarget::Buffer: + return TextureType::Buffer; + case TextureTarget::InvalidEnum: + return TextureType::InvalidEnum; + default: + UNREACHABLE(); + return TextureType::InvalidEnum; + } +} + +bool IsCubeMapFaceTarget(TextureTarget target) +{ + return TextureTargetToType(target) == TextureType::CubeMap; +} + +TextureTarget NonCubeTextureTypeToTarget(TextureType type) +{ + switch (type) + { + case TextureType::External: + return TextureTarget::External; + case TextureType::Rectangle: + return TextureTarget::Rectangle; + case TextureType::_2D: + return TextureTarget::_2D; + case TextureType::_2DArray: + return TextureTarget::_2DArray; + case TextureType::_2DMultisample: + return TextureTarget::_2DMultisample; + case TextureType::_2DMultisampleArray: + return TextureTarget::_2DMultisampleArray; + case TextureType::_3D: + return TextureTarget::_3D; + case TextureType::CubeMapArray: + return TextureTarget::CubeMapArray; + case TextureType::VideoImage: + return TextureTarget::VideoImage; + case TextureType::Buffer: + return TextureTarget::Buffer; + default: + UNREACHABLE(); + return TextureTarget::InvalidEnum; + } +} + +// Check that we can do arithmetic on TextureTarget to convert from / to cube map faces +static_assert(static_cast(TextureTarget::CubeMapNegativeX) - + static_cast(TextureTarget::CubeMapPositiveX) == + 1u, + ""); +static_assert(static_cast(TextureTarget::CubeMapPositiveY) - + static_cast(TextureTarget::CubeMapPositiveX) == + 2u, + ""); +static_assert(static_cast(TextureTarget::CubeMapNegativeY) - + static_cast(TextureTarget::CubeMapPositiveX) == + 3u, + ""); +static_assert(static_cast(TextureTarget::CubeMapPositiveZ) - + static_cast(TextureTarget::CubeMapPositiveX) == + 4u, + ""); +static_assert(static_cast(TextureTarget::CubeMapNegativeZ) - + static_cast(TextureTarget::CubeMapPositiveX) == + 5u, + ""); + +TextureTarget CubeFaceIndexToTextureTarget(size_t face) +{ + ASSERT(face < 6u); + return static_cast(static_cast(TextureTarget::CubeMapPositiveX) + face); +} + +size_t CubeMapTextureTargetToFaceIndex(TextureTarget target) +{ + ASSERT(IsCubeMapFaceTarget(target)); + return static_cast(target) - static_cast(TextureTarget::CubeMapPositiveX); +} + +TextureType SamplerTypeToTextureType(GLenum samplerType) +{ + switch (samplerType) + { + case GL_SAMPLER_2D: + case GL_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_SAMPLER_2D_SHADOW: + return TextureType::_2D; + + case GL_SAMPLER_EXTERNAL_OES: + case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT: + return TextureType::External; + + case GL_SAMPLER_CUBE: + case GL_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + return TextureType::CubeMap; + + case GL_SAMPLER_CUBE_MAP_ARRAY: + case GL_INT_SAMPLER_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: + case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: + return TextureType::CubeMapArray; + + case GL_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + return TextureType::_2DArray; + + case GL_SAMPLER_3D: + case GL_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_3D: + return TextureType::_3D; + + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + return TextureType::_2DMultisample; + + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + return TextureType::_2DMultisampleArray; + + case GL_SAMPLER_BUFFER: + case GL_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + return TextureType::Buffer; + + case GL_SAMPLER_2D_RECT_ANGLE: + return TextureType::Rectangle; + + case GL_SAMPLER_VIDEO_IMAGE_WEBGL: + return TextureType::VideoImage; + + default: + UNREACHABLE(); + return TextureType::InvalidEnum; + } +} + +TextureType ImageTypeToTextureType(GLenum imageType) +{ + switch (imageType) + { + case GL_IMAGE_2D: + case GL_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_2D: + return TextureType::_2D; + + case GL_IMAGE_CUBE: + case GL_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_CUBE: + return TextureType::CubeMap; + + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + return TextureType::CubeMapArray; + + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + return TextureType::_2DArray; + + case GL_IMAGE_3D: + case GL_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_3D: + return TextureType::_3D; + + case GL_IMAGE_BUFFER: + case GL_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + return TextureType::Buffer; + + default: + UNREACHABLE(); + return TextureType::InvalidEnum; + } +} + +bool IsMultisampled(TextureType type) +{ + switch (type) + { + case TextureType::_2DMultisample: + case TextureType::_2DMultisampleArray: + return true; + default: + return false; + } +} + +bool IsArrayTextureType(TextureType type) +{ + switch (type) + { + case TextureType::_2DArray: + case TextureType::_2DMultisampleArray: + case TextureType::CubeMapArray: + return true; + default: + return false; + } +} + +bool IsStaticBufferUsage(BufferUsage useage) +{ + switch (useage) + { + case BufferUsage::StaticCopy: + case BufferUsage::StaticDraw: + case BufferUsage::StaticRead: + return true; + default: + return false; + } +} + +std::ostream &operator<<(std::ostream &os, PrimitiveMode value) +{ + switch (value) + { + case PrimitiveMode::LineLoop: + os << "GL_LINE_LOOP"; + break; + case PrimitiveMode::Lines: + os << "GL_LINES"; + break; + case PrimitiveMode::LinesAdjacency: + os << "GL_LINES_ADJACENCY"; + break; + case PrimitiveMode::LineStrip: + os << "GL_LINE_STRIP"; + break; + case PrimitiveMode::LineStripAdjacency: + os << "GL_LINE_STRIP_ADJANCENCY"; + break; + case PrimitiveMode::Patches: + os << "GL_PATCHES"; + break; + case PrimitiveMode::Points: + os << "GL_POINTS"; + break; + case PrimitiveMode::TriangleFan: + os << "GL_TRIANGLE_FAN"; + break; + case PrimitiveMode::Triangles: + os << "GL_TRIANGLES"; + break; + case PrimitiveMode::TrianglesAdjacency: + os << "GL_TRIANGLES_ADJANCENCY"; + break; + case PrimitiveMode::TriangleStrip: + os << "GL_TRIANGLE_STRIP"; + break; + case PrimitiveMode::TriangleStripAdjacency: + os << "GL_TRIANGLE_STRIP_ADJACENCY"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +std::ostream &operator<<(std::ostream &os, DrawElementsType value) +{ + switch (value) + { + case DrawElementsType::UnsignedByte: + os << "GL_UNSIGNED_BYTE"; + break; + case DrawElementsType::UnsignedShort: + os << "GL_UNSIGNED_SHORT"; + break; + case DrawElementsType::UnsignedInt: + os << "GL_UNSIGNED_INT"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + + return os; +} + +std::ostream &operator<<(std::ostream &os, BlendEquationType value) +{ + switch (value) + { + case BlendEquationType::Add: + os << "GL_FUNC_ADD"; + break; + case BlendEquationType::Min: + os << "GL_MIN"; + break; + case BlendEquationType::Max: + os << "GL_MAX"; + break; + case BlendEquationType::Subtract: + os << "GL_FUNC_SUBTRACT"; + break; + case BlendEquationType::ReverseSubtract: + os << "GL_FUNC_REVERSE_SUBTRACT"; + break; + case BlendEquationType::Multiply: + os << "GL_MULTIPLY_KHR"; + break; + case BlendEquationType::Screen: + os << "GL_SCREEN_KHR"; + break; + case BlendEquationType::Overlay: + os << "GL_OVERLAY_KHR"; + break; + case BlendEquationType::Darken: + os << "GL_DARKEN_KHR"; + break; + case BlendEquationType::Lighten: + os << "GL_LIGHTEN_KHR"; + break; + case BlendEquationType::Colordodge: + os << "GL_COLORDODGE_KHR"; + break; + case BlendEquationType::Colorburn: + os << "GL_COLORBURN_KHR"; + break; + case BlendEquationType::Hardlight: + os << "GL_HARDLIGHT_KHR"; + break; + case BlendEquationType::Softlight: + os << "GL_SOFTLIGHT_KHR"; + break; + case BlendEquationType::Difference: + os << "GL_DIFFERENCE_KHR"; + break; + case BlendEquationType::Exclusion: + os << "GL_EXCLUSION_KHR"; + break; + case BlendEquationType::HslHue: + os << "GL_HSL_HUE_KHR"; + break; + case BlendEquationType::HslSaturation: + os << "GL_HSL_SATURATION_KHR"; + break; + case BlendEquationType::HslColor: + os << "GL_HSL_COLOR_KHR"; + break; + case BlendEquationType::HslLuminosity: + os << "GL_HSL_LUMINOSITY_KHR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + + return os; +} + +std::ostream &operator<<(std::ostream &os, BlendFactorType value) +{ + switch (value) + { + case BlendFactorType::Zero: + os << "GL_ZERO"; + break; + case BlendFactorType::One: + os << "GL_ONE"; + break; + case BlendFactorType::SrcColor: + os << "GL_SRC_COLOR"; + break; + case BlendFactorType::OneMinusSrcColor: + os << "GL_ONE_MINUS_SRC_COLOR"; + break; + case BlendFactorType::SrcAlpha: + os << "GL_SRC_ALPHA"; + break; + case BlendFactorType::OneMinusSrcAlpha: + os << "GL_ONE_MINUS_SRC_ALPHA"; + break; + case BlendFactorType::DstAlpha: + os << "GL_DST_ALPHA"; + break; + case BlendFactorType::OneMinusDstAlpha: + os << "GL_ONE_MINUS_DST_ALPHA"; + break; + case BlendFactorType::DstColor: + os << "GL_DST_COLOR"; + break; + case BlendFactorType::OneMinusDstColor: + os << "GL_ONE_MINUS_DST_COLOR"; + break; + case BlendFactorType::SrcAlphaSaturate: + os << "GL_SRC_ALPHA_SATURATE"; + break; + case BlendFactorType::ConstantColor: + os << "GL_CONSTANT_COLOR"; + break; + case BlendFactorType::OneMinusConstantColor: + os << "GL_ONE_MINUS_CONSTANT_COLOR"; + break; + case BlendFactorType::ConstantAlpha: + os << "GL_CONSTANT_ALPHA"; + break; + case BlendFactorType::OneMinusConstantAlpha: + os << "GL_ONE_MINUS_CONSTANT_ALPHA"; + break; + case BlendFactorType::Src1Alpha: + os << "GL_SRC1_ALPHA_EXT"; + break; + case BlendFactorType::Src1Color: + os << "GL_SRC1_COLOR_EXT"; + break; + case BlendFactorType::OneMinusSrc1Color: + os << "GL_ONE_MINUS_SRC1_COLOR_EXT"; + break; + case BlendFactorType::OneMinusSrc1Alpha: + os << "GL_ONE_MINUS_SRC1_ALPHA_EXT"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + + return os; +} + +std::ostream &operator<<(std::ostream &os, VertexAttribType value) +{ + switch (value) + { + case VertexAttribType::Byte: + os << "GL_BYTE"; + break; + case VertexAttribType::Fixed: + os << "GL_FIXED"; + break; + case VertexAttribType::Float: + os << "GL_FLOAT"; + break; + case VertexAttribType::HalfFloat: + os << "GL_HALF_FLOAT"; + break; + case VertexAttribType::HalfFloatOES: + os << "GL_HALF_FLOAT_OES"; + break; + case VertexAttribType::Int: + os << "GL_INT"; + break; + case VertexAttribType::Int2101010: + os << "GL_INT_2_10_10_10_REV"; + break; + case VertexAttribType::Int1010102: + os << "GL_INT_10_10_10_2_OES"; + break; + case VertexAttribType::Short: + os << "GL_SHORT"; + break; + case VertexAttribType::UnsignedByte: + os << "GL_UNSIGNED_BYTE"; + break; + case VertexAttribType::UnsignedInt: + os << "GL_UNSIGNED_INT"; + break; + case VertexAttribType::UnsignedInt2101010: + os << "GL_UNSIGNED_INT_2_10_10_10_REV"; + break; + case VertexAttribType::UnsignedInt1010102: + os << "GL_UNSIGNED_INT_10_10_10_2_OES"; + break; + case VertexAttribType::UnsignedShort: + os << "GL_UNSIGNED_SHORT"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +std::ostream &operator<<(std::ostream &os, TessEvaluationType value) +{ + switch (value) + { + case TessEvaluationType::Triangles: + os << "GL_TRIANGLES"; + break; + case TessEvaluationType::Quads: + os << "GL_QUADS"; + break; + case TessEvaluationType::Isolines: + os << "GL_ISOLINES"; + break; + case TessEvaluationType::EqualSpacing: + os << "GL_EQUAL"; + break; + case TessEvaluationType::FractionalEvenSpacing: + os << "GL_FRACTIONAL_EVEN"; + break; + case TessEvaluationType::FractionalOddSpacing: + os << "GL_FRACTIONAL_ODD"; + break; + case TessEvaluationType::Cw: + os << "GL_CW"; + break; + case TessEvaluationType::Ccw: + os << "GL_CCW"; + break; + case TessEvaluationType::PointMode: + os << "GL_TESS_GEN_POINT_MODE"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +const char *ShaderTypeToString(ShaderType shaderType) +{ + constexpr ShaderMap kShaderTypeNameMap = { + {ShaderType::Vertex, "Vertex"}, + {ShaderType::TessControl, "Tessellation control"}, + {ShaderType::TessEvaluation, "Tessellation evaluation"}, + {ShaderType::Geometry, "Geometry"}, + {ShaderType::Fragment, "Fragment"}, + {ShaderType::Compute, "Compute"}}; + return kShaderTypeNameMap[shaderType]; +} + +bool operator<(const UniformLocation &lhs, const UniformLocation &rhs) +{ + return lhs.value < rhs.value; +} + +bool IsEmulatedCompressedFormat(GLenum format) +{ + // TODO(anglebug.com/6177): Check for all formats ANGLE will use to emulate a compressed texture + return format == GL_RGBA || format == GL_RG || format == GL_RED; +} +} // namespace gl + +namespace egl +{ +MessageType ErrorCodeToMessageType(EGLint errorCode) +{ + switch (errorCode) + { + case EGL_BAD_ALLOC: + case EGL_CONTEXT_LOST: + case EGL_NOT_INITIALIZED: + return MessageType::Critical; + + case EGL_BAD_ACCESS: + case EGL_BAD_ATTRIBUTE: + case EGL_BAD_CONFIG: + case EGL_BAD_CONTEXT: + case EGL_BAD_CURRENT_SURFACE: + case EGL_BAD_DISPLAY: + case EGL_BAD_MATCH: + case EGL_BAD_NATIVE_PIXMAP: + case EGL_BAD_NATIVE_WINDOW: + case EGL_BAD_PARAMETER: + case EGL_BAD_SURFACE: + case EGL_BAD_STREAM_KHR: + case EGL_BAD_STATE_KHR: + case EGL_BAD_DEVICE_EXT: + return MessageType::Error; + + case EGL_SUCCESS: + default: + UNREACHABLE(); + return MessageType::InvalidEnum; + } +} +} // namespace egl + +namespace egl_gl +{ + +gl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget) +{ + ASSERT(egl::IsCubeMapTextureTarget(eglTarget)); + return gl::CubeFaceIndexToTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget)); +} + +gl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget) +{ + switch (eglTarget) + { + case EGL_GL_TEXTURE_2D_KHR: + return gl::TextureTarget::_2D; + + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: + return EGLCubeMapTargetToCubeMapTarget(eglTarget); + + case EGL_GL_TEXTURE_3D_KHR: + return gl::TextureTarget::_3D; + + default: + UNREACHABLE(); + return gl::TextureTarget::InvalidEnum; + } +} + +gl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget) +{ + switch (eglTarget) + { + case EGL_TEXTURE_2D: + return gl::TextureType::_2D; + + case EGL_TEXTURE_RECTANGLE_ANGLE: + return gl::TextureType::Rectangle; + + default: + UNREACHABLE(); + return gl::TextureType::InvalidEnum; + } +} +} // namespace egl_gl diff --git a/gfx/angle/checkout/src/common/PackedEnums.h b/gfx/angle/checkout/src/common/PackedEnums.h new file mode 100644 index 0000000000..81fa6d6f42 --- /dev/null +++ b/gfx/angle/checkout/src/common/PackedEnums.h @@ -0,0 +1,859 @@ +// Copyright 2017 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. +// +// PackedGLEnums_autogen.h: +// Declares ANGLE-specific enums classes for GLEnum and functions operating +// on them. + +#ifndef COMMON_PACKEDGLENUMS_H_ +#define COMMON_PACKEDGLENUMS_H_ + +#include "common/PackedEGLEnums_autogen.h" +#include "common/PackedGLEnums_autogen.h" + +#include +#include +#include + +#include + +#include "common/bitset_utils.h" + +namespace angle +{ + +// Return the number of elements of a packed enum, including the InvalidEnum element. +template +constexpr size_t EnumSize() +{ + using UnderlyingType = typename std::underlying_type::type; + return static_cast(E::EnumCount); +} + +// Implementation of AllEnums which allows iterating over all the possible values for a packed enums +// like so: +// for (auto value : AllEnums()) { +// // Do something with the enum. +// } + +template +class EnumIterator final +{ + private: + using UnderlyingType = typename std::underlying_type::type; + + public: + EnumIterator(E value) : mValue(static_cast(value)) {} + EnumIterator &operator++() + { + mValue++; + return *this; + } + bool operator==(const EnumIterator &other) const { return mValue == other.mValue; } + bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; } + E operator*() const { return static_cast(mValue); } + + private: + UnderlyingType mValue; +}; + +template ()> +struct AllEnums +{ + EnumIterator begin() const { return {static_cast(0)}; } + EnumIterator end() const { return {static_cast(MaxSize)}; } +}; + +// PackedEnumMap is like an std::array but is indexed with enum values. It +// implements all of the std::array interface except with enum values instead of indices. +template ()> +class PackedEnumMap +{ + using UnderlyingType = typename std::underlying_type::type; + using Storage = std::array; + + public: + using InitPair = std::pair; + + constexpr PackedEnumMap() = default; + + constexpr PackedEnumMap(std::initializer_list init) : mPrivateData{} + { + // We use a for loop instead of range-for to work around a limitation in MSVC. + for (const InitPair *it = init.begin(); it != init.end(); ++it) + { + mPrivateData[static_cast(it->first)] = it->second; + } + } + + // types: + using value_type = T; + using pointer = T *; + using const_pointer = const T *; + using reference = T &; + using const_reference = const T &; + + using size_type = size_t; + using difference_type = ptrdiff_t; + + using iterator = typename Storage::iterator; + using const_iterator = typename Storage::const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // No explicit construct/copy/destroy for aggregate type + void fill(const T &u) { mPrivateData.fill(u); } + void swap(PackedEnumMap &a) noexcept { mPrivateData.swap(a.mPrivateData); } + + // iterators: + iterator begin() noexcept { return mPrivateData.begin(); } + const_iterator begin() const noexcept { return mPrivateData.begin(); } + iterator end() noexcept { return mPrivateData.end(); } + const_iterator end() const noexcept { return mPrivateData.end(); } + + reverse_iterator rbegin() noexcept { return mPrivateData.rbegin(); } + const_reverse_iterator rbegin() const noexcept { return mPrivateData.rbegin(); } + reverse_iterator rend() noexcept { return mPrivateData.rend(); } + const_reverse_iterator rend() const noexcept { return mPrivateData.rend(); } + + // capacity: + constexpr size_type size() const noexcept { return mPrivateData.size(); } + constexpr size_type max_size() const noexcept { return mPrivateData.max_size(); } + constexpr bool empty() const noexcept { return mPrivateData.empty(); } + + // element access: + reference operator[](E n) + { + ASSERT(static_cast(n) < mPrivateData.size()); + return mPrivateData[static_cast(n)]; + } + + constexpr const_reference operator[](E n) const + { + ASSERT(static_cast(n) < mPrivateData.size()); + return mPrivateData[static_cast(n)]; + } + + const_reference at(E n) const { return mPrivateData.at(static_cast(n)); } + reference at(E n) { return mPrivateData.at(static_cast(n)); } + + reference front() { return mPrivateData.front(); } + const_reference front() const { return mPrivateData.front(); } + reference back() { return mPrivateData.back(); } + const_reference back() const { return mPrivateData.back(); } + + T *data() noexcept { return mPrivateData.data(); } + const T *data() const noexcept { return mPrivateData.data(); } + + bool operator==(const PackedEnumMap &rhs) const { return mPrivateData == rhs.mPrivateData; } + bool operator!=(const PackedEnumMap &rhs) const { return mPrivateData != rhs.mPrivateData; } + + template + typename std::enable_if::value>::type operator+=( + const PackedEnumMap &rhs) + { + for (E e : AllEnums()) + { + at(e) += rhs[e]; + } + } + + private: + Storage mPrivateData; +}; + +// PackedEnumBitSetE> is like an std::bitset but is indexed with enum values. It +// implements the std::bitset interface except with enum values instead of indices. +template +using PackedEnumBitSet = BitSetT(), DataT, E>; + +} // namespace angle + +namespace gl +{ + +TextureType TextureTargetToType(TextureTarget target); +TextureTarget NonCubeTextureTypeToTarget(TextureType type); + +TextureTarget CubeFaceIndexToTextureTarget(size_t face); +size_t CubeMapTextureTargetToFaceIndex(TextureTarget target); +bool IsCubeMapFaceTarget(TextureTarget target); + +constexpr TextureTarget kCubeMapTextureTargetMin = TextureTarget::CubeMapPositiveX; +constexpr TextureTarget kCubeMapTextureTargetMax = TextureTarget::CubeMapNegativeZ; +constexpr TextureTarget kAfterCubeMapTextureTargetMax = + static_cast(static_cast(kCubeMapTextureTargetMax) + 1); +struct AllCubeFaceTextureTargets +{ + angle::EnumIterator begin() const { return kCubeMapTextureTargetMin; } + angle::EnumIterator end() const { return kAfterCubeMapTextureTargetMax; } +}; + +constexpr std::array kAllGLES2ShaderTypes = {ShaderType::Vertex, + ShaderType::Fragment}; + +constexpr ShaderType kShaderTypeMin = ShaderType::Vertex; +constexpr ShaderType kShaderTypeMax = ShaderType::Compute; +constexpr ShaderType kAfterShaderTypeMax = + static_cast(static_cast(kShaderTypeMax) + 1); +struct AllShaderTypes +{ + angle::EnumIterator begin() const { return kShaderTypeMin; } + angle::EnumIterator end() const { return kAfterShaderTypeMax; } +}; + +constexpr size_t kGraphicsShaderCount = static_cast(ShaderType::EnumCount) - 1u; +// Arrange the shader types in the order of rendering pipeline +constexpr std::array kAllGraphicsShaderTypes = { + ShaderType::Vertex, ShaderType::TessControl, ShaderType::TessEvaluation, ShaderType::Geometry, + ShaderType::Fragment}; + +using ShaderBitSet = angle::PackedEnumBitSet; +static_assert(sizeof(ShaderBitSet) == sizeof(uint8_t), "Unexpected size"); + +template +using ShaderMap = angle::PackedEnumMap; + +const char *ShaderTypeToString(ShaderType shaderType); + +TextureType SamplerTypeToTextureType(GLenum samplerType); +TextureType ImageTypeToTextureType(GLenum imageType); + +bool IsMultisampled(gl::TextureType type); +bool IsArrayTextureType(gl::TextureType type); + +bool IsStaticBufferUsage(BufferUsage useage); + +enum class PrimitiveMode : uint8_t +{ + Points = 0x0, + Lines = 0x1, + LineLoop = 0x2, + LineStrip = 0x3, + Triangles = 0x4, + TriangleStrip = 0x5, + TriangleFan = 0x6, + Unused1 = 0x7, + Unused2 = 0x8, + Unused3 = 0x9, + LinesAdjacency = 0xA, + LineStripAdjacency = 0xB, + TrianglesAdjacency = 0xC, + TriangleStripAdjacency = 0xD, + Patches = 0xE, + + InvalidEnum = 0xF, + EnumCount = 0xF, +}; + +template <> +constexpr PrimitiveMode FromGLenum(GLenum from) +{ + if (from >= static_cast(PrimitiveMode::EnumCount)) + { + return PrimitiveMode::InvalidEnum; + } + + return static_cast(from); +} + +constexpr GLenum ToGLenum(PrimitiveMode from) +{ + return static_cast(from); +} + +static_assert(ToGLenum(PrimitiveMode::Points) == GL_POINTS, "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::Lines) == GL_LINES, "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::LineLoop) == GL_LINE_LOOP, "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::LineStrip) == GL_LINE_STRIP, "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::Triangles) == GL_TRIANGLES, "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::TriangleStrip) == GL_TRIANGLE_STRIP, + "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::TriangleFan) == GL_TRIANGLE_FAN, "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::LinesAdjacency) == GL_LINES_ADJACENCY, + "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::LineStripAdjacency) == GL_LINE_STRIP_ADJACENCY, + "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::TrianglesAdjacency) == GL_TRIANGLES_ADJACENCY, + "PrimitiveMode violation"); +static_assert(ToGLenum(PrimitiveMode::TriangleStripAdjacency) == GL_TRIANGLE_STRIP_ADJACENCY, + "PrimitiveMode violation"); + +std::ostream &operator<<(std::ostream &os, PrimitiveMode value); + +enum class DrawElementsType : size_t +{ + UnsignedByte = 0, + UnsignedShort = 1, + UnsignedInt = 2, + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +constexpr DrawElementsType FromGLenum(GLenum from) +{ + + GLenum scaled = (from - GL_UNSIGNED_BYTE); + // This code sequence generates a ROR instruction on x86/arm. We want to check if the lowest bit + // of scaled is set and if (scaled >> 1) is greater than a non-pot value. If we rotate the + // lowest bit to the hightest bit both conditions can be checked with a single test. + static_assert(sizeof(GLenum) == 4, "Update (scaled << 31) to sizeof(GLenum) * 8 - 1"); + GLenum packed = (scaled >> 1) | (scaled << 31); + + // operator ? with a simple assignment usually translates to a cmov instruction and thus avoids + // a branch. + packed = (packed >= static_cast(DrawElementsType::EnumCount)) + ? static_cast(DrawElementsType::InvalidEnum) + : packed; + + return static_cast(packed); +} + +constexpr GLenum ToGLenum(DrawElementsType from) +{ + return ((static_cast(from) << 1) + GL_UNSIGNED_BYTE); +} + +#define ANGLE_VALIDATE_PACKED_ENUM(type, packed, glenum) \ + static_assert(ToGLenum(type::packed) == glenum, #type " violation"); \ + static_assert(FromGLenum(glenum) == type::packed, #type " violation") + +ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedByte, GL_UNSIGNED_BYTE); +ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedShort, GL_UNSIGNED_SHORT); +ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedInt, GL_UNSIGNED_INT); + +std::ostream &operator<<(std::ostream &os, DrawElementsType value); + +enum class BlendEquationType +{ + Add = 0, // GLenum == 0x8006 + Min = 1, // GLenum == 0x8007 + Max = 2, // GLenum == 0x8008 + Unused = 3, + Subtract = 4, // GLenum == 0x800A + ReverseSubtract = 5, // GLenum == 0x800B + + Multiply = 6, // GLenum == 0x9294 + Screen = 7, // GLenum == 0x9295 + Overlay = 8, // GLenum == 0x9296 + Darken = 9, // GLenum == 0x9297 + Lighten = 10, // GLenum == 0x9298 + Colordodge = 11, // GLenum == 0x9299 + Colorburn = 12, // GLenum == 0x929A + Hardlight = 13, // GLenum == 0x929B + Softlight = 14, // GLenum == 0x929C + Unused2 = 15, + Difference = 16, // GLenum == 0x929E + Unused3 = 17, + Exclusion = 18, // GLenum == 0x92A0 + + HslHue = 19, // GLenum == 0x92AD + HslSaturation = 20, // GLenum == 0x92AE + HslColor = 21, // GLenum == 0x92AF + HslLuminosity = 22, // GLenum == 0x92B0 + + InvalidEnum = 23, + EnumCount = InvalidEnum +}; + +using BlendEquationBitSet = angle::PackedEnumBitSet; + +template <> +constexpr BlendEquationType FromGLenum(GLenum from) +{ + if (from <= GL_FUNC_REVERSE_SUBTRACT) + { + const GLenum scaled = (from - GL_FUNC_ADD); + return (scaled == static_cast(BlendEquationType::Unused)) + ? BlendEquationType::InvalidEnum + : static_cast(scaled); + } + if (from <= GL_EXCLUSION_KHR) + { + const GLenum scaled = + (from - GL_MULTIPLY_KHR + static_cast(BlendEquationType::Multiply)); + return (scaled == static_cast(BlendEquationType::Unused2) || + scaled == static_cast(BlendEquationType::Unused3)) + ? BlendEquationType::InvalidEnum + : static_cast(scaled); + } + if (from <= GL_HSL_LUMINOSITY_KHR) + { + return static_cast(from - GL_HSL_HUE_KHR + + static_cast(BlendEquationType::HslHue)); + } + return BlendEquationType::InvalidEnum; +} + +constexpr GLenum ToGLenum(BlendEquationType from) +{ + if (from <= BlendEquationType::ReverseSubtract) + { + return static_cast(from) + GL_FUNC_ADD; + } + if (from <= BlendEquationType::Exclusion) + { + return static_cast(from) - static_cast(BlendEquationType::Multiply) + + GL_MULTIPLY_KHR; + } + return static_cast(from) - static_cast(BlendEquationType::HslHue) + + GL_HSL_HUE_KHR; +} + +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Add, GL_FUNC_ADD); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Min, GL_MIN); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Max, GL_MAX); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Subtract, GL_FUNC_SUBTRACT); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, ReverseSubtract, GL_FUNC_REVERSE_SUBTRACT); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Multiply, GL_MULTIPLY_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Screen, GL_SCREEN_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Overlay, GL_OVERLAY_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Darken, GL_DARKEN_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Lighten, GL_LIGHTEN_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Colordodge, GL_COLORDODGE_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Colorburn, GL_COLORBURN_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Hardlight, GL_HARDLIGHT_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Softlight, GL_SOFTLIGHT_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Difference, GL_DIFFERENCE_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Exclusion, GL_EXCLUSION_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslHue, GL_HSL_HUE_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslSaturation, GL_HSL_SATURATION_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslColor, GL_HSL_COLOR_KHR); +ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslLuminosity, GL_HSL_LUMINOSITY_KHR); + +std::ostream &operator<<(std::ostream &os, BlendEquationType value); + +enum class BlendFactorType +{ + Zero = 0, // GLenum == 0 + One = 1, // GLenum == 1 + + MinSrcDstType = 2, + SrcColor = 2, // GLenum == 0x0300 + OneMinusSrcColor = 3, // GLenum == 0x0301 + SrcAlpha = 4, // GLenum == 0x0302 + OneMinusSrcAlpha = 5, // GLenum == 0x0303 + DstAlpha = 6, // GLenum == 0x0304 + OneMinusDstAlpha = 7, // GLenum == 0x0305 + DstColor = 8, // GLenum == 0x0306 + OneMinusDstColor = 9, // GLenum == 0x0307 + SrcAlphaSaturate = 10, // GLenum == 0x0308 + MaxSrcDstType = 10, + + MinConstantType = 11, + ConstantColor = 11, // GLenum == 0x8001 + OneMinusConstantColor = 12, // GLenum == 0x8002 + ConstantAlpha = 13, // GLenum == 0x8003 + OneMinusConstantAlpha = 14, // GLenum == 0x8004 + MaxConstantType = 14, + + // GL_EXT_blend_func_extended + + Src1Alpha = 15, // GLenum == 0x8589 + + Src1Color = 16, // GLenum == 0x88F9 + OneMinusSrc1Color = 17, // GLenum == 0x88FA + OneMinusSrc1Alpha = 18, // GLenum == 0x88FB + + InvalidEnum = 19, + EnumCount = 19 +}; + +template <> +constexpr BlendFactorType FromGLenum(GLenum from) +{ + if (from <= 1) + return static_cast(from); + if (from >= GL_SRC_COLOR && from <= GL_SRC_ALPHA_SATURATE) + return static_cast(from - GL_SRC_COLOR + 2); + if (from >= GL_CONSTANT_COLOR && from <= GL_ONE_MINUS_CONSTANT_ALPHA) + return static_cast(from - GL_CONSTANT_COLOR + 11); + if (from == GL_SRC1_ALPHA_EXT) + return BlendFactorType::Src1Alpha; + if (from >= GL_SRC1_COLOR_EXT && from <= GL_ONE_MINUS_SRC1_ALPHA_EXT) + return static_cast(from - GL_SRC1_COLOR_EXT + 16); + return BlendFactorType::InvalidEnum; +} + +constexpr GLenum ToGLenum(BlendFactorType from) +{ + const GLenum value = static_cast(from); + if (value <= 1) + return value; + if (from >= BlendFactorType::MinSrcDstType && from <= BlendFactorType::MaxSrcDstType) + return value - 2 + GL_SRC_COLOR; + if (from >= BlendFactorType::MinConstantType && from <= BlendFactorType::MaxConstantType) + return value - 11 + GL_CONSTANT_COLOR; + if (from == BlendFactorType::Src1Alpha) + return GL_SRC1_ALPHA_EXT; + return value - 16 + GL_SRC1_COLOR_EXT; +} + +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Zero, GL_ZERO); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, One, GL_ONE); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcColor, GL_SRC_COLOR); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcColor, GL_ONE_MINUS_SRC_COLOR); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlpha, GL_SRC_ALPHA); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcAlpha, GL_ONE_MINUS_SRC_ALPHA); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstAlpha, GL_DST_ALPHA); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstAlpha, GL_ONE_MINUS_DST_ALPHA); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstColor, GL_DST_COLOR); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstColor, GL_ONE_MINUS_DST_COLOR); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlphaSaturate, GL_SRC_ALPHA_SATURATE); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantColor, GL_CONSTANT_COLOR); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantColor, GL_ONE_MINUS_CONSTANT_COLOR); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantAlpha, GL_CONSTANT_ALPHA); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantAlpha, GL_ONE_MINUS_CONSTANT_ALPHA); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Alpha, GL_SRC1_ALPHA_EXT); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Color, GL_SRC1_COLOR_EXT); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Color, GL_ONE_MINUS_SRC1_COLOR_EXT); +ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Alpha, GL_ONE_MINUS_SRC1_ALPHA_EXT); + +std::ostream &operator<<(std::ostream &os, BlendFactorType value); + +enum class VertexAttribType +{ + Byte = 0, // GLenum == 0x1400 + UnsignedByte = 1, // GLenum == 0x1401 + Short = 2, // GLenum == 0x1402 + UnsignedShort = 3, // GLenum == 0x1403 + Int = 4, // GLenum == 0x1404 + UnsignedInt = 5, // GLenum == 0x1405 + Float = 6, // GLenum == 0x1406 + Unused1 = 7, // GLenum == 0x1407 + Unused2 = 8, // GLenum == 0x1408 + Unused3 = 9, // GLenum == 0x1409 + Unused4 = 10, // GLenum == 0x140A + HalfFloat = 11, // GLenum == 0x140B + Fixed = 12, // GLenum == 0x140C + MaxBasicType = 12, + UnsignedInt2101010 = 13, // GLenum == 0x8368 + HalfFloatOES = 14, // GLenum == 0x8D61 + Int2101010 = 15, // GLenum == 0x8D9F + UnsignedInt1010102 = 16, // GLenum == 0x8DF6 + Int1010102 = 17, // GLenum == 0x8DF7 + InvalidEnum = 18, + EnumCount = 18, +}; + +template <> +constexpr VertexAttribType FromGLenum(GLenum from) +{ + GLenum packed = from - GL_BYTE; + if (packed <= static_cast(VertexAttribType::MaxBasicType)) + return static_cast(packed); + if (from == GL_UNSIGNED_INT_2_10_10_10_REV) + return VertexAttribType::UnsignedInt2101010; + if (from == GL_HALF_FLOAT_OES) + return VertexAttribType::HalfFloatOES; + if (from == GL_INT_2_10_10_10_REV) + return VertexAttribType::Int2101010; + if (from == GL_UNSIGNED_INT_10_10_10_2_OES) + return VertexAttribType::UnsignedInt1010102; + if (from == GL_INT_10_10_10_2_OES) + return VertexAttribType::Int1010102; + return VertexAttribType::InvalidEnum; +} + +constexpr GLenum ToGLenum(VertexAttribType from) +{ + // This could be optimized using a constexpr table. + if (from == VertexAttribType::Int2101010) + return GL_INT_2_10_10_10_REV; + if (from == VertexAttribType::HalfFloatOES) + return GL_HALF_FLOAT_OES; + if (from == VertexAttribType::UnsignedInt2101010) + return GL_UNSIGNED_INT_2_10_10_10_REV; + if (from == VertexAttribType::UnsignedInt1010102) + return GL_UNSIGNED_INT_10_10_10_2_OES; + if (from == VertexAttribType::Int1010102) + return GL_INT_10_10_10_2_OES; + return static_cast(from) + GL_BYTE; +} + +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Byte, GL_BYTE); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedByte, GL_UNSIGNED_BYTE); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Short, GL_SHORT); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedShort, GL_UNSIGNED_SHORT); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int, GL_INT); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt, GL_UNSIGNED_INT); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Float, GL_FLOAT); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloat, GL_HALF_FLOAT); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Fixed, GL_FIXED); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int2101010, GL_INT_2_10_10_10_REV); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloatOES, GL_HALF_FLOAT_OES); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt2101010, GL_UNSIGNED_INT_2_10_10_10_REV); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int1010102, GL_INT_10_10_10_2_OES); +ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt1010102, GL_UNSIGNED_INT_10_10_10_2_OES); + +std::ostream &operator<<(std::ostream &os, VertexAttribType value); + +enum class TessEvaluationType +{ + Triangles = 0, + Quads = 1, + Isolines = 2, + EqualSpacing = 3, + FractionalEvenSpacing = 4, + FractionalOddSpacing = 5, + Cw = 6, + Ccw = 7, + PointMode = 8, + InvalidEnum = 9, + EnumCount = 9 +}; + +template <> +constexpr TessEvaluationType FromGLenum(GLenum from) +{ + if (from == GL_TRIANGLES) + return TessEvaluationType::Triangles; + if (from == GL_QUADS) + return TessEvaluationType::Quads; + if (from == GL_ISOLINES) + return TessEvaluationType::Isolines; + if (from == GL_EQUAL) + return TessEvaluationType::EqualSpacing; + if (from == GL_FRACTIONAL_EVEN) + return TessEvaluationType::FractionalEvenSpacing; + if (from == GL_FRACTIONAL_ODD) + return TessEvaluationType::FractionalOddSpacing; + if (from == GL_CW) + return TessEvaluationType::Cw; + if (from == GL_CCW) + return TessEvaluationType::Ccw; + if (from == GL_TESS_GEN_POINT_MODE) + return TessEvaluationType::PointMode; + return TessEvaluationType::InvalidEnum; +} + +constexpr GLenum ToGLenum(TessEvaluationType from) +{ + switch (from) + { + case TessEvaluationType::Triangles: + return GL_TRIANGLES; + case TessEvaluationType::Quads: + return GL_QUADS; + case TessEvaluationType::Isolines: + return GL_ISOLINES; + case TessEvaluationType::EqualSpacing: + return GL_EQUAL; + case TessEvaluationType::FractionalEvenSpacing: + return GL_FRACTIONAL_EVEN; + case TessEvaluationType::FractionalOddSpacing: + return GL_FRACTIONAL_ODD; + case TessEvaluationType::Cw: + return GL_CW; + case TessEvaluationType::Ccw: + return GL_CCW; + case TessEvaluationType::PointMode: + return GL_TESS_GEN_POINT_MODE; + default: + return GL_INVALID_ENUM; + } +} + +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Triangles, GL_TRIANGLES); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Quads, GL_QUADS); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Isolines, GL_ISOLINES); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, EqualSpacing, GL_EQUAL); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalEvenSpacing, GL_FRACTIONAL_EVEN); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalOddSpacing, GL_FRACTIONAL_ODD); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Cw, GL_CW); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Ccw, GL_CCW); +ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, PointMode, GL_TESS_GEN_POINT_MODE); + +std::ostream &operator<<(std::ostream &os, TessEvaluationType value); + +// Typesafe object handles. + +template +struct ResourceTypeToID; + +template +struct IsResourceIDType; + +// Clang Format doesn't like the following X macro. +// clang-format off +#define ANGLE_ID_TYPES_OP(X) \ + X(Buffer) \ + X(FenceNV) \ + X(Framebuffer) \ + X(MemoryObject) \ + X(Path) \ + X(ProgramPipeline) \ + X(Query) \ + X(Renderbuffer) \ + X(Sampler) \ + X(Semaphore) \ + X(Texture) \ + X(TransformFeedback) \ + X(VertexArray) +// clang-format on + +#define ANGLE_DEFINE_ID_TYPE(Type) \ + class Type; \ + struct Type##ID \ + { \ + GLuint value; \ + }; \ + template <> \ + struct ResourceTypeToID \ + { \ + using IDType = Type##ID; \ + }; \ + template <> \ + struct IsResourceIDType \ + { \ + static constexpr bool value = true; \ + }; + +ANGLE_ID_TYPES_OP(ANGLE_DEFINE_ID_TYPE) + +#undef ANGLE_DEFINE_ID_TYPE +#undef ANGLE_ID_TYPES_OP + +// Shaders and programs are a bit special as they share IDs. +struct ShaderProgramID +{ + GLuint value; +}; + +template <> +struct IsResourceIDType +{ + constexpr static bool value = true; +}; + +class Shader; +template <> +struct ResourceTypeToID +{ + using IDType = ShaderProgramID; +}; + +class Program; +template <> +struct ResourceTypeToID +{ + using IDType = ShaderProgramID; +}; + +template +struct ResourceTypeToID +{ + using IDType = void; +}; + +template +struct IsResourceIDType +{ + static constexpr bool value = false; +}; + +template +bool ValueEquals(T lhs, T rhs) +{ + return lhs.value == rhs.value; +} + +// Util funcs for resourceIDs +template +typename std::enable_if::value, bool>::type operator==(const T &lhs, + const T &rhs) +{ + return lhs.value == rhs.value; +} + +template +typename std::enable_if::value, bool>::type operator!=(const T &lhs, + const T &rhs) +{ + return lhs.value != rhs.value; +} + +template +typename std::enable_if::value, bool>::type operator<(const T &lhs, + const T &rhs) +{ + return lhs.value < rhs.value; +} + +// Used to unbox typed values. +template +GLuint GetIDValue(ResourceIDType id); + +template <> +inline GLuint GetIDValue(GLuint id) +{ + return id; +} + +template +inline GLuint GetIDValue(ResourceIDType id) +{ + return id.value; +} + +// First case: handling packed enums. +template +typename std::enable_if::value, EnumT>::type PackParam(FromT from) +{ + return FromGLenum(from); +} + +// Second case: handling non-pointer resource ids. +template +typename std::enable_if::value && !std::is_enum::value, EnumT>::type +PackParam(FromT from) +{ + return {from}; +} + +// Third case: handling pointer resource ids. +template +typename std::enable_if::value && !std::is_enum::value, EnumT>::type +PackParam(FromT from) +{ + static_assert(sizeof(typename std::remove_pointer::type) == + sizeof(typename std::remove_pointer::type), + "Types have different sizes"); + static_assert( + std::is_same< + decltype(std::remove_pointer::type::value), + typename std::remove_const::type>::type>::value, + "Data types are different"); + return reinterpret_cast(from); +} + +struct UniformLocation +{ + int value; +}; + +bool operator<(const UniformLocation &lhs, const UniformLocation &rhs); + +struct UniformBlockIndex +{ + uint32_t value; +}; + +bool IsEmulatedCompressedFormat(GLenum format); +} // namespace gl + +namespace egl +{ +MessageType ErrorCodeToMessageType(EGLint errorCode); +} // namespace egl + +namespace egl_gl +{ +gl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget); +gl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget); +gl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget); +} // namespace egl_gl + +#endif // COMMON_PACKEDGLENUMS_H_ diff --git a/gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp new file mode 100644 index 0000000000..d025b11a14 --- /dev/null +++ b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp @@ -0,0 +1,2449 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json. +// +// Copyright 2017 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. +// +// PackedGLEnums_autogen.cpp: +// Implements ANGLE-specific enums classes for GLenums and functions operating +// on them. + +#include "common/PackedGLEnums_autogen.h" +#include "common/debug.h" + +namespace gl +{ + +template <> +AlphaTestFunc FromGLenum(GLenum from) +{ + switch (from) + { + case GL_ALWAYS: + return AlphaTestFunc::AlwaysPass; + case GL_EQUAL: + return AlphaTestFunc::Equal; + case GL_GEQUAL: + return AlphaTestFunc::Gequal; + case GL_GREATER: + return AlphaTestFunc::Greater; + case GL_LEQUAL: + return AlphaTestFunc::Lequal; + case GL_LESS: + return AlphaTestFunc::Less; + case GL_NEVER: + return AlphaTestFunc::Never; + case GL_NOTEQUAL: + return AlphaTestFunc::NotEqual; + default: + return AlphaTestFunc::InvalidEnum; + } +} + +GLenum ToGLenum(AlphaTestFunc from) +{ + switch (from) + { + case AlphaTestFunc::AlwaysPass: + return GL_ALWAYS; + case AlphaTestFunc::Equal: + return GL_EQUAL; + case AlphaTestFunc::Gequal: + return GL_GEQUAL; + case AlphaTestFunc::Greater: + return GL_GREATER; + case AlphaTestFunc::Lequal: + return GL_LEQUAL; + case AlphaTestFunc::Less: + return GL_LESS; + case AlphaTestFunc::Never: + return GL_NEVER; + case AlphaTestFunc::NotEqual: + return GL_NOTEQUAL; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, AlphaTestFunc value) +{ + switch (value) + { + case AlphaTestFunc::AlwaysPass: + os << "GL_ALWAYS"; + break; + case AlphaTestFunc::Equal: + os << "GL_EQUAL"; + break; + case AlphaTestFunc::Gequal: + os << "GL_GEQUAL"; + break; + case AlphaTestFunc::Greater: + os << "GL_GREATER"; + break; + case AlphaTestFunc::Lequal: + os << "GL_LEQUAL"; + break; + case AlphaTestFunc::Less: + os << "GL_LESS"; + break; + case AlphaTestFunc::Never: + os << "GL_NEVER"; + break; + case AlphaTestFunc::NotEqual: + os << "GL_NOTEQUAL"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +BufferBinding FromGLenum(GLenum from) +{ + switch (from) + { + case GL_ARRAY_BUFFER: + return BufferBinding::Array; + case GL_ATOMIC_COUNTER_BUFFER: + return BufferBinding::AtomicCounter; + case GL_COPY_READ_BUFFER: + return BufferBinding::CopyRead; + case GL_COPY_WRITE_BUFFER: + return BufferBinding::CopyWrite; + case GL_DISPATCH_INDIRECT_BUFFER: + return BufferBinding::DispatchIndirect; + case GL_DRAW_INDIRECT_BUFFER: + return BufferBinding::DrawIndirect; + case GL_ELEMENT_ARRAY_BUFFER: + return BufferBinding::ElementArray; + case GL_PIXEL_PACK_BUFFER: + return BufferBinding::PixelPack; + case GL_PIXEL_UNPACK_BUFFER: + return BufferBinding::PixelUnpack; + case GL_SHADER_STORAGE_BUFFER: + return BufferBinding::ShaderStorage; + case GL_TEXTURE_BUFFER: + return BufferBinding::Texture; + case GL_TRANSFORM_FEEDBACK_BUFFER: + return BufferBinding::TransformFeedback; + case GL_UNIFORM_BUFFER: + return BufferBinding::Uniform; + default: + return BufferBinding::InvalidEnum; + } +} + +GLenum ToGLenum(BufferBinding from) +{ + switch (from) + { + case BufferBinding::Array: + return GL_ARRAY_BUFFER; + case BufferBinding::AtomicCounter: + return GL_ATOMIC_COUNTER_BUFFER; + case BufferBinding::CopyRead: + return GL_COPY_READ_BUFFER; + case BufferBinding::CopyWrite: + return GL_COPY_WRITE_BUFFER; + case BufferBinding::DispatchIndirect: + return GL_DISPATCH_INDIRECT_BUFFER; + case BufferBinding::DrawIndirect: + return GL_DRAW_INDIRECT_BUFFER; + case BufferBinding::ElementArray: + return GL_ELEMENT_ARRAY_BUFFER; + case BufferBinding::PixelPack: + return GL_PIXEL_PACK_BUFFER; + case BufferBinding::PixelUnpack: + return GL_PIXEL_UNPACK_BUFFER; + case BufferBinding::ShaderStorage: + return GL_SHADER_STORAGE_BUFFER; + case BufferBinding::Texture: + return GL_TEXTURE_BUFFER; + case BufferBinding::TransformFeedback: + return GL_TRANSFORM_FEEDBACK_BUFFER; + case BufferBinding::Uniform: + return GL_UNIFORM_BUFFER; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, BufferBinding value) +{ + switch (value) + { + case BufferBinding::Array: + os << "GL_ARRAY_BUFFER"; + break; + case BufferBinding::AtomicCounter: + os << "GL_ATOMIC_COUNTER_BUFFER"; + break; + case BufferBinding::CopyRead: + os << "GL_COPY_READ_BUFFER"; + break; + case BufferBinding::CopyWrite: + os << "GL_COPY_WRITE_BUFFER"; + break; + case BufferBinding::DispatchIndirect: + os << "GL_DISPATCH_INDIRECT_BUFFER"; + break; + case BufferBinding::DrawIndirect: + os << "GL_DRAW_INDIRECT_BUFFER"; + break; + case BufferBinding::ElementArray: + os << "GL_ELEMENT_ARRAY_BUFFER"; + break; + case BufferBinding::PixelPack: + os << "GL_PIXEL_PACK_BUFFER"; + break; + case BufferBinding::PixelUnpack: + os << "GL_PIXEL_UNPACK_BUFFER"; + break; + case BufferBinding::ShaderStorage: + os << "GL_SHADER_STORAGE_BUFFER"; + break; + case BufferBinding::Texture: + os << "GL_TEXTURE_BUFFER"; + break; + case BufferBinding::TransformFeedback: + os << "GL_TRANSFORM_FEEDBACK_BUFFER"; + break; + case BufferBinding::Uniform: + os << "GL_UNIFORM_BUFFER"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +BufferUsage FromGLenum(GLenum from) +{ + switch (from) + { + case GL_DYNAMIC_COPY: + return BufferUsage::DynamicCopy; + case GL_DYNAMIC_DRAW: + return BufferUsage::DynamicDraw; + case GL_DYNAMIC_READ: + return BufferUsage::DynamicRead; + case GL_STATIC_COPY: + return BufferUsage::StaticCopy; + case GL_STATIC_DRAW: + return BufferUsage::StaticDraw; + case GL_STATIC_READ: + return BufferUsage::StaticRead; + case GL_STREAM_COPY: + return BufferUsage::StreamCopy; + case GL_STREAM_DRAW: + return BufferUsage::StreamDraw; + case GL_STREAM_READ: + return BufferUsage::StreamRead; + default: + return BufferUsage::InvalidEnum; + } +} + +GLenum ToGLenum(BufferUsage from) +{ + switch (from) + { + case BufferUsage::DynamicCopy: + return GL_DYNAMIC_COPY; + case BufferUsage::DynamicDraw: + return GL_DYNAMIC_DRAW; + case BufferUsage::DynamicRead: + return GL_DYNAMIC_READ; + case BufferUsage::StaticCopy: + return GL_STATIC_COPY; + case BufferUsage::StaticDraw: + return GL_STATIC_DRAW; + case BufferUsage::StaticRead: + return GL_STATIC_READ; + case BufferUsage::StreamCopy: + return GL_STREAM_COPY; + case BufferUsage::StreamDraw: + return GL_STREAM_DRAW; + case BufferUsage::StreamRead: + return GL_STREAM_READ; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, BufferUsage value) +{ + switch (value) + { + case BufferUsage::DynamicCopy: + os << "GL_DYNAMIC_COPY"; + break; + case BufferUsage::DynamicDraw: + os << "GL_DYNAMIC_DRAW"; + break; + case BufferUsage::DynamicRead: + os << "GL_DYNAMIC_READ"; + break; + case BufferUsage::StaticCopy: + os << "GL_STATIC_COPY"; + break; + case BufferUsage::StaticDraw: + os << "GL_STATIC_DRAW"; + break; + case BufferUsage::StaticRead: + os << "GL_STATIC_READ"; + break; + case BufferUsage::StreamCopy: + os << "GL_STREAM_COPY"; + break; + case BufferUsage::StreamDraw: + os << "GL_STREAM_DRAW"; + break; + case BufferUsage::StreamRead: + os << "GL_STREAM_READ"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ClientVertexArrayType FromGLenum(GLenum from) +{ + switch (from) + { + case GL_COLOR_ARRAY: + return ClientVertexArrayType::Color; + case GL_NORMAL_ARRAY: + return ClientVertexArrayType::Normal; + case GL_POINT_SIZE_ARRAY_OES: + return ClientVertexArrayType::PointSize; + case GL_TEXTURE_COORD_ARRAY: + return ClientVertexArrayType::TextureCoord; + case GL_VERTEX_ARRAY: + return ClientVertexArrayType::Vertex; + default: + return ClientVertexArrayType::InvalidEnum; + } +} + +GLenum ToGLenum(ClientVertexArrayType from) +{ + switch (from) + { + case ClientVertexArrayType::Color: + return GL_COLOR_ARRAY; + case ClientVertexArrayType::Normal: + return GL_NORMAL_ARRAY; + case ClientVertexArrayType::PointSize: + return GL_POINT_SIZE_ARRAY_OES; + case ClientVertexArrayType::TextureCoord: + return GL_TEXTURE_COORD_ARRAY; + case ClientVertexArrayType::Vertex: + return GL_VERTEX_ARRAY; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ClientVertexArrayType value) +{ + switch (value) + { + case ClientVertexArrayType::Color: + os << "GL_COLOR_ARRAY"; + break; + case ClientVertexArrayType::Normal: + os << "GL_NORMAL_ARRAY"; + break; + case ClientVertexArrayType::PointSize: + os << "GL_POINT_SIZE_ARRAY_OES"; + break; + case ClientVertexArrayType::TextureCoord: + os << "GL_TEXTURE_COORD_ARRAY"; + break; + case ClientVertexArrayType::Vertex: + os << "GL_VERTEX_ARRAY"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +CullFaceMode FromGLenum(GLenum from) +{ + switch (from) + { + case GL_BACK: + return CullFaceMode::Back; + case GL_FRONT: + return CullFaceMode::Front; + case GL_FRONT_AND_BACK: + return CullFaceMode::FrontAndBack; + default: + return CullFaceMode::InvalidEnum; + } +} + +GLenum ToGLenum(CullFaceMode from) +{ + switch (from) + { + case CullFaceMode::Back: + return GL_BACK; + case CullFaceMode::Front: + return GL_FRONT; + case CullFaceMode::FrontAndBack: + return GL_FRONT_AND_BACK; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, CullFaceMode value) +{ + switch (value) + { + case CullFaceMode::Back: + os << "GL_BACK"; + break; + case CullFaceMode::Front: + os << "GL_FRONT"; + break; + case CullFaceMode::FrontAndBack: + os << "GL_FRONT_AND_BACK"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +FilterMode FromGLenum(GLenum from) +{ + switch (from) + { + case GL_NEAREST: + return FilterMode::Nearest; + case GL_LINEAR: + return FilterMode::Linear; + case GL_NEAREST_MIPMAP_NEAREST: + return FilterMode::NearestMipmapNearest; + case GL_NEAREST_MIPMAP_LINEAR: + return FilterMode::NearestMipmapLinear; + case GL_LINEAR_MIPMAP_LINEAR: + return FilterMode::LinearMipmapLinear; + default: + return FilterMode::InvalidEnum; + } +} + +GLenum ToGLenum(FilterMode from) +{ + switch (from) + { + case FilterMode::Nearest: + return GL_NEAREST; + case FilterMode::Linear: + return GL_LINEAR; + case FilterMode::NearestMipmapNearest: + return GL_NEAREST_MIPMAP_NEAREST; + case FilterMode::NearestMipmapLinear: + return GL_NEAREST_MIPMAP_LINEAR; + case FilterMode::LinearMipmapLinear: + return GL_LINEAR_MIPMAP_LINEAR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, FilterMode value) +{ + switch (value) + { + case FilterMode::Nearest: + os << "GL_NEAREST"; + break; + case FilterMode::Linear: + os << "GL_LINEAR"; + break; + case FilterMode::NearestMipmapNearest: + os << "GL_NEAREST_MIPMAP_NEAREST"; + break; + case FilterMode::NearestMipmapLinear: + os << "GL_NEAREST_MIPMAP_LINEAR"; + break; + case FilterMode::LinearMipmapLinear: + os << "GL_LINEAR_MIPMAP_LINEAR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +FogMode FromGLenum(GLenum from) +{ + switch (from) + { + case GL_EXP: + return FogMode::Exp; + case GL_EXP2: + return FogMode::Exp2; + case GL_LINEAR: + return FogMode::Linear; + default: + return FogMode::InvalidEnum; + } +} + +GLenum ToGLenum(FogMode from) +{ + switch (from) + { + case FogMode::Exp: + return GL_EXP; + case FogMode::Exp2: + return GL_EXP2; + case FogMode::Linear: + return GL_LINEAR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, FogMode value) +{ + switch (value) + { + case FogMode::Exp: + os << "GL_EXP"; + break; + case FogMode::Exp2: + os << "GL_EXP2"; + break; + case FogMode::Linear: + os << "GL_LINEAR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +GraphicsResetStatus FromGLenum(GLenum from) +{ + switch (from) + { + case GL_NO_ERROR: + return GraphicsResetStatus::NoError; + case GL_GUILTY_CONTEXT_RESET: + return GraphicsResetStatus::GuiltyContextReset; + case GL_INNOCENT_CONTEXT_RESET: + return GraphicsResetStatus::InnocentContextReset; + case GL_UNKNOWN_CONTEXT_RESET: + return GraphicsResetStatus::UnknownContextReset; + case GL_PURGED_CONTEXT_RESET_NV: + return GraphicsResetStatus::PurgedContextResetNV; + default: + return GraphicsResetStatus::InvalidEnum; + } +} + +GLenum ToGLenum(GraphicsResetStatus from) +{ + switch (from) + { + case GraphicsResetStatus::NoError: + return GL_NO_ERROR; + case GraphicsResetStatus::GuiltyContextReset: + return GL_GUILTY_CONTEXT_RESET; + case GraphicsResetStatus::InnocentContextReset: + return GL_INNOCENT_CONTEXT_RESET; + case GraphicsResetStatus::UnknownContextReset: + return GL_UNKNOWN_CONTEXT_RESET; + case GraphicsResetStatus::PurgedContextResetNV: + return GL_PURGED_CONTEXT_RESET_NV; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, GraphicsResetStatus value) +{ + switch (value) + { + case GraphicsResetStatus::NoError: + os << "GL_NO_ERROR"; + break; + case GraphicsResetStatus::GuiltyContextReset: + os << "GL_GUILTY_CONTEXT_RESET"; + break; + case GraphicsResetStatus::InnocentContextReset: + os << "GL_INNOCENT_CONTEXT_RESET"; + break; + case GraphicsResetStatus::UnknownContextReset: + os << "GL_UNKNOWN_CONTEXT_RESET"; + break; + case GraphicsResetStatus::PurgedContextResetNV: + os << "GL_PURGED_CONTEXT_RESET_NV"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +HandleType FromGLenum(GLenum from) +{ + switch (from) + { + case GL_HANDLE_TYPE_OPAQUE_FD_EXT: + return HandleType::OpaqueFd; + case GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE: + return HandleType::ZirconVmo; + case GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE: + return HandleType::ZirconEvent; + default: + return HandleType::InvalidEnum; + } +} + +GLenum ToGLenum(HandleType from) +{ + switch (from) + { + case HandleType::OpaqueFd: + return GL_HANDLE_TYPE_OPAQUE_FD_EXT; + case HandleType::ZirconVmo: + return GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE; + case HandleType::ZirconEvent: + return GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, HandleType value) +{ + switch (value) + { + case HandleType::OpaqueFd: + os << "GL_HANDLE_TYPE_OPAQUE_FD_EXT"; + break; + case HandleType::ZirconVmo: + os << "GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE"; + break; + case HandleType::ZirconEvent: + os << "GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +HintSetting FromGLenum(GLenum from) +{ + switch (from) + { + case GL_DONT_CARE: + return HintSetting::DontCare; + case GL_FASTEST: + return HintSetting::Fastest; + case GL_NICEST: + return HintSetting::Nicest; + default: + return HintSetting::InvalidEnum; + } +} + +GLenum ToGLenum(HintSetting from) +{ + switch (from) + { + case HintSetting::DontCare: + return GL_DONT_CARE; + case HintSetting::Fastest: + return GL_FASTEST; + case HintSetting::Nicest: + return GL_NICEST; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, HintSetting value) +{ + switch (value) + { + case HintSetting::DontCare: + os << "GL_DONT_CARE"; + break; + case HintSetting::Fastest: + os << "GL_FASTEST"; + break; + case HintSetting::Nicest: + os << "GL_NICEST"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ImageLayout FromGLenum(GLenum from) +{ + switch (from) + { + case GL_NONE: + return ImageLayout::Undefined; + case GL_LAYOUT_GENERAL_EXT: + return ImageLayout::General; + case GL_LAYOUT_COLOR_ATTACHMENT_EXT: + return ImageLayout::ColorAttachment; + case GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT: + return ImageLayout::DepthStencilAttachment; + case GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT: + return ImageLayout::DepthStencilReadOnlyAttachment; + case GL_LAYOUT_SHADER_READ_ONLY_EXT: + return ImageLayout::ShaderReadOnly; + case GL_LAYOUT_TRANSFER_SRC_EXT: + return ImageLayout::TransferSrc; + case GL_LAYOUT_TRANSFER_DST_EXT: + return ImageLayout::TransferDst; + case GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT: + return ImageLayout::DepthReadOnlyStencilAttachment; + case GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT: + return ImageLayout::DepthAttachmentStencilReadOnly; + default: + return ImageLayout::InvalidEnum; + } +} + +GLenum ToGLenum(ImageLayout from) +{ + switch (from) + { + case ImageLayout::Undefined: + return GL_NONE; + case ImageLayout::General: + return GL_LAYOUT_GENERAL_EXT; + case ImageLayout::ColorAttachment: + return GL_LAYOUT_COLOR_ATTACHMENT_EXT; + case ImageLayout::DepthStencilAttachment: + return GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT; + case ImageLayout::DepthStencilReadOnlyAttachment: + return GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT; + case ImageLayout::ShaderReadOnly: + return GL_LAYOUT_SHADER_READ_ONLY_EXT; + case ImageLayout::TransferSrc: + return GL_LAYOUT_TRANSFER_SRC_EXT; + case ImageLayout::TransferDst: + return GL_LAYOUT_TRANSFER_DST_EXT; + case ImageLayout::DepthReadOnlyStencilAttachment: + return GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT; + case ImageLayout::DepthAttachmentStencilReadOnly: + return GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ImageLayout value) +{ + switch (value) + { + case ImageLayout::Undefined: + os << "GL_NONE"; + break; + case ImageLayout::General: + os << "GL_LAYOUT_GENERAL_EXT"; + break; + case ImageLayout::ColorAttachment: + os << "GL_LAYOUT_COLOR_ATTACHMENT_EXT"; + break; + case ImageLayout::DepthStencilAttachment: + os << "GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT"; + break; + case ImageLayout::DepthStencilReadOnlyAttachment: + os << "GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT"; + break; + case ImageLayout::ShaderReadOnly: + os << "GL_LAYOUT_SHADER_READ_ONLY_EXT"; + break; + case ImageLayout::TransferSrc: + os << "GL_LAYOUT_TRANSFER_SRC_EXT"; + break; + case ImageLayout::TransferDst: + os << "GL_LAYOUT_TRANSFER_DST_EXT"; + break; + case ImageLayout::DepthReadOnlyStencilAttachment: + os << "GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT"; + break; + case ImageLayout::DepthAttachmentStencilReadOnly: + os << "GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +LightParameter FromGLenum(GLenum from) +{ + switch (from) + { + case GL_AMBIENT: + return LightParameter::Ambient; + case GL_AMBIENT_AND_DIFFUSE: + return LightParameter::AmbientAndDiffuse; + case GL_CONSTANT_ATTENUATION: + return LightParameter::ConstantAttenuation; + case GL_DIFFUSE: + return LightParameter::Diffuse; + case GL_LINEAR_ATTENUATION: + return LightParameter::LinearAttenuation; + case GL_POSITION: + return LightParameter::Position; + case GL_QUADRATIC_ATTENUATION: + return LightParameter::QuadraticAttenuation; + case GL_SPECULAR: + return LightParameter::Specular; + case GL_SPOT_CUTOFF: + return LightParameter::SpotCutoff; + case GL_SPOT_DIRECTION: + return LightParameter::SpotDirection; + case GL_SPOT_EXPONENT: + return LightParameter::SpotExponent; + default: + return LightParameter::InvalidEnum; + } +} + +GLenum ToGLenum(LightParameter from) +{ + switch (from) + { + case LightParameter::Ambient: + return GL_AMBIENT; + case LightParameter::AmbientAndDiffuse: + return GL_AMBIENT_AND_DIFFUSE; + case LightParameter::ConstantAttenuation: + return GL_CONSTANT_ATTENUATION; + case LightParameter::Diffuse: + return GL_DIFFUSE; + case LightParameter::LinearAttenuation: + return GL_LINEAR_ATTENUATION; + case LightParameter::Position: + return GL_POSITION; + case LightParameter::QuadraticAttenuation: + return GL_QUADRATIC_ATTENUATION; + case LightParameter::Specular: + return GL_SPECULAR; + case LightParameter::SpotCutoff: + return GL_SPOT_CUTOFF; + case LightParameter::SpotDirection: + return GL_SPOT_DIRECTION; + case LightParameter::SpotExponent: + return GL_SPOT_EXPONENT; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, LightParameter value) +{ + switch (value) + { + case LightParameter::Ambient: + os << "GL_AMBIENT"; + break; + case LightParameter::AmbientAndDiffuse: + os << "GL_AMBIENT_AND_DIFFUSE"; + break; + case LightParameter::ConstantAttenuation: + os << "GL_CONSTANT_ATTENUATION"; + break; + case LightParameter::Diffuse: + os << "GL_DIFFUSE"; + break; + case LightParameter::LinearAttenuation: + os << "GL_LINEAR_ATTENUATION"; + break; + case LightParameter::Position: + os << "GL_POSITION"; + break; + case LightParameter::QuadraticAttenuation: + os << "GL_QUADRATIC_ATTENUATION"; + break; + case LightParameter::Specular: + os << "GL_SPECULAR"; + break; + case LightParameter::SpotCutoff: + os << "GL_SPOT_CUTOFF"; + break; + case LightParameter::SpotDirection: + os << "GL_SPOT_DIRECTION"; + break; + case LightParameter::SpotExponent: + os << "GL_SPOT_EXPONENT"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +LogicalOperation FromGLenum(GLenum from) +{ + switch (from) + { + case GL_AND: + return LogicalOperation::And; + case GL_AND_INVERTED: + return LogicalOperation::AndInverted; + case GL_AND_REVERSE: + return LogicalOperation::AndReverse; + case GL_CLEAR: + return LogicalOperation::Clear; + case GL_COPY: + return LogicalOperation::Copy; + case GL_COPY_INVERTED: + return LogicalOperation::CopyInverted; + case GL_EQUIV: + return LogicalOperation::Equiv; + case GL_INVERT: + return LogicalOperation::Invert; + case GL_NAND: + return LogicalOperation::Nand; + case GL_NOOP: + return LogicalOperation::Noop; + case GL_NOR: + return LogicalOperation::Nor; + case GL_OR: + return LogicalOperation::Or; + case GL_OR_INVERTED: + return LogicalOperation::OrInverted; + case GL_OR_REVERSE: + return LogicalOperation::OrReverse; + case GL_SET: + return LogicalOperation::Set; + case GL_XOR: + return LogicalOperation::Xor; + default: + return LogicalOperation::InvalidEnum; + } +} + +GLenum ToGLenum(LogicalOperation from) +{ + switch (from) + { + case LogicalOperation::And: + return GL_AND; + case LogicalOperation::AndInverted: + return GL_AND_INVERTED; + case LogicalOperation::AndReverse: + return GL_AND_REVERSE; + case LogicalOperation::Clear: + return GL_CLEAR; + case LogicalOperation::Copy: + return GL_COPY; + case LogicalOperation::CopyInverted: + return GL_COPY_INVERTED; + case LogicalOperation::Equiv: + return GL_EQUIV; + case LogicalOperation::Invert: + return GL_INVERT; + case LogicalOperation::Nand: + return GL_NAND; + case LogicalOperation::Noop: + return GL_NOOP; + case LogicalOperation::Nor: + return GL_NOR; + case LogicalOperation::Or: + return GL_OR; + case LogicalOperation::OrInverted: + return GL_OR_INVERTED; + case LogicalOperation::OrReverse: + return GL_OR_REVERSE; + case LogicalOperation::Set: + return GL_SET; + case LogicalOperation::Xor: + return GL_XOR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, LogicalOperation value) +{ + switch (value) + { + case LogicalOperation::And: + os << "GL_AND"; + break; + case LogicalOperation::AndInverted: + os << "GL_AND_INVERTED"; + break; + case LogicalOperation::AndReverse: + os << "GL_AND_REVERSE"; + break; + case LogicalOperation::Clear: + os << "GL_CLEAR"; + break; + case LogicalOperation::Copy: + os << "GL_COPY"; + break; + case LogicalOperation::CopyInverted: + os << "GL_COPY_INVERTED"; + break; + case LogicalOperation::Equiv: + os << "GL_EQUIV"; + break; + case LogicalOperation::Invert: + os << "GL_INVERT"; + break; + case LogicalOperation::Nand: + os << "GL_NAND"; + break; + case LogicalOperation::Noop: + os << "GL_NOOP"; + break; + case LogicalOperation::Nor: + os << "GL_NOR"; + break; + case LogicalOperation::Or: + os << "GL_OR"; + break; + case LogicalOperation::OrInverted: + os << "GL_OR_INVERTED"; + break; + case LogicalOperation::OrReverse: + os << "GL_OR_REVERSE"; + break; + case LogicalOperation::Set: + os << "GL_SET"; + break; + case LogicalOperation::Xor: + os << "GL_XOR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +MaterialParameter FromGLenum(GLenum from) +{ + switch (from) + { + case GL_AMBIENT: + return MaterialParameter::Ambient; + case GL_AMBIENT_AND_DIFFUSE: + return MaterialParameter::AmbientAndDiffuse; + case GL_DIFFUSE: + return MaterialParameter::Diffuse; + case GL_EMISSION: + return MaterialParameter::Emission; + case GL_SHININESS: + return MaterialParameter::Shininess; + case GL_SPECULAR: + return MaterialParameter::Specular; + default: + return MaterialParameter::InvalidEnum; + } +} + +GLenum ToGLenum(MaterialParameter from) +{ + switch (from) + { + case MaterialParameter::Ambient: + return GL_AMBIENT; + case MaterialParameter::AmbientAndDiffuse: + return GL_AMBIENT_AND_DIFFUSE; + case MaterialParameter::Diffuse: + return GL_DIFFUSE; + case MaterialParameter::Emission: + return GL_EMISSION; + case MaterialParameter::Shininess: + return GL_SHININESS; + case MaterialParameter::Specular: + return GL_SPECULAR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, MaterialParameter value) +{ + switch (value) + { + case MaterialParameter::Ambient: + os << "GL_AMBIENT"; + break; + case MaterialParameter::AmbientAndDiffuse: + os << "GL_AMBIENT_AND_DIFFUSE"; + break; + case MaterialParameter::Diffuse: + os << "GL_DIFFUSE"; + break; + case MaterialParameter::Emission: + os << "GL_EMISSION"; + break; + case MaterialParameter::Shininess: + os << "GL_SHININESS"; + break; + case MaterialParameter::Specular: + os << "GL_SPECULAR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +MatrixType FromGLenum(GLenum from) +{ + switch (from) + { + case GL_MODELVIEW: + return MatrixType::Modelview; + case GL_PROJECTION: + return MatrixType::Projection; + case GL_TEXTURE: + return MatrixType::Texture; + default: + return MatrixType::InvalidEnum; + } +} + +GLenum ToGLenum(MatrixType from) +{ + switch (from) + { + case MatrixType::Modelview: + return GL_MODELVIEW; + case MatrixType::Projection: + return GL_PROJECTION; + case MatrixType::Texture: + return GL_TEXTURE; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, MatrixType value) +{ + switch (value) + { + case MatrixType::Modelview: + os << "GL_MODELVIEW"; + break; + case MatrixType::Projection: + os << "GL_PROJECTION"; + break; + case MatrixType::Texture: + os << "GL_TEXTURE"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +PointParameter FromGLenum(GLenum from) +{ + switch (from) + { + case GL_POINT_SIZE_MIN: + return PointParameter::PointSizeMin; + case GL_POINT_SIZE_MAX: + return PointParameter::PointSizeMax; + case GL_POINT_FADE_THRESHOLD_SIZE: + return PointParameter::PointFadeThresholdSize; + case GL_POINT_DISTANCE_ATTENUATION: + return PointParameter::PointDistanceAttenuation; + default: + return PointParameter::InvalidEnum; + } +} + +GLenum ToGLenum(PointParameter from) +{ + switch (from) + { + case PointParameter::PointSizeMin: + return GL_POINT_SIZE_MIN; + case PointParameter::PointSizeMax: + return GL_POINT_SIZE_MAX; + case PointParameter::PointFadeThresholdSize: + return GL_POINT_FADE_THRESHOLD_SIZE; + case PointParameter::PointDistanceAttenuation: + return GL_POINT_DISTANCE_ATTENUATION; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, PointParameter value) +{ + switch (value) + { + case PointParameter::PointSizeMin: + os << "GL_POINT_SIZE_MIN"; + break; + case PointParameter::PointSizeMax: + os << "GL_POINT_SIZE_MAX"; + break; + case PointParameter::PointFadeThresholdSize: + os << "GL_POINT_FADE_THRESHOLD_SIZE"; + break; + case PointParameter::PointDistanceAttenuation: + os << "GL_POINT_DISTANCE_ATTENUATION"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ProvokingVertexConvention FromGLenum(GLenum from) +{ + switch (from) + { + case GL_FIRST_VERTEX_CONVENTION: + return ProvokingVertexConvention::FirstVertexConvention; + case GL_LAST_VERTEX_CONVENTION: + return ProvokingVertexConvention::LastVertexConvention; + default: + return ProvokingVertexConvention::InvalidEnum; + } +} + +GLenum ToGLenum(ProvokingVertexConvention from) +{ + switch (from) + { + case ProvokingVertexConvention::FirstVertexConvention: + return GL_FIRST_VERTEX_CONVENTION; + case ProvokingVertexConvention::LastVertexConvention: + return GL_LAST_VERTEX_CONVENTION; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ProvokingVertexConvention value) +{ + switch (value) + { + case ProvokingVertexConvention::FirstVertexConvention: + os << "GL_FIRST_VERTEX_CONVENTION"; + break; + case ProvokingVertexConvention::LastVertexConvention: + os << "GL_LAST_VERTEX_CONVENTION"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +QueryType FromGLenum(GLenum from) +{ + switch (from) + { + case GL_ANY_SAMPLES_PASSED: + return QueryType::AnySamples; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return QueryType::AnySamplesConservative; + case GL_COMMANDS_COMPLETED_CHROMIUM: + return QueryType::CommandsCompleted; + case GL_PRIMITIVES_GENERATED_EXT: + return QueryType::PrimitivesGenerated; + case GL_TIME_ELAPSED_EXT: + return QueryType::TimeElapsed; + case GL_TIMESTAMP_EXT: + return QueryType::Timestamp; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return QueryType::TransformFeedbackPrimitivesWritten; + default: + return QueryType::InvalidEnum; + } +} + +GLenum ToGLenum(QueryType from) +{ + switch (from) + { + case QueryType::AnySamples: + return GL_ANY_SAMPLES_PASSED; + case QueryType::AnySamplesConservative: + return GL_ANY_SAMPLES_PASSED_CONSERVATIVE; + case QueryType::CommandsCompleted: + return GL_COMMANDS_COMPLETED_CHROMIUM; + case QueryType::PrimitivesGenerated: + return GL_PRIMITIVES_GENERATED_EXT; + case QueryType::TimeElapsed: + return GL_TIME_ELAPSED_EXT; + case QueryType::Timestamp: + return GL_TIMESTAMP_EXT; + case QueryType::TransformFeedbackPrimitivesWritten: + return GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, QueryType value) +{ + switch (value) + { + case QueryType::AnySamples: + os << "GL_ANY_SAMPLES_PASSED"; + break; + case QueryType::AnySamplesConservative: + os << "GL_ANY_SAMPLES_PASSED_CONSERVATIVE"; + break; + case QueryType::CommandsCompleted: + os << "GL_COMMANDS_COMPLETED_CHROMIUM"; + break; + case QueryType::PrimitivesGenerated: + os << "GL_PRIMITIVES_GENERATED_EXT"; + break; + case QueryType::TimeElapsed: + os << "GL_TIME_ELAPSED_EXT"; + break; + case QueryType::Timestamp: + os << "GL_TIMESTAMP_EXT"; + break; + case QueryType::TransformFeedbackPrimitivesWritten: + os << "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ShaderType FromGLenum(GLenum from) +{ + switch (from) + { + case GL_VERTEX_SHADER: + return ShaderType::Vertex; + case GL_TESS_CONTROL_SHADER_EXT: + return ShaderType::TessControl; + case GL_TESS_EVALUATION_SHADER_EXT: + return ShaderType::TessEvaluation; + case GL_GEOMETRY_SHADER_EXT: + return ShaderType::Geometry; + case GL_FRAGMENT_SHADER: + return ShaderType::Fragment; + case GL_COMPUTE_SHADER: + return ShaderType::Compute; + default: + return ShaderType::InvalidEnum; + } +} + +GLenum ToGLenum(ShaderType from) +{ + switch (from) + { + case ShaderType::Vertex: + return GL_VERTEX_SHADER; + case ShaderType::TessControl: + return GL_TESS_CONTROL_SHADER_EXT; + case ShaderType::TessEvaluation: + return GL_TESS_EVALUATION_SHADER_EXT; + case ShaderType::Geometry: + return GL_GEOMETRY_SHADER_EXT; + case ShaderType::Fragment: + return GL_FRAGMENT_SHADER; + case ShaderType::Compute: + return GL_COMPUTE_SHADER; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ShaderType value) +{ + switch (value) + { + case ShaderType::Vertex: + os << "GL_VERTEX_SHADER"; + break; + case ShaderType::TessControl: + os << "GL_TESS_CONTROL_SHADER_EXT"; + break; + case ShaderType::TessEvaluation: + os << "GL_TESS_EVALUATION_SHADER_EXT"; + break; + case ShaderType::Geometry: + os << "GL_GEOMETRY_SHADER_EXT"; + break; + case ShaderType::Fragment: + os << "GL_FRAGMENT_SHADER"; + break; + case ShaderType::Compute: + os << "GL_COMPUTE_SHADER"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ShadingModel FromGLenum(GLenum from) +{ + switch (from) + { + case GL_FLAT: + return ShadingModel::Flat; + case GL_SMOOTH: + return ShadingModel::Smooth; + default: + return ShadingModel::InvalidEnum; + } +} + +GLenum ToGLenum(ShadingModel from) +{ + switch (from) + { + case ShadingModel::Flat: + return GL_FLAT; + case ShadingModel::Smooth: + return GL_SMOOTH; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ShadingModel value) +{ + switch (value) + { + case ShadingModel::Flat: + os << "GL_FLAT"; + break; + case ShadingModel::Smooth: + os << "GL_SMOOTH"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +ShadingRate FromGLenum(GLenum from) +{ + switch (from) + { + case GL_NONE: + return ShadingRate::Undefined; + case GL_SHADING_RATE_1X1_PIXELS_QCOM: + return ShadingRate::_1x1; + case GL_SHADING_RATE_1X2_PIXELS_QCOM: + return ShadingRate::_1x2; + case GL_SHADING_RATE_2X1_PIXELS_QCOM: + return ShadingRate::_2x1; + case GL_SHADING_RATE_2X2_PIXELS_QCOM: + return ShadingRate::_2x2; + case GL_SHADING_RATE_4X2_PIXELS_QCOM: + return ShadingRate::_4x2; + case GL_SHADING_RATE_4X4_PIXELS_QCOM: + return ShadingRate::_4x4; + default: + return ShadingRate::InvalidEnum; + } +} + +GLenum ToGLenum(ShadingRate from) +{ + switch (from) + { + case ShadingRate::Undefined: + return GL_NONE; + case ShadingRate::_1x1: + return GL_SHADING_RATE_1X1_PIXELS_QCOM; + case ShadingRate::_1x2: + return GL_SHADING_RATE_1X2_PIXELS_QCOM; + case ShadingRate::_2x1: + return GL_SHADING_RATE_2X1_PIXELS_QCOM; + case ShadingRate::_2x2: + return GL_SHADING_RATE_2X2_PIXELS_QCOM; + case ShadingRate::_4x2: + return GL_SHADING_RATE_4X2_PIXELS_QCOM; + case ShadingRate::_4x4: + return GL_SHADING_RATE_4X4_PIXELS_QCOM; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, ShadingRate value) +{ + switch (value) + { + case ShadingRate::Undefined: + os << "GL_NONE"; + break; + case ShadingRate::_1x1: + os << "GL_SHADING_RATE_1X1_PIXELS_QCOM"; + break; + case ShadingRate::_1x2: + os << "GL_SHADING_RATE_1X2_PIXELS_QCOM"; + break; + case ShadingRate::_2x1: + os << "GL_SHADING_RATE_2X1_PIXELS_QCOM"; + break; + case ShadingRate::_2x2: + os << "GL_SHADING_RATE_2X2_PIXELS_QCOM"; + break; + case ShadingRate::_4x2: + os << "GL_SHADING_RATE_4X2_PIXELS_QCOM"; + break; + case ShadingRate::_4x4: + os << "GL_SHADING_RATE_4X4_PIXELS_QCOM"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureCombine FromGLenum(GLenum from) +{ + switch (from) + { + case GL_ADD: + return TextureCombine::Add; + case GL_ADD_SIGNED: + return TextureCombine::AddSigned; + case GL_DOT3_RGB: + return TextureCombine::Dot3Rgb; + case GL_DOT3_RGBA: + return TextureCombine::Dot3Rgba; + case GL_INTERPOLATE: + return TextureCombine::Interpolate; + case GL_MODULATE: + return TextureCombine::Modulate; + case GL_REPLACE: + return TextureCombine::Replace; + case GL_SUBTRACT: + return TextureCombine::Subtract; + default: + return TextureCombine::InvalidEnum; + } +} + +GLenum ToGLenum(TextureCombine from) +{ + switch (from) + { + case TextureCombine::Add: + return GL_ADD; + case TextureCombine::AddSigned: + return GL_ADD_SIGNED; + case TextureCombine::Dot3Rgb: + return GL_DOT3_RGB; + case TextureCombine::Dot3Rgba: + return GL_DOT3_RGBA; + case TextureCombine::Interpolate: + return GL_INTERPOLATE; + case TextureCombine::Modulate: + return GL_MODULATE; + case TextureCombine::Replace: + return GL_REPLACE; + case TextureCombine::Subtract: + return GL_SUBTRACT; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureCombine value) +{ + switch (value) + { + case TextureCombine::Add: + os << "GL_ADD"; + break; + case TextureCombine::AddSigned: + os << "GL_ADD_SIGNED"; + break; + case TextureCombine::Dot3Rgb: + os << "GL_DOT3_RGB"; + break; + case TextureCombine::Dot3Rgba: + os << "GL_DOT3_RGBA"; + break; + case TextureCombine::Interpolate: + os << "GL_INTERPOLATE"; + break; + case TextureCombine::Modulate: + os << "GL_MODULATE"; + break; + case TextureCombine::Replace: + os << "GL_REPLACE"; + break; + case TextureCombine::Subtract: + os << "GL_SUBTRACT"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureEnvMode FromGLenum(GLenum from) +{ + switch (from) + { + case GL_ADD: + return TextureEnvMode::Add; + case GL_BLEND: + return TextureEnvMode::Blend; + case GL_COMBINE: + return TextureEnvMode::Combine; + case GL_DECAL: + return TextureEnvMode::Decal; + case GL_MODULATE: + return TextureEnvMode::Modulate; + case GL_REPLACE: + return TextureEnvMode::Replace; + default: + return TextureEnvMode::InvalidEnum; + } +} + +GLenum ToGLenum(TextureEnvMode from) +{ + switch (from) + { + case TextureEnvMode::Add: + return GL_ADD; + case TextureEnvMode::Blend: + return GL_BLEND; + case TextureEnvMode::Combine: + return GL_COMBINE; + case TextureEnvMode::Decal: + return GL_DECAL; + case TextureEnvMode::Modulate: + return GL_MODULATE; + case TextureEnvMode::Replace: + return GL_REPLACE; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureEnvMode value) +{ + switch (value) + { + case TextureEnvMode::Add: + os << "GL_ADD"; + break; + case TextureEnvMode::Blend: + os << "GL_BLEND"; + break; + case TextureEnvMode::Combine: + os << "GL_COMBINE"; + break; + case TextureEnvMode::Decal: + os << "GL_DECAL"; + break; + case TextureEnvMode::Modulate: + os << "GL_MODULATE"; + break; + case TextureEnvMode::Replace: + os << "GL_REPLACE"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureEnvParameter FromGLenum(GLenum from) +{ + switch (from) + { + case GL_TEXTURE_ENV_MODE: + return TextureEnvParameter::Mode; + case GL_TEXTURE_ENV_COLOR: + return TextureEnvParameter::Color; + case GL_COMBINE_RGB: + return TextureEnvParameter::CombineRgb; + case GL_COMBINE_ALPHA: + return TextureEnvParameter::CombineAlpha; + case GL_RGB_SCALE: + return TextureEnvParameter::RgbScale; + case GL_ALPHA_SCALE: + return TextureEnvParameter::AlphaScale; + case GL_SRC0_RGB: + return TextureEnvParameter::Src0Rgb; + case GL_SRC1_RGB: + return TextureEnvParameter::Src1Rgb; + case GL_SRC2_RGB: + return TextureEnvParameter::Src2Rgb; + case GL_SRC0_ALPHA: + return TextureEnvParameter::Src0Alpha; + case GL_SRC1_ALPHA: + return TextureEnvParameter::Src1Alpha; + case GL_SRC2_ALPHA: + return TextureEnvParameter::Src2Alpha; + case GL_OPERAND0_RGB: + return TextureEnvParameter::Op0Rgb; + case GL_OPERAND1_RGB: + return TextureEnvParameter::Op1Rgb; + case GL_OPERAND2_RGB: + return TextureEnvParameter::Op2Rgb; + case GL_OPERAND0_ALPHA: + return TextureEnvParameter::Op0Alpha; + case GL_OPERAND1_ALPHA: + return TextureEnvParameter::Op1Alpha; + case GL_OPERAND2_ALPHA: + return TextureEnvParameter::Op2Alpha; + case GL_COORD_REPLACE_OES: + return TextureEnvParameter::PointCoordReplace; + default: + return TextureEnvParameter::InvalidEnum; + } +} + +GLenum ToGLenum(TextureEnvParameter from) +{ + switch (from) + { + case TextureEnvParameter::Mode: + return GL_TEXTURE_ENV_MODE; + case TextureEnvParameter::Color: + return GL_TEXTURE_ENV_COLOR; + case TextureEnvParameter::CombineRgb: + return GL_COMBINE_RGB; + case TextureEnvParameter::CombineAlpha: + return GL_COMBINE_ALPHA; + case TextureEnvParameter::RgbScale: + return GL_RGB_SCALE; + case TextureEnvParameter::AlphaScale: + return GL_ALPHA_SCALE; + case TextureEnvParameter::Src0Rgb: + return GL_SRC0_RGB; + case TextureEnvParameter::Src1Rgb: + return GL_SRC1_RGB; + case TextureEnvParameter::Src2Rgb: + return GL_SRC2_RGB; + case TextureEnvParameter::Src0Alpha: + return GL_SRC0_ALPHA; + case TextureEnvParameter::Src1Alpha: + return GL_SRC1_ALPHA; + case TextureEnvParameter::Src2Alpha: + return GL_SRC2_ALPHA; + case TextureEnvParameter::Op0Rgb: + return GL_OPERAND0_RGB; + case TextureEnvParameter::Op1Rgb: + return GL_OPERAND1_RGB; + case TextureEnvParameter::Op2Rgb: + return GL_OPERAND2_RGB; + case TextureEnvParameter::Op0Alpha: + return GL_OPERAND0_ALPHA; + case TextureEnvParameter::Op1Alpha: + return GL_OPERAND1_ALPHA; + case TextureEnvParameter::Op2Alpha: + return GL_OPERAND2_ALPHA; + case TextureEnvParameter::PointCoordReplace: + return GL_COORD_REPLACE_OES; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureEnvParameter value) +{ + switch (value) + { + case TextureEnvParameter::Mode: + os << "GL_TEXTURE_ENV_MODE"; + break; + case TextureEnvParameter::Color: + os << "GL_TEXTURE_ENV_COLOR"; + break; + case TextureEnvParameter::CombineRgb: + os << "GL_COMBINE_RGB"; + break; + case TextureEnvParameter::CombineAlpha: + os << "GL_COMBINE_ALPHA"; + break; + case TextureEnvParameter::RgbScale: + os << "GL_RGB_SCALE"; + break; + case TextureEnvParameter::AlphaScale: + os << "GL_ALPHA_SCALE"; + break; + case TextureEnvParameter::Src0Rgb: + os << "GL_SRC0_RGB"; + break; + case TextureEnvParameter::Src1Rgb: + os << "GL_SRC1_RGB"; + break; + case TextureEnvParameter::Src2Rgb: + os << "GL_SRC2_RGB"; + break; + case TextureEnvParameter::Src0Alpha: + os << "GL_SRC0_ALPHA"; + break; + case TextureEnvParameter::Src1Alpha: + os << "GL_SRC1_ALPHA"; + break; + case TextureEnvParameter::Src2Alpha: + os << "GL_SRC2_ALPHA"; + break; + case TextureEnvParameter::Op0Rgb: + os << "GL_OPERAND0_RGB"; + break; + case TextureEnvParameter::Op1Rgb: + os << "GL_OPERAND1_RGB"; + break; + case TextureEnvParameter::Op2Rgb: + os << "GL_OPERAND2_RGB"; + break; + case TextureEnvParameter::Op0Alpha: + os << "GL_OPERAND0_ALPHA"; + break; + case TextureEnvParameter::Op1Alpha: + os << "GL_OPERAND1_ALPHA"; + break; + case TextureEnvParameter::Op2Alpha: + os << "GL_OPERAND2_ALPHA"; + break; + case TextureEnvParameter::PointCoordReplace: + os << "GL_COORD_REPLACE_OES"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureEnvTarget FromGLenum(GLenum from) +{ + switch (from) + { + case GL_TEXTURE_ENV: + return TextureEnvTarget::Env; + case GL_POINT_SPRITE_OES: + return TextureEnvTarget::PointSprite; + default: + return TextureEnvTarget::InvalidEnum; + } +} + +GLenum ToGLenum(TextureEnvTarget from) +{ + switch (from) + { + case TextureEnvTarget::Env: + return GL_TEXTURE_ENV; + case TextureEnvTarget::PointSprite: + return GL_POINT_SPRITE_OES; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureEnvTarget value) +{ + switch (value) + { + case TextureEnvTarget::Env: + os << "GL_TEXTURE_ENV"; + break; + case TextureEnvTarget::PointSprite: + os << "GL_POINT_SPRITE_OES"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureOp FromGLenum(GLenum from) +{ + switch (from) + { + case GL_ONE_MINUS_SRC_ALPHA: + return TextureOp::OneMinusSrcAlpha; + case GL_ONE_MINUS_SRC_COLOR: + return TextureOp::OneMinusSrcColor; + case GL_SRC_ALPHA: + return TextureOp::SrcAlpha; + case GL_SRC_COLOR: + return TextureOp::SrcColor; + default: + return TextureOp::InvalidEnum; + } +} + +GLenum ToGLenum(TextureOp from) +{ + switch (from) + { + case TextureOp::OneMinusSrcAlpha: + return GL_ONE_MINUS_SRC_ALPHA; + case TextureOp::OneMinusSrcColor: + return GL_ONE_MINUS_SRC_COLOR; + case TextureOp::SrcAlpha: + return GL_SRC_ALPHA; + case TextureOp::SrcColor: + return GL_SRC_COLOR; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureOp value) +{ + switch (value) + { + case TextureOp::OneMinusSrcAlpha: + os << "GL_ONE_MINUS_SRC_ALPHA"; + break; + case TextureOp::OneMinusSrcColor: + os << "GL_ONE_MINUS_SRC_COLOR"; + break; + case TextureOp::SrcAlpha: + os << "GL_SRC_ALPHA"; + break; + case TextureOp::SrcColor: + os << "GL_SRC_COLOR"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureSrc FromGLenum(GLenum from) +{ + switch (from) + { + case GL_CONSTANT: + return TextureSrc::Constant; + case GL_PREVIOUS: + return TextureSrc::Previous; + case GL_PRIMARY_COLOR: + return TextureSrc::PrimaryColor; + case GL_TEXTURE: + return TextureSrc::Texture; + default: + return TextureSrc::InvalidEnum; + } +} + +GLenum ToGLenum(TextureSrc from) +{ + switch (from) + { + case TextureSrc::Constant: + return GL_CONSTANT; + case TextureSrc::Previous: + return GL_PREVIOUS; + case TextureSrc::PrimaryColor: + return GL_PRIMARY_COLOR; + case TextureSrc::Texture: + return GL_TEXTURE; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureSrc value) +{ + switch (value) + { + case TextureSrc::Constant: + os << "GL_CONSTANT"; + break; + case TextureSrc::Previous: + os << "GL_PREVIOUS"; + break; + case TextureSrc::PrimaryColor: + os << "GL_PRIMARY_COLOR"; + break; + case TextureSrc::Texture: + os << "GL_TEXTURE"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureTarget FromGLenum(GLenum from) +{ + switch (from) + { + case GL_TEXTURE_2D: + return TextureTarget::_2D; + case GL_TEXTURE_2D_ARRAY: + return TextureTarget::_2DArray; + case GL_TEXTURE_2D_MULTISAMPLE: + return TextureTarget::_2DMultisample; + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES: + return TextureTarget::_2DMultisampleArray; + case GL_TEXTURE_3D: + return TextureTarget::_3D; + case GL_TEXTURE_EXTERNAL_OES: + return TextureTarget::External; + case GL_TEXTURE_RECTANGLE_ANGLE: + return TextureTarget::Rectangle; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + return TextureTarget::CubeMapPositiveX; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + return TextureTarget::CubeMapNegativeX; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + return TextureTarget::CubeMapPositiveY; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + return TextureTarget::CubeMapNegativeY; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + return TextureTarget::CubeMapPositiveZ; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return TextureTarget::CubeMapNegativeZ; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return TextureTarget::CubeMapArray; + case GL_TEXTURE_VIDEO_IMAGE_WEBGL: + return TextureTarget::VideoImage; + case GL_TEXTURE_BUFFER: + return TextureTarget::Buffer; + default: + return TextureTarget::InvalidEnum; + } +} + +GLenum ToGLenum(TextureTarget from) +{ + switch (from) + { + case TextureTarget::_2D: + return GL_TEXTURE_2D; + case TextureTarget::_2DArray: + return GL_TEXTURE_2D_ARRAY; + case TextureTarget::_2DMultisample: + return GL_TEXTURE_2D_MULTISAMPLE; + case TextureTarget::_2DMultisampleArray: + return GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES; + case TextureTarget::_3D: + return GL_TEXTURE_3D; + case TextureTarget::External: + return GL_TEXTURE_EXTERNAL_OES; + case TextureTarget::Rectangle: + return GL_TEXTURE_RECTANGLE_ANGLE; + case TextureTarget::CubeMapPositiveX: + return GL_TEXTURE_CUBE_MAP_POSITIVE_X; + case TextureTarget::CubeMapNegativeX: + return GL_TEXTURE_CUBE_MAP_NEGATIVE_X; + case TextureTarget::CubeMapPositiveY: + return GL_TEXTURE_CUBE_MAP_POSITIVE_Y; + case TextureTarget::CubeMapNegativeY: + return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; + case TextureTarget::CubeMapPositiveZ: + return GL_TEXTURE_CUBE_MAP_POSITIVE_Z; + case TextureTarget::CubeMapNegativeZ: + return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + case TextureTarget::CubeMapArray: + return GL_TEXTURE_CUBE_MAP_ARRAY; + case TextureTarget::VideoImage: + return GL_TEXTURE_VIDEO_IMAGE_WEBGL; + case TextureTarget::Buffer: + return GL_TEXTURE_BUFFER; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureTarget value) +{ + switch (value) + { + case TextureTarget::_2D: + os << "GL_TEXTURE_2D"; + break; + case TextureTarget::_2DArray: + os << "GL_TEXTURE_2D_ARRAY"; + break; + case TextureTarget::_2DMultisample: + os << "GL_TEXTURE_2D_MULTISAMPLE"; + break; + case TextureTarget::_2DMultisampleArray: + os << "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES"; + break; + case TextureTarget::_3D: + os << "GL_TEXTURE_3D"; + break; + case TextureTarget::External: + os << "GL_TEXTURE_EXTERNAL_OES"; + break; + case TextureTarget::Rectangle: + os << "GL_TEXTURE_RECTANGLE_ANGLE"; + break; + case TextureTarget::CubeMapPositiveX: + os << "GL_TEXTURE_CUBE_MAP_POSITIVE_X"; + break; + case TextureTarget::CubeMapNegativeX: + os << "GL_TEXTURE_CUBE_MAP_NEGATIVE_X"; + break; + case TextureTarget::CubeMapPositiveY: + os << "GL_TEXTURE_CUBE_MAP_POSITIVE_Y"; + break; + case TextureTarget::CubeMapNegativeY: + os << "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y"; + break; + case TextureTarget::CubeMapPositiveZ: + os << "GL_TEXTURE_CUBE_MAP_POSITIVE_Z"; + break; + case TextureTarget::CubeMapNegativeZ: + os << "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z"; + break; + case TextureTarget::CubeMapArray: + os << "GL_TEXTURE_CUBE_MAP_ARRAY"; + break; + case TextureTarget::VideoImage: + os << "GL_TEXTURE_VIDEO_IMAGE_WEBGL"; + break; + case TextureTarget::Buffer: + os << "GL_TEXTURE_BUFFER"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +TextureType FromGLenum(GLenum from) +{ + switch (from) + { + case GL_TEXTURE_2D: + return TextureType::_2D; + case GL_TEXTURE_2D_ARRAY: + return TextureType::_2DArray; + case GL_TEXTURE_2D_MULTISAMPLE: + return TextureType::_2DMultisample; + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES: + return TextureType::_2DMultisampleArray; + case GL_TEXTURE_3D: + return TextureType::_3D; + case GL_TEXTURE_EXTERNAL_OES: + return TextureType::External; + case GL_TEXTURE_RECTANGLE_ANGLE: + return TextureType::Rectangle; + case GL_TEXTURE_CUBE_MAP: + return TextureType::CubeMap; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return TextureType::CubeMapArray; + case GL_TEXTURE_VIDEO_IMAGE_WEBGL: + return TextureType::VideoImage; + case GL_TEXTURE_BUFFER: + return TextureType::Buffer; + default: + return TextureType::InvalidEnum; + } +} + +GLenum ToGLenum(TextureType from) +{ + switch (from) + { + case TextureType::_2D: + return GL_TEXTURE_2D; + case TextureType::_2DArray: + return GL_TEXTURE_2D_ARRAY; + case TextureType::_2DMultisample: + return GL_TEXTURE_2D_MULTISAMPLE; + case TextureType::_2DMultisampleArray: + return GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES; + case TextureType::_3D: + return GL_TEXTURE_3D; + case TextureType::External: + return GL_TEXTURE_EXTERNAL_OES; + case TextureType::Rectangle: + return GL_TEXTURE_RECTANGLE_ANGLE; + case TextureType::CubeMap: + return GL_TEXTURE_CUBE_MAP; + case TextureType::CubeMapArray: + return GL_TEXTURE_CUBE_MAP_ARRAY; + case TextureType::VideoImage: + return GL_TEXTURE_VIDEO_IMAGE_WEBGL; + case TextureType::Buffer: + return GL_TEXTURE_BUFFER; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, TextureType value) +{ + switch (value) + { + case TextureType::_2D: + os << "GL_TEXTURE_2D"; + break; + case TextureType::_2DArray: + os << "GL_TEXTURE_2D_ARRAY"; + break; + case TextureType::_2DMultisample: + os << "GL_TEXTURE_2D_MULTISAMPLE"; + break; + case TextureType::_2DMultisampleArray: + os << "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES"; + break; + case TextureType::_3D: + os << "GL_TEXTURE_3D"; + break; + case TextureType::External: + os << "GL_TEXTURE_EXTERNAL_OES"; + break; + case TextureType::Rectangle: + os << "GL_TEXTURE_RECTANGLE_ANGLE"; + break; + case TextureType::CubeMap: + os << "GL_TEXTURE_CUBE_MAP"; + break; + case TextureType::CubeMapArray: + os << "GL_TEXTURE_CUBE_MAP_ARRAY"; + break; + case TextureType::VideoImage: + os << "GL_TEXTURE_VIDEO_IMAGE_WEBGL"; + break; + case TextureType::Buffer: + os << "GL_TEXTURE_BUFFER"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +VertexArrayType FromGLenum(GLenum from) +{ + switch (from) + { + case GL_COLOR_ARRAY: + return VertexArrayType::Color; + case GL_NORMAL_ARRAY: + return VertexArrayType::Normal; + case GL_POINT_SIZE_ARRAY_OES: + return VertexArrayType::PointSize; + case GL_TEXTURE_COORD_ARRAY: + return VertexArrayType::TextureCoord; + case GL_VERTEX_ARRAY: + return VertexArrayType::Vertex; + default: + return VertexArrayType::InvalidEnum; + } +} + +GLenum ToGLenum(VertexArrayType from) +{ + switch (from) + { + case VertexArrayType::Color: + return GL_COLOR_ARRAY; + case VertexArrayType::Normal: + return GL_NORMAL_ARRAY; + case VertexArrayType::PointSize: + return GL_POINT_SIZE_ARRAY_OES; + case VertexArrayType::TextureCoord: + return GL_TEXTURE_COORD_ARRAY; + case VertexArrayType::Vertex: + return GL_VERTEX_ARRAY; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, VertexArrayType value) +{ + switch (value) + { + case VertexArrayType::Color: + os << "GL_COLOR_ARRAY"; + break; + case VertexArrayType::Normal: + os << "GL_NORMAL_ARRAY"; + break; + case VertexArrayType::PointSize: + os << "GL_POINT_SIZE_ARRAY_OES"; + break; + case VertexArrayType::TextureCoord: + os << "GL_TEXTURE_COORD_ARRAY"; + break; + case VertexArrayType::Vertex: + os << "GL_VERTEX_ARRAY"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +template <> +WrapMode FromGLenum(GLenum from) +{ + switch (from) + { + case GL_CLAMP_TO_EDGE: + return WrapMode::ClampToEdge; + case GL_CLAMP_TO_BORDER: + return WrapMode::ClampToBorder; + case GL_MIRRORED_REPEAT: + return WrapMode::MirroredRepeat; + case GL_REPEAT: + return WrapMode::Repeat; + default: + return WrapMode::InvalidEnum; + } +} + +GLenum ToGLenum(WrapMode from) +{ + switch (from) + { + case WrapMode::ClampToEdge: + return GL_CLAMP_TO_EDGE; + case WrapMode::ClampToBorder: + return GL_CLAMP_TO_BORDER; + case WrapMode::MirroredRepeat: + return GL_MIRRORED_REPEAT; + case WrapMode::Repeat: + return GL_REPEAT; + default: + UNREACHABLE(); + return 0; + } +} + +std::ostream &operator<<(std::ostream &os, WrapMode value) +{ + switch (value) + { + case WrapMode::ClampToEdge: + os << "GL_CLAMP_TO_EDGE"; + break; + case WrapMode::ClampToBorder: + os << "GL_CLAMP_TO_BORDER"; + break; + case WrapMode::MirroredRepeat: + os << "GL_MIRRORED_REPEAT"; + break; + case WrapMode::Repeat: + os << "GL_REPEAT"; + break; + default: + os << "GL_INVALID_ENUM"; + break; + } + return os; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/common/PackedGLEnums_autogen.h b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.h new file mode 100644 index 0000000000..452dca344e --- /dev/null +++ b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.h @@ -0,0 +1,610 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json. +// +// Copyright 2017 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. +// +// PackedGLEnums_autogen.h: +// Declares ANGLE-specific enums classes for GLenums and functions operating +// on them. + +#ifndef COMMON_PACKEDGLENUMS_AUTOGEN_H_ +#define COMMON_PACKEDGLENUMS_AUTOGEN_H_ + +#include + +#include +#include + +namespace gl +{ + +template +Enum FromGLenum(GLenum from); + +enum class AlphaTestFunc : uint8_t +{ + AlwaysPass = 0, + Equal = 1, + Gequal = 2, + Greater = 3, + Lequal = 4, + Less = 5, + Never = 6, + NotEqual = 7, + + InvalidEnum = 8, + EnumCount = 8, +}; + +template <> +AlphaTestFunc FromGLenum(GLenum from); +GLenum ToGLenum(AlphaTestFunc from); +std::ostream &operator<<(std::ostream &os, AlphaTestFunc value); + +enum class BufferBinding : uint8_t +{ + Array = 0, + AtomicCounter = 1, + CopyRead = 2, + CopyWrite = 3, + DispatchIndirect = 4, + DrawIndirect = 5, + ElementArray = 6, + PixelPack = 7, + PixelUnpack = 8, + ShaderStorage = 9, + Texture = 10, + TransformFeedback = 11, + Uniform = 12, + + InvalidEnum = 13, + EnumCount = 13, +}; + +template <> +BufferBinding FromGLenum(GLenum from); +GLenum ToGLenum(BufferBinding from); +std::ostream &operator<<(std::ostream &os, BufferBinding value); + +enum class BufferUsage : uint8_t +{ + DynamicCopy = 0, + DynamicDraw = 1, + DynamicRead = 2, + StaticCopy = 3, + StaticDraw = 4, + StaticRead = 5, + StreamCopy = 6, + StreamDraw = 7, + StreamRead = 8, + + InvalidEnum = 9, + EnumCount = 9, +}; + +template <> +BufferUsage FromGLenum(GLenum from); +GLenum ToGLenum(BufferUsage from); +std::ostream &operator<<(std::ostream &os, BufferUsage value); + +enum class ClientVertexArrayType : uint8_t +{ + Color = 0, + Normal = 1, + PointSize = 2, + TextureCoord = 3, + Vertex = 4, + + InvalidEnum = 5, + EnumCount = 5, +}; + +template <> +ClientVertexArrayType FromGLenum(GLenum from); +GLenum ToGLenum(ClientVertexArrayType from); +std::ostream &operator<<(std::ostream &os, ClientVertexArrayType value); + +enum class CullFaceMode : uint8_t +{ + Back = 0, + Front = 1, + FrontAndBack = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +CullFaceMode FromGLenum(GLenum from); +GLenum ToGLenum(CullFaceMode from); +std::ostream &operator<<(std::ostream &os, CullFaceMode value); + +enum class FilterMode : uint8_t +{ + Nearest = 0, + Linear = 1, + NearestMipmapNearest = 2, + NearestMipmapLinear = 3, + LinearMipmapLinear = 4, + + InvalidEnum = 5, + EnumCount = 5, +}; + +template <> +FilterMode FromGLenum(GLenum from); +GLenum ToGLenum(FilterMode from); +std::ostream &operator<<(std::ostream &os, FilterMode value); + +enum class FogMode : uint8_t +{ + Exp = 0, + Exp2 = 1, + Linear = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +FogMode FromGLenum(GLenum from); +GLenum ToGLenum(FogMode from); +std::ostream &operator<<(std::ostream &os, FogMode value); + +enum class GraphicsResetStatus : uint8_t +{ + NoError = 0, + GuiltyContextReset = 1, + InnocentContextReset = 2, + UnknownContextReset = 3, + PurgedContextResetNV = 4, + + InvalidEnum = 5, + EnumCount = 5, +}; + +template <> +GraphicsResetStatus FromGLenum(GLenum from); +GLenum ToGLenum(GraphicsResetStatus from); +std::ostream &operator<<(std::ostream &os, GraphicsResetStatus value); + +enum class HandleType : uint8_t +{ + OpaqueFd = 0, + ZirconVmo = 1, + ZirconEvent = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +HandleType FromGLenum(GLenum from); +GLenum ToGLenum(HandleType from); +std::ostream &operator<<(std::ostream &os, HandleType value); + +enum class HintSetting : uint8_t +{ + DontCare = 0, + Fastest = 1, + Nicest = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +HintSetting FromGLenum(GLenum from); +GLenum ToGLenum(HintSetting from); +std::ostream &operator<<(std::ostream &os, HintSetting value); + +enum class ImageLayout : uint8_t +{ + Undefined = 0, + General = 1, + ColorAttachment = 2, + DepthStencilAttachment = 3, + DepthStencilReadOnlyAttachment = 4, + ShaderReadOnly = 5, + TransferSrc = 6, + TransferDst = 7, + DepthReadOnlyStencilAttachment = 8, + DepthAttachmentStencilReadOnly = 9, + + InvalidEnum = 10, + EnumCount = 10, +}; + +template <> +ImageLayout FromGLenum(GLenum from); +GLenum ToGLenum(ImageLayout from); +std::ostream &operator<<(std::ostream &os, ImageLayout value); + +enum class LightParameter : uint8_t +{ + Ambient = 0, + AmbientAndDiffuse = 1, + ConstantAttenuation = 2, + Diffuse = 3, + LinearAttenuation = 4, + Position = 5, + QuadraticAttenuation = 6, + Specular = 7, + SpotCutoff = 8, + SpotDirection = 9, + SpotExponent = 10, + + InvalidEnum = 11, + EnumCount = 11, +}; + +template <> +LightParameter FromGLenum(GLenum from); +GLenum ToGLenum(LightParameter from); +std::ostream &operator<<(std::ostream &os, LightParameter value); + +enum class LogicalOperation : uint8_t +{ + And = 0, + AndInverted = 1, + AndReverse = 2, + Clear = 3, + Copy = 4, + CopyInverted = 5, + Equiv = 6, + Invert = 7, + Nand = 8, + Noop = 9, + Nor = 10, + Or = 11, + OrInverted = 12, + OrReverse = 13, + Set = 14, + Xor = 15, + + InvalidEnum = 16, + EnumCount = 16, +}; + +template <> +LogicalOperation FromGLenum(GLenum from); +GLenum ToGLenum(LogicalOperation from); +std::ostream &operator<<(std::ostream &os, LogicalOperation value); + +enum class MaterialParameter : uint8_t +{ + Ambient = 0, + AmbientAndDiffuse = 1, + Diffuse = 2, + Emission = 3, + Shininess = 4, + Specular = 5, + + InvalidEnum = 6, + EnumCount = 6, +}; + +template <> +MaterialParameter FromGLenum(GLenum from); +GLenum ToGLenum(MaterialParameter from); +std::ostream &operator<<(std::ostream &os, MaterialParameter value); + +enum class MatrixType : uint8_t +{ + Modelview = 0, + Projection = 1, + Texture = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +MatrixType FromGLenum(GLenum from); +GLenum ToGLenum(MatrixType from); +std::ostream &operator<<(std::ostream &os, MatrixType value); + +enum class PointParameter : uint8_t +{ + PointSizeMin = 0, + PointSizeMax = 1, + PointFadeThresholdSize = 2, + PointDistanceAttenuation = 3, + + InvalidEnum = 4, + EnumCount = 4, +}; + +template <> +PointParameter FromGLenum(GLenum from); +GLenum ToGLenum(PointParameter from); +std::ostream &operator<<(std::ostream &os, PointParameter value); + +enum class ProvokingVertexConvention : uint8_t +{ + FirstVertexConvention = 0, + LastVertexConvention = 1, + + InvalidEnum = 2, + EnumCount = 2, +}; + +template <> +ProvokingVertexConvention FromGLenum(GLenum from); +GLenum ToGLenum(ProvokingVertexConvention from); +std::ostream &operator<<(std::ostream &os, ProvokingVertexConvention value); + +enum class QueryType : uint8_t +{ + AnySamples = 0, + AnySamplesConservative = 1, + CommandsCompleted = 2, + PrimitivesGenerated = 3, + TimeElapsed = 4, + Timestamp = 5, + TransformFeedbackPrimitivesWritten = 6, + + InvalidEnum = 7, + EnumCount = 7, +}; + +template <> +QueryType FromGLenum(GLenum from); +GLenum ToGLenum(QueryType from); +std::ostream &operator<<(std::ostream &os, QueryType value); + +enum class ShaderType : uint8_t +{ + Vertex = 0, + TessControl = 1, + TessEvaluation = 2, + Geometry = 3, + Fragment = 4, + Compute = 5, + + InvalidEnum = 6, + EnumCount = 6, +}; + +template <> +ShaderType FromGLenum(GLenum from); +GLenum ToGLenum(ShaderType from); +std::ostream &operator<<(std::ostream &os, ShaderType value); + +enum class ShadingModel : uint8_t +{ + Flat = 0, + Smooth = 1, + + InvalidEnum = 2, + EnumCount = 2, +}; + +template <> +ShadingModel FromGLenum(GLenum from); +GLenum ToGLenum(ShadingModel from); +std::ostream &operator<<(std::ostream &os, ShadingModel value); + +enum class ShadingRate : uint8_t +{ + Undefined = 0, + _1x1 = 1, + _1x2 = 2, + _2x1 = 3, + _2x2 = 4, + _4x2 = 5, + _4x4 = 6, + + InvalidEnum = 7, + EnumCount = 7, +}; + +template <> +ShadingRate FromGLenum(GLenum from); +GLenum ToGLenum(ShadingRate from); +std::ostream &operator<<(std::ostream &os, ShadingRate value); + +enum class TextureCombine : uint8_t +{ + Add = 0, + AddSigned = 1, + Dot3Rgb = 2, + Dot3Rgba = 3, + Interpolate = 4, + Modulate = 5, + Replace = 6, + Subtract = 7, + + InvalidEnum = 8, + EnumCount = 8, +}; + +template <> +TextureCombine FromGLenum(GLenum from); +GLenum ToGLenum(TextureCombine from); +std::ostream &operator<<(std::ostream &os, TextureCombine value); + +enum class TextureEnvMode : uint8_t +{ + Add = 0, + Blend = 1, + Combine = 2, + Decal = 3, + Modulate = 4, + Replace = 5, + + InvalidEnum = 6, + EnumCount = 6, +}; + +template <> +TextureEnvMode FromGLenum(GLenum from); +GLenum ToGLenum(TextureEnvMode from); +std::ostream &operator<<(std::ostream &os, TextureEnvMode value); + +enum class TextureEnvParameter : uint8_t +{ + Mode = 0, + Color = 1, + CombineRgb = 2, + CombineAlpha = 3, + RgbScale = 4, + AlphaScale = 5, + Src0Rgb = 6, + Src1Rgb = 7, + Src2Rgb = 8, + Src0Alpha = 9, + Src1Alpha = 10, + Src2Alpha = 11, + Op0Rgb = 12, + Op1Rgb = 13, + Op2Rgb = 14, + Op0Alpha = 15, + Op1Alpha = 16, + Op2Alpha = 17, + PointCoordReplace = 18, + + InvalidEnum = 19, + EnumCount = 19, +}; + +template <> +TextureEnvParameter FromGLenum(GLenum from); +GLenum ToGLenum(TextureEnvParameter from); +std::ostream &operator<<(std::ostream &os, TextureEnvParameter value); + +enum class TextureEnvTarget : uint8_t +{ + Env = 0, + PointSprite = 1, + + InvalidEnum = 2, + EnumCount = 2, +}; + +template <> +TextureEnvTarget FromGLenum(GLenum from); +GLenum ToGLenum(TextureEnvTarget from); +std::ostream &operator<<(std::ostream &os, TextureEnvTarget value); + +enum class TextureOp : uint8_t +{ + OneMinusSrcAlpha = 0, + OneMinusSrcColor = 1, + SrcAlpha = 2, + SrcColor = 3, + + InvalidEnum = 4, + EnumCount = 4, +}; + +template <> +TextureOp FromGLenum(GLenum from); +GLenum ToGLenum(TextureOp from); +std::ostream &operator<<(std::ostream &os, TextureOp value); + +enum class TextureSrc : uint8_t +{ + Constant = 0, + Previous = 1, + PrimaryColor = 2, + Texture = 3, + + InvalidEnum = 4, + EnumCount = 4, +}; + +template <> +TextureSrc FromGLenum(GLenum from); +GLenum ToGLenum(TextureSrc from); +std::ostream &operator<<(std::ostream &os, TextureSrc value); + +enum class TextureTarget : uint8_t +{ + _2D = 0, + _2DArray = 1, + _2DMultisample = 2, + _2DMultisampleArray = 3, + _3D = 4, + External = 5, + Rectangle = 6, + CubeMapPositiveX = 7, + CubeMapNegativeX = 8, + CubeMapPositiveY = 9, + CubeMapNegativeY = 10, + CubeMapPositiveZ = 11, + CubeMapNegativeZ = 12, + CubeMapArray = 13, + VideoImage = 14, + Buffer = 15, + + InvalidEnum = 16, + EnumCount = 16, +}; + +template <> +TextureTarget FromGLenum(GLenum from); +GLenum ToGLenum(TextureTarget from); +std::ostream &operator<<(std::ostream &os, TextureTarget value); + +enum class TextureType : uint8_t +{ + _2D = 0, + _2DArray = 1, + _2DMultisample = 2, + _2DMultisampleArray = 3, + _3D = 4, + External = 5, + Rectangle = 6, + CubeMap = 7, + CubeMapArray = 8, + VideoImage = 9, + Buffer = 10, + + InvalidEnum = 11, + EnumCount = 11, +}; + +template <> +TextureType FromGLenum(GLenum from); +GLenum ToGLenum(TextureType from); +std::ostream &operator<<(std::ostream &os, TextureType value); + +enum class VertexArrayType : uint8_t +{ + Color = 0, + Normal = 1, + PointSize = 2, + TextureCoord = 3, + Vertex = 4, + + InvalidEnum = 5, + EnumCount = 5, +}; + +template <> +VertexArrayType FromGLenum(GLenum from); +GLenum ToGLenum(VertexArrayType from); +std::ostream &operator<<(std::ostream &os, VertexArrayType value); + +enum class WrapMode : uint8_t +{ + ClampToEdge = 0, + ClampToBorder = 1, + MirroredRepeat = 2, + Repeat = 3, + + InvalidEnum = 4, + EnumCount = 4, +}; + +template <> +WrapMode FromGLenum(GLenum from); +GLenum ToGLenum(WrapMode from); +std::ostream &operator<<(std::ostream &os, WrapMode value); + +} // namespace gl + +#endif // COMMON_PACKEDGLENUMS_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/common/PoolAlloc.cpp b/gfx/angle/checkout/src/common/PoolAlloc.cpp new file mode 100644 index 0000000000..eef033ca04 --- /dev/null +++ b/gfx/angle/checkout/src/common/PoolAlloc.cpp @@ -0,0 +1,487 @@ +// +// Copyright 2019 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. +// +// PoolAlloc.cpp: +// Implements the class methods for PoolAllocator and Allocation classes. +// + +#include "common/PoolAlloc.h" + +#include +#include +#include + +#include "common/angleutils.h" +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/platform.h" +#include "common/tls.h" + +namespace angle +{ +// If we are using guard blocks, we must track each individual allocation. If we aren't using guard +// blocks, these never get instantiated, so won't have any impact. + +class Allocation +{ + public: + Allocation(size_t size, unsigned char *mem, Allocation *prev = 0) + : mSize(size), mMem(mem), mPrevAlloc(prev) + { + // Allocations are bracketed: + // + // [allocationHeader][initialGuardBlock][userData][finalGuardBlock] + // + // This would be cleaner with if (kGuardBlockSize)..., but that makes the compiler print + // warnings about 0 length memsets, even with the if() protecting them. +#if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS) + memset(preGuard(), kGuardBlockBeginVal, kGuardBlockSize); + memset(data(), kUserDataFill, mSize); + memset(postGuard(), kGuardBlockEndVal, kGuardBlockSize); +#endif + } + + void checkAllocList() const; + + static size_t AlignedHeaderSize(uint8_t *allocationBasePtr, size_t alignment) + { + // Make sure that the data offset after the header is aligned to the given alignment. + size_t base = reinterpret_cast(allocationBasePtr); + return rx::roundUpPow2(base + kGuardBlockSize + HeaderSize(), alignment) - base; + } + + // Return total size needed to accommodate user buffer of 'size', + // plus our tracking data and any necessary alignments. + static size_t AllocationSize(uint8_t *allocationBasePtr, + size_t size, + size_t alignment, + size_t *preAllocationPaddingOut) + { + // The allocation will be laid out as such: + // + // Aligned to |alignment| + // ^ + // preAllocationPaddingOut | + // ___^___ | + // / \ | + // [header][guard][data][guard] + // \___________ __________/ + // V + // dataOffset + // + // Note that alignment is at least as much as a pointer alignment, so the pointers in the + // header are also necessarily aligned appropriately. + // + size_t dataOffset = AlignedHeaderSize(allocationBasePtr, alignment); + *preAllocationPaddingOut = dataOffset - HeaderSize() - kGuardBlockSize; + + return dataOffset + size + kGuardBlockSize; + } + + // Given memory pointing to |header|, returns |data|. + static uint8_t *GetDataPointer(uint8_t *memory, size_t alignment) + { + uint8_t *alignedPtr = memory + kGuardBlockSize + HeaderSize(); + + // |memory| must be aligned already such that user data is aligned to |alignment|. + ASSERT((reinterpret_cast(alignedPtr) & (alignment - 1)) == 0); + + return alignedPtr; + } + + private: + void checkGuardBlock(unsigned char *blockMem, unsigned char val, const char *locText) const; + + void checkAlloc() const + { + checkGuardBlock(preGuard(), kGuardBlockBeginVal, "before"); + checkGuardBlock(postGuard(), kGuardBlockEndVal, "after"); + } + + // Find offsets to pre and post guard blocks, and user data buffer + unsigned char *preGuard() const { return mMem + HeaderSize(); } + unsigned char *data() const { return preGuard() + kGuardBlockSize; } + unsigned char *postGuard() const { return data() + mSize; } + size_t mSize; // size of the user data area + unsigned char *mMem; // beginning of our allocation (points to header) + Allocation *mPrevAlloc; // prior allocation in the chain + + static constexpr unsigned char kGuardBlockBeginVal = 0xfb; + static constexpr unsigned char kGuardBlockEndVal = 0xfe; + static constexpr unsigned char kUserDataFill = 0xcd; +#if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS) + static constexpr size_t kGuardBlockSize = 16; + static constexpr size_t HeaderSize() { return sizeof(Allocation); } +#else + static constexpr size_t kGuardBlockSize = 0; + static constexpr size_t HeaderSize() { return 0; } +#endif +}; + +#if !defined(ANGLE_DISABLE_POOL_ALLOC) +class PageHeader +{ + public: + PageHeader(PageHeader *nextPage, size_t pageCount) + : nextPage(nextPage), + pageCount(pageCount) +# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS) + , + lastAllocation(nullptr) +# endif + {} + + ~PageHeader() + { +# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS) + if (lastAllocation) + { + lastAllocation->checkAllocList(); + } +# endif + } + + PageHeader *nextPage; + size_t pageCount; +# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS) + Allocation *lastAllocation; +# endif +}; +#endif + +// +// Implement the functionality of the PoolAllocator class, which +// is documented in PoolAlloc.h. +// +PoolAllocator::PoolAllocator(int growthIncrement, int allocationAlignment) + : mAlignment(allocationAlignment), +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + mPageSize(growthIncrement), + mFreeList(nullptr), + mInUseList(nullptr), + mNumCalls(0), + mTotalBytes(0), +#endif + mLocked(false) +{ + initialize(growthIncrement, allocationAlignment); +} + +void PoolAllocator::initialize(int pageSize, int alignment) +{ + mAlignment = alignment; +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + mPageSize = pageSize; + mPageHeaderSkip = sizeof(PageHeader); + + // Alignment == 1 is a special fast-path where fastAllocate() is enabled + if (mAlignment != 1) + { +#endif + // Adjust mAlignment to be at least pointer aligned and + // power of 2. + // + size_t minAlign = sizeof(void *); + if (mAlignment < minAlign) + { + mAlignment = minAlign; + } + mAlignment = gl::ceilPow2(static_cast(mAlignment)); +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + } + // + // Don't allow page sizes we know are smaller than all common + // OS page sizes. + // + if (mPageSize < 4 * 1024) + { + mPageSize = 4 * 1024; + } + + // + // A large mCurrentPageOffset indicates a new page needs to + // be obtained to allocate memory. + // + mCurrentPageOffset = mPageSize; + +#else // !defined(ANGLE_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif +} + +PoolAllocator::~PoolAllocator() +{ +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + while (mInUseList) + { + PageHeader *next = mInUseList->nextPage; + mInUseList->~PageHeader(); + delete[] reinterpret_cast(mInUseList); + mInUseList = next; + } + // We should not check the guard blocks + // here, because we did it already when the block was + // placed into the free list. + // + while (mFreeList) + { + PageHeader *next = mFreeList->nextPage; + delete[] reinterpret_cast(mFreeList); + mFreeList = next; + } +#else // !defined(ANGLE_DISABLE_POOL_ALLOC) + for (auto &allocs : mStack) + { + for (auto alloc : allocs) + { + free(alloc); + } + } + mStack.clear(); +#endif +} + +// +// Check a single guard block for damage +// +void Allocation::checkGuardBlock(unsigned char *blockMem, + unsigned char val, + const char *locText) const +{ +#if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS) + for (size_t x = 0; x < kGuardBlockSize; x++) + { + if (blockMem[x] != val) + { + char assertMsg[80]; + // We don't print the assert message. It's here just to be helpful. + snprintf(assertMsg, sizeof(assertMsg), + "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", locText, mSize, data()); + assert(0 && "PoolAlloc: Damage in guard block"); + } + } +#endif +} + +void PoolAllocator::push() +{ +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + AllocState state = {mCurrentPageOffset, mInUseList}; + + mStack.push_back(state); + + // + // Indicate there is no current page to allocate from. + // + mCurrentPageOffset = mPageSize; +#else // !defined(ANGLE_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif +} + +// Do a mass-deallocation of all the individual allocations that have occurred since the last +// push(), or since the last pop(), or since the object's creation. +// +// The deallocated pages are saved for future allocations. +void PoolAllocator::pop() +{ + if (mStack.size() < 1) + { + return; + } + +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + PageHeader *page = mStack.back().page; + mCurrentPageOffset = mStack.back().offset; + + while (mInUseList != page) + { + // invoke destructor to free allocation list + mInUseList->~PageHeader(); + + PageHeader *nextInUse = mInUseList->nextPage; + if (mInUseList->pageCount > 1) + { + delete[] reinterpret_cast(mInUseList); + } + else + { + mInUseList->nextPage = mFreeList; + mFreeList = mInUseList; + } + mInUseList = nextInUse; + } + + mStack.pop_back(); +#else // !defined(ANGLE_DISABLE_POOL_ALLOC) + for (auto &alloc : mStack.back()) + { + free(alloc); + } + mStack.pop_back(); +#endif +} + +// +// Do a mass-deallocation of all the individual allocations +// that have occurred. +// +void PoolAllocator::popAll() +{ + while (mStack.size() > 0) + pop(); +} + +void *PoolAllocator::allocate(size_t numBytes) +{ + ASSERT(!mLocked); + +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + // + // Just keep some interesting statistics. + // + ++mNumCalls; + mTotalBytes += numBytes; + + uint8_t *currentPagePtr = reinterpret_cast(mInUseList) + mCurrentPageOffset; + + size_t preAllocationPadding = 0; + size_t allocationSize = + Allocation::AllocationSize(currentPagePtr, numBytes, mAlignment, &preAllocationPadding); + + // Integer overflow is unexpected. + ASSERT(allocationSize >= numBytes); + + // Do the allocation, most likely case first, for efficiency. + if (allocationSize <= mPageSize - mCurrentPageOffset) + { + // There is enough room to allocate from the current page at mCurrentPageOffset. + uint8_t *memory = currentPagePtr + preAllocationPadding; + mCurrentPageOffset += allocationSize; + + return initializeAllocation(memory, numBytes); + } + + if (allocationSize > mPageSize - mPageHeaderSkip) + { + // If the allocation is larger than a whole page, do a multi-page allocation. These are not + // mixed with the others. The OS is efficient in allocating and freeing multiple pages. + + // We don't know what the alignment of the new allocated memory will be, so conservatively + // allocate enough memory for up to alignment extra bytes being needed. + allocationSize = Allocation::AllocationSize(reinterpret_cast(mPageHeaderSkip), + numBytes, mAlignment, &preAllocationPadding); + + size_t numBytesToAlloc = allocationSize + mPageHeaderSkip + mAlignment; + + // Integer overflow is unexpected. + ASSERT(numBytesToAlloc >= allocationSize); + + PageHeader *memory = reinterpret_cast(::new char[numBytesToAlloc]); + if (memory == nullptr) + { + return nullptr; + } + + // Use placement-new to initialize header + new (memory) PageHeader(mInUseList, (numBytesToAlloc + mPageSize - 1) / mPageSize); + mInUseList = memory; + + // Make next allocation come from a new page + mCurrentPageOffset = mPageSize; + + // Now that we actually have the pointer, make sure the data pointer will be aligned. + currentPagePtr = reinterpret_cast(memory) + mPageHeaderSkip; + Allocation::AllocationSize(currentPagePtr, numBytes, mAlignment, &preAllocationPadding); + + return initializeAllocation(currentPagePtr + preAllocationPadding, numBytes); + } + + uint8_t *newPageAddr = allocateNewPage(numBytes); + return initializeAllocation(newPageAddr, numBytes); + +#else // !defined(ANGLE_DISABLE_POOL_ALLOC) + + void *alloc = malloc(numBytes + mAlignment - 1); + mStack.back().push_back(alloc); + + intptr_t intAlloc = reinterpret_cast(alloc); + intAlloc = rx::roundUpPow2(intAlloc, mAlignment); + return reinterpret_cast(intAlloc); +#endif +} + +#if !defined(ANGLE_DISABLE_POOL_ALLOC) +uint8_t *PoolAllocator::allocateNewPage(size_t numBytes) +{ + // Need a simple page to allocate from. Pick a page from the free list, if any. Otherwise need + // to make the allocation. + PageHeader *memory; + if (mFreeList) + { + memory = mFreeList; + mFreeList = mFreeList->nextPage; + } + else + { + memory = reinterpret_cast(::new char[mPageSize]); + if (memory == nullptr) + { + return nullptr; + } + } + // Use placement-new to initialize header + new (memory) PageHeader(mInUseList, 1); + mInUseList = memory; + + // Leave room for the page header. + mCurrentPageOffset = mPageHeaderSkip; + uint8_t *currentPagePtr = reinterpret_cast(mInUseList) + mCurrentPageOffset; + + size_t preAllocationPadding = 0; + size_t allocationSize = + Allocation::AllocationSize(currentPagePtr, numBytes, mAlignment, &preAllocationPadding); + + mCurrentPageOffset += allocationSize; + + // The new allocation is made after the page header and any alignment required before it. + return reinterpret_cast(mInUseList) + mPageHeaderSkip + preAllocationPadding; +} + +void *PoolAllocator::initializeAllocation(uint8_t *memory, size_t numBytes) +{ +# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS) + new (memory) Allocation(numBytes, memory, mInUseList->lastAllocation); + mInUseList->lastAllocation = reinterpret_cast(memory); +# endif + + return Allocation::GetDataPointer(memory, mAlignment); +} +#endif + +void PoolAllocator::lock() +{ + ASSERT(!mLocked); + mLocked = true; +} + +void PoolAllocator::unlock() +{ + ASSERT(mLocked); + mLocked = false; +} + +// +// Check all allocations in a list for damage by calling check on each. +// +void Allocation::checkAllocList() const +{ + for (const Allocation *alloc = this; alloc != nullptr; alloc = alloc->mPrevAlloc) + { + alloc->checkAlloc(); + } +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/PoolAlloc.h b/gfx/angle/checkout/src/common/PoolAlloc.h new file mode 100644 index 0000000000..536848f198 --- /dev/null +++ b/gfx/angle/checkout/src/common/PoolAlloc.h @@ -0,0 +1,181 @@ +// +// Copyright 2019 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. +// +// PoolAlloc.h: +// Defines the class interface for PoolAllocator. +// + +#ifndef COMMON_POOLALLOC_H_ +#define COMMON_POOLALLOC_H_ + +#if !defined(NDEBUG) +# define ANGLE_POOL_ALLOC_GUARD_BLOCKS // define to enable guard block checking +#endif + +// +// This header defines an allocator that can be used to efficiently +// allocate a large number of small requests for heap memory, with the +// intention that they are not individually deallocated, but rather +// collectively deallocated at one time. +// +// This simultaneously +// +// * Makes each individual allocation much more efficient; the +// typical allocation is trivial. +// * Completely avoids the cost of doing individual deallocation. +// * Saves the trouble of tracking down and plugging a large class of leaks. +// +// Individual classes can use this allocator by supplying their own +// new and delete methods. +// + +#include "angleutils.h" +#include "common/debug.h" + +namespace angle +{ +class Allocation; +class PageHeader; + +// +// There are several stacks. One is to track the pushing and popping +// of the user, and not yet implemented. The others are simply a +// repositories of free pages or used pages. +// +// Page stacks are linked together with a simple header at the beginning +// of each allocation obtained from the underlying OS. Multi-page allocations +// are returned to the OS. Individual page allocations are kept for future +// re-use. +// +// The "page size" used is not, nor must it match, the underlying OS +// page size. But, having it be about that size or equal to a set of +// pages is likely most optimal. +// +class PoolAllocator : angle::NonCopyable +{ + public: + static const int kDefaultAlignment = sizeof(void *); + // + // Create PoolAllocator. If alignment is set to 1 byte then fastAllocate() + // function can be used to make allocations with less overhead. + // + PoolAllocator(int growthIncrement = 8 * 1024, int allocationAlignment = kDefaultAlignment); + + // + // Don't call the destructor just to free up the memory, call pop() + // + ~PoolAllocator(); + + // + // Initialize page size and alignment after construction + // + void initialize(int pageSize, int alignment); + + // + // Call push() to establish a new place to pop memory to. Does not + // have to be called to get things started. + // + void push(); + + // + // Call pop() to free all memory allocated since the last call to push(), + // or if no last call to push, frees all memory since first allocation. + // + void pop(); + + // + // Call popAll() to free all memory allocated. + // + void popAll(); + + // + // Call allocate() to actually acquire memory. Returns 0 if no memory + // available, otherwise a properly aligned pointer to 'numBytes' of memory. + // + void *allocate(size_t numBytes); + + // + // Call fastAllocate() for a faster allocate function that does minimal bookkeeping + // preCondition: Allocator must have been created w/ alignment of 1 + ANGLE_INLINE uint8_t *fastAllocate(size_t numBytes) + { +#if defined(ANGLE_DISABLE_POOL_ALLOC) + return reinterpret_cast(allocate(numBytes)); +#else + ASSERT(mAlignment == 1); + // No multi-page allocations + ASSERT(numBytes <= (mPageSize - mPageHeaderSkip)); + // + // Do the allocation, most likely case inline first, for efficiency. + // + if (numBytes <= mPageSize - mCurrentPageOffset) + { + // + // Safe to allocate from mCurrentPageOffset. + // + uint8_t *memory = reinterpret_cast(mInUseList) + mCurrentPageOffset; + mCurrentPageOffset += numBytes; + return memory; + } + return allocateNewPage(numBytes); +#endif + } + + // There is no deallocate. The point of this class is that deallocation can be skipped by the + // user of it, as the model of use is to simultaneously deallocate everything at once by calling + // pop(), and to not have to solve memory leak problems. + + // Catch unwanted allocations. + // TODO(jmadill): Remove this when we remove the global allocator. + void lock(); + void unlock(); + + private: + size_t mAlignment; // all returned allocations will be aligned at + // this granularity, which will be a power of 2 +#if !defined(ANGLE_DISABLE_POOL_ALLOC) + struct AllocState + { + size_t offset; + PageHeader *page; + }; + using AllocStack = std::vector; + + // Slow path of allocation when we have to get a new page. + uint8_t *allocateNewPage(size_t numBytes); + // Track allocations if and only if we're using guard blocks + void *initializeAllocation(uint8_t *memory, size_t numBytes); + + // Granularity of allocation from the OS + size_t mPageSize; + // Amount of memory to skip to make room for the page header (which is the size of the page + // header, or PageHeader in PoolAlloc.cpp) + size_t mPageHeaderSkip; + // Next offset in top of inUseList to allocate from. This offset is not necessarily aligned to + // anything. When an allocation is made, the data is aligned to mAlignment, and the header (if + // any) will align to pointer size by extension (since mAlignment is made aligned to at least + // pointer size). + size_t mCurrentPageOffset; + // List of popped memory + PageHeader *mFreeList; + // List of all memory currently being used. The head of this list is where allocations are + // currently being made from. + PageHeader *mInUseList; + // Stack of where to allocate from, to partition pool + AllocStack mStack; + + int mNumCalls; // just an interesting statistic + size_t mTotalBytes; // just an interesting statistic + +#else // !defined(ANGLE_DISABLE_POOL_ALLOC) + std::vector> mStack; +#endif + + bool mLocked; +}; + +} // namespace angle + +#endif // COMMON_POOLALLOC_H_ diff --git a/gfx/angle/checkout/src/common/Spinlock.h b/gfx/angle/checkout/src/common/Spinlock.h new file mode 100644 index 0000000000..494da0943e --- /dev/null +++ b/gfx/angle/checkout/src/common/Spinlock.h @@ -0,0 +1,71 @@ +// +// Copyright 2021 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. +// +// Spinlock.h: +// Spinlock is a lock that loops actively until it gets the resource. +// Only use it when the lock will be granted in reasonably short time. + +#ifndef COMMON_SPINLOCK_H_ +#define COMMON_SPINLOCK_H_ + +#include + +// TODO(jplate) Add pause for ARM, http://anglebug.com:6067 +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) +extern "C" void _mm_pause(); +# pragma intrinsic(_mm_pause) +# define ANGLE_SMT_PAUSE() _mm_pause() +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +# define ANGLE_SMT_PAUSE() __asm__ __volatile__("pause;") +#else +# define ANGLE_SMT_PAUSE() static_cast(0) +#endif + +namespace angle +{ + +class Spinlock +{ + public: + Spinlock() noexcept; + + bool try_lock() noexcept; + void lock() noexcept; + void unlock() noexcept; + + private: + std::atomic_bool mLock; +}; + +inline Spinlock::Spinlock() noexcept : mLock(false) {} + +inline bool Spinlock::try_lock() noexcept +{ + // Relaxed check first to prevent unnecessary cache misses. + return !mLock.load(std::memory_order_relaxed) && + !mLock.exchange(true, std::memory_order_acquire); +} + +inline void Spinlock::lock() noexcept +{ + while (mLock.exchange(true, std::memory_order_acquire)) + { + // Relaxed wait to prevent unnecessary cache misses. + while (mLock.load(std::memory_order_relaxed)) + { + // Optimization for simultaneous multithreading. + ANGLE_SMT_PAUSE(); + } + } +} + +inline void Spinlock::unlock() noexcept +{ + mLock.store(false, std::memory_order_release); +} + +} // namespace angle + +#endif // COMMON_SPINLOCK_H_ diff --git a/gfx/angle/checkout/src/common/SynchronizedValue.h b/gfx/angle/checkout/src/common/SynchronizedValue.h new file mode 100644 index 0000000000..95432cfbcd --- /dev/null +++ b/gfx/angle/checkout/src/common/SynchronizedValue.h @@ -0,0 +1,540 @@ +// +// Copyright 2021 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. +// +// SynchronizedValue.h: +// A class that ensures that the correct mutex is locked when the encapsulated data is accessed. +// Based on boost::synchronized_value, which probably becomes part of the next C++ standard. +// https://www.boost.org/doc/libs/1_76_0/doc/html/thread/sds.html#thread.sds.synchronized_valuesxxx + +#ifndef COMMON_SYNCHRONIZEDVALUE_H_ +#define COMMON_SYNCHRONIZEDVALUE_H_ + +#include "common/debug.h" + +#include +#include + +namespace angle +{ + +template +class ConstStrictLockPtr +{ + public: + using value_type = T; + using mutex_type = Lockable; + + ConstStrictLockPtr(const T &value, Lockable &mutex) : mLock(mutex), mValue(value) {} + ConstStrictLockPtr(const T &value, Lockable &mutex, std::adopt_lock_t) noexcept + : mLock(mutex, std::adopt_lock), mValue(value) + {} + + ConstStrictLockPtr(ConstStrictLockPtr &&other) noexcept + : mLock(std::move(other.mLock)), mValue(other.mValue) + {} + + ConstStrictLockPtr(const ConstStrictLockPtr &) = delete; + ConstStrictLockPtr &operator=(const ConstStrictLockPtr &) = delete; + + ~ConstStrictLockPtr() = default; + + const T *operator->() const { return &mValue; } + const T &operator*() const { return mValue; } + + protected: + std::unique_lock mLock; + T const &mValue; +}; + +template +class StrictLockPtr : public ConstStrictLockPtr +{ + private: + using BaseType = ConstStrictLockPtr; + + public: + StrictLockPtr(T &value, Lockable &mutex) : BaseType(value, mutex) {} + StrictLockPtr(T &value, Lockable &mutex, std::adopt_lock_t) noexcept + : BaseType(value, mutex, std::adopt_lock) + {} + + StrictLockPtr(StrictLockPtr &&other) noexcept + : BaseType(std::move(static_cast(other))) + {} + + StrictLockPtr(const StrictLockPtr &) = delete; + StrictLockPtr &operator=(const StrictLockPtr &) = delete; + + ~StrictLockPtr() = default; + + T *operator->() { return const_cast(&this->mValue); } + T &operator*() { return const_cast(this->mValue); } +}; + +template +struct SynchronizedValueStrictLockPtr +{ + using type = StrictLockPtr; +}; + +template +struct SynchronizedValueStrictLockPtr +{ + using type = ConstStrictLockPtr; +}; + +template +class ConstUniqueLockPtr : public std::unique_lock +{ + private: + using BaseType = std::unique_lock; + + public: + using value_type = T; + using mutex_type = Lockable; + + ConstUniqueLockPtr(const T &value, Lockable &mutex) : BaseType(mutex), mValue(value) {} + ConstUniqueLockPtr(const T &value, Lockable &mutex, std::adopt_lock_t) noexcept + : BaseType(mutex, std::adopt_lock), mValue(value) + {} + ConstUniqueLockPtr(const T &value, Lockable &mutex, std::defer_lock_t) noexcept + : BaseType(mutex, std::defer_lock), mValue(value) + {} + ConstUniqueLockPtr(const T &value, Lockable &mutex, std::try_to_lock_t) noexcept + : BaseType(mutex, std::try_to_lock), mValue(value) + {} + + ConstUniqueLockPtr(ConstUniqueLockPtr &&other) noexcept + : BaseType(std::move(static_cast(other))), mValue(other.mValue) + {} + + ConstUniqueLockPtr(const ConstUniqueLockPtr &) = delete; + ConstUniqueLockPtr &operator=(const ConstUniqueLockPtr &) = delete; + + ~ConstUniqueLockPtr() = default; + + const T *operator->() const + { + ASSERT(this->owns_lock()); + return &mValue; + } + const T &operator*() const + { + ASSERT(this->owns_lock()); + return mValue; + } + + protected: + T const &mValue; +}; + +template +class UniqueLockPtr : public ConstUniqueLockPtr +{ + private: + using BaseType = ConstUniqueLockPtr; + + public: + UniqueLockPtr(T &value, Lockable &mutex) : BaseType(value, mutex) {} + UniqueLockPtr(T &value, Lockable &mutex, std::adopt_lock_t) noexcept + : BaseType(value, mutex, std::adopt_lock) + {} + UniqueLockPtr(T &value, Lockable &mutex, std::defer_lock_t) noexcept + : BaseType(value, mutex, std::defer_lock) + {} + UniqueLockPtr(T &value, Lockable &mutex, std::try_to_lock_t) noexcept + : BaseType(value, mutex, std::try_to_lock) + {} + + UniqueLockPtr(UniqueLockPtr &&other) noexcept + : BaseType(std::move(static_cast(other))) + {} + + UniqueLockPtr(const UniqueLockPtr &) = delete; + UniqueLockPtr &operator=(const UniqueLockPtr &) = delete; + + ~UniqueLockPtr() = default; + + T *operator->() + { + ASSERT(this->owns_lock()); + return const_cast(&this->mValue); + } + T &operator*() + { + ASSERT(this->owns_lock()); + return const_cast(this->mValue); + } +}; + +template +struct SynchronizedValueUniqueLockPtr +{ + using type = UniqueLockPtr; +}; + +template +struct SynchronizedValueUniqueLockPtr +{ + using type = ConstUniqueLockPtr; +}; + +template +class SynchronizedValue +{ + public: + using value_type = T; + using mutex_type = Lockable; + + SynchronizedValue() noexcept(std::is_nothrow_default_constructible::value) : mValue() {} + + SynchronizedValue(const T &other) noexcept(std::is_nothrow_copy_constructible::value) + : mValue(other) + {} + + SynchronizedValue(T &&other) noexcept(std::is_nothrow_move_constructible::value) + : mValue(std::move(other)) + {} + + template + SynchronizedValue(Args &&... args) noexcept(noexcept(T(std::forward(args)...))) + : mValue(std::forward(args)...) + {} + + SynchronizedValue(const SynchronizedValue &other) + { + std::lock_guard lock(other.mMutex); + mValue = other.mValue; + } + + SynchronizedValue(SynchronizedValue &&other) + { + std::lock_guard lock(other.mMutex); + mValue = std::move(other.mValue); + } + + SynchronizedValue &operator=(const SynchronizedValue &other) + { + if (&other != this) + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + mValue = other.mValue; + } + return *this; + } + + SynchronizedValue &operator=(SynchronizedValue &&other) + { + if (&other != this) + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + mValue = std::move(other.mValue); + } + return *this; + } + + SynchronizedValue &operator=(const T &value) + { + { + std::lock_guard lock(mMutex); + mValue = value; + } + return *this; + } + + SynchronizedValue &operator=(T &&value) + { + { + std::lock_guard lock(mMutex); + mValue = std::move(value); + } + return *this; + } + + T get() const + { + std::lock_guard lock(mMutex); + return mValue; + } + + explicit operator T() const { return get(); } + + void swap(SynchronizedValue &other) + { + if (this == &other) + { + return; + } + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + std::swap(mValue, other.mValue); + } + + void swap(T &other) + { + std::lock_guard lock(mMutex); + std::swap(mValue, other); + } + + StrictLockPtr operator->() { return StrictLockPtr(mValue, mMutex); } + ConstStrictLockPtr operator->() const + { + return ConstStrictLockPtr(mValue, mMutex); + } + + StrictLockPtr synchronize() { return StrictLockPtr(mValue, mMutex); } + ConstStrictLockPtr synchronize() const + { + return ConstStrictLockPtr(mValue, mMutex); + } + + UniqueLockPtr unique_synchronize() + { + return UniqueLockPtr(mValue, mMutex); + } + ConstUniqueLockPtr unique_synchronize() const + { + return ConstUniqueLockPtr(mValue, mMutex); + } + + UniqueLockPtr defer_synchronize() noexcept + { + return UniqueLockPtr(mValue, mMutex, std::defer_lock); + } + ConstUniqueLockPtr defer_synchronize() const noexcept + { + return ConstUniqueLockPtr(mValue, mMutex, std::defer_lock); + } + + UniqueLockPtr try_to_synchronize() noexcept + { + return UniqueLockPtr(mValue, mMutex, std::try_to_lock); + } + ConstUniqueLockPtr try_to_synchronize() const noexcept + { + return ConstUniqueLockPtr(mValue, mMutex, std::try_to_lock); + } + + UniqueLockPtr adopt_synchronize() noexcept + { + return UniqueLockPtr(mValue, mMutex, std::adopt_lock); + } + ConstUniqueLockPtr adopt_synchronize() const noexcept + { + return ConstUniqueLockPtr(mValue, mMutex, std::adopt_lock); + } + + class DerefValue + { + public: + DerefValue(DerefValue &&other) : mLock(std::move(other.mLock)), mValue(other.mValue) {} + + DerefValue(const DerefValue &) = delete; + DerefValue &operator=(const DerefValue &) = delete; + + operator T &() { return mValue; } + + DerefValue &operator=(const T &other) + { + mValue = other; + return *this; + } + + private: + explicit DerefValue(SynchronizedValue &outer) : mLock(outer.mMutex), mValue(outer.mValue) {} + + std::unique_lock mLock; + T &mValue; + + friend class SynchronizedValue; + }; + + class ConstDerefValue + { + public: + ConstDerefValue(ConstDerefValue &&other) + : mLock(std::move(other.mLock)), mValue(other.mValue) + {} + + ConstDerefValue(const ConstDerefValue &) = delete; + ConstDerefValue &operator=(const ConstDerefValue &) = delete; + + operator const T &() { return mValue; } + + private: + explicit ConstDerefValue(const SynchronizedValue &outer) + : mLock(outer.mMutex), mValue(outer.mValue) + {} + + std::unique_lock mLock; + const T &mValue; + + friend class SynchronizedValue; + }; + + DerefValue operator*() { return DerefValue(*this); } + ConstDerefValue operator*() const { return ConstDerefValue(*this); } + + template + void save(OStream &os) const + { + std::lock_guard lock(mMutex); + os << mValue; + } + + template + void load(IStream &is) + { + std::lock_guard lock(mMutex); + is >> mValue; + } + + bool operator==(const SynchronizedValue &other) const + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + return mValue == other.mValue; + } + + bool operator!=(const SynchronizedValue &other) const + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + return mValue != other.mValue; + } + + bool operator<(const SynchronizedValue &other) const + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + return mValue < other.mValue; + } + + bool operator>(const SynchronizedValue &other) const + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + return mValue > other.mValue; + } + + bool operator<=(const SynchronizedValue &other) const + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + return mValue <= other.mValue; + } + + bool operator>=(const SynchronizedValue &other) const + { + std::unique_lock lock1(mMutex, std::defer_lock); + std::unique_lock lock2(other.mMutex, std::defer_lock); + std::lock(lock1, lock2); + return mValue >= other.mValue; + } + + bool operator==(const T &other) const + { + std::lock_guard lock(mMutex); + return mValue == other; + } + + bool operator!=(const T &other) const + { + std::lock_guard lock(mMutex); + return mValue != other; + } + + bool operator<(const T &other) const + { + std::lock_guard lock(mMutex); + return mValue < other; + } + + bool operator>(const T &other) const + { + std::lock_guard lock(mMutex); + return mValue > other; + } + + bool operator<=(const T &other) const + { + std::lock_guard lock(mMutex); + return mValue <= other; + } + + bool operator>=(const T &other) const + { + std::lock_guard lock(mMutex); + return mValue >= other; + } + + private: + T mValue; + mutable Lockable mMutex; +}; + +template +inline OStream &operator<<(OStream &os, SynchronizedValue const &sv) +{ + sv.save(os); + return os; +} + +template +inline IStream &operator>>(IStream &is, SynchronizedValue &sv) +{ + sv.load(is); + return is; +} + +template +bool operator==(const T &lhs, const SynchronizedValue &rhs) +{ + return rhs == lhs; +} + +template +bool operator!=(const T &lhs, const SynchronizedValue &rhs) +{ + return rhs != lhs; +} + +template +bool operator<(const T &lhs, const SynchronizedValue &rhs) +{ + return rhs < lhs; +} + +template +bool operator>(const T &lhs, const SynchronizedValue &rhs) +{ + return rhs > lhs; +} + +template +bool operator<=(const T &lhs, const SynchronizedValue &rhs) +{ + return rhs <= lhs; +} + +template +bool operator>=(const T &lhs, const SynchronizedValue &rhs) +{ + return rhs >= lhs; +} + +} // namespace angle + +#endif // COMMON_SYNCHRONIZEDVALUE_H_ diff --git a/gfx/angle/checkout/src/common/aligned_memory.cpp b/gfx/angle/checkout/src/common/aligned_memory.cpp new file mode 100644 index 0000000000..9798fc0f42 --- /dev/null +++ b/gfx/angle/checkout/src/common/aligned_memory.cpp @@ -0,0 +1,64 @@ +// +// Copyright 2017 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. +// +// aligned_memory: An aligned memory allocator. Based on Chrome's base/memory/aligned_memory. +// + +#include "common/aligned_memory.h" + +#include "common/debug.h" +#include "common/platform.h" + +#if defined(COMPILER_MSVC) +# include +#else +# include +#endif + +namespace angle +{ + +void *AlignedAlloc(size_t size, size_t alignment) +{ + ASSERT(size > 0); + ASSERT((alignment & (alignment - 1)) == 0); + ASSERT((alignment % sizeof(void *)) == 0); + void *ptr = nullptr; +#if defined(ANGLE_PLATFORM_WINDOWS) + ptr = _aligned_malloc(size, alignment); +// Android technically supports posix_memalign(), but does not expose it in +// the current version of the library headers used by Chrome. Luckily, +// memalign() on Android returns pointers which can safely be used with +// free(), so we can use it instead. Issue filed to document this: +// http://code.google.com/p/android/issues/detail?id=35391 +#elif defined(ANGLE_PLATFORM_ANDROID) + ptr = memalign(alignment, size); +#else + if (posix_memalign(&ptr, alignment, size)) + ptr = nullptr; +#endif + // Since aligned allocations may fail for non-memory related reasons, force a + // crash if we encounter a failed allocation. + if (!ptr) + { + ERR() << "If you crashed here, your aligned allocation is incorrect: " + << "size=" << size << ", alignment=" << alignment; + ASSERT(false); + } + // Confidence check alignment just to be safe. + ASSERT((reinterpret_cast(ptr) & (alignment - 1)) == 0); + return ptr; +} + +void AlignedFree(void *ptr) +{ +#if defined(ANGLE_PLATFORM_WINDOWS) + _aligned_free(ptr); +#else + free(ptr); +#endif +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/aligned_memory.h b/gfx/angle/checkout/src/common/aligned_memory.h new file mode 100644 index 0000000000..dcbb60d1cb --- /dev/null +++ b/gfx/angle/checkout/src/common/aligned_memory.h @@ -0,0 +1,23 @@ +// +// Copyright 2017 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. +// +// aligned_memory: An aligned memory allocator. Based on Chrome's base/memory/aligned_memory. +// + +#ifndef COMMON_ALIGNED_MEMORY_H_ +#define COMMON_ALIGNED_MEMORY_H_ + +#include + +namespace angle +{ + +// This can be replaced with std::aligned_malloc when we have C++17. +void *AlignedAlloc(size_t size, size_t alignment); +void AlignedFree(void *ptr); + +} // namespace angle + +#endif // COMMON_ALIGNED_MEMORY_H_ diff --git a/gfx/angle/checkout/src/common/android_util.cpp b/gfx/angle/checkout/src/common/android_util.cpp new file mode 100644 index 0000000000..8188da21ef --- /dev/null +++ b/gfx/angle/checkout/src/common/android_util.cpp @@ -0,0 +1,424 @@ +// +// Copyright 2018 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. +// + +// android_util.cpp: Utilities for the using the Android platform + +#include "common/android_util.h" +#include "common/debug.h" + +#include + +#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26 +# define ANGLE_AHARDWARE_BUFFER_SUPPORT +// NDK header file for access to Android Hardware Buffers +# include +#endif + +// Taken from cutils/native_handle.h: +// https://android.googlesource.com/platform/system/core/+/master/libcutils/include/cutils/native_handle.h +typedef struct native_handle +{ + int version; /* sizeof(native_handle_t) */ + int numFds; /* number of file-descriptors at &data[0] */ + int numInts; /* number of ints at &data[numFds] */ +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wzero-length-array" +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 4200) +#endif + int data[0]; /* numFds + numInts ints */ +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(_MSC_VER) +# pragma warning(pop) +#endif +} native_handle_t; + +// Taken from nativebase/nativebase.h +// https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativebase/include/nativebase/nativebase.h +typedef const native_handle_t *buffer_handle_t; + +typedef struct android_native_base_t +{ + /* a magic value defined by the actual EGL native type */ + int magic; + /* the sizeof() of the actual EGL native type */ + int version; + void *reserved[4]; + /* reference-counting interface */ + void (*incRef)(struct android_native_base_t *base); + void (*decRef)(struct android_native_base_t *base); +} android_native_base_t; + +typedef struct ANativeWindowBuffer +{ + struct android_native_base_t common; + int width; + int height; + int stride; + int format; + int usage_deprecated; + uintptr_t layerCount; + void *reserved[1]; + const native_handle_t *handle; + uint64_t usage; + // we needed extra space for storing the 64-bits usage flags + // the number of slots to use from reserved_proc depends on the + // architecture. + void *reserved_proc[8 - (sizeof(uint64_t) / sizeof(void *))]; +} ANativeWindowBuffer_t; + +// Taken from android/hardware_buffer.h +// https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativewindow/include/android/hardware_buffer.h + +// AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM, +// AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM formats were deprecated and re-added explicitly. + +// clang-format off +/** + * Buffer pixel formats. + */ +enum { + +#ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_R8G8B8A8_UNORM + * OpenGL ES: GL_RGBA8 + */ + AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1, + + /** + * 32 bits per pixel, 8 bits per channel format where alpha values are + * ignored (always opaque). + * Corresponding formats: + * Vulkan: VK_FORMAT_R8G8B8A8_UNORM + * OpenGL ES: GL_RGB8 + */ + AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM = 2, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_R8G8B8_UNORM + * OpenGL ES: GL_RGB8 + */ + AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM = 3, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16 + * OpenGL ES: GL_RGB565 + */ + AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM = 4, +#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT + + AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM = 5, + AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM = 6, + AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM = 7, + +#ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT + * OpenGL ES: GL_RGBA16F + */ + AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT = 0x16, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_A2B10G10R10_UNORM_PACK32 + * OpenGL ES: GL_RGB10_A2 + */ + AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM = 0x2b, + + /** + * An opaque binary blob format that must have height 1, with width equal to + * the buffer size in bytes. + */ + AHARDWAREBUFFER_FORMAT_BLOB = 0x21, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_D16_UNORM + * OpenGL ES: GL_DEPTH_COMPONENT16 + */ + AHARDWAREBUFFER_FORMAT_D16_UNORM = 0x30, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_X8_D24_UNORM_PACK32 + * OpenGL ES: GL_DEPTH_COMPONENT24 + */ + AHARDWAREBUFFER_FORMAT_D24_UNORM = 0x31, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_D24_UNORM_S8_UINT + * OpenGL ES: GL_DEPTH24_STENCIL8 + */ + AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT = 0x32, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_D32_SFLOAT + * OpenGL ES: GL_DEPTH_COMPONENT32F + */ + AHARDWAREBUFFER_FORMAT_D32_FLOAT = 0x33, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_D32_SFLOAT_S8_UINT + * OpenGL ES: GL_DEPTH32F_STENCIL8 + */ + AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT = 0x34, + + /** + * Corresponding formats: + * Vulkan: VK_FORMAT_S8_UINT + * OpenGL ES: GL_STENCIL_INDEX8 + */ + AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35, + + /** + * YUV 420 888 format. + * Must have an even width and height. Can be accessed in OpenGL + * shaders through an external sampler. Does not support mip-maps + * cube-maps or multi-layered textures. + */ + AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23, + +#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT + + AHARDWAREBUFFER_FORMAT_YV12 = 0x32315659, + AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED = 0x22, +}; +// clang-format on + +namespace +{ + +// In the Android system: +// - AHardwareBuffer is essentially a typedef of GraphicBuffer. Conversion functions simply +// reinterpret_cast. +// - GraphicBuffer inherits from two base classes, ANativeWindowBuffer and RefBase. +// +// GraphicBuffer implements a getter for ANativeWindowBuffer (getNativeBuffer) by static_casting +// itself to its base class ANativeWindowBuffer. The offset of the ANativeWindowBuffer pointer +// from the GraphicBuffer pointer is 16 bytes. This is likely due to two pointers: The vtable of +// GraphicBuffer and the one pointer member of the RefBase class. +// +// This is not future proof at all. We need to look into getting utilities added to Android to +// perform this cast for us. +constexpr int kAHardwareBufferToANativeWindowBufferOffset = static_cast(sizeof(void *)) * 2; + +template +T1 *OffsetPointer(T2 *ptr, int bytes) +{ + return reinterpret_cast(reinterpret_cast(ptr) + bytes); +} + +GLenum GetPixelFormatInfo(int pixelFormat, bool *isYUV) +{ + *isYUV = false; + switch (pixelFormat) + { + case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: + return GL_RGBA8; + case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: + return GL_RGB8; + case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: + return GL_RGB8; + case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: + return GL_RGB565; + case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM: + return GL_BGRA8_EXT; + case AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM: + return GL_RGB5_A1; + case AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM: + return GL_RGBA4; + case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: + return GL_RGBA16F; + case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: + return GL_RGB10_A2; + case AHARDWAREBUFFER_FORMAT_BLOB: + return GL_NONE; + case AHARDWAREBUFFER_FORMAT_D16_UNORM: + return GL_DEPTH_COMPONENT16; + case AHARDWAREBUFFER_FORMAT_D24_UNORM: + return GL_DEPTH_COMPONENT24; + case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT: + return GL_DEPTH24_STENCIL8; + case AHARDWAREBUFFER_FORMAT_D32_FLOAT: + return GL_DEPTH_COMPONENT32F; + case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT: + return GL_DEPTH32F_STENCIL8; + case AHARDWAREBUFFER_FORMAT_S8_UINT: + return GL_STENCIL_INDEX8; + case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: + case AHARDWAREBUFFER_FORMAT_YV12: + case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED: + *isYUV = true; + return GL_RGB8; + default: + // Treat unknown formats as RGB. They are vendor-specific YUV formats that would sample + // as RGB. + *isYUV = true; + return GL_RGB8; + } +} + +} // anonymous namespace + +namespace angle +{ + +namespace android +{ + +ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer) +{ + return reinterpret_cast(clientBuffer); +} + +uint64_t GetAHBUsage(int eglNativeBufferUsage) +{ + uint64_t ahbUsage = 0; +#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT) + if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) + { + ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT; + } + if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) + { + ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER; + } + if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID) + { + ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; + } +#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT + return ahbUsage; +} + +EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width, + int height, + int depth, + int androidFormat, + int usage) +{ +#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT) + + // The height and width are number of pixels of size format + AHardwareBuffer_Desc aHardwareBufferDescription = {}; + aHardwareBufferDescription.width = static_cast(width); + aHardwareBufferDescription.height = static_cast(height); + aHardwareBufferDescription.layers = static_cast(depth); + aHardwareBufferDescription.format = androidFormat; + aHardwareBufferDescription.usage = GetAHBUsage(usage); + + // Allocate memory from Android Hardware Buffer + AHardwareBuffer *aHardwareBuffer = nullptr; + int res = AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer); + if (res != 0) + { + return nullptr; + } + + return AHardwareBufferToClientBuffer(aHardwareBuffer); +#else + return nullptr; +#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT +} + +void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer, + int *width, + int *height, + int *depth, + int *pixelFormat, + uint64_t *usage) +{ + *width = buffer->width; + *height = buffer->height; + *depth = static_cast(buffer->layerCount); + *height = buffer->height; + *pixelFormat = buffer->format; + *usage = buffer->usage; +} + +GLenum NativePixelFormatToGLInternalFormat(int pixelFormat) +{ + bool isYuv = false; + return GetPixelFormatInfo(pixelFormat, &isYuv); +} + +int GLInternalFormatToNativePixelFormat(GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_RGBA8: + return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; + case GL_RGB8: + return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM; + case GL_RGB565: + return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM; + case GL_BGRA8_EXT: + return AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM; + case GL_RGB5_A1: + return AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM; + case GL_RGBA4: + return AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM; + case GL_RGBA16F: + return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT; + case GL_RGB10_A2: + return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM; + case GL_NONE: + return AHARDWAREBUFFER_FORMAT_BLOB; + case GL_DEPTH_COMPONENT16: + return AHARDWAREBUFFER_FORMAT_D16_UNORM; + case GL_DEPTH_COMPONENT24: + return AHARDWAREBUFFER_FORMAT_D24_UNORM; + case GL_DEPTH24_STENCIL8: + return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT; + case GL_DEPTH_COMPONENT32F: + return AHARDWAREBUFFER_FORMAT_D32_FLOAT; + case GL_DEPTH32F_STENCIL8: + return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT; + case GL_STENCIL_INDEX8: + return AHARDWAREBUFFER_FORMAT_S8_UINT; + default: + WARN() << "Unknown internalFormat: " << internalFormat << ". Treating as 0"; + return 0; + } +} + +bool NativePixelFormatIsYUV(int pixelFormat) +{ + bool isYuv = false; + GetPixelFormatInfo(pixelFormat, &isYuv); + return isYuv; +} + +AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer) +{ + return OffsetPointer(windowBuffer, + -kAHardwareBufferToANativeWindowBufferOffset); +} + +EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer) +{ + return OffsetPointer(hardwareBuffer, + kAHardwareBufferToANativeWindowBufferOffset); +} + +AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer) +{ + return OffsetPointer(clientBuffer, + -kAHardwareBufferToANativeWindowBufferOffset); +} +} // namespace android +} // namespace angle diff --git a/gfx/angle/checkout/src/common/android_util.h b/gfx/angle/checkout/src/common/android_util.h new file mode 100644 index 0000000000..eee60ba244 --- /dev/null +++ b/gfx/angle/checkout/src/common/android_util.h @@ -0,0 +1,59 @@ +// +// Copyright 2018 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. +// + +// android_util.h: Utilities for the using the Android platform + +#ifndef COMMON_ANDROIDUTIL_H_ +#define COMMON_ANDROIDUTIL_H_ + +#include +#include + +#include +#include + +#include "angle_gl.h" + +struct ANativeWindowBuffer; +struct AHardwareBuffer; + +namespace angle +{ + +namespace android +{ + +constexpr std::array kSupportedSizedInternalFormats = {GL_RGBA8, GL_RGB8, GL_RGB565}; + +ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer); +EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer); +AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer); + +EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width, + int height, + int depth, + int androidFormat, + int usage); + +void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer, + int *width, + int *height, + int *depth, + int *pixelFormat, + uint64_t *usage); +GLenum NativePixelFormatToGLInternalFormat(int pixelFormat); +int GLInternalFormatToNativePixelFormat(GLenum internalFormat); + +bool NativePixelFormatIsYUV(int pixelFormat); + +AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer); + +uint64_t GetAHBUsage(int eglNativeBufferUsage); + +} // namespace android +} // namespace angle + +#endif // COMMON_ANDROIDUTIL_H_ diff --git a/gfx/angle/checkout/src/common/angle_version.h b/gfx/angle/checkout/src/common/angle_version.h new file mode 100644 index 0000000000..d9d7e8929d --- /dev/null +++ b/gfx/angle/checkout/src/common/angle_version.h @@ -0,0 +1,28 @@ +// +// Copyright 2014 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. +// +// angle_version.h: ANGLE version constants. Generated from git commands. + +#ifndef COMMON_ANGLE_VERSION_H_ +#define COMMON_ANGLE_VERSION_H_ + +#include "angle_commit.h" + +#define ANGLE_MAJOR_VERSION 2 +#define ANGLE_MINOR_VERSION 1 + +#ifndef ANGLE_REVISION +# define ANGLE_REVISION ANGLE_COMMIT_POSITION +#endif + +#define ANGLE_STRINGIFY(x) #x +#define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x) + +#define ANGLE_VERSION_STRING \ + ANGLE_MACRO_STRINGIFY(ANGLE_MAJOR_VERSION) \ + "." ANGLE_MACRO_STRINGIFY(ANGLE_MINOR_VERSION) "." ANGLE_MACRO_STRINGIFY( \ + ANGLE_REVISION) " git hash: " ANGLE_COMMIT_HASH + +#endif // COMMON_ANGLE_VERSION_H_ diff --git a/gfx/angle/checkout/src/common/angle_version_info.cpp b/gfx/angle/checkout/src/common/angle_version_info.cpp new file mode 100644 index 0000000000..963741a456 --- /dev/null +++ b/gfx/angle/checkout/src/common/angle_version_info.cpp @@ -0,0 +1,40 @@ +// +// Copyright 2021 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. +// +// angle_version_info.cpp: ANGLE version queries. + +#include "common/angle_version.h" + +namespace angle +{ +int GetANGLERevision() +{ + return ANGLE_REVISION; +} + +const char *GetANGLEVersionString() +{ + return ANGLE_VERSION_STRING; +} + +const char *GetANGLECommitHash() +{ + return ANGLE_COMMIT_HASH; +} + +int GetANGLECommitHashSize() +{ + return ANGLE_COMMIT_HASH_SIZE; +} + +bool GetANGLEHasBinaryLoading() +{ +#ifdef ANGLE_HAS_BINARY_LOADING + return true; +#else + return false; +#endif // #ifndef ANGLE_HAS_BINARY_LOADING +} +} // namespace angle diff --git a/gfx/angle/checkout/src/common/angle_version_info.h b/gfx/angle/checkout/src/common/angle_version_info.h new file mode 100644 index 0000000000..1d5392068c --- /dev/null +++ b/gfx/angle/checkout/src/common/angle_version_info.h @@ -0,0 +1,20 @@ +// +// Copyright 2021 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. +// +// angle_version_info.h: ANGLE version queries. + +#ifndef COMMON_VERSION_INFO_H_ +#define COMMON_VERSION_INFO_H_ + +namespace angle +{ +int GetANGLERevision(); +const char *GetANGLEVersionString(); +const char *GetANGLECommitHash(); +int GetANGLECommitHashSize(); +bool GetANGLEHasBinaryLoading(); +} // namespace angle + +#endif // COMMON_VERSION_INFO_H_ diff --git a/gfx/angle/checkout/src/common/angleutils.cpp b/gfx/angle/checkout/src/common/angleutils.cpp new file mode 100644 index 0000000000..2b69f66d74 --- /dev/null +++ b/gfx/angle/checkout/src/common/angleutils.cpp @@ -0,0 +1,156 @@ +// +// Copyright 2014 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. +// + +#include "common/angleutils.h" +#include "common/debug.h" + +#include + +#include +#include + +namespace angle +{ +// dirtyPointer is a special value that will make the comparison with any valid pointer fail and +// force the renderer to re-apply the state. +const uintptr_t DirtyPointer = std::numeric_limits::max(); + +SaveFileHelper::SaveFileHelper(const std::string &filePathIn) + : mOfs(filePathIn, std::ios::binary | std::ios::out), mFilePath(filePathIn) +{ + if (!mOfs.is_open()) + { + FATAL() << "Could not open " << filePathIn; + } +} + +SaveFileHelper::~SaveFileHelper() +{ + printf("Saved '%s'.\n", mFilePath.c_str()); +} + +void SaveFileHelper::checkError() +{ + if (mOfs.bad()) + { + FATAL() << "Error writing to " << mFilePath; + } +} + +void SaveFileHelper::write(const uint8_t *data, size_t size) +{ + mOfs.write(reinterpret_cast(data), size); +} + +// AMD_performance_monitor helpers. + +PerfMonitorCounter::PerfMonitorCounter() = default; + +PerfMonitorCounter::~PerfMonitorCounter() = default; + +PerfMonitorCounterGroup::PerfMonitorCounterGroup() = default; + +PerfMonitorCounterGroup::~PerfMonitorCounterGroup() = default; + +uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name) +{ + for (uint32_t counterIndex = 0; counterIndex < static_cast(counters.size()); + ++counterIndex) + { + if (counters[counterIndex].name == name) + { + return counterIndex; + } + } + + return std::numeric_limits::max(); +} + +uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups, + const std::string &name) +{ + for (uint32_t groupIndex = 0; groupIndex < static_cast(groups.size()); ++groupIndex) + { + if (groups[groupIndex].name == name) + { + return groupIndex; + } + } + + return std::numeric_limits::max(); +} + +const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters, + const std::string &name) +{ + return GetPerfMonitorCounter(const_cast(counters), name); +} + +PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name) +{ + uint32_t counterIndex = GetPerfMonitorCounterIndex(counters, name); + ASSERT(counterIndex < static_cast(counters.size())); + return counters[counterIndex]; +} + +const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups, + const std::string &name) +{ + return GetPerfMonitorCounterGroup(const_cast(groups), name); +} + +PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups, + const std::string &name) +{ + uint32_t groupIndex = GetPerfMonitorCounterGroupIndex(groups, name); + ASSERT(groupIndex < static_cast(groups.size())); + return groups[groupIndex]; +} +} // namespace angle + +std::string ArrayString(unsigned int i) +{ + // We assume that UINT_MAX and GL_INVALID_INDEX are equal. + ASSERT(i != UINT_MAX); + + std::stringstream strstr; + strstr << "["; + strstr << i; + strstr << "]"; + return strstr.str(); +} + +std::string ArrayIndexString(const std::vector &indices) +{ + std::stringstream strstr; + + for (auto indicesIt = indices.rbegin(); indicesIt != indices.rend(); ++indicesIt) + { + // We assume that UINT_MAX and GL_INVALID_INDEX are equal. + ASSERT(*indicesIt != UINT_MAX); + strstr << "["; + strstr << (*indicesIt); + strstr << "]"; + } + + return strstr.str(); +} + +size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector &outBuffer) +{ + va_list varargCopy; + va_copy(varargCopy, vararg); + + int len = vsnprintf(nullptr, 0, fmt, vararg); + ASSERT(len >= 0); + + outBuffer.resize(len + 1, 0); + + len = vsnprintf(outBuffer.data(), outBuffer.size(), fmt, varargCopy); + va_end(varargCopy); + ASSERT(len >= 0); + return static_cast(len); +} diff --git a/gfx/angle/checkout/src/common/angleutils.h b/gfx/angle/checkout/src/common/angleutils.h new file mode 100644 index 0000000000..bcbcabc782 --- /dev/null +++ b/gfx/angle/checkout/src/common/angleutils.h @@ -0,0 +1,601 @@ +// +// 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. +// + +// angleutils.h: Common ANGLE utilities. + +#ifndef COMMON_ANGLEUTILS_H_ +#define COMMON_ANGLEUTILS_H_ + +#include "common/platform.h" + +#if defined(ANGLE_USE_ABSEIL) +# include "absl/container/flat_hash_map.h" +# include "absl/container/flat_hash_set.h" +#endif // defined(ANGLE_USE_ABSEIL) + +#if defined(ANGLE_WITH_LSAN) +# include +#endif // defined(ANGLE_WITH_LSAN) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// A helper class to disallow copy and assignment operators +namespace angle +{ + +#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) +using Microsoft::WRL::ComPtr; +#endif // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) + +#if defined(ANGLE_USE_ABSEIL) +template > +using HashMap = absl::flat_hash_map; +template > +using HashSet = absl::flat_hash_set; +#else +template > +using HashMap = std::unordered_map; +template > +using HashSet = std::unordered_set; +#endif // defined(ANGLE_USE_ABSEIL) + +class NonCopyable +{ + protected: + constexpr NonCopyable() = default; + ~NonCopyable() = default; + + private: + NonCopyable(const NonCopyable &) = delete; + void operator=(const NonCopyable &) = delete; +}; + +extern const uintptr_t DirtyPointer; + +struct SaveFileHelper +{ + public: + // We always use ios::binary to avoid inconsistent line endings when captured on Linux vs Win. + SaveFileHelper(const std::string &filePathIn); + ~SaveFileHelper(); + + template + SaveFileHelper &operator<<(const T &value) + { + mOfs << value; + checkError(); + return *this; + } + + void write(const uint8_t *data, size_t size); + + private: + void checkError(); + + std::ofstream mOfs; + std::string mFilePath; +}; + +// AMD_performance_monitor helpers. +constexpr char kPerfMonitorExtensionName[] = "GL_AMD_performance_monitor"; + +struct PerfMonitorCounter +{ + PerfMonitorCounter(); + ~PerfMonitorCounter(); + + std::string name; + uint64_t value; +}; +using PerfMonitorCounters = std::vector; + +struct PerfMonitorCounterGroup +{ + PerfMonitorCounterGroup(); + ~PerfMonitorCounterGroup(); + + std::string name; + PerfMonitorCounters counters; +}; +using PerfMonitorCounterGroups = std::vector; + +uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name); +const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters, + const std::string &name); +PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name); +uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups, + const std::string &name); +const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups, + const std::string &name); +PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups, + const std::string &name); + +struct PerfMonitorTriplet +{ + uint32_t group; + uint32_t counter; + uint64_t value; +}; + +#define ANGLE_VK_PERF_COUNTERS_X(FN) \ + FN(commandQueueSubmitCallsTotal) \ + FN(commandQueueSubmitCallsPerFrame) \ + FN(vkQueueSubmitCallsTotal) \ + FN(vkQueueSubmitCallsPerFrame) \ + FN(renderPasses) \ + FN(writeDescriptorSets) \ + FN(flushedOutsideRenderPassCommandBuffers) \ + FN(swapchainResolveInSubpass) \ + FN(swapchainResolveOutsideSubpass) \ + FN(resolveImageCommands) \ + FN(colorLoadOpClears) \ + FN(colorLoadOpLoads) \ + FN(colorLoadOpNones) \ + FN(colorStoreOpStores) \ + FN(colorStoreOpNones) \ + FN(colorClearAttachments) \ + FN(depthLoadOpClears) \ + FN(depthLoadOpLoads) \ + FN(depthLoadOpNones) \ + FN(depthStoreOpStores) \ + FN(depthStoreOpNones) \ + FN(depthClearAttachments) \ + FN(stencilLoadOpClears) \ + FN(stencilLoadOpLoads) \ + FN(stencilLoadOpNones) \ + FN(stencilStoreOpStores) \ + FN(stencilStoreOpNones) \ + FN(stencilClearAttachments) \ + FN(colorAttachmentUnresolves) \ + FN(depthAttachmentUnresolves) \ + FN(stencilAttachmentUnresolves) \ + FN(colorAttachmentResolves) \ + FN(depthAttachmentResolves) \ + FN(stencilAttachmentResolves) \ + FN(readOnlyDepthStencilRenderPasses) \ + FN(pipelineCreationCacheHits) \ + FN(pipelineCreationCacheMisses) \ + FN(pipelineCreationTotalCacheHitsDurationNs) \ + FN(pipelineCreationTotalCacheMissesDurationNs) \ + FN(descriptorSetAllocations) \ + FN(descriptorSetCacheTotalSize) \ + FN(descriptorSetCacheKeySizeBytes) \ + FN(uniformsAndXfbDescriptorSetCacheHits) \ + FN(uniformsAndXfbDescriptorSetCacheMisses) \ + FN(uniformsAndXfbDescriptorSetCacheTotalSize) \ + FN(textureDescriptorSetCacheHits) \ + FN(textureDescriptorSetCacheMisses) \ + FN(textureDescriptorSetCacheTotalSize) \ + FN(shaderResourcesDescriptorSetCacheHits) \ + FN(mutableTexturesUploaded) \ + FN(shaderResourcesDescriptorSetCacheMisses) \ + FN(shaderResourcesDescriptorSetCacheTotalSize) \ + FN(buffersGhosted) \ + FN(vertexArraySyncStateCalls) \ + FN(allocateNewBufferBlockCalls) \ + FN(dynamicBufferAllocations) \ + FN(framebufferCacheSize) + +#define ANGLE_DECLARE_PERF_COUNTER(COUNTER) uint64_t COUNTER; + +struct VulkanPerfCounters +{ + ANGLE_VK_PERF_COUNTERS_X(ANGLE_DECLARE_PERF_COUNTER) +}; + +#undef ANGLE_DECLARE_PERF_COUNTER + +} // namespace angle + +template +constexpr inline size_t ArraySize(T (&)[N]) +{ + return N; +} + +template +class WrappedArray final : angle::NonCopyable +{ + public: + template + constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N) + {} + + constexpr WrappedArray() : mArray(nullptr), mSize(0) {} + constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {} + + WrappedArray(WrappedArray &&other) : WrappedArray() + { + std::swap(mArray, other.mArray); + std::swap(mSize, other.mSize); + } + + ~WrappedArray() {} + + constexpr const T *get() const { return mArray; } + constexpr size_t size() const { return mSize; } + + private: + const T *mArray; + size_t mSize; +}; + +template +void SafeRelease(T (&resourceBlock)[N]) +{ + for (unsigned int i = 0; i < N; i++) + { + SafeRelease(resourceBlock[i]); + } +} + +template +void SafeRelease(T &resource) +{ + if (resource) + { + resource->Release(); + resource = nullptr; + } +} + +template +void SafeDelete(T *&resource) +{ + delete resource; + resource = nullptr; +} + +template +void SafeDeleteContainer(T &resource) +{ + for (auto &element : resource) + { + SafeDelete(element); + } + resource.clear(); +} + +template +void SafeDeleteArray(T *&resource) +{ + delete[] resource; + resource = nullptr; +} + +// Provide a less-than function for comparing structs +// Note: struct memory must be initialized to zero, because of packing gaps +template +inline bool StructLessThan(const T &a, const T &b) +{ + return (memcmp(&a, &b, sizeof(T)) < 0); +} + +// Provide a less-than function for comparing structs +// Note: struct memory must be initialized to zero, because of packing gaps +template +inline bool StructEquals(const T &a, const T &b) +{ + return (memcmp(&a, &b, sizeof(T)) == 0); +} + +template +inline void StructZero(T *obj) +{ + memset(obj, 0, sizeof(T)); +} + +template +inline bool IsMaskFlagSet(T mask, T flag) +{ + // Handles multibit flags as well + return (mask & flag) == flag; +} + +inline const char *MakeStaticString(const std::string &str) +{ + // On the heap so that no destructor runs on application exit. + static std::set *strings = new std::set; + std::set::iterator it = strings->find(str); + if (it != strings->end()) + { + return it->c_str(); + } + + return strings->insert(str).first->c_str(); +} + +std::string ArrayString(unsigned int i); + +// Indices are stored in vectors with the outermost index in the back. In the output of the function +// the indices are reversed. +std::string ArrayIndexString(const std::vector &indices); + +inline std::string Str(int i) +{ + std::stringstream strstr; + strstr << i; + return strstr.str(); +} + +template +std::string ToString(const T &value) +{ + std::ostringstream o; + o << value; + return o.str(); +} + +inline bool IsLittleEndian() +{ + constexpr uint32_t kEndiannessTest = 1; + const bool isLittleEndian = *reinterpret_cast(&kEndiannessTest) == 1; + return isLittleEndian; +} + +// Helper class to use a mutex with the control of boolean. +class ConditionalMutex final : angle::NonCopyable +{ + public: + ConditionalMutex() : mUseMutex(true) {} + void init(bool useMutex) { mUseMutex = useMutex; } + void lock() + { + if (mUseMutex) + { + mMutex.lock(); + } + } + void unlock() + { + if (mUseMutex) + { + mMutex.unlock(); + } + } + + private: + std::mutex mMutex; + bool mUseMutex; +}; + +// snprintf is not defined with MSVC prior to to msvc14 +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#define GL_A1RGB5_ANGLEX 0x6AC5 +#define GL_BGRX8_ANGLEX 0x6ABA +#define GL_BGR565_ANGLEX 0x6ABB +#define GL_BGRA4_ANGLEX 0x6ABC +#define GL_BGR5_A1_ANGLEX 0x6ABD +#define GL_INT_64_ANGLEX 0x6ABE +#define GL_UINT_64_ANGLEX 0x6ABF +#define GL_BGRA8_SRGB_ANGLEX 0x6AC0 +#define GL_BGR10_A2_ANGLEX 0x6AF9 + +// These are fake formats used to fit typeless D3D textures that can be bound to EGL pbuffers into +// the format system (for extension EGL_ANGLE_d3d_texture_client_buffer): +#define GL_RGBA8_TYPELESS_ANGLEX 0x6AC1 +#define GL_RGBA8_TYPELESS_SRGB_ANGLEX 0x6AC2 +#define GL_BGRA8_TYPELESS_ANGLEX 0x6AC3 +#define GL_BGRA8_TYPELESS_SRGB_ANGLEX 0x6AC4 + +#define GL_R8_SSCALED_ANGLEX 0x6AC6 +#define GL_RG8_SSCALED_ANGLEX 0x6AC7 +#define GL_RGB8_SSCALED_ANGLEX 0x6AC8 +#define GL_RGBA8_SSCALED_ANGLEX 0x6AC9 +#define GL_R8_USCALED_ANGLEX 0x6ACA +#define GL_RG8_USCALED_ANGLEX 0x6ACB +#define GL_RGB8_USCALED_ANGLEX 0x6ACC +#define GL_RGBA8_USCALED_ANGLEX 0x6ACD + +#define GL_R16_SSCALED_ANGLEX 0x6ACE +#define GL_RG16_SSCALED_ANGLEX 0x6ACF +#define GL_RGB16_SSCALED_ANGLEX 0x6AD0 +#define GL_RGBA16_SSCALED_ANGLEX 0x6AD1 +#define GL_R16_USCALED_ANGLEX 0x6AD2 +#define GL_RG16_USCALED_ANGLEX 0x6AD3 +#define GL_RGB16_USCALED_ANGLEX 0x6AD4 +#define GL_RGBA16_USCALED_ANGLEX 0x6AD5 + +#define GL_R32_SSCALED_ANGLEX 0x6AD6 +#define GL_RG32_SSCALED_ANGLEX 0x6AD7 +#define GL_RGB32_SSCALED_ANGLEX 0x6AD8 +#define GL_RGBA32_SSCALED_ANGLEX 0x6AD9 +#define GL_R32_USCALED_ANGLEX 0x6ADA +#define GL_RG32_USCALED_ANGLEX 0x6ADB +#define GL_RGB32_USCALED_ANGLEX 0x6ADC +#define GL_RGBA32_USCALED_ANGLEX 0x6ADD + +#define GL_R32_SNORM_ANGLEX 0x6ADE +#define GL_RG32_SNORM_ANGLEX 0x6ADF +#define GL_RGB32_SNORM_ANGLEX 0x6AE0 +#define GL_RGBA32_SNORM_ANGLEX 0x6AE1 +#define GL_R32_UNORM_ANGLEX 0x6AE2 +#define GL_RG32_UNORM_ANGLEX 0x6AE3 +#define GL_RGB32_UNORM_ANGLEX 0x6AE4 +#define GL_RGBA32_UNORM_ANGLEX 0x6AE5 + +#define GL_R32_FIXED_ANGLEX 0x6AE6 +#define GL_RG32_FIXED_ANGLEX 0x6AE7 +#define GL_RGB32_FIXED_ANGLEX 0x6AE8 +#define GL_RGBA32_FIXED_ANGLEX 0x6AE9 + +#define GL_RGB10_A2_SINT_ANGLEX 0x6AEA +#define GL_RGB10_A2_SNORM_ANGLEX 0x6AEB +#define GL_RGB10_A2_SSCALED_ANGLEX 0x6AEC +#define GL_RGB10_A2_USCALED_ANGLEX 0x6AED + +// EXT_texture_type_2_10_10_10_REV +#define GL_RGB10_UNORM_ANGLEX 0x6AEE + +// These are fake formats for OES_vertex_type_10_10_10_2 +#define GL_A2_RGB10_UNORM_ANGLEX 0x6AEF +#define GL_A2_RGB10_SNORM_ANGLEX 0x6AF0 +#define GL_A2_RGB10_USCALED_ANGLEX 0x6AF1 +#define GL_A2_RGB10_SSCALED_ANGLEX 0x6AF2 +#define GL_X2_RGB10_UINT_ANGLEX 0x6AF3 +#define GL_X2_RGB10_SINT_ANGLEX 0x6AF4 +#define GL_X2_RGB10_USCALED_ANGLEX 0x6AF5 +#define GL_X2_RGB10_SSCALED_ANGLEX 0x6AF6 +#define GL_X2_RGB10_UNORM_ANGLEX 0x6AF7 +#define GL_X2_RGB10_SNORM_ANGLEX 0x6AF8 + +#define ANGLE_CHECK_GL_ALLOC(context, result) \ + ANGLE_CHECK(context, result, "Failed to allocate host memory", GL_OUT_OF_MEMORY) + +#define ANGLE_CHECK_GL_MATH(context, result) \ + ANGLE_CHECK(context, result, "Integer overflow.", GL_INVALID_OPERATION) + +#define ANGLE_GL_UNREACHABLE(context) \ + UNREACHABLE(); \ + ANGLE_CHECK(context, false, "Unreachable Code.", GL_INVALID_OPERATION) + +#if defined(ANGLE_WITH_LSAN) +# define ANGLE_SCOPED_DISABLE_LSAN() __lsan::ScopedDisabler lsanDisabler +#else +# define ANGLE_SCOPED_DISABLE_LSAN() +#endif + +#if defined(ANGLE_WITH_MSAN) +class MsanScopedDisableInterceptorChecks final : angle::NonCopyable +{ + public: + MsanScopedDisableInterceptorChecks() { __msan_scoped_disable_interceptor_checks(); } + ~MsanScopedDisableInterceptorChecks() { __msan_scoped_enable_interceptor_checks(); } +}; +# define ANGLE_SCOPED_DISABLE_MSAN() \ + MsanScopedDisableInterceptorChecks msanScopedDisableInterceptorChecks +#else +# define ANGLE_SCOPED_DISABLE_MSAN() +#endif + +// The ANGLE_NO_SANITIZE_MEMORY macro suppresses MemorySanitizer checks for +// use-of-uninitialized-data. It can be used to decorate functions with known +// false positives. +#ifdef __clang__ +# define ANGLE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +#else +# define ANGLE_NO_SANITIZE_MEMORY +#endif + +// Similar to the above, but for thread sanitization. +#ifdef __clang__ +# define ANGLE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +#else +# define ANGLE_NO_SANITIZE_THREAD +#endif + +// The below inlining code lifted from V8. +#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute)) +# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) +# define ANGLE_HAS___FORCEINLINE 0 +#elif defined(_MSC_VER) +# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0 +# define ANGLE_HAS___FORCEINLINE 1 +#else +# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0 +# define ANGLE_HAS___FORCEINLINE 0 +#endif + +#if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE +# define ANGLE_INLINE inline __attribute__((always_inline)) +#elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE +# define ANGLE_INLINE __forceinline +#else +# define ANGLE_INLINE inline +#endif + +#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute)) +# if __has_attribute(noinline) +# define ANGLE_NOINLINE __attribute__((noinline)) +# else +# define ANGLE_NOINLINE +# endif +#elif defined(_MSC_VER) +# define ANGLE_NOINLINE __declspec(noinline) +#else +# define ANGLE_NOINLINE +#endif + +#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute)) +# if __has_attribute(format) +# define ANGLE_FORMAT_PRINTF(fmt, args) __attribute__((format(__printf__, fmt, args))) +# else +# define ANGLE_FORMAT_PRINTF(fmt, args) +# endif +#else +# define ANGLE_FORMAT_PRINTF(fmt, args) +#endif + +ANGLE_FORMAT_PRINTF(1, 0) +size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector &buffer); + +// Format messes up the # inside the macro. +// clang-format off +#ifndef ANGLE_STRINGIFY +# define ANGLE_STRINGIFY(x) #x +#endif +// clang-format on + +#ifndef ANGLE_MACRO_STRINGIFY +# define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x) +#endif + +#if __has_cpp_attribute(clang::require_constant_initialization) +# define ANGLE_REQUIRE_CONSTANT_INIT [[clang::require_constant_initialization]] +#else +# define ANGLE_REQUIRE_CONSTANT_INIT +#endif // __has_cpp_attribute(require_constant_initialization) + +// Compiler configs. +inline bool IsASan() +{ +#if defined(ANGLE_WITH_ASAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_ASAN) +} + +inline bool IsMSan() +{ +#if defined(ANGLE_WITH_MSAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_MSAN) +} + +inline bool IsTSan() +{ +#if defined(ANGLE_WITH_TSAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_TSAN) +} + +inline bool IsUBSan() +{ +#if defined(ANGLE_WITH_UBSAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_UBSAN) +} +#endif // COMMON_ANGLEUTILS_H_ diff --git a/gfx/angle/checkout/src/common/apple_platform_utils.h b/gfx/angle/checkout/src/common/apple_platform_utils.h new file mode 100644 index 0000000000..da932a9207 --- /dev/null +++ b/gfx/angle/checkout/src/common/apple_platform_utils.h @@ -0,0 +1,90 @@ +// +// Copyright 2019 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. +// + +// apple_platform_utils.h: Common utilities for Apple platforms. + +#ifndef COMMON_APPLE_PLATFORM_UTILS_H_ +#define COMMON_APPLE_PLATFORM_UTILS_H_ + +#include "common/platform.h" + +// These are macros for substitution of Apple specific directive @available: + +// TARGET_OS_MACCATALYST only available in MacSDK 10.15 + +#if TARGET_OS_MACCATALYST +// ANGLE_APPLE_AVAILABLE_XCI: check if either of the 3 platforms (OSX/Catalyst/iOS) min verions is +// available: +# define ANGLE_APPLE_AVAILABLE_XCI(macVer, macCatalystVer, iOSVer) \ + @available(macOS macVer, macCatalyst macCatalystVer, iOS iOSVer, *) +// ANGLE_APPLE_AVAILABLE_XC: check if either of the 2 platforms (OSX/Catalyst) min verions is +// available: +# define ANGLE_APPLE_AVAILABLE_XC(macVer, macCatalystVer) \ + @available(macOS macVer, macCatalyst macCatalystVer, *) +// ANGLE_APPLE_AVAILABLE_CI: check if either of the 2 platforms (Catalyst/iOS) min verions is +// available: +# define ANGLE_APPLE_AVAILABLE_CI(macCatalystVer, iOSVer) \ + @available(macCatalyst macCatalystVer, iOS iOSVer, *) +#else +# define ANGLE_APPLE_AVAILABLE_XCI(macVer, macCatalystVer, iOSVer) \ + ANGLE_APPLE_AVAILABLE_XI(macVer, iOSVer) + +# define ANGLE_APPLE_AVAILABLE_XC(macVer, macCatalystVer) @available(macOS macVer, *) +# define ANGLE_APPLE_AVAILABLE_CI(macCatalystVer, iOSVer) @available(iOS iOSVer, tvOS iOSVer, *) +#endif + +// ANGLE_APPLE_AVAILABLE_XI: check if either of the 2 platforms (OSX/iOS) min verions is available: +#define ANGLE_APPLE_AVAILABLE_XI(macVer, iOSVer) \ + @available(macOS macVer, iOS iOSVer, tvOS iOSVer, *) + +// ANGLE_APPLE_AVAILABLE_I: check if a particular iOS version is available +#define ANGLE_APPLE_AVAILABLE_I(iOSVer) @available(iOS iOSVer, tvOS iOSVer, *) + +#if TARGET_OS_IPHONE +# if !defined(__IPHONE_11_0) +# define __IPHONE_11_0 110000 +# endif +# if !defined(ANGLE_IOS_DEPLOY_TARGET) +# define ANGLE_IOS_DEPLOY_TARGET __IPHONE_11_0 +# endif +# if !defined(__IPHONE_OS_VERSION_MAX_ALLOWED) +# define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_11_0 +# endif +# if !defined(__TV_OS_VERSION_MAX_ALLOWED) +# define __TV_OS_VERSION_MAX_ALLOWED __IPHONE_11_0 +# endif +#endif + +#if !defined(TARGET_OS_MACCATALYST) +# define TARGET_OS_MACCATALYST 0 +#endif + +#if defined(__ARM_ARCH) +# define ANGLE_APPLE_IS_ARM (__ARM_ARCH != 0) +#else +# define ANGLE_APPLE_IS_ARM 0 +#endif + +#define ANGLE_APPLE_OBJC_SCOPE @autoreleasepool + +#if !__has_feature(objc_arc) +# define ANGLE_APPLE_AUTORELEASE autorelease +# define ANGLE_APPLE_RETAIN retain +# define ANGLE_APPLE_RELEASE release +#else +# define ANGLE_APPLE_AUTORELEASE self +# define ANGLE_APPLE_RETAIN self +# define ANGLE_APPLE_RELEASE self +#endif + +#define ANGLE_APPLE_UNUSED __attribute__((unused)) + +namespace angle +{ +bool IsMetalRendererAvailable(); +} + +#endif diff --git a/gfx/angle/checkout/src/common/bitset_utils.h b/gfx/angle/checkout/src/common/bitset_utils.h new file mode 100644 index 0000000000..ee9a3f1b9b --- /dev/null +++ b/gfx/angle/checkout/src/common/bitset_utils.h @@ -0,0 +1,1106 @@ +// +// Copyright 2015 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. +// +// bitset_utils: +// Bitset-related helper classes, such as a fast iterator to scan for set bits. +// + +#ifndef COMMON_BITSETITERATOR_H_ +#define COMMON_BITSETITERATOR_H_ + +#include + +#include + +#include "common/angleutils.h" +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/platform.h" + +namespace angle +{ +// Given x, create 1 << x. +template +constexpr BitsT Bit(ParamT x) +{ + // It's undefined behavior if the shift size is equal to or larger than the width of the type. + ASSERT(static_cast(x) < sizeof(BitsT) * 8); + + return (static_cast(1) << static_cast(x)); +} + +// Given x, create (1 << x) - 1, i.e. a mask with x bits set. +template +constexpr BitsT BitMask(ParamT x) +{ + if (static_cast(x) == 0) + { + return 0; + } + return ((Bit(static_cast(static_cast(x) - 1)) - 1) << 1) | 1; +} + +template +class BitSetT final +{ + public: + class Reference final + { + public: + ~Reference() {} + Reference &operator=(bool x) + { + mParent->set(mBit, x); + return *this; + } + explicit operator bool() const { return mParent->test(mBit); } + + private: + friend class BitSetT; + + Reference(BitSetT *parent, ParamT bit) : mParent(parent), mBit(bit) {} + + BitSetT *mParent; + ParamT mBit; + }; + + class Iterator final + { + public: + Iterator(const BitSetT &bits); + Iterator &operator++(); + + bool operator==(const Iterator &other) const; + bool operator!=(const Iterator &other) const; + ParamT operator*() const; + + // These helper functions allow mutating an iterator in-flight. + // They only operate on later bits to ensure we don't iterate the same bit twice. + void resetLaterBit(std::size_t index) + { + ASSERT(index > mCurrentBit); + mBitsCopy.reset(index); + } + + void setLaterBit(std::size_t index) + { + ASSERT(index > mCurrentBit); + mBitsCopy.set(index); + } + + void setLaterBits(const BitSetT &bits) + { + ASSERT((BitSetT(bits) &= Mask(mCurrentBit + 1)).none()); + mBitsCopy |= bits; + } + + private: + std::size_t getNextBit(); + + BitSetT mBitsCopy; + std::size_t mCurrentBit; + }; + + using value_type = BitsT; + using param_type = ParamT; + + constexpr BitSetT(); + constexpr explicit BitSetT(BitsT value); + constexpr explicit BitSetT(std::initializer_list init); + + constexpr BitSetT(const BitSetT &other); + constexpr BitSetT &operator=(const BitSetT &other); + + constexpr bool operator==(const BitSetT &other) const; + constexpr bool operator!=(const BitSetT &other) const; + + constexpr bool operator[](ParamT pos) const; + Reference operator[](ParamT pos) { return Reference(this, pos); } + + constexpr bool test(ParamT pos) const; + + constexpr bool all() const; + constexpr bool any() const; + constexpr bool none() const; + constexpr std::size_t count() const; + + constexpr static std::size_t size() { return N; } + + constexpr BitSetT &operator&=(const BitSetT &other); + constexpr BitSetT &operator|=(const BitSetT &other); + constexpr BitSetT &operator^=(const BitSetT &other); + constexpr BitSetT operator~() const; + + constexpr BitSetT &operator&=(BitsT value); + constexpr BitSetT &operator|=(BitsT value); + constexpr BitSetT &operator^=(BitsT value); + + constexpr BitSetT operator<<(std::size_t pos) const; + constexpr BitSetT &operator<<=(std::size_t pos); + constexpr BitSetT operator>>(std::size_t pos) const; + constexpr BitSetT &operator>>=(std::size_t pos); + + constexpr BitSetT &set(); + constexpr BitSetT &set(ParamT pos, bool value = true); + + constexpr BitSetT &reset(); + constexpr BitSetT &reset(ParamT pos); + + constexpr BitSetT &flip(); + constexpr BitSetT &flip(ParamT pos); + + constexpr unsigned long to_ulong() const { return static_cast(mBits); } + constexpr BitsT bits() const { return mBits; } + + Iterator begin() const { return Iterator(*this); } + Iterator end() const { return Iterator(BitSetT()); } + + constexpr static BitSetT Zero() { return BitSetT(); } + + constexpr ParamT first() const; + constexpr ParamT last() const; + + // Produces a mask of ones up to the "x"th bit. + constexpr static BitsT Mask(std::size_t x) { return BitMask(static_cast(x)); } + + private: + BitsT mBits; +}; + +template +constexpr BitSetT::BitSetT() : mBits(0) +{ + static_assert(N > 0, "Bitset type cannot support zero bits."); + static_assert(N <= sizeof(BitsT) * 8, "Bitset type cannot support a size this large."); +} + +template +constexpr BitSetT::BitSetT(BitsT value) : mBits(value & Mask(N)) +{} + +template +constexpr BitSetT::BitSetT(std::initializer_list init) : mBits(0) +{ + for (ParamT element : init) + { + mBits |= Bit(element); + } + ASSERT(mBits == (mBits & Mask(N))); +} + +template +constexpr BitSetT::BitSetT(const BitSetT &other) : mBits(other.mBits) +{} + +template +constexpr BitSetT &BitSetT::operator=(const BitSetT &other) +{ + mBits = other.mBits; + return *this; +} + +template +constexpr bool BitSetT::operator==(const BitSetT &other) const +{ + return mBits == other.mBits; +} + +template +constexpr bool BitSetT::operator!=(const BitSetT &other) const +{ + return mBits != other.mBits; +} + +template +constexpr bool BitSetT::operator[](ParamT pos) const +{ + return test(pos); +} + +template +constexpr bool BitSetT::test(ParamT pos) const +{ + return (mBits & Bit(pos)) != 0; +} + +template +constexpr bool BitSetT::all() const +{ + ASSERT(mBits == (mBits & Mask(N))); + return mBits == Mask(N); +} + +template +constexpr bool BitSetT::any() const +{ + ASSERT(mBits == (mBits & Mask(N))); + return (mBits != 0); +} + +template +constexpr bool BitSetT::none() const +{ + ASSERT(mBits == (mBits & Mask(N))); + return (mBits == 0); +} + +template +constexpr std::size_t BitSetT::count() const +{ + return gl::BitCount(mBits); +} + +template +constexpr BitSetT &BitSetT::operator&=(const BitSetT &other) +{ + mBits &= other.mBits; + return *this; +} + +template +constexpr BitSetT &BitSetT::operator|=(const BitSetT &other) +{ + mBits |= other.mBits; + return *this; +} + +template +constexpr BitSetT &BitSetT::operator^=(const BitSetT &other) +{ + mBits = mBits ^ other.mBits; + return *this; +} + +template +constexpr BitSetT BitSetT::operator~() const +{ + return BitSetT(~mBits & Mask(N)); +} + +template +constexpr BitSetT &BitSetT::operator&=(BitsT value) +{ + mBits &= value; + return *this; +} + +template +constexpr BitSetT &BitSetT::operator|=(BitsT value) +{ + mBits |= value; + ASSERT(mBits == (mBits & Mask(N))); + return *this; +} + +template +constexpr BitSetT &BitSetT::operator^=(BitsT value) +{ + mBits ^= value; + ASSERT(mBits == (mBits & Mask(N))); + return *this; +} + +template +constexpr BitSetT BitSetT::operator<<(std::size_t pos) const +{ + return BitSetT((mBits << pos) & Mask(N)); +} + +template +constexpr BitSetT &BitSetT::operator<<=(std::size_t pos) +{ + mBits = mBits << pos & Mask(N); + return *this; +} + +template +constexpr BitSetT BitSetT::operator>>(std::size_t pos) const +{ + return BitSetT(mBits >> pos); +} + +template +constexpr BitSetT &BitSetT::operator>>=(std::size_t pos) +{ + mBits = (mBits >> pos) & Mask(N); + return *this; +} + +template +constexpr BitSetT &BitSetT::set() +{ + ASSERT(mBits == (mBits & Mask(N))); + mBits = Mask(N); + return *this; +} + +template +constexpr BitSetT &BitSetT::set(ParamT pos, bool value) +{ + ASSERT(static_cast(pos) < N); + if (value) + { + mBits |= Bit(pos); + } + else + { + reset(pos); + } + ASSERT(mBits == (mBits & Mask(N))); + return *this; +} + +template +constexpr BitSetT &BitSetT::reset() +{ + ASSERT(mBits == (mBits & Mask(N))); + mBits = 0; + return *this; +} + +template +constexpr BitSetT &BitSetT::reset(ParamT pos) +{ + ASSERT(static_cast(pos) < N); + ASSERT(mBits == (mBits & Mask(N))); + mBits &= ~Bit(pos); + return *this; +} + +template +constexpr BitSetT &BitSetT::flip() +{ + ASSERT(mBits == (mBits & Mask(N))); + mBits ^= Mask(N); + return *this; +} + +template +constexpr BitSetT &BitSetT::flip(ParamT pos) +{ + ASSERT(static_cast(pos) < N); + mBits ^= Bit(pos); + ASSERT(mBits == (mBits & Mask(N))); + return *this; +} + +template +constexpr ParamT BitSetT::first() const +{ + ASSERT(!none()); + return static_cast(gl::ScanForward(mBits)); +} + +template +constexpr ParamT BitSetT::last() const +{ + ASSERT(!none()); + return static_cast(gl::ScanReverse(mBits)); +} + +template +BitSetT::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0) +{ + if (bits.any()) + { + mCurrentBit = getNextBit(); + } +} + +template +ANGLE_INLINE typename BitSetT::Iterator & +BitSetT::Iterator::operator++() +{ + ASSERT(mBitsCopy.any()); + mBitsCopy.reset(static_cast(mCurrentBit)); + mCurrentBit = getNextBit(); + return *this; +} + +template +bool BitSetT::Iterator::operator==(const Iterator &other) const +{ + return mBitsCopy == other.mBitsCopy; +} + +template +bool BitSetT::Iterator::operator!=(const Iterator &other) const +{ + return !(*this == other); +} + +template +ParamT BitSetT::Iterator::operator*() const +{ + return static_cast(mCurrentBit); +} + +template +std::size_t BitSetT::Iterator::getNextBit() +{ + if (mBitsCopy.none()) + { + return 0; + } + + return gl::ScanForward(mBitsCopy.mBits); +} + +template +using BitSet8 = BitSetT; + +template +using BitSet16 = BitSetT; + +template +using BitSet32 = BitSetT; + +template +using BitSet64 = BitSetT; + +template +class BitSetArray; + +namespace priv +{ + +template +using EnableIfBitsFit = typename std::enable_if::type; + +template +struct GetBitSet +{ + using Type = BitSetArray; +}; + +// Prefer 64-bit bitsets on 64-bit CPUs. They seem faster than 32-bit. +#if defined(ANGLE_IS_64_BIT_CPU) +template +struct GetBitSet> +{ + using Type = BitSet64; +}; +constexpr std::size_t kDefaultBitSetSize = 64; +using BaseBitSetType = BitSet64; +#else +template +struct GetBitSet> +{ + using Type = BitSet32; +}; +constexpr std::size_t kDefaultBitSetSize = 32; +using BaseBitSetType = BitSet32; +#endif // defined(ANGLE_IS_64_BIT_CPU) + +} // namespace priv + +template +using BitSet = typename priv::GetBitSet::Type; + +template +class BitSetArray final +{ + public: + using BaseBitSet = priv::BaseBitSetType; + using value_type = BaseBitSet::value_type; + using param_type = BaseBitSet::param_type; + + constexpr BitSetArray(); + constexpr explicit BitSetArray(std::initializer_list init); + + BitSetArray(const BitSetArray &other); + + class Reference final + { + public: + ~Reference() {} + Reference &operator=(bool x) + { + mParent.set(mPosition, x); + return *this; + } + explicit operator bool() const { return mParent.test(mPosition); } + + private: + friend class BitSetArray; + + Reference(BitSetArray &parent, std::size_t pos) : mParent(parent), mPosition(pos) {} + + BitSetArray &mParent; + std::size_t mPosition; + }; + class Iterator final + { + public: + Iterator(const BitSetArray &bitSetArray, std::size_t index); + Iterator &operator++(); + bool operator==(const Iterator &other) const; + bool operator!=(const Iterator &other) const; + size_t operator*() const; + + // These helper functions allow mutating an iterator in-flight. + // They only operate on later bits to ensure we don't iterate the same bit twice. + void resetLaterBit(std::size_t pos) + { + ASSERT(pos > (mIndex * priv::kDefaultBitSetSize) + *mCurrentIterator); + prepareCopy(); + mParentCopy.reset(pos); + updateIteratorBit(pos, false); + } + + void setLaterBit(std::size_t pos) + { + ASSERT(pos > (mIndex * priv::kDefaultBitSetSize) + *mCurrentIterator); + prepareCopy(); + mParentCopy.set(pos); + updateIteratorBit(pos, true); + } + + void setLaterBits(const BitSetArray &bits) + { + prepareCopy(); + mParentCopy |= bits; + updateIteratorBits(bits); + } + + private: + ANGLE_INLINE void prepareCopy() + { + ASSERT(mParent.mBaseBitSetArray[mIndex].end() == + mParentCopy.mBaseBitSetArray[mIndex].end()); + if (mParentCopy.none()) + { + mParentCopy = mParent; + mCurrentParent = &mParentCopy; + } + } + + ANGLE_INLINE void updateIteratorBit(std::size_t pos, bool setBit) + { + // Get the index and offset, update current interator if within range + size_t index = pos >> kShiftForDivision; + size_t offset = pos & kDefaultBitSetSizeMinusOne; + if (index == mIndex) + { + if (setBit) + { + mCurrentIterator.setLaterBit(offset); + } + else + { + mCurrentIterator.resetLaterBit(offset); + } + } + } + + ANGLE_INLINE void updateIteratorBits(const BitSetArray &bits) + { + mCurrentIterator.setLaterBits(bits.mBaseBitSetArray[mIndex]); + } + + // Problem - + // We want to provide the fastest path possible for usecases that iterate though the bitset. + // + // Options - + // 1) For non-mutating iterations the const ref is set as mCurrentParent and only + // for usecases that need to mutate the bitset while iterating we perform a copy of + // into and modify its bits accordingly. + // 2) The alternate approach was to perform a copy all the time in the constructor + // irrespective of whether it was a mutating usecase or not. + // + // Experiment - + // BitSetIteratorPerfTest was run on a Windows machine with Intel CPU and these were the + // results - + // 1) Copy only when necessary - + // RESULT BitSetIteratorPerf.wall_time: run = 116.1067374961 ns + // RESULT BitSetIteratorPerf.trial_steps : run = 8416124 count + // RESULT BitSetIteratorPerf.total_steps : run = 16832251 count + // 2) Copy always - + // RESULT BitSetIteratorPerf.wall_time: run = 242.7446459439 ns + // RESULT BitSetIteratorPerf.trial_steps : run = 4171416 count + // RESULT BitSetIteratorPerf.total_steps : run = 8342834 count + // + // Resolution - + // We settled on the copy only when necessary path. + size_t mIndex; + const BitSetArray &mParent; + BitSetArray mParentCopy; + const BitSetArray *mCurrentParent; + typename BaseBitSet::Iterator mCurrentIterator; + }; + + constexpr static std::size_t size() { return N; } + Iterator begin() const { return Iterator(*this, 0); } + Iterator end() const { return Iterator(*this, kArraySize); } + constexpr unsigned long to_ulong() const + { + // TODO(anglebug.com/5628): Handle serializing more than kDefaultBitSetSize + for (std::size_t index = 1; index < kArraySize; index++) + { + ASSERT(mBaseBitSetArray[index].none()); + } + return static_cast(mBaseBitSetArray[0].to_ulong()); + } + + // Assignment operators + constexpr BitSetArray &operator=(const BitSetArray &other); + constexpr BitSetArray &operator&=(const BitSetArray &other); + constexpr BitSetArray &operator|=(const BitSetArray &other); + constexpr BitSetArray &operator^=(const BitSetArray &other); + + // Bitwise operators + constexpr BitSetArray operator&(const angle::BitSetArray &other) const; + constexpr BitSetArray operator|(const angle::BitSetArray &other) const; + constexpr BitSetArray operator^(const angle::BitSetArray &other) const; + + // Relational Operators + constexpr bool operator==(const angle::BitSetArray &other) const; + constexpr bool operator!=(const angle::BitSetArray &other) const; + + // Unary operators + constexpr BitSetArray operator~() const; + constexpr bool operator[](std::size_t pos) const; + constexpr Reference operator[](std::size_t pos) + { + ASSERT(pos < size()); + return Reference(*this, pos); + } + + // Setter, getters and other helper methods + constexpr BitSetArray &set(); + constexpr BitSetArray &set(std::size_t pos, bool value = true); + constexpr BitSetArray &reset(); + constexpr BitSetArray &reset(std::size_t pos); + constexpr bool test(std::size_t pos) const; + constexpr bool all() const; + constexpr bool any() const; + constexpr bool none() const; + constexpr std::size_t count() const; + constexpr bool intersects(const BitSetArray &other) const; + constexpr BitSetArray &flip(); + constexpr param_type first() const; + constexpr param_type last() const; + + constexpr value_type bits(size_t index) const; + + private: + static constexpr std::size_t kDefaultBitSetSizeMinusOne = priv::kDefaultBitSetSize - 1; + static constexpr std::size_t kShiftForDivision = + static_cast(rx::Log2(static_cast(priv::kDefaultBitSetSize))); + static constexpr std::size_t kArraySize = + ((N + kDefaultBitSetSizeMinusOne) >> kShiftForDivision); + constexpr static std::size_t kLastElementCount = (N & kDefaultBitSetSizeMinusOne); + constexpr static std::size_t kLastElementMask = priv::BaseBitSetType::Mask( + kLastElementCount == 0 ? priv::kDefaultBitSetSize : kLastElementCount); + + std::array mBaseBitSetArray; +}; + +template +constexpr BitSetArray::BitSetArray() +{ + static_assert(N > priv::kDefaultBitSetSize, "BitSetArray type can't support requested size."); + reset(); +} + +template +constexpr BitSetArray::BitSetArray(std::initializer_list init) +{ + reset(); + + for (param_type element : init) + { + size_t index = element >> kShiftForDivision; + size_t offset = element & kDefaultBitSetSizeMinusOne; + mBaseBitSetArray[index].set(offset, true); + } +} + +template +BitSetArray::BitSetArray(const BitSetArray &other) +{ + for (std::size_t index = 0; index < kArraySize; index++) + { + mBaseBitSetArray[index] = other.mBaseBitSetArray[index]; + } +} + +template +BitSetArray::Iterator::Iterator(const BitSetArray &bitSetArray, std::size_t index) + : mIndex(index), + mParent(bitSetArray), + mCurrentParent(&mParent), + mCurrentIterator(mParent.mBaseBitSetArray[0].begin()) +{ + while (mIndex < mCurrentParent->kArraySize) + { + if (mCurrentParent->mBaseBitSetArray[mIndex].any()) + { + break; + } + mIndex++; + } + + if (mIndex < mCurrentParent->kArraySize) + { + mCurrentIterator = mCurrentParent->mBaseBitSetArray[mIndex].begin(); + } + else + { + mCurrentIterator = mCurrentParent->mBaseBitSetArray[mCurrentParent->kArraySize - 1].end(); + } +} + +template +typename BitSetArray::Iterator &BitSetArray::Iterator::operator++() +{ + ++mCurrentIterator; + while (mCurrentIterator == mCurrentParent->mBaseBitSetArray[mIndex].end()) + { + mIndex++; + if (mIndex >= mCurrentParent->kArraySize) + { + break; + } + mCurrentIterator = mCurrentParent->mBaseBitSetArray[mIndex].begin(); + } + return *this; +} + +template +bool BitSetArray::Iterator::operator==(const BitSetArray::Iterator &other) const +{ + return mCurrentIterator == other.mCurrentIterator; +} + +template +bool BitSetArray::Iterator::operator!=(const BitSetArray::Iterator &other) const +{ + return mCurrentIterator != other.mCurrentIterator; +} + +template +std::size_t BitSetArray::Iterator::operator*() const +{ + return (mIndex * priv::kDefaultBitSetSize) + *mCurrentIterator; +} + +template +constexpr BitSetArray &BitSetArray::operator=(const BitSetArray &other) +{ + for (std::size_t index = 0; index < kArraySize; index++) + { + mBaseBitSetArray[index] = other.mBaseBitSetArray[index]; + } + return *this; +} + +template +constexpr BitSetArray &BitSetArray::operator&=(const BitSetArray &other) +{ + for (std::size_t index = 0; index < kArraySize; index++) + { + mBaseBitSetArray[index] &= other.mBaseBitSetArray[index]; + } + return *this; +} + +template +constexpr BitSetArray &BitSetArray::operator|=(const BitSetArray &other) +{ + for (std::size_t index = 0; index < kArraySize; index++) + { + mBaseBitSetArray[index] |= other.mBaseBitSetArray[index]; + } + return *this; +} + +template +constexpr BitSetArray &BitSetArray::operator^=(const BitSetArray &other) +{ + for (std::size_t index = 0; index < kArraySize; index++) + { + mBaseBitSetArray[index] ^= other.mBaseBitSetArray[index]; + } + return *this; +} + +template +constexpr BitSetArray BitSetArray::operator&(const angle::BitSetArray &other) const +{ + angle::BitSetArray result(other); + result &= *this; + return result; +} + +template +constexpr BitSetArray BitSetArray::operator|(const angle::BitSetArray &other) const +{ + angle::BitSetArray result(other); + result |= *this; + return result; +} + +template +constexpr BitSetArray BitSetArray::operator^(const angle::BitSetArray &other) const +{ + angle::BitSetArray result(other); + result ^= *this; + return result; +} + +template +constexpr bool BitSetArray::operator==(const angle::BitSetArray &other) const +{ + for (std::size_t index = 0; index < kArraySize; index++) + { + if (mBaseBitSetArray[index] != other.mBaseBitSetArray[index]) + { + return false; + } + } + return true; +} + +template +constexpr bool BitSetArray::operator!=(const angle::BitSetArray &other) const +{ + return !(*this == other); +} + +template +constexpr BitSetArray BitSetArray::operator~() const +{ + angle::BitSetArray result; + for (std::size_t index = 0; index < kArraySize; index++) + { + result.mBaseBitSetArray[index] |= ~mBaseBitSetArray[index]; + } + // The last element in result may need special handling + result.mBaseBitSetArray[kArraySize - 1] &= kLastElementMask; + + return result; +} + +template +constexpr bool BitSetArray::operator[](std::size_t pos) const +{ + ASSERT(pos < size()); + return test(pos); +} + +template +constexpr BitSetArray &BitSetArray::set() +{ + for (BaseBitSet &baseBitSet : mBaseBitSetArray) + { + baseBitSet.set(); + } + // The last element in mBaseBitSetArray may need special handling + mBaseBitSetArray[kArraySize - 1] &= kLastElementMask; + + return *this; +} + +template +constexpr BitSetArray &BitSetArray::set(std::size_t pos, bool value) +{ + ASSERT(pos < size()); + // Get the index and offset, then set the bit + size_t index = pos >> kShiftForDivision; + size_t offset = pos & kDefaultBitSetSizeMinusOne; + mBaseBitSetArray[index].set(offset, value); + return *this; +} + +template +constexpr BitSetArray &BitSetArray::reset() +{ + for (BaseBitSet &baseBitSet : mBaseBitSetArray) + { + baseBitSet.reset(); + } + return *this; +} + +template +constexpr BitSetArray &BitSetArray::reset(std::size_t pos) +{ + ASSERT(pos < size()); + return set(pos, false); +} + +template +constexpr bool BitSetArray::test(std::size_t pos) const +{ + ASSERT(pos < size()); + // Get the index and offset, then test the bit + size_t index = pos >> kShiftForDivision; + size_t offset = pos & kDefaultBitSetSizeMinusOne; + return mBaseBitSetArray[index].test(offset); +} + +template +constexpr bool BitSetArray::all() const +{ + constexpr priv::BaseBitSetType kLastElementBitSet = priv::BaseBitSetType(kLastElementMask); + + for (std::size_t index = 0; index < kArraySize - 1; index++) + { + if (!mBaseBitSetArray[index].all()) + { + return false; + } + } + + // The last element in mBaseBitSetArray may need special handling + return mBaseBitSetArray[kArraySize - 1] == kLastElementBitSet; +} + +template +constexpr bool BitSetArray::any() const +{ + for (const BaseBitSet &baseBitSet : mBaseBitSetArray) + { + if (baseBitSet.any()) + { + return true; + } + } + return false; +} + +template +constexpr bool BitSetArray::none() const +{ + for (const BaseBitSet &baseBitSet : mBaseBitSetArray) + { + if (!baseBitSet.none()) + { + return false; + } + } + return true; +} + +template +constexpr std::size_t BitSetArray::count() const +{ + size_t count = 0; + for (const BaseBitSet &baseBitSet : mBaseBitSetArray) + { + count += baseBitSet.count(); + } + return count; +} + +template +constexpr bool BitSetArray::intersects(const BitSetArray &other) const +{ + for (std::size_t index = 0; index < kArraySize; index++) + { + if ((mBaseBitSetArray[index].bits() & other.mBaseBitSetArray[index].bits()) != 0) + { + return true; + } + } + return false; +} + +template +constexpr BitSetArray &BitSetArray::flip() +{ + for (BaseBitSet &baseBitSet : mBaseBitSetArray) + { + baseBitSet.flip(); + } + + // The last element in mBaseBitSetArray may need special handling + mBaseBitSetArray[kArraySize - 1] &= kLastElementMask; + return *this; +} + +template +constexpr typename BitSetArray::param_type BitSetArray::first() const +{ + ASSERT(any()); + for (size_t arrayIndex = 0; arrayIndex < kArraySize; ++arrayIndex) + { + const BaseBitSet &baseBitSet = mBaseBitSetArray[arrayIndex]; + if (baseBitSet.any()) + { + return baseBitSet.first() + arrayIndex * priv::kDefaultBitSetSize; + } + } + UNREACHABLE(); + return 0; +} + +template +constexpr typename BitSetArray::param_type BitSetArray::last() const +{ + ASSERT(any()); + for (size_t arrayIndex = kArraySize; arrayIndex > 0; --arrayIndex) + { + const BaseBitSet &baseBitSet = mBaseBitSetArray[arrayIndex - 1]; + if (baseBitSet.any()) + { + return baseBitSet.last() + (arrayIndex - 1) * priv::kDefaultBitSetSize; + } + } + UNREACHABLE(); + return 0; +} + +template +constexpr typename BitSetArray::value_type BitSetArray::bits(size_t index) const +{ + return mBaseBitSetArray[index].bits(); +} +} // namespace angle + +template +inline constexpr angle::BitSetT operator&( + const angle::BitSetT &lhs, + const angle::BitSetT &rhs) +{ + angle::BitSetT result(lhs); + result &= rhs.bits(); + return result; +} + +template +inline constexpr angle::BitSetT operator|( + const angle::BitSetT &lhs, + const angle::BitSetT &rhs) +{ + angle::BitSetT result(lhs); + result |= rhs.bits(); + return result; +} + +template +inline constexpr angle::BitSetT operator^( + const angle::BitSetT &lhs, + const angle::BitSetT &rhs) +{ + angle::BitSetT result(lhs); + result ^= rhs.bits(); + return result; +} + +template +inline bool operator==(angle::BitSetT &lhs, angle::BitSetT &rhs) +{ + return lhs.bits() == rhs.bits(); +} + +template +inline bool operator!=(angle::BitSetT &lhs, angle::BitSetT &rhs) +{ + return !(lhs == rhs); +} + +#endif // COMMON_BITSETITERATOR_H_ diff --git a/gfx/angle/checkout/src/common/debug.cpp b/gfx/angle/checkout/src/common/debug.cpp new file mode 100644 index 0000000000..23424d443a --- /dev/null +++ b/gfx/angle/checkout/src/common/debug.cpp @@ -0,0 +1,349 @@ +// +// 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. +// + +// debug.cpp: Debugging utilities. + +#include "common/debug.h" + +#include + +#include +#include +#include +#include +#include +#include + +#if defined(ANGLE_PLATFORM_ANDROID) +# include +#endif + +#if defined(ANGLE_PLATFORM_APPLE) +# include +#endif + +#if defined(ANGLE_PLATFORM_WINDOWS) +# include +#endif + +#include "anglebase/no_destructor.h" +#include "common/Optional.h" +#include "common/angleutils.h" +#include "common/entry_points_enum_autogen.h" +#include "common/system_utils.h" + +namespace gl +{ + +namespace +{ + +DebugAnnotator *g_debugAnnotator = nullptr; + +std::mutex *g_debugMutex = nullptr; + +constexpr std::array g_logSeverityNames = { + {"EVENT", "INFO", "WARN", "ERR", "FATAL"}}; + +constexpr const char *LogSeverityName(int severity) +{ + return (severity >= 0 && severity < LOG_NUM_SEVERITIES) ? g_logSeverityNames[severity] + : "UNKNOWN"; +} + +bool ShouldCreateLogMessage(LogSeverity severity) +{ +#if defined(ANGLE_TRACE_ENABLED) + return true; +#elif defined(ANGLE_ENABLE_ASSERTS) + return severity == LOG_FATAL || severity == LOG_ERR || severity == LOG_WARN; +#else + return severity == LOG_FATAL || severity == LOG_ERR; +#endif +} + +} // namespace + +namespace priv +{ + +bool ShouldCreatePlatformLogMessage(LogSeverity severity) +{ +#if defined(ANGLE_TRACE_ENABLED) + return true; +#else + return severity != LOG_EVENT; +#endif +} + +// This is never instantiated, it's just used for EAT_STREAM_PARAMETERS to an object of the correct +// type on the LHS of the unused part of the ternary operator. +std::ostream *gSwallowStream; +} // namespace priv + +bool DebugAnnotationsActive(const gl::Context *context) +{ +#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) || defined(ANGLE_ENABLE_DEBUG_TRACE) + return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus(context); +#else + return false; +#endif +} + +bool ShouldBeginScopedEvent(const gl::Context *context) +{ +#if defined(ANGLE_ENABLE_ANNOTATOR_RUN_TIME_CHECKS) + return DebugAnnotationsActive(context); +#else + return true; +#endif // defined(ANGLE_ENABLE_ANNOTATOR_RUN_TIME_CHECKS) +} + +bool DebugAnnotationsInitialized() +{ + return g_debugAnnotator != nullptr; +} + +void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator) +{ + UninitializeDebugAnnotations(); + g_debugAnnotator = debugAnnotator; +} + +void UninitializeDebugAnnotations() +{ + // Pointer is not managed. + g_debugAnnotator = nullptr; +} + +void InitializeDebugMutexIfNeeded() +{ + if (g_debugMutex == nullptr) + { + g_debugMutex = new std::mutex(); + } +} + +std::mutex &GetDebugMutex() +{ + ASSERT(g_debugMutex); + return *g_debugMutex; +} + +ScopedPerfEventHelper::ScopedPerfEventHelper(gl::Context *context, angle::EntryPoint entryPoint) + : mContext(context), mEntryPoint(entryPoint), mFunctionName(nullptr), mCalledBeginEvent(false) +{} + +ScopedPerfEventHelper::~ScopedPerfEventHelper() +{ + // EGL_Initialize() and EGL_Terminate() can change g_debugAnnotator. Must check the value of + // g_debugAnnotator and whether ScopedPerfEventHelper::begin() initiated a begine that must be + // ended now. + if (DebugAnnotationsInitialized() && mCalledBeginEvent) + { + g_debugAnnotator->endEvent(mContext, mFunctionName, mEntryPoint); + } +} + +void ScopedPerfEventHelper::begin(const char *format, ...) +{ + mFunctionName = GetEntryPointName(mEntryPoint); + + va_list vararg; + va_start(vararg, format); + + std::vector buffer; + size_t len = FormatStringIntoVector(format, vararg, buffer); + va_end(vararg); + + ANGLE_LOG(EVENT) << std::string(&buffer[0], len); + if (DebugAnnotationsInitialized()) + { + mCalledBeginEvent = true; + g_debugAnnotator->beginEvent(mContext, mEntryPoint, mFunctionName, buffer.data()); + } +} + +LogMessage::LogMessage(const char *file, const char *function, int line, LogSeverity severity) + : mFile(file), mFunction(function), mLine(line), mSeverity(severity) +{ + // INFO() and EVENT() do not require additional function(line) info. + if (mSeverity > LOG_INFO) + { + const char *slash = std::max(strrchr(mFile, '/'), strrchr(mFile, '\\')); + mStream << (slash ? (slash + 1) : mFile) << ":" << mLine << " (" << mFunction << "): "; + } +} + +LogMessage::~LogMessage() +{ + { + std::unique_lock lock; + if (g_debugMutex != nullptr) + { + lock = std::unique_lock(*g_debugMutex); + } + + if (DebugAnnotationsInitialized() && (mSeverity > LOG_INFO)) + { + g_debugAnnotator->logMessage(*this); + } + else + { + Trace(getSeverity(), getMessage().c_str()); + } + } + + if (mSeverity == LOG_FATAL) + { + if (angle::IsDebuggerAttached()) + { + angle::BreakDebugger(); + } + else + { + ANGLE_CRASH(); + } + } +} + +void Trace(LogSeverity severity, const char *message) +{ + if (!ShouldCreateLogMessage(severity)) + { + return; + } + + std::string str(message); + + if (DebugAnnotationsActive(/*context=*/nullptr)) + { + + switch (severity) + { + case LOG_EVENT: + // Debugging logging done in ScopedPerfEventHelper + break; + default: + g_debugAnnotator->setMarker(/*context=*/nullptr, message); + break; + } + } + + if (severity == LOG_FATAL || severity == LOG_ERR || severity == LOG_WARN || +#if defined(ANGLE_ENABLE_TRACE_ANDROID_LOGCAT) || defined(ANGLE_ENABLE_TRACE_EVENTS) + severity == LOG_EVENT || +#endif + severity == LOG_INFO) + { +#if defined(ANGLE_PLATFORM_ANDROID) + android_LogPriority android_priority = ANDROID_LOG_ERROR; + switch (severity) + { + case LOG_INFO: + case LOG_EVENT: + android_priority = ANDROID_LOG_INFO; + break; + case LOG_WARN: + android_priority = ANDROID_LOG_WARN; + break; + case LOG_ERR: + android_priority = ANDROID_LOG_ERROR; + break; + case LOG_FATAL: + android_priority = ANDROID_LOG_FATAL; + break; + default: + UNREACHABLE(); + } + __android_log_print(android_priority, "ANGLE", "%s: %s\n", LogSeverityName(severity), + str.c_str()); +#elif defined(ANGLE_PLATFORM_APPLE) + if (__builtin_available(macOS 10.12, iOS 10.0, *)) + { + os_log_type_t apple_log_type = OS_LOG_TYPE_DEFAULT; + switch (severity) + { + case LOG_INFO: + apple_log_type = OS_LOG_TYPE_INFO; + break; + case LOG_WARN: + apple_log_type = OS_LOG_TYPE_DEFAULT; + break; + case LOG_ERR: + apple_log_type = OS_LOG_TYPE_ERROR; + break; + case LOG_FATAL: + // OS_LOG_TYPE_FAULT is too severe - grabs the entire process tree. + apple_log_type = OS_LOG_TYPE_ERROR; + break; + default: + UNREACHABLE(); + } + os_log_with_type(OS_LOG_DEFAULT, apple_log_type, "ANGLE: %s: %s\n", + LogSeverityName(severity), str.c_str()); + } +#else + // Note: we use fprintf because includes static initializers. + fprintf((severity >= LOG_WARN) ? stderr : stdout, "%s: %s\n", LogSeverityName(severity), + str.c_str()); +#endif + } + +#if defined(ANGLE_PLATFORM_WINDOWS) && \ + (defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) || !defined(NDEBUG)) +# if !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) + if (severity >= LOG_ERR) +# endif // !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) + { + OutputDebugStringA(str.c_str()); + OutputDebugStringA("\n"); + } +#endif + +#if defined(ANGLE_ENABLE_DEBUG_TRACE) +# if defined(NDEBUG) + if (severity == LOG_EVENT || severity == LOG_WARN || severity == LOG_INFO) + { + return; + } +# endif // defined(NDEBUG) + static angle::base::NoDestructor file(TRACE_OUTPUT_FILE, std::ofstream::app); + if (file->good()) + { + if (severity > LOG_EVENT) + { + *file << LogSeverityName(severity) << ": "; + } + *file << str << "\n"; + file->flush(); + } +#endif // defined(ANGLE_ENABLE_DEBUG_TRACE) +} + +LogSeverity LogMessage::getSeverity() const +{ + return mSeverity; +} + +std::string LogMessage::getMessage() const +{ + return mStream.str(); +} + +#if defined(ANGLE_PLATFORM_WINDOWS) +priv::FmtHexHelper FmtHR(HRESULT value) +{ + return priv::FmtHexHelper("HRESULT: ", value); +} + +priv::FmtHexHelper FmtErr(DWORD value) +{ + return priv::FmtHexHelper("error: ", value); +} +#endif // defined(ANGLE_PLATFORM_WINDOWS) + +} // namespace gl diff --git a/gfx/angle/checkout/src/common/debug.h b/gfx/angle/checkout/src/common/debug.h new file mode 100644 index 0000000000..a9ee795103 --- /dev/null +++ b/gfx/angle/checkout/src/common/debug.h @@ -0,0 +1,468 @@ +// +// 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. +// + +// debug.h: Debugging utilities. A lot of the logging code is adapted from Chromium's +// base/logging.h. + +#ifndef COMMON_DEBUG_H_ +#define COMMON_DEBUG_H_ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common/angleutils.h" +#include "common/entry_points_enum_autogen.h" +#include "common/platform.h" + +#if defined(ANGLE_PLATFORM_WINDOWS) +# include +typedef unsigned long DWORD; +typedef _Return_type_success_(return >= 0) long HRESULT; +#endif + +#if !defined(TRACE_OUTPUT_FILE) +# define TRACE_OUTPUT_FILE "angle_debug.txt" +#endif + +namespace gl +{ +class Context; + +// Pairs a begin event with an end event. +class [[nodiscard]] ScopedPerfEventHelper : angle::NonCopyable +{ + public: + ScopedPerfEventHelper(Context *context, angle::EntryPoint entryPoint); + ~ScopedPerfEventHelper(); + ANGLE_FORMAT_PRINTF(2, 3) + void begin(const char *format, ...); + + private: + gl::Context *mContext; + const angle::EntryPoint mEntryPoint; + const char *mFunctionName; + bool mCalledBeginEvent; +}; + +using LogSeverity = int; +// Note: the log severities are used to index into the array of names, +// see g_logSeverityNames. +constexpr LogSeverity LOG_EVENT = 0; +constexpr LogSeverity LOG_INFO = 1; +constexpr LogSeverity LOG_WARN = 2; +constexpr LogSeverity LOG_ERR = 3; +constexpr LogSeverity LOG_FATAL = 4; +constexpr LogSeverity LOG_NUM_SEVERITIES = 5; + +void Trace(LogSeverity severity, const char *message); + +// This class more or less represents a particular log message. You +// create an instance of LogMessage and then stream stuff to it. +// When you finish streaming to it, ~LogMessage is called and the +// full message gets streamed to the appropriate destination. +// +// You shouldn't actually use LogMessage's constructor to log things, +// though. You should use the ERR() and WARN() macros. +class LogMessage : angle::NonCopyable +{ + public: + // Used for ANGLE_LOG(severity). + LogMessage(const char *file, const char *function, int line, LogSeverity severity); + ~LogMessage(); + std::ostream &stream() { return mStream; } + + LogSeverity getSeverity() const; + std::string getMessage() const; + + private: + const char *mFile; + const char *mFunction; + const int mLine; + const LogSeverity mSeverity; + + std::ostringstream mStream; +}; + +// Wraps the API/Platform-specific debug annotation functions. +// Also handles redirecting logging destination. +class DebugAnnotator : angle::NonCopyable +{ + public: + DebugAnnotator() {} + virtual ~DebugAnnotator() {} + virtual void beginEvent(gl::Context *context, + angle::EntryPoint entryPoint, + const char *eventName, + const char *eventMessage) = 0; + virtual void endEvent(gl::Context *context, + const char *eventName, + angle::EntryPoint entryPoint) = 0; + virtual void setMarker(gl::Context *context, const char *markerName) = 0; + virtual bool getStatus(const gl::Context *context) = 0; + // Log Message Handler that gets passed every log message, + // when debug annotations are initialized, + // replacing default handling by LogMessage. + virtual void logMessage(const LogMessage &msg) const = 0; +}; + +bool ShouldBeginScopedEvent(const gl::Context *context); +void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator); +void UninitializeDebugAnnotations(); +bool DebugAnnotationsActive(const gl::Context *context); +bool DebugAnnotationsInitialized(); + +void InitializeDebugMutexIfNeeded(); + +std::mutex &GetDebugMutex(); + +namespace priv +{ +// This class is used to explicitly ignore values in the conditional logging macros. This avoids +// compiler warnings like "value computed is not used" and "statement has no effect". +class LogMessageVoidify +{ + public: + LogMessageVoidify() {} + // This has to be an operator with a precedence lower than << but higher than ?: + void operator&(std::ostream &) {} +}; + +extern std::ostream *gSwallowStream; + +// Used by ANGLE_LOG_IS_ON to lazy-evaluate stream arguments. +bool ShouldCreatePlatformLogMessage(LogSeverity severity); + +// N is the width of the output to the stream. The output is padded with zeros +// if value is less than N characters. +// S is the stream type, either ostream for ANSI or wostream for wide character. +// T is the type of the value to output to the stream. +// C is the type of characters - either char for ANSI or wchar_t for wide char. +template +S &FmtHex(S &stream, T value, const C *zeroX, C zero) +{ + stream << zeroX; + + std::ios_base::fmtflags oldFlags = stream.flags(); + std::streamsize oldWidth = stream.width(); + typename S::char_type oldFill = stream.fill(); + + stream << std::hex << std::uppercase << std::setw(N) << std::setfill(zero) << value; + + stream.flags(oldFlags); + stream.width(oldWidth); + stream.fill(oldFill); + + return stream; +} + +template +S &FmtHexAutoSized(S &stream, T value, const C *prefix, const C *zeroX, C zero) +{ + if (prefix) + { + stream << prefix; + } + + constexpr int N = sizeof(T) * 2; + return priv::FmtHex(stream, value, zeroX, zero); +} + +template +class FmtHexHelper +{ + public: + FmtHexHelper(const C *prefix, T value) : mPrefix(prefix), mValue(value) {} + explicit FmtHexHelper(T value) : mPrefix(nullptr), mValue(value) {} + + private: + const C *mPrefix; + T mValue; + + friend std::ostream &operator<<(std::ostream &os, const FmtHexHelper &fmt) + { + return FmtHexAutoSized(os, fmt.mValue, fmt.mPrefix, "0x", '0'); + } + + friend std::wostream &operator<<(std::wostream &wos, const FmtHexHelper &fmt) + { + return FmtHexAutoSized(wos, fmt.mValue, fmt.mPrefix, L"0x", L'0'); + } +}; + +} // namespace priv + +template +priv::FmtHexHelper FmtHex(T value) +{ + return priv::FmtHexHelper(value); +} + +#if defined(ANGLE_PLATFORM_WINDOWS) +priv::FmtHexHelper FmtHR(HRESULT value); +priv::FmtHexHelper FmtErr(DWORD value); +#endif // defined(ANGLE_PLATFORM_WINDOWS) + +template +std::ostream &FmtHex(std::ostream &os, T value) +{ + return priv::FmtHexAutoSized(os, value, "", "0x", '0'); +} + +// A few definitions of macros that don't generate much code. These are used +// by ANGLE_LOG(). Since these are used all over our code, it's +// better to have compact code for these operations. +#define COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ...) \ + ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_EVENT, ##__VA_ARGS__) +#define COMPACT_ANGLE_LOG_EX_INFO(ClassName, ...) \ + ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_INFO, ##__VA_ARGS__) +#define COMPACT_ANGLE_LOG_EX_WARN(ClassName, ...) \ + ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_WARN, ##__VA_ARGS__) +#define COMPACT_ANGLE_LOG_EX_ERR(ClassName, ...) \ + ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_ERR, ##__VA_ARGS__) +#define COMPACT_ANGLE_LOG_EX_FATAL(ClassName, ...) \ + ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_FATAL, ##__VA_ARGS__) + +#define COMPACT_ANGLE_LOG_EVENT COMPACT_ANGLE_LOG_EX_EVENT(LogMessage) +#define COMPACT_ANGLE_LOG_INFO COMPACT_ANGLE_LOG_EX_INFO(LogMessage) +#define COMPACT_ANGLE_LOG_WARN COMPACT_ANGLE_LOG_EX_WARN(LogMessage) +#define COMPACT_ANGLE_LOG_ERR COMPACT_ANGLE_LOG_EX_ERR(LogMessage) +#define COMPACT_ANGLE_LOG_FATAL COMPACT_ANGLE_LOG_EX_FATAL(LogMessage) + +#define ANGLE_LOG_IS_ON(severity) (::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_##severity)) + +// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold. +// Condition is evaluated once and only once. +#define ANGLE_LAZY_STREAM(stream, condition) \ + !(condition) ? static_cast(0) : ::gl::priv::LogMessageVoidify() & (stream) + +// We use the preprocessor's merging operator, "##", so that, e.g., +// ANGLE_LOG(EVENT) becomes the token COMPACT_ANGLE_LOG_EVENT. There's some funny +// subtle difference between ostream member streaming functions (e.g., +// ostream::operator<<(int) and ostream non-member streaming functions +// (e.g., ::operator<<(ostream&, string&): it turns out that it's +// impossible to stream something like a string directly to an unnamed +// ostream. We employ a neat hack by calling the stream() member +// function of LogMessage which seems to avoid the problem. +#define ANGLE_LOG_STREAM(severity) COMPACT_ANGLE_LOG_##severity.stream() + +#define ANGLE_LOG(severity) ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(severity), ANGLE_LOG_IS_ON(severity)) + +} // namespace gl + +#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) +# define ANGLE_TRACE_ENABLED +#endif + +#if !defined(NDEBUG) || defined(ANGLE_ASSERT_ALWAYS_ON) +# define ANGLE_ENABLE_ASSERTS +#endif + +#define INFO() ANGLE_LOG(INFO) +#define WARN() ANGLE_LOG(WARN) +#define ERR() ANGLE_LOG(ERR) +#define FATAL() ANGLE_LOG(FATAL) + +// A macro to log a performance event around a scope. +#if defined(ANGLE_TRACE_ENABLED) +# if defined(_MSC_VER) +# define EVENT(context, entryPoint, message, ...) \ + gl::ScopedPerfEventHelper scopedPerfEventHelper##__LINE__( \ + context, angle::EntryPoint::entryPoint); \ + do \ + { \ + if (gl::ShouldBeginScopedEvent(context)) \ + { \ + scopedPerfEventHelper##__LINE__.begin( \ + "%s(" message ")", GetEntryPointName(angle::EntryPoint::entryPoint), \ + __VA_ARGS__); \ + } \ + } while (0) +# else +# define EVENT(context, entryPoint, message, ...) \ + gl::ScopedPerfEventHelper scopedPerfEventHelper(context, \ + angle::EntryPoint::entryPoint); \ + do \ + { \ + if (gl::ShouldBeginScopedEvent(context)) \ + { \ + scopedPerfEventHelper.begin("%s(" message ")", \ + GetEntryPointName(angle::EntryPoint::entryPoint), \ + ##__VA_ARGS__); \ + } \ + } while (0) +# endif // _MSC_VER +#else +# define EVENT(message, ...) (void(0)) +#endif + +// The state tracked by ANGLE will be validated with the driver state before each call +#if defined(ANGLE_ENABLE_DEBUG_TRACE) +# define ANGLE_STATE_VALIDATION_ENABLED +#endif + +#if defined(__GNUC__) +# define ANGLE_CRASH() __builtin_trap() +#else +# define ANGLE_CRASH() ((void)(*(volatile char *)0 = 0)), __assume(0) +#endif + +#if !defined(NDEBUG) +# define ANGLE_ASSERT_IMPL(expression) assert(expression) +#else +// TODO(jmadill): Detect if debugger is attached and break. +# define ANGLE_ASSERT_IMPL(expression) ANGLE_CRASH() +#endif // !defined(NDEBUG) + +// Note that gSwallowStream is used instead of an arbitrary LOG() stream to avoid the creation of an +// object with a non-trivial destructor (LogMessage). On MSVC x86 (checked on 2015 Update 3), this +// causes a few additional pointless instructions to be emitted even at full optimization level, +// even though the : arm of the ternary operator is clearly never executed. Using a simpler object +// to be &'d with Voidify() avoids these extra instructions. Using a simpler POD object with a +// templated operator<< also works to avoid these instructions. However, this causes warnings on +// statically defined implementations of operator<<(std::ostream, ...) in some .cpp files, because +// they become defined-but-unreferenced functions. A reinterpret_cast of 0 to an ostream* also is +// not suitable, because some compilers warn of undefined behavior. +#define ANGLE_EAT_STREAM_PARAMETERS \ + true ? static_cast(0) : ::gl::priv::LogMessageVoidify() & (*::gl::priv::gSwallowStream) + +// A macro asserting a condition and outputting failures to the debug log +#if defined(ANGLE_ENABLE_ASSERTS) +# define ASSERT(expression) \ + (expression ? static_cast(0) \ + : (FATAL() << "\t! Assert failed in " << __FUNCTION__ << " (" << __FILE__ \ + << ":" << __LINE__ << "): " << #expression)) +#else +# define ASSERT(condition) ANGLE_EAT_STREAM_PARAMETERS << !(condition) +#endif // defined(ANGLE_ENABLE_ASSERTS) + +#define ANGLE_UNUSED_VARIABLE(variable) (static_cast(variable)) + +// A macro to indicate unimplemented functionality +#ifndef NOASSERT_UNIMPLEMENTED +# define NOASSERT_UNIMPLEMENTED 1 +#endif + +#if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS) +# define UNIMPLEMENTED() \ + do \ + { \ + WARN() << "\t! Unimplemented: " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \ + << ")"; \ + ASSERT(NOASSERT_UNIMPLEMENTED); \ + } while (0) + +// A macro for code which is not expected to be reached under valid assumptions +# define UNREACHABLE() \ + do \ + { \ + FATAL() << "\t! Unreachable reached: " << __FUNCTION__ << "(" << __FILE__ << ":" \ + << __LINE__ << ")"; \ + } while (0) +#else +# define UNIMPLEMENTED() \ + do \ + { \ + ASSERT(NOASSERT_UNIMPLEMENTED); \ + } while (0) + +// A macro for code which is not expected to be reached under valid assumptions +# define UNREACHABLE() \ + do \ + { \ + ASSERT(false); \ + } while (0) +#endif // defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS) + +#if defined(ANGLE_PLATFORM_WINDOWS) +# define ANGLE_FUNCTION __FUNCTION__ +#else +# define ANGLE_FUNCTION __func__ +#endif + +// Defining ANGLE_ENABLE_STRUCT_PADDING_WARNINGS will enable warnings when members are added to +// structs to enforce packing. This is helpful for diagnosing unexpected struct sizes when making +// fast cache variables. +#if defined(__clang__) +# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic error \"-Wpadded\"") +# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS _Pragma("clang diagnostic pop") +#elif defined(__GNUC__) +# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS \ + _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic error \"-Wpadded\"") +# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS _Pragma("GCC diagnostic pop") +#elif defined(_MSC_VER) +# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS \ + __pragma(warning(push)) __pragma(warning(error : 4820)) +# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS __pragma(warning(pop)) +#else +# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS +# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS +#endif + +#if defined(__clang__) +# define ANGLE_DISABLE_SUGGEST_OVERRIDE_WARNINGS \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wsuggest-destructor-override\"") \ + _Pragma("clang diagnostic ignored \"-Wsuggest-override\"") +# define ANGLE_REENABLE_SUGGEST_OVERRIDE_WARNINGS _Pragma("clang diagnostic pop") +#else +# define ANGLE_DISABLE_SUGGEST_OVERRIDE_WARNINGS +# define ANGLE_REENABLE_SUGGEST_OVERRIDE_WARNINGS +#endif + +#if defined(__clang__) +# define ANGLE_DISABLE_EXTRA_SEMI_WARNING \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wextra-semi\"") +# define ANGLE_REENABLE_EXTRA_SEMI_WARNING _Pragma("clang diagnostic pop") +#else +# define ANGLE_DISABLE_EXTRA_SEMI_WARNING +# define ANGLE_REENABLE_EXTRA_SEMI_WARNING +#endif + +#if defined(__clang__) +# define ANGLE_DISABLE_EXTRA_SEMI_STMT_WARNING \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wextra-semi-stmt\"") +# define ANGLE_REENABLE_EXTRA_SEMI_STMT_WARNING _Pragma("clang diagnostic pop") +#else +# define ANGLE_DISABLE_EXTRA_SEMI_STMT_WARNING +# define ANGLE_REENABLE_EXTRA_SEMI_STMT_WARNING +#endif + +#if defined(__clang__) +# define ANGLE_DISABLE_SHADOWING_WARNING \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow-field\"") +# define ANGLE_REENABLE_SHADOWING_WARNING _Pragma("clang diagnostic pop") +#else +# define ANGLE_DISABLE_SHADOWING_WARNING +# define ANGLE_REENABLE_SHADOWING_WARNING +#endif + +#if defined(__clang__) +# define ANGLE_DISABLE_DESTRUCTOR_OVERRIDE_WARNING \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Winconsistent-missing-destructor-override\"") +# define ANGLE_REENABLE_DESTRUCTOR_OVERRIDE_WARNING _Pragma("clang diagnostic pop") +#else +# define ANGLE_DISABLE_DESTRUCTOR_OVERRIDE_WARNING +# define ANGLE_REENABLE_DESTRUCTOR_OVERRIDE_WARNING +#endif + +#if defined(__clang__) +# define ANGLE_DISABLE_UNUSED_FUNCTION_WARNING \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunused-function\"") +# define ANGLE_REENABLE_UNUSED_FUNCTION_WARNING _Pragma("clang diagnostic pop") +#else +# define ANGLE_DISABLE_UNUSED_FUNCTION_WARNING +# define ANGLE_REENABLE_UNUSED_FUNCTION_WARNING +#endif + +#endif // COMMON_DEBUG_H_ diff --git a/gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp b/gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp new file mode 100644 index 0000000000..993eecc8da --- /dev/null +++ b/gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp @@ -0,0 +1,3454 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 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. +// +// entry_points_enum_autogen.cpp: +// Helper methods for the GL/GLES entry points enumeration. + +#include "common/entry_points_enum_autogen.h" + +#include "common/debug.h" + +namespace angle +{ +const char *GetEntryPointName(EntryPoint ep) +{ + switch (ep) + { + case EntryPoint::CLBuildProgram: + return "clBuildProgram"; + case EntryPoint::CLCloneKernel: + return "clCloneKernel"; + case EntryPoint::CLCompileProgram: + return "clCompileProgram"; + case EntryPoint::CLCreateBuffer: + return "clCreateBuffer"; + case EntryPoint::CLCreateBufferWithProperties: + return "clCreateBufferWithProperties"; + case EntryPoint::CLCreateCommandQueue: + return "clCreateCommandQueue"; + case EntryPoint::CLCreateCommandQueueWithProperties: + return "clCreateCommandQueueWithProperties"; + case EntryPoint::CLCreateContext: + return "clCreateContext"; + case EntryPoint::CLCreateContextFromType: + return "clCreateContextFromType"; + case EntryPoint::CLCreateImage: + return "clCreateImage"; + case EntryPoint::CLCreateImage2D: + return "clCreateImage2D"; + case EntryPoint::CLCreateImage3D: + return "clCreateImage3D"; + case EntryPoint::CLCreateImageWithProperties: + return "clCreateImageWithProperties"; + case EntryPoint::CLCreateKernel: + return "clCreateKernel"; + case EntryPoint::CLCreateKernelsInProgram: + return "clCreateKernelsInProgram"; + case EntryPoint::CLCreatePipe: + return "clCreatePipe"; + case EntryPoint::CLCreateProgramWithBinary: + return "clCreateProgramWithBinary"; + case EntryPoint::CLCreateProgramWithBuiltInKernels: + return "clCreateProgramWithBuiltInKernels"; + case EntryPoint::CLCreateProgramWithIL: + return "clCreateProgramWithIL"; + case EntryPoint::CLCreateProgramWithSource: + return "clCreateProgramWithSource"; + case EntryPoint::CLCreateSampler: + return "clCreateSampler"; + case EntryPoint::CLCreateSamplerWithProperties: + return "clCreateSamplerWithProperties"; + case EntryPoint::CLCreateSubBuffer: + return "clCreateSubBuffer"; + case EntryPoint::CLCreateSubDevices: + return "clCreateSubDevices"; + case EntryPoint::CLCreateUserEvent: + return "clCreateUserEvent"; + case EntryPoint::CLEnqueueBarrier: + return "clEnqueueBarrier"; + case EntryPoint::CLEnqueueBarrierWithWaitList: + return "clEnqueueBarrierWithWaitList"; + case EntryPoint::CLEnqueueCopyBuffer: + return "clEnqueueCopyBuffer"; + case EntryPoint::CLEnqueueCopyBufferRect: + return "clEnqueueCopyBufferRect"; + case EntryPoint::CLEnqueueCopyBufferToImage: + return "clEnqueueCopyBufferToImage"; + case EntryPoint::CLEnqueueCopyImage: + return "clEnqueueCopyImage"; + case EntryPoint::CLEnqueueCopyImageToBuffer: + return "clEnqueueCopyImageToBuffer"; + case EntryPoint::CLEnqueueFillBuffer: + return "clEnqueueFillBuffer"; + case EntryPoint::CLEnqueueFillImage: + return "clEnqueueFillImage"; + case EntryPoint::CLEnqueueMapBuffer: + return "clEnqueueMapBuffer"; + case EntryPoint::CLEnqueueMapImage: + return "clEnqueueMapImage"; + case EntryPoint::CLEnqueueMarker: + return "clEnqueueMarker"; + case EntryPoint::CLEnqueueMarkerWithWaitList: + return "clEnqueueMarkerWithWaitList"; + case EntryPoint::CLEnqueueMigrateMemObjects: + return "clEnqueueMigrateMemObjects"; + case EntryPoint::CLEnqueueNDRangeKernel: + return "clEnqueueNDRangeKernel"; + case EntryPoint::CLEnqueueNativeKernel: + return "clEnqueueNativeKernel"; + case EntryPoint::CLEnqueueReadBuffer: + return "clEnqueueReadBuffer"; + case EntryPoint::CLEnqueueReadBufferRect: + return "clEnqueueReadBufferRect"; + case EntryPoint::CLEnqueueReadImage: + return "clEnqueueReadImage"; + case EntryPoint::CLEnqueueSVMFree: + return "clEnqueueSVMFree"; + case EntryPoint::CLEnqueueSVMMap: + return "clEnqueueSVMMap"; + case EntryPoint::CLEnqueueSVMMemFill: + return "clEnqueueSVMMemFill"; + case EntryPoint::CLEnqueueSVMMemcpy: + return "clEnqueueSVMMemcpy"; + case EntryPoint::CLEnqueueSVMMigrateMem: + return "clEnqueueSVMMigrateMem"; + case EntryPoint::CLEnqueueSVMUnmap: + return "clEnqueueSVMUnmap"; + case EntryPoint::CLEnqueueTask: + return "clEnqueueTask"; + case EntryPoint::CLEnqueueUnmapMemObject: + return "clEnqueueUnmapMemObject"; + case EntryPoint::CLEnqueueWaitForEvents: + return "clEnqueueWaitForEvents"; + case EntryPoint::CLEnqueueWriteBuffer: + return "clEnqueueWriteBuffer"; + case EntryPoint::CLEnqueueWriteBufferRect: + return "clEnqueueWriteBufferRect"; + case EntryPoint::CLEnqueueWriteImage: + return "clEnqueueWriteImage"; + case EntryPoint::CLFinish: + return "clFinish"; + case EntryPoint::CLFlush: + return "clFlush"; + case EntryPoint::CLGetCommandQueueInfo: + return "clGetCommandQueueInfo"; + case EntryPoint::CLGetContextInfo: + return "clGetContextInfo"; + case EntryPoint::CLGetDeviceAndHostTimer: + return "clGetDeviceAndHostTimer"; + case EntryPoint::CLGetDeviceIDs: + return "clGetDeviceIDs"; + case EntryPoint::CLGetDeviceInfo: + return "clGetDeviceInfo"; + case EntryPoint::CLGetEventInfo: + return "clGetEventInfo"; + case EntryPoint::CLGetEventProfilingInfo: + return "clGetEventProfilingInfo"; + case EntryPoint::CLGetExtensionFunctionAddress: + return "clGetExtensionFunctionAddress"; + case EntryPoint::CLGetExtensionFunctionAddressForPlatform: + return "clGetExtensionFunctionAddressForPlatform"; + case EntryPoint::CLGetHostTimer: + return "clGetHostTimer"; + case EntryPoint::CLGetImageInfo: + return "clGetImageInfo"; + case EntryPoint::CLGetKernelArgInfo: + return "clGetKernelArgInfo"; + case EntryPoint::CLGetKernelInfo: + return "clGetKernelInfo"; + case EntryPoint::CLGetKernelSubGroupInfo: + return "clGetKernelSubGroupInfo"; + case EntryPoint::CLGetKernelWorkGroupInfo: + return "clGetKernelWorkGroupInfo"; + case EntryPoint::CLGetMemObjectInfo: + return "clGetMemObjectInfo"; + case EntryPoint::CLGetPipeInfo: + return "clGetPipeInfo"; + case EntryPoint::CLGetPlatformIDs: + return "clGetPlatformIDs"; + case EntryPoint::CLGetPlatformInfo: + return "clGetPlatformInfo"; + case EntryPoint::CLGetProgramBuildInfo: + return "clGetProgramBuildInfo"; + case EntryPoint::CLGetProgramInfo: + return "clGetProgramInfo"; + case EntryPoint::CLGetSamplerInfo: + return "clGetSamplerInfo"; + case EntryPoint::CLGetSupportedImageFormats: + return "clGetSupportedImageFormats"; + case EntryPoint::CLIcdGetPlatformIDsKHR: + return "clIcdGetPlatformIDsKHR"; + case EntryPoint::CLLinkProgram: + return "clLinkProgram"; + case EntryPoint::CLReleaseCommandQueue: + return "clReleaseCommandQueue"; + case EntryPoint::CLReleaseContext: + return "clReleaseContext"; + case EntryPoint::CLReleaseDevice: + return "clReleaseDevice"; + case EntryPoint::CLReleaseEvent: + return "clReleaseEvent"; + case EntryPoint::CLReleaseKernel: + return "clReleaseKernel"; + case EntryPoint::CLReleaseMemObject: + return "clReleaseMemObject"; + case EntryPoint::CLReleaseProgram: + return "clReleaseProgram"; + case EntryPoint::CLReleaseSampler: + return "clReleaseSampler"; + case EntryPoint::CLRetainCommandQueue: + return "clRetainCommandQueue"; + case EntryPoint::CLRetainContext: + return "clRetainContext"; + case EntryPoint::CLRetainDevice: + return "clRetainDevice"; + case EntryPoint::CLRetainEvent: + return "clRetainEvent"; + case EntryPoint::CLRetainKernel: + return "clRetainKernel"; + case EntryPoint::CLRetainMemObject: + return "clRetainMemObject"; + case EntryPoint::CLRetainProgram: + return "clRetainProgram"; + case EntryPoint::CLRetainSampler: + return "clRetainSampler"; + case EntryPoint::CLSVMAlloc: + return "clSVMAlloc"; + case EntryPoint::CLSVMFree: + return "clSVMFree"; + case EntryPoint::CLSetCommandQueueProperty: + return "clSetCommandQueueProperty"; + case EntryPoint::CLSetContextDestructorCallback: + return "clSetContextDestructorCallback"; + case EntryPoint::CLSetDefaultDeviceCommandQueue: + return "clSetDefaultDeviceCommandQueue"; + case EntryPoint::CLSetEventCallback: + return "clSetEventCallback"; + case EntryPoint::CLSetKernelArg: + return "clSetKernelArg"; + case EntryPoint::CLSetKernelArgSVMPointer: + return "clSetKernelArgSVMPointer"; + case EntryPoint::CLSetKernelExecInfo: + return "clSetKernelExecInfo"; + case EntryPoint::CLSetMemObjectDestructorCallback: + return "clSetMemObjectDestructorCallback"; + case EntryPoint::CLSetProgramReleaseCallback: + return "clSetProgramReleaseCallback"; + case EntryPoint::CLSetProgramSpecializationConstant: + return "clSetProgramSpecializationConstant"; + case EntryPoint::CLSetUserEventStatus: + return "clSetUserEventStatus"; + case EntryPoint::CLUnloadCompiler: + return "clUnloadCompiler"; + case EntryPoint::CLUnloadPlatformCompiler: + return "clUnloadPlatformCompiler"; + case EntryPoint::CLWaitForEvents: + return "clWaitForEvents"; + case EntryPoint::EGLBindAPI: + return "eglBindAPI"; + case EntryPoint::EGLBindTexImage: + return "eglBindTexImage"; + case EntryPoint::EGLChooseConfig: + return "eglChooseConfig"; + case EntryPoint::EGLClientWaitSync: + return "eglClientWaitSync"; + case EntryPoint::EGLClientWaitSyncKHR: + return "eglClientWaitSyncKHR"; + case EntryPoint::EGLCopyBuffers: + return "eglCopyBuffers"; + case EntryPoint::EGLCopyMetalSharedEventANGLE: + return "eglCopyMetalSharedEventANGLE"; + case EntryPoint::EGLCreateContext: + return "eglCreateContext"; + case EntryPoint::EGLCreateDeviceANGLE: + return "eglCreateDeviceANGLE"; + case EntryPoint::EGLCreateImage: + return "eglCreateImage"; + case EntryPoint::EGLCreateImageKHR: + return "eglCreateImageKHR"; + case EntryPoint::EGLCreateNativeClientBufferANDROID: + return "eglCreateNativeClientBufferANDROID"; + case EntryPoint::EGLCreatePbufferFromClientBuffer: + return "eglCreatePbufferFromClientBuffer"; + case EntryPoint::EGLCreatePbufferSurface: + return "eglCreatePbufferSurface"; + case EntryPoint::EGLCreatePixmapSurface: + return "eglCreatePixmapSurface"; + case EntryPoint::EGLCreatePlatformPixmapSurface: + return "eglCreatePlatformPixmapSurface"; + case EntryPoint::EGLCreatePlatformPixmapSurfaceEXT: + return "eglCreatePlatformPixmapSurfaceEXT"; + case EntryPoint::EGLCreatePlatformWindowSurface: + return "eglCreatePlatformWindowSurface"; + case EntryPoint::EGLCreatePlatformWindowSurfaceEXT: + return "eglCreatePlatformWindowSurfaceEXT"; + case EntryPoint::EGLCreateStreamKHR: + return "eglCreateStreamKHR"; + case EntryPoint::EGLCreateStreamProducerD3DTextureANGLE: + return "eglCreateStreamProducerD3DTextureANGLE"; + case EntryPoint::EGLCreateSync: + return "eglCreateSync"; + case EntryPoint::EGLCreateSyncKHR: + return "eglCreateSyncKHR"; + case EntryPoint::EGLCreateWindowSurface: + return "eglCreateWindowSurface"; + case EntryPoint::EGLDebugMessageControlKHR: + return "eglDebugMessageControlKHR"; + case EntryPoint::EGLDestroyContext: + return "eglDestroyContext"; + case EntryPoint::EGLDestroyImage: + return "eglDestroyImage"; + case EntryPoint::EGLDestroyImageKHR: + return "eglDestroyImageKHR"; + case EntryPoint::EGLDestroyStreamKHR: + return "eglDestroyStreamKHR"; + case EntryPoint::EGLDestroySurface: + return "eglDestroySurface"; + case EntryPoint::EGLDestroySync: + return "eglDestroySync"; + case EntryPoint::EGLDestroySyncKHR: + return "eglDestroySyncKHR"; + case EntryPoint::EGLDupNativeFenceFDANDROID: + return "eglDupNativeFenceFDANDROID"; + case EntryPoint::EGLExportVkImageANGLE: + return "eglExportVkImageANGLE"; + case EntryPoint::EGLForceGPUSwitchANGLE: + return "eglForceGPUSwitchANGLE"; + case EntryPoint::EGLGetCompositorTimingANDROID: + return "eglGetCompositorTimingANDROID"; + case EntryPoint::EGLGetCompositorTimingSupportedANDROID: + return "eglGetCompositorTimingSupportedANDROID"; + case EntryPoint::EGLGetConfigAttrib: + return "eglGetConfigAttrib"; + case EntryPoint::EGLGetConfigs: + return "eglGetConfigs"; + case EntryPoint::EGLGetCurrentContext: + return "eglGetCurrentContext"; + case EntryPoint::EGLGetCurrentDisplay: + return "eglGetCurrentDisplay"; + case EntryPoint::EGLGetCurrentSurface: + return "eglGetCurrentSurface"; + case EntryPoint::EGLGetDisplay: + return "eglGetDisplay"; + case EntryPoint::EGLGetError: + return "eglGetError"; + case EntryPoint::EGLGetFrameTimestampSupportedANDROID: + return "eglGetFrameTimestampSupportedANDROID"; + case EntryPoint::EGLGetFrameTimestampsANDROID: + return "eglGetFrameTimestampsANDROID"; + case EntryPoint::EGLGetMscRateANGLE: + return "eglGetMscRateANGLE"; + case EntryPoint::EGLGetNativeClientBufferANDROID: + return "eglGetNativeClientBufferANDROID"; + case EntryPoint::EGLGetNextFrameIdANDROID: + return "eglGetNextFrameIdANDROID"; + case EntryPoint::EGLGetPlatformDisplay: + return "eglGetPlatformDisplay"; + case EntryPoint::EGLGetPlatformDisplayEXT: + return "eglGetPlatformDisplayEXT"; + case EntryPoint::EGLGetProcAddress: + return "eglGetProcAddress"; + case EntryPoint::EGLGetSyncAttrib: + return "eglGetSyncAttrib"; + case EntryPoint::EGLGetSyncAttribKHR: + return "eglGetSyncAttribKHR"; + case EntryPoint::EGLGetSyncValuesCHROMIUM: + return "eglGetSyncValuesCHROMIUM"; + case EntryPoint::EGLHandleGPUSwitchANGLE: + return "eglHandleGPUSwitchANGLE"; + case EntryPoint::EGLInitialize: + return "eglInitialize"; + case EntryPoint::EGLLabelObjectKHR: + return "eglLabelObjectKHR"; + case EntryPoint::EGLLockSurfaceKHR: + return "eglLockSurfaceKHR"; + case EntryPoint::EGLMakeCurrent: + return "eglMakeCurrent"; + case EntryPoint::EGLPostSubBufferNV: + return "eglPostSubBufferNV"; + case EntryPoint::EGLPrepareSwapBuffersANGLE: + return "eglPrepareSwapBuffersANGLE"; + case EntryPoint::EGLPresentationTimeANDROID: + return "eglPresentationTimeANDROID"; + case EntryPoint::EGLProgramCacheGetAttribANGLE: + return "eglProgramCacheGetAttribANGLE"; + case EntryPoint::EGLProgramCachePopulateANGLE: + return "eglProgramCachePopulateANGLE"; + case EntryPoint::EGLProgramCacheQueryANGLE: + return "eglProgramCacheQueryANGLE"; + case EntryPoint::EGLProgramCacheResizeANGLE: + return "eglProgramCacheResizeANGLE"; + case EntryPoint::EGLQueryAPI: + return "eglQueryAPI"; + case EntryPoint::EGLQueryContext: + return "eglQueryContext"; + case EntryPoint::EGLQueryDebugKHR: + return "eglQueryDebugKHR"; + case EntryPoint::EGLQueryDeviceAttribEXT: + return "eglQueryDeviceAttribEXT"; + case EntryPoint::EGLQueryDeviceStringEXT: + return "eglQueryDeviceStringEXT"; + case EntryPoint::EGLQueryDisplayAttribANGLE: + return "eglQueryDisplayAttribANGLE"; + case EntryPoint::EGLQueryDisplayAttribEXT: + return "eglQueryDisplayAttribEXT"; + case EntryPoint::EGLQueryDmaBufFormatsEXT: + return "eglQueryDmaBufFormatsEXT"; + case EntryPoint::EGLQueryDmaBufModifiersEXT: + return "eglQueryDmaBufModifiersEXT"; + case EntryPoint::EGLQueryStreamKHR: + return "eglQueryStreamKHR"; + case EntryPoint::EGLQueryStreamu64KHR: + return "eglQueryStreamu64KHR"; + case EntryPoint::EGLQueryString: + return "eglQueryString"; + case EntryPoint::EGLQueryStringiANGLE: + return "eglQueryStringiANGLE"; + case EntryPoint::EGLQuerySurface: + return "eglQuerySurface"; + case EntryPoint::EGLQuerySurface64KHR: + return "eglQuerySurface64KHR"; + case EntryPoint::EGLQuerySurfacePointerANGLE: + return "eglQuerySurfacePointerANGLE"; + case EntryPoint::EGLReacquireHighPowerGPUANGLE: + return "eglReacquireHighPowerGPUANGLE"; + case EntryPoint::EGLReleaseDeviceANGLE: + return "eglReleaseDeviceANGLE"; + case EntryPoint::EGLReleaseHighPowerGPUANGLE: + return "eglReleaseHighPowerGPUANGLE"; + case EntryPoint::EGLReleaseTexImage: + return "eglReleaseTexImage"; + case EntryPoint::EGLReleaseThread: + return "eglReleaseThread"; + case EntryPoint::EGLSetBlobCacheFuncsANDROID: + return "eglSetBlobCacheFuncsANDROID"; + case EntryPoint::EGLSetDamageRegionKHR: + return "eglSetDamageRegionKHR"; + case EntryPoint::EGLSignalSyncKHR: + return "eglSignalSyncKHR"; + case EntryPoint::EGLStreamAttribKHR: + return "eglStreamAttribKHR"; + case EntryPoint::EGLStreamConsumerAcquireKHR: + return "eglStreamConsumerAcquireKHR"; + case EntryPoint::EGLStreamConsumerGLTextureExternalAttribsNV: + return "eglStreamConsumerGLTextureExternalAttribsNV"; + case EntryPoint::EGLStreamConsumerGLTextureExternalKHR: + return "eglStreamConsumerGLTextureExternalKHR"; + case EntryPoint::EGLStreamConsumerReleaseKHR: + return "eglStreamConsumerReleaseKHR"; + case EntryPoint::EGLStreamPostD3DTextureANGLE: + return "eglStreamPostD3DTextureANGLE"; + case EntryPoint::EGLSurfaceAttrib: + return "eglSurfaceAttrib"; + case EntryPoint::EGLSwapBuffers: + return "eglSwapBuffers"; + case EntryPoint::EGLSwapBuffersWithDamageKHR: + return "eglSwapBuffersWithDamageKHR"; + case EntryPoint::EGLSwapBuffersWithFrameTokenANGLE: + return "eglSwapBuffersWithFrameTokenANGLE"; + case EntryPoint::EGLSwapInterval: + return "eglSwapInterval"; + case EntryPoint::EGLTerminate: + return "eglTerminate"; + case EntryPoint::EGLUnlockSurfaceKHR: + return "eglUnlockSurfaceKHR"; + case EntryPoint::EGLWaitClient: + return "eglWaitClient"; + case EntryPoint::EGLWaitGL: + return "eglWaitGL"; + case EntryPoint::EGLWaitNative: + return "eglWaitNative"; + case EntryPoint::EGLWaitSync: + return "eglWaitSync"; + case EntryPoint::EGLWaitSyncKHR: + return "eglWaitSyncKHR"; + case EntryPoint::GLAccum: + return "glAccum"; + case EntryPoint::GLAcquireTexturesANGLE: + return "glAcquireTexturesANGLE"; + case EntryPoint::GLActiveShaderProgram: + return "glActiveShaderProgram"; + case EntryPoint::GLActiveShaderProgramEXT: + return "glActiveShaderProgramEXT"; + case EntryPoint::GLActiveTexture: + return "glActiveTexture"; + case EntryPoint::GLAlphaFunc: + return "glAlphaFunc"; + case EntryPoint::GLAlphaFuncx: + return "glAlphaFuncx"; + case EntryPoint::GLAreTexturesResident: + return "glAreTexturesResident"; + case EntryPoint::GLArrayElement: + return "glArrayElement"; + case EntryPoint::GLAttachShader: + return "glAttachShader"; + case EntryPoint::GLBegin: + return "glBegin"; + case EntryPoint::GLBeginConditionalRender: + return "glBeginConditionalRender"; + case EntryPoint::GLBeginPerfMonitorAMD: + return "glBeginPerfMonitorAMD"; + case EntryPoint::GLBeginPixelLocalStorageANGLE: + return "glBeginPixelLocalStorageANGLE"; + case EntryPoint::GLBeginQuery: + return "glBeginQuery"; + case EntryPoint::GLBeginQueryEXT: + return "glBeginQueryEXT"; + case EntryPoint::GLBeginQueryIndexed: + return "glBeginQueryIndexed"; + case EntryPoint::GLBeginTransformFeedback: + return "glBeginTransformFeedback"; + case EntryPoint::GLBindAttribLocation: + return "glBindAttribLocation"; + case EntryPoint::GLBindBuffer: + return "glBindBuffer"; + case EntryPoint::GLBindBufferBase: + return "glBindBufferBase"; + case EntryPoint::GLBindBufferRange: + return "glBindBufferRange"; + case EntryPoint::GLBindBuffersBase: + return "glBindBuffersBase"; + case EntryPoint::GLBindBuffersRange: + return "glBindBuffersRange"; + case EntryPoint::GLBindFragDataLocation: + return "glBindFragDataLocation"; + case EntryPoint::GLBindFragDataLocationEXT: + return "glBindFragDataLocationEXT"; + case EntryPoint::GLBindFragDataLocationIndexed: + return "glBindFragDataLocationIndexed"; + case EntryPoint::GLBindFragDataLocationIndexedEXT: + return "glBindFragDataLocationIndexedEXT"; + case EntryPoint::GLBindFramebuffer: + return "glBindFramebuffer"; + case EntryPoint::GLBindFramebufferOES: + return "glBindFramebufferOES"; + case EntryPoint::GLBindImageTexture: + return "glBindImageTexture"; + case EntryPoint::GLBindImageTextures: + return "glBindImageTextures"; + case EntryPoint::GLBindProgramPipeline: + return "glBindProgramPipeline"; + case EntryPoint::GLBindProgramPipelineEXT: + return "glBindProgramPipelineEXT"; + case EntryPoint::GLBindRenderbuffer: + return "glBindRenderbuffer"; + case EntryPoint::GLBindRenderbufferOES: + return "glBindRenderbufferOES"; + case EntryPoint::GLBindSampler: + return "glBindSampler"; + case EntryPoint::GLBindSamplers: + return "glBindSamplers"; + case EntryPoint::GLBindTexture: + return "glBindTexture"; + case EntryPoint::GLBindTextureUnit: + return "glBindTextureUnit"; + case EntryPoint::GLBindTextures: + return "glBindTextures"; + case EntryPoint::GLBindTransformFeedback: + return "glBindTransformFeedback"; + case EntryPoint::GLBindUniformLocationCHROMIUM: + return "glBindUniformLocationCHROMIUM"; + case EntryPoint::GLBindVertexArray: + return "glBindVertexArray"; + case EntryPoint::GLBindVertexArrayOES: + return "glBindVertexArrayOES"; + case EntryPoint::GLBindVertexBuffer: + return "glBindVertexBuffer"; + case EntryPoint::GLBindVertexBuffers: + return "glBindVertexBuffers"; + case EntryPoint::GLBitmap: + return "glBitmap"; + case EntryPoint::GLBlendBarrier: + return "glBlendBarrier"; + case EntryPoint::GLBlendBarrierKHR: + return "glBlendBarrierKHR"; + case EntryPoint::GLBlendColor: + return "glBlendColor"; + case EntryPoint::GLBlendEquation: + return "glBlendEquation"; + case EntryPoint::GLBlendEquationSeparate: + return "glBlendEquationSeparate"; + case EntryPoint::GLBlendEquationSeparatei: + return "glBlendEquationSeparatei"; + case EntryPoint::GLBlendEquationSeparateiEXT: + return "glBlendEquationSeparateiEXT"; + case EntryPoint::GLBlendEquationSeparateiOES: + return "glBlendEquationSeparateiOES"; + case EntryPoint::GLBlendEquationi: + return "glBlendEquationi"; + case EntryPoint::GLBlendEquationiEXT: + return "glBlendEquationiEXT"; + case EntryPoint::GLBlendEquationiOES: + return "glBlendEquationiOES"; + case EntryPoint::GLBlendFunc: + return "glBlendFunc"; + case EntryPoint::GLBlendFuncSeparate: + return "glBlendFuncSeparate"; + case EntryPoint::GLBlendFuncSeparatei: + return "glBlendFuncSeparatei"; + case EntryPoint::GLBlendFuncSeparateiEXT: + return "glBlendFuncSeparateiEXT"; + case EntryPoint::GLBlendFuncSeparateiOES: + return "glBlendFuncSeparateiOES"; + case EntryPoint::GLBlendFunci: + return "glBlendFunci"; + case EntryPoint::GLBlendFunciEXT: + return "glBlendFunciEXT"; + case EntryPoint::GLBlendFunciOES: + return "glBlendFunciOES"; + case EntryPoint::GLBlitFramebuffer: + return "glBlitFramebuffer"; + case EntryPoint::GLBlitFramebufferANGLE: + return "glBlitFramebufferANGLE"; + case EntryPoint::GLBlitFramebufferNV: + return "glBlitFramebufferNV"; + case EntryPoint::GLBlitNamedFramebuffer: + return "glBlitNamedFramebuffer"; + case EntryPoint::GLBufferData: + return "glBufferData"; + case EntryPoint::GLBufferStorage: + return "glBufferStorage"; + case EntryPoint::GLBufferStorageEXT: + return "glBufferStorageEXT"; + case EntryPoint::GLBufferStorageExternalEXT: + return "glBufferStorageExternalEXT"; + case EntryPoint::GLBufferStorageMemEXT: + return "glBufferStorageMemEXT"; + case EntryPoint::GLBufferSubData: + return "glBufferSubData"; + case EntryPoint::GLCallList: + return "glCallList"; + case EntryPoint::GLCallLists: + return "glCallLists"; + case EntryPoint::GLCheckFramebufferStatus: + return "glCheckFramebufferStatus"; + case EntryPoint::GLCheckFramebufferStatusOES: + return "glCheckFramebufferStatusOES"; + case EntryPoint::GLCheckNamedFramebufferStatus: + return "glCheckNamedFramebufferStatus"; + case EntryPoint::GLClampColor: + return "glClampColor"; + case EntryPoint::GLClear: + return "glClear"; + case EntryPoint::GLClearAccum: + return "glClearAccum"; + case EntryPoint::GLClearBufferData: + return "glClearBufferData"; + case EntryPoint::GLClearBufferSubData: + return "glClearBufferSubData"; + case EntryPoint::GLClearBufferfi: + return "glClearBufferfi"; + case EntryPoint::GLClearBufferfv: + return "glClearBufferfv"; + case EntryPoint::GLClearBufferiv: + return "glClearBufferiv"; + case EntryPoint::GLClearBufferuiv: + return "glClearBufferuiv"; + case EntryPoint::GLClearColor: + return "glClearColor"; + case EntryPoint::GLClearColorx: + return "glClearColorx"; + case EntryPoint::GLClearDepth: + return "glClearDepth"; + case EntryPoint::GLClearDepthf: + return "glClearDepthf"; + case EntryPoint::GLClearDepthx: + return "glClearDepthx"; + case EntryPoint::GLClearIndex: + return "glClearIndex"; + case EntryPoint::GLClearNamedBufferData: + return "glClearNamedBufferData"; + case EntryPoint::GLClearNamedBufferSubData: + return "glClearNamedBufferSubData"; + case EntryPoint::GLClearNamedFramebufferfi: + return "glClearNamedFramebufferfi"; + case EntryPoint::GLClearNamedFramebufferfv: + return "glClearNamedFramebufferfv"; + case EntryPoint::GLClearNamedFramebufferiv: + return "glClearNamedFramebufferiv"; + case EntryPoint::GLClearNamedFramebufferuiv: + return "glClearNamedFramebufferuiv"; + case EntryPoint::GLClearStencil: + return "glClearStencil"; + case EntryPoint::GLClearTexImage: + return "glClearTexImage"; + case EntryPoint::GLClearTexSubImage: + return "glClearTexSubImage"; + case EntryPoint::GLClientActiveTexture: + return "glClientActiveTexture"; + case EntryPoint::GLClientWaitSync: + return "glClientWaitSync"; + case EntryPoint::GLClipControl: + return "glClipControl"; + case EntryPoint::GLClipControlEXT: + return "glClipControlEXT"; + case EntryPoint::GLClipPlane: + return "glClipPlane"; + case EntryPoint::GLClipPlanef: + return "glClipPlanef"; + case EntryPoint::GLClipPlanex: + return "glClipPlanex"; + case EntryPoint::GLColor3b: + return "glColor3b"; + case EntryPoint::GLColor3bv: + return "glColor3bv"; + case EntryPoint::GLColor3d: + return "glColor3d"; + case EntryPoint::GLColor3dv: + return "glColor3dv"; + case EntryPoint::GLColor3f: + return "glColor3f"; + case EntryPoint::GLColor3fv: + return "glColor3fv"; + case EntryPoint::GLColor3i: + return "glColor3i"; + case EntryPoint::GLColor3iv: + return "glColor3iv"; + case EntryPoint::GLColor3s: + return "glColor3s"; + case EntryPoint::GLColor3sv: + return "glColor3sv"; + case EntryPoint::GLColor3ub: + return "glColor3ub"; + case EntryPoint::GLColor3ubv: + return "glColor3ubv"; + case EntryPoint::GLColor3ui: + return "glColor3ui"; + case EntryPoint::GLColor3uiv: + return "glColor3uiv"; + case EntryPoint::GLColor3us: + return "glColor3us"; + case EntryPoint::GLColor3usv: + return "glColor3usv"; + case EntryPoint::GLColor4b: + return "glColor4b"; + case EntryPoint::GLColor4bv: + return "glColor4bv"; + case EntryPoint::GLColor4d: + return "glColor4d"; + case EntryPoint::GLColor4dv: + return "glColor4dv"; + case EntryPoint::GLColor4f: + return "glColor4f"; + case EntryPoint::GLColor4fv: + return "glColor4fv"; + case EntryPoint::GLColor4i: + return "glColor4i"; + case EntryPoint::GLColor4iv: + return "glColor4iv"; + case EntryPoint::GLColor4s: + return "glColor4s"; + case EntryPoint::GLColor4sv: + return "glColor4sv"; + case EntryPoint::GLColor4ub: + return "glColor4ub"; + case EntryPoint::GLColor4ubv: + return "glColor4ubv"; + case EntryPoint::GLColor4ui: + return "glColor4ui"; + case EntryPoint::GLColor4uiv: + return "glColor4uiv"; + case EntryPoint::GLColor4us: + return "glColor4us"; + case EntryPoint::GLColor4usv: + return "glColor4usv"; + case EntryPoint::GLColor4x: + return "glColor4x"; + case EntryPoint::GLColorMask: + return "glColorMask"; + case EntryPoint::GLColorMaski: + return "glColorMaski"; + case EntryPoint::GLColorMaskiEXT: + return "glColorMaskiEXT"; + case EntryPoint::GLColorMaskiOES: + return "glColorMaskiOES"; + case EntryPoint::GLColorMaterial: + return "glColorMaterial"; + case EntryPoint::GLColorP3ui: + return "glColorP3ui"; + case EntryPoint::GLColorP3uiv: + return "glColorP3uiv"; + case EntryPoint::GLColorP4ui: + return "glColorP4ui"; + case EntryPoint::GLColorP4uiv: + return "glColorP4uiv"; + case EntryPoint::GLColorPointer: + return "glColorPointer"; + case EntryPoint::GLCompileShader: + return "glCompileShader"; + case EntryPoint::GLCompressedCopyTextureCHROMIUM: + return "glCompressedCopyTextureCHROMIUM"; + case EntryPoint::GLCompressedTexImage1D: + return "glCompressedTexImage1D"; + case EntryPoint::GLCompressedTexImage2D: + return "glCompressedTexImage2D"; + case EntryPoint::GLCompressedTexImage2DRobustANGLE: + return "glCompressedTexImage2DRobustANGLE"; + case EntryPoint::GLCompressedTexImage3D: + return "glCompressedTexImage3D"; + case EntryPoint::GLCompressedTexImage3DOES: + return "glCompressedTexImage3DOES"; + case EntryPoint::GLCompressedTexImage3DRobustANGLE: + return "glCompressedTexImage3DRobustANGLE"; + case EntryPoint::GLCompressedTexSubImage1D: + return "glCompressedTexSubImage1D"; + case EntryPoint::GLCompressedTexSubImage2D: + return "glCompressedTexSubImage2D"; + case EntryPoint::GLCompressedTexSubImage2DRobustANGLE: + return "glCompressedTexSubImage2DRobustANGLE"; + case EntryPoint::GLCompressedTexSubImage3D: + return "glCompressedTexSubImage3D"; + case EntryPoint::GLCompressedTexSubImage3DOES: + return "glCompressedTexSubImage3DOES"; + case EntryPoint::GLCompressedTexSubImage3DRobustANGLE: + return "glCompressedTexSubImage3DRobustANGLE"; + case EntryPoint::GLCompressedTextureSubImage1D: + return "glCompressedTextureSubImage1D"; + case EntryPoint::GLCompressedTextureSubImage2D: + return "glCompressedTextureSubImage2D"; + case EntryPoint::GLCompressedTextureSubImage3D: + return "glCompressedTextureSubImage3D"; + case EntryPoint::GLCopyBufferSubData: + return "glCopyBufferSubData"; + case EntryPoint::GLCopyImageSubData: + return "glCopyImageSubData"; + case EntryPoint::GLCopyImageSubDataEXT: + return "glCopyImageSubDataEXT"; + case EntryPoint::GLCopyImageSubDataOES: + return "glCopyImageSubDataOES"; + case EntryPoint::GLCopyNamedBufferSubData: + return "glCopyNamedBufferSubData"; + case EntryPoint::GLCopyPixels: + return "glCopyPixels"; + case EntryPoint::GLCopySubTexture3DANGLE: + return "glCopySubTexture3DANGLE"; + case EntryPoint::GLCopySubTextureCHROMIUM: + return "glCopySubTextureCHROMIUM"; + case EntryPoint::GLCopyTexImage1D: + return "glCopyTexImage1D"; + case EntryPoint::GLCopyTexImage2D: + return "glCopyTexImage2D"; + case EntryPoint::GLCopyTexSubImage1D: + return "glCopyTexSubImage1D"; + case EntryPoint::GLCopyTexSubImage2D: + return "glCopyTexSubImage2D"; + case EntryPoint::GLCopyTexSubImage3D: + return "glCopyTexSubImage3D"; + case EntryPoint::GLCopyTexSubImage3DOES: + return "glCopyTexSubImage3DOES"; + case EntryPoint::GLCopyTexture3DANGLE: + return "glCopyTexture3DANGLE"; + case EntryPoint::GLCopyTextureCHROMIUM: + return "glCopyTextureCHROMIUM"; + case EntryPoint::GLCopyTextureSubImage1D: + return "glCopyTextureSubImage1D"; + case EntryPoint::GLCopyTextureSubImage2D: + return "glCopyTextureSubImage2D"; + case EntryPoint::GLCopyTextureSubImage3D: + return "glCopyTextureSubImage3D"; + case EntryPoint::GLCoverageModulationCHROMIUM: + return "glCoverageModulationCHROMIUM"; + case EntryPoint::GLCreateBuffers: + return "glCreateBuffers"; + case EntryPoint::GLCreateFramebuffers: + return "glCreateFramebuffers"; + case EntryPoint::GLCreateMemoryObjectsEXT: + return "glCreateMemoryObjectsEXT"; + case EntryPoint::GLCreateProgram: + return "glCreateProgram"; + case EntryPoint::GLCreateProgramPipelines: + return "glCreateProgramPipelines"; + case EntryPoint::GLCreateQueries: + return "glCreateQueries"; + case EntryPoint::GLCreateRenderbuffers: + return "glCreateRenderbuffers"; + case EntryPoint::GLCreateSamplers: + return "glCreateSamplers"; + case EntryPoint::GLCreateShader: + return "glCreateShader"; + case EntryPoint::GLCreateShaderProgramv: + return "glCreateShaderProgramv"; + case EntryPoint::GLCreateShaderProgramvEXT: + return "glCreateShaderProgramvEXT"; + case EntryPoint::GLCreateTextures: + return "glCreateTextures"; + case EntryPoint::GLCreateTransformFeedbacks: + return "glCreateTransformFeedbacks"; + case EntryPoint::GLCreateVertexArrays: + return "glCreateVertexArrays"; + case EntryPoint::GLCullFace: + return "glCullFace"; + case EntryPoint::GLCurrentPaletteMatrixOES: + return "glCurrentPaletteMatrixOES"; + case EntryPoint::GLDebugMessageCallback: + return "glDebugMessageCallback"; + case EntryPoint::GLDebugMessageCallbackKHR: + return "glDebugMessageCallbackKHR"; + case EntryPoint::GLDebugMessageControl: + return "glDebugMessageControl"; + case EntryPoint::GLDebugMessageControlKHR: + return "glDebugMessageControlKHR"; + case EntryPoint::GLDebugMessageInsert: + return "glDebugMessageInsert"; + case EntryPoint::GLDebugMessageInsertKHR: + return "glDebugMessageInsertKHR"; + case EntryPoint::GLDeleteBuffers: + return "glDeleteBuffers"; + case EntryPoint::GLDeleteFencesNV: + return "glDeleteFencesNV"; + case EntryPoint::GLDeleteFramebuffers: + return "glDeleteFramebuffers"; + case EntryPoint::GLDeleteFramebuffersOES: + return "glDeleteFramebuffersOES"; + case EntryPoint::GLDeleteLists: + return "glDeleteLists"; + case EntryPoint::GLDeleteMemoryObjectsEXT: + return "glDeleteMemoryObjectsEXT"; + case EntryPoint::GLDeletePerfMonitorsAMD: + return "glDeletePerfMonitorsAMD"; + case EntryPoint::GLDeleteProgram: + return "glDeleteProgram"; + case EntryPoint::GLDeleteProgramPipelines: + return "glDeleteProgramPipelines"; + case EntryPoint::GLDeleteProgramPipelinesEXT: + return "glDeleteProgramPipelinesEXT"; + case EntryPoint::GLDeleteQueries: + return "glDeleteQueries"; + case EntryPoint::GLDeleteQueriesEXT: + return "glDeleteQueriesEXT"; + case EntryPoint::GLDeleteRenderbuffers: + return "glDeleteRenderbuffers"; + case EntryPoint::GLDeleteRenderbuffersOES: + return "glDeleteRenderbuffersOES"; + case EntryPoint::GLDeleteSamplers: + return "glDeleteSamplers"; + case EntryPoint::GLDeleteSemaphoresEXT: + return "glDeleteSemaphoresEXT"; + case EntryPoint::GLDeleteShader: + return "glDeleteShader"; + case EntryPoint::GLDeleteSync: + return "glDeleteSync"; + case EntryPoint::GLDeleteTextures: + return "glDeleteTextures"; + case EntryPoint::GLDeleteTransformFeedbacks: + return "glDeleteTransformFeedbacks"; + case EntryPoint::GLDeleteVertexArrays: + return "glDeleteVertexArrays"; + case EntryPoint::GLDeleteVertexArraysOES: + return "glDeleteVertexArraysOES"; + case EntryPoint::GLDepthFunc: + return "glDepthFunc"; + case EntryPoint::GLDepthMask: + return "glDepthMask"; + case EntryPoint::GLDepthRange: + return "glDepthRange"; + case EntryPoint::GLDepthRangeArrayv: + return "glDepthRangeArrayv"; + case EntryPoint::GLDepthRangeIndexed: + return "glDepthRangeIndexed"; + case EntryPoint::GLDepthRangef: + return "glDepthRangef"; + case EntryPoint::GLDepthRangex: + return "glDepthRangex"; + case EntryPoint::GLDetachShader: + return "glDetachShader"; + case EntryPoint::GLDisable: + return "glDisable"; + case EntryPoint::GLDisableClientState: + return "glDisableClientState"; + case EntryPoint::GLDisableExtensionANGLE: + return "glDisableExtensionANGLE"; + case EntryPoint::GLDisableVertexArrayAttrib: + return "glDisableVertexArrayAttrib"; + case EntryPoint::GLDisableVertexAttribArray: + return "glDisableVertexAttribArray"; + case EntryPoint::GLDisablei: + return "glDisablei"; + case EntryPoint::GLDisableiEXT: + return "glDisableiEXT"; + case EntryPoint::GLDisableiOES: + return "glDisableiOES"; + case EntryPoint::GLDiscardFramebufferEXT: + return "glDiscardFramebufferEXT"; + case EntryPoint::GLDispatchCompute: + return "glDispatchCompute"; + case EntryPoint::GLDispatchComputeIndirect: + return "glDispatchComputeIndirect"; + case EntryPoint::GLDrawArrays: + return "glDrawArrays"; + case EntryPoint::GLDrawArraysIndirect: + return "glDrawArraysIndirect"; + case EntryPoint::GLDrawArraysInstanced: + return "glDrawArraysInstanced"; + case EntryPoint::GLDrawArraysInstancedANGLE: + return "glDrawArraysInstancedANGLE"; + case EntryPoint::GLDrawArraysInstancedBaseInstance: + return "glDrawArraysInstancedBaseInstance"; + case EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE: + return "glDrawArraysInstancedBaseInstanceANGLE"; + case EntryPoint::GLDrawArraysInstancedBaseInstanceEXT: + return "glDrawArraysInstancedBaseInstanceEXT"; + case EntryPoint::GLDrawArraysInstancedEXT: + return "glDrawArraysInstancedEXT"; + case EntryPoint::GLDrawBuffer: + return "glDrawBuffer"; + case EntryPoint::GLDrawBuffers: + return "glDrawBuffers"; + case EntryPoint::GLDrawBuffersEXT: + return "glDrawBuffersEXT"; + case EntryPoint::GLDrawElements: + return "glDrawElements"; + case EntryPoint::GLDrawElementsBaseVertex: + return "glDrawElementsBaseVertex"; + case EntryPoint::GLDrawElementsBaseVertexEXT: + return "glDrawElementsBaseVertexEXT"; + case EntryPoint::GLDrawElementsBaseVertexOES: + return "glDrawElementsBaseVertexOES"; + case EntryPoint::GLDrawElementsIndirect: + return "glDrawElementsIndirect"; + case EntryPoint::GLDrawElementsInstanced: + return "glDrawElementsInstanced"; + case EntryPoint::GLDrawElementsInstancedANGLE: + return "glDrawElementsInstancedANGLE"; + case EntryPoint::GLDrawElementsInstancedBaseInstance: + return "glDrawElementsInstancedBaseInstance"; + case EntryPoint::GLDrawElementsInstancedBaseInstanceEXT: + return "glDrawElementsInstancedBaseInstanceEXT"; + case EntryPoint::GLDrawElementsInstancedBaseVertex: + return "glDrawElementsInstancedBaseVertex"; + case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstance: + return "glDrawElementsInstancedBaseVertexBaseInstance"; + case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE: + return "glDrawElementsInstancedBaseVertexBaseInstanceANGLE"; + case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceEXT: + return "glDrawElementsInstancedBaseVertexBaseInstanceEXT"; + case EntryPoint::GLDrawElementsInstancedBaseVertexEXT: + return "glDrawElementsInstancedBaseVertexEXT"; + case EntryPoint::GLDrawElementsInstancedBaseVertexOES: + return "glDrawElementsInstancedBaseVertexOES"; + case EntryPoint::GLDrawElementsInstancedEXT: + return "glDrawElementsInstancedEXT"; + case EntryPoint::GLDrawPixels: + return "glDrawPixels"; + case EntryPoint::GLDrawRangeElements: + return "glDrawRangeElements"; + case EntryPoint::GLDrawRangeElementsBaseVertex: + return "glDrawRangeElementsBaseVertex"; + case EntryPoint::GLDrawRangeElementsBaseVertexEXT: + return "glDrawRangeElementsBaseVertexEXT"; + case EntryPoint::GLDrawRangeElementsBaseVertexOES: + return "glDrawRangeElementsBaseVertexOES"; + case EntryPoint::GLDrawTexfOES: + return "glDrawTexfOES"; + case EntryPoint::GLDrawTexfvOES: + return "glDrawTexfvOES"; + case EntryPoint::GLDrawTexiOES: + return "glDrawTexiOES"; + case EntryPoint::GLDrawTexivOES: + return "glDrawTexivOES"; + case EntryPoint::GLDrawTexsOES: + return "glDrawTexsOES"; + case EntryPoint::GLDrawTexsvOES: + return "glDrawTexsvOES"; + case EntryPoint::GLDrawTexxOES: + return "glDrawTexxOES"; + case EntryPoint::GLDrawTexxvOES: + return "glDrawTexxvOES"; + case EntryPoint::GLDrawTransformFeedback: + return "glDrawTransformFeedback"; + case EntryPoint::GLDrawTransformFeedbackInstanced: + return "glDrawTransformFeedbackInstanced"; + case EntryPoint::GLDrawTransformFeedbackStream: + return "glDrawTransformFeedbackStream"; + case EntryPoint::GLDrawTransformFeedbackStreamInstanced: + return "glDrawTransformFeedbackStreamInstanced"; + case EntryPoint::GLEGLImageTargetRenderbufferStorageOES: + return "glEGLImageTargetRenderbufferStorageOES"; + case EntryPoint::GLEGLImageTargetTexStorageEXT: + return "glEGLImageTargetTexStorageEXT"; + case EntryPoint::GLEGLImageTargetTexture2DOES: + return "glEGLImageTargetTexture2DOES"; + case EntryPoint::GLEGLImageTargetTextureStorageEXT: + return "glEGLImageTargetTextureStorageEXT"; + case EntryPoint::GLEdgeFlag: + return "glEdgeFlag"; + case EntryPoint::GLEdgeFlagPointer: + return "glEdgeFlagPointer"; + case EntryPoint::GLEdgeFlagv: + return "glEdgeFlagv"; + case EntryPoint::GLEnable: + return "glEnable"; + case EntryPoint::GLEnableClientState: + return "glEnableClientState"; + case EntryPoint::GLEnableVertexArrayAttrib: + return "glEnableVertexArrayAttrib"; + case EntryPoint::GLEnableVertexAttribArray: + return "glEnableVertexAttribArray"; + case EntryPoint::GLEnablei: + return "glEnablei"; + case EntryPoint::GLEnableiEXT: + return "glEnableiEXT"; + case EntryPoint::GLEnableiOES: + return "glEnableiOES"; + case EntryPoint::GLEnd: + return "glEnd"; + case EntryPoint::GLEndConditionalRender: + return "glEndConditionalRender"; + case EntryPoint::GLEndList: + return "glEndList"; + case EntryPoint::GLEndPerfMonitorAMD: + return "glEndPerfMonitorAMD"; + case EntryPoint::GLEndPixelLocalStorageANGLE: + return "glEndPixelLocalStorageANGLE"; + case EntryPoint::GLEndQuery: + return "glEndQuery"; + case EntryPoint::GLEndQueryEXT: + return "glEndQueryEXT"; + case EntryPoint::GLEndQueryIndexed: + return "glEndQueryIndexed"; + case EntryPoint::GLEndTransformFeedback: + return "glEndTransformFeedback"; + case EntryPoint::GLEvalCoord1d: + return "glEvalCoord1d"; + case EntryPoint::GLEvalCoord1dv: + return "glEvalCoord1dv"; + case EntryPoint::GLEvalCoord1f: + return "glEvalCoord1f"; + case EntryPoint::GLEvalCoord1fv: + return "glEvalCoord1fv"; + case EntryPoint::GLEvalCoord2d: + return "glEvalCoord2d"; + case EntryPoint::GLEvalCoord2dv: + return "glEvalCoord2dv"; + case EntryPoint::GLEvalCoord2f: + return "glEvalCoord2f"; + case EntryPoint::GLEvalCoord2fv: + return "glEvalCoord2fv"; + case EntryPoint::GLEvalMesh1: + return "glEvalMesh1"; + case EntryPoint::GLEvalMesh2: + return "glEvalMesh2"; + case EntryPoint::GLEvalPoint1: + return "glEvalPoint1"; + case EntryPoint::GLEvalPoint2: + return "glEvalPoint2"; + case EntryPoint::GLFeedbackBuffer: + return "glFeedbackBuffer"; + case EntryPoint::GLFenceSync: + return "glFenceSync"; + case EntryPoint::GLFinish: + return "glFinish"; + case EntryPoint::GLFinishFenceNV: + return "glFinishFenceNV"; + case EntryPoint::GLFlush: + return "glFlush"; + case EntryPoint::GLFlushMappedBufferRange: + return "glFlushMappedBufferRange"; + case EntryPoint::GLFlushMappedBufferRangeEXT: + return "glFlushMappedBufferRangeEXT"; + case EntryPoint::GLFlushMappedNamedBufferRange: + return "glFlushMappedNamedBufferRange"; + case EntryPoint::GLFogCoordPointer: + return "glFogCoordPointer"; + case EntryPoint::GLFogCoordd: + return "glFogCoordd"; + case EntryPoint::GLFogCoorddv: + return "glFogCoorddv"; + case EntryPoint::GLFogCoordf: + return "glFogCoordf"; + case EntryPoint::GLFogCoordfv: + return "glFogCoordfv"; + case EntryPoint::GLFogf: + return "glFogf"; + case EntryPoint::GLFogfv: + return "glFogfv"; + case EntryPoint::GLFogi: + return "glFogi"; + case EntryPoint::GLFogiv: + return "glFogiv"; + case EntryPoint::GLFogx: + return "glFogx"; + case EntryPoint::GLFogxv: + return "glFogxv"; + case EntryPoint::GLFramebufferFetchBarrierEXT: + return "glFramebufferFetchBarrierEXT"; + case EntryPoint::GLFramebufferMemorylessPixelLocalStorageANGLE: + return "glFramebufferMemorylessPixelLocalStorageANGLE"; + case EntryPoint::GLFramebufferParameteri: + return "glFramebufferParameteri"; + case EntryPoint::GLFramebufferParameteriMESA: + return "glFramebufferParameteriMESA"; + case EntryPoint::GLFramebufferRenderbuffer: + return "glFramebufferRenderbuffer"; + case EntryPoint::GLFramebufferRenderbufferOES: + return "glFramebufferRenderbufferOES"; + case EntryPoint::GLFramebufferTexture: + return "glFramebufferTexture"; + case EntryPoint::GLFramebufferTexture1D: + return "glFramebufferTexture1D"; + case EntryPoint::GLFramebufferTexture2D: + return "glFramebufferTexture2D"; + case EntryPoint::GLFramebufferTexture2DMultisampleEXT: + return "glFramebufferTexture2DMultisampleEXT"; + case EntryPoint::GLFramebufferTexture2DOES: + return "glFramebufferTexture2DOES"; + case EntryPoint::GLFramebufferTexture3D: + return "glFramebufferTexture3D"; + case EntryPoint::GLFramebufferTexture3DOES: + return "glFramebufferTexture3DOES"; + case EntryPoint::GLFramebufferTextureEXT: + return "glFramebufferTextureEXT"; + case EntryPoint::GLFramebufferTextureLayer: + return "glFramebufferTextureLayer"; + case EntryPoint::GLFramebufferTextureMultiviewOVR: + return "glFramebufferTextureMultiviewOVR"; + case EntryPoint::GLFramebufferTextureOES: + return "glFramebufferTextureOES"; + case EntryPoint::GLFramebufferTexturePixelLocalStorageANGLE: + return "glFramebufferTexturePixelLocalStorageANGLE"; + case EntryPoint::GLFrontFace: + return "glFrontFace"; + case EntryPoint::GLFrustum: + return "glFrustum"; + case EntryPoint::GLFrustumf: + return "glFrustumf"; + case EntryPoint::GLFrustumx: + return "glFrustumx"; + case EntryPoint::GLGenBuffers: + return "glGenBuffers"; + case EntryPoint::GLGenFencesNV: + return "glGenFencesNV"; + case EntryPoint::GLGenFramebuffers: + return "glGenFramebuffers"; + case EntryPoint::GLGenFramebuffersOES: + return "glGenFramebuffersOES"; + case EntryPoint::GLGenLists: + return "glGenLists"; + case EntryPoint::GLGenPerfMonitorsAMD: + return "glGenPerfMonitorsAMD"; + case EntryPoint::GLGenProgramPipelines: + return "glGenProgramPipelines"; + case EntryPoint::GLGenProgramPipelinesEXT: + return "glGenProgramPipelinesEXT"; + case EntryPoint::GLGenQueries: + return "glGenQueries"; + case EntryPoint::GLGenQueriesEXT: + return "glGenQueriesEXT"; + case EntryPoint::GLGenRenderbuffers: + return "glGenRenderbuffers"; + case EntryPoint::GLGenRenderbuffersOES: + return "glGenRenderbuffersOES"; + case EntryPoint::GLGenSamplers: + return "glGenSamplers"; + case EntryPoint::GLGenSemaphoresEXT: + return "glGenSemaphoresEXT"; + case EntryPoint::GLGenTextures: + return "glGenTextures"; + case EntryPoint::GLGenTransformFeedbacks: + return "glGenTransformFeedbacks"; + case EntryPoint::GLGenVertexArrays: + return "glGenVertexArrays"; + case EntryPoint::GLGenVertexArraysOES: + return "glGenVertexArraysOES"; + case EntryPoint::GLGenerateMipmap: + return "glGenerateMipmap"; + case EntryPoint::GLGenerateMipmapOES: + return "glGenerateMipmapOES"; + case EntryPoint::GLGenerateTextureMipmap: + return "glGenerateTextureMipmap"; + case EntryPoint::GLGetActiveAtomicCounterBufferiv: + return "glGetActiveAtomicCounterBufferiv"; + case EntryPoint::GLGetActiveAttrib: + return "glGetActiveAttrib"; + case EntryPoint::GLGetActiveSubroutineName: + return "glGetActiveSubroutineName"; + case EntryPoint::GLGetActiveSubroutineUniformName: + return "glGetActiveSubroutineUniformName"; + case EntryPoint::GLGetActiveSubroutineUniformiv: + return "glGetActiveSubroutineUniformiv"; + case EntryPoint::GLGetActiveUniform: + return "glGetActiveUniform"; + case EntryPoint::GLGetActiveUniformBlockName: + return "glGetActiveUniformBlockName"; + case EntryPoint::GLGetActiveUniformBlockiv: + return "glGetActiveUniformBlockiv"; + case EntryPoint::GLGetActiveUniformBlockivRobustANGLE: + return "glGetActiveUniformBlockivRobustANGLE"; + case EntryPoint::GLGetActiveUniformName: + return "glGetActiveUniformName"; + case EntryPoint::GLGetActiveUniformsiv: + return "glGetActiveUniformsiv"; + case EntryPoint::GLGetAttachedShaders: + return "glGetAttachedShaders"; + case EntryPoint::GLGetAttribLocation: + return "glGetAttribLocation"; + case EntryPoint::GLGetBooleani_v: + return "glGetBooleani_v"; + case EntryPoint::GLGetBooleani_vRobustANGLE: + return "glGetBooleani_vRobustANGLE"; + case EntryPoint::GLGetBooleanv: + return "glGetBooleanv"; + case EntryPoint::GLGetBooleanvRobustANGLE: + return "glGetBooleanvRobustANGLE"; + case EntryPoint::GLGetBufferParameteri64v: + return "glGetBufferParameteri64v"; + case EntryPoint::GLGetBufferParameteri64vRobustANGLE: + return "glGetBufferParameteri64vRobustANGLE"; + case EntryPoint::GLGetBufferParameteriv: + return "glGetBufferParameteriv"; + case EntryPoint::GLGetBufferParameterivRobustANGLE: + return "glGetBufferParameterivRobustANGLE"; + case EntryPoint::GLGetBufferPointerv: + return "glGetBufferPointerv"; + case EntryPoint::GLGetBufferPointervOES: + return "glGetBufferPointervOES"; + case EntryPoint::GLGetBufferPointervRobustANGLE: + return "glGetBufferPointervRobustANGLE"; + case EntryPoint::GLGetBufferSubData: + return "glGetBufferSubData"; + case EntryPoint::GLGetClipPlane: + return "glGetClipPlane"; + case EntryPoint::GLGetClipPlanef: + return "glGetClipPlanef"; + case EntryPoint::GLGetClipPlanex: + return "glGetClipPlanex"; + case EntryPoint::GLGetCompressedTexImage: + return "glGetCompressedTexImage"; + case EntryPoint::GLGetCompressedTexImageANGLE: + return "glGetCompressedTexImageANGLE"; + case EntryPoint::GLGetCompressedTextureImage: + return "glGetCompressedTextureImage"; + case EntryPoint::GLGetCompressedTextureSubImage: + return "glGetCompressedTextureSubImage"; + case EntryPoint::GLGetDebugMessageLog: + return "glGetDebugMessageLog"; + case EntryPoint::GLGetDebugMessageLogKHR: + return "glGetDebugMessageLogKHR"; + case EntryPoint::GLGetDoublei_v: + return "glGetDoublei_v"; + case EntryPoint::GLGetDoublev: + return "glGetDoublev"; + case EntryPoint::GLGetError: + return "glGetError"; + case EntryPoint::GLGetFenceivNV: + return "glGetFenceivNV"; + case EntryPoint::GLGetFixedv: + return "glGetFixedv"; + case EntryPoint::GLGetFloati_v: + return "glGetFloati_v"; + case EntryPoint::GLGetFloatv: + return "glGetFloatv"; + case EntryPoint::GLGetFloatvRobustANGLE: + return "glGetFloatvRobustANGLE"; + case EntryPoint::GLGetFragDataIndex: + return "glGetFragDataIndex"; + case EntryPoint::GLGetFragDataIndexEXT: + return "glGetFragDataIndexEXT"; + case EntryPoint::GLGetFragDataLocation: + return "glGetFragDataLocation"; + case EntryPoint::GLGetFramebufferAttachmentParameteriv: + return "glGetFramebufferAttachmentParameteriv"; + case EntryPoint::GLGetFramebufferAttachmentParameterivOES: + return "glGetFramebufferAttachmentParameterivOES"; + case EntryPoint::GLGetFramebufferAttachmentParameterivRobustANGLE: + return "glGetFramebufferAttachmentParameterivRobustANGLE"; + case EntryPoint::GLGetFramebufferParameteriv: + return "glGetFramebufferParameteriv"; + case EntryPoint::GLGetFramebufferParameterivMESA: + return "glGetFramebufferParameterivMESA"; + case EntryPoint::GLGetFramebufferParameterivRobustANGLE: + return "glGetFramebufferParameterivRobustANGLE"; + case EntryPoint::GLGetGraphicsResetStatus: + return "glGetGraphicsResetStatus"; + case EntryPoint::GLGetGraphicsResetStatusEXT: + return "glGetGraphicsResetStatusEXT"; + case EntryPoint::GLGetInteger64i_v: + return "glGetInteger64i_v"; + case EntryPoint::GLGetInteger64i_vRobustANGLE: + return "glGetInteger64i_vRobustANGLE"; + case EntryPoint::GLGetInteger64v: + return "glGetInteger64v"; + case EntryPoint::GLGetInteger64vEXT: + return "glGetInteger64vEXT"; + case EntryPoint::GLGetInteger64vRobustANGLE: + return "glGetInteger64vRobustANGLE"; + case EntryPoint::GLGetIntegeri_v: + return "glGetIntegeri_v"; + case EntryPoint::GLGetIntegeri_vRobustANGLE: + return "glGetIntegeri_vRobustANGLE"; + case EntryPoint::GLGetIntegerv: + return "glGetIntegerv"; + case EntryPoint::GLGetIntegervRobustANGLE: + return "glGetIntegervRobustANGLE"; + case EntryPoint::GLGetInternalformati64v: + return "glGetInternalformati64v"; + case EntryPoint::GLGetInternalformativ: + return "glGetInternalformativ"; + case EntryPoint::GLGetInternalformativRobustANGLE: + return "glGetInternalformativRobustANGLE"; + case EntryPoint::GLGetLightfv: + return "glGetLightfv"; + case EntryPoint::GLGetLightiv: + return "glGetLightiv"; + case EntryPoint::GLGetLightxv: + return "glGetLightxv"; + case EntryPoint::GLGetMapdv: + return "glGetMapdv"; + case EntryPoint::GLGetMapfv: + return "glGetMapfv"; + case EntryPoint::GLGetMapiv: + return "glGetMapiv"; + case EntryPoint::GLGetMaterialfv: + return "glGetMaterialfv"; + case EntryPoint::GLGetMaterialiv: + return "glGetMaterialiv"; + case EntryPoint::GLGetMaterialxv: + return "glGetMaterialxv"; + case EntryPoint::GLGetMemoryObjectParameterivEXT: + return "glGetMemoryObjectParameterivEXT"; + case EntryPoint::GLGetMultisamplefv: + return "glGetMultisamplefv"; + case EntryPoint::GLGetMultisamplefvANGLE: + return "glGetMultisamplefvANGLE"; + case EntryPoint::GLGetMultisamplefvRobustANGLE: + return "glGetMultisamplefvRobustANGLE"; + case EntryPoint::GLGetNamedBufferParameteri64v: + return "glGetNamedBufferParameteri64v"; + case EntryPoint::GLGetNamedBufferParameteriv: + return "glGetNamedBufferParameteriv"; + case EntryPoint::GLGetNamedBufferPointerv: + return "glGetNamedBufferPointerv"; + case EntryPoint::GLGetNamedBufferSubData: + return "glGetNamedBufferSubData"; + case EntryPoint::GLGetNamedFramebufferAttachmentParameteriv: + return "glGetNamedFramebufferAttachmentParameteriv"; + case EntryPoint::GLGetNamedFramebufferParameteriv: + return "glGetNamedFramebufferParameteriv"; + case EntryPoint::GLGetNamedRenderbufferParameteriv: + return "glGetNamedRenderbufferParameteriv"; + case EntryPoint::GLGetObjectLabel: + return "glGetObjectLabel"; + case EntryPoint::GLGetObjectLabelEXT: + return "glGetObjectLabelEXT"; + case EntryPoint::GLGetObjectLabelKHR: + return "glGetObjectLabelKHR"; + case EntryPoint::GLGetObjectPtrLabel: + return "glGetObjectPtrLabel"; + case EntryPoint::GLGetObjectPtrLabelKHR: + return "glGetObjectPtrLabelKHR"; + case EntryPoint::GLGetPerfMonitorCounterDataAMD: + return "glGetPerfMonitorCounterDataAMD"; + case EntryPoint::GLGetPerfMonitorCounterInfoAMD: + return "glGetPerfMonitorCounterInfoAMD"; + case EntryPoint::GLGetPerfMonitorCounterStringAMD: + return "glGetPerfMonitorCounterStringAMD"; + case EntryPoint::GLGetPerfMonitorCountersAMD: + return "glGetPerfMonitorCountersAMD"; + case EntryPoint::GLGetPerfMonitorGroupStringAMD: + return "glGetPerfMonitorGroupStringAMD"; + case EntryPoint::GLGetPerfMonitorGroupsAMD: + return "glGetPerfMonitorGroupsAMD"; + case EntryPoint::GLGetPixelMapfv: + return "glGetPixelMapfv"; + case EntryPoint::GLGetPixelMapuiv: + return "glGetPixelMapuiv"; + case EntryPoint::GLGetPixelMapusv: + return "glGetPixelMapusv"; + case EntryPoint::GLGetPointerv: + return "glGetPointerv"; + case EntryPoint::GLGetPointervKHR: + return "glGetPointervKHR"; + case EntryPoint::GLGetPointervRobustANGLERobustANGLE: + return "glGetPointervRobustANGLERobustANGLE"; + case EntryPoint::GLGetPolygonStipple: + return "glGetPolygonStipple"; + case EntryPoint::GLGetProgramBinary: + return "glGetProgramBinary"; + case EntryPoint::GLGetProgramBinaryOES: + return "glGetProgramBinaryOES"; + case EntryPoint::GLGetProgramInfoLog: + return "glGetProgramInfoLog"; + case EntryPoint::GLGetProgramInterfaceiv: + return "glGetProgramInterfaceiv"; + case EntryPoint::GLGetProgramInterfaceivRobustANGLE: + return "glGetProgramInterfaceivRobustANGLE"; + case EntryPoint::GLGetProgramPipelineInfoLog: + return "glGetProgramPipelineInfoLog"; + case EntryPoint::GLGetProgramPipelineInfoLogEXT: + return "glGetProgramPipelineInfoLogEXT"; + case EntryPoint::GLGetProgramPipelineiv: + return "glGetProgramPipelineiv"; + case EntryPoint::GLGetProgramPipelineivEXT: + return "glGetProgramPipelineivEXT"; + case EntryPoint::GLGetProgramResourceIndex: + return "glGetProgramResourceIndex"; + case EntryPoint::GLGetProgramResourceLocation: + return "glGetProgramResourceLocation"; + case EntryPoint::GLGetProgramResourceLocationIndex: + return "glGetProgramResourceLocationIndex"; + case EntryPoint::GLGetProgramResourceLocationIndexEXT: + return "glGetProgramResourceLocationIndexEXT"; + case EntryPoint::GLGetProgramResourceName: + return "glGetProgramResourceName"; + case EntryPoint::GLGetProgramResourceiv: + return "glGetProgramResourceiv"; + case EntryPoint::GLGetProgramStageiv: + return "glGetProgramStageiv"; + case EntryPoint::GLGetProgramiv: + return "glGetProgramiv"; + case EntryPoint::GLGetProgramivRobustANGLE: + return "glGetProgramivRobustANGLE"; + case EntryPoint::GLGetQueryBufferObjecti64v: + return "glGetQueryBufferObjecti64v"; + case EntryPoint::GLGetQueryBufferObjectiv: + return "glGetQueryBufferObjectiv"; + case EntryPoint::GLGetQueryBufferObjectui64v: + return "glGetQueryBufferObjectui64v"; + case EntryPoint::GLGetQueryBufferObjectuiv: + return "glGetQueryBufferObjectuiv"; + case EntryPoint::GLGetQueryIndexediv: + return "glGetQueryIndexediv"; + case EntryPoint::GLGetQueryObjecti64v: + return "glGetQueryObjecti64v"; + case EntryPoint::GLGetQueryObjecti64vEXT: + return "glGetQueryObjecti64vEXT"; + case EntryPoint::GLGetQueryObjecti64vRobustANGLE: + return "glGetQueryObjecti64vRobustANGLE"; + case EntryPoint::GLGetQueryObjectiv: + return "glGetQueryObjectiv"; + case EntryPoint::GLGetQueryObjectivEXT: + return "glGetQueryObjectivEXT"; + case EntryPoint::GLGetQueryObjectivRobustANGLE: + return "glGetQueryObjectivRobustANGLE"; + case EntryPoint::GLGetQueryObjectui64v: + return "glGetQueryObjectui64v"; + case EntryPoint::GLGetQueryObjectui64vEXT: + return "glGetQueryObjectui64vEXT"; + case EntryPoint::GLGetQueryObjectui64vRobustANGLE: + return "glGetQueryObjectui64vRobustANGLE"; + case EntryPoint::GLGetQueryObjectuiv: + return "glGetQueryObjectuiv"; + case EntryPoint::GLGetQueryObjectuivEXT: + return "glGetQueryObjectuivEXT"; + case EntryPoint::GLGetQueryObjectuivRobustANGLE: + return "glGetQueryObjectuivRobustANGLE"; + case EntryPoint::GLGetQueryiv: + return "glGetQueryiv"; + case EntryPoint::GLGetQueryivEXT: + return "glGetQueryivEXT"; + case EntryPoint::GLGetQueryivRobustANGLE: + return "glGetQueryivRobustANGLE"; + case EntryPoint::GLGetRenderbufferImageANGLE: + return "glGetRenderbufferImageANGLE"; + case EntryPoint::GLGetRenderbufferParameteriv: + return "glGetRenderbufferParameteriv"; + case EntryPoint::GLGetRenderbufferParameterivOES: + return "glGetRenderbufferParameterivOES"; + case EntryPoint::GLGetRenderbufferParameterivRobustANGLE: + return "glGetRenderbufferParameterivRobustANGLE"; + case EntryPoint::GLGetSamplerParameterIiv: + return "glGetSamplerParameterIiv"; + case EntryPoint::GLGetSamplerParameterIivEXT: + return "glGetSamplerParameterIivEXT"; + case EntryPoint::GLGetSamplerParameterIivOES: + return "glGetSamplerParameterIivOES"; + case EntryPoint::GLGetSamplerParameterIivRobustANGLE: + return "glGetSamplerParameterIivRobustANGLE"; + case EntryPoint::GLGetSamplerParameterIuiv: + return "glGetSamplerParameterIuiv"; + case EntryPoint::GLGetSamplerParameterIuivEXT: + return "glGetSamplerParameterIuivEXT"; + case EntryPoint::GLGetSamplerParameterIuivOES: + return "glGetSamplerParameterIuivOES"; + case EntryPoint::GLGetSamplerParameterIuivRobustANGLE: + return "glGetSamplerParameterIuivRobustANGLE"; + case EntryPoint::GLGetSamplerParameterfv: + return "glGetSamplerParameterfv"; + case EntryPoint::GLGetSamplerParameterfvRobustANGLE: + return "glGetSamplerParameterfvRobustANGLE"; + case EntryPoint::GLGetSamplerParameteriv: + return "glGetSamplerParameteriv"; + case EntryPoint::GLGetSamplerParameterivRobustANGLE: + return "glGetSamplerParameterivRobustANGLE"; + case EntryPoint::GLGetSemaphoreParameterui64vEXT: + return "glGetSemaphoreParameterui64vEXT"; + case EntryPoint::GLGetShaderInfoLog: + return "glGetShaderInfoLog"; + case EntryPoint::GLGetShaderPrecisionFormat: + return "glGetShaderPrecisionFormat"; + case EntryPoint::GLGetShaderSource: + return "glGetShaderSource"; + case EntryPoint::GLGetShaderiv: + return "glGetShaderiv"; + case EntryPoint::GLGetShaderivRobustANGLE: + return "glGetShaderivRobustANGLE"; + case EntryPoint::GLGetString: + return "glGetString"; + case EntryPoint::GLGetStringi: + return "glGetStringi"; + case EntryPoint::GLGetSubroutineIndex: + return "glGetSubroutineIndex"; + case EntryPoint::GLGetSubroutineUniformLocation: + return "glGetSubroutineUniformLocation"; + case EntryPoint::GLGetSynciv: + return "glGetSynciv"; + case EntryPoint::GLGetTexEnvfv: + return "glGetTexEnvfv"; + case EntryPoint::GLGetTexEnviv: + return "glGetTexEnviv"; + case EntryPoint::GLGetTexEnvxv: + return "glGetTexEnvxv"; + case EntryPoint::GLGetTexGendv: + return "glGetTexGendv"; + case EntryPoint::GLGetTexGenfv: + return "glGetTexGenfv"; + case EntryPoint::GLGetTexGenfvOES: + return "glGetTexGenfvOES"; + case EntryPoint::GLGetTexGeniv: + return "glGetTexGeniv"; + case EntryPoint::GLGetTexGenivOES: + return "glGetTexGenivOES"; + case EntryPoint::GLGetTexGenxvOES: + return "glGetTexGenxvOES"; + case EntryPoint::GLGetTexImage: + return "glGetTexImage"; + case EntryPoint::GLGetTexImageANGLE: + return "glGetTexImageANGLE"; + case EntryPoint::GLGetTexLevelParameterfv: + return "glGetTexLevelParameterfv"; + case EntryPoint::GLGetTexLevelParameterfvANGLE: + return "glGetTexLevelParameterfvANGLE"; + case EntryPoint::GLGetTexLevelParameterfvRobustANGLE: + return "glGetTexLevelParameterfvRobustANGLE"; + case EntryPoint::GLGetTexLevelParameteriv: + return "glGetTexLevelParameteriv"; + case EntryPoint::GLGetTexLevelParameterivANGLE: + return "glGetTexLevelParameterivANGLE"; + case EntryPoint::GLGetTexLevelParameterivRobustANGLE: + return "glGetTexLevelParameterivRobustANGLE"; + case EntryPoint::GLGetTexParameterIiv: + return "glGetTexParameterIiv"; + case EntryPoint::GLGetTexParameterIivEXT: + return "glGetTexParameterIivEXT"; + case EntryPoint::GLGetTexParameterIivOES: + return "glGetTexParameterIivOES"; + case EntryPoint::GLGetTexParameterIivRobustANGLE: + return "glGetTexParameterIivRobustANGLE"; + case EntryPoint::GLGetTexParameterIuiv: + return "glGetTexParameterIuiv"; + case EntryPoint::GLGetTexParameterIuivEXT: + return "glGetTexParameterIuivEXT"; + case EntryPoint::GLGetTexParameterIuivOES: + return "glGetTexParameterIuivOES"; + case EntryPoint::GLGetTexParameterIuivRobustANGLE: + return "glGetTexParameterIuivRobustANGLE"; + case EntryPoint::GLGetTexParameterfv: + return "glGetTexParameterfv"; + case EntryPoint::GLGetTexParameterfvRobustANGLE: + return "glGetTexParameterfvRobustANGLE"; + case EntryPoint::GLGetTexParameteriv: + return "glGetTexParameteriv"; + case EntryPoint::GLGetTexParameterivRobustANGLE: + return "glGetTexParameterivRobustANGLE"; + case EntryPoint::GLGetTexParameterxv: + return "glGetTexParameterxv"; + case EntryPoint::GLGetTextureImage: + return "glGetTextureImage"; + case EntryPoint::GLGetTextureLevelParameterfv: + return "glGetTextureLevelParameterfv"; + case EntryPoint::GLGetTextureLevelParameteriv: + return "glGetTextureLevelParameteriv"; + case EntryPoint::GLGetTextureParameterIiv: + return "glGetTextureParameterIiv"; + case EntryPoint::GLGetTextureParameterIuiv: + return "glGetTextureParameterIuiv"; + case EntryPoint::GLGetTextureParameterfv: + return "glGetTextureParameterfv"; + case EntryPoint::GLGetTextureParameteriv: + return "glGetTextureParameteriv"; + case EntryPoint::GLGetTextureSubImage: + return "glGetTextureSubImage"; + case EntryPoint::GLGetTransformFeedbackVarying: + return "glGetTransformFeedbackVarying"; + case EntryPoint::GLGetTransformFeedbacki64_v: + return "glGetTransformFeedbacki64_v"; + case EntryPoint::GLGetTransformFeedbacki_v: + return "glGetTransformFeedbacki_v"; + case EntryPoint::GLGetTransformFeedbackiv: + return "glGetTransformFeedbackiv"; + case EntryPoint::GLGetTranslatedShaderSourceANGLE: + return "glGetTranslatedShaderSourceANGLE"; + case EntryPoint::GLGetUniformBlockIndex: + return "glGetUniformBlockIndex"; + case EntryPoint::GLGetUniformIndices: + return "glGetUniformIndices"; + case EntryPoint::GLGetUniformLocation: + return "glGetUniformLocation"; + case EntryPoint::GLGetUniformSubroutineuiv: + return "glGetUniformSubroutineuiv"; + case EntryPoint::GLGetUniformdv: + return "glGetUniformdv"; + case EntryPoint::GLGetUniformfv: + return "glGetUniformfv"; + case EntryPoint::GLGetUniformfvRobustANGLE: + return "glGetUniformfvRobustANGLE"; + case EntryPoint::GLGetUniformiv: + return "glGetUniformiv"; + case EntryPoint::GLGetUniformivRobustANGLE: + return "glGetUniformivRobustANGLE"; + case EntryPoint::GLGetUniformuiv: + return "glGetUniformuiv"; + case EntryPoint::GLGetUniformuivRobustANGLE: + return "glGetUniformuivRobustANGLE"; + case EntryPoint::GLGetUnsignedBytei_vEXT: + return "glGetUnsignedBytei_vEXT"; + case EntryPoint::GLGetUnsignedBytevEXT: + return "glGetUnsignedBytevEXT"; + case EntryPoint::GLGetVertexArrayIndexed64iv: + return "glGetVertexArrayIndexed64iv"; + case EntryPoint::GLGetVertexArrayIndexediv: + return "glGetVertexArrayIndexediv"; + case EntryPoint::GLGetVertexArrayiv: + return "glGetVertexArrayiv"; + case EntryPoint::GLGetVertexAttribIiv: + return "glGetVertexAttribIiv"; + case EntryPoint::GLGetVertexAttribIivRobustANGLE: + return "glGetVertexAttribIivRobustANGLE"; + case EntryPoint::GLGetVertexAttribIuiv: + return "glGetVertexAttribIuiv"; + case EntryPoint::GLGetVertexAttribIuivRobustANGLE: + return "glGetVertexAttribIuivRobustANGLE"; + case EntryPoint::GLGetVertexAttribLdv: + return "glGetVertexAttribLdv"; + case EntryPoint::GLGetVertexAttribPointerv: + return "glGetVertexAttribPointerv"; + case EntryPoint::GLGetVertexAttribPointervRobustANGLE: + return "glGetVertexAttribPointervRobustANGLE"; + case EntryPoint::GLGetVertexAttribdv: + return "glGetVertexAttribdv"; + case EntryPoint::GLGetVertexAttribfv: + return "glGetVertexAttribfv"; + case EntryPoint::GLGetVertexAttribfvRobustANGLE: + return "glGetVertexAttribfvRobustANGLE"; + case EntryPoint::GLGetVertexAttribiv: + return "glGetVertexAttribiv"; + case EntryPoint::GLGetVertexAttribivRobustANGLE: + return "glGetVertexAttribivRobustANGLE"; + case EntryPoint::GLGetnColorTable: + return "glGetnColorTable"; + case EntryPoint::GLGetnCompressedTexImage: + return "glGetnCompressedTexImage"; + case EntryPoint::GLGetnConvolutionFilter: + return "glGetnConvolutionFilter"; + case EntryPoint::GLGetnHistogram: + return "glGetnHistogram"; + case EntryPoint::GLGetnMapdv: + return "glGetnMapdv"; + case EntryPoint::GLGetnMapfv: + return "glGetnMapfv"; + case EntryPoint::GLGetnMapiv: + return "glGetnMapiv"; + case EntryPoint::GLGetnMinmax: + return "glGetnMinmax"; + case EntryPoint::GLGetnPixelMapfv: + return "glGetnPixelMapfv"; + case EntryPoint::GLGetnPixelMapuiv: + return "glGetnPixelMapuiv"; + case EntryPoint::GLGetnPixelMapusv: + return "glGetnPixelMapusv"; + case EntryPoint::GLGetnPolygonStipple: + return "glGetnPolygonStipple"; + case EntryPoint::GLGetnSeparableFilter: + return "glGetnSeparableFilter"; + case EntryPoint::GLGetnTexImage: + return "glGetnTexImage"; + case EntryPoint::GLGetnUniformdv: + return "glGetnUniformdv"; + case EntryPoint::GLGetnUniformfv: + return "glGetnUniformfv"; + case EntryPoint::GLGetnUniformfvEXT: + return "glGetnUniformfvEXT"; + case EntryPoint::GLGetnUniformfvRobustANGLE: + return "glGetnUniformfvRobustANGLE"; + case EntryPoint::GLGetnUniformiv: + return "glGetnUniformiv"; + case EntryPoint::GLGetnUniformivEXT: + return "glGetnUniformivEXT"; + case EntryPoint::GLGetnUniformivRobustANGLE: + return "glGetnUniformivRobustANGLE"; + case EntryPoint::GLGetnUniformuiv: + return "glGetnUniformuiv"; + case EntryPoint::GLGetnUniformuivRobustANGLE: + return "glGetnUniformuivRobustANGLE"; + case EntryPoint::GLHint: + return "glHint"; + case EntryPoint::GLImportMemoryFdEXT: + return "glImportMemoryFdEXT"; + case EntryPoint::GLImportMemoryZirconHandleANGLE: + return "glImportMemoryZirconHandleANGLE"; + case EntryPoint::GLImportSemaphoreFdEXT: + return "glImportSemaphoreFdEXT"; + case EntryPoint::GLImportSemaphoreZirconHandleANGLE: + return "glImportSemaphoreZirconHandleANGLE"; + case EntryPoint::GLIndexMask: + return "glIndexMask"; + case EntryPoint::GLIndexPointer: + return "glIndexPointer"; + case EntryPoint::GLIndexd: + return "glIndexd"; + case EntryPoint::GLIndexdv: + return "glIndexdv"; + case EntryPoint::GLIndexf: + return "glIndexf"; + case EntryPoint::GLIndexfv: + return "glIndexfv"; + case EntryPoint::GLIndexi: + return "glIndexi"; + case EntryPoint::GLIndexiv: + return "glIndexiv"; + case EntryPoint::GLIndexs: + return "glIndexs"; + case EntryPoint::GLIndexsv: + return "glIndexsv"; + case EntryPoint::GLIndexub: + return "glIndexub"; + case EntryPoint::GLIndexubv: + return "glIndexubv"; + case EntryPoint::GLInitNames: + return "glInitNames"; + case EntryPoint::GLInsertEventMarkerEXT: + return "glInsertEventMarkerEXT"; + case EntryPoint::GLInterleavedArrays: + return "glInterleavedArrays"; + case EntryPoint::GLInvalid: + return "glInvalid"; + case EntryPoint::GLInvalidateBufferData: + return "glInvalidateBufferData"; + case EntryPoint::GLInvalidateBufferSubData: + return "glInvalidateBufferSubData"; + case EntryPoint::GLInvalidateFramebuffer: + return "glInvalidateFramebuffer"; + case EntryPoint::GLInvalidateNamedFramebufferData: + return "glInvalidateNamedFramebufferData"; + case EntryPoint::GLInvalidateNamedFramebufferSubData: + return "glInvalidateNamedFramebufferSubData"; + case EntryPoint::GLInvalidateSubFramebuffer: + return "glInvalidateSubFramebuffer"; + case EntryPoint::GLInvalidateTexImage: + return "glInvalidateTexImage"; + case EntryPoint::GLInvalidateTexSubImage: + return "glInvalidateTexSubImage"; + case EntryPoint::GLInvalidateTextureANGLE: + return "glInvalidateTextureANGLE"; + case EntryPoint::GLIsBuffer: + return "glIsBuffer"; + case EntryPoint::GLIsEnabled: + return "glIsEnabled"; + case EntryPoint::GLIsEnabledi: + return "glIsEnabledi"; + case EntryPoint::GLIsEnablediEXT: + return "glIsEnablediEXT"; + case EntryPoint::GLIsEnablediOES: + return "glIsEnablediOES"; + case EntryPoint::GLIsFenceNV: + return "glIsFenceNV"; + case EntryPoint::GLIsFramebuffer: + return "glIsFramebuffer"; + case EntryPoint::GLIsFramebufferOES: + return "glIsFramebufferOES"; + case EntryPoint::GLIsList: + return "glIsList"; + case EntryPoint::GLIsMemoryObjectEXT: + return "glIsMemoryObjectEXT"; + case EntryPoint::GLIsProgram: + return "glIsProgram"; + case EntryPoint::GLIsProgramPipeline: + return "glIsProgramPipeline"; + case EntryPoint::GLIsProgramPipelineEXT: + return "glIsProgramPipelineEXT"; + case EntryPoint::GLIsQuery: + return "glIsQuery"; + case EntryPoint::GLIsQueryEXT: + return "glIsQueryEXT"; + case EntryPoint::GLIsRenderbuffer: + return "glIsRenderbuffer"; + case EntryPoint::GLIsRenderbufferOES: + return "glIsRenderbufferOES"; + case EntryPoint::GLIsSampler: + return "glIsSampler"; + case EntryPoint::GLIsSemaphoreEXT: + return "glIsSemaphoreEXT"; + case EntryPoint::GLIsShader: + return "glIsShader"; + case EntryPoint::GLIsSync: + return "glIsSync"; + case EntryPoint::GLIsTexture: + return "glIsTexture"; + case EntryPoint::GLIsTransformFeedback: + return "glIsTransformFeedback"; + case EntryPoint::GLIsVertexArray: + return "glIsVertexArray"; + case EntryPoint::GLIsVertexArrayOES: + return "glIsVertexArrayOES"; + case EntryPoint::GLLabelObjectEXT: + return "glLabelObjectEXT"; + case EntryPoint::GLLightModelf: + return "glLightModelf"; + case EntryPoint::GLLightModelfv: + return "glLightModelfv"; + case EntryPoint::GLLightModeli: + return "glLightModeli"; + case EntryPoint::GLLightModeliv: + return "glLightModeliv"; + case EntryPoint::GLLightModelx: + return "glLightModelx"; + case EntryPoint::GLLightModelxv: + return "glLightModelxv"; + case EntryPoint::GLLightf: + return "glLightf"; + case EntryPoint::GLLightfv: + return "glLightfv"; + case EntryPoint::GLLighti: + return "glLighti"; + case EntryPoint::GLLightiv: + return "glLightiv"; + case EntryPoint::GLLightx: + return "glLightx"; + case EntryPoint::GLLightxv: + return "glLightxv"; + case EntryPoint::GLLineStipple: + return "glLineStipple"; + case EntryPoint::GLLineWidth: + return "glLineWidth"; + case EntryPoint::GLLineWidthx: + return "glLineWidthx"; + case EntryPoint::GLLinkProgram: + return "glLinkProgram"; + case EntryPoint::GLListBase: + return "glListBase"; + case EntryPoint::GLLoadIdentity: + return "glLoadIdentity"; + case EntryPoint::GLLoadMatrixd: + return "glLoadMatrixd"; + case EntryPoint::GLLoadMatrixf: + return "glLoadMatrixf"; + case EntryPoint::GLLoadMatrixx: + return "glLoadMatrixx"; + case EntryPoint::GLLoadName: + return "glLoadName"; + case EntryPoint::GLLoadPaletteFromModelViewMatrixOES: + return "glLoadPaletteFromModelViewMatrixOES"; + case EntryPoint::GLLoadTransposeMatrixd: + return "glLoadTransposeMatrixd"; + case EntryPoint::GLLoadTransposeMatrixf: + return "glLoadTransposeMatrixf"; + case EntryPoint::GLLogicOp: + return "glLogicOp"; + case EntryPoint::GLLogicOpANGLE: + return "glLogicOpANGLE"; + case EntryPoint::GLLoseContextCHROMIUM: + return "glLoseContextCHROMIUM"; + case EntryPoint::GLMap1d: + return "glMap1d"; + case EntryPoint::GLMap1f: + return "glMap1f"; + case EntryPoint::GLMap2d: + return "glMap2d"; + case EntryPoint::GLMap2f: + return "glMap2f"; + case EntryPoint::GLMapBuffer: + return "glMapBuffer"; + case EntryPoint::GLMapBufferOES: + return "glMapBufferOES"; + case EntryPoint::GLMapBufferRange: + return "glMapBufferRange"; + case EntryPoint::GLMapBufferRangeEXT: + return "glMapBufferRangeEXT"; + case EntryPoint::GLMapGrid1d: + return "glMapGrid1d"; + case EntryPoint::GLMapGrid1f: + return "glMapGrid1f"; + case EntryPoint::GLMapGrid2d: + return "glMapGrid2d"; + case EntryPoint::GLMapGrid2f: + return "glMapGrid2f"; + case EntryPoint::GLMapNamedBuffer: + return "glMapNamedBuffer"; + case EntryPoint::GLMapNamedBufferRange: + return "glMapNamedBufferRange"; + case EntryPoint::GLMaterialf: + return "glMaterialf"; + case EntryPoint::GLMaterialfv: + return "glMaterialfv"; + case EntryPoint::GLMateriali: + return "glMateriali"; + case EntryPoint::GLMaterialiv: + return "glMaterialiv"; + case EntryPoint::GLMaterialx: + return "glMaterialx"; + case EntryPoint::GLMaterialxv: + return "glMaterialxv"; + case EntryPoint::GLMatrixIndexPointerOES: + return "glMatrixIndexPointerOES"; + case EntryPoint::GLMatrixMode: + return "glMatrixMode"; + case EntryPoint::GLMaxShaderCompilerThreadsKHR: + return "glMaxShaderCompilerThreadsKHR"; + case EntryPoint::GLMemoryBarrier: + return "glMemoryBarrier"; + case EntryPoint::GLMemoryBarrierByRegion: + return "glMemoryBarrierByRegion"; + case EntryPoint::GLMemoryObjectParameterivEXT: + return "glMemoryObjectParameterivEXT"; + case EntryPoint::GLMinSampleShading: + return "glMinSampleShading"; + case EntryPoint::GLMinSampleShadingOES: + return "glMinSampleShadingOES"; + case EntryPoint::GLMultMatrixd: + return "glMultMatrixd"; + case EntryPoint::GLMultMatrixf: + return "glMultMatrixf"; + case EntryPoint::GLMultMatrixx: + return "glMultMatrixx"; + case EntryPoint::GLMultTransposeMatrixd: + return "glMultTransposeMatrixd"; + case EntryPoint::GLMultTransposeMatrixf: + return "glMultTransposeMatrixf"; + case EntryPoint::GLMultiDrawArrays: + return "glMultiDrawArrays"; + case EntryPoint::GLMultiDrawArraysANGLE: + return "glMultiDrawArraysANGLE"; + case EntryPoint::GLMultiDrawArraysIndirect: + return "glMultiDrawArraysIndirect"; + case EntryPoint::GLMultiDrawArraysIndirectCount: + return "glMultiDrawArraysIndirectCount"; + case EntryPoint::GLMultiDrawArraysIndirectEXT: + return "glMultiDrawArraysIndirectEXT"; + case EntryPoint::GLMultiDrawArraysInstancedANGLE: + return "glMultiDrawArraysInstancedANGLE"; + case EntryPoint::GLMultiDrawArraysInstancedBaseInstanceANGLE: + return "glMultiDrawArraysInstancedBaseInstanceANGLE"; + case EntryPoint::GLMultiDrawElements: + return "glMultiDrawElements"; + case EntryPoint::GLMultiDrawElementsANGLE: + return "glMultiDrawElementsANGLE"; + case EntryPoint::GLMultiDrawElementsBaseVertex: + return "glMultiDrawElementsBaseVertex"; + case EntryPoint::GLMultiDrawElementsBaseVertexEXT: + return "glMultiDrawElementsBaseVertexEXT"; + case EntryPoint::GLMultiDrawElementsIndirect: + return "glMultiDrawElementsIndirect"; + case EntryPoint::GLMultiDrawElementsIndirectCount: + return "glMultiDrawElementsIndirectCount"; + case EntryPoint::GLMultiDrawElementsIndirectEXT: + return "glMultiDrawElementsIndirectEXT"; + case EntryPoint::GLMultiDrawElementsInstancedANGLE: + return "glMultiDrawElementsInstancedANGLE"; + case EntryPoint::GLMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE: + return "glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE"; + case EntryPoint::GLMultiTexCoord1d: + return "glMultiTexCoord1d"; + case EntryPoint::GLMultiTexCoord1dv: + return "glMultiTexCoord1dv"; + case EntryPoint::GLMultiTexCoord1f: + return "glMultiTexCoord1f"; + case EntryPoint::GLMultiTexCoord1fv: + return "glMultiTexCoord1fv"; + case EntryPoint::GLMultiTexCoord1i: + return "glMultiTexCoord1i"; + case EntryPoint::GLMultiTexCoord1iv: + return "glMultiTexCoord1iv"; + case EntryPoint::GLMultiTexCoord1s: + return "glMultiTexCoord1s"; + case EntryPoint::GLMultiTexCoord1sv: + return "glMultiTexCoord1sv"; + case EntryPoint::GLMultiTexCoord2d: + return "glMultiTexCoord2d"; + case EntryPoint::GLMultiTexCoord2dv: + return "glMultiTexCoord2dv"; + case EntryPoint::GLMultiTexCoord2f: + return "glMultiTexCoord2f"; + case EntryPoint::GLMultiTexCoord2fv: + return "glMultiTexCoord2fv"; + case EntryPoint::GLMultiTexCoord2i: + return "glMultiTexCoord2i"; + case EntryPoint::GLMultiTexCoord2iv: + return "glMultiTexCoord2iv"; + case EntryPoint::GLMultiTexCoord2s: + return "glMultiTexCoord2s"; + case EntryPoint::GLMultiTexCoord2sv: + return "glMultiTexCoord2sv"; + case EntryPoint::GLMultiTexCoord3d: + return "glMultiTexCoord3d"; + case EntryPoint::GLMultiTexCoord3dv: + return "glMultiTexCoord3dv"; + case EntryPoint::GLMultiTexCoord3f: + return "glMultiTexCoord3f"; + case EntryPoint::GLMultiTexCoord3fv: + return "glMultiTexCoord3fv"; + case EntryPoint::GLMultiTexCoord3i: + return "glMultiTexCoord3i"; + case EntryPoint::GLMultiTexCoord3iv: + return "glMultiTexCoord3iv"; + case EntryPoint::GLMultiTexCoord3s: + return "glMultiTexCoord3s"; + case EntryPoint::GLMultiTexCoord3sv: + return "glMultiTexCoord3sv"; + case EntryPoint::GLMultiTexCoord4d: + return "glMultiTexCoord4d"; + case EntryPoint::GLMultiTexCoord4dv: + return "glMultiTexCoord4dv"; + case EntryPoint::GLMultiTexCoord4f: + return "glMultiTexCoord4f"; + case EntryPoint::GLMultiTexCoord4fv: + return "glMultiTexCoord4fv"; + case EntryPoint::GLMultiTexCoord4i: + return "glMultiTexCoord4i"; + case EntryPoint::GLMultiTexCoord4iv: + return "glMultiTexCoord4iv"; + case EntryPoint::GLMultiTexCoord4s: + return "glMultiTexCoord4s"; + case EntryPoint::GLMultiTexCoord4sv: + return "glMultiTexCoord4sv"; + case EntryPoint::GLMultiTexCoord4x: + return "glMultiTexCoord4x"; + case EntryPoint::GLMultiTexCoordP1ui: + return "glMultiTexCoordP1ui"; + case EntryPoint::GLMultiTexCoordP1uiv: + return "glMultiTexCoordP1uiv"; + case EntryPoint::GLMultiTexCoordP2ui: + return "glMultiTexCoordP2ui"; + case EntryPoint::GLMultiTexCoordP2uiv: + return "glMultiTexCoordP2uiv"; + case EntryPoint::GLMultiTexCoordP3ui: + return "glMultiTexCoordP3ui"; + case EntryPoint::GLMultiTexCoordP3uiv: + return "glMultiTexCoordP3uiv"; + case EntryPoint::GLMultiTexCoordP4ui: + return "glMultiTexCoordP4ui"; + case EntryPoint::GLMultiTexCoordP4uiv: + return "glMultiTexCoordP4uiv"; + case EntryPoint::GLNamedBufferData: + return "glNamedBufferData"; + case EntryPoint::GLNamedBufferStorage: + return "glNamedBufferStorage"; + case EntryPoint::GLNamedBufferStorageExternalEXT: + return "glNamedBufferStorageExternalEXT"; + case EntryPoint::GLNamedBufferSubData: + return "glNamedBufferSubData"; + case EntryPoint::GLNamedFramebufferDrawBuffer: + return "glNamedFramebufferDrawBuffer"; + case EntryPoint::GLNamedFramebufferDrawBuffers: + return "glNamedFramebufferDrawBuffers"; + case EntryPoint::GLNamedFramebufferParameteri: + return "glNamedFramebufferParameteri"; + case EntryPoint::GLNamedFramebufferReadBuffer: + return "glNamedFramebufferReadBuffer"; + case EntryPoint::GLNamedFramebufferRenderbuffer: + return "glNamedFramebufferRenderbuffer"; + case EntryPoint::GLNamedFramebufferTexture: + return "glNamedFramebufferTexture"; + case EntryPoint::GLNamedFramebufferTextureLayer: + return "glNamedFramebufferTextureLayer"; + case EntryPoint::GLNamedRenderbufferStorage: + return "glNamedRenderbufferStorage"; + case EntryPoint::GLNamedRenderbufferStorageMultisample: + return "glNamedRenderbufferStorageMultisample"; + case EntryPoint::GLNewList: + return "glNewList"; + case EntryPoint::GLNormal3b: + return "glNormal3b"; + case EntryPoint::GLNormal3bv: + return "glNormal3bv"; + case EntryPoint::GLNormal3d: + return "glNormal3d"; + case EntryPoint::GLNormal3dv: + return "glNormal3dv"; + case EntryPoint::GLNormal3f: + return "glNormal3f"; + case EntryPoint::GLNormal3fv: + return "glNormal3fv"; + case EntryPoint::GLNormal3i: + return "glNormal3i"; + case EntryPoint::GLNormal3iv: + return "glNormal3iv"; + case EntryPoint::GLNormal3s: + return "glNormal3s"; + case EntryPoint::GLNormal3sv: + return "glNormal3sv"; + case EntryPoint::GLNormal3x: + return "glNormal3x"; + case EntryPoint::GLNormalP3ui: + return "glNormalP3ui"; + case EntryPoint::GLNormalP3uiv: + return "glNormalP3uiv"; + case EntryPoint::GLNormalPointer: + return "glNormalPointer"; + case EntryPoint::GLObjectLabel: + return "glObjectLabel"; + case EntryPoint::GLObjectLabelKHR: + return "glObjectLabelKHR"; + case EntryPoint::GLObjectPtrLabel: + return "glObjectPtrLabel"; + case EntryPoint::GLObjectPtrLabelKHR: + return "glObjectPtrLabelKHR"; + case EntryPoint::GLOrtho: + return "glOrtho"; + case EntryPoint::GLOrthof: + return "glOrthof"; + case EntryPoint::GLOrthox: + return "glOrthox"; + case EntryPoint::GLPassThrough: + return "glPassThrough"; + case EntryPoint::GLPatchParameterfv: + return "glPatchParameterfv"; + case EntryPoint::GLPatchParameteri: + return "glPatchParameteri"; + case EntryPoint::GLPatchParameteriEXT: + return "glPatchParameteriEXT"; + case EntryPoint::GLPauseTransformFeedback: + return "glPauseTransformFeedback"; + case EntryPoint::GLPixelLocalStorageBarrierANGLE: + return "glPixelLocalStorageBarrierANGLE"; + case EntryPoint::GLPixelMapfv: + return "glPixelMapfv"; + case EntryPoint::GLPixelMapuiv: + return "glPixelMapuiv"; + case EntryPoint::GLPixelMapusv: + return "glPixelMapusv"; + case EntryPoint::GLPixelStoref: + return "glPixelStoref"; + case EntryPoint::GLPixelStorei: + return "glPixelStorei"; + case EntryPoint::GLPixelTransferf: + return "glPixelTransferf"; + case EntryPoint::GLPixelTransferi: + return "glPixelTransferi"; + case EntryPoint::GLPixelZoom: + return "glPixelZoom"; + case EntryPoint::GLPointParameterf: + return "glPointParameterf"; + case EntryPoint::GLPointParameterfv: + return "glPointParameterfv"; + case EntryPoint::GLPointParameteri: + return "glPointParameteri"; + case EntryPoint::GLPointParameteriv: + return "glPointParameteriv"; + case EntryPoint::GLPointParameterx: + return "glPointParameterx"; + case EntryPoint::GLPointParameterxv: + return "glPointParameterxv"; + case EntryPoint::GLPointSize: + return "glPointSize"; + case EntryPoint::GLPointSizePointerOES: + return "glPointSizePointerOES"; + case EntryPoint::GLPointSizex: + return "glPointSizex"; + case EntryPoint::GLPolygonMode: + return "glPolygonMode"; + case EntryPoint::GLPolygonOffset: + return "glPolygonOffset"; + case EntryPoint::GLPolygonOffsetClamp: + return "glPolygonOffsetClamp"; + case EntryPoint::GLPolygonOffsetx: + return "glPolygonOffsetx"; + case EntryPoint::GLPolygonStipple: + return "glPolygonStipple"; + case EntryPoint::GLPopAttrib: + return "glPopAttrib"; + case EntryPoint::GLPopClientAttrib: + return "glPopClientAttrib"; + case EntryPoint::GLPopDebugGroup: + return "glPopDebugGroup"; + case EntryPoint::GLPopDebugGroupKHR: + return "glPopDebugGroupKHR"; + case EntryPoint::GLPopGroupMarkerEXT: + return "glPopGroupMarkerEXT"; + case EntryPoint::GLPopMatrix: + return "glPopMatrix"; + case EntryPoint::GLPopName: + return "glPopName"; + case EntryPoint::GLPrimitiveBoundingBox: + return "glPrimitiveBoundingBox"; + case EntryPoint::GLPrimitiveBoundingBoxEXT: + return "glPrimitiveBoundingBoxEXT"; + case EntryPoint::GLPrimitiveBoundingBoxOES: + return "glPrimitiveBoundingBoxOES"; + case EntryPoint::GLPrimitiveRestartIndex: + return "glPrimitiveRestartIndex"; + case EntryPoint::GLPrioritizeTextures: + return "glPrioritizeTextures"; + case EntryPoint::GLProgramBinary: + return "glProgramBinary"; + case EntryPoint::GLProgramBinaryOES: + return "glProgramBinaryOES"; + case EntryPoint::GLProgramParameteri: + return "glProgramParameteri"; + case EntryPoint::GLProgramParameteriEXT: + return "glProgramParameteriEXT"; + case EntryPoint::GLProgramUniform1d: + return "glProgramUniform1d"; + case EntryPoint::GLProgramUniform1dv: + return "glProgramUniform1dv"; + case EntryPoint::GLProgramUniform1f: + return "glProgramUniform1f"; + case EntryPoint::GLProgramUniform1fEXT: + return "glProgramUniform1fEXT"; + case EntryPoint::GLProgramUniform1fv: + return "glProgramUniform1fv"; + case EntryPoint::GLProgramUniform1fvEXT: + return "glProgramUniform1fvEXT"; + case EntryPoint::GLProgramUniform1i: + return "glProgramUniform1i"; + case EntryPoint::GLProgramUniform1iEXT: + return "glProgramUniform1iEXT"; + case EntryPoint::GLProgramUniform1iv: + return "glProgramUniform1iv"; + case EntryPoint::GLProgramUniform1ivEXT: + return "glProgramUniform1ivEXT"; + case EntryPoint::GLProgramUniform1ui: + return "glProgramUniform1ui"; + case EntryPoint::GLProgramUniform1uiEXT: + return "glProgramUniform1uiEXT"; + case EntryPoint::GLProgramUniform1uiv: + return "glProgramUniform1uiv"; + case EntryPoint::GLProgramUniform1uivEXT: + return "glProgramUniform1uivEXT"; + case EntryPoint::GLProgramUniform2d: + return "glProgramUniform2d"; + case EntryPoint::GLProgramUniform2dv: + return "glProgramUniform2dv"; + case EntryPoint::GLProgramUniform2f: + return "glProgramUniform2f"; + case EntryPoint::GLProgramUniform2fEXT: + return "glProgramUniform2fEXT"; + case EntryPoint::GLProgramUniform2fv: + return "glProgramUniform2fv"; + case EntryPoint::GLProgramUniform2fvEXT: + return "glProgramUniform2fvEXT"; + case EntryPoint::GLProgramUniform2i: + return "glProgramUniform2i"; + case EntryPoint::GLProgramUniform2iEXT: + return "glProgramUniform2iEXT"; + case EntryPoint::GLProgramUniform2iv: + return "glProgramUniform2iv"; + case EntryPoint::GLProgramUniform2ivEXT: + return "glProgramUniform2ivEXT"; + case EntryPoint::GLProgramUniform2ui: + return "glProgramUniform2ui"; + case EntryPoint::GLProgramUniform2uiEXT: + return "glProgramUniform2uiEXT"; + case EntryPoint::GLProgramUniform2uiv: + return "glProgramUniform2uiv"; + case EntryPoint::GLProgramUniform2uivEXT: + return "glProgramUniform2uivEXT"; + case EntryPoint::GLProgramUniform3d: + return "glProgramUniform3d"; + case EntryPoint::GLProgramUniform3dv: + return "glProgramUniform3dv"; + case EntryPoint::GLProgramUniform3f: + return "glProgramUniform3f"; + case EntryPoint::GLProgramUniform3fEXT: + return "glProgramUniform3fEXT"; + case EntryPoint::GLProgramUniform3fv: + return "glProgramUniform3fv"; + case EntryPoint::GLProgramUniform3fvEXT: + return "glProgramUniform3fvEXT"; + case EntryPoint::GLProgramUniform3i: + return "glProgramUniform3i"; + case EntryPoint::GLProgramUniform3iEXT: + return "glProgramUniform3iEXT"; + case EntryPoint::GLProgramUniform3iv: + return "glProgramUniform3iv"; + case EntryPoint::GLProgramUniform3ivEXT: + return "glProgramUniform3ivEXT"; + case EntryPoint::GLProgramUniform3ui: + return "glProgramUniform3ui"; + case EntryPoint::GLProgramUniform3uiEXT: + return "glProgramUniform3uiEXT"; + case EntryPoint::GLProgramUniform3uiv: + return "glProgramUniform3uiv"; + case EntryPoint::GLProgramUniform3uivEXT: + return "glProgramUniform3uivEXT"; + case EntryPoint::GLProgramUniform4d: + return "glProgramUniform4d"; + case EntryPoint::GLProgramUniform4dv: + return "glProgramUniform4dv"; + case EntryPoint::GLProgramUniform4f: + return "glProgramUniform4f"; + case EntryPoint::GLProgramUniform4fEXT: + return "glProgramUniform4fEXT"; + case EntryPoint::GLProgramUniform4fv: + return "glProgramUniform4fv"; + case EntryPoint::GLProgramUniform4fvEXT: + return "glProgramUniform4fvEXT"; + case EntryPoint::GLProgramUniform4i: + return "glProgramUniform4i"; + case EntryPoint::GLProgramUniform4iEXT: + return "glProgramUniform4iEXT"; + case EntryPoint::GLProgramUniform4iv: + return "glProgramUniform4iv"; + case EntryPoint::GLProgramUniform4ivEXT: + return "glProgramUniform4ivEXT"; + case EntryPoint::GLProgramUniform4ui: + return "glProgramUniform4ui"; + case EntryPoint::GLProgramUniform4uiEXT: + return "glProgramUniform4uiEXT"; + case EntryPoint::GLProgramUniform4uiv: + return "glProgramUniform4uiv"; + case EntryPoint::GLProgramUniform4uivEXT: + return "glProgramUniform4uivEXT"; + case EntryPoint::GLProgramUniformMatrix2dv: + return "glProgramUniformMatrix2dv"; + case EntryPoint::GLProgramUniformMatrix2fv: + return "glProgramUniformMatrix2fv"; + case EntryPoint::GLProgramUniformMatrix2fvEXT: + return "glProgramUniformMatrix2fvEXT"; + case EntryPoint::GLProgramUniformMatrix2x3dv: + return "glProgramUniformMatrix2x3dv"; + case EntryPoint::GLProgramUniformMatrix2x3fv: + return "glProgramUniformMatrix2x3fv"; + case EntryPoint::GLProgramUniformMatrix2x3fvEXT: + return "glProgramUniformMatrix2x3fvEXT"; + case EntryPoint::GLProgramUniformMatrix2x4dv: + return "glProgramUniformMatrix2x4dv"; + case EntryPoint::GLProgramUniformMatrix2x4fv: + return "glProgramUniformMatrix2x4fv"; + case EntryPoint::GLProgramUniformMatrix2x4fvEXT: + return "glProgramUniformMatrix2x4fvEXT"; + case EntryPoint::GLProgramUniformMatrix3dv: + return "glProgramUniformMatrix3dv"; + case EntryPoint::GLProgramUniformMatrix3fv: + return "glProgramUniformMatrix3fv"; + case EntryPoint::GLProgramUniformMatrix3fvEXT: + return "glProgramUniformMatrix3fvEXT"; + case EntryPoint::GLProgramUniformMatrix3x2dv: + return "glProgramUniformMatrix3x2dv"; + case EntryPoint::GLProgramUniformMatrix3x2fv: + return "glProgramUniformMatrix3x2fv"; + case EntryPoint::GLProgramUniformMatrix3x2fvEXT: + return "glProgramUniformMatrix3x2fvEXT"; + case EntryPoint::GLProgramUniformMatrix3x4dv: + return "glProgramUniformMatrix3x4dv"; + case EntryPoint::GLProgramUniformMatrix3x4fv: + return "glProgramUniformMatrix3x4fv"; + case EntryPoint::GLProgramUniformMatrix3x4fvEXT: + return "glProgramUniformMatrix3x4fvEXT"; + case EntryPoint::GLProgramUniformMatrix4dv: + return "glProgramUniformMatrix4dv"; + case EntryPoint::GLProgramUniformMatrix4fv: + return "glProgramUniformMatrix4fv"; + case EntryPoint::GLProgramUniformMatrix4fvEXT: + return "glProgramUniformMatrix4fvEXT"; + case EntryPoint::GLProgramUniformMatrix4x2dv: + return "glProgramUniformMatrix4x2dv"; + case EntryPoint::GLProgramUniformMatrix4x2fv: + return "glProgramUniformMatrix4x2fv"; + case EntryPoint::GLProgramUniformMatrix4x2fvEXT: + return "glProgramUniformMatrix4x2fvEXT"; + case EntryPoint::GLProgramUniformMatrix4x3dv: + return "glProgramUniformMatrix4x3dv"; + case EntryPoint::GLProgramUniformMatrix4x3fv: + return "glProgramUniformMatrix4x3fv"; + case EntryPoint::GLProgramUniformMatrix4x3fvEXT: + return "glProgramUniformMatrix4x3fvEXT"; + case EntryPoint::GLProvokingVertex: + return "glProvokingVertex"; + case EntryPoint::GLProvokingVertexANGLE: + return "glProvokingVertexANGLE"; + case EntryPoint::GLPushAttrib: + return "glPushAttrib"; + case EntryPoint::GLPushClientAttrib: + return "glPushClientAttrib"; + case EntryPoint::GLPushDebugGroup: + return "glPushDebugGroup"; + case EntryPoint::GLPushDebugGroupKHR: + return "glPushDebugGroupKHR"; + case EntryPoint::GLPushGroupMarkerEXT: + return "glPushGroupMarkerEXT"; + case EntryPoint::GLPushMatrix: + return "glPushMatrix"; + case EntryPoint::GLPushName: + return "glPushName"; + case EntryPoint::GLQueryCounter: + return "glQueryCounter"; + case EntryPoint::GLQueryCounterEXT: + return "glQueryCounterEXT"; + case EntryPoint::GLQueryMatrixxOES: + return "glQueryMatrixxOES"; + case EntryPoint::GLRasterPos2d: + return "glRasterPos2d"; + case EntryPoint::GLRasterPos2dv: + return "glRasterPos2dv"; + case EntryPoint::GLRasterPos2f: + return "glRasterPos2f"; + case EntryPoint::GLRasterPos2fv: + return "glRasterPos2fv"; + case EntryPoint::GLRasterPos2i: + return "glRasterPos2i"; + case EntryPoint::GLRasterPos2iv: + return "glRasterPos2iv"; + case EntryPoint::GLRasterPos2s: + return "glRasterPos2s"; + case EntryPoint::GLRasterPos2sv: + return "glRasterPos2sv"; + case EntryPoint::GLRasterPos3d: + return "glRasterPos3d"; + case EntryPoint::GLRasterPos3dv: + return "glRasterPos3dv"; + case EntryPoint::GLRasterPos3f: + return "glRasterPos3f"; + case EntryPoint::GLRasterPos3fv: + return "glRasterPos3fv"; + case EntryPoint::GLRasterPos3i: + return "glRasterPos3i"; + case EntryPoint::GLRasterPos3iv: + return "glRasterPos3iv"; + case EntryPoint::GLRasterPos3s: + return "glRasterPos3s"; + case EntryPoint::GLRasterPos3sv: + return "glRasterPos3sv"; + case EntryPoint::GLRasterPos4d: + return "glRasterPos4d"; + case EntryPoint::GLRasterPos4dv: + return "glRasterPos4dv"; + case EntryPoint::GLRasterPos4f: + return "glRasterPos4f"; + case EntryPoint::GLRasterPos4fv: + return "glRasterPos4fv"; + case EntryPoint::GLRasterPos4i: + return "glRasterPos4i"; + case EntryPoint::GLRasterPos4iv: + return "glRasterPos4iv"; + case EntryPoint::GLRasterPos4s: + return "glRasterPos4s"; + case EntryPoint::GLRasterPos4sv: + return "glRasterPos4sv"; + case EntryPoint::GLReadBuffer: + return "glReadBuffer"; + case EntryPoint::GLReadPixels: + return "glReadPixels"; + case EntryPoint::GLReadPixelsRobustANGLE: + return "glReadPixelsRobustANGLE"; + case EntryPoint::GLReadnPixels: + return "glReadnPixels"; + case EntryPoint::GLReadnPixelsEXT: + return "glReadnPixelsEXT"; + case EntryPoint::GLReadnPixelsRobustANGLE: + return "glReadnPixelsRobustANGLE"; + case EntryPoint::GLRectd: + return "glRectd"; + case EntryPoint::GLRectdv: + return "glRectdv"; + case EntryPoint::GLRectf: + return "glRectf"; + case EntryPoint::GLRectfv: + return "glRectfv"; + case EntryPoint::GLRecti: + return "glRecti"; + case EntryPoint::GLRectiv: + return "glRectiv"; + case EntryPoint::GLRects: + return "glRects"; + case EntryPoint::GLRectsv: + return "glRectsv"; + case EntryPoint::GLReleaseShaderCompiler: + return "glReleaseShaderCompiler"; + case EntryPoint::GLReleaseTexturesANGLE: + return "glReleaseTexturesANGLE"; + case EntryPoint::GLRenderMode: + return "glRenderMode"; + case EntryPoint::GLRenderbufferStorage: + return "glRenderbufferStorage"; + case EntryPoint::GLRenderbufferStorageMultisample: + return "glRenderbufferStorageMultisample"; + case EntryPoint::GLRenderbufferStorageMultisampleANGLE: + return "glRenderbufferStorageMultisampleANGLE"; + case EntryPoint::GLRenderbufferStorageMultisampleEXT: + return "glRenderbufferStorageMultisampleEXT"; + case EntryPoint::GLRenderbufferStorageOES: + return "glRenderbufferStorageOES"; + case EntryPoint::GLRequestExtensionANGLE: + return "glRequestExtensionANGLE"; + case EntryPoint::GLResumeTransformFeedback: + return "glResumeTransformFeedback"; + case EntryPoint::GLRotated: + return "glRotated"; + case EntryPoint::GLRotatef: + return "glRotatef"; + case EntryPoint::GLRotatex: + return "glRotatex"; + case EntryPoint::GLSampleCoverage: + return "glSampleCoverage"; + case EntryPoint::GLSampleCoveragex: + return "glSampleCoveragex"; + case EntryPoint::GLSampleMaski: + return "glSampleMaski"; + case EntryPoint::GLSampleMaskiANGLE: + return "glSampleMaskiANGLE"; + case EntryPoint::GLSamplerParameterIiv: + return "glSamplerParameterIiv"; + case EntryPoint::GLSamplerParameterIivEXT: + return "glSamplerParameterIivEXT"; + case EntryPoint::GLSamplerParameterIivOES: + return "glSamplerParameterIivOES"; + case EntryPoint::GLSamplerParameterIivRobustANGLE: + return "glSamplerParameterIivRobustANGLE"; + case EntryPoint::GLSamplerParameterIuiv: + return "glSamplerParameterIuiv"; + case EntryPoint::GLSamplerParameterIuivEXT: + return "glSamplerParameterIuivEXT"; + case EntryPoint::GLSamplerParameterIuivOES: + return "glSamplerParameterIuivOES"; + case EntryPoint::GLSamplerParameterIuivRobustANGLE: + return "glSamplerParameterIuivRobustANGLE"; + case EntryPoint::GLSamplerParameterf: + return "glSamplerParameterf"; + case EntryPoint::GLSamplerParameterfv: + return "glSamplerParameterfv"; + case EntryPoint::GLSamplerParameterfvRobustANGLE: + return "glSamplerParameterfvRobustANGLE"; + case EntryPoint::GLSamplerParameteri: + return "glSamplerParameteri"; + case EntryPoint::GLSamplerParameteriv: + return "glSamplerParameteriv"; + case EntryPoint::GLSamplerParameterivRobustANGLE: + return "glSamplerParameterivRobustANGLE"; + case EntryPoint::GLScaled: + return "glScaled"; + case EntryPoint::GLScalef: + return "glScalef"; + case EntryPoint::GLScalex: + return "glScalex"; + case EntryPoint::GLScissor: + return "glScissor"; + case EntryPoint::GLScissorArrayv: + return "glScissorArrayv"; + case EntryPoint::GLScissorIndexed: + return "glScissorIndexed"; + case EntryPoint::GLScissorIndexedv: + return "glScissorIndexedv"; + case EntryPoint::GLSecondaryColor3b: + return "glSecondaryColor3b"; + case EntryPoint::GLSecondaryColor3bv: + return "glSecondaryColor3bv"; + case EntryPoint::GLSecondaryColor3d: + return "glSecondaryColor3d"; + case EntryPoint::GLSecondaryColor3dv: + return "glSecondaryColor3dv"; + case EntryPoint::GLSecondaryColor3f: + return "glSecondaryColor3f"; + case EntryPoint::GLSecondaryColor3fv: + return "glSecondaryColor3fv"; + case EntryPoint::GLSecondaryColor3i: + return "glSecondaryColor3i"; + case EntryPoint::GLSecondaryColor3iv: + return "glSecondaryColor3iv"; + case EntryPoint::GLSecondaryColor3s: + return "glSecondaryColor3s"; + case EntryPoint::GLSecondaryColor3sv: + return "glSecondaryColor3sv"; + case EntryPoint::GLSecondaryColor3ub: + return "glSecondaryColor3ub"; + case EntryPoint::GLSecondaryColor3ubv: + return "glSecondaryColor3ubv"; + case EntryPoint::GLSecondaryColor3ui: + return "glSecondaryColor3ui"; + case EntryPoint::GLSecondaryColor3uiv: + return "glSecondaryColor3uiv"; + case EntryPoint::GLSecondaryColor3us: + return "glSecondaryColor3us"; + case EntryPoint::GLSecondaryColor3usv: + return "glSecondaryColor3usv"; + case EntryPoint::GLSecondaryColorP3ui: + return "glSecondaryColorP3ui"; + case EntryPoint::GLSecondaryColorP3uiv: + return "glSecondaryColorP3uiv"; + case EntryPoint::GLSecondaryColorPointer: + return "glSecondaryColorPointer"; + case EntryPoint::GLSelectBuffer: + return "glSelectBuffer"; + case EntryPoint::GLSelectPerfMonitorCountersAMD: + return "glSelectPerfMonitorCountersAMD"; + case EntryPoint::GLSemaphoreParameterui64vEXT: + return "glSemaphoreParameterui64vEXT"; + case EntryPoint::GLSetFenceNV: + return "glSetFenceNV"; + case EntryPoint::GLShadeModel: + return "glShadeModel"; + case EntryPoint::GLShaderBinary: + return "glShaderBinary"; + case EntryPoint::GLShaderSource: + return "glShaderSource"; + case EntryPoint::GLShaderStorageBlockBinding: + return "glShaderStorageBlockBinding"; + case EntryPoint::GLShadingRateQCOM: + return "glShadingRateQCOM"; + case EntryPoint::GLSignalSemaphoreEXT: + return "glSignalSemaphoreEXT"; + case EntryPoint::GLSpecializeShader: + return "glSpecializeShader"; + case EntryPoint::GLStencilFunc: + return "glStencilFunc"; + case EntryPoint::GLStencilFuncSeparate: + return "glStencilFuncSeparate"; + case EntryPoint::GLStencilMask: + return "glStencilMask"; + case EntryPoint::GLStencilMaskSeparate: + return "glStencilMaskSeparate"; + case EntryPoint::GLStencilOp: + return "glStencilOp"; + case EntryPoint::GLStencilOpSeparate: + return "glStencilOpSeparate"; + case EntryPoint::GLTestFenceNV: + return "glTestFenceNV"; + case EntryPoint::GLTexBuffer: + return "glTexBuffer"; + case EntryPoint::GLTexBufferEXT: + return "glTexBufferEXT"; + case EntryPoint::GLTexBufferOES: + return "glTexBufferOES"; + case EntryPoint::GLTexBufferRange: + return "glTexBufferRange"; + case EntryPoint::GLTexBufferRangeEXT: + return "glTexBufferRangeEXT"; + case EntryPoint::GLTexBufferRangeOES: + return "glTexBufferRangeOES"; + case EntryPoint::GLTexCoord1d: + return "glTexCoord1d"; + case EntryPoint::GLTexCoord1dv: + return "glTexCoord1dv"; + case EntryPoint::GLTexCoord1f: + return "glTexCoord1f"; + case EntryPoint::GLTexCoord1fv: + return "glTexCoord1fv"; + case EntryPoint::GLTexCoord1i: + return "glTexCoord1i"; + case EntryPoint::GLTexCoord1iv: + return "glTexCoord1iv"; + case EntryPoint::GLTexCoord1s: + return "glTexCoord1s"; + case EntryPoint::GLTexCoord1sv: + return "glTexCoord1sv"; + case EntryPoint::GLTexCoord2d: + return "glTexCoord2d"; + case EntryPoint::GLTexCoord2dv: + return "glTexCoord2dv"; + case EntryPoint::GLTexCoord2f: + return "glTexCoord2f"; + case EntryPoint::GLTexCoord2fv: + return "glTexCoord2fv"; + case EntryPoint::GLTexCoord2i: + return "glTexCoord2i"; + case EntryPoint::GLTexCoord2iv: + return "glTexCoord2iv"; + case EntryPoint::GLTexCoord2s: + return "glTexCoord2s"; + case EntryPoint::GLTexCoord2sv: + return "glTexCoord2sv"; + case EntryPoint::GLTexCoord3d: + return "glTexCoord3d"; + case EntryPoint::GLTexCoord3dv: + return "glTexCoord3dv"; + case EntryPoint::GLTexCoord3f: + return "glTexCoord3f"; + case EntryPoint::GLTexCoord3fv: + return "glTexCoord3fv"; + case EntryPoint::GLTexCoord3i: + return "glTexCoord3i"; + case EntryPoint::GLTexCoord3iv: + return "glTexCoord3iv"; + case EntryPoint::GLTexCoord3s: + return "glTexCoord3s"; + case EntryPoint::GLTexCoord3sv: + return "glTexCoord3sv"; + case EntryPoint::GLTexCoord4d: + return "glTexCoord4d"; + case EntryPoint::GLTexCoord4dv: + return "glTexCoord4dv"; + case EntryPoint::GLTexCoord4f: + return "glTexCoord4f"; + case EntryPoint::GLTexCoord4fv: + return "glTexCoord4fv"; + case EntryPoint::GLTexCoord4i: + return "glTexCoord4i"; + case EntryPoint::GLTexCoord4iv: + return "glTexCoord4iv"; + case EntryPoint::GLTexCoord4s: + return "glTexCoord4s"; + case EntryPoint::GLTexCoord4sv: + return "glTexCoord4sv"; + case EntryPoint::GLTexCoordP1ui: + return "glTexCoordP1ui"; + case EntryPoint::GLTexCoordP1uiv: + return "glTexCoordP1uiv"; + case EntryPoint::GLTexCoordP2ui: + return "glTexCoordP2ui"; + case EntryPoint::GLTexCoordP2uiv: + return "glTexCoordP2uiv"; + case EntryPoint::GLTexCoordP3ui: + return "glTexCoordP3ui"; + case EntryPoint::GLTexCoordP3uiv: + return "glTexCoordP3uiv"; + case EntryPoint::GLTexCoordP4ui: + return "glTexCoordP4ui"; + case EntryPoint::GLTexCoordP4uiv: + return "glTexCoordP4uiv"; + case EntryPoint::GLTexCoordPointer: + return "glTexCoordPointer"; + case EntryPoint::GLTexEnvf: + return "glTexEnvf"; + case EntryPoint::GLTexEnvfv: + return "glTexEnvfv"; + case EntryPoint::GLTexEnvi: + return "glTexEnvi"; + case EntryPoint::GLTexEnviv: + return "glTexEnviv"; + case EntryPoint::GLTexEnvx: + return "glTexEnvx"; + case EntryPoint::GLTexEnvxv: + return "glTexEnvxv"; + case EntryPoint::GLTexGend: + return "glTexGend"; + case EntryPoint::GLTexGendv: + return "glTexGendv"; + case EntryPoint::GLTexGenf: + return "glTexGenf"; + case EntryPoint::GLTexGenfOES: + return "glTexGenfOES"; + case EntryPoint::GLTexGenfv: + return "glTexGenfv"; + case EntryPoint::GLTexGenfvOES: + return "glTexGenfvOES"; + case EntryPoint::GLTexGeni: + return "glTexGeni"; + case EntryPoint::GLTexGeniOES: + return "glTexGeniOES"; + case EntryPoint::GLTexGeniv: + return "glTexGeniv"; + case EntryPoint::GLTexGenivOES: + return "glTexGenivOES"; + case EntryPoint::GLTexGenxOES: + return "glTexGenxOES"; + case EntryPoint::GLTexGenxvOES: + return "glTexGenxvOES"; + case EntryPoint::GLTexImage1D: + return "glTexImage1D"; + case EntryPoint::GLTexImage2D: + return "glTexImage2D"; + case EntryPoint::GLTexImage2DExternalANGLE: + return "glTexImage2DExternalANGLE"; + case EntryPoint::GLTexImage2DMultisample: + return "glTexImage2DMultisample"; + case EntryPoint::GLTexImage2DRobustANGLE: + return "glTexImage2DRobustANGLE"; + case EntryPoint::GLTexImage3D: + return "glTexImage3D"; + case EntryPoint::GLTexImage3DMultisample: + return "glTexImage3DMultisample"; + case EntryPoint::GLTexImage3DOES: + return "glTexImage3DOES"; + case EntryPoint::GLTexImage3DRobustANGLE: + return "glTexImage3DRobustANGLE"; + case EntryPoint::GLTexParameterIiv: + return "glTexParameterIiv"; + case EntryPoint::GLTexParameterIivEXT: + return "glTexParameterIivEXT"; + case EntryPoint::GLTexParameterIivOES: + return "glTexParameterIivOES"; + case EntryPoint::GLTexParameterIivRobustANGLE: + return "glTexParameterIivRobustANGLE"; + case EntryPoint::GLTexParameterIuiv: + return "glTexParameterIuiv"; + case EntryPoint::GLTexParameterIuivEXT: + return "glTexParameterIuivEXT"; + case EntryPoint::GLTexParameterIuivOES: + return "glTexParameterIuivOES"; + case EntryPoint::GLTexParameterIuivRobustANGLE: + return "glTexParameterIuivRobustANGLE"; + case EntryPoint::GLTexParameterf: + return "glTexParameterf"; + case EntryPoint::GLTexParameterfv: + return "glTexParameterfv"; + case EntryPoint::GLTexParameterfvRobustANGLE: + return "glTexParameterfvRobustANGLE"; + case EntryPoint::GLTexParameteri: + return "glTexParameteri"; + case EntryPoint::GLTexParameteriv: + return "glTexParameteriv"; + case EntryPoint::GLTexParameterivRobustANGLE: + return "glTexParameterivRobustANGLE"; + case EntryPoint::GLTexParameterx: + return "glTexParameterx"; + case EntryPoint::GLTexParameterxv: + return "glTexParameterxv"; + case EntryPoint::GLTexStorage1D: + return "glTexStorage1D"; + case EntryPoint::GLTexStorage1DEXT: + return "glTexStorage1DEXT"; + case EntryPoint::GLTexStorage2D: + return "glTexStorage2D"; + case EntryPoint::GLTexStorage2DEXT: + return "glTexStorage2DEXT"; + case EntryPoint::GLTexStorage2DMultisample: + return "glTexStorage2DMultisample"; + case EntryPoint::GLTexStorage2DMultisampleANGLE: + return "glTexStorage2DMultisampleANGLE"; + case EntryPoint::GLTexStorage3D: + return "glTexStorage3D"; + case EntryPoint::GLTexStorage3DEXT: + return "glTexStorage3DEXT"; + case EntryPoint::GLTexStorage3DMultisample: + return "glTexStorage3DMultisample"; + case EntryPoint::GLTexStorage3DMultisampleOES: + return "glTexStorage3DMultisampleOES"; + case EntryPoint::GLTexStorageMem2DEXT: + return "glTexStorageMem2DEXT"; + case EntryPoint::GLTexStorageMem2DMultisampleEXT: + return "glTexStorageMem2DMultisampleEXT"; + case EntryPoint::GLTexStorageMem3DEXT: + return "glTexStorageMem3DEXT"; + case EntryPoint::GLTexStorageMem3DMultisampleEXT: + return "glTexStorageMem3DMultisampleEXT"; + case EntryPoint::GLTexStorageMemFlags2DANGLE: + return "glTexStorageMemFlags2DANGLE"; + case EntryPoint::GLTexStorageMemFlags2DMultisampleANGLE: + return "glTexStorageMemFlags2DMultisampleANGLE"; + case EntryPoint::GLTexStorageMemFlags3DANGLE: + return "glTexStorageMemFlags3DANGLE"; + case EntryPoint::GLTexStorageMemFlags3DMultisampleANGLE: + return "glTexStorageMemFlags3DMultisampleANGLE"; + case EntryPoint::GLTexSubImage1D: + return "glTexSubImage1D"; + case EntryPoint::GLTexSubImage2D: + return "glTexSubImage2D"; + case EntryPoint::GLTexSubImage2DRobustANGLE: + return "glTexSubImage2DRobustANGLE"; + case EntryPoint::GLTexSubImage3D: + return "glTexSubImage3D"; + case EntryPoint::GLTexSubImage3DOES: + return "glTexSubImage3DOES"; + case EntryPoint::GLTexSubImage3DRobustANGLE: + return "glTexSubImage3DRobustANGLE"; + case EntryPoint::GLTextureBarrier: + return "glTextureBarrier"; + case EntryPoint::GLTextureBuffer: + return "glTextureBuffer"; + case EntryPoint::GLTextureBufferRange: + return "glTextureBufferRange"; + case EntryPoint::GLTextureParameterIiv: + return "glTextureParameterIiv"; + case EntryPoint::GLTextureParameterIuiv: + return "glTextureParameterIuiv"; + case EntryPoint::GLTextureParameterf: + return "glTextureParameterf"; + case EntryPoint::GLTextureParameterfv: + return "glTextureParameterfv"; + case EntryPoint::GLTextureParameteri: + return "glTextureParameteri"; + case EntryPoint::GLTextureParameteriv: + return "glTextureParameteriv"; + case EntryPoint::GLTextureStorage1D: + return "glTextureStorage1D"; + case EntryPoint::GLTextureStorage2D: + return "glTextureStorage2D"; + case EntryPoint::GLTextureStorage2DMultisample: + return "glTextureStorage2DMultisample"; + case EntryPoint::GLTextureStorage3D: + return "glTextureStorage3D"; + case EntryPoint::GLTextureStorage3DMultisample: + return "glTextureStorage3DMultisample"; + case EntryPoint::GLTextureSubImage1D: + return "glTextureSubImage1D"; + case EntryPoint::GLTextureSubImage2D: + return "glTextureSubImage2D"; + case EntryPoint::GLTextureSubImage3D: + return "glTextureSubImage3D"; + case EntryPoint::GLTextureView: + return "glTextureView"; + case EntryPoint::GLTransformFeedbackBufferBase: + return "glTransformFeedbackBufferBase"; + case EntryPoint::GLTransformFeedbackBufferRange: + return "glTransformFeedbackBufferRange"; + case EntryPoint::GLTransformFeedbackVaryings: + return "glTransformFeedbackVaryings"; + case EntryPoint::GLTranslated: + return "glTranslated"; + case EntryPoint::GLTranslatef: + return "glTranslatef"; + case EntryPoint::GLTranslatex: + return "glTranslatex"; + case EntryPoint::GLUniform1d: + return "glUniform1d"; + case EntryPoint::GLUniform1dv: + return "glUniform1dv"; + case EntryPoint::GLUniform1f: + return "glUniform1f"; + case EntryPoint::GLUniform1fv: + return "glUniform1fv"; + case EntryPoint::GLUniform1i: + return "glUniform1i"; + case EntryPoint::GLUniform1iv: + return "glUniform1iv"; + case EntryPoint::GLUniform1ui: + return "glUniform1ui"; + case EntryPoint::GLUniform1uiv: + return "glUniform1uiv"; + case EntryPoint::GLUniform2d: + return "glUniform2d"; + case EntryPoint::GLUniform2dv: + return "glUniform2dv"; + case EntryPoint::GLUniform2f: + return "glUniform2f"; + case EntryPoint::GLUniform2fv: + return "glUniform2fv"; + case EntryPoint::GLUniform2i: + return "glUniform2i"; + case EntryPoint::GLUniform2iv: + return "glUniform2iv"; + case EntryPoint::GLUniform2ui: + return "glUniform2ui"; + case EntryPoint::GLUniform2uiv: + return "glUniform2uiv"; + case EntryPoint::GLUniform3d: + return "glUniform3d"; + case EntryPoint::GLUniform3dv: + return "glUniform3dv"; + case EntryPoint::GLUniform3f: + return "glUniform3f"; + case EntryPoint::GLUniform3fv: + return "glUniform3fv"; + case EntryPoint::GLUniform3i: + return "glUniform3i"; + case EntryPoint::GLUniform3iv: + return "glUniform3iv"; + case EntryPoint::GLUniform3ui: + return "glUniform3ui"; + case EntryPoint::GLUniform3uiv: + return "glUniform3uiv"; + case EntryPoint::GLUniform4d: + return "glUniform4d"; + case EntryPoint::GLUniform4dv: + return "glUniform4dv"; + case EntryPoint::GLUniform4f: + return "glUniform4f"; + case EntryPoint::GLUniform4fv: + return "glUniform4fv"; + case EntryPoint::GLUniform4i: + return "glUniform4i"; + case EntryPoint::GLUniform4iv: + return "glUniform4iv"; + case EntryPoint::GLUniform4ui: + return "glUniform4ui"; + case EntryPoint::GLUniform4uiv: + return "glUniform4uiv"; + case EntryPoint::GLUniformBlockBinding: + return "glUniformBlockBinding"; + case EntryPoint::GLUniformMatrix2dv: + return "glUniformMatrix2dv"; + case EntryPoint::GLUniformMatrix2fv: + return "glUniformMatrix2fv"; + case EntryPoint::GLUniformMatrix2x3dv: + return "glUniformMatrix2x3dv"; + case EntryPoint::GLUniformMatrix2x3fv: + return "glUniformMatrix2x3fv"; + case EntryPoint::GLUniformMatrix2x4dv: + return "glUniformMatrix2x4dv"; + case EntryPoint::GLUniformMatrix2x4fv: + return "glUniformMatrix2x4fv"; + case EntryPoint::GLUniformMatrix3dv: + return "glUniformMatrix3dv"; + case EntryPoint::GLUniformMatrix3fv: + return "glUniformMatrix3fv"; + case EntryPoint::GLUniformMatrix3x2dv: + return "glUniformMatrix3x2dv"; + case EntryPoint::GLUniformMatrix3x2fv: + return "glUniformMatrix3x2fv"; + case EntryPoint::GLUniformMatrix3x4dv: + return "glUniformMatrix3x4dv"; + case EntryPoint::GLUniformMatrix3x4fv: + return "glUniformMatrix3x4fv"; + case EntryPoint::GLUniformMatrix4dv: + return "glUniformMatrix4dv"; + case EntryPoint::GLUniformMatrix4fv: + return "glUniformMatrix4fv"; + case EntryPoint::GLUniformMatrix4x2dv: + return "glUniformMatrix4x2dv"; + case EntryPoint::GLUniformMatrix4x2fv: + return "glUniformMatrix4x2fv"; + case EntryPoint::GLUniformMatrix4x3dv: + return "glUniformMatrix4x3dv"; + case EntryPoint::GLUniformMatrix4x3fv: + return "glUniformMatrix4x3fv"; + case EntryPoint::GLUniformSubroutinesuiv: + return "glUniformSubroutinesuiv"; + case EntryPoint::GLUnmapBuffer: + return "glUnmapBuffer"; + case EntryPoint::GLUnmapBufferOES: + return "glUnmapBufferOES"; + case EntryPoint::GLUnmapNamedBuffer: + return "glUnmapNamedBuffer"; + case EntryPoint::GLUseProgram: + return "glUseProgram"; + case EntryPoint::GLUseProgramStages: + return "glUseProgramStages"; + case EntryPoint::GLUseProgramStagesEXT: + return "glUseProgramStagesEXT"; + case EntryPoint::GLValidateProgram: + return "glValidateProgram"; + case EntryPoint::GLValidateProgramPipeline: + return "glValidateProgramPipeline"; + case EntryPoint::GLValidateProgramPipelineEXT: + return "glValidateProgramPipelineEXT"; + case EntryPoint::GLVertex2d: + return "glVertex2d"; + case EntryPoint::GLVertex2dv: + return "glVertex2dv"; + case EntryPoint::GLVertex2f: + return "glVertex2f"; + case EntryPoint::GLVertex2fv: + return "glVertex2fv"; + case EntryPoint::GLVertex2i: + return "glVertex2i"; + case EntryPoint::GLVertex2iv: + return "glVertex2iv"; + case EntryPoint::GLVertex2s: + return "glVertex2s"; + case EntryPoint::GLVertex2sv: + return "glVertex2sv"; + case EntryPoint::GLVertex3d: + return "glVertex3d"; + case EntryPoint::GLVertex3dv: + return "glVertex3dv"; + case EntryPoint::GLVertex3f: + return "glVertex3f"; + case EntryPoint::GLVertex3fv: + return "glVertex3fv"; + case EntryPoint::GLVertex3i: + return "glVertex3i"; + case EntryPoint::GLVertex3iv: + return "glVertex3iv"; + case EntryPoint::GLVertex3s: + return "glVertex3s"; + case EntryPoint::GLVertex3sv: + return "glVertex3sv"; + case EntryPoint::GLVertex4d: + return "glVertex4d"; + case EntryPoint::GLVertex4dv: + return "glVertex4dv"; + case EntryPoint::GLVertex4f: + return "glVertex4f"; + case EntryPoint::GLVertex4fv: + return "glVertex4fv"; + case EntryPoint::GLVertex4i: + return "glVertex4i"; + case EntryPoint::GLVertex4iv: + return "glVertex4iv"; + case EntryPoint::GLVertex4s: + return "glVertex4s"; + case EntryPoint::GLVertex4sv: + return "glVertex4sv"; + case EntryPoint::GLVertexArrayAttribBinding: + return "glVertexArrayAttribBinding"; + case EntryPoint::GLVertexArrayAttribFormat: + return "glVertexArrayAttribFormat"; + case EntryPoint::GLVertexArrayAttribIFormat: + return "glVertexArrayAttribIFormat"; + case EntryPoint::GLVertexArrayAttribLFormat: + return "glVertexArrayAttribLFormat"; + case EntryPoint::GLVertexArrayBindingDivisor: + return "glVertexArrayBindingDivisor"; + case EntryPoint::GLVertexArrayElementBuffer: + return "glVertexArrayElementBuffer"; + case EntryPoint::GLVertexArrayVertexBuffer: + return "glVertexArrayVertexBuffer"; + case EntryPoint::GLVertexArrayVertexBuffers: + return "glVertexArrayVertexBuffers"; + case EntryPoint::GLVertexAttrib1d: + return "glVertexAttrib1d"; + case EntryPoint::GLVertexAttrib1dv: + return "glVertexAttrib1dv"; + case EntryPoint::GLVertexAttrib1f: + return "glVertexAttrib1f"; + case EntryPoint::GLVertexAttrib1fv: + return "glVertexAttrib1fv"; + case EntryPoint::GLVertexAttrib1s: + return "glVertexAttrib1s"; + case EntryPoint::GLVertexAttrib1sv: + return "glVertexAttrib1sv"; + case EntryPoint::GLVertexAttrib2d: + return "glVertexAttrib2d"; + case EntryPoint::GLVertexAttrib2dv: + return "glVertexAttrib2dv"; + case EntryPoint::GLVertexAttrib2f: + return "glVertexAttrib2f"; + case EntryPoint::GLVertexAttrib2fv: + return "glVertexAttrib2fv"; + case EntryPoint::GLVertexAttrib2s: + return "glVertexAttrib2s"; + case EntryPoint::GLVertexAttrib2sv: + return "glVertexAttrib2sv"; + case EntryPoint::GLVertexAttrib3d: + return "glVertexAttrib3d"; + case EntryPoint::GLVertexAttrib3dv: + return "glVertexAttrib3dv"; + case EntryPoint::GLVertexAttrib3f: + return "glVertexAttrib3f"; + case EntryPoint::GLVertexAttrib3fv: + return "glVertexAttrib3fv"; + case EntryPoint::GLVertexAttrib3s: + return "glVertexAttrib3s"; + case EntryPoint::GLVertexAttrib3sv: + return "glVertexAttrib3sv"; + case EntryPoint::GLVertexAttrib4Nbv: + return "glVertexAttrib4Nbv"; + case EntryPoint::GLVertexAttrib4Niv: + return "glVertexAttrib4Niv"; + case EntryPoint::GLVertexAttrib4Nsv: + return "glVertexAttrib4Nsv"; + case EntryPoint::GLVertexAttrib4Nub: + return "glVertexAttrib4Nub"; + case EntryPoint::GLVertexAttrib4Nubv: + return "glVertexAttrib4Nubv"; + case EntryPoint::GLVertexAttrib4Nuiv: + return "glVertexAttrib4Nuiv"; + case EntryPoint::GLVertexAttrib4Nusv: + return "glVertexAttrib4Nusv"; + case EntryPoint::GLVertexAttrib4bv: + return "glVertexAttrib4bv"; + case EntryPoint::GLVertexAttrib4d: + return "glVertexAttrib4d"; + case EntryPoint::GLVertexAttrib4dv: + return "glVertexAttrib4dv"; + case EntryPoint::GLVertexAttrib4f: + return "glVertexAttrib4f"; + case EntryPoint::GLVertexAttrib4fv: + return "glVertexAttrib4fv"; + case EntryPoint::GLVertexAttrib4iv: + return "glVertexAttrib4iv"; + case EntryPoint::GLVertexAttrib4s: + return "glVertexAttrib4s"; + case EntryPoint::GLVertexAttrib4sv: + return "glVertexAttrib4sv"; + case EntryPoint::GLVertexAttrib4ubv: + return "glVertexAttrib4ubv"; + case EntryPoint::GLVertexAttrib4uiv: + return "glVertexAttrib4uiv"; + case EntryPoint::GLVertexAttrib4usv: + return "glVertexAttrib4usv"; + case EntryPoint::GLVertexAttribBinding: + return "glVertexAttribBinding"; + case EntryPoint::GLVertexAttribDivisor: + return "glVertexAttribDivisor"; + case EntryPoint::GLVertexAttribDivisorANGLE: + return "glVertexAttribDivisorANGLE"; + case EntryPoint::GLVertexAttribDivisorEXT: + return "glVertexAttribDivisorEXT"; + case EntryPoint::GLVertexAttribFormat: + return "glVertexAttribFormat"; + case EntryPoint::GLVertexAttribI1i: + return "glVertexAttribI1i"; + case EntryPoint::GLVertexAttribI1iv: + return "glVertexAttribI1iv"; + case EntryPoint::GLVertexAttribI1ui: + return "glVertexAttribI1ui"; + case EntryPoint::GLVertexAttribI1uiv: + return "glVertexAttribI1uiv"; + case EntryPoint::GLVertexAttribI2i: + return "glVertexAttribI2i"; + case EntryPoint::GLVertexAttribI2iv: + return "glVertexAttribI2iv"; + case EntryPoint::GLVertexAttribI2ui: + return "glVertexAttribI2ui"; + case EntryPoint::GLVertexAttribI2uiv: + return "glVertexAttribI2uiv"; + case EntryPoint::GLVertexAttribI3i: + return "glVertexAttribI3i"; + case EntryPoint::GLVertexAttribI3iv: + return "glVertexAttribI3iv"; + case EntryPoint::GLVertexAttribI3ui: + return "glVertexAttribI3ui"; + case EntryPoint::GLVertexAttribI3uiv: + return "glVertexAttribI3uiv"; + case EntryPoint::GLVertexAttribI4bv: + return "glVertexAttribI4bv"; + case EntryPoint::GLVertexAttribI4i: + return "glVertexAttribI4i"; + case EntryPoint::GLVertexAttribI4iv: + return "glVertexAttribI4iv"; + case EntryPoint::GLVertexAttribI4sv: + return "glVertexAttribI4sv"; + case EntryPoint::GLVertexAttribI4ubv: + return "glVertexAttribI4ubv"; + case EntryPoint::GLVertexAttribI4ui: + return "glVertexAttribI4ui"; + case EntryPoint::GLVertexAttribI4uiv: + return "glVertexAttribI4uiv"; + case EntryPoint::GLVertexAttribI4usv: + return "glVertexAttribI4usv"; + case EntryPoint::GLVertexAttribIFormat: + return "glVertexAttribIFormat"; + case EntryPoint::GLVertexAttribIPointer: + return "glVertexAttribIPointer"; + case EntryPoint::GLVertexAttribL1d: + return "glVertexAttribL1d"; + case EntryPoint::GLVertexAttribL1dv: + return "glVertexAttribL1dv"; + case EntryPoint::GLVertexAttribL2d: + return "glVertexAttribL2d"; + case EntryPoint::GLVertexAttribL2dv: + return "glVertexAttribL2dv"; + case EntryPoint::GLVertexAttribL3d: + return "glVertexAttribL3d"; + case EntryPoint::GLVertexAttribL3dv: + return "glVertexAttribL3dv"; + case EntryPoint::GLVertexAttribL4d: + return "glVertexAttribL4d"; + case EntryPoint::GLVertexAttribL4dv: + return "glVertexAttribL4dv"; + case EntryPoint::GLVertexAttribLFormat: + return "glVertexAttribLFormat"; + case EntryPoint::GLVertexAttribLPointer: + return "glVertexAttribLPointer"; + case EntryPoint::GLVertexAttribP1ui: + return "glVertexAttribP1ui"; + case EntryPoint::GLVertexAttribP1uiv: + return "glVertexAttribP1uiv"; + case EntryPoint::GLVertexAttribP2ui: + return "glVertexAttribP2ui"; + case EntryPoint::GLVertexAttribP2uiv: + return "glVertexAttribP2uiv"; + case EntryPoint::GLVertexAttribP3ui: + return "glVertexAttribP3ui"; + case EntryPoint::GLVertexAttribP3uiv: + return "glVertexAttribP3uiv"; + case EntryPoint::GLVertexAttribP4ui: + return "glVertexAttribP4ui"; + case EntryPoint::GLVertexAttribP4uiv: + return "glVertexAttribP4uiv"; + case EntryPoint::GLVertexAttribPointer: + return "glVertexAttribPointer"; + case EntryPoint::GLVertexBindingDivisor: + return "glVertexBindingDivisor"; + case EntryPoint::GLVertexP2ui: + return "glVertexP2ui"; + case EntryPoint::GLVertexP2uiv: + return "glVertexP2uiv"; + case EntryPoint::GLVertexP3ui: + return "glVertexP3ui"; + case EntryPoint::GLVertexP3uiv: + return "glVertexP3uiv"; + case EntryPoint::GLVertexP4ui: + return "glVertexP4ui"; + case EntryPoint::GLVertexP4uiv: + return "glVertexP4uiv"; + case EntryPoint::GLVertexPointer: + return "glVertexPointer"; + case EntryPoint::GLViewport: + return "glViewport"; + case EntryPoint::GLViewportArrayv: + return "glViewportArrayv"; + case EntryPoint::GLViewportIndexedf: + return "glViewportIndexedf"; + case EntryPoint::GLViewportIndexedfv: + return "glViewportIndexedfv"; + case EntryPoint::GLWaitSemaphoreEXT: + return "glWaitSemaphoreEXT"; + case EntryPoint::GLWaitSync: + return "glWaitSync"; + case EntryPoint::GLWeightPointerOES: + return "glWeightPointerOES"; + case EntryPoint::GLWindowPos2d: + return "glWindowPos2d"; + case EntryPoint::GLWindowPos2dv: + return "glWindowPos2dv"; + case EntryPoint::GLWindowPos2f: + return "glWindowPos2f"; + case EntryPoint::GLWindowPos2fv: + return "glWindowPos2fv"; + case EntryPoint::GLWindowPos2i: + return "glWindowPos2i"; + case EntryPoint::GLWindowPos2iv: + return "glWindowPos2iv"; + case EntryPoint::GLWindowPos2s: + return "glWindowPos2s"; + case EntryPoint::GLWindowPos2sv: + return "glWindowPos2sv"; + case EntryPoint::GLWindowPos3d: + return "glWindowPos3d"; + case EntryPoint::GLWindowPos3dv: + return "glWindowPos3dv"; + case EntryPoint::GLWindowPos3f: + return "glWindowPos3f"; + case EntryPoint::GLWindowPos3fv: + return "glWindowPos3fv"; + case EntryPoint::GLWindowPos3i: + return "glWindowPos3i"; + case EntryPoint::GLWindowPos3iv: + return "glWindowPos3iv"; + case EntryPoint::GLWindowPos3s: + return "glWindowPos3s"; + case EntryPoint::GLWindowPos3sv: + return "glWindowPos3sv"; + case EntryPoint::WGLChoosePixelFormat: + return "wglChoosePixelFormat"; + case EntryPoint::WGLCopyContext: + return "wglCopyContext"; + case EntryPoint::WGLCreateContext: + return "wglCreateContext"; + case EntryPoint::WGLCreateLayerContext: + return "wglCreateLayerContext"; + case EntryPoint::WGLDeleteContext: + return "wglDeleteContext"; + case EntryPoint::WGLDescribeLayerPlane: + return "wglDescribeLayerPlane"; + case EntryPoint::WGLDescribePixelFormat: + return "wglDescribePixelFormat"; + case EntryPoint::WGLGetCurrentContext: + return "wglGetCurrentContext"; + case EntryPoint::WGLGetCurrentDC: + return "wglGetCurrentDC"; + case EntryPoint::WGLGetEnhMetaFilePixelFormat: + return "wglGetEnhMetaFilePixelFormat"; + case EntryPoint::WGLGetLayerPaletteEntries: + return "wglGetLayerPaletteEntries"; + case EntryPoint::WGLGetPixelFormat: + return "wglGetPixelFormat"; + case EntryPoint::WGLGetProcAddress: + return "wglGetProcAddress"; + case EntryPoint::WGLMakeCurrent: + return "wglMakeCurrent"; + case EntryPoint::WGLRealizeLayerPalette: + return "wglRealizeLayerPalette"; + case EntryPoint::WGLSetLayerPaletteEntries: + return "wglSetLayerPaletteEntries"; + case EntryPoint::WGLSetPixelFormat: + return "wglSetPixelFormat"; + case EntryPoint::WGLShareLists: + return "wglShareLists"; + case EntryPoint::WGLSwapBuffers: + return "wglSwapBuffers"; + case EntryPoint::WGLSwapLayerBuffers: + return "wglSwapLayerBuffers"; + case EntryPoint::WGLUseFontBitmaps: + return "wglUseFontBitmaps"; + case EntryPoint::WGLUseFontBitmapsA: + return "wglUseFontBitmapsA"; + case EntryPoint::WGLUseFontBitmapsW: + return "wglUseFontBitmapsW"; + case EntryPoint::WGLUseFontOutlines: + return "wglUseFontOutlines"; + case EntryPoint::WGLUseFontOutlinesA: + return "wglUseFontOutlinesA"; + case EntryPoint::WGLUseFontOutlinesW: + return "wglUseFontOutlinesW"; + default: + UNREACHABLE(); + return "error"; + } +} +} // namespace angle diff --git a/gfx/angle/checkout/src/common/entry_points_enum_autogen.h b/gfx/angle/checkout/src/common/entry_points_enum_autogen.h new file mode 100644 index 0000000000..61c5c76f58 --- /dev/null +++ b/gfx/angle/checkout/src/common/entry_points_enum_autogen.h @@ -0,0 +1,1736 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml. +// +// Copyright 2020 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. +// +// entry_points_enum_autogen.h: +// Defines the GL/GLES entry points enumeration. + +#ifndef COMMON_ENTRYPOINTSENUM_AUTOGEN_H_ +#define COMMON_ENTRYPOINTSENUM_AUTOGEN_H_ + +namespace angle +{ +enum class EntryPoint +{ + CLBuildProgram, + CLCloneKernel, + CLCompileProgram, + CLCreateBuffer, + CLCreateBufferWithProperties, + CLCreateCommandQueue, + CLCreateCommandQueueWithProperties, + CLCreateContext, + CLCreateContextFromType, + CLCreateImage, + CLCreateImage2D, + CLCreateImage3D, + CLCreateImageWithProperties, + CLCreateKernel, + CLCreateKernelsInProgram, + CLCreatePipe, + CLCreateProgramWithBinary, + CLCreateProgramWithBuiltInKernels, + CLCreateProgramWithIL, + CLCreateProgramWithSource, + CLCreateSampler, + CLCreateSamplerWithProperties, + CLCreateSubBuffer, + CLCreateSubDevices, + CLCreateUserEvent, + CLEnqueueBarrier, + CLEnqueueBarrierWithWaitList, + CLEnqueueCopyBuffer, + CLEnqueueCopyBufferRect, + CLEnqueueCopyBufferToImage, + CLEnqueueCopyImage, + CLEnqueueCopyImageToBuffer, + CLEnqueueFillBuffer, + CLEnqueueFillImage, + CLEnqueueMapBuffer, + CLEnqueueMapImage, + CLEnqueueMarker, + CLEnqueueMarkerWithWaitList, + CLEnqueueMigrateMemObjects, + CLEnqueueNDRangeKernel, + CLEnqueueNativeKernel, + CLEnqueueReadBuffer, + CLEnqueueReadBufferRect, + CLEnqueueReadImage, + CLEnqueueSVMFree, + CLEnqueueSVMMap, + CLEnqueueSVMMemFill, + CLEnqueueSVMMemcpy, + CLEnqueueSVMMigrateMem, + CLEnqueueSVMUnmap, + CLEnqueueTask, + CLEnqueueUnmapMemObject, + CLEnqueueWaitForEvents, + CLEnqueueWriteBuffer, + CLEnqueueWriteBufferRect, + CLEnqueueWriteImage, + CLFinish, + CLFlush, + CLGetCommandQueueInfo, + CLGetContextInfo, + CLGetDeviceAndHostTimer, + CLGetDeviceIDs, + CLGetDeviceInfo, + CLGetEventInfo, + CLGetEventProfilingInfo, + CLGetExtensionFunctionAddress, + CLGetExtensionFunctionAddressForPlatform, + CLGetHostTimer, + CLGetImageInfo, + CLGetKernelArgInfo, + CLGetKernelInfo, + CLGetKernelSubGroupInfo, + CLGetKernelWorkGroupInfo, + CLGetMemObjectInfo, + CLGetPipeInfo, + CLGetPlatformIDs, + CLGetPlatformInfo, + CLGetProgramBuildInfo, + CLGetProgramInfo, + CLGetSamplerInfo, + CLGetSupportedImageFormats, + CLIcdGetPlatformIDsKHR, + CLLinkProgram, + CLReleaseCommandQueue, + CLReleaseContext, + CLReleaseDevice, + CLReleaseEvent, + CLReleaseKernel, + CLReleaseMemObject, + CLReleaseProgram, + CLReleaseSampler, + CLRetainCommandQueue, + CLRetainContext, + CLRetainDevice, + CLRetainEvent, + CLRetainKernel, + CLRetainMemObject, + CLRetainProgram, + CLRetainSampler, + CLSVMAlloc, + CLSVMFree, + CLSetCommandQueueProperty, + CLSetContextDestructorCallback, + CLSetDefaultDeviceCommandQueue, + CLSetEventCallback, + CLSetKernelArg, + CLSetKernelArgSVMPointer, + CLSetKernelExecInfo, + CLSetMemObjectDestructorCallback, + CLSetProgramReleaseCallback, + CLSetProgramSpecializationConstant, + CLSetUserEventStatus, + CLUnloadCompiler, + CLUnloadPlatformCompiler, + CLWaitForEvents, + EGLBindAPI, + EGLBindTexImage, + EGLChooseConfig, + EGLClientWaitSync, + EGLClientWaitSyncKHR, + EGLCopyBuffers, + EGLCopyMetalSharedEventANGLE, + EGLCreateContext, + EGLCreateDeviceANGLE, + EGLCreateImage, + EGLCreateImageKHR, + EGLCreateNativeClientBufferANDROID, + EGLCreatePbufferFromClientBuffer, + EGLCreatePbufferSurface, + EGLCreatePixmapSurface, + EGLCreatePlatformPixmapSurface, + EGLCreatePlatformPixmapSurfaceEXT, + EGLCreatePlatformWindowSurface, + EGLCreatePlatformWindowSurfaceEXT, + EGLCreateStreamKHR, + EGLCreateStreamProducerD3DTextureANGLE, + EGLCreateSync, + EGLCreateSyncKHR, + EGLCreateWindowSurface, + EGLDebugMessageControlKHR, + EGLDestroyContext, + EGLDestroyImage, + EGLDestroyImageKHR, + EGLDestroyStreamKHR, + EGLDestroySurface, + EGLDestroySync, + EGLDestroySyncKHR, + EGLDupNativeFenceFDANDROID, + EGLExportVkImageANGLE, + EGLForceGPUSwitchANGLE, + EGLGetCompositorTimingANDROID, + EGLGetCompositorTimingSupportedANDROID, + EGLGetConfigAttrib, + EGLGetConfigs, + EGLGetCurrentContext, + EGLGetCurrentDisplay, + EGLGetCurrentSurface, + EGLGetDisplay, + EGLGetError, + EGLGetFrameTimestampSupportedANDROID, + EGLGetFrameTimestampsANDROID, + EGLGetMscRateANGLE, + EGLGetNativeClientBufferANDROID, + EGLGetNextFrameIdANDROID, + EGLGetPlatformDisplay, + EGLGetPlatformDisplayEXT, + EGLGetProcAddress, + EGLGetSyncAttrib, + EGLGetSyncAttribKHR, + EGLGetSyncValuesCHROMIUM, + EGLHandleGPUSwitchANGLE, + EGLInitialize, + EGLLabelObjectKHR, + EGLLockSurfaceKHR, + EGLMakeCurrent, + EGLPostSubBufferNV, + EGLPrepareSwapBuffersANGLE, + EGLPresentationTimeANDROID, + EGLProgramCacheGetAttribANGLE, + EGLProgramCachePopulateANGLE, + EGLProgramCacheQueryANGLE, + EGLProgramCacheResizeANGLE, + EGLQueryAPI, + EGLQueryContext, + EGLQueryDebugKHR, + EGLQueryDeviceAttribEXT, + EGLQueryDeviceStringEXT, + EGLQueryDisplayAttribANGLE, + EGLQueryDisplayAttribEXT, + EGLQueryDmaBufFormatsEXT, + EGLQueryDmaBufModifiersEXT, + EGLQueryStreamKHR, + EGLQueryStreamu64KHR, + EGLQueryString, + EGLQueryStringiANGLE, + EGLQuerySurface, + EGLQuerySurface64KHR, + EGLQuerySurfacePointerANGLE, + EGLReacquireHighPowerGPUANGLE, + EGLReleaseDeviceANGLE, + EGLReleaseHighPowerGPUANGLE, + EGLReleaseTexImage, + EGLReleaseThread, + EGLSetBlobCacheFuncsANDROID, + EGLSetDamageRegionKHR, + EGLSignalSyncKHR, + EGLStreamAttribKHR, + EGLStreamConsumerAcquireKHR, + EGLStreamConsumerGLTextureExternalAttribsNV, + EGLStreamConsumerGLTextureExternalKHR, + EGLStreamConsumerReleaseKHR, + EGLStreamPostD3DTextureANGLE, + EGLSurfaceAttrib, + EGLSwapBuffers, + EGLSwapBuffersWithDamageKHR, + EGLSwapBuffersWithFrameTokenANGLE, + EGLSwapInterval, + EGLTerminate, + EGLUnlockSurfaceKHR, + EGLWaitClient, + EGLWaitGL, + EGLWaitNative, + EGLWaitSync, + EGLWaitSyncKHR, + GLAccum, + GLAcquireTexturesANGLE, + GLActiveShaderProgram, + GLActiveShaderProgramEXT, + GLActiveTexture, + GLAlphaFunc, + GLAlphaFuncx, + GLAreTexturesResident, + GLArrayElement, + GLAttachShader, + GLBegin, + GLBeginConditionalRender, + GLBeginPerfMonitorAMD, + GLBeginPixelLocalStorageANGLE, + GLBeginQuery, + GLBeginQueryEXT, + GLBeginQueryIndexed, + GLBeginTransformFeedback, + GLBindAttribLocation, + GLBindBuffer, + GLBindBufferBase, + GLBindBufferRange, + GLBindBuffersBase, + GLBindBuffersRange, + GLBindFragDataLocation, + GLBindFragDataLocationEXT, + GLBindFragDataLocationIndexed, + GLBindFragDataLocationIndexedEXT, + GLBindFramebuffer, + GLBindFramebufferOES, + GLBindImageTexture, + GLBindImageTextures, + GLBindProgramPipeline, + GLBindProgramPipelineEXT, + GLBindRenderbuffer, + GLBindRenderbufferOES, + GLBindSampler, + GLBindSamplers, + GLBindTexture, + GLBindTextureUnit, + GLBindTextures, + GLBindTransformFeedback, + GLBindUniformLocationCHROMIUM, + GLBindVertexArray, + GLBindVertexArrayOES, + GLBindVertexBuffer, + GLBindVertexBuffers, + GLBitmap, + GLBlendBarrier, + GLBlendBarrierKHR, + GLBlendColor, + GLBlendEquation, + GLBlendEquationSeparate, + GLBlendEquationSeparatei, + GLBlendEquationSeparateiEXT, + GLBlendEquationSeparateiOES, + GLBlendEquationi, + GLBlendEquationiEXT, + GLBlendEquationiOES, + GLBlendFunc, + GLBlendFuncSeparate, + GLBlendFuncSeparatei, + GLBlendFuncSeparateiEXT, + GLBlendFuncSeparateiOES, + GLBlendFunci, + GLBlendFunciEXT, + GLBlendFunciOES, + GLBlitFramebuffer, + GLBlitFramebufferANGLE, + GLBlitFramebufferNV, + GLBlitNamedFramebuffer, + GLBufferData, + GLBufferStorage, + GLBufferStorageEXT, + GLBufferStorageExternalEXT, + GLBufferStorageMemEXT, + GLBufferSubData, + GLCallList, + GLCallLists, + GLCheckFramebufferStatus, + GLCheckFramebufferStatusOES, + GLCheckNamedFramebufferStatus, + GLClampColor, + GLClear, + GLClearAccum, + GLClearBufferData, + GLClearBufferSubData, + GLClearBufferfi, + GLClearBufferfv, + GLClearBufferiv, + GLClearBufferuiv, + GLClearColor, + GLClearColorx, + GLClearDepth, + GLClearDepthf, + GLClearDepthx, + GLClearIndex, + GLClearNamedBufferData, + GLClearNamedBufferSubData, + GLClearNamedFramebufferfi, + GLClearNamedFramebufferfv, + GLClearNamedFramebufferiv, + GLClearNamedFramebufferuiv, + GLClearStencil, + GLClearTexImage, + GLClearTexSubImage, + GLClientActiveTexture, + GLClientWaitSync, + GLClipControl, + GLClipControlEXT, + GLClipPlane, + GLClipPlanef, + GLClipPlanex, + GLColor3b, + GLColor3bv, + GLColor3d, + GLColor3dv, + GLColor3f, + GLColor3fv, + GLColor3i, + GLColor3iv, + GLColor3s, + GLColor3sv, + GLColor3ub, + GLColor3ubv, + GLColor3ui, + GLColor3uiv, + GLColor3us, + GLColor3usv, + GLColor4b, + GLColor4bv, + GLColor4d, + GLColor4dv, + GLColor4f, + GLColor4fv, + GLColor4i, + GLColor4iv, + GLColor4s, + GLColor4sv, + GLColor4ub, + GLColor4ubv, + GLColor4ui, + GLColor4uiv, + GLColor4us, + GLColor4usv, + GLColor4x, + GLColorMask, + GLColorMaski, + GLColorMaskiEXT, + GLColorMaskiOES, + GLColorMaterial, + GLColorP3ui, + GLColorP3uiv, + GLColorP4ui, + GLColorP4uiv, + GLColorPointer, + GLCompileShader, + GLCompressedCopyTextureCHROMIUM, + GLCompressedTexImage1D, + GLCompressedTexImage2D, + GLCompressedTexImage2DRobustANGLE, + GLCompressedTexImage3D, + GLCompressedTexImage3DOES, + GLCompressedTexImage3DRobustANGLE, + GLCompressedTexSubImage1D, + GLCompressedTexSubImage2D, + GLCompressedTexSubImage2DRobustANGLE, + GLCompressedTexSubImage3D, + GLCompressedTexSubImage3DOES, + GLCompressedTexSubImage3DRobustANGLE, + GLCompressedTextureSubImage1D, + GLCompressedTextureSubImage2D, + GLCompressedTextureSubImage3D, + GLCopyBufferSubData, + GLCopyImageSubData, + GLCopyImageSubDataEXT, + GLCopyImageSubDataOES, + GLCopyNamedBufferSubData, + GLCopyPixels, + GLCopySubTexture3DANGLE, + GLCopySubTextureCHROMIUM, + GLCopyTexImage1D, + GLCopyTexImage2D, + GLCopyTexSubImage1D, + GLCopyTexSubImage2D, + GLCopyTexSubImage3D, + GLCopyTexSubImage3DOES, + GLCopyTexture3DANGLE, + GLCopyTextureCHROMIUM, + GLCopyTextureSubImage1D, + GLCopyTextureSubImage2D, + GLCopyTextureSubImage3D, + GLCoverageModulationCHROMIUM, + GLCreateBuffers, + GLCreateFramebuffers, + GLCreateMemoryObjectsEXT, + GLCreateProgram, + GLCreateProgramPipelines, + GLCreateQueries, + GLCreateRenderbuffers, + GLCreateSamplers, + GLCreateShader, + GLCreateShaderProgramv, + GLCreateShaderProgramvEXT, + GLCreateTextures, + GLCreateTransformFeedbacks, + GLCreateVertexArrays, + GLCullFace, + GLCurrentPaletteMatrixOES, + GLDebugMessageCallback, + GLDebugMessageCallbackKHR, + GLDebugMessageControl, + GLDebugMessageControlKHR, + GLDebugMessageInsert, + GLDebugMessageInsertKHR, + GLDeleteBuffers, + GLDeleteFencesNV, + GLDeleteFramebuffers, + GLDeleteFramebuffersOES, + GLDeleteLists, + GLDeleteMemoryObjectsEXT, + GLDeletePerfMonitorsAMD, + GLDeleteProgram, + GLDeleteProgramPipelines, + GLDeleteProgramPipelinesEXT, + GLDeleteQueries, + GLDeleteQueriesEXT, + GLDeleteRenderbuffers, + GLDeleteRenderbuffersOES, + GLDeleteSamplers, + GLDeleteSemaphoresEXT, + GLDeleteShader, + GLDeleteSync, + GLDeleteTextures, + GLDeleteTransformFeedbacks, + GLDeleteVertexArrays, + GLDeleteVertexArraysOES, + GLDepthFunc, + GLDepthMask, + GLDepthRange, + GLDepthRangeArrayv, + GLDepthRangeIndexed, + GLDepthRangef, + GLDepthRangex, + GLDetachShader, + GLDisable, + GLDisableClientState, + GLDisableExtensionANGLE, + GLDisableVertexArrayAttrib, + GLDisableVertexAttribArray, + GLDisablei, + GLDisableiEXT, + GLDisableiOES, + GLDiscardFramebufferEXT, + GLDispatchCompute, + GLDispatchComputeIndirect, + GLDrawArrays, + GLDrawArraysIndirect, + GLDrawArraysInstanced, + GLDrawArraysInstancedANGLE, + GLDrawArraysInstancedBaseInstance, + GLDrawArraysInstancedBaseInstanceANGLE, + GLDrawArraysInstancedBaseInstanceEXT, + GLDrawArraysInstancedEXT, + GLDrawBuffer, + GLDrawBuffers, + GLDrawBuffersEXT, + GLDrawElements, + GLDrawElementsBaseVertex, + GLDrawElementsBaseVertexEXT, + GLDrawElementsBaseVertexOES, + GLDrawElementsIndirect, + GLDrawElementsInstanced, + GLDrawElementsInstancedANGLE, + GLDrawElementsInstancedBaseInstance, + GLDrawElementsInstancedBaseInstanceEXT, + GLDrawElementsInstancedBaseVertex, + GLDrawElementsInstancedBaseVertexBaseInstance, + GLDrawElementsInstancedBaseVertexBaseInstanceANGLE, + GLDrawElementsInstancedBaseVertexBaseInstanceEXT, + GLDrawElementsInstancedBaseVertexEXT, + GLDrawElementsInstancedBaseVertexOES, + GLDrawElementsInstancedEXT, + GLDrawPixels, + GLDrawRangeElements, + GLDrawRangeElementsBaseVertex, + GLDrawRangeElementsBaseVertexEXT, + GLDrawRangeElementsBaseVertexOES, + GLDrawTexfOES, + GLDrawTexfvOES, + GLDrawTexiOES, + GLDrawTexivOES, + GLDrawTexsOES, + GLDrawTexsvOES, + GLDrawTexxOES, + GLDrawTexxvOES, + GLDrawTransformFeedback, + GLDrawTransformFeedbackInstanced, + GLDrawTransformFeedbackStream, + GLDrawTransformFeedbackStreamInstanced, + GLEGLImageTargetRenderbufferStorageOES, + GLEGLImageTargetTexStorageEXT, + GLEGLImageTargetTexture2DOES, + GLEGLImageTargetTextureStorageEXT, + GLEdgeFlag, + GLEdgeFlagPointer, + GLEdgeFlagv, + GLEnable, + GLEnableClientState, + GLEnableVertexArrayAttrib, + GLEnableVertexAttribArray, + GLEnablei, + GLEnableiEXT, + GLEnableiOES, + GLEnd, + GLEndConditionalRender, + GLEndList, + GLEndPerfMonitorAMD, + GLEndPixelLocalStorageANGLE, + GLEndQuery, + GLEndQueryEXT, + GLEndQueryIndexed, + GLEndTransformFeedback, + GLEvalCoord1d, + GLEvalCoord1dv, + GLEvalCoord1f, + GLEvalCoord1fv, + GLEvalCoord2d, + GLEvalCoord2dv, + GLEvalCoord2f, + GLEvalCoord2fv, + GLEvalMesh1, + GLEvalMesh2, + GLEvalPoint1, + GLEvalPoint2, + GLFeedbackBuffer, + GLFenceSync, + GLFinish, + GLFinishFenceNV, + GLFlush, + GLFlushMappedBufferRange, + GLFlushMappedBufferRangeEXT, + GLFlushMappedNamedBufferRange, + GLFogCoordPointer, + GLFogCoordd, + GLFogCoorddv, + GLFogCoordf, + GLFogCoordfv, + GLFogf, + GLFogfv, + GLFogi, + GLFogiv, + GLFogx, + GLFogxv, + GLFramebufferFetchBarrierEXT, + GLFramebufferMemorylessPixelLocalStorageANGLE, + GLFramebufferParameteri, + GLFramebufferParameteriMESA, + GLFramebufferRenderbuffer, + GLFramebufferRenderbufferOES, + GLFramebufferTexture, + GLFramebufferTexture1D, + GLFramebufferTexture2D, + GLFramebufferTexture2DMultisampleEXT, + GLFramebufferTexture2DOES, + GLFramebufferTexture3D, + GLFramebufferTexture3DOES, + GLFramebufferTextureEXT, + GLFramebufferTextureLayer, + GLFramebufferTextureMultiviewOVR, + GLFramebufferTextureOES, + GLFramebufferTexturePixelLocalStorageANGLE, + GLFrontFace, + GLFrustum, + GLFrustumf, + GLFrustumx, + GLGenBuffers, + GLGenFencesNV, + GLGenFramebuffers, + GLGenFramebuffersOES, + GLGenLists, + GLGenPerfMonitorsAMD, + GLGenProgramPipelines, + GLGenProgramPipelinesEXT, + GLGenQueries, + GLGenQueriesEXT, + GLGenRenderbuffers, + GLGenRenderbuffersOES, + GLGenSamplers, + GLGenSemaphoresEXT, + GLGenTextures, + GLGenTransformFeedbacks, + GLGenVertexArrays, + GLGenVertexArraysOES, + GLGenerateMipmap, + GLGenerateMipmapOES, + GLGenerateTextureMipmap, + GLGetActiveAtomicCounterBufferiv, + GLGetActiveAttrib, + GLGetActiveSubroutineName, + GLGetActiveSubroutineUniformName, + GLGetActiveSubroutineUniformiv, + GLGetActiveUniform, + GLGetActiveUniformBlockName, + GLGetActiveUniformBlockiv, + GLGetActiveUniformBlockivRobustANGLE, + GLGetActiveUniformName, + GLGetActiveUniformsiv, + GLGetAttachedShaders, + GLGetAttribLocation, + GLGetBooleani_v, + GLGetBooleani_vRobustANGLE, + GLGetBooleanv, + GLGetBooleanvRobustANGLE, + GLGetBufferParameteri64v, + GLGetBufferParameteri64vRobustANGLE, + GLGetBufferParameteriv, + GLGetBufferParameterivRobustANGLE, + GLGetBufferPointerv, + GLGetBufferPointervOES, + GLGetBufferPointervRobustANGLE, + GLGetBufferSubData, + GLGetClipPlane, + GLGetClipPlanef, + GLGetClipPlanex, + GLGetCompressedTexImage, + GLGetCompressedTexImageANGLE, + GLGetCompressedTextureImage, + GLGetCompressedTextureSubImage, + GLGetDebugMessageLog, + GLGetDebugMessageLogKHR, + GLGetDoublei_v, + GLGetDoublev, + GLGetError, + GLGetFenceivNV, + GLGetFixedv, + GLGetFloati_v, + GLGetFloatv, + GLGetFloatvRobustANGLE, + GLGetFragDataIndex, + GLGetFragDataIndexEXT, + GLGetFragDataLocation, + GLGetFramebufferAttachmentParameteriv, + GLGetFramebufferAttachmentParameterivOES, + GLGetFramebufferAttachmentParameterivRobustANGLE, + GLGetFramebufferParameteriv, + GLGetFramebufferParameterivMESA, + GLGetFramebufferParameterivRobustANGLE, + GLGetGraphicsResetStatus, + GLGetGraphicsResetStatusEXT, + GLGetInteger64i_v, + GLGetInteger64i_vRobustANGLE, + GLGetInteger64v, + GLGetInteger64vEXT, + GLGetInteger64vRobustANGLE, + GLGetIntegeri_v, + GLGetIntegeri_vRobustANGLE, + GLGetIntegerv, + GLGetIntegervRobustANGLE, + GLGetInternalformati64v, + GLGetInternalformativ, + GLGetInternalformativRobustANGLE, + GLGetLightfv, + GLGetLightiv, + GLGetLightxv, + GLGetMapdv, + GLGetMapfv, + GLGetMapiv, + GLGetMaterialfv, + GLGetMaterialiv, + GLGetMaterialxv, + GLGetMemoryObjectParameterivEXT, + GLGetMultisamplefv, + GLGetMultisamplefvANGLE, + GLGetMultisamplefvRobustANGLE, + GLGetNamedBufferParameteri64v, + GLGetNamedBufferParameteriv, + GLGetNamedBufferPointerv, + GLGetNamedBufferSubData, + GLGetNamedFramebufferAttachmentParameteriv, + GLGetNamedFramebufferParameteriv, + GLGetNamedRenderbufferParameteriv, + GLGetObjectLabel, + GLGetObjectLabelEXT, + GLGetObjectLabelKHR, + GLGetObjectPtrLabel, + GLGetObjectPtrLabelKHR, + GLGetPerfMonitorCounterDataAMD, + GLGetPerfMonitorCounterInfoAMD, + GLGetPerfMonitorCounterStringAMD, + GLGetPerfMonitorCountersAMD, + GLGetPerfMonitorGroupStringAMD, + GLGetPerfMonitorGroupsAMD, + GLGetPixelMapfv, + GLGetPixelMapuiv, + GLGetPixelMapusv, + GLGetPointerv, + GLGetPointervKHR, + GLGetPointervRobustANGLERobustANGLE, + GLGetPolygonStipple, + GLGetProgramBinary, + GLGetProgramBinaryOES, + GLGetProgramInfoLog, + GLGetProgramInterfaceiv, + GLGetProgramInterfaceivRobustANGLE, + GLGetProgramPipelineInfoLog, + GLGetProgramPipelineInfoLogEXT, + GLGetProgramPipelineiv, + GLGetProgramPipelineivEXT, + GLGetProgramResourceIndex, + GLGetProgramResourceLocation, + GLGetProgramResourceLocationIndex, + GLGetProgramResourceLocationIndexEXT, + GLGetProgramResourceName, + GLGetProgramResourceiv, + GLGetProgramStageiv, + GLGetProgramiv, + GLGetProgramivRobustANGLE, + GLGetQueryBufferObjecti64v, + GLGetQueryBufferObjectiv, + GLGetQueryBufferObjectui64v, + GLGetQueryBufferObjectuiv, + GLGetQueryIndexediv, + GLGetQueryObjecti64v, + GLGetQueryObjecti64vEXT, + GLGetQueryObjecti64vRobustANGLE, + GLGetQueryObjectiv, + GLGetQueryObjectivEXT, + GLGetQueryObjectivRobustANGLE, + GLGetQueryObjectui64v, + GLGetQueryObjectui64vEXT, + GLGetQueryObjectui64vRobustANGLE, + GLGetQueryObjectuiv, + GLGetQueryObjectuivEXT, + GLGetQueryObjectuivRobustANGLE, + GLGetQueryiv, + GLGetQueryivEXT, + GLGetQueryivRobustANGLE, + GLGetRenderbufferImageANGLE, + GLGetRenderbufferParameteriv, + GLGetRenderbufferParameterivOES, + GLGetRenderbufferParameterivRobustANGLE, + GLGetSamplerParameterIiv, + GLGetSamplerParameterIivEXT, + GLGetSamplerParameterIivOES, + GLGetSamplerParameterIivRobustANGLE, + GLGetSamplerParameterIuiv, + GLGetSamplerParameterIuivEXT, + GLGetSamplerParameterIuivOES, + GLGetSamplerParameterIuivRobustANGLE, + GLGetSamplerParameterfv, + GLGetSamplerParameterfvRobustANGLE, + GLGetSamplerParameteriv, + GLGetSamplerParameterivRobustANGLE, + GLGetSemaphoreParameterui64vEXT, + GLGetShaderInfoLog, + GLGetShaderPrecisionFormat, + GLGetShaderSource, + GLGetShaderiv, + GLGetShaderivRobustANGLE, + GLGetString, + GLGetStringi, + GLGetSubroutineIndex, + GLGetSubroutineUniformLocation, + GLGetSynciv, + GLGetTexEnvfv, + GLGetTexEnviv, + GLGetTexEnvxv, + GLGetTexGendv, + GLGetTexGenfv, + GLGetTexGenfvOES, + GLGetTexGeniv, + GLGetTexGenivOES, + GLGetTexGenxvOES, + GLGetTexImage, + GLGetTexImageANGLE, + GLGetTexLevelParameterfv, + GLGetTexLevelParameterfvANGLE, + GLGetTexLevelParameterfvRobustANGLE, + GLGetTexLevelParameteriv, + GLGetTexLevelParameterivANGLE, + GLGetTexLevelParameterivRobustANGLE, + GLGetTexParameterIiv, + GLGetTexParameterIivEXT, + GLGetTexParameterIivOES, + GLGetTexParameterIivRobustANGLE, + GLGetTexParameterIuiv, + GLGetTexParameterIuivEXT, + GLGetTexParameterIuivOES, + GLGetTexParameterIuivRobustANGLE, + GLGetTexParameterfv, + GLGetTexParameterfvRobustANGLE, + GLGetTexParameteriv, + GLGetTexParameterivRobustANGLE, + GLGetTexParameterxv, + GLGetTextureImage, + GLGetTextureLevelParameterfv, + GLGetTextureLevelParameteriv, + GLGetTextureParameterIiv, + GLGetTextureParameterIuiv, + GLGetTextureParameterfv, + GLGetTextureParameteriv, + GLGetTextureSubImage, + GLGetTransformFeedbackVarying, + GLGetTransformFeedbacki64_v, + GLGetTransformFeedbacki_v, + GLGetTransformFeedbackiv, + GLGetTranslatedShaderSourceANGLE, + GLGetUniformBlockIndex, + GLGetUniformIndices, + GLGetUniformLocation, + GLGetUniformSubroutineuiv, + GLGetUniformdv, + GLGetUniformfv, + GLGetUniformfvRobustANGLE, + GLGetUniformiv, + GLGetUniformivRobustANGLE, + GLGetUniformuiv, + GLGetUniformuivRobustANGLE, + GLGetUnsignedBytei_vEXT, + GLGetUnsignedBytevEXT, + GLGetVertexArrayIndexed64iv, + GLGetVertexArrayIndexediv, + GLGetVertexArrayiv, + GLGetVertexAttribIiv, + GLGetVertexAttribIivRobustANGLE, + GLGetVertexAttribIuiv, + GLGetVertexAttribIuivRobustANGLE, + GLGetVertexAttribLdv, + GLGetVertexAttribPointerv, + GLGetVertexAttribPointervRobustANGLE, + GLGetVertexAttribdv, + GLGetVertexAttribfv, + GLGetVertexAttribfvRobustANGLE, + GLGetVertexAttribiv, + GLGetVertexAttribivRobustANGLE, + GLGetnColorTable, + GLGetnCompressedTexImage, + GLGetnConvolutionFilter, + GLGetnHistogram, + GLGetnMapdv, + GLGetnMapfv, + GLGetnMapiv, + GLGetnMinmax, + GLGetnPixelMapfv, + GLGetnPixelMapuiv, + GLGetnPixelMapusv, + GLGetnPolygonStipple, + GLGetnSeparableFilter, + GLGetnTexImage, + GLGetnUniformdv, + GLGetnUniformfv, + GLGetnUniformfvEXT, + GLGetnUniformfvRobustANGLE, + GLGetnUniformiv, + GLGetnUniformivEXT, + GLGetnUniformivRobustANGLE, + GLGetnUniformuiv, + GLGetnUniformuivRobustANGLE, + GLHint, + GLImportMemoryFdEXT, + GLImportMemoryZirconHandleANGLE, + GLImportSemaphoreFdEXT, + GLImportSemaphoreZirconHandleANGLE, + GLIndexMask, + GLIndexPointer, + GLIndexd, + GLIndexdv, + GLIndexf, + GLIndexfv, + GLIndexi, + GLIndexiv, + GLIndexs, + GLIndexsv, + GLIndexub, + GLIndexubv, + GLInitNames, + GLInsertEventMarkerEXT, + GLInterleavedArrays, + GLInvalid, + GLInvalidateBufferData, + GLInvalidateBufferSubData, + GLInvalidateFramebuffer, + GLInvalidateNamedFramebufferData, + GLInvalidateNamedFramebufferSubData, + GLInvalidateSubFramebuffer, + GLInvalidateTexImage, + GLInvalidateTexSubImage, + GLInvalidateTextureANGLE, + GLIsBuffer, + GLIsEnabled, + GLIsEnabledi, + GLIsEnablediEXT, + GLIsEnablediOES, + GLIsFenceNV, + GLIsFramebuffer, + GLIsFramebufferOES, + GLIsList, + GLIsMemoryObjectEXT, + GLIsProgram, + GLIsProgramPipeline, + GLIsProgramPipelineEXT, + GLIsQuery, + GLIsQueryEXT, + GLIsRenderbuffer, + GLIsRenderbufferOES, + GLIsSampler, + GLIsSemaphoreEXT, + GLIsShader, + GLIsSync, + GLIsTexture, + GLIsTransformFeedback, + GLIsVertexArray, + GLIsVertexArrayOES, + GLLabelObjectEXT, + GLLightModelf, + GLLightModelfv, + GLLightModeli, + GLLightModeliv, + GLLightModelx, + GLLightModelxv, + GLLightf, + GLLightfv, + GLLighti, + GLLightiv, + GLLightx, + GLLightxv, + GLLineStipple, + GLLineWidth, + GLLineWidthx, + GLLinkProgram, + GLListBase, + GLLoadIdentity, + GLLoadMatrixd, + GLLoadMatrixf, + GLLoadMatrixx, + GLLoadName, + GLLoadPaletteFromModelViewMatrixOES, + GLLoadTransposeMatrixd, + GLLoadTransposeMatrixf, + GLLogicOp, + GLLogicOpANGLE, + GLLoseContextCHROMIUM, + GLMap1d, + GLMap1f, + GLMap2d, + GLMap2f, + GLMapBuffer, + GLMapBufferOES, + GLMapBufferRange, + GLMapBufferRangeEXT, + GLMapGrid1d, + GLMapGrid1f, + GLMapGrid2d, + GLMapGrid2f, + GLMapNamedBuffer, + GLMapNamedBufferRange, + GLMaterialf, + GLMaterialfv, + GLMateriali, + GLMaterialiv, + GLMaterialx, + GLMaterialxv, + GLMatrixIndexPointerOES, + GLMatrixMode, + GLMaxShaderCompilerThreadsKHR, + GLMemoryBarrier, + GLMemoryBarrierByRegion, + GLMemoryObjectParameterivEXT, + GLMinSampleShading, + GLMinSampleShadingOES, + GLMultMatrixd, + GLMultMatrixf, + GLMultMatrixx, + GLMultTransposeMatrixd, + GLMultTransposeMatrixf, + GLMultiDrawArrays, + GLMultiDrawArraysANGLE, + GLMultiDrawArraysIndirect, + GLMultiDrawArraysIndirectCount, + GLMultiDrawArraysIndirectEXT, + GLMultiDrawArraysInstancedANGLE, + GLMultiDrawArraysInstancedBaseInstanceANGLE, + GLMultiDrawElements, + GLMultiDrawElementsANGLE, + GLMultiDrawElementsBaseVertex, + GLMultiDrawElementsBaseVertexEXT, + GLMultiDrawElementsIndirect, + GLMultiDrawElementsIndirectCount, + GLMultiDrawElementsIndirectEXT, + GLMultiDrawElementsInstancedANGLE, + GLMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE, + GLMultiTexCoord1d, + GLMultiTexCoord1dv, + GLMultiTexCoord1f, + GLMultiTexCoord1fv, + GLMultiTexCoord1i, + GLMultiTexCoord1iv, + GLMultiTexCoord1s, + GLMultiTexCoord1sv, + GLMultiTexCoord2d, + GLMultiTexCoord2dv, + GLMultiTexCoord2f, + GLMultiTexCoord2fv, + GLMultiTexCoord2i, + GLMultiTexCoord2iv, + GLMultiTexCoord2s, + GLMultiTexCoord2sv, + GLMultiTexCoord3d, + GLMultiTexCoord3dv, + GLMultiTexCoord3f, + GLMultiTexCoord3fv, + GLMultiTexCoord3i, + GLMultiTexCoord3iv, + GLMultiTexCoord3s, + GLMultiTexCoord3sv, + GLMultiTexCoord4d, + GLMultiTexCoord4dv, + GLMultiTexCoord4f, + GLMultiTexCoord4fv, + GLMultiTexCoord4i, + GLMultiTexCoord4iv, + GLMultiTexCoord4s, + GLMultiTexCoord4sv, + GLMultiTexCoord4x, + GLMultiTexCoordP1ui, + GLMultiTexCoordP1uiv, + GLMultiTexCoordP2ui, + GLMultiTexCoordP2uiv, + GLMultiTexCoordP3ui, + GLMultiTexCoordP3uiv, + GLMultiTexCoordP4ui, + GLMultiTexCoordP4uiv, + GLNamedBufferData, + GLNamedBufferStorage, + GLNamedBufferStorageExternalEXT, + GLNamedBufferSubData, + GLNamedFramebufferDrawBuffer, + GLNamedFramebufferDrawBuffers, + GLNamedFramebufferParameteri, + GLNamedFramebufferReadBuffer, + GLNamedFramebufferRenderbuffer, + GLNamedFramebufferTexture, + GLNamedFramebufferTextureLayer, + GLNamedRenderbufferStorage, + GLNamedRenderbufferStorageMultisample, + GLNewList, + GLNormal3b, + GLNormal3bv, + GLNormal3d, + GLNormal3dv, + GLNormal3f, + GLNormal3fv, + GLNormal3i, + GLNormal3iv, + GLNormal3s, + GLNormal3sv, + GLNormal3x, + GLNormalP3ui, + GLNormalP3uiv, + GLNormalPointer, + GLObjectLabel, + GLObjectLabelKHR, + GLObjectPtrLabel, + GLObjectPtrLabelKHR, + GLOrtho, + GLOrthof, + GLOrthox, + GLPassThrough, + GLPatchParameterfv, + GLPatchParameteri, + GLPatchParameteriEXT, + GLPauseTransformFeedback, + GLPixelLocalStorageBarrierANGLE, + GLPixelMapfv, + GLPixelMapuiv, + GLPixelMapusv, + GLPixelStoref, + GLPixelStorei, + GLPixelTransferf, + GLPixelTransferi, + GLPixelZoom, + GLPointParameterf, + GLPointParameterfv, + GLPointParameteri, + GLPointParameteriv, + GLPointParameterx, + GLPointParameterxv, + GLPointSize, + GLPointSizePointerOES, + GLPointSizex, + GLPolygonMode, + GLPolygonOffset, + GLPolygonOffsetClamp, + GLPolygonOffsetx, + GLPolygonStipple, + GLPopAttrib, + GLPopClientAttrib, + GLPopDebugGroup, + GLPopDebugGroupKHR, + GLPopGroupMarkerEXT, + GLPopMatrix, + GLPopName, + GLPrimitiveBoundingBox, + GLPrimitiveBoundingBoxEXT, + GLPrimitiveBoundingBoxOES, + GLPrimitiveRestartIndex, + GLPrioritizeTextures, + GLProgramBinary, + GLProgramBinaryOES, + GLProgramParameteri, + GLProgramParameteriEXT, + GLProgramUniform1d, + GLProgramUniform1dv, + GLProgramUniform1f, + GLProgramUniform1fEXT, + GLProgramUniform1fv, + GLProgramUniform1fvEXT, + GLProgramUniform1i, + GLProgramUniform1iEXT, + GLProgramUniform1iv, + GLProgramUniform1ivEXT, + GLProgramUniform1ui, + GLProgramUniform1uiEXT, + GLProgramUniform1uiv, + GLProgramUniform1uivEXT, + GLProgramUniform2d, + GLProgramUniform2dv, + GLProgramUniform2f, + GLProgramUniform2fEXT, + GLProgramUniform2fv, + GLProgramUniform2fvEXT, + GLProgramUniform2i, + GLProgramUniform2iEXT, + GLProgramUniform2iv, + GLProgramUniform2ivEXT, + GLProgramUniform2ui, + GLProgramUniform2uiEXT, + GLProgramUniform2uiv, + GLProgramUniform2uivEXT, + GLProgramUniform3d, + GLProgramUniform3dv, + GLProgramUniform3f, + GLProgramUniform3fEXT, + GLProgramUniform3fv, + GLProgramUniform3fvEXT, + GLProgramUniform3i, + GLProgramUniform3iEXT, + GLProgramUniform3iv, + GLProgramUniform3ivEXT, + GLProgramUniform3ui, + GLProgramUniform3uiEXT, + GLProgramUniform3uiv, + GLProgramUniform3uivEXT, + GLProgramUniform4d, + GLProgramUniform4dv, + GLProgramUniform4f, + GLProgramUniform4fEXT, + GLProgramUniform4fv, + GLProgramUniform4fvEXT, + GLProgramUniform4i, + GLProgramUniform4iEXT, + GLProgramUniform4iv, + GLProgramUniform4ivEXT, + GLProgramUniform4ui, + GLProgramUniform4uiEXT, + GLProgramUniform4uiv, + GLProgramUniform4uivEXT, + GLProgramUniformMatrix2dv, + GLProgramUniformMatrix2fv, + GLProgramUniformMatrix2fvEXT, + GLProgramUniformMatrix2x3dv, + GLProgramUniformMatrix2x3fv, + GLProgramUniformMatrix2x3fvEXT, + GLProgramUniformMatrix2x4dv, + GLProgramUniformMatrix2x4fv, + GLProgramUniformMatrix2x4fvEXT, + GLProgramUniformMatrix3dv, + GLProgramUniformMatrix3fv, + GLProgramUniformMatrix3fvEXT, + GLProgramUniformMatrix3x2dv, + GLProgramUniformMatrix3x2fv, + GLProgramUniformMatrix3x2fvEXT, + GLProgramUniformMatrix3x4dv, + GLProgramUniformMatrix3x4fv, + GLProgramUniformMatrix3x4fvEXT, + GLProgramUniformMatrix4dv, + GLProgramUniformMatrix4fv, + GLProgramUniformMatrix4fvEXT, + GLProgramUniformMatrix4x2dv, + GLProgramUniformMatrix4x2fv, + GLProgramUniformMatrix4x2fvEXT, + GLProgramUniformMatrix4x3dv, + GLProgramUniformMatrix4x3fv, + GLProgramUniformMatrix4x3fvEXT, + GLProvokingVertex, + GLProvokingVertexANGLE, + GLPushAttrib, + GLPushClientAttrib, + GLPushDebugGroup, + GLPushDebugGroupKHR, + GLPushGroupMarkerEXT, + GLPushMatrix, + GLPushName, + GLQueryCounter, + GLQueryCounterEXT, + GLQueryMatrixxOES, + GLRasterPos2d, + GLRasterPos2dv, + GLRasterPos2f, + GLRasterPos2fv, + GLRasterPos2i, + GLRasterPos2iv, + GLRasterPos2s, + GLRasterPos2sv, + GLRasterPos3d, + GLRasterPos3dv, + GLRasterPos3f, + GLRasterPos3fv, + GLRasterPos3i, + GLRasterPos3iv, + GLRasterPos3s, + GLRasterPos3sv, + GLRasterPos4d, + GLRasterPos4dv, + GLRasterPos4f, + GLRasterPos4fv, + GLRasterPos4i, + GLRasterPos4iv, + GLRasterPos4s, + GLRasterPos4sv, + GLReadBuffer, + GLReadPixels, + GLReadPixelsRobustANGLE, + GLReadnPixels, + GLReadnPixelsEXT, + GLReadnPixelsRobustANGLE, + GLRectd, + GLRectdv, + GLRectf, + GLRectfv, + GLRecti, + GLRectiv, + GLRects, + GLRectsv, + GLReleaseShaderCompiler, + GLReleaseTexturesANGLE, + GLRenderMode, + GLRenderbufferStorage, + GLRenderbufferStorageMultisample, + GLRenderbufferStorageMultisampleANGLE, + GLRenderbufferStorageMultisampleEXT, + GLRenderbufferStorageOES, + GLRequestExtensionANGLE, + GLResumeTransformFeedback, + GLRotated, + GLRotatef, + GLRotatex, + GLSampleCoverage, + GLSampleCoveragex, + GLSampleMaski, + GLSampleMaskiANGLE, + GLSamplerParameterIiv, + GLSamplerParameterIivEXT, + GLSamplerParameterIivOES, + GLSamplerParameterIivRobustANGLE, + GLSamplerParameterIuiv, + GLSamplerParameterIuivEXT, + GLSamplerParameterIuivOES, + GLSamplerParameterIuivRobustANGLE, + GLSamplerParameterf, + GLSamplerParameterfv, + GLSamplerParameterfvRobustANGLE, + GLSamplerParameteri, + GLSamplerParameteriv, + GLSamplerParameterivRobustANGLE, + GLScaled, + GLScalef, + GLScalex, + GLScissor, + GLScissorArrayv, + GLScissorIndexed, + GLScissorIndexedv, + GLSecondaryColor3b, + GLSecondaryColor3bv, + GLSecondaryColor3d, + GLSecondaryColor3dv, + GLSecondaryColor3f, + GLSecondaryColor3fv, + GLSecondaryColor3i, + GLSecondaryColor3iv, + GLSecondaryColor3s, + GLSecondaryColor3sv, + GLSecondaryColor3ub, + GLSecondaryColor3ubv, + GLSecondaryColor3ui, + GLSecondaryColor3uiv, + GLSecondaryColor3us, + GLSecondaryColor3usv, + GLSecondaryColorP3ui, + GLSecondaryColorP3uiv, + GLSecondaryColorPointer, + GLSelectBuffer, + GLSelectPerfMonitorCountersAMD, + GLSemaphoreParameterui64vEXT, + GLSetFenceNV, + GLShadeModel, + GLShaderBinary, + GLShaderSource, + GLShaderStorageBlockBinding, + GLShadingRateQCOM, + GLSignalSemaphoreEXT, + GLSpecializeShader, + GLStencilFunc, + GLStencilFuncSeparate, + GLStencilMask, + GLStencilMaskSeparate, + GLStencilOp, + GLStencilOpSeparate, + GLTestFenceNV, + GLTexBuffer, + GLTexBufferEXT, + GLTexBufferOES, + GLTexBufferRange, + GLTexBufferRangeEXT, + GLTexBufferRangeOES, + GLTexCoord1d, + GLTexCoord1dv, + GLTexCoord1f, + GLTexCoord1fv, + GLTexCoord1i, + GLTexCoord1iv, + GLTexCoord1s, + GLTexCoord1sv, + GLTexCoord2d, + GLTexCoord2dv, + GLTexCoord2f, + GLTexCoord2fv, + GLTexCoord2i, + GLTexCoord2iv, + GLTexCoord2s, + GLTexCoord2sv, + GLTexCoord3d, + GLTexCoord3dv, + GLTexCoord3f, + GLTexCoord3fv, + GLTexCoord3i, + GLTexCoord3iv, + GLTexCoord3s, + GLTexCoord3sv, + GLTexCoord4d, + GLTexCoord4dv, + GLTexCoord4f, + GLTexCoord4fv, + GLTexCoord4i, + GLTexCoord4iv, + GLTexCoord4s, + GLTexCoord4sv, + GLTexCoordP1ui, + GLTexCoordP1uiv, + GLTexCoordP2ui, + GLTexCoordP2uiv, + GLTexCoordP3ui, + GLTexCoordP3uiv, + GLTexCoordP4ui, + GLTexCoordP4uiv, + GLTexCoordPointer, + GLTexEnvf, + GLTexEnvfv, + GLTexEnvi, + GLTexEnviv, + GLTexEnvx, + GLTexEnvxv, + GLTexGend, + GLTexGendv, + GLTexGenf, + GLTexGenfOES, + GLTexGenfv, + GLTexGenfvOES, + GLTexGeni, + GLTexGeniOES, + GLTexGeniv, + GLTexGenivOES, + GLTexGenxOES, + GLTexGenxvOES, + GLTexImage1D, + GLTexImage2D, + GLTexImage2DExternalANGLE, + GLTexImage2DMultisample, + GLTexImage2DRobustANGLE, + GLTexImage3D, + GLTexImage3DMultisample, + GLTexImage3DOES, + GLTexImage3DRobustANGLE, + GLTexParameterIiv, + GLTexParameterIivEXT, + GLTexParameterIivOES, + GLTexParameterIivRobustANGLE, + GLTexParameterIuiv, + GLTexParameterIuivEXT, + GLTexParameterIuivOES, + GLTexParameterIuivRobustANGLE, + GLTexParameterf, + GLTexParameterfv, + GLTexParameterfvRobustANGLE, + GLTexParameteri, + GLTexParameteriv, + GLTexParameterivRobustANGLE, + GLTexParameterx, + GLTexParameterxv, + GLTexStorage1D, + GLTexStorage1DEXT, + GLTexStorage2D, + GLTexStorage2DEXT, + GLTexStorage2DMultisample, + GLTexStorage2DMultisampleANGLE, + GLTexStorage3D, + GLTexStorage3DEXT, + GLTexStorage3DMultisample, + GLTexStorage3DMultisampleOES, + GLTexStorageMem2DEXT, + GLTexStorageMem2DMultisampleEXT, + GLTexStorageMem3DEXT, + GLTexStorageMem3DMultisampleEXT, + GLTexStorageMemFlags2DANGLE, + GLTexStorageMemFlags2DMultisampleANGLE, + GLTexStorageMemFlags3DANGLE, + GLTexStorageMemFlags3DMultisampleANGLE, + GLTexSubImage1D, + GLTexSubImage2D, + GLTexSubImage2DRobustANGLE, + GLTexSubImage3D, + GLTexSubImage3DOES, + GLTexSubImage3DRobustANGLE, + GLTextureBarrier, + GLTextureBuffer, + GLTextureBufferRange, + GLTextureParameterIiv, + GLTextureParameterIuiv, + GLTextureParameterf, + GLTextureParameterfv, + GLTextureParameteri, + GLTextureParameteriv, + GLTextureStorage1D, + GLTextureStorage2D, + GLTextureStorage2DMultisample, + GLTextureStorage3D, + GLTextureStorage3DMultisample, + GLTextureSubImage1D, + GLTextureSubImage2D, + GLTextureSubImage3D, + GLTextureView, + GLTransformFeedbackBufferBase, + GLTransformFeedbackBufferRange, + GLTransformFeedbackVaryings, + GLTranslated, + GLTranslatef, + GLTranslatex, + GLUniform1d, + GLUniform1dv, + GLUniform1f, + GLUniform1fv, + GLUniform1i, + GLUniform1iv, + GLUniform1ui, + GLUniform1uiv, + GLUniform2d, + GLUniform2dv, + GLUniform2f, + GLUniform2fv, + GLUniform2i, + GLUniform2iv, + GLUniform2ui, + GLUniform2uiv, + GLUniform3d, + GLUniform3dv, + GLUniform3f, + GLUniform3fv, + GLUniform3i, + GLUniform3iv, + GLUniform3ui, + GLUniform3uiv, + GLUniform4d, + GLUniform4dv, + GLUniform4f, + GLUniform4fv, + GLUniform4i, + GLUniform4iv, + GLUniform4ui, + GLUniform4uiv, + GLUniformBlockBinding, + GLUniformMatrix2dv, + GLUniformMatrix2fv, + GLUniformMatrix2x3dv, + GLUniformMatrix2x3fv, + GLUniformMatrix2x4dv, + GLUniformMatrix2x4fv, + GLUniformMatrix3dv, + GLUniformMatrix3fv, + GLUniformMatrix3x2dv, + GLUniformMatrix3x2fv, + GLUniformMatrix3x4dv, + GLUniformMatrix3x4fv, + GLUniformMatrix4dv, + GLUniformMatrix4fv, + GLUniformMatrix4x2dv, + GLUniformMatrix4x2fv, + GLUniformMatrix4x3dv, + GLUniformMatrix4x3fv, + GLUniformSubroutinesuiv, + GLUnmapBuffer, + GLUnmapBufferOES, + GLUnmapNamedBuffer, + GLUseProgram, + GLUseProgramStages, + GLUseProgramStagesEXT, + GLValidateProgram, + GLValidateProgramPipeline, + GLValidateProgramPipelineEXT, + GLVertex2d, + GLVertex2dv, + GLVertex2f, + GLVertex2fv, + GLVertex2i, + GLVertex2iv, + GLVertex2s, + GLVertex2sv, + GLVertex3d, + GLVertex3dv, + GLVertex3f, + GLVertex3fv, + GLVertex3i, + GLVertex3iv, + GLVertex3s, + GLVertex3sv, + GLVertex4d, + GLVertex4dv, + GLVertex4f, + GLVertex4fv, + GLVertex4i, + GLVertex4iv, + GLVertex4s, + GLVertex4sv, + GLVertexArrayAttribBinding, + GLVertexArrayAttribFormat, + GLVertexArrayAttribIFormat, + GLVertexArrayAttribLFormat, + GLVertexArrayBindingDivisor, + GLVertexArrayElementBuffer, + GLVertexArrayVertexBuffer, + GLVertexArrayVertexBuffers, + GLVertexAttrib1d, + GLVertexAttrib1dv, + GLVertexAttrib1f, + GLVertexAttrib1fv, + GLVertexAttrib1s, + GLVertexAttrib1sv, + GLVertexAttrib2d, + GLVertexAttrib2dv, + GLVertexAttrib2f, + GLVertexAttrib2fv, + GLVertexAttrib2s, + GLVertexAttrib2sv, + GLVertexAttrib3d, + GLVertexAttrib3dv, + GLVertexAttrib3f, + GLVertexAttrib3fv, + GLVertexAttrib3s, + GLVertexAttrib3sv, + GLVertexAttrib4Nbv, + GLVertexAttrib4Niv, + GLVertexAttrib4Nsv, + GLVertexAttrib4Nub, + GLVertexAttrib4Nubv, + GLVertexAttrib4Nuiv, + GLVertexAttrib4Nusv, + GLVertexAttrib4bv, + GLVertexAttrib4d, + GLVertexAttrib4dv, + GLVertexAttrib4f, + GLVertexAttrib4fv, + GLVertexAttrib4iv, + GLVertexAttrib4s, + GLVertexAttrib4sv, + GLVertexAttrib4ubv, + GLVertexAttrib4uiv, + GLVertexAttrib4usv, + GLVertexAttribBinding, + GLVertexAttribDivisor, + GLVertexAttribDivisorANGLE, + GLVertexAttribDivisorEXT, + GLVertexAttribFormat, + GLVertexAttribI1i, + GLVertexAttribI1iv, + GLVertexAttribI1ui, + GLVertexAttribI1uiv, + GLVertexAttribI2i, + GLVertexAttribI2iv, + GLVertexAttribI2ui, + GLVertexAttribI2uiv, + GLVertexAttribI3i, + GLVertexAttribI3iv, + GLVertexAttribI3ui, + GLVertexAttribI3uiv, + GLVertexAttribI4bv, + GLVertexAttribI4i, + GLVertexAttribI4iv, + GLVertexAttribI4sv, + GLVertexAttribI4ubv, + GLVertexAttribI4ui, + GLVertexAttribI4uiv, + GLVertexAttribI4usv, + GLVertexAttribIFormat, + GLVertexAttribIPointer, + GLVertexAttribL1d, + GLVertexAttribL1dv, + GLVertexAttribL2d, + GLVertexAttribL2dv, + GLVertexAttribL3d, + GLVertexAttribL3dv, + GLVertexAttribL4d, + GLVertexAttribL4dv, + GLVertexAttribLFormat, + GLVertexAttribLPointer, + GLVertexAttribP1ui, + GLVertexAttribP1uiv, + GLVertexAttribP2ui, + GLVertexAttribP2uiv, + GLVertexAttribP3ui, + GLVertexAttribP3uiv, + GLVertexAttribP4ui, + GLVertexAttribP4uiv, + GLVertexAttribPointer, + GLVertexBindingDivisor, + GLVertexP2ui, + GLVertexP2uiv, + GLVertexP3ui, + GLVertexP3uiv, + GLVertexP4ui, + GLVertexP4uiv, + GLVertexPointer, + GLViewport, + GLViewportArrayv, + GLViewportIndexedf, + GLViewportIndexedfv, + GLWaitSemaphoreEXT, + GLWaitSync, + GLWeightPointerOES, + GLWindowPos2d, + GLWindowPos2dv, + GLWindowPos2f, + GLWindowPos2fv, + GLWindowPos2i, + GLWindowPos2iv, + GLWindowPos2s, + GLWindowPos2sv, + GLWindowPos3d, + GLWindowPos3dv, + GLWindowPos3f, + GLWindowPos3fv, + GLWindowPos3i, + GLWindowPos3iv, + GLWindowPos3s, + GLWindowPos3sv, + WGLChoosePixelFormat, + WGLCopyContext, + WGLCreateContext, + WGLCreateLayerContext, + WGLDeleteContext, + WGLDescribeLayerPlane, + WGLDescribePixelFormat, + WGLGetCurrentContext, + WGLGetCurrentDC, + WGLGetEnhMetaFilePixelFormat, + WGLGetLayerPaletteEntries, + WGLGetPixelFormat, + WGLGetProcAddress, + WGLMakeCurrent, + WGLRealizeLayerPalette, + WGLSetLayerPaletteEntries, + WGLSetPixelFormat, + WGLShareLists, + WGLSwapBuffers, + WGLSwapLayerBuffers, + WGLUseFontBitmaps, + WGLUseFontBitmapsA, + WGLUseFontBitmapsW, + WGLUseFontOutlines, + WGLUseFontOutlinesA, + WGLUseFontOutlinesW +}; + +const char *GetEntryPointName(EntryPoint ep); +} // namespace angle +#endif // COMMON_ENTRY_POINTS_ENUM_AUTOGEN_H_ diff --git a/gfx/angle/checkout/src/common/event_tracer.cpp b/gfx/angle/checkout/src/common/event_tracer.cpp new file mode 100644 index 0000000000..151cb2cd70 --- /dev/null +++ b/gfx/angle/checkout/src/common/event_tracer.cpp @@ -0,0 +1,53 @@ +// Copyright 2012 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. + +#include "common/event_tracer.h" + +#include "common/debug.h" + +namespace angle +{ + +const unsigned char *GetTraceCategoryEnabledFlag(PlatformMethods *platform, const char *name) +{ + ASSERT(platform); + + const unsigned char *categoryEnabledFlag = + platform->getTraceCategoryEnabledFlag(platform, name); + if (categoryEnabledFlag != nullptr) + { + return categoryEnabledFlag; + } + + static unsigned char disabled = 0; + return &disabled; +} + +angle::TraceEventHandle AddTraceEvent(PlatformMethods *platform, + char phase, + const unsigned char *categoryGroupEnabled, + const char *name, + unsigned long long id, + int numArgs, + const char **argNames, + const unsigned char *argTypes, + const unsigned long long *argValues, + unsigned char flags) +{ + ASSERT(platform); + + double timestamp = platform->monotonicallyIncreasingTime(platform); + + if (timestamp != 0) + { + angle::TraceEventHandle handle = + platform->addTraceEvent(platform, phase, categoryGroupEnabled, name, id, timestamp, + numArgs, argNames, argTypes, argValues, flags); + return handle; + } + + return static_cast(0); +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/event_tracer.h b/gfx/angle/checkout/src/common/event_tracer.h new file mode 100644 index 0000000000..128d88b9e0 --- /dev/null +++ b/gfx/angle/checkout/src/common/event_tracer.h @@ -0,0 +1,26 @@ +// Copyright 2012 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. + +#ifndef COMMON_EVENT_TRACER_H_ +#define COMMON_EVENT_TRACER_H_ + +#include "common/platform.h" +#include "platform/PlatformMethods.h" + +namespace angle +{ +const unsigned char *GetTraceCategoryEnabledFlag(PlatformMethods *platform, const char *name); +angle::TraceEventHandle AddTraceEvent(PlatformMethods *platform, + char phase, + const unsigned char *categoryGroupEnabled, + const char *name, + unsigned long long id, + int numArgs, + const char **argNames, + const unsigned char *argTypes, + const unsigned long long *argValues, + unsigned char flags); +} // namespace angle + +#endif // COMMON_EVENT_TRACER_H_ diff --git a/gfx/angle/checkout/src/common/hash_utils.h b/gfx/angle/checkout/src/common/hash_utils.h new file mode 100644 index 0000000000..aec4e7f77c --- /dev/null +++ b/gfx/angle/checkout/src/common/hash_utils.h @@ -0,0 +1,39 @@ +// +// Copyright 2018 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. +// +// hash_utils.h: Hashing based helper functions. + +#ifndef COMMON_HASHUTILS_H_ +#define COMMON_HASHUTILS_H_ + +#include "common/debug.h" +#include "common/third_party/xxhash/xxhash.h" + +namespace angle +{ +// Computes a hash of "key". Any data passed to this function must be multiples of +// 4 bytes, since the PMurHash32 method can only operate increments of 4-byte words. +inline std::size_t ComputeGenericHash(const void *key, size_t keySize) +{ + static constexpr unsigned int kSeed = 0xABCDEF98; + + // We can't support "odd" alignments. ComputeGenericHash requires aligned types + ASSERT(keySize % 4 == 0); +#if defined(ANGLE_IS_64_BIT_CPU) + return XXH64(key, keySize, kSeed); +#else + return XXH32(key, keySize, kSeed); +#endif // defined(ANGLE_IS_64_BIT_CPU) +} + +template +std::size_t ComputeGenericHash(const T &key) +{ + static_assert(sizeof(key) % 4 == 0, "ComputeGenericHash requires aligned types"); + return ComputeGenericHash(&key, sizeof(key)); +} +} // namespace angle + +#endif // COMMON_HASHUTILS_H_ diff --git a/gfx/angle/checkout/src/common/mathutil.cpp b/gfx/angle/checkout/src/common/mathutil.cpp new file mode 100644 index 0000000000..5cbc6a920a --- /dev/null +++ b/gfx/angle/checkout/src/common/mathutil.cpp @@ -0,0 +1,83 @@ +// +// 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. +// + +// mathutil.cpp: Math and bit manipulation functions. + +#include "common/mathutil.h" + +#include +#include + +namespace gl +{ + +namespace +{ + +struct RGB9E5Data +{ + unsigned int R : 9; + unsigned int G : 9; + unsigned int B : 9; + unsigned int E : 5; +}; + +// B is the exponent bias (15) +constexpr int g_sharedexp_bias = 15; + +// N is the number of mantissa bits per component (9) +constexpr int g_sharedexp_mantissabits = 9; + +// number of mantissa bits per component pre-biased +constexpr int g_sharedexp_biased_mantissabits = g_sharedexp_bias + g_sharedexp_mantissabits; + +// Emax is the maximum allowed biased exponent value (31) +constexpr int g_sharedexp_maxexponent = 31; + +constexpr float g_sharedexp_max = + ((static_cast(1 << g_sharedexp_mantissabits) - 1) / + static_cast(1 << g_sharedexp_mantissabits)) * + static_cast(1 << (g_sharedexp_maxexponent - g_sharedexp_bias)); + +} // anonymous namespace + +unsigned int convertRGBFloatsTo999E5(float red, float green, float blue) +{ + const float red_c = std::max(0, std::min(g_sharedexp_max, red)); + const float green_c = std::max(0, std::min(g_sharedexp_max, green)); + const float blue_c = std::max(0, std::min(g_sharedexp_max, blue)); + + const float max_c = std::max(std::max(red_c, green_c), blue_c); + const float exp_p = + std::max(-g_sharedexp_bias - 1, floor(log(max_c))) + 1 + g_sharedexp_bias; + const int max_s = static_cast( + floor((max_c / (pow(2.0f, exp_p - g_sharedexp_biased_mantissabits))) + 0.5f)); + const int exp_s = + static_cast((max_s < pow(2.0f, g_sharedexp_mantissabits)) ? exp_p : exp_p + 1); + const float pow2_exp = pow(2.0f, static_cast(exp_s) - g_sharedexp_biased_mantissabits); + + RGB9E5Data output; + output.R = static_cast(floor((red_c / pow2_exp) + 0.5f)); + output.G = static_cast(floor((green_c / pow2_exp) + 0.5f)); + output.B = static_cast(floor((blue_c / pow2_exp) + 0.5f)); + output.E = exp_s; + + return bitCast(output); +} + +void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue) +{ + const RGB9E5Data *inputData = reinterpret_cast(&input); + + const float pow2_exp = + pow(2.0f, static_cast(inputData->E) - g_sharedexp_biased_mantissabits); + + *red = inputData->R * pow2_exp; + *green = inputData->G * pow2_exp; + *blue = inputData->B * pow2_exp; +} + +} // namespace gl diff --git a/gfx/angle/checkout/src/common/mathutil.h b/gfx/angle/checkout/src/common/mathutil.h new file mode 100644 index 0000000000..560929239f --- /dev/null +++ b/gfx/angle/checkout/src/common/mathutil.h @@ -0,0 +1,1482 @@ +// +// 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. +// + +// mathutil.h: Math and bit manipulation functions. + +#ifndef COMMON_MATHUTIL_H_ +#define COMMON_MATHUTIL_H_ + +#include +#include +#include +#include +#include +#include + +#include + +#include "common/debug.h" +#include "common/platform.h" + +namespace angle +{ +using base::CheckedNumeric; +using base::IsValueInRangeForNumericType; +} // namespace angle + +namespace gl +{ + +const unsigned int Float32One = 0x3F800000; +const unsigned short Float16One = 0x3C00; + +template +inline constexpr bool isPow2(T x) +{ + static_assert(std::is_integral::value, "isPow2 must be called on an integer type."); + return (x & (x - 1)) == 0 && (x != 0); +} + +template +inline int log2(T x) +{ + static_assert(std::is_integral::value, "log2 must be called on an integer type."); + int r = 0; + while ((x >> r) > 1) + r++; + return r; +} + +inline unsigned int ceilPow2(unsigned int x) +{ + if (x != 0) + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + + return x; +} + +template +inline DestT clampCast(SrcT value) +{ + // For floating-point types with denormalization, min returns the minimum positive normalized + // value. To find the value that has no values less than it, use numeric_limits::lowest. + constexpr const long double destLo = + static_cast(std::numeric_limits::lowest()); + constexpr const long double destHi = + static_cast(std::numeric_limits::max()); + constexpr const long double srcLo = + static_cast(std::numeric_limits::lowest()); + constexpr long double srcHi = static_cast(std::numeric_limits::max()); + + if (destHi < srcHi) + { + DestT destMax = std::numeric_limits::max(); + if (value >= static_cast(destMax)) + { + return destMax; + } + } + + if (destLo > srcLo) + { + DestT destLow = std::numeric_limits::lowest(); + if (value <= static_cast(destLow)) + { + return destLow; + } + } + + return static_cast(value); +} + +// Specialize clampCast for bool->int conversion to avoid MSVS 2015 performance warning when the max +// value is casted to the source type. +template <> +inline unsigned int clampCast(bool value) +{ + return static_cast(value); +} + +template <> +inline int clampCast(bool value) +{ + return static_cast(value); +} + +template +inline T clamp(T x, MIN min, MAX max) +{ + // Since NaNs fail all comparison tests, a NaN value will default to min + return x > min ? (x > max ? max : x) : min; +} + +template +T clampForBitCount(T value, size_t bitCount) +{ + static_assert(std::numeric_limits::is_integer, "T must be an integer."); + + if (bitCount == 0) + { + constexpr T kZero = 0; + return kZero; + } + ASSERT(bitCount <= sizeof(T) * 8); + + constexpr bool kIsSigned = std::numeric_limits::is_signed; + ASSERT((bitCount > 1) || !kIsSigned); + + T min = 0; + T max = 0; + if (bitCount == sizeof(T) * 8) + { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + } + else + { + constexpr T kOne = 1; + min = (kIsSigned) ? -1 * (kOne << (bitCount - 1)) : 0; + max = (kIsSigned) ? (kOne << (bitCount - 1)) - 1 : (kOne << bitCount) - 1; + } + + return gl::clamp(value, min, max); +} + +inline float clamp01(float x) +{ + return clamp(x, 0.0f, 1.0f); +} + +template +inline unsigned int unorm(float x) +{ + const unsigned int max = 0xFFFFFFFF >> (32 - n); + + if (x > 1) + { + return max; + } + else if (x < 0) + { + return 0; + } + else + { + return (unsigned int)(max * x + 0.5f); + } +} + +inline bool supportsSSE2() +{ +#if defined(ANGLE_USE_SSE) + static bool checked = false; + static bool supports = false; + + if (checked) + { + return supports; + } + +# if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) + { + int info[4]; + __cpuid(info, 0); + + if (info[0] >= 1) + { + __cpuid(info, 1); + + supports = (info[3] >> 26) & 1; + } + } +# endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) + checked = true; + return supports; +#else // defined(ANGLE_USE_SSE) + return false; +#endif +} + +template +destType bitCast(const sourceType &source) +{ + size_t copySize = std::min(sizeof(destType), sizeof(sourceType)); + destType output; + memcpy(&output, &source, copySize); + return output; +} + +// https://stackoverflow.com/a/37581284 +template +static constexpr double normalize(T value) +{ + return value < 0 ? -static_cast(value) / std::numeric_limits::min() + : static_cast(value) / std::numeric_limits::max(); +} + +inline unsigned short float32ToFloat16(float fp32) +{ + unsigned int fp32i = bitCast(fp32); + unsigned int sign = (fp32i & 0x80000000) >> 16; + unsigned int abs = fp32i & 0x7FFFFFFF; + + if (abs > 0x7F800000) + { // NaN + return 0x7FFF; + } + else if (abs > 0x47FFEFFF) + { // Infinity + return static_cast(sign | 0x7C00); + } + else if (abs < 0x38800000) // Denormal + { + unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000; + int e = 113 - (abs >> 23); + + if (e < 24) + { + abs = mantissa >> e; + } + else + { + abs = 0; + } + + return static_cast(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13); + } + else + { + return static_cast( + sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13); + } +} + +float float16ToFloat32(unsigned short h); + +unsigned int convertRGBFloatsTo999E5(float red, float green, float blue); +void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue); + +inline unsigned short float32ToFloat11(float fp32) +{ + const unsigned int float32MantissaMask = 0x7FFFFF; + const unsigned int float32ExponentMask = 0x7F800000; + const unsigned int float32SignMask = 0x80000000; + const unsigned int float32ValueMask = ~float32SignMask; + const unsigned int float32ExponentFirstBit = 23; + const unsigned int float32ExponentBias = 127; + + const unsigned short float11Max = 0x7BF; + const unsigned short float11MantissaMask = 0x3F; + const unsigned short float11ExponentMask = 0x7C0; + const unsigned short float11BitMask = 0x7FF; + const unsigned int float11ExponentBias = 14; + + const unsigned int float32Maxfloat11 = 0x477E0000; + const unsigned int float32MinNormfloat11 = 0x38800000; + const unsigned int float32MinDenormfloat11 = 0x35000080; + + const unsigned int float32Bits = bitCast(fp32); + const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; + + unsigned int float32Val = float32Bits & float32ValueMask; + + if ((float32Val & float32ExponentMask) == float32ExponentMask) + { + // INF or NAN + if ((float32Val & float32MantissaMask) != 0) + { + return float11ExponentMask | + (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & + float11MantissaMask); + } + else if (float32Sign) + { + // -INF is clamped to 0 since float11 is positive only + return 0; + } + else + { + return float11ExponentMask; + } + } + else if (float32Sign) + { + // float11 is positive only, so clamp to zero + return 0; + } + else if (float32Val > float32Maxfloat11) + { + // The number is too large to be represented as a float11, set to max + return float11Max; + } + else if (float32Val < float32MinDenormfloat11) + { + // The number is too small to be represented as a denormalized float11, set to 0 + return 0; + } + else + { + if (float32Val < float32MinNormfloat11) + { + // The number is too small to be represented as a normalized float11 + // Convert it to a denormalized value. + const unsigned int shift = (float32ExponentBias - float11ExponentBias) - + (float32Val >> float32ExponentFirstBit); + ASSERT(shift < 32); + float32Val = + ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift; + } + else + { + // Rebias the exponent to represent the value as a normalized float11 + float32Val += 0xC8000000; + } + + return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask; + } +} + +inline unsigned short float32ToFloat10(float fp32) +{ + const unsigned int float32MantissaMask = 0x7FFFFF; + const unsigned int float32ExponentMask = 0x7F800000; + const unsigned int float32SignMask = 0x80000000; + const unsigned int float32ValueMask = ~float32SignMask; + const unsigned int float32ExponentFirstBit = 23; + const unsigned int float32ExponentBias = 127; + + const unsigned short float10Max = 0x3DF; + const unsigned short float10MantissaMask = 0x1F; + const unsigned short float10ExponentMask = 0x3E0; + const unsigned short float10BitMask = 0x3FF; + const unsigned int float10ExponentBias = 14; + + const unsigned int float32Maxfloat10 = 0x477C0000; + const unsigned int float32MinNormfloat10 = 0x38800000; + const unsigned int float32MinDenormfloat10 = 0x35800040; + + const unsigned int float32Bits = bitCast(fp32); + const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; + + unsigned int float32Val = float32Bits & float32ValueMask; + + if ((float32Val & float32ExponentMask) == float32ExponentMask) + { + // INF or NAN + if ((float32Val & float32MantissaMask) != 0) + { + return float10ExponentMask | + (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & + float10MantissaMask); + } + else if (float32Sign) + { + // -INF is clamped to 0 since float10 is positive only + return 0; + } + else + { + return float10ExponentMask; + } + } + else if (float32Sign) + { + // float10 is positive only, so clamp to zero + return 0; + } + else if (float32Val > float32Maxfloat10) + { + // The number is too large to be represented as a float10, set to max + return float10Max; + } + else if (float32Val < float32MinDenormfloat10) + { + // The number is too small to be represented as a denormalized float10, set to 0 + return 0; + } + else + { + if (float32Val < float32MinNormfloat10) + { + // The number is too small to be represented as a normalized float10 + // Convert it to a denormalized value. + const unsigned int shift = (float32ExponentBias - float10ExponentBias) - + (float32Val >> float32ExponentFirstBit); + ASSERT(shift < 32); + float32Val = + ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift; + } + else + { + // Rebias the exponent to represent the value as a normalized float10 + float32Val += 0xC8000000; + } + + return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask; + } +} + +inline float float11ToFloat32(unsigned short fp11) +{ + unsigned short exponent = (fp11 >> 6) & 0x1F; + unsigned short mantissa = fp11 & 0x3F; + + if (exponent == 0x1F) + { + // INF or NAN + return bitCast(0x7f800000 | (mantissa << 17)); + } + else + { + if (exponent != 0) + { + // normalized + } + else if (mantissa != 0) + { + // The value is denormalized + exponent = 1; + + do + { + exponent--; + mantissa <<= 1; + } while ((mantissa & 0x40) == 0); + + mantissa = mantissa & 0x3F; + } + else // The value is zero + { + exponent = static_cast(-112); + } + + return bitCast(((exponent + 112) << 23) | (mantissa << 17)); + } +} + +inline float float10ToFloat32(unsigned short fp10) +{ + unsigned short exponent = (fp10 >> 5) & 0x1F; + unsigned short mantissa = fp10 & 0x1F; + + if (exponent == 0x1F) + { + // INF or NAN + return bitCast(0x7f800000 | (mantissa << 17)); + } + else + { + if (exponent != 0) + { + // normalized + } + else if (mantissa != 0) + { + // The value is denormalized + exponent = 1; + + do + { + exponent--; + mantissa <<= 1; + } while ((mantissa & 0x20) == 0); + + mantissa = mantissa & 0x1F; + } + else // The value is zero + { + exponent = static_cast(-112); + } + + return bitCast(((exponent + 112) << 23) | (mantissa << 18)); + } +} + +// Converts to and from float and 16.16 fixed point format. +inline float ConvertFixedToFloat(int32_t fixedInput) +{ + return static_cast(fixedInput) / 65536.0f; +} + +inline uint32_t ConvertFloatToFixed(float floatInput) +{ + static constexpr uint32_t kHighest = 32767 * 65536 + 65535; + static constexpr uint32_t kLowest = static_cast(-32768 * 65536 + 65535); + + if (floatInput > 32767.65535) + { + return kHighest; + } + else if (floatInput < -32768.65535) + { + return kLowest; + } + else + { + return static_cast(floatInput * 65536); + } +} + +template +inline float normalizedToFloat(T input) +{ + static_assert(std::numeric_limits::is_integer, "T must be an integer."); + + if (sizeof(T) > 2) + { + // float has only a 23 bit mantissa, so we need to do the calculation in double precision + constexpr double inverseMax = 1.0 / std::numeric_limits::max(); + return static_cast(input * inverseMax); + } + else + { + constexpr float inverseMax = 1.0f / std::numeric_limits::max(); + return input * inverseMax; + } +} + +template +inline float normalizedToFloat(T input) +{ + static_assert(std::numeric_limits::is_integer, "T must be an integer."); + static_assert(inputBitCount < (sizeof(T) * 8), "T must have more bits than inputBitCount."); + ASSERT((input & ~((1 << inputBitCount) - 1)) == 0); + + if (inputBitCount > 23) + { + // float has only a 23 bit mantissa, so we need to do the calculation in double precision + constexpr double inverseMax = 1.0 / ((1 << inputBitCount) - 1); + return static_cast(input * inverseMax); + } + else + { + constexpr float inverseMax = 1.0f / ((1 << inputBitCount) - 1); + return input * inverseMax; + } +} + +template +inline T floatToNormalized(float input) +{ + if constexpr (sizeof(T) > 2) + { + // float has only a 23 bit mantissa, so we need to do the calculation in double precision + return static_cast(std::numeric_limits::max() * static_cast(input) + 0.5); + } + else + { + return static_cast(std::numeric_limits::max() * input + 0.5f); + } +} + +template +inline T floatToNormalized(float input) +{ + static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount."); + + if (outputBitCount > 23) + { + // float has only a 23 bit mantissa, so we need to do the calculation in double precision + return static_cast(((1 << outputBitCount) - 1) * static_cast(input) + 0.5); + } + else + { + return static_cast(((1 << outputBitCount) - 1) * input + 0.5f); + } +} + +template +inline T getShiftedData(T input) +{ + static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8), + "T must have at least as many bits as inputBitCount + inputBitStart."); + const T mask = (1 << inputBitCount) - 1; + return (input >> inputBitStart) & mask; +} + +template +inline T shiftData(T input) +{ + static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8), + "T must have at least as many bits as inputBitCount + inputBitStart."); + const T mask = (1 << inputBitCount) - 1; + return (input & mask) << inputBitStart; +} + +inline unsigned int CountLeadingZeros(uint32_t x) +{ + // Use binary search to find the amount of leading zeros. + unsigned int zeros = 32u; + uint32_t y; + + y = x >> 16u; + if (y != 0) + { + zeros = zeros - 16u; + x = y; + } + y = x >> 8u; + if (y != 0) + { + zeros = zeros - 8u; + x = y; + } + y = x >> 4u; + if (y != 0) + { + zeros = zeros - 4u; + x = y; + } + y = x >> 2u; + if (y != 0) + { + zeros = zeros - 2u; + x = y; + } + y = x >> 1u; + if (y != 0) + { + return zeros - 2u; + } + return zeros - x; +} + +inline unsigned char average(unsigned char a, unsigned char b) +{ + return ((a ^ b) >> 1) + (a & b); +} + +inline signed char average(signed char a, signed char b) +{ + return ((short)a + (short)b) / 2; +} + +inline unsigned short average(unsigned short a, unsigned short b) +{ + return ((a ^ b) >> 1) + (a & b); +} + +inline signed short average(signed short a, signed short b) +{ + return ((int)a + (int)b) / 2; +} + +inline unsigned int average(unsigned int a, unsigned int b) +{ + return ((a ^ b) >> 1) + (a & b); +} + +inline int average(int a, int b) +{ + long long average = (static_cast(a) + static_cast(b)) / 2LL; + return static_cast(average); +} + +inline float average(float a, float b) +{ + return (a + b) * 0.5f; +} + +inline unsigned short averageHalfFloat(unsigned short a, unsigned short b) +{ + return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f); +} + +inline unsigned int averageFloat11(unsigned int a, unsigned int b) +{ + return float32ToFloat11((float11ToFloat32(static_cast(a)) + + float11ToFloat32(static_cast(b))) * + 0.5f); +} + +inline unsigned int averageFloat10(unsigned int a, unsigned int b) +{ + return float32ToFloat10((float10ToFloat32(static_cast(a)) + + float10ToFloat32(static_cast(b))) * + 0.5f); +} + +template +class Range +{ + public: + Range() {} + Range(T lo, T hi) : mLow(lo), mHigh(hi) {} + + T length() const { return (empty() ? 0 : (mHigh - mLow)); } + + bool intersects(Range other) + { + if (mLow <= other.mLow) + { + return other.mLow < mHigh; + } + else + { + return mLow < other.mHigh; + } + } + + // Assumes that end is non-inclusive.. for example, extending to 5 will make "end" 6. + void extend(T value) + { + mLow = value < mLow ? value : mLow; + mHigh = value >= mHigh ? (value + 1) : mHigh; + } + + bool empty() const { return mHigh <= mLow; } + + bool contains(T value) const { return value >= mLow && value < mHigh; } + + class Iterator final + { + public: + Iterator(T value) : mCurrent(value) {} + + Iterator &operator++() + { + mCurrent++; + return *this; + } + bool operator==(const Iterator &other) const { return mCurrent == other.mCurrent; } + bool operator!=(const Iterator &other) const { return mCurrent != other.mCurrent; } + T operator*() const { return mCurrent; } + + private: + T mCurrent; + }; + + Iterator begin() const { return Iterator(mLow); } + + Iterator end() const { return Iterator(mHigh); } + + T low() const { return mLow; } + T high() const { return mHigh; } + + void invalidate() + { + mLow = std::numeric_limits::max(); + mHigh = std::numeric_limits::min(); + } + + private: + T mLow; + T mHigh; +}; + +typedef Range RangeI; +typedef Range RangeUI; + +struct IndexRange +{ + struct Undefined + {}; + IndexRange(Undefined) {} + IndexRange() : IndexRange(0, 0, 0) {} + IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_) + : start(start_), end(end_), vertexIndexCount(vertexIndexCount_) + { + ASSERT(start <= end); + } + + // Number of vertices in the range. + size_t vertexCount() const { return (end - start) + 1; } + + // Inclusive range of indices that are not primitive restart + size_t start; + size_t end; + + // Number of non-primitive restart indices + size_t vertexIndexCount; +}; + +// Combine a floating-point value representing a mantissa (x) and an integer exponent (exp) into a +// floating-point value. As in GLSL ldexp() built-in. +inline float Ldexp(float x, int exp) +{ + if (exp > 128) + { + return std::numeric_limits::infinity(); + } + if (exp < -126) + { + return 0.0f; + } + double result = static_cast(x) * std::pow(2.0, static_cast(exp)); + return static_cast(result); +} + +// First, both normalized floating-point values are converted into 16-bit integer values. +// Then, the results are packed into the returned 32-bit unsigned integer. +// The first float value will be written to the least significant bits of the output; +// the last float value will be written to the most significant bits. +// The conversion of each value to fixed point is done as follows : +// packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0) +inline uint32_t packSnorm2x16(float f1, float f2) +{ + int16_t leastSignificantBits = static_cast(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f)); + int16_t mostSignificantBits = static_cast(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f)); + return static_cast(mostSignificantBits) << 16 | + (static_cast(leastSignificantBits) & 0xFFFF); +} + +// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, +// each component is converted to a normalized floating-point value to generate the returned two +// float values. The first float value will be extracted from the least significant bits of the +// input; the last float value will be extracted from the most-significant bits. The conversion for +// unpacked fixed-point value to floating point is done as follows: unpackSnorm2x16 : clamp(f / +// 32767.0, -1, +1) +inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2) +{ + int16_t leastSignificantBits = static_cast(u & 0xFFFF); + int16_t mostSignificantBits = static_cast(u >> 16); + *f1 = clamp(static_cast(leastSignificantBits) / 32767.0f, -1.0f, 1.0f); + *f2 = clamp(static_cast(mostSignificantBits) / 32767.0f, -1.0f, 1.0f); +} + +// First, both normalized floating-point values are converted into 16-bit integer values. +// Then, the results are packed into the returned 32-bit unsigned integer. +// The first float value will be written to the least significant bits of the output; +// the last float value will be written to the most significant bits. +// The conversion of each value to fixed point is done as follows: +// packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0) +inline uint32_t packUnorm2x16(float f1, float f2) +{ + uint16_t leastSignificantBits = static_cast(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f)); + uint16_t mostSignificantBits = static_cast(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f)); + return static_cast(mostSignificantBits) << 16 | + static_cast(leastSignificantBits); +} + +// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, +// each component is converted to a normalized floating-point value to generate the returned two +// float values. The first float value will be extracted from the least significant bits of the +// input; the last float value will be extracted from the most-significant bits. The conversion for +// unpacked fixed-point value to floating point is done as follows: unpackUnorm2x16 : f / 65535.0 +inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2) +{ + uint16_t leastSignificantBits = static_cast(u & 0xFFFF); + uint16_t mostSignificantBits = static_cast(u >> 16); + *f1 = static_cast(leastSignificantBits) / 65535.0f; + *f2 = static_cast(mostSignificantBits) / 65535.0f; +} + +// Helper functions intended to be used only here. +namespace priv +{ + +inline uint8_t ToPackedUnorm8(float f) +{ + return static_cast(roundf(clamp(f, 0.0f, 1.0f) * 255.0f)); +} + +inline int8_t ToPackedSnorm8(float f) +{ + return static_cast(roundf(clamp(f, -1.0f, 1.0f) * 127.0f)); +} + +} // namespace priv + +// Packs 4 normalized unsigned floating-point values to a single 32-bit unsigned integer. Works +// similarly to packUnorm2x16. The floats are clamped to the range 0.0 to 1.0, and written to the +// unsigned integer starting from the least significant bits. +inline uint32_t PackUnorm4x8(float f1, float f2, float f3, float f4) +{ + uint8_t bits[4]; + bits[0] = priv::ToPackedUnorm8(f1); + bits[1] = priv::ToPackedUnorm8(f2); + bits[2] = priv::ToPackedUnorm8(f3); + bits[3] = priv::ToPackedUnorm8(f4); + uint32_t result = 0u; + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + result |= (static_cast(bits[i]) << shift); + } + return result; +} + +// Unpacks 4 normalized unsigned floating-point values from a single 32-bit unsigned integer into f. +// Works similarly to unpackUnorm2x16. The floats are unpacked starting from the least significant +// bits. +inline void UnpackUnorm4x8(uint32_t u, float *f) +{ + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + uint8_t bits = static_cast((u >> shift) & 0xFF); + f[i] = static_cast(bits) / 255.0f; + } +} + +// Packs 4 normalized signed floating-point values to a single 32-bit unsigned integer. The floats +// are clamped to the range -1.0 to 1.0, and written to the unsigned integer starting from the least +// significant bits. +inline uint32_t PackSnorm4x8(float f1, float f2, float f3, float f4) +{ + int8_t bits[4]; + bits[0] = priv::ToPackedSnorm8(f1); + bits[1] = priv::ToPackedSnorm8(f2); + bits[2] = priv::ToPackedSnorm8(f3); + bits[3] = priv::ToPackedSnorm8(f4); + uint32_t result = 0u; + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + result |= ((static_cast(bits[i]) & 0xFF) << shift); + } + return result; +} + +// Unpacks 4 normalized signed floating-point values from a single 32-bit unsigned integer into f. +// Works similarly to unpackSnorm2x16. The floats are unpacked starting from the least significant +// bits, and clamped to the range -1.0 to 1.0. +inline void UnpackSnorm4x8(uint32_t u, float *f) +{ + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + int8_t bits = static_cast((u >> shift) & 0xFF); + f[i] = clamp(static_cast(bits) / 127.0f, -1.0f, 1.0f); + } +} + +// Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit +// floating-point representation found in the OpenGL ES Specification, and then packing these +// two 16-bit integers into a 32-bit unsigned integer. +// f1: The 16 least-significant bits of the result; +// f2: The 16 most-significant bits. +inline uint32_t packHalf2x16(float f1, float f2) +{ + uint16_t leastSignificantBits = static_cast(float32ToFloat16(f1)); + uint16_t mostSignificantBits = static_cast(float32ToFloat16(f2)); + return static_cast(mostSignificantBits) << 16 | + static_cast(leastSignificantBits); +} + +// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of +// 16-bit values, interpreting those values as 16-bit floating-point numbers according to the OpenGL +// ES Specification, and converting them to 32-bit floating-point values. The first float value is +// obtained from the 16 least-significant bits of u; the second component is obtained from the 16 +// most-significant bits of u. +inline void unpackHalf2x16(uint32_t u, float *f1, float *f2) +{ + uint16_t leastSignificantBits = static_cast(u & 0xFFFF); + uint16_t mostSignificantBits = static_cast(u >> 16); + + *f1 = float16ToFloat32(leastSignificantBits); + *f2 = float16ToFloat32(mostSignificantBits); +} + +inline uint8_t sRGBToLinear(uint8_t srgbValue) +{ + float value = srgbValue / 255.0f; + if (value <= 0.04045f) + { + value = value / 12.92f; + } + else + { + value = std::pow((value + 0.055f) / 1.055f, 2.4f); + } + return static_cast(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f)); +} + +inline uint8_t linearToSRGB(uint8_t linearValue) +{ + float value = linearValue / 255.0f; + if (value <= 0.0f) + { + value = 0.0f; + } + else if (value < 0.0031308f) + { + value = value * 12.92f; + } + else if (value < 1.0f) + { + value = std::pow(value, 0.41666f) * 1.055f - 0.055f; + } + else + { + value = 1.0f; + } + return static_cast(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f)); +} + +// Reverse the order of the bits. +inline uint32_t BitfieldReverse(uint32_t value) +{ + // TODO(oetuaho@nvidia.com): Optimize this if needed. There don't seem to be compiler intrinsics + // for this, and right now it's not used in performance-critical paths. + uint32_t result = 0u; + for (size_t j = 0u; j < 32u; ++j) + { + result |= (((value >> j) & 1u) << (31u - j)); + } + return result; +} + +// Count the 1 bits. +#if defined(_MSC_VER) && !defined(__clang__) +# if defined(_M_IX86) || defined(_M_X64) +namespace priv +{ +// Check POPCNT instruction support and cache the result. +// https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64#remarks +static const bool kHasPopcnt = [] { + int info[4]; + __cpuid(&info[0], 1); + return static_cast(info[2] & 0x800000); +}(); +} // namespace priv + +// Polyfills for x86/x64 CPUs without POPCNT. +// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel +inline int BitCountPolyfill(uint32_t bits) +{ + bits = bits - ((bits >> 1) & 0x55555555); + bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); + bits = ((bits + (bits >> 4) & 0x0F0F0F0F) * 0x01010101) >> 24; + return static_cast(bits); +} + +inline int BitCountPolyfill(uint64_t bits) +{ + bits = bits - ((bits >> 1) & 0x5555555555555555ull); + bits = (bits & 0x3333333333333333ull) + ((bits >> 2) & 0x3333333333333333ull); + bits = ((bits + (bits >> 4) & 0x0F0F0F0F0F0F0F0Full) * 0x0101010101010101ull) >> 56; + return static_cast(bits); +} + +inline int BitCount(uint32_t bits) +{ + if (priv::kHasPopcnt) + { + return static_cast(__popcnt(bits)); + } + return BitCountPolyfill(bits); +} + +inline int BitCount(uint64_t bits) +{ + if (priv::kHasPopcnt) + { +# if defined(_M_X64) + return static_cast(__popcnt64(bits)); +# else // x86 + return static_cast(__popcnt(static_cast(bits >> 32)) + + __popcnt(static_cast(bits))); +# endif // defined(_M_X64) + } + return BitCountPolyfill(bits); +} + +# elif defined(_M_ARM) || defined(_M_ARM64) + +// MSVC's _CountOneBits* intrinsics are not defined for ARM64, moreover they do not use dedicated +// NEON instructions. + +inline int BitCount(uint32_t bits) +{ + // cast bits to 8x8 datatype and use VCNT on it + const uint8x8_t vsum = vcnt_u8(vcreate_u8(static_cast(bits))); + + // pairwise sums: 8x8 -> 16x4 -> 32x2 + return static_cast(vget_lane_u32(vpaddl_u16(vpaddl_u8(vsum)), 0)); +} + +inline int BitCount(uint64_t bits) +{ + // cast bits to 8x8 datatype and use VCNT on it + const uint8x8_t vsum = vcnt_u8(vcreate_u8(bits)); + + // pairwise sums: 8x8 -> 16x4 -> 32x2 -> 64x1 + return static_cast(vget_lane_u64(vpaddl_u32(vpaddl_u16(vpaddl_u8(vsum))), 0)); +} +# endif // defined(_M_IX86) || defined(_M_X64) +#endif // defined(_MSC_VER) && !defined(__clang__) + +#if defined(ANGLE_PLATFORM_POSIX) || defined(__clang__) +inline int BitCount(uint32_t bits) +{ + return __builtin_popcount(bits); +} + +inline int BitCount(uint64_t bits) +{ + return __builtin_popcountll(bits); +} +#endif // defined(ANGLE_PLATFORM_POSIX) || defined(__clang__) + +inline int BitCount(uint8_t bits) +{ + return BitCount(static_cast(bits)); +} + +inline int BitCount(uint16_t bits) +{ + return BitCount(static_cast(bits)); +} + +#if defined(ANGLE_PLATFORM_WINDOWS) +// Return the index of the least significant bit set. Indexing is such that bit 0 is the least +// significant bit. Implemented for different bit widths on different platforms. +inline unsigned long ScanForward(uint32_t bits) +{ + ASSERT(bits != 0u); + unsigned long firstBitIndex = 0ul; + unsigned char ret = _BitScanForward(&firstBitIndex, bits); + ASSERT(ret != 0u); + return firstBitIndex; +} + +inline unsigned long ScanForward(uint64_t bits) +{ + ASSERT(bits != 0u); + unsigned long firstBitIndex = 0ul; +# if defined(ANGLE_IS_64_BIT_CPU) + unsigned char ret = _BitScanForward64(&firstBitIndex, bits); +# else + unsigned char ret; + if (static_cast(bits) == 0) + { + ret = _BitScanForward(&firstBitIndex, static_cast(bits >> 32)); + firstBitIndex += 32ul; + } + else + { + ret = _BitScanForward(&firstBitIndex, static_cast(bits)); + } +# endif // defined(ANGLE_IS_64_BIT_CPU) + ASSERT(ret != 0u); + return firstBitIndex; +} + +// Return the index of the most significant bit set. Indexing is such that bit 0 is the least +// significant bit. +inline unsigned long ScanReverse(uint32_t bits) +{ + ASSERT(bits != 0u); + unsigned long lastBitIndex = 0ul; + unsigned char ret = _BitScanReverse(&lastBitIndex, bits); + ASSERT(ret != 0u); + return lastBitIndex; +} + +inline unsigned long ScanReverse(uint64_t bits) +{ + ASSERT(bits != 0u); + unsigned long lastBitIndex = 0ul; +# if defined(ANGLE_IS_64_BIT_CPU) + unsigned char ret = _BitScanReverse64(&lastBitIndex, bits); +# else + unsigned char ret; + if (static_cast(bits >> 32) == 0) + { + ret = _BitScanReverse(&lastBitIndex, static_cast(bits)); + } + else + { + ret = _BitScanReverse(&lastBitIndex, static_cast(bits >> 32)); + lastBitIndex += 32ul; + } +# endif // defined(ANGLE_IS_64_BIT_CPU) + ASSERT(ret != 0u); + return lastBitIndex; +} +#endif // defined(ANGLE_PLATFORM_WINDOWS) + +#if defined(ANGLE_PLATFORM_POSIX) +inline unsigned long ScanForward(uint32_t bits) +{ + ASSERT(bits != 0u); + return static_cast(__builtin_ctz(bits)); +} + +inline unsigned long ScanForward(uint64_t bits) +{ + ASSERT(bits != 0u); +# if defined(ANGLE_IS_64_BIT_CPU) + return static_cast(__builtin_ctzll(bits)); +# else + return static_cast(static_cast(bits) == 0 + ? __builtin_ctz(static_cast(bits >> 32)) + 32 + : __builtin_ctz(static_cast(bits))); +# endif // defined(ANGLE_IS_64_BIT_CPU) +} + +inline unsigned long ScanReverse(uint32_t bits) +{ + ASSERT(bits != 0u); + return static_cast(sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(bits)); +} + +inline unsigned long ScanReverse(uint64_t bits) +{ + ASSERT(bits != 0u); +# if defined(ANGLE_IS_64_BIT_CPU) + return static_cast(sizeof(uint64_t) * CHAR_BIT - 1 - __builtin_clzll(bits)); +# else + if (static_cast(bits >> 32) == 0) + { + return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast(bits)); + } + else + { + return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast(bits >> 32)) + + 32; + } +# endif // defined(ANGLE_IS_64_BIT_CPU) +} +#endif // defined(ANGLE_PLATFORM_POSIX) + +inline unsigned long ScanForward(uint8_t bits) +{ + return ScanForward(static_cast(bits)); +} + +inline unsigned long ScanForward(uint16_t bits) +{ + return ScanForward(static_cast(bits)); +} + +inline unsigned long ScanReverse(uint8_t bits) +{ + return ScanReverse(static_cast(bits)); +} + +inline unsigned long ScanReverse(uint16_t bits) +{ + return ScanReverse(static_cast(bits)); +} + +// Returns -1 on 0, otherwise the index of the least significant 1 bit as in GLSL. +template +int FindLSB(T bits) +{ + static_assert(std::is_integral::value, "must be integral type."); + if (bits == 0u) + { + return -1; + } + else + { + return static_cast(ScanForward(bits)); + } +} + +// Returns -1 on 0, otherwise the index of the most significant 1 bit as in GLSL. +template +int FindMSB(T bits) +{ + static_assert(std::is_integral::value, "must be integral type."); + if (bits == 0u) + { + return -1; + } + else + { + return static_cast(ScanReverse(bits)); + } +} + +// Returns whether the argument is Not a Number. +// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - +// non-zero. +inline bool isNaN(float f) +{ + // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u + // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu + return ((bitCast(f) & 0x7f800000u) == 0x7f800000u) && + (bitCast(f) & 0x7fffffu); +} + +// Returns whether the argument is infinity. +// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - +// zero. +inline bool isInf(float f) +{ + // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u + // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu + return ((bitCast(f) & 0x7f800000u) == 0x7f800000u) && + !(bitCast(f) & 0x7fffffu); +} + +namespace priv +{ +template +struct iSquareRoot +{ + static constexpr unsigned int solve() + { + return (R * R > N) + ? 0 + : ((R * R == N) ? R : static_cast(iSquareRoot::value)); + } + enum Result + { + value = iSquareRoot::solve() + }; +}; + +template +struct iSquareRoot +{ + enum result + { + value = N + }; +}; + +} // namespace priv + +template +constexpr unsigned int iSquareRoot() +{ + return priv::iSquareRoot::value; +} + +// Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow. +// +// Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow +// behavior is undefined. + +template +inline T WrappingSum(T lhs, T rhs) +{ + uint32_t lhsUnsigned = static_cast(lhs); + uint32_t rhsUnsigned = static_cast(rhs); + return static_cast(lhsUnsigned + rhsUnsigned); +} + +template +inline T WrappingDiff(T lhs, T rhs) +{ + uint32_t lhsUnsigned = static_cast(lhs); + uint32_t rhsUnsigned = static_cast(rhs); + return static_cast(lhsUnsigned - rhsUnsigned); +} + +inline int32_t WrappingMul(int32_t lhs, int32_t rhs) +{ + int64_t lhsWide = static_cast(lhs); + int64_t rhsWide = static_cast(rhs); + // The multiplication is guaranteed not to overflow. + int64_t resultWide = lhsWide * rhsWide; + // Implement the desired wrapping behavior by masking out the high-order 32 bits. + resultWide = resultWide & 0xffffffffLL; + // Casting to a narrower signed type is fine since the casted value is representable in the + // narrower type. + return static_cast(resultWide); +} + +inline float scaleScreenDimensionToNdc(float dimensionScreen, float viewportDimension) +{ + return 2.0f * dimensionScreen / viewportDimension; +} + +inline float scaleScreenCoordinateToNdc(float coordinateScreen, float viewportDimension) +{ + float halfShifted = coordinateScreen / viewportDimension; + return 2.0f * (halfShifted - 0.5f); +} + +} // namespace gl + +namespace rx +{ + +template +T roundUp(const T value, const T alignment) +{ + auto temp = value + alignment - static_cast(1); + return temp - temp % alignment; +} + +template +constexpr T roundUpPow2(const T value, const T alignment) +{ + ASSERT(gl::isPow2(alignment)); + return (value + alignment - 1) & ~(alignment - 1); +} + +template +constexpr T roundDownPow2(const T value, const T alignment) +{ + ASSERT(gl::isPow2(alignment)); + return value & ~(alignment - 1); +} + +template +angle::CheckedNumeric CheckedRoundUp(const T value, const T alignment) +{ + angle::CheckedNumeric checkedValue(value); + angle::CheckedNumeric checkedAlignment(alignment); + return roundUp(checkedValue, checkedAlignment); +} + +inline constexpr unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor) +{ + unsigned int divided = value / divisor; + return (divided + ((value % divisor == 0) ? 0 : 1)); +} + +#if defined(__has_builtin) +# define ANGLE_HAS_BUILTIN(x) __has_builtin(x) +#else +# define ANGLE_HAS_BUILTIN(x) 0 +#endif + +#if defined(_MSC_VER) + +# define ANGLE_ROTL(x, y) _rotl(x, y) +# define ANGLE_ROTL64(x, y) _rotl64(x, y) +# define ANGLE_ROTR16(x, y) _rotr16(x, y) + +#elif defined(__clang__) && ANGLE_HAS_BUILTIN(__builtin_rotateleft32) && \ + ANGLE_HAS_BUILTIN(__builtin_rotateleft64) && ANGLE_HAS_BUILTIN(__builtin_rotateright16) + +# define ANGLE_ROTL(x, y) __builtin_rotateleft32(x, y) +# define ANGLE_ROTL64(x, y) __builtin_rotateleft64(x, y) +# define ANGLE_ROTR16(x, y) __builtin_rotateright16(x, y) + +#else + +inline uint32_t RotL(uint32_t x, int8_t r) +{ + return (x << r) | (x >> (32 - r)); +} + +inline uint64_t RotL64(uint64_t x, int8_t r) +{ + return (x << r) | (x >> (64 - r)); +} + +inline uint16_t RotR16(uint16_t x, int8_t r) +{ + return (x >> r) | (x << (16 - r)); +} + +# define ANGLE_ROTL(x, y) ::rx::RotL(x, y) +# define ANGLE_ROTL64(x, y) ::rx::RotL64(x, y) +# define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y) + +#endif // namespace rx + +constexpr unsigned int Log2(unsigned int bytes) +{ + return bytes == 1 ? 0 : (1 + Log2(bytes / 2)); +} +} // namespace rx + +#endif // COMMON_MATHUTIL_H_ diff --git a/gfx/angle/checkout/src/common/matrix_utils.cpp b/gfx/angle/checkout/src/common/matrix_utils.cpp new file mode 100644 index 0000000000..59ab4ca437 --- /dev/null +++ b/gfx/angle/checkout/src/common/matrix_utils.cpp @@ -0,0 +1,285 @@ +// +// Copyright 2018 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. +// + +// matrix_utils.cpp: Contains implementations for Mat4 methods. + +#include "common/matrix_utils.h" + +namespace angle +{ + +Mat4::Mat4() : Mat4(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f) +{} + +Mat4::Mat4(const Matrix generalMatrix) : Matrix(std::vector(16, 0), 4, 4) +{ + unsigned int minCols = std::min((unsigned int)4, generalMatrix.columns()); + unsigned int minRows = std::min((unsigned int)4, generalMatrix.rows()); + for (unsigned int i = 0; i < minCols; i++) + { + for (unsigned int j = 0; j < minRows; j++) + { + mElements[j * minCols + i] = generalMatrix.at(j, i); + } + } +} + +Mat4::Mat4(const std::vector &elements) : Matrix(elements, 4) {} + +Mat4::Mat4(const float *elements) : Matrix(elements, 4) {} + +Mat4::Mat4(float m00, + float m01, + float m02, + float m03, + float m10, + float m11, + float m12, + float m13, + float m20, + float m21, + float m22, + float m23, + float m30, + float m31, + float m32, + float m33) + : Matrix(std::vector(16, 0), 4, 4) +{ + mElements[0] = m00; + mElements[1] = m01; + mElements[2] = m02; + mElements[3] = m03; + mElements[4] = m10; + mElements[5] = m11; + mElements[6] = m12; + mElements[7] = m13; + mElements[8] = m20; + mElements[9] = m21; + mElements[10] = m22; + mElements[11] = m23; + mElements[12] = m30; + mElements[13] = m31; + mElements[14] = m32; + mElements[15] = m33; +} + +// static +Mat4 Mat4::Rotate(float angle, const Vector3 &axis) +{ + auto axis_normalized = axis.normalized(); + float angle_radians = angle * (3.14159265358979323f / 180.0f); + float c = cos(angle_radians); + float ci = 1.f - c; + float s = sin(angle_radians); + + float x = axis_normalized.x(); + float y = axis_normalized.y(); + float z = axis_normalized.z(); + + float x2 = x * x; + float y2 = y * y; + float z2 = z * z; + + float xy = x * y; + float yz = y * z; + float zx = z * x; + + float r00 = c + ci * x2; + float r01 = ci * xy + s * z; + float r02 = ci * zx - s * y; + float r03 = 0.f; + + float r10 = ci * xy - s * z; + float r11 = c + ci * y2; + float r12 = ci * yz + s * x; + float r13 = 0.f; + + float r20 = ci * zx + s * y; + float r21 = ci * yz - s * x; + float r22 = c + ci * z2; + float r23 = 0.f; + + float r30 = 0.f; + float r31 = 0.f; + float r32 = 0.f; + float r33 = 1.f; + + return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); +} + +// static +Mat4 Mat4::Translate(const Vector3 &t) +{ + float r00 = 1.f; + float r01 = 0.f; + float r02 = 0.f; + float r03 = 0.f; + + float r10 = 0.f; + float r11 = 1.f; + float r12 = 0.f; + float r13 = 0.f; + + float r20 = 0.f; + float r21 = 0.f; + float r22 = 1.f; + float r23 = 0.f; + + float r30 = t.x(); + float r31 = t.y(); + float r32 = t.z(); + float r33 = 1.f; + + return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); +} + +// static +Mat4 Mat4::Scale(const Vector3 &s) +{ + float r00 = s.x(); + float r01 = 0.f; + float r02 = 0.f; + float r03 = 0.f; + + float r10 = 0.f; + float r11 = s.y(); + float r12 = 0.f; + float r13 = 0.f; + + float r20 = 0.f; + float r21 = 0.f; + float r22 = s.z(); + float r23 = 0.f; + + float r30 = 0.f; + float r31 = 0.f; + float r32 = 0.f; + float r33 = 1.f; + + return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); +} + +// static +Mat4 Mat4::Frustum(float l, float r, float b, float t, float n, float f) +{ + float nn = 2.f * n; + float fpn = f + n; + float fmn = f - n; + float tpb = t + b; + float tmb = t - b; + float rpl = r + l; + float rml = r - l; + + float r00 = nn / rml; + float r01 = 0.f; + float r02 = 0.f; + float r03 = 0.f; + + float r10 = 0.f; + float r11 = nn / tmb; + float r12 = 0.f; + float r13 = 0.f; + + float r20 = rpl / rml; + float r21 = tpb / tmb; + float r22 = -fpn / fmn; + float r23 = -1.f; + + float r30 = 0.f; + float r31 = 0.f; + float r32 = -nn * f / fmn; + float r33 = 0.f; + + return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); +} + +// static +Mat4 Mat4::Perspective(float fov, float aspectRatio, float n, float f) +{ + const float frustumHeight = tanf(static_cast(fov / 360.0f * 3.14159265358979323)) * n; + const float frustumWidth = frustumHeight * aspectRatio; + return Frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, n, f); +} + +// static +Mat4 Mat4::Ortho(float l, float r, float b, float t, float n, float f) +{ + float fpn = f + n; + float fmn = f - n; + float tpb = t + b; + float tmb = t - b; + float rpl = r + l; + float rml = r - l; + + float r00 = 2.f / rml; + float r01 = 0.f; + float r02 = 0.f; + float r03 = 0.f; + + float r10 = 0.f; + float r11 = 2.f / tmb; + float r12 = 0.f; + float r13 = 0.f; + + float r20 = 0.f; + float r21 = 0.f; + float r22 = -2.f / fmn; + float r23 = 0.f; + + float r30 = -rpl / rml; + float r31 = -tpb / tmb; + float r32 = -fpn / fmn; + float r33 = 1.f; + + return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33); +} + +Mat4 Mat4::product(const Mat4 &m) +{ + const float *a = mElements.data(); + const float *b = m.mElements.data(); + + return Mat4(a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3], + a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3], + a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3], + a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3], + + a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7], + a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7], + a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7], + a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7], + + a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11], + a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11], + a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11], + a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11], + + a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15], + a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15], + a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15], + a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]); +} + +Vector4 Mat4::product(const Vector4 &b) +{ + return Vector4( + mElements[0] * b.x() + mElements[4] * b.y() + mElements[8] * b.z() + mElements[12] * b.w(), + mElements[1] * b.x() + mElements[5] * b.y() + mElements[9] * b.z() + mElements[13] * b.w(), + mElements[2] * b.x() + mElements[6] * b.y() + mElements[10] * b.z() + mElements[14] * b.w(), + mElements[3] * b.x() + mElements[7] * b.y() + mElements[11] * b.z() + + mElements[15] * b.w()); +} + +void Mat4::dump() +{ + printf("[ %f %f %f %f ]\n", mElements[0], mElements[4], mElements[8], mElements[12]); + printf("[ %f %f %f %f ]\n", mElements[1], mElements[5], mElements[9], mElements[13]); + printf("[ %f %f %f %f ]\n", mElements[2], mElements[6], mElements[10], mElements[14]); + printf("[ %f %f %f %f ]\n", mElements[3], mElements[7], mElements[11], mElements[15]); +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/matrix_utils.h b/gfx/angle/checkout/src/common/matrix_utils.h new file mode 100644 index 0000000000..7cca7a9461 --- /dev/null +++ b/gfx/angle/checkout/src/common/matrix_utils.h @@ -0,0 +1,424 @@ +// +// Copyright 2015 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. +// +// Matrix: +// Utility class implementing various matrix operations. +// Supports matrices with minimum 2 and maximum 4 number of rows/columns. +// +// TODO: Check if we can merge Matrix.h in sample_util with this and replace it with this +// implementation. +// TODO: Rename this file to Matrix.h once we remove Matrix.h in sample_util. + +#ifndef COMMON_MATRIX_UTILS_H_ +#define COMMON_MATRIX_UTILS_H_ + +#include + +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/vector_utils.h" + +namespace angle +{ + +template +class Matrix +{ + public: + Matrix(const std::vector &elements, const unsigned int numRows, const unsigned int numCols) + : mElements(elements), mRows(numRows), mCols(numCols) + { + ASSERT(rows() >= 1 && rows() <= 4); + ASSERT(columns() >= 1 && columns() <= 4); + } + + Matrix(const std::vector &elements, const unsigned int size) + : mElements(elements), mRows(size), mCols(size) + { + ASSERT(rows() >= 1 && rows() <= 4); + ASSERT(columns() >= 1 && columns() <= 4); + } + + Matrix(const T *elements, const unsigned int size) : mRows(size), mCols(size) + { + ASSERT(rows() >= 1 && rows() <= 4); + ASSERT(columns() >= 1 && columns() <= 4); + for (size_t i = 0; i < size * size; i++) + mElements.push_back(elements[i]); + } + + const T &operator()(const unsigned int rowIndex, const unsigned int columnIndex) const + { + ASSERT(rowIndex < mRows); + ASSERT(columnIndex < mCols); + return mElements[rowIndex * columns() + columnIndex]; + } + + T &operator()(const unsigned int rowIndex, const unsigned int columnIndex) + { + ASSERT(rowIndex < mRows); + ASSERT(columnIndex < mCols); + return mElements[rowIndex * columns() + columnIndex]; + } + + const T &at(const unsigned int rowIndex, const unsigned int columnIndex) const + { + ASSERT(rowIndex < mRows); + ASSERT(columnIndex < mCols); + return operator()(rowIndex, columnIndex); + } + + Matrix operator*(const Matrix &m) + { + ASSERT(columns() == m.rows()); + + unsigned int resultRows = rows(); + unsigned int resultCols = m.columns(); + Matrix result(std::vector(resultRows * resultCols), resultRows, resultCols); + for (unsigned int i = 0; i < resultRows; i++) + { + for (unsigned int j = 0; j < resultCols; j++) + { + T tmp = 0.0f; + for (unsigned int k = 0; k < columns(); k++) + tmp += at(i, k) * m(k, j); + result(i, j) = tmp; + } + } + + return result; + } + + void operator*=(const Matrix &m) + { + ASSERT(columns() == m.rows()); + Matrix res = (*this) * m; + size_t numElts = res.elements().size(); + mElements.resize(numElts); + memcpy(mElements.data(), res.data(), numElts * sizeof(float)); + } + + bool operator==(const Matrix &m) const + { + ASSERT(columns() == m.columns()); + ASSERT(rows() == m.rows()); + return mElements == m.elements(); + } + + bool operator!=(const Matrix &m) const { return !(mElements == m.elements()); } + + bool nearlyEqual(T epsilon, const Matrix &m) const + { + ASSERT(columns() == m.columns()); + ASSERT(rows() == m.rows()); + const auto &otherElts = m.elements(); + for (size_t i = 0; i < otherElts.size(); i++) + { + if ((mElements[i] - otherElts[i] > epsilon) && (otherElts[i] - mElements[i] > epsilon)) + return false; + } + return true; + } + + unsigned int size() const + { + ASSERT(rows() == columns()); + return rows(); + } + + unsigned int rows() const { return mRows; } + + unsigned int columns() const { return mCols; } + + std::vector elements() const { return mElements; } + T *data() { return mElements.data(); } + const T *constData() const { return mElements.data(); } + + Matrix compMult(const Matrix &mat1) const + { + Matrix result(std::vector(mElements.size()), rows(), columns()); + for (unsigned int i = 0; i < rows(); i++) + { + for (unsigned int j = 0; j < columns(); j++) + { + T lhs = at(i, j); + T rhs = mat1(i, j); + result(i, j) = rhs * lhs; + } + } + + return result; + } + + Matrix outerProduct(const Matrix &mat1) const + { + unsigned int cols = mat1.columns(); + Matrix result(std::vector(rows() * cols), rows(), cols); + for (unsigned int i = 0; i < rows(); i++) + for (unsigned int j = 0; j < cols; j++) + result(i, j) = at(i, 0) * mat1(0, j); + + return result; + } + + Matrix transpose() const + { + Matrix result(std::vector(mElements.size()), columns(), rows()); + for (unsigned int i = 0; i < columns(); i++) + for (unsigned int j = 0; j < rows(); j++) + result(i, j) = at(j, i); + + return result; + } + + T determinant() const + { + ASSERT(rows() == columns()); + + switch (size()) + { + case 2: + return at(0, 0) * at(1, 1) - at(0, 1) * at(1, 0); + + case 3: + return at(0, 0) * at(1, 1) * at(2, 2) + at(0, 1) * at(1, 2) * at(2, 0) + + at(0, 2) * at(1, 0) * at(2, 1) - at(0, 2) * at(1, 1) * at(2, 0) - + at(0, 1) * at(1, 0) * at(2, 2) - at(0, 0) * at(1, 2) * at(2, 1); + + case 4: + { + const float minorMatrices[4][3 * 3] = {{ + at(1, 1), + at(2, 1), + at(3, 1), + at(1, 2), + at(2, 2), + at(3, 2), + at(1, 3), + at(2, 3), + at(3, 3), + }, + { + at(1, 0), + at(2, 0), + at(3, 0), + at(1, 2), + at(2, 2), + at(3, 2), + at(1, 3), + at(2, 3), + at(3, 3), + }, + { + at(1, 0), + at(2, 0), + at(3, 0), + at(1, 1), + at(2, 1), + at(3, 1), + at(1, 3), + at(2, 3), + at(3, 3), + }, + { + at(1, 0), + at(2, 0), + at(3, 0), + at(1, 1), + at(2, 1), + at(3, 1), + at(1, 2), + at(2, 2), + at(3, 2), + }}; + return at(0, 0) * Matrix(minorMatrices[0], 3).determinant() - + at(0, 1) * Matrix(minorMatrices[1], 3).determinant() + + at(0, 2) * Matrix(minorMatrices[2], 3).determinant() - + at(0, 3) * Matrix(minorMatrices[3], 3).determinant(); + } + + default: + UNREACHABLE(); + break; + } + + return T(); + } + + Matrix inverse() const + { + ASSERT(rows() == columns()); + + Matrix cof(std::vector(mElements.size()), rows(), columns()); + switch (size()) + { + case 2: + cof(0, 0) = at(1, 1); + cof(0, 1) = -at(1, 0); + cof(1, 0) = -at(0, 1); + cof(1, 1) = at(0, 0); + break; + + case 3: + cof(0, 0) = at(1, 1) * at(2, 2) - at(2, 1) * at(1, 2); + cof(0, 1) = -(at(1, 0) * at(2, 2) - at(2, 0) * at(1, 2)); + cof(0, 2) = at(1, 0) * at(2, 1) - at(2, 0) * at(1, 1); + cof(1, 0) = -(at(0, 1) * at(2, 2) - at(2, 1) * at(0, 2)); + cof(1, 1) = at(0, 0) * at(2, 2) - at(2, 0) * at(0, 2); + cof(1, 2) = -(at(0, 0) * at(2, 1) - at(2, 0) * at(0, 1)); + cof(2, 0) = at(0, 1) * at(1, 2) - at(1, 1) * at(0, 2); + cof(2, 1) = -(at(0, 0) * at(1, 2) - at(1, 0) * at(0, 2)); + cof(2, 2) = at(0, 0) * at(1, 1) - at(1, 0) * at(0, 1); + break; + + case 4: + cof(0, 0) = at(1, 1) * at(2, 2) * at(3, 3) + at(2, 1) * at(3, 2) * at(1, 3) + + at(3, 1) * at(1, 2) * at(2, 3) - at(1, 1) * at(3, 2) * at(2, 3) - + at(2, 1) * at(1, 2) * at(3, 3) - at(3, 1) * at(2, 2) * at(1, 3); + cof(0, 1) = -(at(1, 0) * at(2, 2) * at(3, 3) + at(2, 0) * at(3, 2) * at(1, 3) + + at(3, 0) * at(1, 2) * at(2, 3) - at(1, 0) * at(3, 2) * at(2, 3) - + at(2, 0) * at(1, 2) * at(3, 3) - at(3, 0) * at(2, 2) * at(1, 3)); + cof(0, 2) = at(1, 0) * at(2, 1) * at(3, 3) + at(2, 0) * at(3, 1) * at(1, 3) + + at(3, 0) * at(1, 1) * at(2, 3) - at(1, 0) * at(3, 1) * at(2, 3) - + at(2, 0) * at(1, 1) * at(3, 3) - at(3, 0) * at(2, 1) * at(1, 3); + cof(0, 3) = -(at(1, 0) * at(2, 1) * at(3, 2) + at(2, 0) * at(3, 1) * at(1, 2) + + at(3, 0) * at(1, 1) * at(2, 2) - at(1, 0) * at(3, 1) * at(2, 2) - + at(2, 0) * at(1, 1) * at(3, 2) - at(3, 0) * at(2, 1) * at(1, 2)); + cof(1, 0) = -(at(0, 1) * at(2, 2) * at(3, 3) + at(2, 1) * at(3, 2) * at(0, 3) + + at(3, 1) * at(0, 2) * at(2, 3) - at(0, 1) * at(3, 2) * at(2, 3) - + at(2, 1) * at(0, 2) * at(3, 3) - at(3, 1) * at(2, 2) * at(0, 3)); + cof(1, 1) = at(0, 0) * at(2, 2) * at(3, 3) + at(2, 0) * at(3, 2) * at(0, 3) + + at(3, 0) * at(0, 2) * at(2, 3) - at(0, 0) * at(3, 2) * at(2, 3) - + at(2, 0) * at(0, 2) * at(3, 3) - at(3, 0) * at(2, 2) * at(0, 3); + cof(1, 2) = -(at(0, 0) * at(2, 1) * at(3, 3) + at(2, 0) * at(3, 1) * at(0, 3) + + at(3, 0) * at(0, 1) * at(2, 3) - at(0, 0) * at(3, 1) * at(2, 3) - + at(2, 0) * at(0, 1) * at(3, 3) - at(3, 0) * at(2, 1) * at(0, 3)); + cof(1, 3) = at(0, 0) * at(2, 1) * at(3, 2) + at(2, 0) * at(3, 1) * at(0, 2) + + at(3, 0) * at(0, 1) * at(2, 2) - at(0, 0) * at(3, 1) * at(2, 2) - + at(2, 0) * at(0, 1) * at(3, 2) - at(3, 0) * at(2, 1) * at(0, 2); + cof(2, 0) = at(0, 1) * at(1, 2) * at(3, 3) + at(1, 1) * at(3, 2) * at(0, 3) + + at(3, 1) * at(0, 2) * at(1, 3) - at(0, 1) * at(3, 2) * at(1, 3) - + at(1, 1) * at(0, 2) * at(3, 3) - at(3, 1) * at(1, 2) * at(0, 3); + cof(2, 1) = -(at(0, 0) * at(1, 2) * at(3, 3) + at(1, 0) * at(3, 2) * at(0, 3) + + at(3, 0) * at(0, 2) * at(1, 3) - at(0, 0) * at(3, 2) * at(1, 3) - + at(1, 0) * at(0, 2) * at(3, 3) - at(3, 0) * at(1, 2) * at(0, 3)); + cof(2, 2) = at(0, 0) * at(1, 1) * at(3, 3) + at(1, 0) * at(3, 1) * at(0, 3) + + at(3, 0) * at(0, 1) * at(1, 3) - at(0, 0) * at(3, 1) * at(1, 3) - + at(1, 0) * at(0, 1) * at(3, 3) - at(3, 0) * at(1, 1) * at(0, 3); + cof(2, 3) = -(at(0, 0) * at(1, 1) * at(3, 2) + at(1, 0) * at(3, 1) * at(0, 2) + + at(3, 0) * at(0, 1) * at(1, 2) - at(0, 0) * at(3, 1) * at(1, 2) - + at(1, 0) * at(0, 1) * at(3, 2) - at(3, 0) * at(1, 1) * at(0, 2)); + cof(3, 0) = -(at(0, 1) * at(1, 2) * at(2, 3) + at(1, 1) * at(2, 2) * at(0, 3) + + at(2, 1) * at(0, 2) * at(1, 3) - at(0, 1) * at(2, 2) * at(1, 3) - + at(1, 1) * at(0, 2) * at(2, 3) - at(2, 1) * at(1, 2) * at(0, 3)); + cof(3, 1) = at(0, 0) * at(1, 2) * at(2, 3) + at(1, 0) * at(2, 2) * at(0, 3) + + at(2, 0) * at(0, 2) * at(1, 3) - at(0, 0) * at(2, 2) * at(1, 3) - + at(1, 0) * at(0, 2) * at(2, 3) - at(2, 0) * at(1, 2) * at(0, 3); + cof(3, 2) = -(at(0, 0) * at(1, 1) * at(2, 3) + at(1, 0) * at(2, 1) * at(0, 3) + + at(2, 0) * at(0, 1) * at(1, 3) - at(0, 0) * at(2, 1) * at(1, 3) - + at(1, 0) * at(0, 1) * at(2, 3) - at(2, 0) * at(1, 1) * at(0, 3)); + cof(3, 3) = at(0, 0) * at(1, 1) * at(2, 2) + at(1, 0) * at(2, 1) * at(0, 2) + + at(2, 0) * at(0, 1) * at(1, 2) - at(0, 0) * at(2, 1) * at(1, 2) - + at(1, 0) * at(0, 1) * at(2, 2) - at(2, 0) * at(1, 1) * at(0, 2); + break; + + default: + UNREACHABLE(); + break; + } + + // The inverse of A is the transpose of the cofactor matrix times the reciprocal of the + // determinant of A. + Matrix adjugateMatrix(cof.transpose()); + T det = determinant(); + Matrix result(std::vector(mElements.size()), rows(), columns()); + for (unsigned int i = 0; i < rows(); i++) + for (unsigned int j = 0; j < columns(); j++) + result(i, j) = (det != static_cast(0)) ? adjugateMatrix(i, j) / det : T(); + + return result; + } + + void setToIdentity() + { + ASSERT(rows() == columns()); + + const auto one = T(1); + const auto zero = T(0); + + for (auto &e : mElements) + e = zero; + + for (unsigned int i = 0; i < rows(); ++i) + { + const auto pos = i * columns() + (i % columns()); + mElements[pos] = one; + } + } + + template + static void setToIdentity(T (&matrix)[Size]) + { + static_assert(gl::iSquareRoot() != 0, "Matrix is not square."); + + const auto cols = gl::iSquareRoot(); + const auto one = T(1); + const auto zero = T(0); + + for (auto &e : matrix) + e = zero; + + for (unsigned int i = 0; i < cols; ++i) + { + const auto pos = i * cols + (i % cols); + matrix[pos] = one; + } + } + + protected: + std::vector mElements; + unsigned int mRows; + unsigned int mCols; +}; + +class Mat4 : public Matrix +{ + public: + Mat4(); + Mat4(const Matrix generalMatrix); + Mat4(const std::vector &elements); + Mat4(const float *elements); + Mat4(float m00, + float m01, + float m02, + float m03, + float m10, + float m11, + float m12, + float m13, + float m20, + float m21, + float m22, + float m23, + float m30, + float m31, + float m32, + float m33); + + static Mat4 Rotate(float angle, const Vector3 &axis); + static Mat4 Translate(const Vector3 &t); + static Mat4 Scale(const Vector3 &s); + static Mat4 Frustum(float l, float r, float b, float t, float n, float f); + static Mat4 Perspective(float fov, float aspectRatio, float n, float f); + static Mat4 Ortho(float l, float r, float b, float t, float n, float f); + + Mat4 product(const Mat4 &m); + Vector4 product(const Vector4 &b); + void dump(); +}; + +} // namespace angle + +#endif // COMMON_MATRIX_UTILS_H_ diff --git a/gfx/angle/checkout/src/common/platform.h b/gfx/angle/checkout/src/common/platform.h new file mode 100644 index 0000000000..77267ab680 --- /dev/null +++ b/gfx/angle/checkout/src/common/platform.h @@ -0,0 +1,209 @@ +// +// Copyright 2014 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. +// + +// platform.h: Operating system specific includes and defines. + +#ifndef COMMON_PLATFORM_H_ +#define COMMON_PLATFORM_H_ + +#if defined(_WIN32) +# define ANGLE_PLATFORM_WINDOWS 1 +#elif defined(__Fuchsia__) +# define ANGLE_PLATFORM_FUCHSIA 1 +# define ANGLE_PLATFORM_POSIX 1 +#elif defined(__APPLE__) +# define ANGLE_PLATFORM_APPLE 1 +# define ANGLE_PLATFORM_POSIX 1 +#elif defined(ANDROID) +# define ANGLE_PLATFORM_ANDROID 1 +# define ANGLE_PLATFORM_POSIX 1 +#elif defined(__ggp__) +# define ANGLE_PLATFORM_GGP 1 +# define ANGLE_PLATFORM_POSIX 1 +#elif defined(__linux__) || defined(EMSCRIPTEN) +# define ANGLE_PLATFORM_LINUX 1 +# define ANGLE_PLATFORM_POSIX 1 +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ + defined(__DragonFly__) || defined(__sun) || defined(__GLIBC__) || defined(__GNU__) || \ + defined(__QNX__) || defined(__Fuchsia__) || defined(__HAIKU__) +# define ANGLE_PLATFORM_POSIX 1 +#else +# error Unsupported platform. +#endif + +#ifdef ANGLE_PLATFORM_WINDOWS +# ifndef STRICT +# define STRICT 1 +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# ifndef NOMINMAX +# define NOMINMAX 1 +# endif + +# include + +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) +# define ANGLE_ENABLE_WINDOWS_UWP 1 +# endif + +# if defined(ANGLE_ENABLE_D3D9) +# include +# include +# endif + +// Include D3D11 headers when OpenGL is enabled on Windows for interop extensions. +# if defined(ANGLE_ENABLE_D3D11) || defined(ANGLE_ENABLE_OPENGL) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif + +# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) +# include +# endif + +# if defined(ANGLE_ENABLE_WINDOWS_UWP) +# include +# if defined(_DEBUG) +# include +# include +# endif +# endif + +// Include to ensure tests related files can be built when building +// vulkan only backend ANGLE on windows. +# if defined(ANGLE_ENABLE_VULKAN) +# include +# endif + +// Macros 'near', 'far', 'NEAR' and 'FAR' are defined by 'shared/minwindef.h' in the Windows SDK. +// Macros 'near' and 'far' are empty. They are not used by other Windows headers and are undefined +// here to avoid identifier conflicts. Macros 'NEAR' and 'FAR' contain 'near' and 'far'. They are +// used by other Windows headers and are cleared here to avoid compilation errors. +# undef near +# undef far +# undef NEAR +# undef FAR +# define NEAR +# define FAR +#endif + +#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) +# include +# define ANGLE_USE_SSE +#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) +# include +# define ANGLE_USE_SSE +#endif + +// Mips and arm devices need to include stddef for size_t. +#if defined(__mips__) || defined(__arm__) || defined(__aarch64__) +# include +#endif + +// The MemoryBarrier function name collides with a macro under Windows +// We will undef the macro so that the function name does not get replaced +#undef MemoryBarrier + +// Macro for hinting that an expression is likely to be true/false. +#if !defined(ANGLE_LIKELY) || !defined(ANGLE_UNLIKELY) +# if defined(__GNUC__) || defined(__clang__) +# define ANGLE_LIKELY(x) __builtin_expect(!!(x), 1) +# define ANGLE_UNLIKELY(x) __builtin_expect(!!(x), 0) +# else +# define ANGLE_LIKELY(x) (x) +# define ANGLE_UNLIKELY(x) (x) +# endif // defined(__GNUC__) || defined(__clang__) +#endif // !defined(ANGLE_LIKELY) || !defined(ANGLE_UNLIKELY) + +#ifdef ANGLE_PLATFORM_APPLE +# include +# if TARGET_OS_OSX +# define ANGLE_PLATFORM_MACOS 1 +# elif TARGET_OS_IPHONE +# define ANGLE_PLATFORM_IOS 1 +# if TARGET_OS_SIMULATOR +# define ANGLE_PLATFORM_IOS_SIMULATOR 1 +# endif +# if TARGET_OS_MACCATALYST +# define ANGLE_PLATFORM_MACCATALYST 1 +# endif +# elif TARGET_OS_WATCH +# define ANGLE_PLATFORM_WATCHOS 1 +# if TARGET_OS_SIMULATOR +# define ANGLE_PLATFORM_IOS_SIMULATOR 1 +# endif +# elif TARGET_OS_TV +# define ANGLE_PLATFORM_APPLETV 1 +# if TARGET_OS_SIMULATOR +# define ANGLE_PLATFORM_IOS_SIMULATOR 1 +# endif +# endif +# // This might be useful globally. At the moment it is used +# // to differentiate MacCatalyst on Intel and Apple Silicon. +# if defined(__arm64__) || defined(__aarch64__) +# define ANGLE_CPU_ARM64 1 +# endif +# // EAGL should be enabled on iOS, but not Mac Catalyst unless it is running on Apple Silicon. +# if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || \ + (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64)) +# define ANGLE_ENABLE_EAGL +# endif +# // Identify Metal API >= what shipped on macOS Catalina. +# if (defined(ANGLE_PLATFORM_MACOS) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500) || \ + (defined(ANGLE_PLATFORM_IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) +# define ANGLE_WITH_MODERN_METAL_API 1 +# endif +#endif + +// Define ANGLE_WITH_ASAN macro. +#if defined(__has_feature) +# if __has_feature(address_sanitizer) +# define ANGLE_WITH_ASAN 1 +# endif +#endif + +// Define ANGLE_WITH_MSAN macro. +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# define ANGLE_WITH_MSAN 1 +# endif +#endif + +// Define ANGLE_WITH_TSAN macro. +#if defined(__has_feature) +# if __has_feature(thread_sanitizer) +# define ANGLE_WITH_TSAN 1 +# endif +#endif + +// Define ANGLE_WITH_UBSAN macro. +#if defined(__has_feature) +# if __has_feature(undefined_behavior_sanitizer) +# define ANGLE_WITH_UBSAN 1 +# endif +#endif + +#if defined(ANGLE_WITH_ASAN) || defined(ANGLE_WITH_TSAN) || defined(ANGLE_WITH_UBSAN) +# define ANGLE_WITH_SANITIZER 1 +#endif // defined(ANGLE_WITH_ASAN) || defined(ANGLE_WITH_TSAN) || defined(ANGLE_WITH_UBSAN) + +#include +#if INTPTR_MAX == INT64_MAX +# define ANGLE_IS_64_BIT_CPU 1 +#else +# define ANGLE_IS_32_BIT_CPU 1 +#endif + +#endif // COMMON_PLATFORM_H_ diff --git a/gfx/angle/checkout/src/common/spirv/spirv_types.h b/gfx/angle/checkout/src/common/spirv/spirv_types.h new file mode 100644 index 0000000000..faf2174481 --- /dev/null +++ b/gfx/angle/checkout/src/common/spirv/spirv_types.h @@ -0,0 +1,133 @@ +// +// Copyright 2021 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. +// +// spirv_types.h: +// Strong types for SPIR-V Ids to prevent mistakes when using the builder and parser APIs. +// + +#ifndef COMMON_SPIRV_TYPES_H_ +#define COMMON_SPIRV_TYPES_H_ + +#include "common/FastVector.h" + +#include + +namespace angle +{ +namespace spirv +{ +template +class BoxedUint32 +{ + public: + BoxedUint32() : mValue{0} {} + explicit BoxedUint32(uint32_t value) : mValue{value} {} + template + T as() const + { + return T{mValue}; + } + BoxedUint32(const BoxedUint32 &other) = default; + BoxedUint32 &operator=(const BoxedUint32 &other) = default; + operator uint32_t() const { return mValue.value; } + bool operator==(const BoxedUint32 &other) const { return mValue.value == other.mValue.value; } + // Applicable to ids, which cannot be 0. + bool valid() const { return static_cast(mValue.value); } + + private: + Helper mValue; +}; + +struct IdRefHelper +{ + uint32_t value; +}; +struct LiteralIntegerHelper +{ + uint32_t value; +}; + +using IdRef = BoxedUint32; + +template <> +inline BoxedUint32::operator uint32_t() const +{ + ASSERT(valid()); + return mValue.value; +} + +// IdResult, IdResultType, IdMemorySemantics and IdScope are all translated as IdRef. This makes +// the type verification weaker, but stops the API from becoming tediously verbose. +using IdResult = IdRef; +using IdResultType = IdRef; +using IdMemorySemantics = IdRef; +using IdScope = IdRef; +using LiteralInteger = BoxedUint32; +using LiteralString = const char *; +// Note: In ANGLE's use cases, all literals fit in 32 bits. +using LiteralContextDependentNumber = LiteralInteger; +// TODO(syoussefi): To be made stronger when generating SPIR-V from the translator. +// http://anglebug.com/4889 +using LiteralExtInstInteger = LiteralInteger; + +struct PairLiteralIntegerIdRef +{ + LiteralInteger literal; + IdRef id; +}; + +struct PairIdRefLiteralInteger +{ + IdRef id; + LiteralInteger literal; +}; + +struct PairIdRefIdRef +{ + IdRef id1; + IdRef id2; +}; + +// Some instructions need 4 components. The drivers uniform struct in ANGLE has 8 fields. A value +// of 8 means almost no instruction would end up making dynamic allocations. Notable exceptions are +// user-defined structs/blocks and OpEntryPoint. +constexpr size_t kFastVectorSize = 8; + +template +using FastVectorHelper = angle::FastVector; + +using IdRefList = FastVectorHelper; +using LiteralIntegerList = FastVectorHelper; +using PairLiteralIntegerIdRefList = FastVectorHelper; +using PairIdRefLiteralIntegerList = FastVectorHelper; +using PairIdRefIdRefList = FastVectorHelper; + +// Id 0 is invalid in SPIR-V. +constexpr uint32_t kMinValidId = 1; + +// The SPIR-V blob is a sequence of uint32_t's +using Blob = std::vector; + +// Format of the SPIR-V header. +// SPIR-V 1.0 Table 1: First Words of Physical Layout +enum HeaderIndex +{ + kHeaderIndexMagic = 0, + kHeaderIndexVersion = 1, + kHeaderIndexGenerator = 2, + kHeaderIndexIndexBound = 3, + kHeaderIndexSchema = 4, + kHeaderIndexInstructions = 5, +}; + +// Returns whether SPIR-V is valid. Useful for ASSERTs. Automatically generates a warning if +// SPIR-V is not valid. +bool Validate(const Blob &blob); +void Print(const Blob &blob); + +} // namespace spirv +} // namespace angle + +#endif // COMMON_SPIRV_TYPES_H_ diff --git a/gfx/angle/checkout/src/common/string_utils.cpp b/gfx/angle/checkout/src/common/string_utils.cpp new file mode 100644 index 0000000000..192d82917c --- /dev/null +++ b/gfx/angle/checkout/src/common/string_utils.cpp @@ -0,0 +1,357 @@ +// +// Copyright 2015 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. +// +// string_utils: +// String helper functions. +// + +#include "common/string_utils.h" + +#include +#include +#include +#include +#include +#include + +#include "common/platform.h" +#include "common/system_utils.h" + +namespace +{ + +bool EndsWithSuffix(const char *str, + const size_t strLen, + const char *suffix, + const size_t suffixLen) +{ + return suffixLen <= strLen && strncmp(str + strLen - suffixLen, suffix, suffixLen) == 0; +} + +} // anonymous namespace + +namespace angle +{ + +const char kWhitespaceASCII[] = " \f\n\r\t\v"; + +std::vector SplitString(const std::string &input, + const std::string &delimiters, + WhitespaceHandling whitespace, + SplitResult resultType) +{ + std::vector result; + if (input.empty()) + { + return result; + } + + std::string::size_type start = 0; + while (start != std::string::npos) + { + auto end = input.find_first_of(delimiters, start); + + std::string piece; + if (end == std::string::npos) + { + piece = input.substr(start); + start = std::string::npos; + } + else + { + piece = input.substr(start, end - start); + start = end + 1; + } + + if (whitespace == TRIM_WHITESPACE) + { + piece = TrimString(piece, kWhitespaceASCII); + } + + if (resultType == SPLIT_WANT_ALL || !piece.empty()) + { + result.push_back(std::move(piece)); + } + } + + return result; +} + +void SplitStringAlongWhitespace(const std::string &input, std::vector *tokensOut) +{ + + std::istringstream stream(input); + std::string line; + + while (std::getline(stream, line)) + { + size_t prev = 0, pos; + while ((pos = line.find_first_of(kWhitespaceASCII, prev)) != std::string::npos) + { + if (pos > prev) + tokensOut->push_back(line.substr(prev, pos - prev)); + prev = pos + 1; + } + if (prev < line.length()) + tokensOut->push_back(line.substr(prev, std::string::npos)); + } +} + +std::string TrimString(const std::string &input, const std::string &trimChars) +{ + auto begin = input.find_first_not_of(trimChars); + if (begin == std::string::npos) + { + return ""; + } + + std::string::size_type end = input.find_last_not_of(trimChars); + if (end == std::string::npos) + { + return input.substr(begin); + } + + return input.substr(begin, end - begin + 1); +} + +std::string GetPrefix(const std::string &input, size_t offset, const char *delimiter) +{ + size_t match = input.find(delimiter, offset); + if (match == std::string::npos) + { + return input.substr(offset); + } + return input.substr(offset, match - offset); +} + +std::string GetPrefix(const std::string &input, size_t offset, char delimiter) +{ + size_t match = input.find(delimiter, offset); + if (match == std::string::npos) + { + return input.substr(offset); + } + return input.substr(offset, match - offset); +} + +bool HexStringToUInt(const std::string &input, unsigned int *uintOut) +{ + unsigned int offset = 0; + + if (input.size() >= 2 && input[0] == '0' && input[1] == 'x') + { + offset = 2u; + } + + // Simple validity check + if (input.find_first_not_of("0123456789ABCDEFabcdef", offset) != std::string::npos) + { + return false; + } + + std::stringstream inStream(input); + inStream >> std::hex >> *uintOut; + return !inStream.fail(); +} + +bool ReadFileToString(const std::string &path, std::string *stringOut) +{ + std::ifstream inFile(path.c_str()); + if (inFile.fail()) + { + return false; + } + + inFile.seekg(0, std::ios::end); + stringOut->reserve(static_cast(inFile.tellg())); + inFile.seekg(0, std::ios::beg); + + stringOut->assign(std::istreambuf_iterator(inFile), std::istreambuf_iterator()); + return !inFile.fail(); +} + +bool BeginsWith(const std::string &str, const std::string &prefix) +{ + return strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0; +} + +bool BeginsWith(const std::string &str, const char *prefix) +{ + return strncmp(str.c_str(), prefix, strlen(prefix)) == 0; +} + +bool BeginsWith(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)) == 0; +} + +bool BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength) +{ + return strncmp(str.c_str(), prefix.c_str(), prefixLength) == 0; +} + +bool EndsWith(const std::string &str, const std::string &suffix) +{ + return EndsWithSuffix(str.c_str(), str.length(), suffix.c_str(), suffix.length()); +} + +bool EndsWith(const std::string &str, const char *suffix) +{ + return EndsWithSuffix(str.c_str(), str.length(), suffix, strlen(suffix)); +} + +bool EndsWith(const char *str, const char *suffix) +{ + return EndsWithSuffix(str, strlen(str), suffix, strlen(suffix)); +} + +bool ContainsToken(const std::string &tokenStr, char delimiter, const std::string &token) +{ + if (token.empty()) + { + return false; + } + // Compare token with all sub-strings terminated by delimiter or end of string + std::string::size_type start = 0u; + do + { + std::string::size_type end = tokenStr.find(delimiter, start); + if (end == std::string::npos) + { + end = tokenStr.length(); + } + const std::string::size_type length = end - start; + if (length == token.length() && tokenStr.compare(start, length, token) == 0) + { + return true; + } + start = end + 1u; + } while (start < tokenStr.size()); + return false; +} + +void ToLower(std::string *str) +{ + for (char &ch : *str) + { + ch = static_cast(::tolower(ch)); + } +} + +void ToUpper(std::string *str) +{ + for (char &ch : *str) + { + ch = static_cast(::toupper(ch)); + } +} + +bool ReplaceSubstring(std::string *str, + const std::string &substring, + const std::string &replacement) +{ + size_t replacePos = str->find(substring); + if (replacePos == std::string::npos) + { + return false; + } + str->replace(replacePos, substring.size(), replacement); + return true; +} + +int ReplaceAllSubstrings(std::string *str, + const std::string &substring, + const std::string &replacement) +{ + int count = 0; + while (ReplaceSubstring(str, substring, replacement)) + { + count++; + } + return count; +} + +std::string ToCamelCase(const std::string &str) +{ + std::string result; + + bool lastWasUnderscore = false; + for (char c : str) + { + if (c == '_') + { + lastWasUnderscore = true; + continue; + } + + if (lastWasUnderscore) + { + c = static_cast(std::toupper(c)); + lastWasUnderscore = false; + } + result += c; + } + + return result; +} + +std::vector GetStringsFromEnvironmentVarOrAndroidProperty(const char *varName, + const char *propertyName, + const char *separator) +{ + std::string environment = GetEnvironmentVarOrAndroidProperty(varName, propertyName); + return SplitString(environment, separator, TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); +} + +std::vector GetCachedStringsFromEnvironmentVarOrAndroidProperty( + const char *varName, + const char *propertyName, + const char *separator) +{ + std::string environment = GetEnvironmentVarOrAndroidProperty(varName, propertyName); + return SplitString(environment, separator, TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); +} + +// glob can have * as wildcard +bool NamesMatchWithWildcard(const char *glob, const char *name) +{ + // Find the first * in glob. + const char *firstWildcard = strchr(glob, '*'); + + // If there are no wildcards, match the strings precisely. + if (firstWildcard == nullptr) + { + return strcmp(glob, name) == 0; + } + + // Otherwise, match up to the wildcard first. + size_t preWildcardLen = firstWildcard - glob; + if (strncmp(glob, name, preWildcardLen) != 0) + { + return false; + } + + const char *postWildcardRef = glob + preWildcardLen + 1; + + // As a small optimization, if the wildcard is the last character in glob, accept the match + // already. + if (postWildcardRef[0] == '\0') + { + return true; + } + + // Try to match the wildcard with a number of characters. + for (size_t matchSize = 0; name[matchSize] != '\0'; ++matchSize) + { + if (NamesMatchWithWildcard(postWildcardRef, name + matchSize)) + { + return true; + } + } + + return false; +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/string_utils.h b/gfx/angle/checkout/src/common/string_utils.h new file mode 100644 index 0000000000..7be7efe983 --- /dev/null +++ b/gfx/angle/checkout/src/common/string_utils.h @@ -0,0 +1,125 @@ +// +// Copyright 2015 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. +// +// string_utils: +// String helper functions. +// + +#ifndef LIBANGLE_STRING_UTILS_H_ +#define LIBANGLE_STRING_UTILS_H_ + +#include +#include + +#include "common/Optional.h" + +namespace angle +{ + +extern const char kWhitespaceASCII[]; + +enum WhitespaceHandling +{ + KEEP_WHITESPACE, + TRIM_WHITESPACE, +}; + +enum SplitResult +{ + SPLIT_WANT_ALL, + SPLIT_WANT_NONEMPTY, +}; + +std::vector SplitString(const std::string &input, + const std::string &delimiters, + WhitespaceHandling whitespace, + SplitResult resultType); + +void SplitStringAlongWhitespace(const std::string &input, std::vector *tokensOut); + +std::string TrimString(const std::string &input, const std::string &trimChars); + +// Return the substring starting at offset and up to the first occurance of the |delimeter|. +std::string GetPrefix(const std::string &input, size_t offset, const char *delimiter); +std::string GetPrefix(const std::string &input, size_t offset, char delimiter); + +bool HexStringToUInt(const std::string &input, unsigned int *uintOut); + +bool ReadFileToString(const std::string &path, std::string *stringOut); + +// Check if the string str begins with the given prefix. +// The comparison is case sensitive. +bool BeginsWith(const std::string &str, const std::string &prefix); + +// Check if the string str begins with the given prefix. +// Prefix may not be NULL and needs to be NULL terminated. +// The comparison is case sensitive. +bool BeginsWith(const std::string &str, const char *prefix); + +// Check if the string str begins with the given prefix. +// str and prefix may not be NULL and need to be NULL terminated. +// The comparison is case sensitive. +bool BeginsWith(const char *str, const char *prefix); + +// Check if the string str begins with the first prefixLength characters of the given prefix. +// The length of the prefix string should be greater than or equal to prefixLength. +// The comparison is case sensitive. +bool BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength); + +// Check if the string str ends with the given suffix. +// The comparison is case sensitive. +bool EndsWith(const std::string &str, const std::string &suffix); + +// Check if the string str ends with the given suffix. +// Suffix may not be NULL and needs to be NULL terminated. +// The comparison is case sensitive. +bool EndsWith(const std::string &str, const char *suffix); + +// Check if the string str ends with the given suffix. +// str and suffix may not be NULL and need to be NULL terminated. +// The comparison is case sensitive. +bool EndsWith(const char *str, const char *suffix); + +// Check if the given token string contains the given token. +// The tokens are separated by the given delimiter. +// The comparison is case sensitive. +bool ContainsToken(const std::string &tokenStr, char delimiter, const std::string &token); + +// Convert to lower-case. +void ToLower(std::string *str); + +// Convert to upper-case. +void ToUpper(std::string *str); + +// Replaces the substring 'substring' in 'str' with 'replacement'. Returns true if successful. +bool ReplaceSubstring(std::string *str, + const std::string &substring, + const std::string &replacement); + +// Replaces all substrings 'substring' in 'str' with 'replacement'. Returns count of replacements. +int ReplaceAllSubstrings(std::string *str, + const std::string &substring, + const std::string &replacement); + +// Takes a snake_case string and turns it into camelCase. +std::string ToCamelCase(const std::string &str); + +// Split up a string parsed from an environment variable. +std::vector GetStringsFromEnvironmentVarOrAndroidProperty(const char *varName, + const char *propertyName, + const char *separator); + +// Split up a string parsed from environment variable or via Android property, use cached result if +// available. +std::vector GetCachedStringsFromEnvironmentVarOrAndroidProperty( + const char *varName, + const char *propertyName, + const char *separator); + +// glob can have * as wildcard +bool NamesMatchWithWildcard(const char *glob, const char *name); +} // namespace angle + +#endif // LIBANGLE_STRING_UTILS_H_ diff --git a/gfx/angle/checkout/src/common/system_utils.cpp b/gfx/angle/checkout/src/common/system_utils.cpp new file mode 100644 index 0000000000..89b632bc17 --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils.cpp @@ -0,0 +1,267 @@ +// +// Copyright 2018 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. +// + +// system_utils.cpp: Implementation of common functions + +#include "common/system_utils.h" +#include "common/debug.h" + +#include +#include + +#if defined(ANGLE_PLATFORM_ANDROID) +# include +#endif + +#if defined(ANGLE_PLATFORM_APPLE) +# include +# include +#endif + +namespace angle +{ +std::string GetExecutableName() +{ +#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21 + // Support for "getprogname" function in bionic was introduced in L (API level 21) + const char *executableName = getprogname(); + return (executableName) ? std::string(executableName) : "ANGLE"; +#else + std::string executableName = GetExecutablePath(); + size_t lastPathSepLoc = executableName.find_last_of(GetPathSeparator()); + return (lastPathSepLoc > 0 ? executableName.substr(lastPathSepLoc + 1, executableName.length()) + : "ANGLE"); +#endif // ANGLE_PLATFORM_ANDROID +} + +// On Android return value cached in the process environment, if none, call +// GetEnvironmentVarOrUnCachedAndroidProperty if not in environment. +std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName) +{ +#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21 + // Can't use GetEnvironmentVar here because that won't allow us to distinguish between the + // environment being set to an empty string vs. not set at all. + const char *variableValue = getenv(variableName); + if (variableValue != nullptr) + { + std::string value(variableValue); + return value; + } +#endif + return GetEnvironmentVarOrUnCachedAndroidProperty(variableName, propertyName); +} + +// On Android call out to 'getprop' on a shell to get an Android property. On desktop, return +// the value of the environment variable. +std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, + const char *propertyName) +{ +#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26 + std::string propertyValue; + + const prop_info *propertyInfo = __system_property_find(propertyName); + if (propertyInfo != nullptr) + { + __system_property_read_callback( + propertyInfo, + [](void *cookie, const char *, const char *value, unsigned) { + auto propertyValue = reinterpret_cast(cookie); + *propertyValue = value; + }, + &propertyValue); + } + + return propertyValue; +#else + // Return the environment variable's value. + return GetEnvironmentVar(variableName); +#endif // ANGLE_PLATFORM_ANDROID +} + +// Look up a property and add it to the application's environment. +// Adding to the env is a performance optimization, as getting properties is expensive. +// This should only be used in non-Release paths, i.e. when using FrameCapture or DebugUtils. +// It can cause race conditions in stress testing. See http://anglebug.com/6822 +std::string GetAndSetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, + const char *propertyName) +{ + std::string value = GetEnvironmentVarOrUnCachedAndroidProperty(variableName, propertyName); + +#if defined(ANGLE_PLATFORM_ANDROID) + if (!value.empty()) + { + // Set the environment variable with the value to improve future lookups (avoids + SetEnvironmentVar(variableName, value.c_str()); + } +#endif + + return value; +} + +bool GetBoolEnvironmentVar(const char *variableName) +{ + std::string envVarString = GetEnvironmentVar(variableName); + return (!envVarString.empty() && envVarString == "1"); +} + +bool PrependPathToEnvironmentVar(const char *variableName, const char *path) +{ + std::string oldValue = GetEnvironmentVar(variableName); + const char *newValue = nullptr; + std::string buf; + if (oldValue.empty()) + { + newValue = path; + } + else + { + buf = path; + buf += GetPathSeparatorForEnvironmentVar(); + buf += oldValue; + newValue = buf.c_str(); + } + return SetEnvironmentVar(variableName, newValue); +} + +bool IsFullPath(std::string dirName) +{ + if (dirName.find(GetRootDirectory()) == 0) + { + return true; + } + return false; +} + +std::string ConcatenatePath(std::string first, std::string second) +{ + if (first.empty()) + { + return second; + } + if (second.empty()) + { + return first; + } + if (IsFullPath(second)) + { + return second; + } + bool firstRedundantPathSeparator = first.find_last_of(GetPathSeparator()) == first.length() - 1; + bool secondRedundantPathSeparator = second.find(GetPathSeparator()) == 0; + if (firstRedundantPathSeparator && secondRedundantPathSeparator) + { + return first + second.substr(1); + } + else if (firstRedundantPathSeparator || secondRedundantPathSeparator) + { + return first + second; + } + return first + GetPathSeparator() + second; +} + +Optional CreateTemporaryFile() +{ + const Optional tempDir = GetTempDirectory(); + if (!tempDir.valid()) + return Optional::Invalid(); + + return CreateTemporaryFileInDirectory(tempDir.value()); +} + +PageFaultHandler::PageFaultHandler(PageFaultCallback callback) : mCallback(callback) {} +PageFaultHandler::~PageFaultHandler() {} + +Library *OpenSharedLibrary(const char *libraryName, SearchType searchType) +{ + void *libraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, nullptr); + return new Library(libraryHandle); +} + +Library *OpenSharedLibraryWithExtension(const char *libraryName, SearchType searchType) +{ + void *libraryHandle = + OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, nullptr); + return new Library(libraryHandle); +} + +Library *OpenSharedLibraryAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut) +{ + void *libraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, errorOut); + return new Library(libraryHandle); +} + +Library *OpenSharedLibraryWithExtensionAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut) +{ + void *libraryHandle = + OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, errorOut); + return new Library(libraryHandle); +} + +void *OpenSystemLibrary(const char *libraryName, SearchType searchType) +{ + return OpenSystemLibraryAndGetError(libraryName, searchType, nullptr); +} + +void *OpenSystemLibraryWithExtension(const char *libraryName, SearchType searchType) +{ + return OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, nullptr); +} + +void *OpenSystemLibraryAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut) +{ + std::string libraryWithExtension = std::string(libraryName) + "." + GetSharedLibraryExtension(); +#if ANGLE_PLATFORM_IOS + // On iOS, libraryWithExtension is a directory in which the library resides. + // The actual library name doesn't have an extension at all. + // E.g. "libEGL.framework/libEGL" + libraryWithExtension = libraryWithExtension + "/" + libraryName; +#endif + return OpenSystemLibraryWithExtensionAndGetError(libraryWithExtension.c_str(), searchType, + errorOut); +} + +std::string StripFilenameFromPath(const std::string &path) +{ + size_t lastPathSepLoc = path.find_last_of("\\/"); + return (lastPathSepLoc != std::string::npos) ? path.substr(0, lastPathSepLoc) : ""; +} + +static std::atomic globalThreadSerial(1); + +#if defined(ANGLE_PLATFORM_APPLE) +// https://anglebug.com/6479, similar to egl::GetCurrentThread() in libGLESv2/global_state.cpp +uint64_t GetCurrentThreadUniqueId() +{ + static pthread_key_t tlsIndex; + static dispatch_once_t once; + dispatch_once(&once, ^{ + ASSERT(pthread_key_create(&tlsIndex, nullptr) == 0); + }); + + void *tlsValue = pthread_getspecific(tlsIndex); + if (tlsValue == nullptr) + { + uint64_t threadId = globalThreadSerial++; + ASSERT(pthread_setspecific(tlsIndex, reinterpret_cast(threadId)) == 0); + return threadId; + } + return reinterpret_cast(tlsValue); +} +#else +uint64_t GetCurrentThreadUniqueId() +{ + thread_local uint64_t threadId(globalThreadSerial++); + return threadId; +} +#endif + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/system_utils.h b/gfx/angle/checkout/src/common/system_utils.h new file mode 100644 index 0000000000..d9e435afaa --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils.h @@ -0,0 +1,224 @@ +// +// Copyright 2014 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. +// + +// system_utils.h: declaration of OS-specific utility functions + +#ifndef COMMON_SYSTEM_UTILS_H_ +#define COMMON_SYSTEM_UTILS_H_ + +#include "common/Optional.h" +#include "common/angleutils.h" + +#include +#include +#include + +namespace angle +{ +std::string GetExecutableName(); +std::string GetExecutablePath(); +std::string GetExecutableDirectory(); +std::string GetModuleDirectory(); +const char *GetSharedLibraryExtension(); +const char *GetExecutableExtension(); +char GetPathSeparator(); +Optional GetCWD(); +bool SetCWD(const char *dirName); +bool SetEnvironmentVar(const char *variableName, const char *value); +bool UnsetEnvironmentVar(const char *variableName); +bool GetBoolEnvironmentVar(const char *variableName); +std::string GetEnvironmentVar(const char *variableName); +std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, + const char *propertyName); +std::string GetAndSetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, + const char *propertyName); +std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName); +const char *GetPathSeparatorForEnvironmentVar(); +bool PrependPathToEnvironmentVar(const char *variableName, const char *path); +bool IsDirectory(const char *filename); +bool IsFullPath(std::string dirName); +std::string GetRootDirectory(); +std::string ConcatenatePath(std::string first, std::string second); + +Optional GetTempDirectory(); +Optional CreateTemporaryFileInDirectory(const std::string &directory); +Optional CreateTemporaryFile(); + +// Get absolute time in seconds. Use this function to get an absolute time with an unknown origin. +double GetCurrentSystemTime(); +// Get CPU time for current process in seconds. +double GetCurrentProcessCpuTime(); + +// Unique thread id (std::this_thread::get_id() gets recycled!) +uint64_t GetCurrentThreadUniqueId(); + +// Run an application and get the output. Gets a nullptr-terminated set of args to execute the +// application with, and returns the stdout and stderr outputs as well as the exit code. +// +// Pass nullptr for stdoutOut/stderrOut if you don't need to capture. exitCodeOut is required. +// +// Returns false if it fails to actually execute the application. +bool RunApp(const std::vector &args, + std::string *stdoutOut, + std::string *stderrOut, + int *exitCodeOut); + +// Use SYSTEM_DIR to bypass loading ANGLE libraries with the same name as system DLLS +// (e.g. opengl32.dll) +enum class SearchType +{ + // Try to find the library in the same directory as the current module + ModuleDir, + // Load the library from the system directories + SystemDir, + // Get a reference to an already loaded shared library. + AlreadyLoaded, +}; + +void *OpenSystemLibrary(const char *libraryName, SearchType searchType); +void *OpenSystemLibraryWithExtension(const char *libraryName, SearchType searchType); +void *OpenSystemLibraryAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut); +void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut); + +void *GetLibrarySymbol(void *libraryHandle, const char *symbolName); +std::string GetLibraryPath(void *libraryHandle); +void CloseSystemLibrary(void *libraryHandle); + +class Library : angle::NonCopyable +{ + public: + Library() {} + Library(void *libraryHandle) : mLibraryHandle(libraryHandle) {} + ~Library() { close(); } + + [[nodiscard]] bool open(const char *libraryName, SearchType searchType) + { + close(); + mLibraryHandle = OpenSystemLibrary(libraryName, searchType); + return mLibraryHandle != nullptr; + } + + [[nodiscard]] bool openWithExtension(const char *libraryName, SearchType searchType) + { + close(); + mLibraryHandle = OpenSystemLibraryWithExtension(libraryName, searchType); + return mLibraryHandle != nullptr; + } + + [[nodiscard]] bool openAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut) + { + close(); + mLibraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, errorOut); + return mLibraryHandle != nullptr; + } + + [[nodiscard]] bool openWithExtensionAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut) + { + close(); + mLibraryHandle = + OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, errorOut); + return mLibraryHandle != nullptr; + } + + void close() + { + if (mLibraryHandle) + { + CloseSystemLibrary(mLibraryHandle); + mLibraryHandle = nullptr; + } + } + + void *getSymbol(const char *symbolName) { return GetLibrarySymbol(mLibraryHandle, symbolName); } + + void *getNative() const { return mLibraryHandle; } + + std::string getPath() const { return GetLibraryPath(mLibraryHandle); } + + template + void getAs(const char *symbolName, FuncT *funcOut) + { + *funcOut = reinterpret_cast(getSymbol(symbolName)); + } + + private: + void *mLibraryHandle = nullptr; +}; + +Library *OpenSharedLibrary(const char *libraryName, SearchType searchType); +Library *OpenSharedLibraryWithExtension(const char *libraryName, SearchType searchType); +Library *OpenSharedLibraryAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut); +Library *OpenSharedLibraryWithExtensionAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut); + +// Returns true if the process is currently being debugged. +bool IsDebuggerAttached(); + +// Calls system APIs to break into the debugger. +void BreakDebugger(); + +uint64_t GetProcessMemoryUsageKB(); + +bool ProtectMemory(uintptr_t start, size_t size); +bool UnprotectMemory(uintptr_t start, size_t size); + +size_t GetPageSize(); + +// Return type of the PageFaultCallback +enum class PageFaultHandlerRangeType +{ + // The memory address was known by the page fault handler + InRange, + // The memory address was not in the page fault handler's range + // and the signal will be forwarded to the default page handler. + OutOfRange, +}; + +using PageFaultCallback = std::function; + +class PageFaultHandler : angle::NonCopyable +{ + public: + PageFaultHandler(PageFaultCallback callback); + virtual ~PageFaultHandler(); + + // Registers OS level page fault handler for memory protection signals + // and enables reception on PageFaultCallback + virtual bool enable() = 0; + + // Unregisters OS level page fault handler and deactivates PageFaultCallback + virtual bool disable() = 0; + + protected: + PageFaultCallback mCallback; +}; + +// Creates single instance page fault handler +PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback); + +#ifdef ANGLE_PLATFORM_WINDOWS +// Convert an UTF-16 wstring to an UTF-8 string. +std::string Narrow(const std::wstring_view &utf16); + +// Convert an UTF-8 string to an UTF-16 wstring. +std::wstring Widen(const std::string_view &utf8); +#endif + +std::string StripFilenameFromPath(const std::string &path); +} // namespace angle + +#endif // COMMON_SYSTEM_UTILS_H_ diff --git a/gfx/angle/checkout/src/common/system_utils_apple.cpp b/gfx/angle/checkout/src/common/system_utils_apple.cpp new file mode 100644 index 0000000000..532714248c --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils_apple.cpp @@ -0,0 +1,59 @@ +// +// Copyright 2020 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. +// + +// system_utils_apple.cpp: Implementation of OS-specific functions for Apple platforms + +#include "system_utils.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace angle +{ +std::string GetExecutablePath() +{ + std::string result; + + uint32_t size = 0; + _NSGetExecutablePath(nullptr, &size); + + std::vector buffer; + buffer.resize(size + 1); + + _NSGetExecutablePath(buffer.data(), &size); + buffer[size] = '\0'; + + if (!strrchr(buffer.data(), '/')) + { + return ""; + } + return buffer.data(); +} + +std::string GetExecutableDirectory() +{ + std::string executablePath = GetExecutablePath(); + size_t lastPathSepLoc = executablePath.find_last_of("/"); + return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : ""; +} + +double GetCurrentSystemTime() +{ + mach_timebase_info_data_t timebaseInfo; + mach_timebase_info(&timebaseInfo); + + double secondCoeff = timebaseInfo.numer * 1e-9 / timebaseInfo.denom; + return secondCoeff * mach_absolute_time(); +} +} // namespace angle diff --git a/gfx/angle/checkout/src/common/system_utils_linux.cpp b/gfx/angle/checkout/src/common/system_utils_linux.cpp new file mode 100644 index 0000000000..da0ed86028 --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils_linux.cpp @@ -0,0 +1,55 @@ +// +// Copyright 2015 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. +// + +// system_utils_linux.cpp: Implementation of OS-specific functions for Linux + +#include "system_utils.h" + +#include +#include +#include +#include + +#include + +namespace angle +{ +std::string GetExecutablePath() +{ + // We cannot use lstat to get the size of /proc/self/exe as it always returns 0 + // so we just use a big buffer and hope the path fits in it. + char path[4096]; + + ssize_t result = readlink("/proc/self/exe", path, sizeof(path) - 1); + if (result < 0 || static_cast(result) >= sizeof(path) - 1) + { + return ""; + } + + path[result] = '\0'; + return path; +} + +std::string GetExecutableDirectory() +{ + std::string executablePath = GetExecutablePath(); + size_t lastPathSepLoc = executablePath.find_last_of("/"); + return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : ""; +} + +const char *GetSharedLibraryExtension() +{ + return "so"; +} + +double GetCurrentSystemTime() +{ + struct timespec currentTime; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + return currentTime.tv_sec + currentTime.tv_nsec * 1e-9; +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/system_utils_mac.cpp b/gfx/angle/checkout/src/common/system_utils_mac.cpp new file mode 100644 index 0000000000..2c48a7eb04 --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils_mac.cpp @@ -0,0 +1,28 @@ +// +// Copyright 2015 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. +// + +// system_utils_osx.cpp: Implementation of OS-specific functions for OSX + +#include "system_utils.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace angle +{ +const char *GetSharedLibraryExtension() +{ + return "dylib"; +} +} // namespace angle diff --git a/gfx/angle/checkout/src/common/system_utils_posix.cpp b/gfx/angle/checkout/src/common/system_utils_posix.cpp new file mode 100644 index 0000000000..ab0faee0bc --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils_posix.cpp @@ -0,0 +1,470 @@ +// +// Copyright 2018 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. +// + +// system_utils_posix.cpp: Implementation of POSIX OS-specific functions. + +#include "common/debug.h" +#include "system_utils.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/string_utils.h" + +#ifdef ANGLE_PLATFORM_FUCHSIA +# include +# include +#else +# include +#endif + +namespace angle +{ + +namespace +{ +std::string GetModulePath(void *moduleOrSymbol) +{ + Dl_info dlInfo; + if (dladdr(moduleOrSymbol, &dlInfo) == 0) + { + return ""; + } + + return dlInfo.dli_fname; +} + +void *OpenPosixLibrary(const std::string &fullPath, int extraFlags, std::string *errorOut) +{ + void *module = dlopen(fullPath.c_str(), RTLD_NOW | extraFlags); + if (module) + { + if (errorOut) + { + *errorOut = fullPath; + } + } + else if (errorOut) + { + *errorOut = "dlopen("; + *errorOut += fullPath; + *errorOut += ") failed with error: "; + *errorOut += dlerror(); + struct stat sfile; + if (-1 == stat(fullPath.c_str(), &sfile)) + { + *errorOut += ", stat() call failed."; + } + else + { + *errorOut += ", stat() info: "; + struct passwd *pwuser = getpwuid(sfile.st_uid); + if (pwuser) + { + *errorOut += "owner: "; + *errorOut += pwuser->pw_name; + *errorOut += ", "; + } + struct group *grpnam = getgrgid(sfile.st_gid); + if (grpnam) + { + *errorOut += "group: "; + *errorOut += grpnam->gr_name; + *errorOut += ", "; + } + *errorOut += "perms: "; + *errorOut += std::to_string(sfile.st_mode); + *errorOut += ", links: "; + *errorOut += std::to_string(sfile.st_nlink); + *errorOut += ", size: "; + *errorOut += std::to_string(sfile.st_size); + } + } + return module; +} +} // namespace + +Optional GetCWD() +{ + std::array pathBuf; + char *result = getcwd(pathBuf.data(), pathBuf.size()); + if (result == nullptr) + { + return Optional::Invalid(); + } + return std::string(pathBuf.data()); +} + +bool SetCWD(const char *dirName) +{ + return (chdir(dirName) == 0); +} + +bool UnsetEnvironmentVar(const char *variableName) +{ + return (unsetenv(variableName) == 0); +} + +bool SetEnvironmentVar(const char *variableName, const char *value) +{ + return (setenv(variableName, value, 1) == 0); +} + +std::string GetEnvironmentVar(const char *variableName) +{ + const char *value = getenv(variableName); + return (value == nullptr ? std::string() : std::string(value)); +} + +const char *GetPathSeparatorForEnvironmentVar() +{ + return ":"; +} + +std::string GetModuleDirectoryAndGetError(std::string *errorOut) +{ + std::string directory; + static int placeholderSymbol = 0; + std::string moduleName = GetModulePath(&placeholderSymbol); + if (!moduleName.empty()) + { + directory = moduleName.substr(0, moduleName.find_last_of('/') + 1); + } + + // Ensure we return the full path to the module, not the relative path + if (!IsFullPath(directory)) + { + if (errorOut) + { + *errorOut += "Directory: '"; + *errorOut += directory; + *errorOut += "' is not full path"; + } + Optional cwd = GetCWD(); + if (cwd.valid()) + { + directory = ConcatenatePath(cwd.value(), directory); + if (errorOut) + { + *errorOut += ", so it has been modified to: '"; + *errorOut += directory; + *errorOut += "'. "; + } + } + else if (errorOut) + { + *errorOut += " and getcwd was invalid. "; + } + } + return directory; +} + +std::string GetModuleDirectory() +{ + return GetModuleDirectoryAndGetError(nullptr); +} + +void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut) +{ + std::string directory; + if (searchType == SearchType::ModuleDir) + { +#if ANGLE_PLATFORM_IOS + // On iOS, shared libraries must be loaded from within the app bundle. + directory = GetExecutableDirectory() + "/Frameworks/"; +#elif ANGLE_PLATFORM_FUCHSIA + // On Fuchsia the dynamic loader always looks up libraries in /pkg/lib + // and disallows loading of libraries via absolute paths. + directory = ""; +#else + directory = GetModuleDirectoryAndGetError(errorOut); +#endif + } + + int extraFlags = 0; + if (searchType == SearchType::AlreadyLoaded) + { + extraFlags = RTLD_NOLOAD; + } + + std::string fullPath = directory + libraryName; + return OpenPosixLibrary(fullPath, extraFlags, errorOut); +} + +void *GetLibrarySymbol(void *libraryHandle, const char *symbolName) +{ + if (!libraryHandle) + { + return nullptr; + } + + return dlsym(libraryHandle, symbolName); +} + +std::string GetLibraryPath(void *libraryHandle) +{ + if (!libraryHandle) + { + return ""; + } + + return GetModulePath(libraryHandle); +} + +void CloseSystemLibrary(void *libraryHandle) +{ + if (libraryHandle) + { + dlclose(libraryHandle); + } +} + +bool IsDirectory(const char *filename) +{ + struct stat st; + int result = stat(filename, &st); + return result == 0 && ((st.st_mode & S_IFDIR) == S_IFDIR); +} + +bool IsDebuggerAttached() +{ + // This could have a fuller implementation. + // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc + return false; +} + +void BreakDebugger() +{ + // This could have a fuller implementation. + // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc + abort(); +} + +const char *GetExecutableExtension() +{ + return ""; +} + +char GetPathSeparator() +{ + return '/'; +} + +std::string GetRootDirectory() +{ + return "/"; +} + +Optional GetTempDirectory() +{ + const char *tmp = getenv("TMPDIR"); + if (tmp != nullptr) + { + return std::string(tmp); + } + +#if defined(ANGLE_PLATFORM_ANDROID) + // Not used right now in the ANGLE test runner. + // return PathService::Get(DIR_CACHE, path); + return Optional::Invalid(); +#else + return std::string("/tmp"); +#endif +} + +Optional CreateTemporaryFileInDirectory(const std::string &directory) +{ + std::string tempFileTemplate = directory + "/.angle.XXXXXX"; + + char tempFile[1000]; + strcpy(tempFile, tempFileTemplate.c_str()); + + int fd = mkstemp(tempFile); + close(fd); + + if (fd != -1) + { + return std::string(tempFile); + } + + return Optional::Invalid(); +} + +double GetCurrentProcessCpuTime() +{ +#ifdef ANGLE_PLATFORM_FUCHSIA + static zx_handle_t me = zx_process_self(); + zx_info_task_runtime_t task_runtime; + zx_object_get_info(me, ZX_INFO_TASK_RUNTIME, &task_runtime, sizeof(task_runtime), nullptr, + nullptr); + return static_cast(task_runtime.cpu_time) * 1e-9; +#else + // We could also have used /proc/stat, but that requires us to read the + // filesystem and convert from jiffies. /proc/stat also relies on jiffies + // (lower resolution) while getrusage can potentially use a sched_clock() + // underneath that has higher resolution. + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); + double userTime = usage.ru_utime.tv_sec + usage.ru_utime.tv_usec * 1e-6; + double systemTime = usage.ru_stime.tv_sec + usage.ru_stime.tv_usec * 1e-6; + return userTime + systemTime; +#endif +} + +namespace +{ +bool SetMemoryProtection(uintptr_t start, size_t size, int protections) +{ + int ret = mprotect(reinterpret_cast(start), size, protections); + if (ret < 0) + { + perror("mprotect failed"); + } + return ret == 0; +} + +class PosixPageFaultHandler : public PageFaultHandler +{ + public: + PosixPageFaultHandler(PageFaultCallback callback) : PageFaultHandler(callback) {} + ~PosixPageFaultHandler() override {} + + bool enable() override; + bool disable() override; + void handle(int sig, siginfo_t *info, void *unused); + + private: + struct sigaction mDefaultBusAction = {}; + struct sigaction mDefaultSegvAction = {}; +}; + +PosixPageFaultHandler *gPosixPageFaultHandler = nullptr; +void SegfaultHandlerFunction(int sig, siginfo_t *info, void *unused) +{ + gPosixPageFaultHandler->handle(sig, info, unused); +} + +void PosixPageFaultHandler::handle(int sig, siginfo_t *info, void *unused) +{ + bool found = false; + if ((sig == SIGSEGV || sig == SIGBUS) && + (info->si_code == SEGV_ACCERR || info->si_code == SEGV_MAPERR)) + { + found = mCallback(reinterpret_cast(info->si_addr)) == + PageFaultHandlerRangeType::InRange; + } + + // Fall back to default signal handler + if (!found) + { + if (sig == SIGSEGV) + { + mDefaultSegvAction.sa_sigaction(sig, info, unused); + } + else if (sig == SIGBUS) + { + mDefaultBusAction.sa_sigaction(sig, info, unused); + } + else + { + UNREACHABLE(); + } + } +} + +bool PosixPageFaultHandler::disable() +{ + return sigaction(SIGSEGV, &mDefaultSegvAction, nullptr) == 0 && + sigaction(SIGBUS, &mDefaultBusAction, nullptr) == 0; +} + +bool PosixPageFaultHandler::enable() +{ + struct sigaction sigAction = {}; + sigAction.sa_flags = SA_SIGINFO; + sigAction.sa_sigaction = &SegfaultHandlerFunction; + sigemptyset(&sigAction.sa_mask); + + // Some POSIX implementations use SIGBUS for mprotect faults + return sigaction(SIGSEGV, &sigAction, &mDefaultSegvAction) == 0 && + sigaction(SIGBUS, &sigAction, &mDefaultBusAction) == 0; +} +} // namespace + +// Set write protection +bool ProtectMemory(uintptr_t start, size_t size) +{ + return SetMemoryProtection(start, size, PROT_READ); +} + +// Allow reading and writing +bool UnprotectMemory(uintptr_t start, size_t size) +{ + return SetMemoryProtection(start, size, PROT_READ | PROT_WRITE); +} + +size_t GetPageSize() +{ + long pageSize = sysconf(_SC_PAGE_SIZE); + if (pageSize < 0) + { + perror("Could not get sysconf page size"); + return 0; + } + return static_cast(pageSize); +} + +PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback) +{ + gPosixPageFaultHandler = new PosixPageFaultHandler(callback); + return gPosixPageFaultHandler; +} + +uint64_t GetProcessMemoryUsageKB() +{ + FILE *file = fopen("/proc/self/status", "r"); + + if (!file) + { + return 0; + } + + const char *kSearchString = "VmRSS:"; + constexpr size_t kMaxLineSize = 100; + std::array line = {}; + + uint64_t kb = 0; + + while (fgets(line.data(), line.size(), file) != nullptr) + { + if (strncmp(line.data(), kSearchString, strlen(kSearchString)) == 0) + { + std::vector strings; + SplitStringAlongWhitespace(line.data(), &strings); + + sscanf(strings[1].c_str(), "%" SCNu64, &kb); + break; + } + } + fclose(file); + + return kb; +} +} // namespace angle diff --git a/gfx/angle/checkout/src/common/system_utils_win.cpp b/gfx/angle/checkout/src/common/system_utils_win.cpp new file mode 100644 index 0000000000..8770235cd7 --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils_win.cpp @@ -0,0 +1,264 @@ +// +// Copyright 2014 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. +// + +// system_utils_win.cpp: Implementation of OS-specific functions for Windows + +#include "system_utils.h" + +#include +#include +#include +#include + +namespace angle +{ + +namespace +{ + +std::string GetPath(HMODULE module) +{ + std::array executableFileBuf; + DWORD executablePathLen = GetModuleFileNameW(module, executableFileBuf.data(), + static_cast(executableFileBuf.size())); + return Narrow(executablePathLen > 0 ? executableFileBuf.data() : L""); +} + +std::string GetDirectory(HMODULE module) +{ + std::string executablePath = GetPath(module); + return StripFilenameFromPath(executablePath); +} + +} // anonymous namespace + +std::string GetExecutablePath() +{ + return GetPath(nullptr); +} + +std::string GetExecutableDirectory() +{ + return GetDirectory(nullptr); +} + +const char *GetSharedLibraryExtension() +{ + return "dll"; +} + +Optional GetCWD() +{ + std::array pathBuf; + DWORD result = GetCurrentDirectoryW(static_cast(pathBuf.size()), pathBuf.data()); + if (result == 0) + { + return Optional::Invalid(); + } + return Narrow(pathBuf.data()); +} + +bool SetCWD(const char *dirName) +{ + return (SetCurrentDirectoryW(Widen(dirName).c_str()) == TRUE); +} + +const char *GetPathSeparatorForEnvironmentVar() +{ + return ";"; +} + +double GetCurrentSystemTime() +{ + LARGE_INTEGER frequency = {}; + QueryPerformanceFrequency(&frequency); + + LARGE_INTEGER curTime; + QueryPerformanceCounter(&curTime); + + return static_cast(curTime.QuadPart) / frequency.QuadPart; +} + +double GetCurrentProcessCpuTime() +{ + FILETIME creationTime = {}; + FILETIME exitTime = {}; + FILETIME kernelTime = {}; + FILETIME userTime = {}; + + // Note this will not give accurate results if the current thread is + // scheduled for less than the tick rate, which is often 15 ms. In that + // case, GetProcessTimes will not return different values, making it + // possible to end up with 0 ms for a process that takes 93% of a core + // (14/15 ms)! An alternative is QueryProcessCycleTime but there is no + // simple way to convert cycles back to seconds, and on top of that, it's + // not supported pre-Windows Vista. + + // Returns 100-ns intervals, so we want to divide by 1e7 to get seconds + GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime); + + ULARGE_INTEGER kernelInt64; + kernelInt64.LowPart = kernelTime.dwLowDateTime; + kernelInt64.HighPart = kernelTime.dwHighDateTime; + double systemTimeSeconds = static_cast(kernelInt64.QuadPart) * 1e-7; + + ULARGE_INTEGER userInt64; + userInt64.LowPart = userTime.dwLowDateTime; + userInt64.HighPart = userTime.dwHighDateTime; + double userTimeSeconds = static_cast(userInt64.QuadPart) * 1e-7; + + return systemTimeSeconds + userTimeSeconds; +} + +bool IsDirectory(const char *filename) +{ + WIN32_FILE_ATTRIBUTE_DATA fileInformation; + + BOOL result = + GetFileAttributesExW(Widen(filename).c_str(), GetFileExInfoStandard, &fileInformation); + if (result) + { + DWORD attribs = fileInformation.dwFileAttributes; + return (attribs != INVALID_FILE_ATTRIBUTES) && ((attribs & FILE_ATTRIBUTE_DIRECTORY) > 0); + } + + return false; +} + +bool IsDebuggerAttached() +{ + return !!::IsDebuggerPresent(); +} + +void BreakDebugger() +{ + __debugbreak(); +} + +const char *GetExecutableExtension() +{ + return ".exe"; +} + +char GetPathSeparator() +{ + return '\\'; +} + +std::string GetModuleDirectory() +{ +// GetModuleHandleEx is unavailable on UWP +#if !defined(ANGLE_IS_WINUWP) + static int placeholderSymbol = 0; + HMODULE module = nullptr; + if (GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(&placeholderSymbol), &module)) + { + return GetDirectory(module); + } +#endif + return GetDirectory(nullptr); +} + +std::string GetRootDirectory() +{ + return "C:\\"; +} + +Optional GetTempDirectory() +{ + char tempDirOut[MAX_PATH + 1]; + GetTempPathA(MAX_PATH + 1, tempDirOut); + std::string tempDir = std::string(tempDirOut); + + if (tempDir.length() < 0 || tempDir.length() > MAX_PATH) + { + return Optional::Invalid(); + } + + if (tempDir.length() > 0 && tempDir.back() == '\\') + { + tempDir.pop_back(); + } + + return tempDir; +} + +Optional CreateTemporaryFileInDirectory(const std::string &directory) +{ + char fileName[MAX_PATH + 1]; + if (GetTempFileNameA(directory.c_str(), "ANGLE", 0, fileName) == 0) + return Optional::Invalid(); + + return std::string(fileName); +} + +std::string GetLibraryPath(void *libraryHandle) +{ + if (!libraryHandle) + { + return ""; + } + + std::array buffer; + if (GetModuleFileNameW(reinterpret_cast(libraryHandle), buffer.data(), + buffer.size()) == 0) + { + return ""; + } + + return Narrow(buffer.data()); +} + +void *GetLibrarySymbol(void *libraryHandle, const char *symbolName) +{ + if (!libraryHandle) + { + fprintf(stderr, "Module was not loaded\n"); + return nullptr; + } + + return reinterpret_cast( + GetProcAddress(reinterpret_cast(libraryHandle), symbolName)); +} + +void CloseSystemLibrary(void *libraryHandle) +{ + if (libraryHandle) + { + FreeLibrary(reinterpret_cast(libraryHandle)); + } +} +std::string Narrow(const std::wstring_view &utf16) +{ + if (utf16.empty()) + { + return {}; + } + int requiredSize = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast(utf16.size()), + nullptr, 0, nullptr, nullptr); + std::string utf8(requiredSize, '\0'); + WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast(utf16.size()), &utf8[0], + requiredSize, nullptr, nullptr); + return utf8; +} + +std::wstring Widen(const std::string_view &utf8) +{ + if (utf8.empty()) + { + return {}; + } + int requiredSize = + MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast(utf8.size()), nullptr, 0); + std::wstring utf16(requiredSize, L'\0'); + MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast(utf8.size()), &utf16[0], + requiredSize); + return utf16; +} + +} // namespace angle diff --git a/gfx/angle/checkout/src/common/system_utils_win32.cpp b/gfx/angle/checkout/src/common/system_utils_win32.cpp new file mode 100644 index 0000000000..5bcfa2347e --- /dev/null +++ b/gfx/angle/checkout/src/common/system_utils_win32.cpp @@ -0,0 +1,235 @@ +// +// Copyright 2019 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. +// +// system_utils_win32.cpp: Implementation of OS-specific functions for Windows. + +#include "common/FastVector.h" +#include "system_utils.h" + +#include + +// Must be included in this order. +// clang-format off +#include +#include +// clang-format on + +namespace angle +{ +bool UnsetEnvironmentVar(const char *variableName) +{ + return (SetEnvironmentVariableW(Widen(variableName).c_str(), nullptr) == TRUE); +} + +bool SetEnvironmentVar(const char *variableName, const char *value) +{ + return (SetEnvironmentVariableW(Widen(variableName).c_str(), Widen(value).c_str()) == TRUE); +} + +std::string GetEnvironmentVar(const char *variableName) +{ + std::wstring variableNameUtf16 = Widen(variableName); + FastVector value; + + DWORD result; + + // First get the length of the variable, including the null terminator + result = GetEnvironmentVariableW(variableNameUtf16.c_str(), nullptr, 0); + + // Zero means the variable was not found, so return now. + if (result == 0) + { + return std::string(); + } + + // Now size the vector to fit the data, and read the environment variable. + value.resize(result, 0); + result = GetEnvironmentVariableW(variableNameUtf16.c_str(), value.data(), result); + + return Narrow(value.data()); +} + +void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName, + SearchType searchType, + std::string *errorOut) +{ + char buffer[MAX_PATH]; + int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension()); + if (ret <= 0 || ret >= MAX_PATH) + { + fprintf(stderr, "Error loading shared library: 0x%x", ret); + return nullptr; + } + + HMODULE libraryModule = nullptr; + + switch (searchType) + { + case SearchType::ModuleDir: + { + std::string moduleRelativePath = ConcatenatePath(GetModuleDirectory(), libraryName); + if (errorOut) + { + *errorOut = moduleRelativePath; + } + libraryModule = LoadLibraryW(Widen(moduleRelativePath).c_str()); + break; + } + + case SearchType::SystemDir: + { + if (errorOut) + { + *errorOut = libraryName; + } + libraryModule = + LoadLibraryExW(Widen(libraryName).c_str(), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + break; + } + + case SearchType::AlreadyLoaded: + { + if (errorOut) + { + *errorOut = libraryName; + } + libraryModule = GetModuleHandleW(Widen(libraryName).c_str()); + break; + } + } + + return reinterpret_cast(libraryModule); +} + +namespace +{ +class Win32PageFaultHandler : public PageFaultHandler +{ + public: + Win32PageFaultHandler(PageFaultCallback callback) : PageFaultHandler(callback) {} + ~Win32PageFaultHandler() override {} + + bool enable() override; + bool disable() override; + + LONG handle(PEXCEPTION_POINTERS pExceptionInfo); + + private: + void *mVectoredExceptionHandler = nullptr; +}; + +Win32PageFaultHandler *gWin32PageFaultHandler = nullptr; +static LONG CALLBACK VectoredExceptionHandler(PEXCEPTION_POINTERS info) +{ + return gWin32PageFaultHandler->handle(info); +} + +bool SetMemoryProtection(uintptr_t start, size_t size, DWORD protections) +{ + DWORD oldProtect; + BOOL res = VirtualProtect(reinterpret_cast(start), size, protections, &oldProtect); + if (!res) + { + DWORD lastError = GetLastError(); + fprintf(stderr, "VirtualProtect failed: 0x%lx\n", lastError); + return false; + } + + return true; +} + +LONG Win32PageFaultHandler::handle(PEXCEPTION_POINTERS info) +{ + bool found = false; + + if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && + info->ExceptionRecord->NumberParameters >= 2 && + info->ExceptionRecord->ExceptionInformation[0] == 1) + { + found = mCallback(static_cast(info->ExceptionRecord->ExceptionInformation[1])) == + PageFaultHandlerRangeType::InRange; + } + + if (found) + { + return EXCEPTION_CONTINUE_EXECUTION; + } + else + { + return EXCEPTION_CONTINUE_SEARCH; + } +} + +bool Win32PageFaultHandler::disable() +{ + if (mVectoredExceptionHandler) + { + ULONG res = RemoveVectoredExceptionHandler(mVectoredExceptionHandler); + mVectoredExceptionHandler = nullptr; + if (res == 0) + { + DWORD lastError = GetLastError(); + fprintf(stderr, "RemoveVectoredExceptionHandler failed: 0x%lx\n", lastError); + return false; + } + } + return true; +} + +bool Win32PageFaultHandler::enable() +{ + if (mVectoredExceptionHandler) + { + return true; + } + + PVECTORED_EXCEPTION_HANDLER handler = + reinterpret_cast(&VectoredExceptionHandler); + + mVectoredExceptionHandler = AddVectoredExceptionHandler(1, handler); + + if (!mVectoredExceptionHandler) + { + DWORD lastError = GetLastError(); + fprintf(stderr, "AddVectoredExceptionHandler failed: 0x%lx\n", lastError); + return false; + } + return true; +} +} // namespace + +// Set write protection +bool ProtectMemory(uintptr_t start, size_t size) +{ + return SetMemoryProtection(start, size, PAGE_READONLY); +} + +// Allow reading and writing +bool UnprotectMemory(uintptr_t start, size_t size) +{ + return SetMemoryProtection(start, size, PAGE_READWRITE); +} + +size_t GetPageSize() +{ + SYSTEM_INFO info; + GetSystemInfo(&info); + return static_cast(info.dwPageSize); +} + +PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback) +{ + gWin32PageFaultHandler = new Win32PageFaultHandler(callback); + return gWin32PageFaultHandler; +} + +uint64_t GetProcessMemoryUsageKB() +{ + PROCESS_MEMORY_COUNTERS_EX pmc; + ::GetProcessMemoryInfo(::GetCurrentProcess(), reinterpret_cast(&pmc), + sizeof(pmc)); + return static_cast(pmc.PrivateUsage) / 1024ull; +} +} // namespace angle diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h new file mode 100644 index 0000000000..426047a992 --- /dev/null +++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h @@ -0,0 +1,13 @@ +// +// Copyright 2017 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. +// +// base_export.h: Compatiblity hacks for importing Chromium's base/SHA1. + +#ifndef ANGLEBASE_BASE_EXPORT_H_ +#define ANGLEBASE_BASE_EXPORT_H_ + +#define ANGLEBASE_EXPORT + +#endif // ANGLEBASE_BASE_EXPORT_H_ diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h new file mode 100644 index 0000000000..30b564aff6 --- /dev/null +++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h @@ -0,0 +1,275 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file contains a template for a Most Recently Used cache that allows +// constant-time access to items using a key, but easy identification of the +// least-recently-used items for removal. Each key can only be associated with +// one payload item at a time. +// +// The key object will be stored twice, so it should support efficient copying. +// +// NOTE: While all operations are O(1), this code is written for +// legibility rather than optimality. If future profiling identifies this as +// a bottleneck, there is room for smaller values of 1 in the O(1). :] + +#ifndef ANGLEBASE_CONTAINERS_MRU_CACHE_H_ +#define ANGLEBASE_CONTAINERS_MRU_CACHE_H_ + +#include + +#include +#include +#include +#include +#include +#include + +#include "anglebase/logging.h" +#include "anglebase/macros.h" + +namespace angle +{ + +namespace base +{ + +// MRUCacheBase ---------------------------------------------------------------- + +// This template is used to standardize map type containers that can be used +// by MRUCacheBase. This level of indirection is necessary because of the way +// that template template params and default template params interact. +template +struct MRUCacheStandardMap +{ + typedef std::map Type; +}; + +// Base class for the MRU cache specializations defined below. +template class MapType = MRUCacheStandardMap> +class MRUCacheBase +{ + public: + // The payload of the list. This maintains a copy of the key so we can + // efficiently delete things given an element of the list. + typedef std::pair value_type; + + private: + typedef std::list PayloadList; + typedef + typename MapType::Type KeyIndex; + + public: + typedef typename PayloadList::size_type size_type; + + typedef typename PayloadList::iterator iterator; + typedef typename PayloadList::const_iterator const_iterator; + typedef typename PayloadList::reverse_iterator reverse_iterator; + typedef typename PayloadList::const_reverse_iterator const_reverse_iterator; + + enum + { + NO_AUTO_EVICT = 0 + }; + + // The max_size is the size at which the cache will prune its members to when + // a new item is inserted. If the caller wants to manager this itself (for + // example, maybe it has special work to do when something is evicted), it + // can pass NO_AUTO_EVICT to not restrict the cache size. + explicit MRUCacheBase(size_type max_size) : max_size_(max_size) {} + + virtual ~MRUCacheBase() {} + + size_type max_size() const { return max_size_; } + + // Inserts a payload item with the given key. If an existing item has + // the same key, it is removed prior to insertion. An iterator indicating the + // inserted item will be returned (this will always be the front of the list). + // + // The payload will be forwarded. + template + iterator Put(const KeyType &key, Payload &&payload) + { + // Remove any existing payload with that key. + typename KeyIndex::iterator index_iter = index_.find(key); + if (index_iter != index_.end()) + { + // Erase the reference to it. The index reference will be replaced in the + // code below. + Erase(index_iter->second); + } + else if (max_size_ != NO_AUTO_EVICT) + { + // New item is being inserted which might make it larger than the maximum + // size: kick the oldest thing out if necessary. + ShrinkToSize(max_size_ - 1); + } + + ordering_.emplace_front(key, std::forward(payload)); + index_.emplace(key, ordering_.begin()); + return ordering_.begin(); + } + + // Retrieves the contents of the given key, or end() if not found. This method + // has the side effect of moving the requested item to the front of the + // recency list. + iterator Get(const KeyType &key) + { + typename KeyIndex::iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + typename PayloadList::iterator iter = index_iter->second; + + // Move the touched item to the front of the recency ordering. + ordering_.splice(ordering_.begin(), ordering_, iter); + return ordering_.begin(); + } + + // Retrieves the payload associated with a given key and returns it via + // result without affecting the ordering (unlike Get). + iterator Peek(const KeyType &key) + { + typename KeyIndex::const_iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + return index_iter->second; + } + + const_iterator Peek(const KeyType &key) const + { + typename KeyIndex::const_iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + return index_iter->second; + } + + // Exchanges the contents of |this| by the contents of the |other|. + void Swap(MRUCacheBase &other) + { + ordering_.swap(other.ordering_); + index_.swap(other.index_); + std::swap(max_size_, other.max_size_); + } + + // Erases the item referenced by the given iterator. An iterator to the item + // following it will be returned. The iterator must be valid. + iterator Erase(iterator pos) + { + index_.erase(pos->first); + return ordering_.erase(pos); + } + + // MRUCache entries are often processed in reverse order, so we add this + // convenience function (not typically defined by STL containers). + reverse_iterator Erase(reverse_iterator pos) + { + // We have to actually give it the incremented iterator to delete, since + // the forward iterator that base() returns is actually one past the item + // being iterated over. + return reverse_iterator(Erase((++pos).base())); + } + + // Shrinks the cache so it only holds |new_size| items. If |new_size| is + // bigger or equal to the current number of items, this will do nothing. + void ShrinkToSize(size_type new_size) + { + for (size_type i = size(); i > new_size; i--) + Erase(rbegin()); + } + + // Deletes everything from the cache. + void Clear() + { + index_.clear(); + ordering_.clear(); + } + + // Returns the number of elements in the cache. + size_type size() const + { + // We don't use ordering_.size() for the return value because + // (as a linked list) it can be O(n). + DCHECK(index_.size() == ordering_.size()); + return index_.size(); + } + + // Allows iteration over the list. Forward iteration starts with the most + // recent item and works backwards. + // + // Note that since these iterators are actually iterators over a list, you + // can keep them as you insert or delete things (as long as you don't delete + // the one you are pointing to) and they will still be valid. + iterator begin() { return ordering_.begin(); } + const_iterator begin() const { return ordering_.begin(); } + iterator end() { return ordering_.end(); } + const_iterator end() const { return ordering_.end(); } + + reverse_iterator rbegin() { return ordering_.rbegin(); } + const_reverse_iterator rbegin() const { return ordering_.rbegin(); } + reverse_iterator rend() { return ordering_.rend(); } + const_reverse_iterator rend() const { return ordering_.rend(); } + + bool empty() const { return ordering_.empty(); } + + private: + PayloadList ordering_; + KeyIndex index_; + + size_type max_size_; + + DISALLOW_COPY_AND_ASSIGN(MRUCacheBase); +}; + +// MRUCache -------------------------------------------------------------------- + +// A container that does not do anything to free its data. Use this when storing +// value types (as opposed to pointers) in the list. +template > +class MRUCache : public MRUCacheBase +{ + private: + using ParentType = MRUCacheBase; + + public: + // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. + explicit MRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {} + virtual ~MRUCache() {} + + private: + DISALLOW_COPY_AND_ASSIGN(MRUCache); +}; + +// HashingMRUCache ------------------------------------------------------------ + +template +struct MRUCacheHashMap +{ + typedef std::unordered_map Type; +}; + +// This class is similar to MRUCache, except that it uses std::unordered_map as +// the map type instead of std::map. Note that your KeyType must be hashable to +// use this cache or you need to provide a hashing class. +template > +class HashingMRUCache : public MRUCacheBase +{ + private: + using ParentType = MRUCacheBase; + + public: + // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. + explicit HashingMRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {} + virtual ~HashingMRUCache() override {} + + private: + DISALLOW_COPY_AND_ASSIGN(HashingMRUCache); +}; + +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_CONTAINERS_MRU_CACHE_H_ diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h new file mode 100644 index 0000000000..73f81e87f2 --- /dev/null +++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h @@ -0,0 +1,26 @@ +// +// Copyright 2016 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. +// +// logging.h: Compatiblity hacks for importing Chromium's base/numerics. + +#ifndef ANGLEBASE_LOGGING_H_ +#define ANGLEBASE_LOGGING_H_ + +#include "common/debug.h" + +#ifndef DCHECK +# define DCHECK(X) ASSERT(X) +#endif + +#ifndef CHECK +# define CHECK(X) ASSERT(X) +#endif + +// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect. +#ifndef NOTREACHED +# define NOTREACHED() ({ UNREACHABLE(); }) +#endif + +#endif // ANGLEBASE_LOGGING_H_ diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h new file mode 100644 index 0000000000..06391784e4 --- /dev/null +++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h @@ -0,0 +1,17 @@ +// +// Copyright 2017 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. +// +// macros.h: Compatiblity hacks for importing Chromium's MRUCache. + +#ifndef ANGLEBASE_MACROS_H_ +#define ANGLEBASE_MACROS_H_ + +// A macro to disallow the copy constructor and operator= functions. +// This should be used in the private: declarations for a class. +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName &) = delete; \ + void operator=(const TypeName &) = delete + +#endif // ANGLEBASE_MACROS_H_ diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h new file mode 100644 index 0000000000..5090dd9817 --- /dev/null +++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h @@ -0,0 +1,106 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANGLEBASE_NO_DESTRUCTOR_H_ +#define ANGLEBASE_NO_DESTRUCTOR_H_ + +#include +#include + +namespace angle +{ + +namespace base +{ + +// A wrapper that makes it easy to create an object of type T with static +// storage duration that: +// - is only constructed on first access +// - never invokes the destructor +// in order to satisfy the styleguide ban on global constructors and +// destructors. +// +// Runtime constant example: +// const std::string& GetLineSeparator() { +// // Forwards to std::string(size_t, char, const Allocator&) constructor. +// static const base::NoDestructor s(5, '-'); +// return *s; +// } +// +// More complex initialization with a lambda: +// const std::string& GetSessionNonce() { +// static const base::NoDestructor nonce([] { +// std::string s(16); +// crypto::RandString(s.data(), s.size()); +// return s; +// }()); +// return *nonce; +// } +// +// NoDestructor stores the object inline, so it also avoids a pointer +// indirection and a malloc. Also note that since C++11 static local variable +// initialization is thread-safe and so is this pattern. Code should prefer to +// use NoDestructor over: +// - A function scoped static T* or T& that is dynamically initialized. +// - A global base::LazyInstance. +// +// Note that since the destructor is never run, this *will* leak memory if used +// as a stack or member variable. Furthermore, a NoDestructor should never +// have global scope as that may require a static initializer. +template +class NoDestructor +{ + public: + // Not constexpr; just write static constexpr T x = ...; if the value should + // be a constexpr. + template + explicit NoDestructor(Args &&... args) + { + new (storage_) T(std::forward(args)...); + } + + // Allows copy and move construction of the contained type, to allow + // construction from an initializer list, e.g. for std::vector. + explicit NoDestructor(const T &x) { new (storage_) T(x); } + explicit NoDestructor(T &&x) { new (storage_) T(std::move(x)); } + + NoDestructor(const NoDestructor &) = delete; + NoDestructor &operator=(const NoDestructor &) = delete; + + ~NoDestructor() = default; + + const T &operator*() const { return *get(); } + T &operator*() { return *get(); } + + const T *operator->() const { return get(); } + T *operator->() { return get(); } + + const T *get() const { return reinterpret_cast(storage_); } + T *get() { return reinterpret_cast(storage_); } + + private: + alignas(T) char storage_[sizeof(T)]; + +#if defined(LEAK_SANITIZER) + // TODO(https://crbug.com/812277): This is a hack to work around the fact + // that LSan doesn't seem to treat NoDestructor as a root for reachability + // analysis. This means that code like this: + // static base::NoDestructor> v({1, 2, 3}); + // is considered a leak. Using the standard leak sanitizer annotations to + // suppress leaks doesn't work: std::vector is implicitly constructed before + // calling the base::NoDestructor constructor. + // + // Unfortunately, I haven't been able to demonstrate this issue in simpler + // reproductions: until that's resolved, hold an explicit pointer to the + // placement-new'd object in leak sanitizer mode to help LSan realize that + // objects allocated by the contained type are still reachable. + T *storage_ptr_ = reinterpret_cast(storage_); +#endif // defined(LEAK_SANITIZER) +}; + +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_NO_DESTRUCTOR_H_ diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h new file mode 100644 index 0000000000..18bceb7468 --- /dev/null +++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h @@ -0,0 +1,384 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_NUMERICS_CHECKED_MATH_H_ +#define BASE_NUMERICS_CHECKED_MATH_H_ + +#include + +#include +#include + +#include "anglebase/numerics/checked_math_impl.h" + +namespace angle +{ +namespace base +{ +namespace internal +{ + +template +class CheckedNumeric +{ + static_assert(std::is_arithmetic::value, "CheckedNumeric: T must be a numeric type."); + + public: + template + friend class CheckedNumeric; + + using type = T; + + constexpr CheckedNumeric() = default; + + // Copy constructor. + template + constexpr CheckedNumeric(const CheckedNumeric &rhs) + : state_(rhs.state_.value(), rhs.IsValid()) + {} + + // This is not an explicit constructor because we implicitly upgrade regular + // numerics to CheckedNumerics to make them easier to use. + template + constexpr CheckedNumeric(Src value) // NOLINT(runtime/explicit) + : state_(value) + { + static_assert(std::is_arithmetic::value, "Argument must be numeric."); + } + + // This is not an explicit constructor because we want a seamless conversion + // from StrictNumeric types. + template + constexpr CheckedNumeric(StrictNumeric value) // NOLINT(runtime/explicit) + : state_(static_cast(value)) + {} + + // IsValid() - The public API to test if a CheckedNumeric is currently valid. + // A range checked destination type can be supplied using the Dst template + // parameter. + template + constexpr bool IsValid() const + { + return state_.is_valid() && IsValueInRangeForNumericType(state_.value()); + } + + // AssignIfValid(Dst) - Assigns the underlying value if it is currently valid + // and is within the range supported by the destination type. Returns true if + // successful and false otherwise. + template +#if defined(__clang__) || defined(__GNUC__) + __attribute__((warn_unused_result)) +#elif defined(_MSC_VER) + _Check_return_ +#endif + constexpr bool + AssignIfValid(Dst *result) const + { + return BASE_NUMERICS_LIKELY(IsValid()) + ? ((*result = static_cast(state_.value())), true) + : false; + } + + // ValueOrDie() - The primary accessor for the underlying value. If the + // current state is not valid it will CHECK and crash. + // A range checked destination type can be supplied using the Dst template + // parameter, which will trigger a CHECK if the value is not in bounds for + // the destination. + // The CHECK behavior can be overridden by supplying a handler as a + // template parameter, for test code, etc. However, the handler cannot access + // the underlying value, and it is not available through other means. + template + constexpr StrictNumeric ValueOrDie() const + { + return BASE_NUMERICS_LIKELY(IsValid()) ? static_cast(state_.value()) + : CheckHandler::template HandleFailure(); + } + + // ValueOrDefault(T default_value) - A convenience method that returns the + // current value if the state is valid, and the supplied default_value for + // any other state. + // A range checked destination type can be supplied using the Dst template + // parameter. WARNING: This function may fail to compile or CHECK at runtime + // if the supplied default_value is not within range of the destination type. + template + constexpr StrictNumeric ValueOrDefault(const Src default_value) const + { + return BASE_NUMERICS_LIKELY(IsValid()) ? static_cast(state_.value()) + : checked_cast(default_value); + } + + // Returns a checked numeric of the specified type, cast from the current + // CheckedNumeric. If the current state is invalid or the destination cannot + // represent the result then the returned CheckedNumeric will be invalid. + template + constexpr CheckedNumeric::type> Cast() const + { + return *this; + } + + // This friend method is available solely for providing more detailed logging + // in the tests. Do not implement it in production code, because the + // underlying values may change at any time. + template + friend U GetNumericValueForTest(const CheckedNumeric &src); + + // Prototypes for the supported arithmetic operator overloads. + template + constexpr CheckedNumeric &operator+=(const Src rhs); + template + constexpr CheckedNumeric &operator-=(const Src rhs); + template + constexpr CheckedNumeric &operator*=(const Src rhs); + template + constexpr CheckedNumeric &operator/=(const Src rhs); + template + constexpr CheckedNumeric &operator%=(const Src rhs); + template + constexpr CheckedNumeric &operator<<=(const Src rhs); + template + constexpr CheckedNumeric &operator>>=(const Src rhs); + template + constexpr CheckedNumeric &operator&=(const Src rhs); + template + constexpr CheckedNumeric &operator|=(const Src rhs); + template + constexpr CheckedNumeric &operator^=(const Src rhs); + + constexpr CheckedNumeric operator-() const + { + // Use an optimized code path for a known run-time variable. + if (!MustTreatAsConstexpr(state_.value()) && std::is_signed::value && + std::is_floating_point::value) + { + return FastRuntimeNegate(); + } + // The negation of two's complement int min is int min. + const bool is_valid = + IsValid() && (!std::is_signed::value || std::is_floating_point::value || + NegateWrapper(state_.value()) != std::numeric_limits::lowest()); + return CheckedNumeric(NegateWrapper(state_.value()), is_valid); + } + + constexpr CheckedNumeric operator~() const + { + return CheckedNumeric(InvertWrapper(state_.value()), + IsValid()); + } + + constexpr CheckedNumeric Abs() const + { + return !IsValueNegative(state_.value()) ? *this : -*this; + } + + template + constexpr CheckedNumeric::type> Max(const U rhs) const + { + return CheckMax(*this, rhs); + } + + template + constexpr CheckedNumeric::type> Min(const U rhs) const + { + return CheckMin(*this, rhs); + } + + // This function is available only for integral types. It returns an unsigned + // integer of the same width as the source type, containing the absolute value + // of the source, and properly handling signed min. + constexpr CheckedNumeric::type> UnsignedAbs() const + { + return CheckedNumeric::type>( + SafeUnsignedAbs(state_.value()), state_.is_valid()); + } + + constexpr CheckedNumeric &operator++() + { + *this += 1; + return *this; + } + + constexpr CheckedNumeric operator++(int) + { + CheckedNumeric value = *this; + *this += 1; + return value; + } + + constexpr CheckedNumeric &operator--() + { + *this -= 1; + return *this; + } + + constexpr CheckedNumeric operator--(int) + { + // TODO(pkasting): Consider std::exchange() once it's constexpr in C++20. + const CheckedNumeric value = *this; + *this -= 1; + return value; + } + + // These perform the actual math operations on the CheckedNumerics. + // Binary arithmetic operations. + template