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