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