1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // utilities.cpp: Conversion functions and other utility routines.
8
9 #include "common/utilities.h"
10 #include "GLES3/gl3.h"
11 #include "common/mathutil.h"
12 #include "common/platform.h"
13 #include "common/string_utils.h"
14
15 #include <set>
16
17 #if defined(ANGLE_ENABLE_WINDOWS_UWP)
18 # include <windows.applicationmodel.core.h>
19 # include <windows.graphics.display.h>
20 # include <wrl.h>
21 # include <wrl/wrappers/corewrappers.h>
22 #endif
23
24 namespace
25 {
26
27 template <class IndexType>
ComputeTypedIndexRange(const IndexType * indices,size_t count,bool primitiveRestartEnabled,GLuint primitiveRestartIndex)28 gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
29 size_t count,
30 bool primitiveRestartEnabled,
31 GLuint primitiveRestartIndex)
32 {
33 ASSERT(count > 0);
34
35 IndexType minIndex = 0;
36 IndexType maxIndex = 0;
37 size_t nonPrimitiveRestartIndices = 0;
38
39 if (primitiveRestartEnabled)
40 {
41 // Find the first non-primitive restart index to initialize the min and max values
42 size_t i = 0;
43 for (; i < count; i++)
44 {
45 if (indices[i] != primitiveRestartIndex)
46 {
47 minIndex = indices[i];
48 maxIndex = indices[i];
49 nonPrimitiveRestartIndices++;
50 break;
51 }
52 }
53
54 // Loop over the rest of the indices
55 for (; i < count; i++)
56 {
57 if (indices[i] != primitiveRestartIndex)
58 {
59 if (minIndex > indices[i])
60 {
61 minIndex = indices[i];
62 }
63 if (maxIndex < indices[i])
64 {
65 maxIndex = indices[i];
66 }
67 nonPrimitiveRestartIndices++;
68 }
69 }
70 }
71 else
72 {
73 minIndex = indices[0];
74 maxIndex = indices[0];
75 nonPrimitiveRestartIndices = count;
76
77 for (size_t i = 1; i < count; i++)
78 {
79 if (minIndex > indices[i])
80 {
81 minIndex = indices[i];
82 }
83 if (maxIndex < indices[i])
84 {
85 maxIndex = indices[i];
86 }
87 }
88 }
89
90 return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
91 nonPrimitiveRestartIndices);
92 }
93
94 } // anonymous namespace
95
96 namespace gl
97 {
98
VariableComponentCount(GLenum type)99 int VariableComponentCount(GLenum type)
100 {
101 return VariableRowCount(type) * VariableColumnCount(type);
102 }
103
VariableComponentType(GLenum type)104 GLenum VariableComponentType(GLenum type)
105 {
106 switch (type)
107 {
108 case GL_BOOL:
109 case GL_BOOL_VEC2:
110 case GL_BOOL_VEC3:
111 case GL_BOOL_VEC4:
112 return GL_BOOL;
113 case GL_FLOAT:
114 case GL_FLOAT_VEC2:
115 case GL_FLOAT_VEC3:
116 case GL_FLOAT_VEC4:
117 case GL_FLOAT_MAT2:
118 case GL_FLOAT_MAT3:
119 case GL_FLOAT_MAT4:
120 case GL_FLOAT_MAT2x3:
121 case GL_FLOAT_MAT3x2:
122 case GL_FLOAT_MAT2x4:
123 case GL_FLOAT_MAT4x2:
124 case GL_FLOAT_MAT3x4:
125 case GL_FLOAT_MAT4x3:
126 return GL_FLOAT;
127 case GL_INT:
128 case GL_SAMPLER_2D:
129 case GL_SAMPLER_2D_RECT_ANGLE:
130 case GL_SAMPLER_3D:
131 case GL_SAMPLER_CUBE:
132 case GL_SAMPLER_CUBE_MAP_ARRAY:
133 case GL_SAMPLER_2D_ARRAY:
134 case GL_SAMPLER_EXTERNAL_OES:
135 case GL_SAMPLER_2D_MULTISAMPLE:
136 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
137 case GL_INT_SAMPLER_BUFFER:
138 case GL_INT_SAMPLER_2D:
139 case GL_INT_SAMPLER_3D:
140 case GL_INT_SAMPLER_CUBE:
141 case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
142 case GL_INT_SAMPLER_2D_ARRAY:
143 case GL_INT_SAMPLER_2D_MULTISAMPLE:
144 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
145 case GL_UNSIGNED_INT_SAMPLER_2D:
146 case GL_UNSIGNED_INT_SAMPLER_3D:
147 case GL_UNSIGNED_INT_SAMPLER_CUBE:
148 case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
149 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
150 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
151 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
152 case GL_SAMPLER_2D_SHADOW:
153 case GL_SAMPLER_BUFFER:
154 case GL_SAMPLER_CUBE_SHADOW:
155 case GL_SAMPLER_2D_ARRAY_SHADOW:
156 case GL_INT_VEC2:
157 case GL_INT_VEC3:
158 case GL_INT_VEC4:
159 case GL_IMAGE_2D:
160 case GL_INT_IMAGE_2D:
161 case GL_UNSIGNED_INT_IMAGE_2D:
162 case GL_IMAGE_3D:
163 case GL_INT_IMAGE_3D:
164 case GL_UNSIGNED_INT_IMAGE_3D:
165 case GL_IMAGE_2D_ARRAY:
166 case GL_INT_IMAGE_2D_ARRAY:
167 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
168 case GL_IMAGE_CUBE:
169 case GL_INT_IMAGE_CUBE:
170 case GL_UNSIGNED_INT_IMAGE_CUBE:
171 case GL_IMAGE_CUBE_MAP_ARRAY:
172 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
173 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
174 case GL_IMAGE_BUFFER:
175 case GL_INT_IMAGE_BUFFER:
176 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
177 case GL_UNSIGNED_INT_IMAGE_BUFFER:
178 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
179 case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
180 case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
181 return GL_INT;
182 case GL_UNSIGNED_INT:
183 case GL_UNSIGNED_INT_VEC2:
184 case GL_UNSIGNED_INT_VEC3:
185 case GL_UNSIGNED_INT_VEC4:
186 return GL_UNSIGNED_INT;
187 default:
188 UNREACHABLE();
189 }
190
191 return GL_NONE;
192 }
193
VariableComponentSize(GLenum type)194 size_t VariableComponentSize(GLenum type)
195 {
196 switch (type)
197 {
198 case GL_BOOL:
199 return sizeof(GLint);
200 case GL_FLOAT:
201 return sizeof(GLfloat);
202 case GL_INT:
203 return sizeof(GLint);
204 case GL_UNSIGNED_INT:
205 return sizeof(GLuint);
206 default:
207 UNREACHABLE();
208 }
209
210 return 0;
211 }
212
VariableInternalSize(GLenum type)213 size_t VariableInternalSize(GLenum type)
214 {
215 // Expanded to 4-element vectors
216 return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
217 }
218
VariableExternalSize(GLenum type)219 size_t VariableExternalSize(GLenum type)
220 {
221 return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
222 }
223
GetGLSLTypeString(GLenum type)224 std::string GetGLSLTypeString(GLenum type)
225 {
226 switch (type)
227 {
228 case GL_BOOL:
229 return "bool";
230 case GL_INT:
231 return "int";
232 case GL_UNSIGNED_INT:
233 return "uint";
234 case GL_FLOAT:
235 return "float";
236 case GL_BOOL_VEC2:
237 return "bvec2";
238 case GL_BOOL_VEC3:
239 return "bvec3";
240 case GL_BOOL_VEC4:
241 return "bvec4";
242 case GL_INT_VEC2:
243 return "ivec2";
244 case GL_INT_VEC3:
245 return "ivec3";
246 case GL_INT_VEC4:
247 return "ivec4";
248 case GL_FLOAT_VEC2:
249 return "vec2";
250 case GL_FLOAT_VEC3:
251 return "vec3";
252 case GL_FLOAT_VEC4:
253 return "vec4";
254 case GL_UNSIGNED_INT_VEC2:
255 return "uvec2";
256 case GL_UNSIGNED_INT_VEC3:
257 return "uvec3";
258 case GL_UNSIGNED_INT_VEC4:
259 return "uvec4";
260 case GL_FLOAT_MAT2:
261 return "mat2";
262 case GL_FLOAT_MAT3:
263 return "mat3";
264 case GL_FLOAT_MAT4:
265 return "mat4";
266 default:
267 UNREACHABLE();
268 return "";
269 }
270 }
271
VariableBoolVectorType(GLenum type)272 GLenum VariableBoolVectorType(GLenum type)
273 {
274 switch (type)
275 {
276 case GL_FLOAT:
277 case GL_INT:
278 case GL_UNSIGNED_INT:
279 return GL_BOOL;
280 case GL_FLOAT_VEC2:
281 case GL_INT_VEC2:
282 case GL_UNSIGNED_INT_VEC2:
283 return GL_BOOL_VEC2;
284 case GL_FLOAT_VEC3:
285 case GL_INT_VEC3:
286 case GL_UNSIGNED_INT_VEC3:
287 return GL_BOOL_VEC3;
288 case GL_FLOAT_VEC4:
289 case GL_INT_VEC4:
290 case GL_UNSIGNED_INT_VEC4:
291 return GL_BOOL_VEC4;
292
293 default:
294 UNREACHABLE();
295 return GL_NONE;
296 }
297 }
298
VariableRowCount(GLenum type)299 int VariableRowCount(GLenum type)
300 {
301 switch (type)
302 {
303 case GL_NONE:
304 return 0;
305 case GL_BOOL:
306 case GL_FLOAT:
307 case GL_INT:
308 case GL_UNSIGNED_INT:
309 case GL_BOOL_VEC2:
310 case GL_FLOAT_VEC2:
311 case GL_INT_VEC2:
312 case GL_UNSIGNED_INT_VEC2:
313 case GL_BOOL_VEC3:
314 case GL_FLOAT_VEC3:
315 case GL_INT_VEC3:
316 case GL_UNSIGNED_INT_VEC3:
317 case GL_BOOL_VEC4:
318 case GL_FLOAT_VEC4:
319 case GL_INT_VEC4:
320 case GL_UNSIGNED_INT_VEC4:
321 case GL_SAMPLER_2D:
322 case GL_SAMPLER_3D:
323 case GL_SAMPLER_CUBE:
324 case GL_SAMPLER_2D_ARRAY:
325 case GL_SAMPLER_EXTERNAL_OES:
326 case GL_SAMPLER_2D_RECT_ANGLE:
327 case GL_SAMPLER_2D_MULTISAMPLE:
328 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
329 case GL_SAMPLER_CUBE_MAP_ARRAY:
330 case GL_SAMPLER_BUFFER:
331 case GL_INT_SAMPLER_2D:
332 case GL_INT_SAMPLER_3D:
333 case GL_INT_SAMPLER_CUBE:
334 case GL_INT_SAMPLER_2D_ARRAY:
335 case GL_INT_SAMPLER_2D_MULTISAMPLE:
336 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
337 case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
338 case GL_INT_SAMPLER_BUFFER:
339 case GL_UNSIGNED_INT_SAMPLER_2D:
340 case GL_UNSIGNED_INT_SAMPLER_3D:
341 case GL_UNSIGNED_INT_SAMPLER_CUBE:
342 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
343 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
344 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
345 case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
346 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
347 case GL_SAMPLER_2D_SHADOW:
348 case GL_SAMPLER_CUBE_SHADOW:
349 case GL_SAMPLER_2D_ARRAY_SHADOW:
350 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
351 case GL_IMAGE_2D:
352 case GL_INT_IMAGE_2D:
353 case GL_UNSIGNED_INT_IMAGE_2D:
354 case GL_IMAGE_2D_ARRAY:
355 case GL_INT_IMAGE_2D_ARRAY:
356 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
357 case GL_IMAGE_3D:
358 case GL_INT_IMAGE_3D:
359 case GL_UNSIGNED_INT_IMAGE_3D:
360 case GL_IMAGE_CUBE:
361 case GL_INT_IMAGE_CUBE:
362 case GL_UNSIGNED_INT_IMAGE_CUBE:
363 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
364 case GL_IMAGE_CUBE_MAP_ARRAY:
365 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
366 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
367 case GL_IMAGE_BUFFER:
368 case GL_INT_IMAGE_BUFFER:
369 case GL_UNSIGNED_INT_IMAGE_BUFFER:
370 case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
371 case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
372 return 1;
373 case GL_FLOAT_MAT2:
374 case GL_FLOAT_MAT3x2:
375 case GL_FLOAT_MAT4x2:
376 return 2;
377 case GL_FLOAT_MAT3:
378 case GL_FLOAT_MAT2x3:
379 case GL_FLOAT_MAT4x3:
380 return 3;
381 case GL_FLOAT_MAT4:
382 case GL_FLOAT_MAT2x4:
383 case GL_FLOAT_MAT3x4:
384 return 4;
385 default:
386 UNREACHABLE();
387 }
388
389 return 0;
390 }
391
VariableColumnCount(GLenum type)392 int VariableColumnCount(GLenum type)
393 {
394 switch (type)
395 {
396 case GL_NONE:
397 return 0;
398 case GL_BOOL:
399 case GL_FLOAT:
400 case GL_INT:
401 case GL_UNSIGNED_INT:
402 case GL_SAMPLER_2D:
403 case GL_SAMPLER_3D:
404 case GL_SAMPLER_CUBE:
405 case GL_SAMPLER_2D_ARRAY:
406 case GL_SAMPLER_2D_MULTISAMPLE:
407 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
408 case GL_SAMPLER_CUBE_MAP_ARRAY:
409 case GL_SAMPLER_BUFFER:
410 case GL_INT_SAMPLER_2D:
411 case GL_INT_SAMPLER_3D:
412 case GL_INT_SAMPLER_CUBE:
413 case GL_INT_SAMPLER_2D_ARRAY:
414 case GL_INT_SAMPLER_2D_MULTISAMPLE:
415 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
416 case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
417 case GL_INT_SAMPLER_BUFFER:
418 case GL_SAMPLER_EXTERNAL_OES:
419 case GL_SAMPLER_2D_RECT_ANGLE:
420 case GL_UNSIGNED_INT_SAMPLER_2D:
421 case GL_UNSIGNED_INT_SAMPLER_3D:
422 case GL_UNSIGNED_INT_SAMPLER_CUBE:
423 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
424 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
425 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
426 case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
427 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
428 case GL_SAMPLER_2D_SHADOW:
429 case GL_SAMPLER_CUBE_SHADOW:
430 case GL_SAMPLER_2D_ARRAY_SHADOW:
431 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
432 case GL_IMAGE_2D:
433 case GL_INT_IMAGE_2D:
434 case GL_UNSIGNED_INT_IMAGE_2D:
435 case GL_IMAGE_3D:
436 case GL_INT_IMAGE_3D:
437 case GL_UNSIGNED_INT_IMAGE_3D:
438 case GL_IMAGE_2D_ARRAY:
439 case GL_INT_IMAGE_2D_ARRAY:
440 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
441 case GL_IMAGE_CUBE_MAP_ARRAY:
442 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
443 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
444 case GL_IMAGE_BUFFER:
445 case GL_INT_IMAGE_BUFFER:
446 case GL_UNSIGNED_INT_IMAGE_BUFFER:
447 case GL_IMAGE_CUBE:
448 case GL_INT_IMAGE_CUBE:
449 case GL_UNSIGNED_INT_IMAGE_CUBE:
450 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
451 case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
452 case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
453 return 1;
454 case GL_BOOL_VEC2:
455 case GL_FLOAT_VEC2:
456 case GL_INT_VEC2:
457 case GL_UNSIGNED_INT_VEC2:
458 case GL_FLOAT_MAT2:
459 case GL_FLOAT_MAT2x3:
460 case GL_FLOAT_MAT2x4:
461 return 2;
462 case GL_BOOL_VEC3:
463 case GL_FLOAT_VEC3:
464 case GL_INT_VEC3:
465 case GL_UNSIGNED_INT_VEC3:
466 case GL_FLOAT_MAT3:
467 case GL_FLOAT_MAT3x2:
468 case GL_FLOAT_MAT3x4:
469 return 3;
470 case GL_BOOL_VEC4:
471 case GL_FLOAT_VEC4:
472 case GL_INT_VEC4:
473 case GL_UNSIGNED_INT_VEC4:
474 case GL_FLOAT_MAT4:
475 case GL_FLOAT_MAT4x2:
476 case GL_FLOAT_MAT4x3:
477 return 4;
478 default:
479 UNREACHABLE();
480 }
481
482 return 0;
483 }
484
IsSamplerType(GLenum type)485 bool IsSamplerType(GLenum type)
486 {
487 switch (type)
488 {
489 case GL_SAMPLER_2D:
490 case GL_SAMPLER_3D:
491 case GL_SAMPLER_CUBE:
492 case GL_SAMPLER_2D_ARRAY:
493 case GL_SAMPLER_EXTERNAL_OES:
494 case GL_SAMPLER_2D_MULTISAMPLE:
495 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
496 case GL_SAMPLER_CUBE_MAP_ARRAY:
497 case GL_SAMPLER_BUFFER:
498 case GL_SAMPLER_2D_RECT_ANGLE:
499 case GL_INT_SAMPLER_2D:
500 case GL_INT_SAMPLER_3D:
501 case GL_INT_SAMPLER_CUBE:
502 case GL_INT_SAMPLER_2D_ARRAY:
503 case GL_INT_SAMPLER_2D_MULTISAMPLE:
504 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
505 case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
506 case GL_INT_SAMPLER_BUFFER:
507 case GL_UNSIGNED_INT_SAMPLER_2D:
508 case GL_UNSIGNED_INT_SAMPLER_3D:
509 case GL_UNSIGNED_INT_SAMPLER_CUBE:
510 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
511 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
512 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
513 case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
514 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
515 case GL_SAMPLER_2D_SHADOW:
516 case GL_SAMPLER_CUBE_SHADOW:
517 case GL_SAMPLER_2D_ARRAY_SHADOW:
518 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
519 case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
520 case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
521 return true;
522 }
523
524 return false;
525 }
526
IsSamplerCubeType(GLenum type)527 bool IsSamplerCubeType(GLenum type)
528 {
529 switch (type)
530 {
531 case GL_SAMPLER_CUBE:
532 case GL_INT_SAMPLER_CUBE:
533 case GL_UNSIGNED_INT_SAMPLER_CUBE:
534 case GL_SAMPLER_CUBE_SHADOW:
535 return true;
536 }
537
538 return false;
539 }
540
IsSamplerYUVType(GLenum type)541 bool IsSamplerYUVType(GLenum type)
542 {
543 switch (type)
544 {
545 case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
546 return true;
547
548 default:
549 return false;
550 }
551 }
552
IsImageType(GLenum type)553 bool IsImageType(GLenum type)
554 {
555 switch (type)
556 {
557 case GL_IMAGE_2D:
558 case GL_INT_IMAGE_2D:
559 case GL_UNSIGNED_INT_IMAGE_2D:
560 case GL_IMAGE_3D:
561 case GL_INT_IMAGE_3D:
562 case GL_UNSIGNED_INT_IMAGE_3D:
563 case GL_IMAGE_2D_ARRAY:
564 case GL_INT_IMAGE_2D_ARRAY:
565 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
566 case GL_IMAGE_CUBE_MAP_ARRAY:
567 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
568 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
569 case GL_IMAGE_BUFFER:
570 case GL_INT_IMAGE_BUFFER:
571 case GL_UNSIGNED_INT_IMAGE_BUFFER:
572 case GL_IMAGE_CUBE:
573 case GL_INT_IMAGE_CUBE:
574 case GL_UNSIGNED_INT_IMAGE_CUBE:
575 return true;
576 }
577 return false;
578 }
579
IsImage2DType(GLenum type)580 bool IsImage2DType(GLenum type)
581 {
582 switch (type)
583 {
584 case GL_IMAGE_2D:
585 case GL_INT_IMAGE_2D:
586 case GL_UNSIGNED_INT_IMAGE_2D:
587 return true;
588 case GL_IMAGE_3D:
589 case GL_INT_IMAGE_3D:
590 case GL_UNSIGNED_INT_IMAGE_3D:
591 case GL_IMAGE_2D_ARRAY:
592 case GL_INT_IMAGE_2D_ARRAY:
593 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
594 case GL_IMAGE_CUBE_MAP_ARRAY:
595 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
596 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
597 case GL_IMAGE_CUBE:
598 case GL_INT_IMAGE_CUBE:
599 case GL_UNSIGNED_INT_IMAGE_CUBE:
600 case GL_IMAGE_BUFFER:
601 case GL_INT_IMAGE_BUFFER:
602 case GL_UNSIGNED_INT_IMAGE_BUFFER:
603 return false;
604 default:
605 UNREACHABLE();
606 return false;
607 }
608 }
609
IsAtomicCounterType(GLenum type)610 bool IsAtomicCounterType(GLenum type)
611 {
612 return type == GL_UNSIGNED_INT_ATOMIC_COUNTER;
613 }
614
IsOpaqueType(GLenum type)615 bool IsOpaqueType(GLenum type)
616 {
617 // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
618 return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
619 }
620
IsMatrixType(GLenum type)621 bool IsMatrixType(GLenum type)
622 {
623 return VariableRowCount(type) > 1;
624 }
625
TransposeMatrixType(GLenum type)626 GLenum TransposeMatrixType(GLenum type)
627 {
628 if (!IsMatrixType(type))
629 {
630 return type;
631 }
632
633 switch (type)
634 {
635 case GL_FLOAT_MAT2:
636 return GL_FLOAT_MAT2;
637 case GL_FLOAT_MAT3:
638 return GL_FLOAT_MAT3;
639 case GL_FLOAT_MAT4:
640 return GL_FLOAT_MAT4;
641 case GL_FLOAT_MAT2x3:
642 return GL_FLOAT_MAT3x2;
643 case GL_FLOAT_MAT3x2:
644 return GL_FLOAT_MAT2x3;
645 case GL_FLOAT_MAT2x4:
646 return GL_FLOAT_MAT4x2;
647 case GL_FLOAT_MAT4x2:
648 return GL_FLOAT_MAT2x4;
649 case GL_FLOAT_MAT3x4:
650 return GL_FLOAT_MAT4x3;
651 case GL_FLOAT_MAT4x3:
652 return GL_FLOAT_MAT3x4;
653 default:
654 UNREACHABLE();
655 return GL_NONE;
656 }
657 }
658
MatrixRegisterCount(GLenum type,bool isRowMajorMatrix)659 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
660 {
661 ASSERT(IsMatrixType(type));
662 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
663 }
664
MatrixComponentCount(GLenum type,bool isRowMajorMatrix)665 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
666 {
667 ASSERT(IsMatrixType(type));
668 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
669 }
670
VariableRegisterCount(GLenum type)671 int VariableRegisterCount(GLenum type)
672 {
673 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
674 }
675
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)676 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
677 {
678 ASSERT(allocationSize <= bitsSize);
679
680 unsigned int mask = std::numeric_limits<unsigned int>::max() >>
681 (std::numeric_limits<unsigned int>::digits - allocationSize);
682
683 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
684 {
685 if ((*bits & mask) == 0)
686 {
687 *bits |= mask;
688 return i;
689 }
690
691 mask <<= 1;
692 }
693
694 return -1;
695 }
696
ComputeIndexRange(DrawElementsType indexType,const GLvoid * indices,size_t count,bool primitiveRestartEnabled)697 IndexRange ComputeIndexRange(DrawElementsType indexType,
698 const GLvoid *indices,
699 size_t count,
700 bool primitiveRestartEnabled)
701 {
702 switch (indexType)
703 {
704 case DrawElementsType::UnsignedByte:
705 return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
706 primitiveRestartEnabled,
707 GetPrimitiveRestartIndex(indexType));
708 case DrawElementsType::UnsignedShort:
709 return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
710 primitiveRestartEnabled,
711 GetPrimitiveRestartIndex(indexType));
712 case DrawElementsType::UnsignedInt:
713 return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
714 primitiveRestartEnabled,
715 GetPrimitiveRestartIndex(indexType));
716 default:
717 UNREACHABLE();
718 return IndexRange();
719 }
720 }
721
GetPrimitiveRestartIndex(DrawElementsType indexType)722 GLuint GetPrimitiveRestartIndex(DrawElementsType indexType)
723 {
724 switch (indexType)
725 {
726 case DrawElementsType::UnsignedByte:
727 return 0xFF;
728 case DrawElementsType::UnsignedShort:
729 return 0xFFFF;
730 case DrawElementsType::UnsignedInt:
731 return 0xFFFFFFFF;
732 default:
733 UNREACHABLE();
734 return 0;
735 }
736 }
737
IsTriangleMode(PrimitiveMode drawMode)738 bool IsTriangleMode(PrimitiveMode drawMode)
739 {
740 switch (drawMode)
741 {
742 case PrimitiveMode::Triangles:
743 case PrimitiveMode::TriangleFan:
744 case PrimitiveMode::TriangleStrip:
745 return true;
746 case PrimitiveMode::Points:
747 case PrimitiveMode::Lines:
748 case PrimitiveMode::LineLoop:
749 case PrimitiveMode::LineStrip:
750 return false;
751 default:
752 UNREACHABLE();
753 }
754
755 return false;
756 }
757
IsPolygonMode(PrimitiveMode mode)758 bool IsPolygonMode(PrimitiveMode mode)
759 {
760 switch (mode)
761 {
762 case PrimitiveMode::Points:
763 case PrimitiveMode::Lines:
764 case PrimitiveMode::LineStrip:
765 case PrimitiveMode::LineLoop:
766 case PrimitiveMode::LinesAdjacency:
767 case PrimitiveMode::LineStripAdjacency:
768 return false;
769 default:
770 break;
771 }
772
773 return true;
774 }
775
776 namespace priv
777 {
778 const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes = {
779 {{PrimitiveMode::LineLoop, true},
780 {PrimitiveMode::LineStrip, true},
781 {PrimitiveMode::LineStripAdjacency, true},
782 {PrimitiveMode::Lines, true}}};
783 } // namespace priv
784
IsIntegerFormat(GLenum unsizedFormat)785 bool IsIntegerFormat(GLenum unsizedFormat)
786 {
787 switch (unsizedFormat)
788 {
789 case GL_RGBA_INTEGER:
790 case GL_RGB_INTEGER:
791 case GL_RG_INTEGER:
792 case GL_RED_INTEGER:
793 return true;
794
795 default:
796 return false;
797 }
798 }
799
800 // [OpenGL ES SL 3.00.4] Section 11 p. 120
801 // Vertex Outs/Fragment Ins packing priorities
VariableSortOrder(GLenum type)802 int VariableSortOrder(GLenum type)
803 {
804 switch (type)
805 {
806 // 1. Arrays of mat4 and mat4
807 // Non-square matrices of type matCxR consume the same space as a square
808 // matrix of type matN where N is the greater of C and R
809 case GL_FLOAT_MAT4:
810 case GL_FLOAT_MAT2x4:
811 case GL_FLOAT_MAT3x4:
812 case GL_FLOAT_MAT4x2:
813 case GL_FLOAT_MAT4x3:
814 return 0;
815
816 // 2. Arrays of mat2 and mat2 (since they occupy full rows)
817 case GL_FLOAT_MAT2:
818 return 1;
819
820 // 3. Arrays of vec4 and vec4
821 case GL_FLOAT_VEC4:
822 case GL_INT_VEC4:
823 case GL_BOOL_VEC4:
824 case GL_UNSIGNED_INT_VEC4:
825 return 2;
826
827 // 4. Arrays of mat3 and mat3
828 case GL_FLOAT_MAT3:
829 case GL_FLOAT_MAT2x3:
830 case GL_FLOAT_MAT3x2:
831 return 3;
832
833 // 5. Arrays of vec3 and vec3
834 case GL_FLOAT_VEC3:
835 case GL_INT_VEC3:
836 case GL_BOOL_VEC3:
837 case GL_UNSIGNED_INT_VEC3:
838 return 4;
839
840 // 6. Arrays of vec2 and vec2
841 case GL_FLOAT_VEC2:
842 case GL_INT_VEC2:
843 case GL_BOOL_VEC2:
844 case GL_UNSIGNED_INT_VEC2:
845 return 5;
846
847 // 7. Single component types
848 case GL_FLOAT:
849 case GL_INT:
850 case GL_BOOL:
851 case GL_UNSIGNED_INT:
852 case GL_SAMPLER_2D:
853 case GL_SAMPLER_CUBE:
854 case GL_SAMPLER_EXTERNAL_OES:
855 case GL_SAMPLER_2D_RECT_ANGLE:
856 case GL_SAMPLER_2D_ARRAY:
857 case GL_SAMPLER_2D_MULTISAMPLE:
858 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
859 case GL_SAMPLER_3D:
860 case GL_INT_SAMPLER_2D:
861 case GL_INT_SAMPLER_3D:
862 case GL_INT_SAMPLER_CUBE:
863 case GL_INT_SAMPLER_2D_ARRAY:
864 case GL_INT_SAMPLER_2D_MULTISAMPLE:
865 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
866 case GL_UNSIGNED_INT_SAMPLER_2D:
867 case GL_UNSIGNED_INT_SAMPLER_3D:
868 case GL_UNSIGNED_INT_SAMPLER_CUBE:
869 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
870 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
871 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
872 case GL_SAMPLER_2D_SHADOW:
873 case GL_SAMPLER_2D_ARRAY_SHADOW:
874 case GL_SAMPLER_CUBE_SHADOW:
875 case GL_IMAGE_2D:
876 case GL_INT_IMAGE_2D:
877 case GL_UNSIGNED_INT_IMAGE_2D:
878 case GL_IMAGE_3D:
879 case GL_INT_IMAGE_3D:
880 case GL_UNSIGNED_INT_IMAGE_3D:
881 case GL_IMAGE_2D_ARRAY:
882 case GL_INT_IMAGE_2D_ARRAY:
883 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
884 case GL_IMAGE_CUBE:
885 case GL_INT_IMAGE_CUBE:
886 case GL_UNSIGNED_INT_IMAGE_CUBE:
887 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
888 case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
889 case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
890 return 6;
891
892 default:
893 UNREACHABLE();
894 return 0;
895 }
896 }
897
ParseResourceName(const std::string & name,std::vector<unsigned int> * outSubscripts)898 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts)
899 {
900 if (outSubscripts)
901 {
902 outSubscripts->clear();
903 }
904 // Strip any trailing array indexing operators and retrieve the subscripts.
905 size_t baseNameLength = name.length();
906 bool hasIndex = true;
907 while (hasIndex)
908 {
909 size_t open = name.find_last_of('[', baseNameLength - 1);
910 size_t close = name.find_last_of(']', baseNameLength - 1);
911 hasIndex = (open != std::string::npos) && (close == baseNameLength - 1);
912 if (hasIndex)
913 {
914 baseNameLength = open;
915 if (outSubscripts)
916 {
917 int index = atoi(name.substr(open + 1).c_str());
918 if (index >= 0)
919 {
920 outSubscripts->push_back(index);
921 }
922 else
923 {
924 outSubscripts->push_back(GL_INVALID_INDEX);
925 }
926 }
927 }
928 }
929
930 return name.substr(0, baseNameLength);
931 }
932
IsBuiltInName(const char * name)933 bool IsBuiltInName(const char *name)
934 {
935 return angle::BeginsWith(name, "gl_");
936 }
937
StripLastArrayIndex(const std::string & name)938 std::string StripLastArrayIndex(const std::string &name)
939 {
940 size_t strippedNameLength = name.find_last_of('[');
941 if (strippedNameLength != std::string::npos && name.back() == ']')
942 {
943 return name.substr(0, strippedNameLength);
944 }
945 return name;
946 }
947
SamplerNameContainsNonZeroArrayElement(const std::string & name)948 bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
949 {
950 constexpr char kZERO_ELEMENT[] = "[0]";
951
952 size_t start = 0;
953 while (true)
954 {
955 start = name.find(kZERO_ELEMENT[0], start);
956 if (start == std::string::npos)
957 {
958 break;
959 }
960 if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
961 {
962 return true;
963 }
964 start++;
965 }
966 return false;
967 }
968
ArraySizeProduct(const std::vector<unsigned int> & arraySizes)969 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
970 {
971 unsigned int arraySizeProduct = 1u;
972 for (unsigned int arraySize : arraySizes)
973 {
974 arraySizeProduct *= arraySize;
975 }
976 return arraySizeProduct;
977 }
978
InnerArraySizeProduct(const std::vector<unsigned int> & arraySizes)979 unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes)
980 {
981 unsigned int arraySizeProduct = 1u;
982 for (size_t index = 0; index + 1 < arraySizes.size(); ++index)
983 {
984 arraySizeProduct *= arraySizes[index];
985 }
986 return arraySizeProduct;
987 }
988
OutermostArraySize(const std::vector<unsigned int> & arraySizes)989 unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes)
990 {
991 return arraySizes.empty() || arraySizes.back() == 0 ? 1 : arraySizes.back();
992 }
993
ParseArrayIndex(const std::string & name,size_t * nameLengthWithoutArrayIndexOut)994 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
995 {
996 ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
997
998 // Strip any trailing array operator and retrieve the subscript
999 size_t open = name.find_last_of('[');
1000 if (open != std::string::npos && name.back() == ']')
1001 {
1002 bool indexIsValidDecimalNumber = true;
1003 for (size_t i = open + 1; i < name.length() - 1u; ++i)
1004 {
1005 if (!isdigit(name[i]))
1006 {
1007 indexIsValidDecimalNumber = false;
1008 break;
1009 }
1010
1011 // Leading zeroes are invalid
1012 if ((i == (open + 1)) && (name[i] == '0') && (name[i + 1] != ']'))
1013 {
1014 indexIsValidDecimalNumber = false;
1015 break;
1016 }
1017 }
1018 if (indexIsValidDecimalNumber)
1019 {
1020 errno = 0; // reset global error flag.
1021 unsigned long subscript =
1022 strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
1023
1024 // Check if resulting integer is out-of-range or conversion error.
1025 if (angle::base::IsValueInRangeForNumericType<uint32_t>(subscript) &&
1026 !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
1027 {
1028 *nameLengthWithoutArrayIndexOut = open;
1029 return static_cast<unsigned int>(subscript);
1030 }
1031 }
1032 }
1033
1034 *nameLengthWithoutArrayIndexOut = name.length();
1035 return GL_INVALID_INDEX;
1036 }
1037
GetGenericErrorMessage(GLenum error)1038 const char *GetGenericErrorMessage(GLenum error)
1039 {
1040 switch (error)
1041 {
1042 case GL_NO_ERROR:
1043 return "";
1044 case GL_INVALID_ENUM:
1045 return "Invalid enum.";
1046 case GL_INVALID_VALUE:
1047 return "Invalid value.";
1048 case GL_INVALID_OPERATION:
1049 return "Invalid operation.";
1050 case GL_STACK_OVERFLOW:
1051 return "Stack overflow.";
1052 case GL_STACK_UNDERFLOW:
1053 return "Stack underflow.";
1054 case GL_OUT_OF_MEMORY:
1055 return "Out of memory.";
1056 case GL_INVALID_FRAMEBUFFER_OPERATION:
1057 return "Invalid framebuffer operation.";
1058 default:
1059 UNREACHABLE();
1060 return "Unknown error.";
1061 }
1062 }
1063
ElementTypeSize(GLenum elementType)1064 unsigned int ElementTypeSize(GLenum elementType)
1065 {
1066 switch (elementType)
1067 {
1068 case GL_UNSIGNED_BYTE:
1069 return sizeof(GLubyte);
1070 case GL_UNSIGNED_SHORT:
1071 return sizeof(GLushort);
1072 case GL_UNSIGNED_INT:
1073 return sizeof(GLuint);
1074 default:
1075 UNREACHABLE();
1076 return 0;
1077 }
1078 }
1079
IsMipmapFiltered(GLenum minFilterMode)1080 bool IsMipmapFiltered(GLenum minFilterMode)
1081 {
1082 switch (minFilterMode)
1083 {
1084 case GL_NEAREST:
1085 case GL_LINEAR:
1086 return false;
1087 case GL_NEAREST_MIPMAP_NEAREST:
1088 case GL_LINEAR_MIPMAP_NEAREST:
1089 case GL_NEAREST_MIPMAP_LINEAR:
1090 case GL_LINEAR_MIPMAP_LINEAR:
1091 return true;
1092 default:
1093 UNREACHABLE();
1094 return false;
1095 }
1096 }
1097
GetPipelineType(ShaderType type)1098 PipelineType GetPipelineType(ShaderType type)
1099 {
1100 switch (type)
1101 {
1102 case ShaderType::Vertex:
1103 case ShaderType::Fragment:
1104 case ShaderType::Geometry:
1105 return PipelineType::GraphicsPipeline;
1106 case ShaderType::Compute:
1107 return PipelineType::ComputePipeline;
1108 default:
1109 UNREACHABLE();
1110 return PipelineType::GraphicsPipeline;
1111 }
1112 }
1113
GetDebugMessageSourceString(GLenum source)1114 const char *GetDebugMessageSourceString(GLenum source)
1115 {
1116 switch (source)
1117 {
1118 case GL_DEBUG_SOURCE_API:
1119 return "API";
1120 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1121 return "Window System";
1122 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1123 return "Shader Compiler";
1124 case GL_DEBUG_SOURCE_THIRD_PARTY:
1125 return "Third Party";
1126 case GL_DEBUG_SOURCE_APPLICATION:
1127 return "Application";
1128 case GL_DEBUG_SOURCE_OTHER:
1129 return "Other";
1130 default:
1131 return "Unknown Source";
1132 }
1133 }
1134
GetDebugMessageTypeString(GLenum type)1135 const char *GetDebugMessageTypeString(GLenum type)
1136 {
1137 switch (type)
1138 {
1139 case GL_DEBUG_TYPE_ERROR:
1140 return "Error";
1141 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1142 return "Deprecated behavior";
1143 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1144 return "Undefined behavior";
1145 case GL_DEBUG_TYPE_PORTABILITY:
1146 return "Portability";
1147 case GL_DEBUG_TYPE_PERFORMANCE:
1148 return "Performance";
1149 case GL_DEBUG_TYPE_OTHER:
1150 return "Other";
1151 case GL_DEBUG_TYPE_MARKER:
1152 return "Marker";
1153 default:
1154 return "Unknown Type";
1155 }
1156 }
1157
GetDebugMessageSeverityString(GLenum severity)1158 const char *GetDebugMessageSeverityString(GLenum severity)
1159 {
1160 switch (severity)
1161 {
1162 case GL_DEBUG_SEVERITY_HIGH:
1163 return "High";
1164 case GL_DEBUG_SEVERITY_MEDIUM:
1165 return "Medium";
1166 case GL_DEBUG_SEVERITY_LOW:
1167 return "Low";
1168 case GL_DEBUG_SEVERITY_NOTIFICATION:
1169 return "Notification";
1170 default:
1171 return "Unknown Severity";
1172 }
1173 }
1174
GetShaderTypeFromBitfield(size_t singleShaderType)1175 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType)
1176 {
1177 switch (singleShaderType)
1178 {
1179 case GL_VERTEX_SHADER_BIT:
1180 return ShaderType::Vertex;
1181 case GL_FRAGMENT_SHADER_BIT:
1182 return ShaderType::Fragment;
1183 case GL_COMPUTE_SHADER_BIT:
1184 return ShaderType::Compute;
1185 case GL_GEOMETRY_SHADER_BIT:
1186 return ShaderType::Geometry;
1187 case GL_TESS_CONTROL_SHADER_BIT:
1188 return ShaderType::TessControl;
1189 case GL_TESS_EVALUATION_SHADER_BIT:
1190 return ShaderType::TessEvaluation;
1191 default:
1192 return ShaderType::InvalidEnum;
1193 }
1194 }
1195
GetBitfieldFromShaderType(ShaderType shaderType)1196 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType)
1197 {
1198 switch (shaderType)
1199 {
1200 case ShaderType::Vertex:
1201 return GL_VERTEX_SHADER_BIT;
1202 case ShaderType::Fragment:
1203 return GL_FRAGMENT_SHADER_BIT;
1204 case ShaderType::Compute:
1205 return GL_COMPUTE_SHADER_BIT;
1206 case ShaderType::Geometry:
1207 return GL_GEOMETRY_SHADER_BIT;
1208 case ShaderType::TessControl:
1209 return GL_TESS_CONTROL_SHADER_BIT;
1210 case ShaderType::TessEvaluation:
1211 return GL_TESS_EVALUATION_SHADER_BIT;
1212 default:
1213 UNREACHABLE();
1214 return GL_ZERO;
1215 }
1216 }
1217
ShaderTypeSupportsTransformFeedback(ShaderType shaderType)1218 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
1219 {
1220 switch (shaderType)
1221 {
1222 case ShaderType::Vertex:
1223 case ShaderType::Geometry:
1224 case ShaderType::TessEvaluation:
1225 return true;
1226 default:
1227 return false;
1228 }
1229 }
1230
GetLastPreFragmentStage(ShaderBitSet shaderTypes)1231 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes)
1232 {
1233 shaderTypes.reset(ShaderType::Fragment);
1234 shaderTypes.reset(ShaderType::Compute);
1235 return shaderTypes.any() ? shaderTypes.last() : ShaderType::InvalidEnum;
1236 }
1237 } // namespace gl
1238
1239 namespace egl
1240 {
1241 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
1242 "Unexpected EGL cube map enum value.");
1243 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
1244 "Unexpected EGL cube map enum value.");
1245 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
1246 "Unexpected EGL cube map enum value.");
1247 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
1248 "Unexpected EGL cube map enum value.");
1249 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
1250 "Unexpected EGL cube map enum value.");
1251
IsCubeMapTextureTarget(EGLenum target)1252 bool IsCubeMapTextureTarget(EGLenum target)
1253 {
1254 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
1255 }
1256
CubeMapTextureTargetToLayerIndex(EGLenum target)1257 size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
1258 {
1259 ASSERT(IsCubeMapTextureTarget(target));
1260 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
1261 }
1262
LayerIndexToCubeMapTextureTarget(size_t index)1263 EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
1264 {
1265 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
1266 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
1267 }
1268
IsTextureTarget(EGLenum target)1269 bool IsTextureTarget(EGLenum target)
1270 {
1271 switch (target)
1272 {
1273 case EGL_GL_TEXTURE_2D_KHR:
1274 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
1275 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
1276 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
1277 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
1278 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
1279 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
1280 case EGL_GL_TEXTURE_3D_KHR:
1281 return true;
1282
1283 default:
1284 return false;
1285 }
1286 }
1287
IsRenderbufferTarget(EGLenum target)1288 bool IsRenderbufferTarget(EGLenum target)
1289 {
1290 return target == EGL_GL_RENDERBUFFER_KHR;
1291 }
1292
IsExternalImageTarget(EGLenum target)1293 bool IsExternalImageTarget(EGLenum target)
1294 {
1295 switch (target)
1296 {
1297 case EGL_NATIVE_BUFFER_ANDROID:
1298 case EGL_D3D11_TEXTURE_ANGLE:
1299 case EGL_LINUX_DMA_BUF_EXT:
1300 case EGL_METAL_TEXTURE_ANGLE:
1301 case EGL_VULKAN_IMAGE_ANGLE:
1302 return true;
1303
1304 default:
1305 return false;
1306 }
1307 }
1308
GetGenericErrorMessage(EGLint error)1309 const char *GetGenericErrorMessage(EGLint error)
1310 {
1311 switch (error)
1312 {
1313 case EGL_SUCCESS:
1314 return "";
1315 case EGL_NOT_INITIALIZED:
1316 return "Not initialized.";
1317 case EGL_BAD_ACCESS:
1318 return "Bad access.";
1319 case EGL_BAD_ALLOC:
1320 return "Bad allocation.";
1321 case EGL_BAD_ATTRIBUTE:
1322 return "Bad attribute.";
1323 case EGL_BAD_CONFIG:
1324 return "Bad config.";
1325 case EGL_BAD_CONTEXT:
1326 return "Bad context.";
1327 case EGL_BAD_CURRENT_SURFACE:
1328 return "Bad current surface.";
1329 case EGL_BAD_DISPLAY:
1330 return "Bad display.";
1331 case EGL_BAD_MATCH:
1332 return "Bad match.";
1333 case EGL_BAD_NATIVE_WINDOW:
1334 return "Bad native window.";
1335 case EGL_BAD_NATIVE_PIXMAP:
1336 return "Bad native pixmap.";
1337 case EGL_BAD_PARAMETER:
1338 return "Bad parameter.";
1339 case EGL_BAD_SURFACE:
1340 return "Bad surface.";
1341 case EGL_CONTEXT_LOST:
1342 return "Context lost.";
1343 case EGL_BAD_STREAM_KHR:
1344 return "Bad stream.";
1345 case EGL_BAD_STATE_KHR:
1346 return "Bad state.";
1347 case EGL_BAD_DEVICE_EXT:
1348 return "Bad device.";
1349 default:
1350 UNREACHABLE();
1351 return "Unknown error.";
1352 }
1353 }
1354
1355 } // namespace egl
1356
1357 namespace egl_gl
1358 {
EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)1359 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
1360 {
1361 return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
1362 }
1363 } // namespace egl_gl
1364
1365 namespace gl_egl
1366 {
GLComponentTypeToEGLColorComponentType(GLenum glComponentType)1367 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
1368 {
1369 switch (glComponentType)
1370 {
1371 case GL_FLOAT:
1372 return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
1373
1374 case GL_UNSIGNED_NORMALIZED:
1375 return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
1376
1377 default:
1378 UNREACHABLE();
1379 return EGL_NONE;
1380 }
1381 }
1382
GLObjectHandleToEGLClientBuffer(GLuint handle)1383 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
1384 {
1385 return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
1386 }
1387
1388 } // namespace gl_egl
1389
1390 namespace angle
1391 {
IsDrawEntryPoint(EntryPoint entryPoint)1392 bool IsDrawEntryPoint(EntryPoint entryPoint)
1393 {
1394 switch (entryPoint)
1395 {
1396 case EntryPoint::GLDrawArrays:
1397 case EntryPoint::GLDrawArraysIndirect:
1398 case EntryPoint::GLDrawArraysInstanced:
1399 case EntryPoint::GLDrawArraysInstancedANGLE:
1400 case EntryPoint::GLDrawArraysInstancedBaseInstance:
1401 case EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE:
1402 case EntryPoint::GLDrawArraysInstancedEXT:
1403 case EntryPoint::GLDrawElements:
1404 case EntryPoint::GLDrawElementsBaseVertex:
1405 case EntryPoint::GLDrawElementsBaseVertexEXT:
1406 case EntryPoint::GLDrawElementsBaseVertexOES:
1407 case EntryPoint::GLDrawElementsIndirect:
1408 case EntryPoint::GLDrawElementsInstanced:
1409 case EntryPoint::GLDrawElementsInstancedANGLE:
1410 case EntryPoint::GLDrawElementsInstancedBaseInstance:
1411 case EntryPoint::GLDrawElementsInstancedBaseVertex:
1412 case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstance:
1413 case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE:
1414 case EntryPoint::GLDrawElementsInstancedBaseVertexEXT:
1415 case EntryPoint::GLDrawElementsInstancedBaseVertexOES:
1416 case EntryPoint::GLDrawElementsInstancedEXT:
1417 case EntryPoint::GLDrawPixels:
1418 case EntryPoint::GLDrawRangeElements:
1419 case EntryPoint::GLDrawRangeElementsBaseVertex:
1420 case EntryPoint::GLDrawRangeElementsBaseVertexEXT:
1421 case EntryPoint::GLDrawRangeElementsBaseVertexOES:
1422 case EntryPoint::GLDrawTexfOES:
1423 case EntryPoint::GLDrawTexfvOES:
1424 case EntryPoint::GLDrawTexiOES:
1425 case EntryPoint::GLDrawTexivOES:
1426 case EntryPoint::GLDrawTexsOES:
1427 case EntryPoint::GLDrawTexsvOES:
1428 case EntryPoint::GLDrawTexxOES:
1429 case EntryPoint::GLDrawTexxvOES:
1430 case EntryPoint::GLDrawTransformFeedback:
1431 case EntryPoint::GLDrawTransformFeedbackInstanced:
1432 case EntryPoint::GLDrawTransformFeedbackStream:
1433 case EntryPoint::GLDrawTransformFeedbackStreamInstanced:
1434 return true;
1435 default:
1436 return false;
1437 }
1438 }
1439
IsDispatchEntryPoint(EntryPoint entryPoint)1440 bool IsDispatchEntryPoint(EntryPoint entryPoint)
1441 {
1442 switch (entryPoint)
1443 {
1444 case EntryPoint::GLDispatchCompute:
1445 case EntryPoint::GLDispatchComputeIndirect:
1446 return true;
1447 default:
1448 return false;
1449 }
1450 }
1451
IsClearEntryPoint(EntryPoint entryPoint)1452 bool IsClearEntryPoint(EntryPoint entryPoint)
1453 {
1454 switch (entryPoint)
1455 {
1456 case EntryPoint::GLClear:
1457 case EntryPoint::GLClearBufferfi:
1458 case EntryPoint::GLClearBufferfv:
1459 case EntryPoint::GLClearBufferiv:
1460 case EntryPoint::GLClearBufferuiv:
1461 return true;
1462 default:
1463 return false;
1464 }
1465 }
1466
IsQueryEntryPoint(EntryPoint entryPoint)1467 bool IsQueryEntryPoint(EntryPoint entryPoint)
1468 {
1469 switch (entryPoint)
1470 {
1471 case EntryPoint::GLBeginQuery:
1472 case EntryPoint::GLBeginQueryEXT:
1473 case EntryPoint::GLBeginQueryIndexed:
1474 case EntryPoint::GLEndQuery:
1475 case EntryPoint::GLEndQueryEXT:
1476 case EntryPoint::GLEndQueryIndexed:
1477 return true;
1478 default:
1479 return false;
1480 }
1481 }
1482 } // namespace angle
1483
writeFile(const char * path,const void * content,size_t size)1484 void writeFile(const char *path, const void *content, size_t size)
1485 {
1486 #if !defined(ANGLE_ENABLE_WINDOWS_UWP)
1487 FILE *file = fopen(path, "w");
1488 if (!file)
1489 {
1490 UNREACHABLE();
1491 return;
1492 }
1493
1494 fwrite(content, sizeof(char), size, file);
1495 fclose(file);
1496 #else
1497 UNREACHABLE();
1498 return;
1499 #endif // !ANGLE_ENABLE_WINDOWS_UWP
1500 }
1501