Line data Source code
1 : //
2 : // Copyright (c) 2002-2013 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 "common/mathutil.h"
11 : #include "common/platform.h"
12 :
13 : #include <set>
14 :
15 : #if defined(ANGLE_ENABLE_WINDOWS_STORE)
16 : # include <wrl.h>
17 : # include <wrl/wrappers/corewrappers.h>
18 : # include <windows.applicationmodel.core.h>
19 : # include <windows.graphics.display.h>
20 : #endif
21 :
22 : namespace
23 : {
24 :
25 : template <class IndexType>
26 0 : gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
27 : size_t count,
28 : bool primitiveRestartEnabled,
29 : GLuint primitiveRestartIndex)
30 : {
31 0 : ASSERT(count > 0);
32 :
33 0 : IndexType minIndex = 0;
34 0 : IndexType maxIndex = 0;
35 0 : size_t nonPrimitiveRestartIndices = 0;
36 :
37 0 : if (primitiveRestartEnabled)
38 : {
39 : // Find the first non-primitive restart index to initialize the min and max values
40 0 : size_t i = 0;
41 0 : for (; i < count; i++)
42 : {
43 0 : if (indices[i] != primitiveRestartIndex)
44 : {
45 0 : minIndex = indices[i];
46 0 : maxIndex = indices[i];
47 0 : nonPrimitiveRestartIndices++;
48 0 : break;
49 : }
50 : }
51 :
52 : // Loop over the rest of the indices
53 0 : for (; i < count; i++)
54 : {
55 0 : if (indices[i] != primitiveRestartIndex)
56 : {
57 0 : if (minIndex > indices[i])
58 : {
59 0 : minIndex = indices[i];
60 : }
61 0 : if (maxIndex < indices[i])
62 : {
63 0 : maxIndex = indices[i];
64 : }
65 0 : nonPrimitiveRestartIndices++;
66 : }
67 : }
68 : }
69 : else
70 : {
71 0 : minIndex = indices[0];
72 0 : maxIndex = indices[0];
73 0 : nonPrimitiveRestartIndices = count;
74 :
75 0 : for (size_t i = 1; i < count; i++)
76 : {
77 0 : if (minIndex > indices[i])
78 : {
79 0 : minIndex = indices[i];
80 : }
81 0 : if (maxIndex < indices[i])
82 : {
83 0 : maxIndex = indices[i];
84 : }
85 : }
86 : }
87 :
88 : return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
89 0 : nonPrimitiveRestartIndices);
90 : }
91 :
92 : } // anonymous namespace
93 :
94 : namespace gl
95 : {
96 :
97 0 : int VariableComponentCount(GLenum type)
98 : {
99 0 : return VariableRowCount(type) * VariableColumnCount(type);
100 : }
101 :
102 0 : GLenum VariableComponentType(GLenum type)
103 : {
104 0 : switch(type)
105 : {
106 : case GL_BOOL:
107 : case GL_BOOL_VEC2:
108 : case GL_BOOL_VEC3:
109 : case GL_BOOL_VEC4:
110 0 : return GL_BOOL;
111 : case GL_FLOAT:
112 : case GL_FLOAT_VEC2:
113 : case GL_FLOAT_VEC3:
114 : case GL_FLOAT_VEC4:
115 : case GL_FLOAT_MAT2:
116 : case GL_FLOAT_MAT3:
117 : case GL_FLOAT_MAT4:
118 : case GL_FLOAT_MAT2x3:
119 : case GL_FLOAT_MAT3x2:
120 : case GL_FLOAT_MAT2x4:
121 : case GL_FLOAT_MAT4x2:
122 : case GL_FLOAT_MAT3x4:
123 : case GL_FLOAT_MAT4x3:
124 0 : return GL_FLOAT;
125 : case GL_INT:
126 : case GL_SAMPLER_2D:
127 : case GL_SAMPLER_3D:
128 : case GL_SAMPLER_CUBE:
129 : case GL_SAMPLER_2D_ARRAY:
130 : case GL_SAMPLER_EXTERNAL_OES:
131 : case GL_INT_SAMPLER_2D:
132 : case GL_INT_SAMPLER_3D:
133 : case GL_INT_SAMPLER_CUBE:
134 : case GL_INT_SAMPLER_2D_ARRAY:
135 : case GL_UNSIGNED_INT_SAMPLER_2D:
136 : case GL_UNSIGNED_INT_SAMPLER_3D:
137 : case GL_UNSIGNED_INT_SAMPLER_CUBE:
138 : case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
139 : case GL_SAMPLER_2D_SHADOW:
140 : case GL_SAMPLER_CUBE_SHADOW:
141 : case GL_SAMPLER_2D_ARRAY_SHADOW:
142 : case GL_INT_VEC2:
143 : case GL_INT_VEC3:
144 : case GL_INT_VEC4:
145 0 : return GL_INT;
146 : case GL_UNSIGNED_INT:
147 : case GL_UNSIGNED_INT_VEC2:
148 : case GL_UNSIGNED_INT_VEC3:
149 : case GL_UNSIGNED_INT_VEC4:
150 0 : return GL_UNSIGNED_INT;
151 : default:
152 0 : UNREACHABLE();
153 : }
154 :
155 : return GL_NONE;
156 : }
157 :
158 0 : size_t VariableComponentSize(GLenum type)
159 : {
160 0 : switch(type)
161 : {
162 0 : case GL_BOOL: return sizeof(GLint);
163 0 : case GL_FLOAT: return sizeof(GLfloat);
164 0 : case GL_INT: return sizeof(GLint);
165 0 : case GL_UNSIGNED_INT: return sizeof(GLuint);
166 0 : default: UNREACHABLE();
167 : }
168 :
169 : return 0;
170 : }
171 :
172 0 : size_t VariableInternalSize(GLenum type)
173 : {
174 : // Expanded to 4-element vectors
175 0 : return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
176 : }
177 :
178 0 : size_t VariableExternalSize(GLenum type)
179 : {
180 0 : return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
181 : }
182 :
183 0 : GLenum VariableBoolVectorType(GLenum type)
184 : {
185 0 : switch (type)
186 : {
187 : case GL_FLOAT:
188 : case GL_INT:
189 : case GL_UNSIGNED_INT:
190 0 : return GL_BOOL;
191 : case GL_FLOAT_VEC2:
192 : case GL_INT_VEC2:
193 : case GL_UNSIGNED_INT_VEC2:
194 0 : return GL_BOOL_VEC2;
195 : case GL_FLOAT_VEC3:
196 : case GL_INT_VEC3:
197 : case GL_UNSIGNED_INT_VEC3:
198 0 : return GL_BOOL_VEC3;
199 : case GL_FLOAT_VEC4:
200 : case GL_INT_VEC4:
201 : case GL_UNSIGNED_INT_VEC4:
202 0 : return GL_BOOL_VEC4;
203 :
204 : default:
205 0 : UNREACHABLE();
206 : return GL_NONE;
207 : }
208 : }
209 :
210 0 : int VariableRowCount(GLenum type)
211 : {
212 0 : switch (type)
213 : {
214 : case GL_NONE:
215 : case GL_STRUCT_ANGLEX:
216 0 : return 0;
217 : case GL_BOOL:
218 : case GL_FLOAT:
219 : case GL_INT:
220 : case GL_UNSIGNED_INT:
221 : case GL_BOOL_VEC2:
222 : case GL_FLOAT_VEC2:
223 : case GL_INT_VEC2:
224 : case GL_UNSIGNED_INT_VEC2:
225 : case GL_BOOL_VEC3:
226 : case GL_FLOAT_VEC3:
227 : case GL_INT_VEC3:
228 : case GL_UNSIGNED_INT_VEC3:
229 : case GL_BOOL_VEC4:
230 : case GL_FLOAT_VEC4:
231 : case GL_INT_VEC4:
232 : case GL_UNSIGNED_INT_VEC4:
233 : case GL_SAMPLER_2D:
234 : case GL_SAMPLER_3D:
235 : case GL_SAMPLER_CUBE:
236 : case GL_SAMPLER_2D_ARRAY:
237 : case GL_SAMPLER_EXTERNAL_OES:
238 : case GL_SAMPLER_2D_RECT_ARB:
239 : case GL_INT_SAMPLER_2D:
240 : case GL_INT_SAMPLER_3D:
241 : case GL_INT_SAMPLER_CUBE:
242 : case GL_INT_SAMPLER_2D_ARRAY:
243 : case GL_UNSIGNED_INT_SAMPLER_2D:
244 : case GL_UNSIGNED_INT_SAMPLER_3D:
245 : case GL_UNSIGNED_INT_SAMPLER_CUBE:
246 : case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
247 : case GL_SAMPLER_2D_SHADOW:
248 : case GL_SAMPLER_CUBE_SHADOW:
249 : case GL_SAMPLER_2D_ARRAY_SHADOW:
250 : case GL_IMAGE_2D:
251 : case GL_INT_IMAGE_2D:
252 : case GL_UNSIGNED_INT_IMAGE_2D:
253 : case GL_IMAGE_2D_ARRAY:
254 : case GL_INT_IMAGE_2D_ARRAY:
255 : case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
256 : case GL_IMAGE_3D:
257 : case GL_INT_IMAGE_3D:
258 : case GL_UNSIGNED_INT_IMAGE_3D:
259 : case GL_IMAGE_CUBE:
260 : case GL_INT_IMAGE_CUBE:
261 : case GL_UNSIGNED_INT_IMAGE_CUBE:
262 0 : return 1;
263 : case GL_FLOAT_MAT2:
264 : case GL_FLOAT_MAT3x2:
265 : case GL_FLOAT_MAT4x2:
266 0 : return 2;
267 : case GL_FLOAT_MAT3:
268 : case GL_FLOAT_MAT2x3:
269 : case GL_FLOAT_MAT4x3:
270 0 : return 3;
271 : case GL_FLOAT_MAT4:
272 : case GL_FLOAT_MAT2x4:
273 : case GL_FLOAT_MAT3x4:
274 0 : return 4;
275 : default:
276 0 : UNREACHABLE();
277 : }
278 :
279 : return 0;
280 : }
281 :
282 0 : int VariableColumnCount(GLenum type)
283 : {
284 0 : switch (type)
285 : {
286 : case GL_NONE:
287 : case GL_STRUCT_ANGLEX:
288 0 : return 0;
289 : case GL_BOOL:
290 : case GL_FLOAT:
291 : case GL_INT:
292 : case GL_UNSIGNED_INT:
293 : case GL_SAMPLER_2D:
294 : case GL_SAMPLER_3D:
295 : case GL_SAMPLER_CUBE:
296 : case GL_SAMPLER_2D_ARRAY:
297 : case GL_INT_SAMPLER_2D:
298 : case GL_INT_SAMPLER_3D:
299 : case GL_INT_SAMPLER_CUBE:
300 : case GL_INT_SAMPLER_2D_ARRAY:
301 : case GL_SAMPLER_EXTERNAL_OES:
302 : case GL_SAMPLER_2D_RECT_ARB:
303 : case GL_UNSIGNED_INT_SAMPLER_2D:
304 : case GL_UNSIGNED_INT_SAMPLER_3D:
305 : case GL_UNSIGNED_INT_SAMPLER_CUBE:
306 : case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
307 : case GL_SAMPLER_2D_SHADOW:
308 : case GL_SAMPLER_CUBE_SHADOW:
309 : case GL_SAMPLER_2D_ARRAY_SHADOW:
310 0 : return 1;
311 : case GL_BOOL_VEC2:
312 : case GL_FLOAT_VEC2:
313 : case GL_INT_VEC2:
314 : case GL_UNSIGNED_INT_VEC2:
315 : case GL_FLOAT_MAT2:
316 : case GL_FLOAT_MAT2x3:
317 : case GL_FLOAT_MAT2x4:
318 0 : return 2;
319 : case GL_BOOL_VEC3:
320 : case GL_FLOAT_VEC3:
321 : case GL_INT_VEC3:
322 : case GL_UNSIGNED_INT_VEC3:
323 : case GL_FLOAT_MAT3:
324 : case GL_FLOAT_MAT3x2:
325 : case GL_FLOAT_MAT3x4:
326 0 : return 3;
327 : case GL_BOOL_VEC4:
328 : case GL_FLOAT_VEC4:
329 : case GL_INT_VEC4:
330 : case GL_UNSIGNED_INT_VEC4:
331 : case GL_FLOAT_MAT4:
332 : case GL_FLOAT_MAT4x2:
333 : case GL_FLOAT_MAT4x3:
334 0 : return 4;
335 : default:
336 0 : UNREACHABLE();
337 : }
338 :
339 : return 0;
340 : }
341 :
342 0 : bool IsSamplerType(GLenum type)
343 : {
344 0 : switch (type)
345 : {
346 : case GL_SAMPLER_2D:
347 : case GL_SAMPLER_3D:
348 : case GL_SAMPLER_CUBE:
349 : case GL_SAMPLER_2D_ARRAY:
350 : case GL_SAMPLER_EXTERNAL_OES:
351 : case GL_INT_SAMPLER_2D:
352 : case GL_INT_SAMPLER_3D:
353 : case GL_INT_SAMPLER_CUBE:
354 : case GL_INT_SAMPLER_2D_ARRAY:
355 : case GL_UNSIGNED_INT_SAMPLER_2D:
356 : case GL_UNSIGNED_INT_SAMPLER_3D:
357 : case GL_UNSIGNED_INT_SAMPLER_CUBE:
358 : case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
359 : case GL_SAMPLER_2D_SHADOW:
360 : case GL_SAMPLER_CUBE_SHADOW:
361 : case GL_SAMPLER_2D_ARRAY_SHADOW:
362 0 : return true;
363 : }
364 :
365 0 : return false;
366 : }
367 :
368 0 : GLenum SamplerTypeToTextureType(GLenum samplerType)
369 : {
370 0 : switch (samplerType)
371 : {
372 : case GL_SAMPLER_2D:
373 : case GL_INT_SAMPLER_2D:
374 : case GL_UNSIGNED_INT_SAMPLER_2D:
375 : case GL_SAMPLER_2D_SHADOW:
376 0 : return GL_TEXTURE_2D;
377 :
378 : case GL_SAMPLER_EXTERNAL_OES:
379 0 : return GL_TEXTURE_EXTERNAL_OES;
380 :
381 : case GL_SAMPLER_CUBE:
382 : case GL_INT_SAMPLER_CUBE:
383 : case GL_UNSIGNED_INT_SAMPLER_CUBE:
384 : case GL_SAMPLER_CUBE_SHADOW:
385 0 : return GL_TEXTURE_CUBE_MAP;
386 :
387 : case GL_SAMPLER_2D_ARRAY:
388 : case GL_INT_SAMPLER_2D_ARRAY:
389 : case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
390 : case GL_SAMPLER_2D_ARRAY_SHADOW:
391 0 : return GL_TEXTURE_2D_ARRAY;
392 :
393 : case GL_SAMPLER_3D:
394 : case GL_INT_SAMPLER_3D:
395 : case GL_UNSIGNED_INT_SAMPLER_3D:
396 0 : return GL_TEXTURE_3D;
397 :
398 : default:
399 0 : UNREACHABLE();
400 : return 0;
401 : }
402 : }
403 :
404 0 : bool IsMatrixType(GLenum type)
405 : {
406 0 : return VariableRowCount(type) > 1;
407 : }
408 :
409 0 : GLenum TransposeMatrixType(GLenum type)
410 : {
411 0 : if (!IsMatrixType(type))
412 : {
413 0 : return type;
414 : }
415 :
416 0 : switch (type)
417 : {
418 0 : case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
419 0 : case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
420 0 : case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
421 0 : case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
422 0 : case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
423 0 : case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
424 0 : case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
425 0 : case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
426 0 : case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
427 0 : default: UNREACHABLE(); return GL_NONE;
428 : }
429 : }
430 :
431 0 : int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
432 : {
433 0 : ASSERT(IsMatrixType(type));
434 0 : return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
435 : }
436 :
437 0 : int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
438 : {
439 0 : ASSERT(IsMatrixType(type));
440 0 : return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
441 : }
442 :
443 0 : int VariableRegisterCount(GLenum type)
444 : {
445 0 : return IsMatrixType(type) ? VariableColumnCount(type) : 1;
446 : }
447 :
448 0 : int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
449 : {
450 0 : ASSERT(allocationSize <= bitsSize);
451 :
452 0 : unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
453 :
454 0 : for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
455 : {
456 0 : if ((*bits & mask) == 0)
457 : {
458 0 : *bits |= mask;
459 0 : return i;
460 : }
461 :
462 0 : mask <<= 1;
463 : }
464 :
465 0 : return -1;
466 : }
467 :
468 : static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
469 : static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
470 : static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
471 : static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
472 : static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
473 :
474 0 : bool IsCubeMapTextureTarget(GLenum target)
475 : {
476 0 : return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
477 : }
478 :
479 0 : size_t CubeMapTextureTargetToLayerIndex(GLenum target)
480 : {
481 0 : ASSERT(IsCubeMapTextureTarget(target));
482 0 : return target - static_cast<size_t>(FirstCubeMapTextureTarget);
483 : }
484 :
485 0 : GLenum LayerIndexToCubeMapTextureTarget(size_t index)
486 : {
487 0 : ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
488 0 : return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
489 : }
490 :
491 0 : IndexRange ComputeIndexRange(GLenum indexType,
492 : const GLvoid *indices,
493 : size_t count,
494 : bool primitiveRestartEnabled)
495 : {
496 0 : switch (indexType)
497 : {
498 : case GL_UNSIGNED_BYTE:
499 : return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
500 : primitiveRestartEnabled,
501 0 : GetPrimitiveRestartIndex(indexType));
502 : case GL_UNSIGNED_SHORT:
503 : return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
504 : primitiveRestartEnabled,
505 0 : GetPrimitiveRestartIndex(indexType));
506 : case GL_UNSIGNED_INT:
507 : return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
508 : primitiveRestartEnabled,
509 0 : GetPrimitiveRestartIndex(indexType));
510 : default:
511 0 : UNREACHABLE();
512 : return IndexRange();
513 : }
514 : }
515 :
516 0 : GLuint GetPrimitiveRestartIndex(GLenum indexType)
517 : {
518 0 : switch (indexType)
519 : {
520 : case GL_UNSIGNED_BYTE:
521 0 : return 0xFF;
522 : case GL_UNSIGNED_SHORT:
523 0 : return 0xFFFF;
524 : case GL_UNSIGNED_INT:
525 0 : return 0xFFFFFFFF;
526 : default:
527 0 : UNREACHABLE();
528 : return 0;
529 : }
530 : }
531 :
532 0 : bool IsTriangleMode(GLenum drawMode)
533 : {
534 0 : switch (drawMode)
535 : {
536 : case GL_TRIANGLES:
537 : case GL_TRIANGLE_FAN:
538 : case GL_TRIANGLE_STRIP:
539 0 : return true;
540 : case GL_POINTS:
541 : case GL_LINES:
542 : case GL_LINE_LOOP:
543 : case GL_LINE_STRIP:
544 0 : return false;
545 0 : default: UNREACHABLE();
546 : }
547 :
548 : return false;
549 : }
550 :
551 : // [OpenGL ES SL 3.00.4] Section 11 p. 120
552 : // Vertex Outs/Fragment Ins packing priorities
553 0 : int VariableSortOrder(GLenum type)
554 : {
555 0 : switch (type)
556 : {
557 : // 1. Arrays of mat4 and mat4
558 : // Non-square matrices of type matCxR consume the same space as a square
559 : // matrix of type matN where N is the greater of C and R
560 : case GL_FLOAT_MAT4:
561 : case GL_FLOAT_MAT2x4:
562 : case GL_FLOAT_MAT3x4:
563 : case GL_FLOAT_MAT4x2:
564 : case GL_FLOAT_MAT4x3:
565 0 : return 0;
566 :
567 : // 2. Arrays of mat2 and mat2 (since they occupy full rows)
568 : case GL_FLOAT_MAT2:
569 0 : return 1;
570 :
571 : // 3. Arrays of vec4 and vec4
572 : case GL_FLOAT_VEC4:
573 : case GL_INT_VEC4:
574 : case GL_BOOL_VEC4:
575 : case GL_UNSIGNED_INT_VEC4:
576 0 : return 2;
577 :
578 : // 4. Arrays of mat3 and mat3
579 : case GL_FLOAT_MAT3:
580 : case GL_FLOAT_MAT2x3:
581 : case GL_FLOAT_MAT3x2:
582 0 : return 3;
583 :
584 : // 5. Arrays of vec3 and vec3
585 : case GL_FLOAT_VEC3:
586 : case GL_INT_VEC3:
587 : case GL_BOOL_VEC3:
588 : case GL_UNSIGNED_INT_VEC3:
589 0 : return 4;
590 :
591 : // 6. Arrays of vec2 and vec2
592 : case GL_FLOAT_VEC2:
593 : case GL_INT_VEC2:
594 : case GL_BOOL_VEC2:
595 : case GL_UNSIGNED_INT_VEC2:
596 0 : return 5;
597 :
598 : // 7. Single component types
599 : case GL_FLOAT:
600 : case GL_INT:
601 : case GL_BOOL:
602 : case GL_UNSIGNED_INT:
603 : case GL_SAMPLER_2D:
604 : case GL_SAMPLER_CUBE:
605 : case GL_SAMPLER_EXTERNAL_OES:
606 : case GL_SAMPLER_2D_RECT_ARB:
607 : case GL_SAMPLER_2D_ARRAY:
608 : case GL_SAMPLER_3D:
609 : case GL_INT_SAMPLER_2D:
610 : case GL_INT_SAMPLER_3D:
611 : case GL_INT_SAMPLER_CUBE:
612 : case GL_INT_SAMPLER_2D_ARRAY:
613 : case GL_UNSIGNED_INT_SAMPLER_2D:
614 : case GL_UNSIGNED_INT_SAMPLER_3D:
615 : case GL_UNSIGNED_INT_SAMPLER_CUBE:
616 : case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
617 : case GL_SAMPLER_2D_SHADOW:
618 : case GL_SAMPLER_2D_ARRAY_SHADOW:
619 : case GL_SAMPLER_CUBE_SHADOW:
620 0 : return 6;
621 :
622 : default:
623 0 : UNREACHABLE();
624 : return 0;
625 : }
626 : }
627 :
628 0 : std::string ParseUniformName(const std::string &name, size_t *outSubscript)
629 : {
630 : // Strip any trailing array operator and retrieve the subscript
631 0 : size_t open = name.find_last_of('[');
632 0 : size_t close = name.find_last_of(']');
633 0 : bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
634 0 : if (!hasIndex)
635 : {
636 0 : if (outSubscript)
637 : {
638 0 : *outSubscript = GL_INVALID_INDEX;
639 : }
640 0 : return name;
641 : }
642 :
643 0 : if (outSubscript)
644 : {
645 0 : int index = atoi(name.substr(open + 1).c_str());
646 0 : if (index >= 0)
647 : {
648 0 : *outSubscript = index;
649 : }
650 : else
651 : {
652 0 : *outSubscript = GL_INVALID_INDEX;
653 : }
654 : }
655 :
656 0 : return name.substr(0, open);
657 : }
658 :
659 : template <>
660 0 : GLuint ConvertToGLuint(GLfloat param)
661 : {
662 0 : return uiround<GLuint>(param);
663 : }
664 :
665 : template <>
666 0 : GLint ConvertToGLint(GLfloat param)
667 : {
668 0 : return iround<GLint>(param);
669 : }
670 :
671 : template <>
672 0 : GLint ConvertFromGLfloat(GLfloat param)
673 : {
674 0 : return iround<GLint>(param);
675 : }
676 : template <>
677 0 : GLuint ConvertFromGLfloat(GLfloat param)
678 : {
679 0 : return uiround<GLuint>(param);
680 : }
681 :
682 0 : unsigned int ParseAndStripArrayIndex(std::string *name)
683 : {
684 0 : unsigned int subscript = GL_INVALID_INDEX;
685 :
686 : // Strip any trailing array operator and retrieve the subscript
687 0 : size_t open = name->find_last_of('[');
688 0 : size_t close = name->find_last_of(']');
689 0 : if (open != std::string::npos && close == name->length() - 1)
690 : {
691 0 : subscript = atoi(name->c_str() + open + 1);
692 0 : name->erase(open);
693 : }
694 :
695 0 : return subscript;
696 : }
697 :
698 : } // namespace gl
699 :
700 : namespace egl
701 : {
702 : static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
703 : "Unexpected EGL cube map enum value.");
704 : static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
705 : "Unexpected EGL cube map enum value.");
706 : static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
707 : "Unexpected EGL cube map enum value.");
708 : static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
709 : "Unexpected EGL cube map enum value.");
710 : static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
711 : "Unexpected EGL cube map enum value.");
712 :
713 0 : bool IsCubeMapTextureTarget(EGLenum target)
714 : {
715 0 : return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
716 : }
717 :
718 0 : size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
719 : {
720 0 : ASSERT(IsCubeMapTextureTarget(target));
721 0 : return target - static_cast<size_t>(FirstCubeMapTextureTarget);
722 : }
723 :
724 0 : EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
725 : {
726 0 : ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
727 0 : return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
728 : }
729 :
730 0 : bool IsTextureTarget(EGLenum target)
731 : {
732 0 : switch (target)
733 : {
734 : case EGL_GL_TEXTURE_2D_KHR:
735 : case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
736 : case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
737 : case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
738 : case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
739 : case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
740 : case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
741 : case EGL_GL_TEXTURE_3D_KHR:
742 0 : return true;
743 :
744 : default:
745 0 : return false;
746 : }
747 : }
748 :
749 0 : bool IsRenderbufferTarget(EGLenum target)
750 : {
751 0 : return target == EGL_GL_RENDERBUFFER_KHR;
752 : }
753 : } // namespace egl
754 :
755 : namespace egl_gl
756 : {
757 0 : GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
758 : {
759 0 : ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
760 0 : return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
761 : }
762 :
763 0 : GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
764 : {
765 0 : switch (eglTarget)
766 : {
767 : case EGL_GL_TEXTURE_2D_KHR:
768 0 : return GL_TEXTURE_2D;
769 :
770 : case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
771 : case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
772 : case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
773 : case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
774 : case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
775 : case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
776 0 : return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
777 :
778 : case EGL_GL_TEXTURE_3D_KHR:
779 0 : return GL_TEXTURE_3D;
780 :
781 : default:
782 0 : UNREACHABLE();
783 : return GL_NONE;
784 : }
785 : }
786 :
787 0 : GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
788 : {
789 0 : return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
790 : }
791 : } // namespace egl_gl
792 :
793 : #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
794 0 : std::string getTempPath()
795 : {
796 : #ifdef ANGLE_PLATFORM_WINDOWS
797 : char path[MAX_PATH];
798 : DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
799 : if (pathLen == 0)
800 : {
801 : UNREACHABLE();
802 : return std::string();
803 : }
804 :
805 : UINT unique = GetTempFileNameA(path, "sh", 0, path);
806 : if (unique == 0)
807 : {
808 : UNREACHABLE();
809 : return std::string();
810 : }
811 :
812 : return path;
813 : #else
814 0 : UNIMPLEMENTED();
815 : return "";
816 : #endif
817 : }
818 :
819 0 : void writeFile(const char* path, const void* content, size_t size)
820 : {
821 0 : FILE* file = fopen(path, "w");
822 0 : if (!file)
823 : {
824 0 : UNREACHABLE();
825 : return;
826 : }
827 :
828 0 : fwrite(content, sizeof(char), size, file);
829 0 : fclose(file);
830 : }
831 : #endif // !ANGLE_ENABLE_WINDOWS_STORE
832 :
833 : #if defined (ANGLE_PLATFORM_WINDOWS)
834 :
835 : // Causes the thread to relinquish the remainder of its time slice to any
836 : // other thread that is ready to run.If there are no other threads ready
837 : // to run, the function returns immediately, and the thread continues execution.
838 : void ScheduleYield()
839 : {
840 : Sleep(0);
841 : }
842 :
843 : #endif
|