blob: 9d9f657234a33452934b7b7b02c74144f552eb4d [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// 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
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +00009#include "common/utilities.h"
10#include "common/mathutil.h"
Geoff Lang44fa7592014-05-30 11:50:07 -040011#include "common/platform.h"
Geoff Lang83217792014-01-16 09:52:38 -050012
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000013#include <set>
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000014
Cooper Partin88d3b8c2014-10-08 10:41:56 -070015#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
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000022namespace gl
23{
24
Jamie Madillf2575982014-06-25 16:04:54 -040025int VariableComponentCount(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000026{
Jamie Madillaa72d782014-07-02 15:31:19 -040027 return VariableRowCount(type) * VariableColumnCount(type);
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000028}
29
Jamie Madillf2575982014-06-25 16:04:54 -040030GLenum VariableComponentType(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000031{
32 switch(type)
33 {
34 case GL_BOOL:
35 case GL_BOOL_VEC2:
36 case GL_BOOL_VEC3:
37 case GL_BOOL_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -040038 return GL_BOOL;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000039 case GL_FLOAT:
40 case GL_FLOAT_VEC2:
41 case GL_FLOAT_VEC3:
42 case GL_FLOAT_VEC4:
43 case GL_FLOAT_MAT2:
44 case GL_FLOAT_MAT3:
45 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.come6ca6702013-04-13 03:40:44 +000046 case GL_FLOAT_MAT2x3:
47 case GL_FLOAT_MAT3x2:
48 case GL_FLOAT_MAT2x4:
49 case GL_FLOAT_MAT4x2:
50 case GL_FLOAT_MAT3x4:
51 case GL_FLOAT_MAT4x3:
Nicolas Capense6050882013-07-08 10:43:10 -040052 return GL_FLOAT;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000053 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000054 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -040055 case GL_SAMPLER_3D:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000056 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -040057 case GL_SAMPLER_2D_ARRAY:
58 case GL_INT_SAMPLER_2D:
59 case GL_INT_SAMPLER_3D:
60 case GL_INT_SAMPLER_CUBE:
61 case GL_INT_SAMPLER_2D_ARRAY:
62 case GL_UNSIGNED_INT_SAMPLER_2D:
63 case GL_UNSIGNED_INT_SAMPLER_3D:
64 case GL_UNSIGNED_INT_SAMPLER_CUBE:
65 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -040066 case GL_SAMPLER_2D_SHADOW:
67 case GL_SAMPLER_CUBE_SHADOW:
68 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000069 case GL_INT_VEC2:
70 case GL_INT_VEC3:
71 case GL_INT_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -040072 return GL_INT;
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +000073 case GL_UNSIGNED_INT:
74 case GL_UNSIGNED_INT_VEC2:
75 case GL_UNSIGNED_INT_VEC3:
76 case GL_UNSIGNED_INT_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -040077 return GL_UNSIGNED_INT;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000078 default:
Nicolas Capense6050882013-07-08 10:43:10 -040079 UNREACHABLE();
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000080 }
81
82 return GL_NONE;
83}
84
Jamie Madillf2575982014-06-25 16:04:54 -040085size_t VariableComponentSize(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000086{
87 switch(type)
88 {
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +000089 case GL_BOOL: return sizeof(GLint);
90 case GL_FLOAT: return sizeof(GLfloat);
91 case GL_INT: return sizeof(GLint);
92 case GL_UNSIGNED_INT: return sizeof(GLuint);
jbauman@chromium.org72e8f442011-10-20 00:22:01 +000093 default: UNREACHABLE();
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000094 }
95
jbauman@chromium.org72e8f442011-10-20 00:22:01 +000096 return 0;
97}
98
Jamie Madillf2575982014-06-25 16:04:54 -040099size_t VariableInternalSize(GLenum type)
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000100{
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000101 // Expanded to 4-element vectors
Jamie Madillf2575982014-06-25 16:04:54 -0400102 return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000103}
104
Jamie Madillf2575982014-06-25 16:04:54 -0400105size_t VariableExternalSize(GLenum type)
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000106{
Jamie Madillf2575982014-06-25 16:04:54 -0400107 return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000108}
109
Jamie Madillf2575982014-06-25 16:04:54 -0400110GLenum VariableBoolVectorType(GLenum type)
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000111{
112 switch (type)
113 {
114 case GL_FLOAT:
115 case GL_INT:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000116 case GL_UNSIGNED_INT:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000117 return GL_BOOL;
118 case GL_FLOAT_VEC2:
119 case GL_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000120 case GL_UNSIGNED_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000121 return GL_BOOL_VEC2;
122 case GL_FLOAT_VEC3:
123 case GL_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000124 case GL_UNSIGNED_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000125 return GL_BOOL_VEC3;
126 case GL_FLOAT_VEC4:
127 case GL_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000128 case GL_UNSIGNED_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000129 return GL_BOOL_VEC4;
130
131 default:
132 UNREACHABLE();
133 return GL_NONE;
134 }
135}
136
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000137int VariableRowCount(GLenum type)
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000138{
139 switch (type)
140 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000141 case GL_NONE:
Jamie Madill66192b32013-09-09 15:41:37 -0400142 case GL_STRUCT_ANGLEX:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000143 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000144 case GL_BOOL:
145 case GL_FLOAT:
146 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000147 case GL_UNSIGNED_INT:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000148 case GL_BOOL_VEC2:
149 case GL_FLOAT_VEC2:
150 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000151 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000152 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000153 case GL_FLOAT_VEC3:
154 case GL_INT_VEC3:
155 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000156 case GL_BOOL_VEC4:
157 case GL_FLOAT_VEC4:
158 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000159 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000160 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -0400161 case GL_SAMPLER_3D:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000162 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -0400163 case GL_SAMPLER_2D_ARRAY:
Jamie Madillaa72d782014-07-02 15:31:19 -0400164 case GL_SAMPLER_EXTERNAL_OES:
165 case GL_SAMPLER_2D_RECT_ARB:
Nicolas Capense6050882013-07-08 10:43:10 -0400166 case GL_INT_SAMPLER_2D:
167 case GL_INT_SAMPLER_3D:
168 case GL_INT_SAMPLER_CUBE:
169 case GL_INT_SAMPLER_2D_ARRAY:
170 case GL_UNSIGNED_INT_SAMPLER_2D:
171 case GL_UNSIGNED_INT_SAMPLER_3D:
172 case GL_UNSIGNED_INT_SAMPLER_CUBE:
173 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400174 case GL_SAMPLER_2D_SHADOW:
175 case GL_SAMPLER_CUBE_SHADOW:
176 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000177 return 1;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000178 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000179 case GL_FLOAT_MAT3x2:
180 case GL_FLOAT_MAT4x2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000181 return 2;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000182 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000183 case GL_FLOAT_MAT2x3:
184 case GL_FLOAT_MAT4x3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000185 return 3;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000186 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000187 case GL_FLOAT_MAT2x4:
188 case GL_FLOAT_MAT3x4:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000189 return 4;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000190 default:
191 UNREACHABLE();
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000192 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000193
194 return 0;
195}
196
197int VariableColumnCount(GLenum type)
198{
199 switch (type)
200 {
201 case GL_NONE:
Jamie Madill66192b32013-09-09 15:41:37 -0400202 case GL_STRUCT_ANGLEX:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000203 return 0;
204 case GL_BOOL:
205 case GL_FLOAT:
206 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000207 case GL_UNSIGNED_INT:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000208 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -0400209 case GL_SAMPLER_3D:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000210 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -0400211 case GL_SAMPLER_2D_ARRAY:
212 case GL_INT_SAMPLER_2D:
213 case GL_INT_SAMPLER_3D:
214 case GL_INT_SAMPLER_CUBE:
215 case GL_INT_SAMPLER_2D_ARRAY:
Jamie Madillaa72d782014-07-02 15:31:19 -0400216 case GL_SAMPLER_EXTERNAL_OES:
217 case GL_SAMPLER_2D_RECT_ARB:
Nicolas Capense6050882013-07-08 10:43:10 -0400218 case GL_UNSIGNED_INT_SAMPLER_2D:
219 case GL_UNSIGNED_INT_SAMPLER_3D:
220 case GL_UNSIGNED_INT_SAMPLER_CUBE:
221 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400222 case GL_SAMPLER_2D_SHADOW:
223 case GL_SAMPLER_CUBE_SHADOW:
224 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000225 return 1;
226 case GL_BOOL_VEC2:
227 case GL_FLOAT_VEC2:
228 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000229 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000230 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000231 case GL_FLOAT_MAT2x3:
232 case GL_FLOAT_MAT2x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000233 return 2;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000234 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000235 case GL_FLOAT_VEC3:
236 case GL_INT_VEC3:
237 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000238 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000239 case GL_FLOAT_MAT3x2:
240 case GL_FLOAT_MAT3x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000241 return 3;
242 case GL_BOOL_VEC4:
243 case GL_FLOAT_VEC4:
244 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000245 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000246 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000247 case GL_FLOAT_MAT4x2:
248 case GL_FLOAT_MAT4x3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000249 return 4;
250 default:
251 UNREACHABLE();
252 }
253
254 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000255}
256
Geoff Lang2ec386b2014-12-03 14:44:38 -0500257bool IsSamplerType(GLenum type)
Nicolas Capense6050882013-07-08 10:43:10 -0400258{
259 switch (type)
260 {
261 case GL_SAMPLER_2D:
262 case GL_SAMPLER_3D:
263 case GL_SAMPLER_CUBE:
264 case GL_SAMPLER_2D_ARRAY:
265 case GL_INT_SAMPLER_2D:
266 case GL_INT_SAMPLER_3D:
267 case GL_INT_SAMPLER_CUBE:
268 case GL_INT_SAMPLER_2D_ARRAY:
269 case GL_UNSIGNED_INT_SAMPLER_2D:
270 case GL_UNSIGNED_INT_SAMPLER_3D:
271 case GL_UNSIGNED_INT_SAMPLER_CUBE:
272 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400273 case GL_SAMPLER_2D_SHADOW:
274 case GL_SAMPLER_CUBE_SHADOW:
275 case GL_SAMPLER_2D_ARRAY_SHADOW:
Nicolas Capense6050882013-07-08 10:43:10 -0400276 return true;
277 }
278
279 return false;
280}
281
Geoff Langf51bc792015-05-04 14:57:03 -0400282GLenum SamplerTypeToTextureType(GLenum samplerType)
283{
284 switch (samplerType)
285 {
286 case GL_SAMPLER_2D:
287 case GL_INT_SAMPLER_2D:
288 case GL_UNSIGNED_INT_SAMPLER_2D:
289 case GL_SAMPLER_2D_SHADOW:
290 return GL_TEXTURE_2D;
291
292 case GL_SAMPLER_CUBE:
293 case GL_INT_SAMPLER_CUBE:
294 case GL_UNSIGNED_INT_SAMPLER_CUBE:
295 case GL_SAMPLER_CUBE_SHADOW:
296 return GL_TEXTURE_CUBE_MAP;
297
298 case GL_SAMPLER_2D_ARRAY:
299 case GL_INT_SAMPLER_2D_ARRAY:
300 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
301 case GL_SAMPLER_2D_ARRAY_SHADOW:
302 return GL_TEXTURE_2D_ARRAY;
303
304 case GL_SAMPLER_3D:
305 case GL_INT_SAMPLER_3D:
306 case GL_UNSIGNED_INT_SAMPLER_3D:
307 return GL_TEXTURE_3D;
308
309 default:
310 UNREACHABLE();
311 return 0;
312 }
313}
314
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000315bool IsMatrixType(GLenum type)
316{
317 return VariableRowCount(type) > 1;
318}
319
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000320GLenum TransposeMatrixType(GLenum type)
321{
322 if (!IsMatrixType(type))
323 {
324 return type;
325 }
326
327 switch (type)
328 {
329 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
330 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
331 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
332 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
333 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
334 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
335 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
336 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
337 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
338 default: UNREACHABLE(); return GL_NONE;
339 }
340}
341
Jamie Madill8c6befc2013-06-20 11:55:55 -0400342int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
343{
344 ASSERT(IsMatrixType(type));
345 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
346}
347
348int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
349{
350 ASSERT(IsMatrixType(type));
351 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
352}
353
Jamie Madillf2575982014-06-25 16:04:54 -0400354int VariableRegisterCount(GLenum type)
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000355{
356 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
357}
358
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000359int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
360{
361 ASSERT(allocationSize <= bitsSize);
362
363 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
364
365 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
366 {
367 if ((*bits & mask) == 0)
368 {
369 *bits |= mask;
370 return i;
371 }
372
373 mask <<= 1;
374 }
375
376 return -1;
377}
378
Geoff Langd4475812015-03-18 10:53:05 -0400379static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
380static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
381static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
382static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
383static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
Geoff Lang691e58c2014-12-19 17:03:25 -0500384
385bool IsCubeMapTextureTarget(GLenum target)
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000386{
Geoff Lang691e58c2014-12-19 17:03:25 -0500387 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
388}
389
390size_t CubeMapTextureTargetToLayerIndex(GLenum target)
391{
392 ASSERT(IsCubeMapTextureTarget(target));
393 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
394}
395
396GLenum LayerIndexToCubeMapTextureTarget(size_t index)
397{
398 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
399 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000400}
401
Geoff Lang831b1952015-05-05 11:02:27 -0400402template <class IndexType>
403static RangeUI ComputeTypedIndexRange(const IndexType *indices, GLsizei count)
404{
405 ASSERT(count > 0);
406 IndexType minIndex = indices[0];
407 IndexType maxIndex = indices[0];
408
409 for (GLsizei i = 1; i < count; i++)
410 {
411 if (minIndex > indices[i]) minIndex = indices[i];
412 if (maxIndex < indices[i]) maxIndex = indices[i];
413 }
414
415 return RangeUI(static_cast<GLuint>(minIndex), static_cast<GLuint>(maxIndex));
416}
417
418RangeUI ComputeIndexRange(GLenum indexType, const GLvoid *indices, GLsizei count)
419{
420 switch (indexType)
421 {
422 case GL_UNSIGNED_BYTE: return ComputeTypedIndexRange(static_cast<const GLubyte*>(indices), count);
423 case GL_UNSIGNED_SHORT: return ComputeTypedIndexRange(static_cast<const GLushort*>(indices), count);
424 case GL_UNSIGNED_INT: return ComputeTypedIndexRange(static_cast<const GLuint*>(indices), count);
425 default: UNREACHABLE(); return RangeUI(0, 0);
426 }
427}
428
daniel@transgaming.com97c852b2012-12-20 20:56:23 +0000429bool IsTriangleMode(GLenum drawMode)
430{
431 switch (drawMode)
432 {
433 case GL_TRIANGLES:
434 case GL_TRIANGLE_FAN:
435 case GL_TRIANGLE_STRIP:
436 return true;
437 case GL_POINTS:
438 case GL_LINES:
439 case GL_LINE_LOOP:
440 case GL_LINE_STRIP:
441 return false;
442 default: UNREACHABLE();
443 }
444
445 return false;
446}
447
Jamie Madill865d1452014-07-02 15:31:20 -0400448// [OpenGL ES SL 3.00.4] Section 11 p. 120
449// Vertex Outs/Fragment Ins packing priorities
450int VariableSortOrder(GLenum type)
451{
452 switch (type)
453 {
454 // 1. Arrays of mat4 and mat4
455 // Non-square matrices of type matCxR consume the same space as a square
456 // matrix of type matN where N is the greater of C and R
457 case GL_FLOAT_MAT4:
458 case GL_FLOAT_MAT2x4:
459 case GL_FLOAT_MAT3x4:
460 case GL_FLOAT_MAT4x2:
461 case GL_FLOAT_MAT4x3:
462 return 0;
463
464 // 2. Arrays of mat2 and mat2 (since they occupy full rows)
465 case GL_FLOAT_MAT2:
466 return 1;
467
468 // 3. Arrays of vec4 and vec4
469 case GL_FLOAT_VEC4:
470 case GL_INT_VEC4:
471 case GL_BOOL_VEC4:
472 case GL_UNSIGNED_INT_VEC4:
473 return 2;
474
475 // 4. Arrays of mat3 and mat3
476 case GL_FLOAT_MAT3:
477 case GL_FLOAT_MAT2x3:
478 case GL_FLOAT_MAT3x2:
479 return 3;
480
481 // 5. Arrays of vec3 and vec3
482 case GL_FLOAT_VEC3:
483 case GL_INT_VEC3:
484 case GL_BOOL_VEC3:
485 case GL_UNSIGNED_INT_VEC3:
486 return 4;
487
488 // 6. Arrays of vec2 and vec2
489 case GL_FLOAT_VEC2:
490 case GL_INT_VEC2:
491 case GL_BOOL_VEC2:
492 case GL_UNSIGNED_INT_VEC2:
493 return 5;
494
495 // 7. Single component types
496 case GL_FLOAT:
497 case GL_INT:
498 case GL_BOOL:
499 case GL_UNSIGNED_INT:
500 case GL_SAMPLER_2D:
501 case GL_SAMPLER_CUBE:
502 case GL_SAMPLER_EXTERNAL_OES:
503 case GL_SAMPLER_2D_RECT_ARB:
504 case GL_SAMPLER_2D_ARRAY:
505 case GL_SAMPLER_3D:
506 case GL_INT_SAMPLER_2D:
507 case GL_INT_SAMPLER_3D:
508 case GL_INT_SAMPLER_CUBE:
509 case GL_INT_SAMPLER_2D_ARRAY:
510 case GL_UNSIGNED_INT_SAMPLER_2D:
511 case GL_UNSIGNED_INT_SAMPLER_3D:
512 case GL_UNSIGNED_INT_SAMPLER_CUBE:
513 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
514 case GL_SAMPLER_2D_SHADOW:
515 case GL_SAMPLER_2D_ARRAY_SHADOW:
516 case GL_SAMPLER_CUBE_SHADOW:
517 return 6;
518
519 default:
520 UNREACHABLE();
521 return 0;
522 }
523}
524
Geoff Langcfaeaa92015-04-14 13:41:02 -0400525std::string ParseUniformName(const std::string &name, size_t *outSubscript)
526{
527 // Strip any trailing array operator and retrieve the subscript
528 size_t open = name.find_last_of('[');
529 size_t close = name.find_last_of(']');
530 bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
531 if (!hasIndex)
532 {
533 if (outSubscript)
534 {
535 *outSubscript = GL_INVALID_INDEX;
536 }
537 return name;
538 }
539
540 if (outSubscript)
541 {
542 int index = atoi(name.substr(open + 1).c_str());
543 if (index >= 0)
544 {
545 *outSubscript = index;
546 }
547 else
548 {
549 *outSubscript = GL_INVALID_INDEX;
550 }
551 }
552
553 return name.substr(0, open);
554}
555
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000556}
557
Geoff Langa8406172015-07-21 16:53:39 -0400558namespace egl
559{
560static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
561 "Unexpected EGL cube map enum value.");
562static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
563 "Unexpected EGL cube map enum value.");
564static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
565 "Unexpected EGL cube map enum value.");
566static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
567 "Unexpected EGL cube map enum value.");
568static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
569 "Unexpected EGL cube map enum value.");
570
571bool IsCubeMapTextureTarget(EGLenum target)
572{
573 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
574}
575
576size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
577{
578 ASSERT(IsCubeMapTextureTarget(target));
579 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
580}
581
582EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
583{
584 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
585 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
586}
587
588bool IsTextureTarget(EGLenum target)
589{
590 switch (target)
591 {
592 case EGL_GL_TEXTURE_2D_KHR:
593 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
594 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
595 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
596 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
597 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
598 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
599 case EGL_GL_TEXTURE_3D_KHR:
600 return true;
601
602 default:
603 return false;
604 }
605}
606
607bool IsRenderbufferTarget(EGLenum target)
608{
609 return target == EGL_GL_RENDERBUFFER_KHR;
610}
611}
612
613namespace egl_gl
614{
615GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
616{
617 ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
618 return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
619}
620
621GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
622{
623 switch (eglTarget)
624 {
625 case EGL_GL_TEXTURE_2D_KHR:
626 return GL_TEXTURE_2D;
627
628 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
629 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
630 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
631 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
632 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
633 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
634 return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
635
636 case EGL_GL_TEXTURE_3D_KHR:
637 return GL_TEXTURE_3D;
638
639 default:
640 UNREACHABLE();
641 return GL_NONE;
642 }
643}
644
645GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
646{
647 return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
648}
649}
650
Austin Kinross922a9fb2014-10-21 14:26:33 -0700651#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000652std::string getTempPath()
653{
Shannon Woodsfb839472014-06-16 13:21:41 -0400654#ifdef ANGLE_PLATFORM_WINDOWS
Austin Kinross922a9fb2014-10-21 14:26:33 -0700655 char path[MAX_PATH];
656 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
657 if (pathLen == 0)
658 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000659 UNREACHABLE();
660 return std::string();
Austin Kinross922a9fb2014-10-21 14:26:33 -0700661 }
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000662
Austin Kinross922a9fb2014-10-21 14:26:33 -0700663 UINT unique = GetTempFileNameA(path, "sh", 0, path);
664 if (unique == 0)
665 {
666 UNREACHABLE();
667 return std::string();
668 }
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +0000669
Austin Kinross922a9fb2014-10-21 14:26:33 -0700670 return path;
Geoff Lang83217792014-01-16 09:52:38 -0500671#else
672 UNIMPLEMENTED();
673 return "";
674#endif
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000675}
676
677void writeFile(const char* path, const void* content, size_t size)
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000678{
679 FILE* file = fopen(path, "w");
680 if (!file)
681 {
682 UNREACHABLE();
683 return;
684 }
685
686 fwrite(content, sizeof(char), size, file);
687 fclose(file);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000688}
Austin Kinross922a9fb2014-10-21 14:26:33 -0700689#endif // !ANGLE_ENABLE_WINDOWS_STORE
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700690
Cooper Partin1edac3b2014-11-20 13:49:27 -0800691#if defined (ANGLE_PLATFORM_WINDOWS)
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700692
Cooper Partin1edac3b2014-11-20 13:49:27 -0800693// Causes the thread to relinquish the remainder of its time slice to any
694// other thread that is ready to run.If there are no other threads ready
695// to run, the function returns immediately, and the thread continues execution.
696void ScheduleYield()
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700697{
Cooper Partin1edac3b2014-11-20 13:49:27 -0800698#if defined(ANGLE_ENABLE_WINDOWS_STORE)
699 // This implementation of Sleep exists because it is not available prior to Update 4.
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700700 static HANDLE singletonEvent = nullptr;
701 HANDLE sleepEvent = singletonEvent;
702 if (!sleepEvent)
703 {
704 sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
705
706 if (!sleepEvent)
707 return;
708
709 HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
710
711 if (previousEvent)
712 {
713 // Back out if multiple threads try to demand create at the same time.
714 CloseHandle(sleepEvent);
715 sleepEvent = previousEvent;
716 }
717 }
718
719 // Emulate sleep by waiting with timeout on an event that is never signalled.
Cooper Partin1edac3b2014-11-20 13:49:27 -0800720 WaitForSingleObjectEx(sleepEvent, 0, false);
721#else
722 Sleep(0);
723#endif
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700724}
725
Kenneth Russellb23deb22014-11-21 14:53:56 -0800726#endif