• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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