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 <GLSLANG/ShaderVars.h>
11 #include "common/mathutil.h"
12 #include "common/platform.h"
13
14 #include <set>
15
16 #if defined(ANGLE_ENABLE_WINDOWS_STORE)
17 # include <windows.applicationmodel.core.h>
18 # include <windows.graphics.display.h>
19 # include <wrl.h>
20 # include <wrl/wrappers/corewrappers.h>
21 #endif
22
23 namespace
24 {
25
26 template <class IndexType>
ComputeTypedIndexRange(const IndexType * indices,size_t count,bool primitiveRestartEnabled,GLuint primitiveRestartIndex)27 gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
28 size_t count,
29 bool primitiveRestartEnabled,
30 GLuint primitiveRestartIndex)
31 {
32 ASSERT(count > 0);
33
34 IndexType minIndex = 0;
35 IndexType maxIndex = 0;
36 size_t nonPrimitiveRestartIndices = 0;
37
38 if (primitiveRestartEnabled)
39 {
40 // Find the first non-primitive restart index to initialize the min and max values
41 size_t i = 0;
42 for (; i < count; i++)
43 {
44 if (indices[i] != primitiveRestartIndex)
45 {
46 minIndex = indices[i];
47 maxIndex = indices[i];
48 nonPrimitiveRestartIndices++;
49 break;
50 }
51 }
52
53 // Loop over the rest of the indices
54 for (; i < count; i++)
55 {
56 if (indices[i] != primitiveRestartIndex)
57 {
58 if (minIndex > indices[i])
59 {
60 minIndex = indices[i];
61 }
62 if (maxIndex < indices[i])
63 {
64 maxIndex = indices[i];
65 }
66 nonPrimitiveRestartIndices++;
67 }
68 }
69 }
70 else
71 {
72 minIndex = indices[0];
73 maxIndex = indices[0];
74 nonPrimitiveRestartIndices = count;
75
76 for (size_t i = 1; i < count; i++)
77 {
78 if (minIndex > indices[i])
79 {
80 minIndex = indices[i];
81 }
82 if (maxIndex < indices[i])
83 {
84 maxIndex = indices[i];
85 }
86 }
87 }
88
89 return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
90 nonPrimitiveRestartIndices);
91 }
92
93 } // anonymous namespace
94
95 namespace gl
96 {
97
VariableComponentCount(GLenum type)98 int VariableComponentCount(GLenum type)
99 {
100 return VariableRowCount(type) * VariableColumnCount(type);
101 }
102
VariableComponentType(GLenum type)103 GLenum VariableComponentType(GLenum type)
104 {
105 switch (type)
106 {
107 case GL_BOOL:
108 case GL_BOOL_VEC2:
109 case GL_BOOL_VEC3:
110 case GL_BOOL_VEC4:
111 return GL_BOOL;
112 case GL_FLOAT:
113 case GL_FLOAT_VEC2:
114 case GL_FLOAT_VEC3:
115 case GL_FLOAT_VEC4:
116 case GL_FLOAT_MAT2:
117 case GL_FLOAT_MAT3:
118 case GL_FLOAT_MAT4:
119 case GL_FLOAT_MAT2x3:
120 case GL_FLOAT_MAT3x2:
121 case GL_FLOAT_MAT2x4:
122 case GL_FLOAT_MAT4x2:
123 case GL_FLOAT_MAT3x4:
124 case GL_FLOAT_MAT4x3:
125 return GL_FLOAT;
126 case GL_INT:
127 case GL_SAMPLER_2D:
128 case GL_SAMPLER_2D_RECT_ANGLE:
129 case GL_SAMPLER_3D:
130 case GL_SAMPLER_CUBE:
131 case GL_SAMPLER_2D_ARRAY:
132 case GL_SAMPLER_EXTERNAL_OES:
133 case GL_SAMPLER_2D_MULTISAMPLE:
134 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
135 case GL_INT_SAMPLER_2D:
136 case GL_INT_SAMPLER_3D:
137 case GL_INT_SAMPLER_CUBE:
138 case GL_INT_SAMPLER_2D_ARRAY:
139 case GL_INT_SAMPLER_2D_MULTISAMPLE:
140 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
141 case GL_UNSIGNED_INT_SAMPLER_2D:
142 case GL_UNSIGNED_INT_SAMPLER_3D:
143 case GL_UNSIGNED_INT_SAMPLER_CUBE:
144 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
145 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
146 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
147 case GL_SAMPLER_2D_SHADOW:
148 case GL_SAMPLER_CUBE_SHADOW:
149 case GL_SAMPLER_2D_ARRAY_SHADOW:
150 case GL_INT_VEC2:
151 case GL_INT_VEC3:
152 case GL_INT_VEC4:
153 case GL_IMAGE_2D:
154 case GL_INT_IMAGE_2D:
155 case GL_UNSIGNED_INT_IMAGE_2D:
156 case GL_IMAGE_3D:
157 case GL_INT_IMAGE_3D:
158 case GL_UNSIGNED_INT_IMAGE_3D:
159 case GL_IMAGE_2D_ARRAY:
160 case GL_INT_IMAGE_2D_ARRAY:
161 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
162 case GL_IMAGE_CUBE:
163 case GL_INT_IMAGE_CUBE:
164 case GL_UNSIGNED_INT_IMAGE_CUBE:
165 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
166 return GL_INT;
167 case GL_UNSIGNED_INT:
168 case GL_UNSIGNED_INT_VEC2:
169 case GL_UNSIGNED_INT_VEC3:
170 case GL_UNSIGNED_INT_VEC4:
171 return GL_UNSIGNED_INT;
172 default:
173 UNREACHABLE();
174 }
175
176 return GL_NONE;
177 }
178
VariableComponentSize(GLenum type)179 size_t VariableComponentSize(GLenum type)
180 {
181 switch (type)
182 {
183 case GL_BOOL:
184 return sizeof(GLint);
185 case GL_FLOAT:
186 return sizeof(GLfloat);
187 case GL_INT:
188 return sizeof(GLint);
189 case GL_UNSIGNED_INT:
190 return sizeof(GLuint);
191 default:
192 UNREACHABLE();
193 }
194
195 return 0;
196 }
197
VariableInternalSize(GLenum type)198 size_t VariableInternalSize(GLenum type)
199 {
200 // Expanded to 4-element vectors
201 return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
202 }
203
VariableExternalSize(GLenum type)204 size_t VariableExternalSize(GLenum type)
205 {
206 return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
207 }
208
VariableBoolVectorType(GLenum type)209 GLenum VariableBoolVectorType(GLenum type)
210 {
211 switch (type)
212 {
213 case GL_FLOAT:
214 case GL_INT:
215 case GL_UNSIGNED_INT:
216 return GL_BOOL;
217 case GL_FLOAT_VEC2:
218 case GL_INT_VEC2:
219 case GL_UNSIGNED_INT_VEC2:
220 return GL_BOOL_VEC2;
221 case GL_FLOAT_VEC3:
222 case GL_INT_VEC3:
223 case GL_UNSIGNED_INT_VEC3:
224 return GL_BOOL_VEC3;
225 case GL_FLOAT_VEC4:
226 case GL_INT_VEC4:
227 case GL_UNSIGNED_INT_VEC4:
228 return GL_BOOL_VEC4;
229
230 default:
231 UNREACHABLE();
232 return GL_NONE;
233 }
234 }
235
VariableRowCount(GLenum type)236 int VariableRowCount(GLenum type)
237 {
238 switch (type)
239 {
240 case GL_NONE:
241 return 0;
242 case GL_BOOL:
243 case GL_FLOAT:
244 case GL_INT:
245 case GL_UNSIGNED_INT:
246 case GL_BOOL_VEC2:
247 case GL_FLOAT_VEC2:
248 case GL_INT_VEC2:
249 case GL_UNSIGNED_INT_VEC2:
250 case GL_BOOL_VEC3:
251 case GL_FLOAT_VEC3:
252 case GL_INT_VEC3:
253 case GL_UNSIGNED_INT_VEC3:
254 case GL_BOOL_VEC4:
255 case GL_FLOAT_VEC4:
256 case GL_INT_VEC4:
257 case GL_UNSIGNED_INT_VEC4:
258 case GL_SAMPLER_2D:
259 case GL_SAMPLER_3D:
260 case GL_SAMPLER_CUBE:
261 case GL_SAMPLER_2D_ARRAY:
262 case GL_SAMPLER_EXTERNAL_OES:
263 case GL_SAMPLER_2D_RECT_ANGLE:
264 case GL_SAMPLER_2D_MULTISAMPLE:
265 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
266 case GL_INT_SAMPLER_2D:
267 case GL_INT_SAMPLER_3D:
268 case GL_INT_SAMPLER_CUBE:
269 case GL_INT_SAMPLER_2D_ARRAY:
270 case GL_INT_SAMPLER_2D_MULTISAMPLE:
271 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
272 case GL_UNSIGNED_INT_SAMPLER_2D:
273 case GL_UNSIGNED_INT_SAMPLER_3D:
274 case GL_UNSIGNED_INT_SAMPLER_CUBE:
275 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
276 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
277 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
278 case GL_SAMPLER_2D_SHADOW:
279 case GL_SAMPLER_CUBE_SHADOW:
280 case GL_SAMPLER_2D_ARRAY_SHADOW:
281 case GL_IMAGE_2D:
282 case GL_INT_IMAGE_2D:
283 case GL_UNSIGNED_INT_IMAGE_2D:
284 case GL_IMAGE_2D_ARRAY:
285 case GL_INT_IMAGE_2D_ARRAY:
286 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
287 case GL_IMAGE_3D:
288 case GL_INT_IMAGE_3D:
289 case GL_UNSIGNED_INT_IMAGE_3D:
290 case GL_IMAGE_CUBE:
291 case GL_INT_IMAGE_CUBE:
292 case GL_UNSIGNED_INT_IMAGE_CUBE:
293 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
294 return 1;
295 case GL_FLOAT_MAT2:
296 case GL_FLOAT_MAT3x2:
297 case GL_FLOAT_MAT4x2:
298 return 2;
299 case GL_FLOAT_MAT3:
300 case GL_FLOAT_MAT2x3:
301 case GL_FLOAT_MAT4x3:
302 return 3;
303 case GL_FLOAT_MAT4:
304 case GL_FLOAT_MAT2x4:
305 case GL_FLOAT_MAT3x4:
306 return 4;
307 default:
308 UNREACHABLE();
309 }
310
311 return 0;
312 }
313
VariableColumnCount(GLenum type)314 int VariableColumnCount(GLenum type)
315 {
316 switch (type)
317 {
318 case GL_NONE:
319 return 0;
320 case GL_BOOL:
321 case GL_FLOAT:
322 case GL_INT:
323 case GL_UNSIGNED_INT:
324 case GL_SAMPLER_2D:
325 case GL_SAMPLER_3D:
326 case GL_SAMPLER_CUBE:
327 case GL_SAMPLER_2D_ARRAY:
328 case GL_SAMPLER_2D_MULTISAMPLE:
329 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
330 case GL_INT_SAMPLER_2D:
331 case GL_INT_SAMPLER_3D:
332 case GL_INT_SAMPLER_CUBE:
333 case GL_INT_SAMPLER_2D_ARRAY:
334 case GL_INT_SAMPLER_2D_MULTISAMPLE:
335 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
336 case GL_SAMPLER_EXTERNAL_OES:
337 case GL_SAMPLER_2D_RECT_ANGLE:
338 case GL_UNSIGNED_INT_SAMPLER_2D:
339 case GL_UNSIGNED_INT_SAMPLER_3D:
340 case GL_UNSIGNED_INT_SAMPLER_CUBE:
341 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
342 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
343 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
344 case GL_SAMPLER_2D_SHADOW:
345 case GL_SAMPLER_CUBE_SHADOW:
346 case GL_SAMPLER_2D_ARRAY_SHADOW:
347 case GL_IMAGE_2D:
348 case GL_INT_IMAGE_2D:
349 case GL_UNSIGNED_INT_IMAGE_2D:
350 case GL_IMAGE_3D:
351 case GL_INT_IMAGE_3D:
352 case GL_UNSIGNED_INT_IMAGE_3D:
353 case GL_IMAGE_2D_ARRAY:
354 case GL_INT_IMAGE_2D_ARRAY:
355 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
356 case GL_IMAGE_CUBE:
357 case GL_INT_IMAGE_CUBE:
358 case GL_UNSIGNED_INT_IMAGE_CUBE:
359 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
360 return 1;
361 case GL_BOOL_VEC2:
362 case GL_FLOAT_VEC2:
363 case GL_INT_VEC2:
364 case GL_UNSIGNED_INT_VEC2:
365 case GL_FLOAT_MAT2:
366 case GL_FLOAT_MAT2x3:
367 case GL_FLOAT_MAT2x4:
368 return 2;
369 case GL_BOOL_VEC3:
370 case GL_FLOAT_VEC3:
371 case GL_INT_VEC3:
372 case GL_UNSIGNED_INT_VEC3:
373 case GL_FLOAT_MAT3:
374 case GL_FLOAT_MAT3x2:
375 case GL_FLOAT_MAT3x4:
376 return 3;
377 case GL_BOOL_VEC4:
378 case GL_FLOAT_VEC4:
379 case GL_INT_VEC4:
380 case GL_UNSIGNED_INT_VEC4:
381 case GL_FLOAT_MAT4:
382 case GL_FLOAT_MAT4x2:
383 case GL_FLOAT_MAT4x3:
384 return 4;
385 default:
386 UNREACHABLE();
387 }
388
389 return 0;
390 }
391
IsSamplerType(GLenum type)392 bool IsSamplerType(GLenum type)
393 {
394 switch (type)
395 {
396 case GL_SAMPLER_2D:
397 case GL_SAMPLER_3D:
398 case GL_SAMPLER_CUBE:
399 case GL_SAMPLER_2D_ARRAY:
400 case GL_SAMPLER_EXTERNAL_OES:
401 case GL_SAMPLER_2D_MULTISAMPLE:
402 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
403 case GL_SAMPLER_2D_RECT_ANGLE:
404 case GL_INT_SAMPLER_2D:
405 case GL_INT_SAMPLER_3D:
406 case GL_INT_SAMPLER_CUBE:
407 case GL_INT_SAMPLER_2D_ARRAY:
408 case GL_INT_SAMPLER_2D_MULTISAMPLE:
409 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
410 case GL_UNSIGNED_INT_SAMPLER_2D:
411 case GL_UNSIGNED_INT_SAMPLER_3D:
412 case GL_UNSIGNED_INT_SAMPLER_CUBE:
413 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
414 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
415 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
416 case GL_SAMPLER_2D_SHADOW:
417 case GL_SAMPLER_CUBE_SHADOW:
418 case GL_SAMPLER_2D_ARRAY_SHADOW:
419 return true;
420 }
421
422 return false;
423 }
424
IsSamplerCubeType(GLenum type)425 bool IsSamplerCubeType(GLenum type)
426 {
427 switch (type)
428 {
429 case GL_SAMPLER_CUBE:
430 case GL_INT_SAMPLER_CUBE:
431 case GL_UNSIGNED_INT_SAMPLER_CUBE:
432 case GL_SAMPLER_CUBE_SHADOW:
433 return true;
434 }
435
436 return false;
437 }
438
IsImageType(GLenum type)439 bool IsImageType(GLenum type)
440 {
441 switch (type)
442 {
443 case GL_IMAGE_2D:
444 case GL_INT_IMAGE_2D:
445 case GL_UNSIGNED_INT_IMAGE_2D:
446 case GL_IMAGE_3D:
447 case GL_INT_IMAGE_3D:
448 case GL_UNSIGNED_INT_IMAGE_3D:
449 case GL_IMAGE_2D_ARRAY:
450 case GL_INT_IMAGE_2D_ARRAY:
451 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
452 case GL_IMAGE_CUBE:
453 case GL_INT_IMAGE_CUBE:
454 case GL_UNSIGNED_INT_IMAGE_CUBE:
455 return true;
456 }
457 return false;
458 }
459
IsImage2DType(GLenum type)460 bool IsImage2DType(GLenum type)
461 {
462 switch (type)
463 {
464 case GL_IMAGE_2D:
465 case GL_INT_IMAGE_2D:
466 case GL_UNSIGNED_INT_IMAGE_2D:
467 return true;
468 case GL_IMAGE_3D:
469 case GL_INT_IMAGE_3D:
470 case GL_UNSIGNED_INT_IMAGE_3D:
471 case GL_IMAGE_2D_ARRAY:
472 case GL_INT_IMAGE_2D_ARRAY:
473 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
474 case GL_IMAGE_CUBE:
475 case GL_INT_IMAGE_CUBE:
476 case GL_UNSIGNED_INT_IMAGE_CUBE:
477 return false;
478 default:
479 UNREACHABLE();
480 return false;
481 }
482 }
483
IsAtomicCounterType(GLenum type)484 bool IsAtomicCounterType(GLenum type)
485 {
486 return type == GL_UNSIGNED_INT_ATOMIC_COUNTER;
487 }
488
IsOpaqueType(GLenum type)489 bool IsOpaqueType(GLenum type)
490 {
491 // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
492 return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
493 }
494
IsMatrixType(GLenum type)495 bool IsMatrixType(GLenum type)
496 {
497 return VariableRowCount(type) > 1;
498 }
499
TransposeMatrixType(GLenum type)500 GLenum TransposeMatrixType(GLenum type)
501 {
502 if (!IsMatrixType(type))
503 {
504 return type;
505 }
506
507 switch (type)
508 {
509 case GL_FLOAT_MAT2:
510 return GL_FLOAT_MAT2;
511 case GL_FLOAT_MAT3:
512 return GL_FLOAT_MAT3;
513 case GL_FLOAT_MAT4:
514 return GL_FLOAT_MAT4;
515 case GL_FLOAT_MAT2x3:
516 return GL_FLOAT_MAT3x2;
517 case GL_FLOAT_MAT3x2:
518 return GL_FLOAT_MAT2x3;
519 case GL_FLOAT_MAT2x4:
520 return GL_FLOAT_MAT4x2;
521 case GL_FLOAT_MAT4x2:
522 return GL_FLOAT_MAT2x4;
523 case GL_FLOAT_MAT3x4:
524 return GL_FLOAT_MAT4x3;
525 case GL_FLOAT_MAT4x3:
526 return GL_FLOAT_MAT3x4;
527 default:
528 UNREACHABLE();
529 return GL_NONE;
530 }
531 }
532
MatrixRegisterCount(GLenum type,bool isRowMajorMatrix)533 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
534 {
535 ASSERT(IsMatrixType(type));
536 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
537 }
538
MatrixComponentCount(GLenum type,bool isRowMajorMatrix)539 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
540 {
541 ASSERT(IsMatrixType(type));
542 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
543 }
544
VariableRegisterCount(GLenum type)545 int VariableRegisterCount(GLenum type)
546 {
547 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
548 }
549
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)550 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
551 {
552 ASSERT(allocationSize <= bitsSize);
553
554 unsigned int mask = std::numeric_limits<unsigned int>::max() >>
555 (std::numeric_limits<unsigned int>::digits - allocationSize);
556
557 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
558 {
559 if ((*bits & mask) == 0)
560 {
561 *bits |= mask;
562 return i;
563 }
564
565 mask <<= 1;
566 }
567
568 return -1;
569 }
570
ComputeIndexRange(DrawElementsType indexType,const GLvoid * indices,size_t count,bool primitiveRestartEnabled)571 IndexRange ComputeIndexRange(DrawElementsType indexType,
572 const GLvoid *indices,
573 size_t count,
574 bool primitiveRestartEnabled)
575 {
576 switch (indexType)
577 {
578 case DrawElementsType::UnsignedByte:
579 return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
580 primitiveRestartEnabled,
581 GetPrimitiveRestartIndex(indexType));
582 case DrawElementsType::UnsignedShort:
583 return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
584 primitiveRestartEnabled,
585 GetPrimitiveRestartIndex(indexType));
586 case DrawElementsType::UnsignedInt:
587 return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
588 primitiveRestartEnabled,
589 GetPrimitiveRestartIndex(indexType));
590 default:
591 UNREACHABLE();
592 return IndexRange();
593 }
594 }
595
GetPrimitiveRestartIndex(DrawElementsType indexType)596 GLuint GetPrimitiveRestartIndex(DrawElementsType indexType)
597 {
598 switch (indexType)
599 {
600 case DrawElementsType::UnsignedByte:
601 return 0xFF;
602 case DrawElementsType::UnsignedShort:
603 return 0xFFFF;
604 case DrawElementsType::UnsignedInt:
605 return 0xFFFFFFFF;
606 default:
607 UNREACHABLE();
608 return 0;
609 }
610 }
611
IsTriangleMode(PrimitiveMode drawMode)612 bool IsTriangleMode(PrimitiveMode drawMode)
613 {
614 switch (drawMode)
615 {
616 case PrimitiveMode::Triangles:
617 case PrimitiveMode::TriangleFan:
618 case PrimitiveMode::TriangleStrip:
619 return true;
620 case PrimitiveMode::Points:
621 case PrimitiveMode::Lines:
622 case PrimitiveMode::LineLoop:
623 case PrimitiveMode::LineStrip:
624 return false;
625 default:
626 UNREACHABLE();
627 }
628
629 return false;
630 }
631
632 namespace priv
633 {
634 const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes = {
635 {{PrimitiveMode::LineLoop, true},
636 {PrimitiveMode::LineStrip, true},
637 {PrimitiveMode::LineStripAdjacency, true},
638 {PrimitiveMode::Lines, true}}};
639 } // namespace priv
640
IsIntegerFormat(GLenum unsizedFormat)641 bool IsIntegerFormat(GLenum unsizedFormat)
642 {
643 switch (unsizedFormat)
644 {
645 case GL_RGBA_INTEGER:
646 case GL_RGB_INTEGER:
647 case GL_RG_INTEGER:
648 case GL_RED_INTEGER:
649 return true;
650
651 default:
652 return false;
653 }
654 }
655
656 // [OpenGL ES SL 3.00.4] Section 11 p. 120
657 // Vertex Outs/Fragment Ins packing priorities
VariableSortOrder(GLenum type)658 int VariableSortOrder(GLenum type)
659 {
660 switch (type)
661 {
662 // 1. Arrays of mat4 and mat4
663 // Non-square matrices of type matCxR consume the same space as a square
664 // matrix of type matN where N is the greater of C and R
665 case GL_FLOAT_MAT4:
666 case GL_FLOAT_MAT2x4:
667 case GL_FLOAT_MAT3x4:
668 case GL_FLOAT_MAT4x2:
669 case GL_FLOAT_MAT4x3:
670 return 0;
671
672 // 2. Arrays of mat2 and mat2 (since they occupy full rows)
673 case GL_FLOAT_MAT2:
674 return 1;
675
676 // 3. Arrays of vec4 and vec4
677 case GL_FLOAT_VEC4:
678 case GL_INT_VEC4:
679 case GL_BOOL_VEC4:
680 case GL_UNSIGNED_INT_VEC4:
681 return 2;
682
683 // 4. Arrays of mat3 and mat3
684 case GL_FLOAT_MAT3:
685 case GL_FLOAT_MAT2x3:
686 case GL_FLOAT_MAT3x2:
687 return 3;
688
689 // 5. Arrays of vec3 and vec3
690 case GL_FLOAT_VEC3:
691 case GL_INT_VEC3:
692 case GL_BOOL_VEC3:
693 case GL_UNSIGNED_INT_VEC3:
694 return 4;
695
696 // 6. Arrays of vec2 and vec2
697 case GL_FLOAT_VEC2:
698 case GL_INT_VEC2:
699 case GL_BOOL_VEC2:
700 case GL_UNSIGNED_INT_VEC2:
701 return 5;
702
703 // 7. Single component types
704 case GL_FLOAT:
705 case GL_INT:
706 case GL_BOOL:
707 case GL_UNSIGNED_INT:
708 case GL_SAMPLER_2D:
709 case GL_SAMPLER_CUBE:
710 case GL_SAMPLER_EXTERNAL_OES:
711 case GL_SAMPLER_2D_RECT_ANGLE:
712 case GL_SAMPLER_2D_ARRAY:
713 case GL_SAMPLER_2D_MULTISAMPLE:
714 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
715 case GL_SAMPLER_3D:
716 case GL_INT_SAMPLER_2D:
717 case GL_INT_SAMPLER_3D:
718 case GL_INT_SAMPLER_CUBE:
719 case GL_INT_SAMPLER_2D_ARRAY:
720 case GL_INT_SAMPLER_2D_MULTISAMPLE:
721 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
722 case GL_UNSIGNED_INT_SAMPLER_2D:
723 case GL_UNSIGNED_INT_SAMPLER_3D:
724 case GL_UNSIGNED_INT_SAMPLER_CUBE:
725 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
726 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
727 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
728 case GL_SAMPLER_2D_SHADOW:
729 case GL_SAMPLER_2D_ARRAY_SHADOW:
730 case GL_SAMPLER_CUBE_SHADOW:
731 case GL_IMAGE_2D:
732 case GL_INT_IMAGE_2D:
733 case GL_UNSIGNED_INT_IMAGE_2D:
734 case GL_IMAGE_3D:
735 case GL_INT_IMAGE_3D:
736 case GL_UNSIGNED_INT_IMAGE_3D:
737 case GL_IMAGE_2D_ARRAY:
738 case GL_INT_IMAGE_2D_ARRAY:
739 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
740 case GL_IMAGE_CUBE:
741 case GL_INT_IMAGE_CUBE:
742 case GL_UNSIGNED_INT_IMAGE_CUBE:
743 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
744 return 6;
745
746 default:
747 UNREACHABLE();
748 return 0;
749 }
750 }
751
ParseResourceName(const std::string & name,std::vector<unsigned int> * outSubscripts)752 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts)
753 {
754 if (outSubscripts)
755 {
756 outSubscripts->clear();
757 }
758 // Strip any trailing array indexing operators and retrieve the subscripts.
759 size_t baseNameLength = name.length();
760 bool hasIndex = true;
761 while (hasIndex)
762 {
763 size_t open = name.find_last_of('[', baseNameLength - 1);
764 size_t close = name.find_last_of(']', baseNameLength - 1);
765 hasIndex = (open != std::string::npos) && (close == baseNameLength - 1);
766 if (hasIndex)
767 {
768 baseNameLength = open;
769 if (outSubscripts)
770 {
771 int index = atoi(name.substr(open + 1).c_str());
772 if (index >= 0)
773 {
774 outSubscripts->push_back(index);
775 }
776 else
777 {
778 outSubscripts->push_back(GL_INVALID_INDEX);
779 }
780 }
781 }
782 }
783
784 return name.substr(0, baseNameLength);
785 }
786
StripLastArrayIndex(const std::string & name)787 std::string StripLastArrayIndex(const std::string &name)
788 {
789 size_t strippedNameLength = name.find_last_of('[');
790 ASSERT(strippedNameLength != std::string::npos && name.back() == ']');
791 return name.substr(0, strippedNameLength);
792 }
793
FindShaderVarField(const sh::ShaderVariable & var,const std::string & fullName,GLuint * fieldIndexOut)794 const sh::ShaderVariable *FindShaderVarField(const sh::ShaderVariable &var,
795 const std::string &fullName,
796 GLuint *fieldIndexOut)
797 {
798 if (var.fields.empty())
799 {
800 return nullptr;
801 }
802 size_t pos = fullName.find_first_of(".");
803 if (pos == std::string::npos)
804 {
805 return nullptr;
806 }
807 std::string topName = fullName.substr(0, pos);
808 if (topName != var.name)
809 {
810 return nullptr;
811 }
812 std::string fieldName = fullName.substr(pos + 1);
813 if (fieldName.empty())
814 {
815 return nullptr;
816 }
817 for (size_t field = 0; field < var.fields.size(); ++field)
818 {
819 if (var.fields[field].name == fieldName)
820 {
821 *fieldIndexOut = static_cast<GLuint>(field);
822 return &var.fields[field];
823 }
824 }
825 return nullptr;
826 }
827
ArraySizeProduct(const std::vector<unsigned int> & arraySizes)828 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
829 {
830 unsigned int arraySizeProduct = 1u;
831 for (unsigned int arraySize : arraySizes)
832 {
833 arraySizeProduct *= arraySize;
834 }
835 return arraySizeProduct;
836 }
837
ParseArrayIndex(const std::string & name,size_t * nameLengthWithoutArrayIndexOut)838 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
839 {
840 ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
841
842 // Strip any trailing array operator and retrieve the subscript
843 size_t open = name.find_last_of('[');
844 if (open != std::string::npos && name.back() == ']')
845 {
846 bool indexIsValidDecimalNumber = true;
847 for (size_t i = open + 1; i < name.length() - 1u; ++i)
848 {
849 if (!isdigit(name[i]))
850 {
851 indexIsValidDecimalNumber = false;
852 break;
853 }
854 }
855 if (indexIsValidDecimalNumber)
856 {
857 errno = 0; // reset global error flag.
858 unsigned long subscript =
859 strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
860
861 // Check if resulting integer is out-of-range or conversion error.
862 if ((subscript <= static_cast<unsigned long>(UINT_MAX)) &&
863 !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
864 {
865 *nameLengthWithoutArrayIndexOut = open;
866 return static_cast<unsigned int>(subscript);
867 }
868 }
869 }
870
871 *nameLengthWithoutArrayIndexOut = name.length();
872 return GL_INVALID_INDEX;
873 }
874
GetGenericErrorMessage(GLenum error)875 const char *GetGenericErrorMessage(GLenum error)
876 {
877 switch (error)
878 {
879 case GL_NO_ERROR:
880 return "";
881 case GL_INVALID_ENUM:
882 return "Invalid enum.";
883 case GL_INVALID_VALUE:
884 return "Invalid value.";
885 case GL_INVALID_OPERATION:
886 return "Invalid operation.";
887 case GL_STACK_OVERFLOW:
888 return "Stack overflow.";
889 case GL_STACK_UNDERFLOW:
890 return "Stack underflow.";
891 case GL_OUT_OF_MEMORY:
892 return "Out of memory.";
893 case GL_INVALID_FRAMEBUFFER_OPERATION:
894 return "Invalid framebuffer operation.";
895 default:
896 UNREACHABLE();
897 return "Unknown error.";
898 }
899 }
900
ElementTypeSize(GLenum elementType)901 unsigned int ElementTypeSize(GLenum elementType)
902 {
903 switch (elementType)
904 {
905 case GL_UNSIGNED_BYTE:
906 return sizeof(GLubyte);
907 case GL_UNSIGNED_SHORT:
908 return sizeof(GLushort);
909 case GL_UNSIGNED_INT:
910 return sizeof(GLuint);
911 default:
912 UNREACHABLE();
913 return 0;
914 }
915 }
916
GetPipelineType(ShaderType type)917 PipelineType GetPipelineType(ShaderType type)
918 {
919 switch (type)
920 {
921 case ShaderType::Vertex:
922 case ShaderType::Fragment:
923 case ShaderType::Geometry:
924 return PipelineType::GraphicsPipeline;
925 case ShaderType::Compute:
926 return PipelineType::ComputePipeline;
927 default:
928 UNREACHABLE();
929 return PipelineType::GraphicsPipeline;
930 }
931 }
932
933 } // namespace gl
934
935 namespace egl
936 {
937 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
938 "Unexpected EGL cube map enum value.");
939 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
940 "Unexpected EGL cube map enum value.");
941 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
942 "Unexpected EGL cube map enum value.");
943 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
944 "Unexpected EGL cube map enum value.");
945 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
946 "Unexpected EGL cube map enum value.");
947
IsCubeMapTextureTarget(EGLenum target)948 bool IsCubeMapTextureTarget(EGLenum target)
949 {
950 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
951 }
952
CubeMapTextureTargetToLayerIndex(EGLenum target)953 size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
954 {
955 ASSERT(IsCubeMapTextureTarget(target));
956 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
957 }
958
LayerIndexToCubeMapTextureTarget(size_t index)959 EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
960 {
961 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
962 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
963 }
964
IsTextureTarget(EGLenum target)965 bool IsTextureTarget(EGLenum target)
966 {
967 switch (target)
968 {
969 case EGL_GL_TEXTURE_2D_KHR:
970 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
971 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
972 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
973 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
974 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
975 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
976 case EGL_GL_TEXTURE_3D_KHR:
977 return true;
978
979 default:
980 return false;
981 }
982 }
983
IsRenderbufferTarget(EGLenum target)984 bool IsRenderbufferTarget(EGLenum target)
985 {
986 return target == EGL_GL_RENDERBUFFER_KHR;
987 }
988
IsExternalImageTarget(EGLenum target)989 bool IsExternalImageTarget(EGLenum target)
990 {
991 switch (target)
992 {
993 case EGL_NATIVE_BUFFER_ANDROID:
994 case EGL_D3D11_TEXTURE_ANGLE:
995 return true;
996
997 default:
998 return false;
999 }
1000 }
1001
GetGenericErrorMessage(EGLint error)1002 const char *GetGenericErrorMessage(EGLint error)
1003 {
1004 switch (error)
1005 {
1006 case EGL_SUCCESS:
1007 return "";
1008 case EGL_NOT_INITIALIZED:
1009 return "Not initialized.";
1010 case EGL_BAD_ACCESS:
1011 return "Bad access.";
1012 case EGL_BAD_ALLOC:
1013 return "Bad allocation.";
1014 case EGL_BAD_ATTRIBUTE:
1015 return "Bad attribute.";
1016 case EGL_BAD_CONFIG:
1017 return "Bad config.";
1018 case EGL_BAD_CONTEXT:
1019 return "Bad context.";
1020 case EGL_BAD_CURRENT_SURFACE:
1021 return "Bad current surface.";
1022 case EGL_BAD_DISPLAY:
1023 return "Bad display.";
1024 case EGL_BAD_MATCH:
1025 return "Bad match.";
1026 case EGL_BAD_NATIVE_WINDOW:
1027 return "Bad native window.";
1028 case EGL_BAD_PARAMETER:
1029 return "Bad parameter.";
1030 case EGL_BAD_SURFACE:
1031 return "Bad surface.";
1032 case EGL_CONTEXT_LOST:
1033 return "Context lost.";
1034 case EGL_BAD_STREAM_KHR:
1035 return "Bad stream.";
1036 case EGL_BAD_STATE_KHR:
1037 return "Bad state.";
1038 case EGL_BAD_DEVICE_EXT:
1039 return "Bad device.";
1040 default:
1041 UNREACHABLE();
1042 return "Unknown error.";
1043 }
1044 }
1045
1046 } // namespace egl
1047
1048 namespace egl_gl
1049 {
EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)1050 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
1051 {
1052 return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
1053 }
1054 } // namespace egl_gl
1055
1056 namespace gl_egl
1057 {
GLComponentTypeToEGLColorComponentType(GLenum glComponentType)1058 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
1059 {
1060 switch (glComponentType)
1061 {
1062 case GL_FLOAT:
1063 return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
1064
1065 case GL_UNSIGNED_NORMALIZED:
1066 return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
1067
1068 default:
1069 UNREACHABLE();
1070 return EGL_NONE;
1071 }
1072 }
1073
GLObjectHandleToEGLClientBuffer(GLuint handle)1074 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
1075 {
1076 return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
1077 }
1078
1079 } // namespace gl_egl
1080
1081 #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
getTempPath()1082 std::string getTempPath()
1083 {
1084 # ifdef ANGLE_PLATFORM_WINDOWS
1085 char path[MAX_PATH];
1086 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
1087 if (pathLen == 0)
1088 {
1089 UNREACHABLE();
1090 return std::string();
1091 }
1092
1093 UINT unique = GetTempFileNameA(path, "sh", 0, path);
1094 if (unique == 0)
1095 {
1096 UNREACHABLE();
1097 return std::string();
1098 }
1099
1100 return path;
1101 # else
1102 UNIMPLEMENTED();
1103 return "";
1104 # endif
1105 }
1106
writeFile(const char * path,const void * content,size_t size)1107 void writeFile(const char *path, const void *content, size_t size)
1108 {
1109 FILE *file = fopen(path, "w");
1110 if (!file)
1111 {
1112 UNREACHABLE();
1113 return;
1114 }
1115
1116 fwrite(content, sizeof(char), size, file);
1117 fclose(file);
1118 }
1119 #endif // !ANGLE_ENABLE_WINDOWS_STORE
1120
1121 #if defined(ANGLE_PLATFORM_WINDOWS)
1122
1123 // Causes the thread to relinquish the remainder of its time slice to any
1124 // other thread that is ready to run.If there are no other threads ready
1125 // to run, the function returns immediately, and the thread continues execution.
ScheduleYield()1126 void ScheduleYield()
1127 {
1128 Sleep(0);
1129 }
1130
1131 #endif
1132