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 namespace gl
16 {
17
VariableComponentCount(GLenum type)18 int VariableComponentCount(GLenum type)
19 {
20 return VariableRowCount(type) * VariableColumnCount(type);
21 }
22
VariableComponentType(GLenum type)23 GLenum VariableComponentType(GLenum type)
24 {
25 switch(type)
26 {
27 case GL_BOOL:
28 case GL_BOOL_VEC2:
29 case GL_BOOL_VEC3:
30 case GL_BOOL_VEC4:
31 return GL_BOOL;
32 case GL_FLOAT:
33 case GL_FLOAT_VEC2:
34 case GL_FLOAT_VEC3:
35 case GL_FLOAT_VEC4:
36 case GL_FLOAT_MAT2:
37 case GL_FLOAT_MAT3:
38 case GL_FLOAT_MAT4:
39 case GL_FLOAT_MAT2x3:
40 case GL_FLOAT_MAT3x2:
41 case GL_FLOAT_MAT2x4:
42 case GL_FLOAT_MAT4x2:
43 case GL_FLOAT_MAT3x4:
44 case GL_FLOAT_MAT4x3:
45 return GL_FLOAT;
46 case GL_INT:
47 case GL_SAMPLER_2D:
48 case GL_SAMPLER_3D:
49 case GL_SAMPLER_CUBE:
50 case GL_SAMPLER_2D_ARRAY:
51 case GL_INT_SAMPLER_2D:
52 case GL_INT_SAMPLER_3D:
53 case GL_INT_SAMPLER_CUBE:
54 case GL_INT_SAMPLER_2D_ARRAY:
55 case GL_UNSIGNED_INT_SAMPLER_2D:
56 case GL_UNSIGNED_INT_SAMPLER_3D:
57 case GL_UNSIGNED_INT_SAMPLER_CUBE:
58 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
59 case GL_SAMPLER_2D_SHADOW:
60 case GL_SAMPLER_CUBE_SHADOW:
61 case GL_SAMPLER_2D_ARRAY_SHADOW:
62 case GL_INT_VEC2:
63 case GL_INT_VEC3:
64 case GL_INT_VEC4:
65 return GL_INT;
66 case GL_UNSIGNED_INT:
67 case GL_UNSIGNED_INT_VEC2:
68 case GL_UNSIGNED_INT_VEC3:
69 case GL_UNSIGNED_INT_VEC4:
70 return GL_UNSIGNED_INT;
71 default:
72 UNREACHABLE();
73 }
74
75 return GL_NONE;
76 }
77
VariableComponentSize(GLenum type)78 size_t VariableComponentSize(GLenum type)
79 {
80 switch(type)
81 {
82 case GL_BOOL: return sizeof(GLint);
83 case GL_FLOAT: return sizeof(GLfloat);
84 case GL_INT: return sizeof(GLint);
85 case GL_UNSIGNED_INT: return sizeof(GLuint);
86 default: UNREACHABLE();
87 }
88
89 return 0;
90 }
91
VariableInternalSize(GLenum type)92 size_t VariableInternalSize(GLenum type)
93 {
94 // Expanded to 4-element vectors
95 return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
96 }
97
VariableExternalSize(GLenum type)98 size_t VariableExternalSize(GLenum type)
99 {
100 return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
101 }
102
VariableBoolVectorType(GLenum type)103 GLenum VariableBoolVectorType(GLenum type)
104 {
105 switch (type)
106 {
107 case GL_FLOAT:
108 case GL_INT:
109 case GL_UNSIGNED_INT:
110 return GL_BOOL;
111 case GL_FLOAT_VEC2:
112 case GL_INT_VEC2:
113 case GL_UNSIGNED_INT_VEC2:
114 return GL_BOOL_VEC2;
115 case GL_FLOAT_VEC3:
116 case GL_INT_VEC3:
117 case GL_UNSIGNED_INT_VEC3:
118 return GL_BOOL_VEC3;
119 case GL_FLOAT_VEC4:
120 case GL_INT_VEC4:
121 case GL_UNSIGNED_INT_VEC4:
122 return GL_BOOL_VEC4;
123
124 default:
125 UNREACHABLE();
126 return GL_NONE;
127 }
128 }
129
VariableRowCount(GLenum type)130 int VariableRowCount(GLenum type)
131 {
132 switch (type)
133 {
134 case GL_NONE:
135 case GL_STRUCT_ANGLEX:
136 return 0;
137 case GL_BOOL:
138 case GL_FLOAT:
139 case GL_INT:
140 case GL_UNSIGNED_INT:
141 case GL_BOOL_VEC2:
142 case GL_FLOAT_VEC2:
143 case GL_INT_VEC2:
144 case GL_UNSIGNED_INT_VEC2:
145 case GL_BOOL_VEC3:
146 case GL_FLOAT_VEC3:
147 case GL_INT_VEC3:
148 case GL_UNSIGNED_INT_VEC3:
149 case GL_BOOL_VEC4:
150 case GL_FLOAT_VEC4:
151 case GL_INT_VEC4:
152 case GL_UNSIGNED_INT_VEC4:
153 case GL_SAMPLER_2D:
154 case GL_SAMPLER_3D:
155 case GL_SAMPLER_CUBE:
156 case GL_SAMPLER_2D_ARRAY:
157 case GL_SAMPLER_EXTERNAL_OES:
158 case GL_SAMPLER_2D_RECT_ARB:
159 case GL_INT_SAMPLER_2D:
160 case GL_INT_SAMPLER_3D:
161 case GL_INT_SAMPLER_CUBE:
162 case GL_INT_SAMPLER_2D_ARRAY:
163 case GL_UNSIGNED_INT_SAMPLER_2D:
164 case GL_UNSIGNED_INT_SAMPLER_3D:
165 case GL_UNSIGNED_INT_SAMPLER_CUBE:
166 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
167 case GL_SAMPLER_2D_SHADOW:
168 case GL_SAMPLER_CUBE_SHADOW:
169 case GL_SAMPLER_2D_ARRAY_SHADOW:
170 return 1;
171 case GL_FLOAT_MAT2:
172 case GL_FLOAT_MAT3x2:
173 case GL_FLOAT_MAT4x2:
174 return 2;
175 case GL_FLOAT_MAT3:
176 case GL_FLOAT_MAT2x3:
177 case GL_FLOAT_MAT4x3:
178 return 3;
179 case GL_FLOAT_MAT4:
180 case GL_FLOAT_MAT2x4:
181 case GL_FLOAT_MAT3x4:
182 return 4;
183 default:
184 UNREACHABLE();
185 }
186
187 return 0;
188 }
189
VariableColumnCount(GLenum type)190 int VariableColumnCount(GLenum type)
191 {
192 switch (type)
193 {
194 case GL_NONE:
195 case GL_STRUCT_ANGLEX:
196 return 0;
197 case GL_BOOL:
198 case GL_FLOAT:
199 case GL_INT:
200 case GL_UNSIGNED_INT:
201 case GL_SAMPLER_2D:
202 case GL_SAMPLER_3D:
203 case GL_SAMPLER_CUBE:
204 case GL_SAMPLER_2D_ARRAY:
205 case GL_INT_SAMPLER_2D:
206 case GL_INT_SAMPLER_3D:
207 case GL_INT_SAMPLER_CUBE:
208 case GL_INT_SAMPLER_2D_ARRAY:
209 case GL_SAMPLER_EXTERNAL_OES:
210 case GL_SAMPLER_2D_RECT_ARB:
211 case GL_UNSIGNED_INT_SAMPLER_2D:
212 case GL_UNSIGNED_INT_SAMPLER_3D:
213 case GL_UNSIGNED_INT_SAMPLER_CUBE:
214 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
215 case GL_SAMPLER_2D_SHADOW:
216 case GL_SAMPLER_CUBE_SHADOW:
217 case GL_SAMPLER_2D_ARRAY_SHADOW:
218 return 1;
219 case GL_BOOL_VEC2:
220 case GL_FLOAT_VEC2:
221 case GL_INT_VEC2:
222 case GL_UNSIGNED_INT_VEC2:
223 case GL_FLOAT_MAT2:
224 case GL_FLOAT_MAT2x3:
225 case GL_FLOAT_MAT2x4:
226 return 2;
227 case GL_BOOL_VEC3:
228 case GL_FLOAT_VEC3:
229 case GL_INT_VEC3:
230 case GL_UNSIGNED_INT_VEC3:
231 case GL_FLOAT_MAT3:
232 case GL_FLOAT_MAT3x2:
233 case GL_FLOAT_MAT3x4:
234 return 3;
235 case GL_BOOL_VEC4:
236 case GL_FLOAT_VEC4:
237 case GL_INT_VEC4:
238 case GL_UNSIGNED_INT_VEC4:
239 case GL_FLOAT_MAT4:
240 case GL_FLOAT_MAT4x2:
241 case GL_FLOAT_MAT4x3:
242 return 4;
243 default:
244 UNREACHABLE();
245 }
246
247 return 0;
248 }
249
IsSampler(GLenum type)250 bool IsSampler(GLenum type)
251 {
252 switch (type)
253 {
254 case GL_SAMPLER_2D:
255 case GL_SAMPLER_3D:
256 case GL_SAMPLER_CUBE:
257 case GL_SAMPLER_2D_ARRAY:
258 case GL_INT_SAMPLER_2D:
259 case GL_INT_SAMPLER_3D:
260 case GL_INT_SAMPLER_CUBE:
261 case GL_INT_SAMPLER_2D_ARRAY:
262 case GL_UNSIGNED_INT_SAMPLER_2D:
263 case GL_UNSIGNED_INT_SAMPLER_3D:
264 case GL_UNSIGNED_INT_SAMPLER_CUBE:
265 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
266 case GL_SAMPLER_2D_SHADOW:
267 case GL_SAMPLER_CUBE_SHADOW:
268 case GL_SAMPLER_2D_ARRAY_SHADOW:
269 return true;
270 }
271
272 return false;
273 }
274
IsMatrixType(GLenum type)275 bool IsMatrixType(GLenum type)
276 {
277 return VariableRowCount(type) > 1;
278 }
279
TransposeMatrixType(GLenum type)280 GLenum TransposeMatrixType(GLenum type)
281 {
282 if (!IsMatrixType(type))
283 {
284 return type;
285 }
286
287 switch (type)
288 {
289 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
290 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
291 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
292 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
293 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
294 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
295 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
296 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
297 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
298 default: UNREACHABLE(); return GL_NONE;
299 }
300 }
301
MatrixRegisterCount(GLenum type,bool isRowMajorMatrix)302 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
303 {
304 ASSERT(IsMatrixType(type));
305 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
306 }
307
MatrixComponentCount(GLenum type,bool isRowMajorMatrix)308 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
309 {
310 ASSERT(IsMatrixType(type));
311 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
312 }
313
VariableRegisterCount(GLenum type)314 int VariableRegisterCount(GLenum type)
315 {
316 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
317 }
318
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)319 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
320 {
321 ASSERT(allocationSize <= bitsSize);
322
323 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
324
325 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
326 {
327 if ((*bits & mask) == 0)
328 {
329 *bits |= mask;
330 return i;
331 }
332
333 mask <<= 1;
334 }
335
336 return -1;
337 }
338
IsCubemapTextureTarget(GLenum target)339 bool IsCubemapTextureTarget(GLenum target)
340 {
341 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
342 }
343
IsTriangleMode(GLenum drawMode)344 bool IsTriangleMode(GLenum drawMode)
345 {
346 switch (drawMode)
347 {
348 case GL_TRIANGLES:
349 case GL_TRIANGLE_FAN:
350 case GL_TRIANGLE_STRIP:
351 return true;
352 case GL_POINTS:
353 case GL_LINES:
354 case GL_LINE_LOOP:
355 case GL_LINE_STRIP:
356 return false;
357 default: UNREACHABLE();
358 }
359
360 return false;
361 }
362
363 // [OpenGL ES SL 3.00.4] Section 11 p. 120
364 // Vertex Outs/Fragment Ins packing priorities
VariableSortOrder(GLenum type)365 int VariableSortOrder(GLenum type)
366 {
367 switch (type)
368 {
369 // 1. Arrays of mat4 and mat4
370 // Non-square matrices of type matCxR consume the same space as a square
371 // matrix of type matN where N is the greater of C and R
372 case GL_FLOAT_MAT4:
373 case GL_FLOAT_MAT2x4:
374 case GL_FLOAT_MAT3x4:
375 case GL_FLOAT_MAT4x2:
376 case GL_FLOAT_MAT4x3:
377 return 0;
378
379 // 2. Arrays of mat2 and mat2 (since they occupy full rows)
380 case GL_FLOAT_MAT2:
381 return 1;
382
383 // 3. Arrays of vec4 and vec4
384 case GL_FLOAT_VEC4:
385 case GL_INT_VEC4:
386 case GL_BOOL_VEC4:
387 case GL_UNSIGNED_INT_VEC4:
388 return 2;
389
390 // 4. Arrays of mat3 and mat3
391 case GL_FLOAT_MAT3:
392 case GL_FLOAT_MAT2x3:
393 case GL_FLOAT_MAT3x2:
394 return 3;
395
396 // 5. Arrays of vec3 and vec3
397 case GL_FLOAT_VEC3:
398 case GL_INT_VEC3:
399 case GL_BOOL_VEC3:
400 case GL_UNSIGNED_INT_VEC3:
401 return 4;
402
403 // 6. Arrays of vec2 and vec2
404 case GL_FLOAT_VEC2:
405 case GL_INT_VEC2:
406 case GL_BOOL_VEC2:
407 case GL_UNSIGNED_INT_VEC2:
408 return 5;
409
410 // 7. Single component types
411 case GL_FLOAT:
412 case GL_INT:
413 case GL_BOOL:
414 case GL_UNSIGNED_INT:
415 case GL_SAMPLER_2D:
416 case GL_SAMPLER_CUBE:
417 case GL_SAMPLER_EXTERNAL_OES:
418 case GL_SAMPLER_2D_RECT_ARB:
419 case GL_SAMPLER_2D_ARRAY:
420 case GL_SAMPLER_3D:
421 case GL_INT_SAMPLER_2D:
422 case GL_INT_SAMPLER_3D:
423 case GL_INT_SAMPLER_CUBE:
424 case GL_INT_SAMPLER_2D_ARRAY:
425 case GL_UNSIGNED_INT_SAMPLER_2D:
426 case GL_UNSIGNED_INT_SAMPLER_3D:
427 case GL_UNSIGNED_INT_SAMPLER_CUBE:
428 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
429 case GL_SAMPLER_2D_SHADOW:
430 case GL_SAMPLER_2D_ARRAY_SHADOW:
431 case GL_SAMPLER_CUBE_SHADOW:
432 return 6;
433
434 default:
435 UNREACHABLE();
436 return 0;
437 }
438 }
439
440 }
441
getTempPath()442 std::string getTempPath()
443 {
444 #ifdef ANGLE_PLATFORM_WINDOWS
445 char path[MAX_PATH];
446 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
447 if (pathLen == 0)
448 {
449 UNREACHABLE();
450 return std::string();
451 }
452
453 UINT unique = GetTempFileNameA(path, "sh", 0, path);
454 if (unique == 0)
455 {
456 UNREACHABLE();
457 return std::string();
458 }
459
460 return path;
461 #else
462 UNIMPLEMENTED();
463 return "";
464 #endif
465 }
466
writeFile(const char * path,const void * content,size_t size)467 void writeFile(const char* path, const void* content, size_t size)
468 {
469 FILE* file = fopen(path, "w");
470 if (!file)
471 {
472 UNREACHABLE();
473 return;
474 }
475
476 fwrite(content, sizeof(char), size, file);
477 fclose(file);
478 }
479