1cb93a386Sopenharmony_ci// Copyright 2017 The ANGLE Project Authors. All rights reserved. 2cb93a386Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 3cb93a386Sopenharmony_ci// found in the LICENSE file. 4cb93a386Sopenharmony_ci// 5cb93a386Sopenharmony_ci// PackedGLEnums_autogen.h: 6cb93a386Sopenharmony_ci// Declares ANGLE-specific enums classes for GLEnum and functions operating 7cb93a386Sopenharmony_ci// on them. 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#ifndef COMMON_PACKEDGLENUMS_H_ 10cb93a386Sopenharmony_ci#define COMMON_PACKEDGLENUMS_H_ 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "common/PackedEGLEnums_autogen.h" 13cb93a386Sopenharmony_ci#include "common/PackedGLEnums_autogen.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci#include <array> 16cb93a386Sopenharmony_ci#include <bitset> 17cb93a386Sopenharmony_ci#include <cstddef> 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#include <EGL/egl.h> 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci#include "common/bitset_utils.h" 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_cinamespace angle 24cb93a386Sopenharmony_ci{ 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci// Return the number of elements of a packed enum, including the InvalidEnum element. 27cb93a386Sopenharmony_citemplate <typename E> 28cb93a386Sopenharmony_ciconstexpr size_t EnumSize() 29cb93a386Sopenharmony_ci{ 30cb93a386Sopenharmony_ci using UnderlyingType = typename std::underlying_type<E>::type; 31cb93a386Sopenharmony_ci return static_cast<UnderlyingType>(E::EnumCount); 32cb93a386Sopenharmony_ci} 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci// Implementation of AllEnums which allows iterating over all the possible values for a packed enums 35cb93a386Sopenharmony_ci// like so: 36cb93a386Sopenharmony_ci// for (auto value : AllEnums<MyPackedEnum>()) { 37cb93a386Sopenharmony_ci// // Do something with the enum. 38cb93a386Sopenharmony_ci// } 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_citemplate <typename E> 41cb93a386Sopenharmony_ciclass EnumIterator final 42cb93a386Sopenharmony_ci{ 43cb93a386Sopenharmony_ci private: 44cb93a386Sopenharmony_ci using UnderlyingType = typename std::underlying_type<E>::type; 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci public: 47cb93a386Sopenharmony_ci EnumIterator(E value) : mValue(static_cast<UnderlyingType>(value)) {} 48cb93a386Sopenharmony_ci EnumIterator &operator++() 49cb93a386Sopenharmony_ci { 50cb93a386Sopenharmony_ci mValue++; 51cb93a386Sopenharmony_ci return *this; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci bool operator==(const EnumIterator &other) const { return mValue == other.mValue; } 54cb93a386Sopenharmony_ci bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; } 55cb93a386Sopenharmony_ci E operator*() const { return static_cast<E>(mValue); } 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci private: 58cb93a386Sopenharmony_ci UnderlyingType mValue; 59cb93a386Sopenharmony_ci}; 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_citemplate <typename E, size_t MaxSize = EnumSize<E>()> 62cb93a386Sopenharmony_cistruct AllEnums 63cb93a386Sopenharmony_ci{ 64cb93a386Sopenharmony_ci EnumIterator<E> begin() const { return {static_cast<E>(0)}; } 65cb93a386Sopenharmony_ci EnumIterator<E> end() const { return {static_cast<E>(MaxSize)}; } 66cb93a386Sopenharmony_ci}; 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci// PackedEnumMap<E, T> is like an std::array<T, E::EnumCount> but is indexed with enum values. It 69cb93a386Sopenharmony_ci// implements all of the std::array interface except with enum values instead of indices. 70cb93a386Sopenharmony_citemplate <typename E, typename T, size_t MaxSize = EnumSize<E>()> 71cb93a386Sopenharmony_ciclass PackedEnumMap 72cb93a386Sopenharmony_ci{ 73cb93a386Sopenharmony_ci using UnderlyingType = typename std::underlying_type<E>::type; 74cb93a386Sopenharmony_ci using Storage = std::array<T, MaxSize>; 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci public: 77cb93a386Sopenharmony_ci using InitPair = std::pair<E, T>; 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ci constexpr PackedEnumMap() = default; 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci constexpr PackedEnumMap(std::initializer_list<InitPair> init) : mPrivateData{} 82cb93a386Sopenharmony_ci { 83cb93a386Sopenharmony_ci // We use a for loop instead of range-for to work around a limitation in MSVC. 84cb93a386Sopenharmony_ci for (const InitPair *it = init.begin(); it != init.end(); ++it) 85cb93a386Sopenharmony_ci { 86cb93a386Sopenharmony_ci#if (__cplusplus < 201703L) 87cb93a386Sopenharmony_ci // This horrible const_cast pattern is necessary to work around a constexpr limitation. 88cb93a386Sopenharmony_ci // See https://stackoverflow.com/q/34199774/ . Note that it should be fixed with C++17. 89cb93a386Sopenharmony_ci const_cast<T &>(const_cast<const Storage &>( 90cb93a386Sopenharmony_ci mPrivateData)[static_cast<UnderlyingType>(it->first)]) = it->second; 91cb93a386Sopenharmony_ci#else 92cb93a386Sopenharmony_ci mPrivateData[static_cast<UnderlyingType>(it->first)] = it->second; 93cb93a386Sopenharmony_ci#endif 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci // types: 98cb93a386Sopenharmony_ci using value_type = T; 99cb93a386Sopenharmony_ci using pointer = T *; 100cb93a386Sopenharmony_ci using const_pointer = const T *; 101cb93a386Sopenharmony_ci using reference = T &; 102cb93a386Sopenharmony_ci using const_reference = const T &; 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci using size_type = size_t; 105cb93a386Sopenharmony_ci using difference_type = ptrdiff_t; 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci using iterator = typename Storage::iterator; 108cb93a386Sopenharmony_ci using const_iterator = typename Storage::const_iterator; 109cb93a386Sopenharmony_ci using reverse_iterator = std::reverse_iterator<iterator>; 110cb93a386Sopenharmony_ci using const_reverse_iterator = std::reverse_iterator<const_iterator>; 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci // No explicit construct/copy/destroy for aggregate type 113cb93a386Sopenharmony_ci void fill(const T &u) { mPrivateData.fill(u); } 114cb93a386Sopenharmony_ci void swap(PackedEnumMap<E, T, MaxSize> &a) noexcept { mPrivateData.swap(a.mPrivateData); } 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci // iterators: 117cb93a386Sopenharmony_ci iterator begin() noexcept { return mPrivateData.begin(); } 118cb93a386Sopenharmony_ci const_iterator begin() const noexcept { return mPrivateData.begin(); } 119cb93a386Sopenharmony_ci iterator end() noexcept { return mPrivateData.end(); } 120cb93a386Sopenharmony_ci const_iterator end() const noexcept { return mPrivateData.end(); } 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci reverse_iterator rbegin() noexcept { return mPrivateData.rbegin(); } 123cb93a386Sopenharmony_ci const_reverse_iterator rbegin() const noexcept { return mPrivateData.rbegin(); } 124cb93a386Sopenharmony_ci reverse_iterator rend() noexcept { return mPrivateData.rend(); } 125cb93a386Sopenharmony_ci const_reverse_iterator rend() const noexcept { return mPrivateData.rend(); } 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci // capacity: 128cb93a386Sopenharmony_ci constexpr size_type size() const noexcept { return mPrivateData.size(); } 129cb93a386Sopenharmony_ci constexpr size_type max_size() const noexcept { return mPrivateData.max_size(); } 130cb93a386Sopenharmony_ci constexpr bool empty() const noexcept { return mPrivateData.empty(); } 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci // element access: 133cb93a386Sopenharmony_ci reference operator[](E n) 134cb93a386Sopenharmony_ci { 135cb93a386Sopenharmony_ci ASSERT(static_cast<size_t>(n) < mPrivateData.size()); 136cb93a386Sopenharmony_ci return mPrivateData[static_cast<UnderlyingType>(n)]; 137cb93a386Sopenharmony_ci } 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci constexpr const_reference operator[](E n) const 140cb93a386Sopenharmony_ci { 141cb93a386Sopenharmony_ci ASSERT(static_cast<size_t>(n) < mPrivateData.size()); 142cb93a386Sopenharmony_ci return mPrivateData[static_cast<UnderlyingType>(n)]; 143cb93a386Sopenharmony_ci } 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci const_reference at(E n) const { return mPrivateData.at(static_cast<UnderlyingType>(n)); } 146cb93a386Sopenharmony_ci reference at(E n) { return mPrivateData.at(static_cast<UnderlyingType>(n)); } 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci reference front() { return mPrivateData.front(); } 149cb93a386Sopenharmony_ci const_reference front() const { return mPrivateData.front(); } 150cb93a386Sopenharmony_ci reference back() { return mPrivateData.back(); } 151cb93a386Sopenharmony_ci const_reference back() const { return mPrivateData.back(); } 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci T *data() noexcept { return mPrivateData.data(); } 154cb93a386Sopenharmony_ci const T *data() const noexcept { return mPrivateData.data(); } 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_ci bool operator==(const PackedEnumMap &rhs) const { return mPrivateData == rhs.mPrivateData; } 157cb93a386Sopenharmony_ci bool operator!=(const PackedEnumMap &rhs) const { return mPrivateData != rhs.mPrivateData; } 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci template <typename SubT = T> 160cb93a386Sopenharmony_ci typename std::enable_if<std::is_integral<SubT>::value>::type operator+=( 161cb93a386Sopenharmony_ci const PackedEnumMap<E, SubT, MaxSize> &rhs) 162cb93a386Sopenharmony_ci { 163cb93a386Sopenharmony_ci for (E e : AllEnums<E, MaxSize>()) 164cb93a386Sopenharmony_ci { 165cb93a386Sopenharmony_ci at(e) += rhs[e]; 166cb93a386Sopenharmony_ci } 167cb93a386Sopenharmony_ci } 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci private: 170cb93a386Sopenharmony_ci Storage mPrivateData; 171cb93a386Sopenharmony_ci}; 172cb93a386Sopenharmony_ci 173cb93a386Sopenharmony_ci// PackedEnumBitSetE> is like an std::bitset<E::EnumCount> but is indexed with enum values. It 174cb93a386Sopenharmony_ci// implements the std::bitset interface except with enum values instead of indices. 175cb93a386Sopenharmony_citemplate <typename E, typename DataT = uint32_t> 176cb93a386Sopenharmony_ciusing PackedEnumBitSet = BitSetT<EnumSize<E>(), DataT, E>; 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci} // namespace angle 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_cinamespace gl 181cb93a386Sopenharmony_ci{ 182cb93a386Sopenharmony_ci 183cb93a386Sopenharmony_ciTextureType TextureTargetToType(TextureTarget target); 184cb93a386Sopenharmony_ciTextureTarget NonCubeTextureTypeToTarget(TextureType type); 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_ciTextureTarget CubeFaceIndexToTextureTarget(size_t face); 187cb93a386Sopenharmony_cisize_t CubeMapTextureTargetToFaceIndex(TextureTarget target); 188cb93a386Sopenharmony_cibool IsCubeMapFaceTarget(TextureTarget target); 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ciconstexpr TextureTarget kCubeMapTextureTargetMin = TextureTarget::CubeMapPositiveX; 191cb93a386Sopenharmony_ciconstexpr TextureTarget kCubeMapTextureTargetMax = TextureTarget::CubeMapNegativeZ; 192cb93a386Sopenharmony_ciconstexpr TextureTarget kAfterCubeMapTextureTargetMax = 193cb93a386Sopenharmony_ci static_cast<TextureTarget>(static_cast<uint8_t>(kCubeMapTextureTargetMax) + 1); 194cb93a386Sopenharmony_cistruct AllCubeFaceTextureTargets 195cb93a386Sopenharmony_ci{ 196cb93a386Sopenharmony_ci angle::EnumIterator<TextureTarget> begin() const { return kCubeMapTextureTargetMin; } 197cb93a386Sopenharmony_ci angle::EnumIterator<TextureTarget> end() const { return kAfterCubeMapTextureTargetMax; } 198cb93a386Sopenharmony_ci}; 199cb93a386Sopenharmony_ci 200cb93a386Sopenharmony_ciconstexpr std::array<ShaderType, 2> kAllGLES2ShaderTypes = {ShaderType::Vertex, 201cb93a386Sopenharmony_ci ShaderType::Fragment}; 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ciconstexpr ShaderType kShaderTypeMin = ShaderType::Vertex; 204cb93a386Sopenharmony_ciconstexpr ShaderType kShaderTypeMax = ShaderType::Compute; 205cb93a386Sopenharmony_ciconstexpr ShaderType kAfterShaderTypeMax = 206cb93a386Sopenharmony_ci static_cast<ShaderType>(static_cast<uint8_t>(kShaderTypeMax) + 1); 207cb93a386Sopenharmony_cistruct AllShaderTypes 208cb93a386Sopenharmony_ci{ 209cb93a386Sopenharmony_ci angle::EnumIterator<ShaderType> begin() const { return kShaderTypeMin; } 210cb93a386Sopenharmony_ci angle::EnumIterator<ShaderType> end() const { return kAfterShaderTypeMax; } 211cb93a386Sopenharmony_ci}; 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_ciconstexpr size_t kGraphicsShaderCount = static_cast<size_t>(ShaderType::EnumCount) - 1u; 214cb93a386Sopenharmony_ci// Arrange the shader types in the order of rendering pipeline 215cb93a386Sopenharmony_ciconstexpr std::array<ShaderType, kGraphicsShaderCount> kAllGraphicsShaderTypes = { 216cb93a386Sopenharmony_ci ShaderType::Vertex, ShaderType::TessControl, ShaderType::TessEvaluation, ShaderType::Geometry, 217cb93a386Sopenharmony_ci ShaderType::Fragment}; 218cb93a386Sopenharmony_ci 219cb93a386Sopenharmony_ciusing ShaderBitSet = angle::PackedEnumBitSet<ShaderType, uint8_t>; 220cb93a386Sopenharmony_cistatic_assert(sizeof(ShaderBitSet) == sizeof(uint8_t), "Unexpected size"); 221cb93a386Sopenharmony_ci 222cb93a386Sopenharmony_citemplate <typename T> 223cb93a386Sopenharmony_ciusing ShaderMap = angle::PackedEnumMap<ShaderType, T>; 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_ciconst char *ShaderTypeToString(ShaderType shaderType); 226cb93a386Sopenharmony_ci 227cb93a386Sopenharmony_ciTextureType SamplerTypeToTextureType(GLenum samplerType); 228cb93a386Sopenharmony_ciTextureType ImageTypeToTextureType(GLenum imageType); 229cb93a386Sopenharmony_ci 230cb93a386Sopenharmony_cibool IsMultisampled(gl::TextureType type); 231cb93a386Sopenharmony_cibool IsArrayTextureType(gl::TextureType type); 232cb93a386Sopenharmony_ci 233cb93a386Sopenharmony_cibool IsStaticBufferUsage(BufferUsage useage); 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_cienum class PrimitiveMode : uint8_t 236cb93a386Sopenharmony_ci{ 237cb93a386Sopenharmony_ci Points = 0x0, 238cb93a386Sopenharmony_ci Lines = 0x1, 239cb93a386Sopenharmony_ci LineLoop = 0x2, 240cb93a386Sopenharmony_ci LineStrip = 0x3, 241cb93a386Sopenharmony_ci Triangles = 0x4, 242cb93a386Sopenharmony_ci TriangleStrip = 0x5, 243cb93a386Sopenharmony_ci TriangleFan = 0x6, 244cb93a386Sopenharmony_ci Unused1 = 0x7, 245cb93a386Sopenharmony_ci Unused2 = 0x8, 246cb93a386Sopenharmony_ci Unused3 = 0x9, 247cb93a386Sopenharmony_ci LinesAdjacency = 0xA, 248cb93a386Sopenharmony_ci LineStripAdjacency = 0xB, 249cb93a386Sopenharmony_ci TrianglesAdjacency = 0xC, 250cb93a386Sopenharmony_ci TriangleStripAdjacency = 0xD, 251cb93a386Sopenharmony_ci Patches = 0xE, 252cb93a386Sopenharmony_ci 253cb93a386Sopenharmony_ci InvalidEnum = 0xF, 254cb93a386Sopenharmony_ci EnumCount = 0xF, 255cb93a386Sopenharmony_ci}; 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_citemplate <> 258cb93a386Sopenharmony_ciconstexpr PrimitiveMode FromGLenum<PrimitiveMode>(GLenum from) 259cb93a386Sopenharmony_ci{ 260cb93a386Sopenharmony_ci if (from >= static_cast<GLenum>(PrimitiveMode::EnumCount)) 261cb93a386Sopenharmony_ci { 262cb93a386Sopenharmony_ci return PrimitiveMode::InvalidEnum; 263cb93a386Sopenharmony_ci } 264cb93a386Sopenharmony_ci 265cb93a386Sopenharmony_ci return static_cast<PrimitiveMode>(from); 266cb93a386Sopenharmony_ci} 267cb93a386Sopenharmony_ci 268cb93a386Sopenharmony_ciconstexpr GLenum ToGLenum(PrimitiveMode from) 269cb93a386Sopenharmony_ci{ 270cb93a386Sopenharmony_ci return static_cast<GLenum>(from); 271cb93a386Sopenharmony_ci} 272cb93a386Sopenharmony_ci 273cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::Points) == GL_POINTS, "PrimitiveMode violation"); 274cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::Lines) == GL_LINES, "PrimitiveMode violation"); 275cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::LineLoop) == GL_LINE_LOOP, "PrimitiveMode violation"); 276cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::LineStrip) == GL_LINE_STRIP, "PrimitiveMode violation"); 277cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::Triangles) == GL_TRIANGLES, "PrimitiveMode violation"); 278cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::TriangleStrip) == GL_TRIANGLE_STRIP, 279cb93a386Sopenharmony_ci "PrimitiveMode violation"); 280cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::TriangleFan) == GL_TRIANGLE_FAN, "PrimitiveMode violation"); 281cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::LinesAdjacency) == GL_LINES_ADJACENCY, 282cb93a386Sopenharmony_ci "PrimitiveMode violation"); 283cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::LineStripAdjacency) == GL_LINE_STRIP_ADJACENCY, 284cb93a386Sopenharmony_ci "PrimitiveMode violation"); 285cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::TrianglesAdjacency) == GL_TRIANGLES_ADJACENCY, 286cb93a386Sopenharmony_ci "PrimitiveMode violation"); 287cb93a386Sopenharmony_cistatic_assert(ToGLenum(PrimitiveMode::TriangleStripAdjacency) == GL_TRIANGLE_STRIP_ADJACENCY, 288cb93a386Sopenharmony_ci "PrimitiveMode violation"); 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_cistd::ostream &operator<<(std::ostream &os, PrimitiveMode value); 291cb93a386Sopenharmony_ci 292cb93a386Sopenharmony_cienum class DrawElementsType : size_t 293cb93a386Sopenharmony_ci{ 294cb93a386Sopenharmony_ci UnsignedByte = 0, 295cb93a386Sopenharmony_ci UnsignedShort = 1, 296cb93a386Sopenharmony_ci UnsignedInt = 2, 297cb93a386Sopenharmony_ci InvalidEnum = 3, 298cb93a386Sopenharmony_ci EnumCount = 3, 299cb93a386Sopenharmony_ci}; 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_citemplate <> 302cb93a386Sopenharmony_ciconstexpr DrawElementsType FromGLenum<DrawElementsType>(GLenum from) 303cb93a386Sopenharmony_ci{ 304cb93a386Sopenharmony_ci 305cb93a386Sopenharmony_ci GLenum scaled = (from - GL_UNSIGNED_BYTE); 306cb93a386Sopenharmony_ci // This code sequence generates a ROR instruction on x86/arm. We want to check if the lowest bit 307cb93a386Sopenharmony_ci // of scaled is set and if (scaled >> 1) is greater than a non-pot value. If we rotate the 308cb93a386Sopenharmony_ci // lowest bit to the hightest bit both conditions can be checked with a single test. 309cb93a386Sopenharmony_ci static_assert(sizeof(GLenum) == 4, "Update (scaled << 31) to sizeof(GLenum) * 8 - 1"); 310cb93a386Sopenharmony_ci GLenum packed = (scaled >> 1) | (scaled << 31); 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_ci // operator ? with a simple assignment usually translates to a cmov instruction and thus avoids 313cb93a386Sopenharmony_ci // a branch. 314cb93a386Sopenharmony_ci packed = (packed >= static_cast<GLenum>(DrawElementsType::EnumCount)) 315cb93a386Sopenharmony_ci ? static_cast<GLenum>(DrawElementsType::InvalidEnum) 316cb93a386Sopenharmony_ci : packed; 317cb93a386Sopenharmony_ci 318cb93a386Sopenharmony_ci return static_cast<DrawElementsType>(packed); 319cb93a386Sopenharmony_ci} 320cb93a386Sopenharmony_ci 321cb93a386Sopenharmony_ciconstexpr GLenum ToGLenum(DrawElementsType from) 322cb93a386Sopenharmony_ci{ 323cb93a386Sopenharmony_ci return ((static_cast<GLenum>(from) << 1) + GL_UNSIGNED_BYTE); 324cb93a386Sopenharmony_ci} 325cb93a386Sopenharmony_ci 326cb93a386Sopenharmony_ci#define ANGLE_VALIDATE_PACKED_ENUM(type, packed, glenum) \ 327cb93a386Sopenharmony_ci static_assert(ToGLenum(type::packed) == glenum, #type " violation"); \ 328cb93a386Sopenharmony_ci static_assert(FromGLenum<type>(glenum) == type::packed, #type " violation") 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedByte, GL_UNSIGNED_BYTE); 331cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedShort, GL_UNSIGNED_SHORT); 332cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedInt, GL_UNSIGNED_INT); 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_cistd::ostream &operator<<(std::ostream &os, DrawElementsType value); 335cb93a386Sopenharmony_ci 336cb93a386Sopenharmony_cienum class BlendEquationType 337cb93a386Sopenharmony_ci{ 338cb93a386Sopenharmony_ci Add = 0, // GLenum == 0x8006 339cb93a386Sopenharmony_ci Min = 1, // GLenum == 0x8007 340cb93a386Sopenharmony_ci Max = 2, // GLenum == 0x8008 341cb93a386Sopenharmony_ci Unused = 3, 342cb93a386Sopenharmony_ci Subtract = 4, // GLenum == 0x800A 343cb93a386Sopenharmony_ci ReverseSubtract = 5, // GLenum == 0x800B 344cb93a386Sopenharmony_ci InvalidEnum = 6, 345cb93a386Sopenharmony_ci EnumCount = 6 346cb93a386Sopenharmony_ci}; 347cb93a386Sopenharmony_ci 348cb93a386Sopenharmony_citemplate <> 349cb93a386Sopenharmony_ciconstexpr BlendEquationType FromGLenum<BlendEquationType>(GLenum from) 350cb93a386Sopenharmony_ci{ 351cb93a386Sopenharmony_ci const GLenum scaled = (from - GL_FUNC_ADD); 352cb93a386Sopenharmony_ci return (scaled == static_cast<GLenum>(BlendEquationType::Unused) || 353cb93a386Sopenharmony_ci scaled >= static_cast<GLenum>(BlendEquationType::EnumCount)) 354cb93a386Sopenharmony_ci ? BlendEquationType::InvalidEnum 355cb93a386Sopenharmony_ci : static_cast<BlendEquationType>(scaled); 356cb93a386Sopenharmony_ci} 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ciconstexpr GLenum ToGLenum(BlendEquationType from) 359cb93a386Sopenharmony_ci{ 360cb93a386Sopenharmony_ci return static_cast<GLenum>(from) + GL_FUNC_ADD; 361cb93a386Sopenharmony_ci} 362cb93a386Sopenharmony_ci 363cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Add, GL_FUNC_ADD); 364cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Min, GL_MIN); 365cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Max, GL_MAX); 366cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Subtract, GL_FUNC_SUBTRACT); 367cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, ReverseSubtract, GL_FUNC_REVERSE_SUBTRACT); 368cb93a386Sopenharmony_ci 369cb93a386Sopenharmony_cistd::ostream &operator<<(std::ostream &os, BlendEquationType value); 370cb93a386Sopenharmony_ci 371cb93a386Sopenharmony_cienum class BlendFactorType 372cb93a386Sopenharmony_ci{ 373cb93a386Sopenharmony_ci Zero = 0, // GLenum == 0 374cb93a386Sopenharmony_ci One = 1, // GLenum == 1 375cb93a386Sopenharmony_ci 376cb93a386Sopenharmony_ci MinSrcDstType = 2, 377cb93a386Sopenharmony_ci SrcColor = 2, // GLenum == 0x0300 378cb93a386Sopenharmony_ci OneMinusSrcColor = 3, // GLenum == 0x0301 379cb93a386Sopenharmony_ci SrcAlpha = 4, // GLenum == 0x0302 380cb93a386Sopenharmony_ci OneMinusSrcAlpha = 5, // GLenum == 0x0303 381cb93a386Sopenharmony_ci DstAlpha = 6, // GLenum == 0x0304 382cb93a386Sopenharmony_ci OneMinusDstAlpha = 7, // GLenum == 0x0305 383cb93a386Sopenharmony_ci DstColor = 8, // GLenum == 0x0306 384cb93a386Sopenharmony_ci OneMinusDstColor = 9, // GLenum == 0x0307 385cb93a386Sopenharmony_ci SrcAlphaSaturate = 10, // GLenum == 0x0308 386cb93a386Sopenharmony_ci MaxSrcDstType = 10, 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci MinConstantType = 11, 389cb93a386Sopenharmony_ci ConstantColor = 11, // GLenum == 0x8001 390cb93a386Sopenharmony_ci OneMinusConstantColor = 12, // GLenum == 0x8002 391cb93a386Sopenharmony_ci ConstantAlpha = 13, // GLenum == 0x8003 392cb93a386Sopenharmony_ci OneMinusConstantAlpha = 14, // GLenum == 0x8004 393cb93a386Sopenharmony_ci MaxConstantType = 14, 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci // GL_EXT_blend_func_extended 396cb93a386Sopenharmony_ci 397cb93a386Sopenharmony_ci Src1Alpha = 15, // GLenum == 0x8589 398cb93a386Sopenharmony_ci 399cb93a386Sopenharmony_ci Src1Color = 16, // GLenum == 0x88F9 400cb93a386Sopenharmony_ci OneMinusSrc1Color = 17, // GLenum == 0x88FA 401cb93a386Sopenharmony_ci OneMinusSrc1Alpha = 18, // GLenum == 0x88FB 402cb93a386Sopenharmony_ci 403cb93a386Sopenharmony_ci InvalidEnum = 19, 404cb93a386Sopenharmony_ci EnumCount = 19 405cb93a386Sopenharmony_ci}; 406cb93a386Sopenharmony_ci 407cb93a386Sopenharmony_citemplate <> 408cb93a386Sopenharmony_ciconstexpr BlendFactorType FromGLenum<BlendFactorType>(GLenum from) 409cb93a386Sopenharmony_ci{ 410cb93a386Sopenharmony_ci if (from <= 1) 411cb93a386Sopenharmony_ci return static_cast<BlendFactorType>(from); 412cb93a386Sopenharmony_ci if (from >= GL_SRC_COLOR && from <= GL_SRC_ALPHA_SATURATE) 413cb93a386Sopenharmony_ci return static_cast<BlendFactorType>(from - GL_SRC_COLOR + 2); 414cb93a386Sopenharmony_ci if (from >= GL_CONSTANT_COLOR && from <= GL_ONE_MINUS_CONSTANT_ALPHA) 415cb93a386Sopenharmony_ci return static_cast<BlendFactorType>(from - GL_CONSTANT_COLOR + 11); 416cb93a386Sopenharmony_ci if (from == GL_SRC1_ALPHA_EXT) 417cb93a386Sopenharmony_ci return BlendFactorType::Src1Alpha; 418cb93a386Sopenharmony_ci if (from >= GL_SRC1_COLOR_EXT && from <= GL_ONE_MINUS_SRC1_ALPHA_EXT) 419cb93a386Sopenharmony_ci return static_cast<BlendFactorType>(from - GL_SRC1_COLOR_EXT + 16); 420cb93a386Sopenharmony_ci return BlendFactorType::InvalidEnum; 421cb93a386Sopenharmony_ci} 422cb93a386Sopenharmony_ci 423cb93a386Sopenharmony_ciconstexpr GLenum ToGLenum(BlendFactorType from) 424cb93a386Sopenharmony_ci{ 425cb93a386Sopenharmony_ci const GLenum value = static_cast<GLenum>(from); 426cb93a386Sopenharmony_ci if (value <= 1) 427cb93a386Sopenharmony_ci return value; 428cb93a386Sopenharmony_ci if (from >= BlendFactorType::MinSrcDstType && from <= BlendFactorType::MaxSrcDstType) 429cb93a386Sopenharmony_ci return value - 2 + GL_SRC_COLOR; 430cb93a386Sopenharmony_ci if (from >= BlendFactorType::MinConstantType && from <= BlendFactorType::MaxConstantType) 431cb93a386Sopenharmony_ci return value - 11 + GL_CONSTANT_COLOR; 432cb93a386Sopenharmony_ci if (from == BlendFactorType::Src1Alpha) 433cb93a386Sopenharmony_ci return GL_SRC1_ALPHA_EXT; 434cb93a386Sopenharmony_ci return value - 16 + GL_SRC1_COLOR_EXT; 435cb93a386Sopenharmony_ci} 436cb93a386Sopenharmony_ci 437cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Zero, GL_ZERO); 438cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, One, GL_ONE); 439cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcColor, GL_SRC_COLOR); 440cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcColor, GL_ONE_MINUS_SRC_COLOR); 441cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlpha, GL_SRC_ALPHA); 442cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcAlpha, GL_ONE_MINUS_SRC_ALPHA); 443cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstAlpha, GL_DST_ALPHA); 444cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstAlpha, GL_ONE_MINUS_DST_ALPHA); 445cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstColor, GL_DST_COLOR); 446cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstColor, GL_ONE_MINUS_DST_COLOR); 447cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlphaSaturate, GL_SRC_ALPHA_SATURATE); 448cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantColor, GL_CONSTANT_COLOR); 449cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantColor, GL_ONE_MINUS_CONSTANT_COLOR); 450cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantAlpha, GL_CONSTANT_ALPHA); 451cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantAlpha, GL_ONE_MINUS_CONSTANT_ALPHA); 452cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Alpha, GL_SRC1_ALPHA_EXT); 453cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Color, GL_SRC1_COLOR_EXT); 454cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Color, GL_ONE_MINUS_SRC1_COLOR_EXT); 455cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Alpha, GL_ONE_MINUS_SRC1_ALPHA_EXT); 456cb93a386Sopenharmony_ci 457cb93a386Sopenharmony_cistd::ostream &operator<<(std::ostream &os, BlendFactorType value); 458cb93a386Sopenharmony_ci 459cb93a386Sopenharmony_cienum class VertexAttribType 460cb93a386Sopenharmony_ci{ 461cb93a386Sopenharmony_ci Byte = 0, // GLenum == 0x1400 462cb93a386Sopenharmony_ci UnsignedByte = 1, // GLenum == 0x1401 463cb93a386Sopenharmony_ci Short = 2, // GLenum == 0x1402 464cb93a386Sopenharmony_ci UnsignedShort = 3, // GLenum == 0x1403 465cb93a386Sopenharmony_ci Int = 4, // GLenum == 0x1404 466cb93a386Sopenharmony_ci UnsignedInt = 5, // GLenum == 0x1405 467cb93a386Sopenharmony_ci Float = 6, // GLenum == 0x1406 468cb93a386Sopenharmony_ci Unused1 = 7, // GLenum == 0x1407 469cb93a386Sopenharmony_ci Unused2 = 8, // GLenum == 0x1408 470cb93a386Sopenharmony_ci Unused3 = 9, // GLenum == 0x1409 471cb93a386Sopenharmony_ci Unused4 = 10, // GLenum == 0x140A 472cb93a386Sopenharmony_ci HalfFloat = 11, // GLenum == 0x140B 473cb93a386Sopenharmony_ci Fixed = 12, // GLenum == 0x140C 474cb93a386Sopenharmony_ci MaxBasicType = 12, 475cb93a386Sopenharmony_ci UnsignedInt2101010 = 13, // GLenum == 0x8368 476cb93a386Sopenharmony_ci HalfFloatOES = 14, // GLenum == 0x8D61 477cb93a386Sopenharmony_ci Int2101010 = 15, // GLenum == 0x8D9F 478cb93a386Sopenharmony_ci UnsignedInt1010102 = 16, // GLenum == 0x8DF6 479cb93a386Sopenharmony_ci Int1010102 = 17, // GLenum == 0x8DF7 480cb93a386Sopenharmony_ci InvalidEnum = 18, 481cb93a386Sopenharmony_ci EnumCount = 18, 482cb93a386Sopenharmony_ci}; 483cb93a386Sopenharmony_ci 484cb93a386Sopenharmony_citemplate <> 485cb93a386Sopenharmony_ciconstexpr VertexAttribType FromGLenum<VertexAttribType>(GLenum from) 486cb93a386Sopenharmony_ci{ 487cb93a386Sopenharmony_ci GLenum packed = from - GL_BYTE; 488cb93a386Sopenharmony_ci if (packed <= static_cast<GLenum>(VertexAttribType::MaxBasicType)) 489cb93a386Sopenharmony_ci return static_cast<VertexAttribType>(packed); 490cb93a386Sopenharmony_ci if (from == GL_UNSIGNED_INT_2_10_10_10_REV) 491cb93a386Sopenharmony_ci return VertexAttribType::UnsignedInt2101010; 492cb93a386Sopenharmony_ci if (from == GL_HALF_FLOAT_OES) 493cb93a386Sopenharmony_ci return VertexAttribType::HalfFloatOES; 494cb93a386Sopenharmony_ci if (from == GL_INT_2_10_10_10_REV) 495cb93a386Sopenharmony_ci return VertexAttribType::Int2101010; 496cb93a386Sopenharmony_ci if (from == GL_UNSIGNED_INT_10_10_10_2_OES) 497cb93a386Sopenharmony_ci return VertexAttribType::UnsignedInt1010102; 498cb93a386Sopenharmony_ci if (from == GL_INT_10_10_10_2_OES) 499cb93a386Sopenharmony_ci return VertexAttribType::Int1010102; 500cb93a386Sopenharmony_ci return VertexAttribType::InvalidEnum; 501cb93a386Sopenharmony_ci} 502cb93a386Sopenharmony_ci 503cb93a386Sopenharmony_ciconstexpr GLenum ToGLenum(VertexAttribType from) 504cb93a386Sopenharmony_ci{ 505cb93a386Sopenharmony_ci // This could be optimized using a constexpr table. 506cb93a386Sopenharmony_ci if (from == VertexAttribType::Int2101010) 507cb93a386Sopenharmony_ci return GL_INT_2_10_10_10_REV; 508cb93a386Sopenharmony_ci if (from == VertexAttribType::HalfFloatOES) 509cb93a386Sopenharmony_ci return GL_HALF_FLOAT_OES; 510cb93a386Sopenharmony_ci if (from == VertexAttribType::UnsignedInt2101010) 511cb93a386Sopenharmony_ci return GL_UNSIGNED_INT_2_10_10_10_REV; 512cb93a386Sopenharmony_ci if (from == VertexAttribType::UnsignedInt1010102) 513cb93a386Sopenharmony_ci return GL_UNSIGNED_INT_10_10_10_2_OES; 514cb93a386Sopenharmony_ci if (from == VertexAttribType::Int1010102) 515cb93a386Sopenharmony_ci return GL_INT_10_10_10_2_OES; 516cb93a386Sopenharmony_ci return static_cast<GLenum>(from) + GL_BYTE; 517cb93a386Sopenharmony_ci} 518cb93a386Sopenharmony_ci 519cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Byte, GL_BYTE); 520cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedByte, GL_UNSIGNED_BYTE); 521cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Short, GL_SHORT); 522cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedShort, GL_UNSIGNED_SHORT); 523cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int, GL_INT); 524cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt, GL_UNSIGNED_INT); 525cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Float, GL_FLOAT); 526cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloat, GL_HALF_FLOAT); 527cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Fixed, GL_FIXED); 528cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int2101010, GL_INT_2_10_10_10_REV); 529cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloatOES, GL_HALF_FLOAT_OES); 530cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt2101010, GL_UNSIGNED_INT_2_10_10_10_REV); 531cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int1010102, GL_INT_10_10_10_2_OES); 532cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt1010102, GL_UNSIGNED_INT_10_10_10_2_OES); 533cb93a386Sopenharmony_ci 534cb93a386Sopenharmony_cistd::ostream &operator<<(std::ostream &os, VertexAttribType value); 535cb93a386Sopenharmony_ci 536cb93a386Sopenharmony_cienum class TessEvaluationType 537cb93a386Sopenharmony_ci{ 538cb93a386Sopenharmony_ci Triangles = 0, 539cb93a386Sopenharmony_ci Quads = 1, 540cb93a386Sopenharmony_ci Isolines = 2, 541cb93a386Sopenharmony_ci EqualSpacing = 3, 542cb93a386Sopenharmony_ci FractionalEvenSpacing = 4, 543cb93a386Sopenharmony_ci FractionalOddSpacing = 5, 544cb93a386Sopenharmony_ci Cw = 6, 545cb93a386Sopenharmony_ci Ccw = 7, 546cb93a386Sopenharmony_ci PointMode = 8, 547cb93a386Sopenharmony_ci InvalidEnum = 9, 548cb93a386Sopenharmony_ci EnumCount = 9 549cb93a386Sopenharmony_ci}; 550cb93a386Sopenharmony_ci 551cb93a386Sopenharmony_citemplate <> 552cb93a386Sopenharmony_ciconstexpr TessEvaluationType FromGLenum<TessEvaluationType>(GLenum from) 553cb93a386Sopenharmony_ci{ 554cb93a386Sopenharmony_ci if (from == GL_TRIANGLES) 555cb93a386Sopenharmony_ci return TessEvaluationType::Triangles; 556cb93a386Sopenharmony_ci if (from == GL_QUADS) 557cb93a386Sopenharmony_ci return TessEvaluationType::Quads; 558cb93a386Sopenharmony_ci if (from == GL_ISOLINES) 559cb93a386Sopenharmony_ci return TessEvaluationType::Isolines; 560cb93a386Sopenharmony_ci if (from == GL_EQUAL) 561cb93a386Sopenharmony_ci return TessEvaluationType::EqualSpacing; 562cb93a386Sopenharmony_ci if (from == GL_FRACTIONAL_EVEN) 563cb93a386Sopenharmony_ci return TessEvaluationType::FractionalEvenSpacing; 564cb93a386Sopenharmony_ci if (from == GL_FRACTIONAL_ODD) 565cb93a386Sopenharmony_ci return TessEvaluationType::FractionalOddSpacing; 566cb93a386Sopenharmony_ci if (from == GL_CW) 567cb93a386Sopenharmony_ci return TessEvaluationType::Cw; 568cb93a386Sopenharmony_ci if (from == GL_CCW) 569cb93a386Sopenharmony_ci return TessEvaluationType::Ccw; 570cb93a386Sopenharmony_ci if (from == GL_TESS_GEN_POINT_MODE) 571cb93a386Sopenharmony_ci return TessEvaluationType::PointMode; 572cb93a386Sopenharmony_ci return TessEvaluationType::InvalidEnum; 573cb93a386Sopenharmony_ci} 574cb93a386Sopenharmony_ci 575cb93a386Sopenharmony_ciconstexpr GLenum ToGLenum(TessEvaluationType from) 576cb93a386Sopenharmony_ci{ 577cb93a386Sopenharmony_ci switch (from) 578cb93a386Sopenharmony_ci { 579cb93a386Sopenharmony_ci case TessEvaluationType::Triangles: 580cb93a386Sopenharmony_ci return GL_TRIANGLES; 581cb93a386Sopenharmony_ci case TessEvaluationType::Quads: 582cb93a386Sopenharmony_ci return GL_QUADS; 583cb93a386Sopenharmony_ci case TessEvaluationType::Isolines: 584cb93a386Sopenharmony_ci return GL_ISOLINES; 585cb93a386Sopenharmony_ci case TessEvaluationType::EqualSpacing: 586cb93a386Sopenharmony_ci return GL_EQUAL; 587cb93a386Sopenharmony_ci case TessEvaluationType::FractionalEvenSpacing: 588cb93a386Sopenharmony_ci return GL_FRACTIONAL_EVEN; 589cb93a386Sopenharmony_ci case TessEvaluationType::FractionalOddSpacing: 590cb93a386Sopenharmony_ci return GL_FRACTIONAL_ODD; 591cb93a386Sopenharmony_ci case TessEvaluationType::Cw: 592cb93a386Sopenharmony_ci return GL_CW; 593cb93a386Sopenharmony_ci case TessEvaluationType::Ccw: 594cb93a386Sopenharmony_ci return GL_CCW; 595cb93a386Sopenharmony_ci case TessEvaluationType::PointMode: 596cb93a386Sopenharmony_ci return GL_TESS_GEN_POINT_MODE; 597cb93a386Sopenharmony_ci default: 598cb93a386Sopenharmony_ci return GL_INVALID_ENUM; 599cb93a386Sopenharmony_ci } 600cb93a386Sopenharmony_ci} 601cb93a386Sopenharmony_ci 602cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Triangles, GL_TRIANGLES); 603cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Quads, GL_QUADS); 604cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Isolines, GL_ISOLINES); 605cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, EqualSpacing, GL_EQUAL); 606cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalEvenSpacing, GL_FRACTIONAL_EVEN); 607cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalOddSpacing, GL_FRACTIONAL_ODD); 608cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Cw, GL_CW); 609cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Ccw, GL_CCW); 610cb93a386Sopenharmony_ciANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, PointMode, GL_TESS_GEN_POINT_MODE); 611cb93a386Sopenharmony_ci 612cb93a386Sopenharmony_cistd::ostream &operator<<(std::ostream &os, TessEvaluationType value); 613cb93a386Sopenharmony_ci 614cb93a386Sopenharmony_ci// Typesafe object handles. 615cb93a386Sopenharmony_ci 616cb93a386Sopenharmony_citemplate <typename T> 617cb93a386Sopenharmony_cistruct ResourceTypeToID; 618cb93a386Sopenharmony_ci 619cb93a386Sopenharmony_citemplate <typename T> 620cb93a386Sopenharmony_cistruct IsResourceIDType; 621cb93a386Sopenharmony_ci 622cb93a386Sopenharmony_ci// Clang Format doesn't like the following X macro. 623cb93a386Sopenharmony_ci// clang-format off 624cb93a386Sopenharmony_ci#define ANGLE_ID_TYPES_OP(X) \ 625cb93a386Sopenharmony_ci X(Buffer) \ 626cb93a386Sopenharmony_ci X(FenceNV) \ 627cb93a386Sopenharmony_ci X(Framebuffer) \ 628cb93a386Sopenharmony_ci X(MemoryObject) \ 629cb93a386Sopenharmony_ci X(Path) \ 630cb93a386Sopenharmony_ci X(ProgramPipeline) \ 631cb93a386Sopenharmony_ci X(Query) \ 632cb93a386Sopenharmony_ci X(Renderbuffer) \ 633cb93a386Sopenharmony_ci X(Sampler) \ 634cb93a386Sopenharmony_ci X(Semaphore) \ 635cb93a386Sopenharmony_ci X(Texture) \ 636cb93a386Sopenharmony_ci X(TransformFeedback) \ 637cb93a386Sopenharmony_ci X(VertexArray) 638cb93a386Sopenharmony_ci// clang-format on 639cb93a386Sopenharmony_ci 640cb93a386Sopenharmony_ci#define ANGLE_DEFINE_ID_TYPE(Type) \ 641cb93a386Sopenharmony_ci class Type; \ 642cb93a386Sopenharmony_ci struct Type##ID \ 643cb93a386Sopenharmony_ci { \ 644cb93a386Sopenharmony_ci GLuint value; \ 645cb93a386Sopenharmony_ci }; \ 646cb93a386Sopenharmony_ci template <> \ 647cb93a386Sopenharmony_ci struct ResourceTypeToID<Type> \ 648cb93a386Sopenharmony_ci { \ 649cb93a386Sopenharmony_ci using IDType = Type##ID; \ 650cb93a386Sopenharmony_ci }; \ 651cb93a386Sopenharmony_ci template <> \ 652cb93a386Sopenharmony_ci struct IsResourceIDType<Type##ID> \ 653cb93a386Sopenharmony_ci { \ 654cb93a386Sopenharmony_ci static constexpr bool value = true; \ 655cb93a386Sopenharmony_ci }; 656cb93a386Sopenharmony_ci 657cb93a386Sopenharmony_ciANGLE_ID_TYPES_OP(ANGLE_DEFINE_ID_TYPE) 658cb93a386Sopenharmony_ci 659cb93a386Sopenharmony_ci#undef ANGLE_DEFINE_ID_TYPE 660cb93a386Sopenharmony_ci#undef ANGLE_ID_TYPES_OP 661cb93a386Sopenharmony_ci 662cb93a386Sopenharmony_ci// Shaders and programs are a bit special as they share IDs. 663cb93a386Sopenharmony_cistruct ShaderProgramID 664cb93a386Sopenharmony_ci{ 665cb93a386Sopenharmony_ci GLuint value; 666cb93a386Sopenharmony_ci}; 667cb93a386Sopenharmony_ci 668cb93a386Sopenharmony_citemplate <> 669cb93a386Sopenharmony_cistruct IsResourceIDType<ShaderProgramID> 670cb93a386Sopenharmony_ci{ 671cb93a386Sopenharmony_ci constexpr static bool value = true; 672cb93a386Sopenharmony_ci}; 673cb93a386Sopenharmony_ci 674cb93a386Sopenharmony_ciclass Shader; 675cb93a386Sopenharmony_citemplate <> 676cb93a386Sopenharmony_cistruct ResourceTypeToID<Shader> 677cb93a386Sopenharmony_ci{ 678cb93a386Sopenharmony_ci using IDType = ShaderProgramID; 679cb93a386Sopenharmony_ci}; 680cb93a386Sopenharmony_ci 681cb93a386Sopenharmony_ciclass Program; 682cb93a386Sopenharmony_citemplate <> 683cb93a386Sopenharmony_cistruct ResourceTypeToID<Program> 684cb93a386Sopenharmony_ci{ 685cb93a386Sopenharmony_ci using IDType = ShaderProgramID; 686cb93a386Sopenharmony_ci}; 687cb93a386Sopenharmony_ci 688cb93a386Sopenharmony_citemplate <typename T> 689cb93a386Sopenharmony_cistruct ResourceTypeToID 690cb93a386Sopenharmony_ci{ 691cb93a386Sopenharmony_ci using IDType = void; 692cb93a386Sopenharmony_ci}; 693cb93a386Sopenharmony_ci 694cb93a386Sopenharmony_citemplate <typename T> 695cb93a386Sopenharmony_cistruct IsResourceIDType 696cb93a386Sopenharmony_ci{ 697cb93a386Sopenharmony_ci static constexpr bool value = false; 698cb93a386Sopenharmony_ci}; 699cb93a386Sopenharmony_ci 700cb93a386Sopenharmony_citemplate <typename T> 701cb93a386Sopenharmony_cibool ValueEquals(T lhs, T rhs) 702cb93a386Sopenharmony_ci{ 703cb93a386Sopenharmony_ci return lhs.value == rhs.value; 704cb93a386Sopenharmony_ci} 705cb93a386Sopenharmony_ci 706cb93a386Sopenharmony_ci// Util funcs for resourceIDs 707cb93a386Sopenharmony_citemplate <typename T> 708cb93a386Sopenharmony_citypename std::enable_if<IsResourceIDType<T>::value, bool>::type operator==(const T &lhs, 709cb93a386Sopenharmony_ci const T &rhs) 710cb93a386Sopenharmony_ci{ 711cb93a386Sopenharmony_ci return lhs.value == rhs.value; 712cb93a386Sopenharmony_ci} 713cb93a386Sopenharmony_ci 714cb93a386Sopenharmony_citemplate <typename T> 715cb93a386Sopenharmony_citypename std::enable_if<IsResourceIDType<T>::value, bool>::type operator!=(const T &lhs, 716cb93a386Sopenharmony_ci const T &rhs) 717cb93a386Sopenharmony_ci{ 718cb93a386Sopenharmony_ci return lhs.value != rhs.value; 719cb93a386Sopenharmony_ci} 720cb93a386Sopenharmony_ci 721cb93a386Sopenharmony_citemplate <typename T> 722cb93a386Sopenharmony_citypename std::enable_if<IsResourceIDType<T>::value, bool>::type operator<(const T &lhs, 723cb93a386Sopenharmony_ci const T &rhs) 724cb93a386Sopenharmony_ci{ 725cb93a386Sopenharmony_ci return lhs.value < rhs.value; 726cb93a386Sopenharmony_ci} 727cb93a386Sopenharmony_ci 728cb93a386Sopenharmony_ci// Used to unbox typed values. 729cb93a386Sopenharmony_citemplate <typename ResourceIDType> 730cb93a386Sopenharmony_ciGLuint GetIDValue(ResourceIDType id); 731cb93a386Sopenharmony_ci 732cb93a386Sopenharmony_citemplate <> 733cb93a386Sopenharmony_ciinline GLuint GetIDValue(GLuint id) 734cb93a386Sopenharmony_ci{ 735cb93a386Sopenharmony_ci return id; 736cb93a386Sopenharmony_ci} 737cb93a386Sopenharmony_ci 738cb93a386Sopenharmony_citemplate <typename ResourceIDType> 739cb93a386Sopenharmony_ciinline GLuint GetIDValue(ResourceIDType id) 740cb93a386Sopenharmony_ci{ 741cb93a386Sopenharmony_ci return id.value; 742cb93a386Sopenharmony_ci} 743cb93a386Sopenharmony_ci 744cb93a386Sopenharmony_ci// First case: handling packed enums. 745cb93a386Sopenharmony_citemplate <typename EnumT, typename FromT> 746cb93a386Sopenharmony_citypename std::enable_if<std::is_enum<EnumT>::value, EnumT>::type PackParam(FromT from) 747cb93a386Sopenharmony_ci{ 748cb93a386Sopenharmony_ci return FromGLenum<EnumT>(from); 749cb93a386Sopenharmony_ci} 750cb93a386Sopenharmony_ci 751cb93a386Sopenharmony_ci// Second case: handling non-pointer resource ids. 752cb93a386Sopenharmony_citemplate <typename EnumT, typename FromT> 753cb93a386Sopenharmony_citypename std::enable_if<!std::is_pointer<FromT>::value && !std::is_enum<EnumT>::value, EnumT>::type 754cb93a386Sopenharmony_ciPackParam(FromT from) 755cb93a386Sopenharmony_ci{ 756cb93a386Sopenharmony_ci return {from}; 757cb93a386Sopenharmony_ci} 758cb93a386Sopenharmony_ci 759cb93a386Sopenharmony_ci// Third case: handling pointer resource ids. 760cb93a386Sopenharmony_citemplate <typename EnumT, typename FromT> 761cb93a386Sopenharmony_citypename std::enable_if<std::is_pointer<FromT>::value && !std::is_enum<EnumT>::value, EnumT>::type 762cb93a386Sopenharmony_ciPackParam(FromT from) 763cb93a386Sopenharmony_ci{ 764cb93a386Sopenharmony_ci static_assert(sizeof(typename std::remove_pointer<EnumT>::type) == 765cb93a386Sopenharmony_ci sizeof(typename std::remove_pointer<FromT>::type), 766cb93a386Sopenharmony_ci "Types have different sizes"); 767cb93a386Sopenharmony_ci static_assert( 768cb93a386Sopenharmony_ci std::is_same< 769cb93a386Sopenharmony_ci decltype(std::remove_pointer<EnumT>::type::value), 770cb93a386Sopenharmony_ci typename std::remove_const<typename std::remove_pointer<FromT>::type>::type>::value, 771cb93a386Sopenharmony_ci "Data types are different"); 772cb93a386Sopenharmony_ci return reinterpret_cast<EnumT>(from); 773cb93a386Sopenharmony_ci} 774cb93a386Sopenharmony_ci 775cb93a386Sopenharmony_cistruct UniformLocation 776cb93a386Sopenharmony_ci{ 777cb93a386Sopenharmony_ci int value; 778cb93a386Sopenharmony_ci}; 779cb93a386Sopenharmony_ci 780cb93a386Sopenharmony_cistruct UniformBlockIndex 781cb93a386Sopenharmony_ci{ 782cb93a386Sopenharmony_ci uint32_t value; 783cb93a386Sopenharmony_ci}; 784cb93a386Sopenharmony_ci} // namespace gl 785cb93a386Sopenharmony_ci 786cb93a386Sopenharmony_cinamespace egl 787cb93a386Sopenharmony_ci{ 788cb93a386Sopenharmony_ciMessageType ErrorCodeToMessageType(EGLint errorCode); 789cb93a386Sopenharmony_ci} // namespace egl 790cb93a386Sopenharmony_ci 791cb93a386Sopenharmony_cinamespace egl_gl 792cb93a386Sopenharmony_ci{ 793cb93a386Sopenharmony_cigl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget); 794cb93a386Sopenharmony_cigl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget); 795cb93a386Sopenharmony_cigl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget); 796cb93a386Sopenharmony_ci} // namespace egl_gl 797cb93a386Sopenharmony_ci 798cb93a386Sopenharmony_ci#endif // COMMON_PACKEDGLENUMS_H_ 799