• 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 =
912             (open != std::string::npos) && (close == baseNameLength - 1) && (close != open + 1);
913         if (hasIndex)
914         {
915             baseNameLength = open;
916             if (outSubscripts)
917             {
918                 if (!isdigit(name[open + 1]))
919                 {
920                     outSubscripts->push_back(GL_INVALID_INDEX);
921                     break;
922                 }
923                 int index = atoi(name.substr(open + 1).c_str());
924                 if (index >= 0)
925                 {
926                     outSubscripts->push_back(index);
927                 }
928                 else
929                 {
930                     outSubscripts->push_back(GL_INVALID_INDEX);
931                 }
932             }
933         }
934     }
935 
936     return name.substr(0, baseNameLength);
937 }
938 
IsBuiltInName(const char * name)939 bool IsBuiltInName(const char *name)
940 {
941     return angle::BeginsWith(name, "gl_");
942 }
943 
StripLastArrayIndex(const std::string & name)944 std::string StripLastArrayIndex(const std::string &name)
945 {
946     size_t strippedNameLength = name.find_last_of('[');
947     if (strippedNameLength != std::string::npos && name.back() == ']')
948     {
949         return name.substr(0, strippedNameLength);
950     }
951     return name;
952 }
953 
SamplerNameContainsNonZeroArrayElement(const std::string & name)954 bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
955 {
956     constexpr char kZERO_ELEMENT[] = "[0]";
957 
958     size_t start = 0;
959     while (true)
960     {
961         start = name.find(kZERO_ELEMENT[0], start);
962         if (start == std::string::npos)
963         {
964             break;
965         }
966         if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
967         {
968             return true;
969         }
970         start++;
971     }
972     return false;
973 }
974 
ArraySizeProduct(const std::vector<unsigned int> & arraySizes)975 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
976 {
977     unsigned int arraySizeProduct = 1u;
978     for (unsigned int arraySize : arraySizes)
979     {
980         arraySizeProduct *= arraySize;
981     }
982     return arraySizeProduct;
983 }
984 
InnerArraySizeProduct(const std::vector<unsigned int> & arraySizes)985 unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes)
986 {
987     unsigned int arraySizeProduct = 1u;
988     for (size_t index = 0; index + 1 < arraySizes.size(); ++index)
989     {
990         arraySizeProduct *= arraySizes[index];
991     }
992     return arraySizeProduct;
993 }
994 
OutermostArraySize(const std::vector<unsigned int> & arraySizes)995 unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes)
996 {
997     return arraySizes.empty() || arraySizes.back() == 0 ? 1 : arraySizes.back();
998 }
999 
ParseArrayIndex(const std::string & name,size_t * nameLengthWithoutArrayIndexOut)1000 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
1001 {
1002     ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
1003 
1004     // Strip any trailing array operator and retrieve the subscript
1005     size_t open = name.find_last_of('[');
1006     if (open != std::string::npos && name.back() == ']')
1007     {
1008         bool indexIsValidDecimalNumber = true;
1009         for (size_t i = open + 1; i < name.length() - 1u; ++i)
1010         {
1011             if (!isdigit(name[i]))
1012             {
1013                 indexIsValidDecimalNumber = false;
1014                 break;
1015             }
1016 
1017             // Leading zeroes are invalid
1018             if ((i == (open + 1)) && (name[i] == '0') && (name[i + 1] != ']'))
1019             {
1020                 indexIsValidDecimalNumber = false;
1021                 break;
1022             }
1023         }
1024         if (indexIsValidDecimalNumber)
1025         {
1026             errno = 0;  // reset global error flag.
1027             unsigned long subscript =
1028                 strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
1029 
1030             // Check if resulting integer is out-of-range or conversion error.
1031             if (angle::base::IsValueInRangeForNumericType<uint32_t>(subscript) &&
1032                 !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
1033             {
1034                 *nameLengthWithoutArrayIndexOut = open;
1035                 return static_cast<unsigned int>(subscript);
1036             }
1037         }
1038     }
1039 
1040     *nameLengthWithoutArrayIndexOut = name.length();
1041     return GL_INVALID_INDEX;
1042 }
1043 
GetGenericErrorMessage(GLenum error)1044 const char *GetGenericErrorMessage(GLenum error)
1045 {
1046     switch (error)
1047     {
1048         case GL_NO_ERROR:
1049             return "";
1050         case GL_INVALID_ENUM:
1051             return "Invalid enum.";
1052         case GL_INVALID_VALUE:
1053             return "Invalid value.";
1054         case GL_INVALID_OPERATION:
1055             return "Invalid operation.";
1056         case GL_STACK_OVERFLOW:
1057             return "Stack overflow.";
1058         case GL_STACK_UNDERFLOW:
1059             return "Stack underflow.";
1060         case GL_OUT_OF_MEMORY:
1061             return "Out of memory.";
1062         case GL_INVALID_FRAMEBUFFER_OPERATION:
1063             return "Invalid framebuffer operation.";
1064         default:
1065             UNREACHABLE();
1066             return "Unknown error.";
1067     }
1068 }
1069 
ElementTypeSize(GLenum elementType)1070 unsigned int ElementTypeSize(GLenum elementType)
1071 {
1072     switch (elementType)
1073     {
1074         case GL_UNSIGNED_BYTE:
1075             return sizeof(GLubyte);
1076         case GL_UNSIGNED_SHORT:
1077             return sizeof(GLushort);
1078         case GL_UNSIGNED_INT:
1079             return sizeof(GLuint);
1080         default:
1081             UNREACHABLE();
1082             return 0;
1083     }
1084 }
1085 
IsMipmapFiltered(GLenum minFilterMode)1086 bool IsMipmapFiltered(GLenum minFilterMode)
1087 {
1088     switch (minFilterMode)
1089     {
1090         case GL_NEAREST:
1091         case GL_LINEAR:
1092             return false;
1093         case GL_NEAREST_MIPMAP_NEAREST:
1094         case GL_LINEAR_MIPMAP_NEAREST:
1095         case GL_NEAREST_MIPMAP_LINEAR:
1096         case GL_LINEAR_MIPMAP_LINEAR:
1097             return true;
1098         default:
1099             UNREACHABLE();
1100             return false;
1101     }
1102 }
1103 
GetPipelineType(ShaderType type)1104 PipelineType GetPipelineType(ShaderType type)
1105 {
1106     switch (type)
1107     {
1108         case ShaderType::Vertex:
1109         case ShaderType::Fragment:
1110         case ShaderType::Geometry:
1111             return PipelineType::GraphicsPipeline;
1112         case ShaderType::Compute:
1113             return PipelineType::ComputePipeline;
1114         default:
1115             UNREACHABLE();
1116             return PipelineType::GraphicsPipeline;
1117     }
1118 }
1119 
GetDebugMessageSourceString(GLenum source)1120 const char *GetDebugMessageSourceString(GLenum source)
1121 {
1122     switch (source)
1123     {
1124         case GL_DEBUG_SOURCE_API:
1125             return "API";
1126         case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1127             return "Window System";
1128         case GL_DEBUG_SOURCE_SHADER_COMPILER:
1129             return "Shader Compiler";
1130         case GL_DEBUG_SOURCE_THIRD_PARTY:
1131             return "Third Party";
1132         case GL_DEBUG_SOURCE_APPLICATION:
1133             return "Application";
1134         case GL_DEBUG_SOURCE_OTHER:
1135             return "Other";
1136         default:
1137             return "Unknown Source";
1138     }
1139 }
1140 
GetDebugMessageTypeString(GLenum type)1141 const char *GetDebugMessageTypeString(GLenum type)
1142 {
1143     switch (type)
1144     {
1145         case GL_DEBUG_TYPE_ERROR:
1146             return "Error";
1147         case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1148             return "Deprecated behavior";
1149         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1150             return "Undefined behavior";
1151         case GL_DEBUG_TYPE_PORTABILITY:
1152             return "Portability";
1153         case GL_DEBUG_TYPE_PERFORMANCE:
1154             return "Performance";
1155         case GL_DEBUG_TYPE_OTHER:
1156             return "Other";
1157         case GL_DEBUG_TYPE_MARKER:
1158             return "Marker";
1159         default:
1160             return "Unknown Type";
1161     }
1162 }
1163 
GetDebugMessageSeverityString(GLenum severity)1164 const char *GetDebugMessageSeverityString(GLenum severity)
1165 {
1166     switch (severity)
1167     {
1168         case GL_DEBUG_SEVERITY_HIGH:
1169             return "High";
1170         case GL_DEBUG_SEVERITY_MEDIUM:
1171             return "Medium";
1172         case GL_DEBUG_SEVERITY_LOW:
1173             return "Low";
1174         case GL_DEBUG_SEVERITY_NOTIFICATION:
1175             return "Notification";
1176         default:
1177             return "Unknown Severity";
1178     }
1179 }
1180 
GetShaderTypeFromBitfield(size_t singleShaderType)1181 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType)
1182 {
1183     switch (singleShaderType)
1184     {
1185         case GL_VERTEX_SHADER_BIT:
1186             return ShaderType::Vertex;
1187         case GL_FRAGMENT_SHADER_BIT:
1188             return ShaderType::Fragment;
1189         case GL_COMPUTE_SHADER_BIT:
1190             return ShaderType::Compute;
1191         case GL_GEOMETRY_SHADER_BIT:
1192             return ShaderType::Geometry;
1193         case GL_TESS_CONTROL_SHADER_BIT:
1194             return ShaderType::TessControl;
1195         case GL_TESS_EVALUATION_SHADER_BIT:
1196             return ShaderType::TessEvaluation;
1197         default:
1198             return ShaderType::InvalidEnum;
1199     }
1200 }
1201 
GetBitfieldFromShaderType(ShaderType shaderType)1202 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType)
1203 {
1204     switch (shaderType)
1205     {
1206         case ShaderType::Vertex:
1207             return GL_VERTEX_SHADER_BIT;
1208         case ShaderType::Fragment:
1209             return GL_FRAGMENT_SHADER_BIT;
1210         case ShaderType::Compute:
1211             return GL_COMPUTE_SHADER_BIT;
1212         case ShaderType::Geometry:
1213             return GL_GEOMETRY_SHADER_BIT;
1214         case ShaderType::TessControl:
1215             return GL_TESS_CONTROL_SHADER_BIT;
1216         case ShaderType::TessEvaluation:
1217             return GL_TESS_EVALUATION_SHADER_BIT;
1218         default:
1219             UNREACHABLE();
1220             return GL_ZERO;
1221     }
1222 }
1223 
ShaderTypeSupportsTransformFeedback(ShaderType shaderType)1224 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
1225 {
1226     switch (shaderType)
1227     {
1228         case ShaderType::Vertex:
1229         case ShaderType::Geometry:
1230         case ShaderType::TessEvaluation:
1231             return true;
1232         default:
1233             return false;
1234     }
1235 }
1236 
GetLastPreFragmentStage(ShaderBitSet shaderTypes)1237 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes)
1238 {
1239     shaderTypes.reset(ShaderType::Fragment);
1240     shaderTypes.reset(ShaderType::Compute);
1241     return shaderTypes.any() ? shaderTypes.last() : ShaderType::InvalidEnum;
1242 }
1243 }  // namespace gl
1244 
1245 namespace egl
1246 {
1247 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
1248               "Unexpected EGL cube map enum value.");
1249 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
1250               "Unexpected EGL cube map enum value.");
1251 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
1252               "Unexpected EGL cube map enum value.");
1253 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
1254               "Unexpected EGL cube map enum value.");
1255 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
1256               "Unexpected EGL cube map enum value.");
1257 
IsCubeMapTextureTarget(EGLenum target)1258 bool IsCubeMapTextureTarget(EGLenum target)
1259 {
1260     return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
1261 }
1262 
CubeMapTextureTargetToLayerIndex(EGLenum target)1263 size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
1264 {
1265     ASSERT(IsCubeMapTextureTarget(target));
1266     return target - static_cast<size_t>(FirstCubeMapTextureTarget);
1267 }
1268 
LayerIndexToCubeMapTextureTarget(size_t index)1269 EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
1270 {
1271     ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
1272     return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
1273 }
1274 
IsTextureTarget(EGLenum target)1275 bool IsTextureTarget(EGLenum target)
1276 {
1277     switch (target)
1278     {
1279         case EGL_GL_TEXTURE_2D_KHR:
1280         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
1281         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
1282         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
1283         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
1284         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
1285         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
1286         case EGL_GL_TEXTURE_3D_KHR:
1287             return true;
1288 
1289         default:
1290             return false;
1291     }
1292 }
1293 
IsRenderbufferTarget(EGLenum target)1294 bool IsRenderbufferTarget(EGLenum target)
1295 {
1296     return target == EGL_GL_RENDERBUFFER_KHR;
1297 }
1298 
IsExternalImageTarget(EGLenum target)1299 bool IsExternalImageTarget(EGLenum target)
1300 {
1301     switch (target)
1302     {
1303         case EGL_NATIVE_BUFFER_ANDROID:
1304         case EGL_D3D11_TEXTURE_ANGLE:
1305         case EGL_LINUX_DMA_BUF_EXT:
1306         case EGL_METAL_TEXTURE_ANGLE:
1307         case EGL_VULKAN_IMAGE_ANGLE:
1308             return true;
1309 
1310         default:
1311             return false;
1312     }
1313 }
1314 
GetGenericErrorMessage(EGLint error)1315 const char *GetGenericErrorMessage(EGLint error)
1316 {
1317     switch (error)
1318     {
1319         case EGL_SUCCESS:
1320             return "";
1321         case EGL_NOT_INITIALIZED:
1322             return "Not initialized.";
1323         case EGL_BAD_ACCESS:
1324             return "Bad access.";
1325         case EGL_BAD_ALLOC:
1326             return "Bad allocation.";
1327         case EGL_BAD_ATTRIBUTE:
1328             return "Bad attribute.";
1329         case EGL_BAD_CONFIG:
1330             return "Bad config.";
1331         case EGL_BAD_CONTEXT:
1332             return "Bad context.";
1333         case EGL_BAD_CURRENT_SURFACE:
1334             return "Bad current surface.";
1335         case EGL_BAD_DISPLAY:
1336             return "Bad display.";
1337         case EGL_BAD_MATCH:
1338             return "Bad match.";
1339         case EGL_BAD_NATIVE_WINDOW:
1340             return "Bad native window.";
1341         case EGL_BAD_NATIVE_PIXMAP:
1342             return "Bad native pixmap.";
1343         case EGL_BAD_PARAMETER:
1344             return "Bad parameter.";
1345         case EGL_BAD_SURFACE:
1346             return "Bad surface.";
1347         case EGL_CONTEXT_LOST:
1348             return "Context lost.";
1349         case EGL_BAD_STREAM_KHR:
1350             return "Bad stream.";
1351         case EGL_BAD_STATE_KHR:
1352             return "Bad state.";
1353         case EGL_BAD_DEVICE_EXT:
1354             return "Bad device.";
1355         default:
1356             UNREACHABLE();
1357             return "Unknown error.";
1358     }
1359 }
1360 
1361 }  // namespace egl
1362 
1363 namespace egl_gl
1364 {
EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)1365 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
1366 {
1367     return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
1368 }
1369 }  // namespace egl_gl
1370 
1371 namespace gl_egl
1372 {
GLComponentTypeToEGLColorComponentType(GLenum glComponentType)1373 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
1374 {
1375     switch (glComponentType)
1376     {
1377         case GL_FLOAT:
1378             return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
1379 
1380         case GL_UNSIGNED_NORMALIZED:
1381             return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
1382 
1383         default:
1384             UNREACHABLE();
1385             return EGL_NONE;
1386     }
1387 }
1388 
GLObjectHandleToEGLClientBuffer(GLuint handle)1389 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
1390 {
1391     return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
1392 }
1393 
1394 }  // namespace gl_egl
1395 
1396 namespace angle
1397 {
IsDrawEntryPoint(EntryPoint entryPoint)1398 bool IsDrawEntryPoint(EntryPoint entryPoint)
1399 {
1400     switch (entryPoint)
1401     {
1402         case EntryPoint::GLDrawArrays:
1403         case EntryPoint::GLDrawArraysIndirect:
1404         case EntryPoint::GLDrawArraysInstanced:
1405         case EntryPoint::GLDrawArraysInstancedANGLE:
1406         case EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE:
1407         case EntryPoint::GLDrawArraysInstancedEXT:
1408         case EntryPoint::GLDrawElements:
1409         case EntryPoint::GLDrawElementsBaseVertex:
1410         case EntryPoint::GLDrawElementsBaseVertexEXT:
1411         case EntryPoint::GLDrawElementsBaseVertexOES:
1412         case EntryPoint::GLDrawElementsIndirect:
1413         case EntryPoint::GLDrawElementsInstanced:
1414         case EntryPoint::GLDrawElementsInstancedANGLE:
1415         case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE:
1416         case EntryPoint::GLDrawElementsInstancedBaseVertexEXT:
1417         case EntryPoint::GLDrawElementsInstancedBaseVertexOES:
1418         case EntryPoint::GLDrawElementsInstancedEXT:
1419         case EntryPoint::GLDrawRangeElements:
1420         case EntryPoint::GLDrawRangeElementsBaseVertex:
1421         case EntryPoint::GLDrawRangeElementsBaseVertexEXT:
1422         case EntryPoint::GLDrawRangeElementsBaseVertexOES:
1423         case EntryPoint::GLDrawTexfOES:
1424         case EntryPoint::GLDrawTexfvOES:
1425         case EntryPoint::GLDrawTexiOES:
1426         case EntryPoint::GLDrawTexivOES:
1427         case EntryPoint::GLDrawTexsOES:
1428         case EntryPoint::GLDrawTexsvOES:
1429         case EntryPoint::GLDrawTexxOES:
1430         case EntryPoint::GLDrawTexxvOES:
1431             return true;
1432         default:
1433             return false;
1434     }
1435 }
1436 
IsDispatchEntryPoint(EntryPoint entryPoint)1437 bool IsDispatchEntryPoint(EntryPoint entryPoint)
1438 {
1439     switch (entryPoint)
1440     {
1441         case EntryPoint::GLDispatchCompute:
1442         case EntryPoint::GLDispatchComputeIndirect:
1443             return true;
1444         default:
1445             return false;
1446     }
1447 }
1448 
IsClearEntryPoint(EntryPoint entryPoint)1449 bool IsClearEntryPoint(EntryPoint entryPoint)
1450 {
1451     switch (entryPoint)
1452     {
1453         case EntryPoint::GLClear:
1454         case EntryPoint::GLClearBufferfi:
1455         case EntryPoint::GLClearBufferfv:
1456         case EntryPoint::GLClearBufferiv:
1457         case EntryPoint::GLClearBufferuiv:
1458             return true;
1459         default:
1460             return false;
1461     }
1462 }
1463 
IsQueryEntryPoint(EntryPoint entryPoint)1464 bool IsQueryEntryPoint(EntryPoint entryPoint)
1465 {
1466     switch (entryPoint)
1467     {
1468         case EntryPoint::GLBeginQuery:
1469         case EntryPoint::GLBeginQueryEXT:
1470         case EntryPoint::GLEndQuery:
1471         case EntryPoint::GLEndQueryEXT:
1472             return true;
1473         default:
1474             return false;
1475     }
1476 }
1477 }  // namespace angle
1478 
writeFile(const char * path,const void * content,size_t size)1479 void writeFile(const char *path, const void *content, size_t size)
1480 {
1481 #if !defined(ANGLE_ENABLE_WINDOWS_UWP)
1482     FILE *file = fopen(path, "w");
1483     if (!file)
1484     {
1485         UNREACHABLE();
1486         return;
1487     }
1488 
1489     fwrite(content, sizeof(char), size, file);
1490     fclose(file);
1491 #else
1492     UNREACHABLE();
1493     return;
1494 #endif  // !ANGLE_ENABLE_WINDOWS_UWP
1495 }
1496