blob: 3952872cf0b7a96cbfb884646aa95bec51966d30 [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
Geoff Lang3edfe032015-09-04 16:38:24 -040022namespace
23{
24
25template <class IndexType>
26gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
27 size_t count,
28 bool primitiveRestartEnabled,
29 GLuint primitiveRestartIndex)
30{
31 ASSERT(count > 0);
32
33 IndexType minIndex = 0;
34 IndexType maxIndex = 0;
35 size_t nonPrimitiveRestartIndices = 0;
36
37 if (primitiveRestartEnabled)
38 {
39 // Find the first non-primitive restart index to initialize the min and max values
40 size_t i = 0;
41 for (; i < count; i++)
42 {
43 if (indices[i] != primitiveRestartIndex)
44 {
45 minIndex = indices[i];
46 maxIndex = indices[i];
47 nonPrimitiveRestartIndices++;
48 break;
49 }
50 }
51
52 // Loop over the rest of the indices
53 for (; i < count; i++)
54 {
55 if (indices[i] != primitiveRestartIndex)
56 {
57 if (minIndex > indices[i])
58 {
59 minIndex = indices[i];
60 }
61 if (maxIndex < indices[i])
62 {
63 maxIndex = indices[i];
64 }
65 nonPrimitiveRestartIndices++;
66 }
67 }
68 }
69 else
70 {
71 minIndex = indices[0];
72 maxIndex = indices[0];
73 nonPrimitiveRestartIndices = count;
74
75 for (size_t i = 1; i < count; i++)
76 {
77 if (minIndex > indices[i])
78 {
79 minIndex = indices[i];
80 }
81 if (maxIndex < indices[i])
82 {
83 maxIndex = indices[i];
84 }
85 }
86 }
87
88 return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
89 nonPrimitiveRestartIndices);
90}
91
92} // anonymous namespace
93
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000094namespace gl
95{
96
Jamie Madillf2575982014-06-25 16:04:54 -040097int VariableComponentCount(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000098{
Jamie Madillaa72d782014-07-02 15:31:19 -040099 return VariableRowCount(type) * VariableColumnCount(type);
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000100}
101
Jamie Madillf2575982014-06-25 16:04:54 -0400102GLenum VariableComponentType(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000103{
104 switch(type)
105 {
106 case GL_BOOL:
107 case GL_BOOL_VEC2:
108 case GL_BOOL_VEC3:
109 case GL_BOOL_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -0400110 return GL_BOOL;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000111 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:
shannon.woods%transgaming.com@gtempaccount.come6ca6702013-04-13 03:40:44 +0000118 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:
Nicolas Capense6050882013-07-08 10:43:10 -0400124 return GL_FLOAT;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000125 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +0000126 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -0400127 case GL_SAMPLER_3D:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +0000128 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -0400129 case GL_SAMPLER_2D_ARRAY:
130 case GL_INT_SAMPLER_2D:
131 case GL_INT_SAMPLER_3D:
132 case GL_INT_SAMPLER_CUBE:
133 case GL_INT_SAMPLER_2D_ARRAY:
134 case GL_UNSIGNED_INT_SAMPLER_2D:
135 case GL_UNSIGNED_INT_SAMPLER_3D:
136 case GL_UNSIGNED_INT_SAMPLER_CUBE:
137 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400138 case GL_SAMPLER_2D_SHADOW:
139 case GL_SAMPLER_CUBE_SHADOW:
140 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000141 case GL_INT_VEC2:
142 case GL_INT_VEC3:
143 case GL_INT_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -0400144 return GL_INT;
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000145 case GL_UNSIGNED_INT:
146 case GL_UNSIGNED_INT_VEC2:
147 case GL_UNSIGNED_INT_VEC3:
148 case GL_UNSIGNED_INT_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -0400149 return GL_UNSIGNED_INT;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000150 default:
Nicolas Capense6050882013-07-08 10:43:10 -0400151 UNREACHABLE();
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000152 }
153
154 return GL_NONE;
155}
156
Jamie Madillf2575982014-06-25 16:04:54 -0400157size_t VariableComponentSize(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000158{
159 switch(type)
160 {
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000161 case GL_BOOL: return sizeof(GLint);
162 case GL_FLOAT: return sizeof(GLfloat);
163 case GL_INT: return sizeof(GLint);
164 case GL_UNSIGNED_INT: return sizeof(GLuint);
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000165 default: UNREACHABLE();
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000166 }
167
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000168 return 0;
169}
170
Jamie Madillf2575982014-06-25 16:04:54 -0400171size_t VariableInternalSize(GLenum type)
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000172{
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000173 // Expanded to 4-element vectors
Jamie Madillf2575982014-06-25 16:04:54 -0400174 return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000175}
176
Jamie Madillf2575982014-06-25 16:04:54 -0400177size_t VariableExternalSize(GLenum type)
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000178{
Jamie Madillf2575982014-06-25 16:04:54 -0400179 return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000180}
181
Jamie Madillf2575982014-06-25 16:04:54 -0400182GLenum VariableBoolVectorType(GLenum type)
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000183{
184 switch (type)
185 {
186 case GL_FLOAT:
187 case GL_INT:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000188 case GL_UNSIGNED_INT:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000189 return GL_BOOL;
190 case GL_FLOAT_VEC2:
191 case GL_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000192 case GL_UNSIGNED_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000193 return GL_BOOL_VEC2;
194 case GL_FLOAT_VEC3:
195 case GL_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000196 case GL_UNSIGNED_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000197 return GL_BOOL_VEC3;
198 case GL_FLOAT_VEC4:
199 case GL_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000200 case GL_UNSIGNED_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000201 return GL_BOOL_VEC4;
202
203 default:
204 UNREACHABLE();
205 return GL_NONE;
206 }
207}
208
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000209int VariableRowCount(GLenum type)
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000210{
211 switch (type)
212 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000213 case GL_NONE:
Jamie Madill66192b32013-09-09 15:41:37 -0400214 case GL_STRUCT_ANGLEX:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000215 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000216 case GL_BOOL:
217 case GL_FLOAT:
218 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000219 case GL_UNSIGNED_INT:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000220 case GL_BOOL_VEC2:
221 case GL_FLOAT_VEC2:
222 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000223 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000224 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000225 case GL_FLOAT_VEC3:
226 case GL_INT_VEC3:
227 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000228 case GL_BOOL_VEC4:
229 case GL_FLOAT_VEC4:
230 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000231 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000232 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -0400233 case GL_SAMPLER_3D:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000234 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -0400235 case GL_SAMPLER_2D_ARRAY:
Jamie Madillaa72d782014-07-02 15:31:19 -0400236 case GL_SAMPLER_EXTERNAL_OES:
237 case GL_SAMPLER_2D_RECT_ARB:
Nicolas Capense6050882013-07-08 10:43:10 -0400238 case GL_INT_SAMPLER_2D:
239 case GL_INT_SAMPLER_3D:
240 case GL_INT_SAMPLER_CUBE:
241 case GL_INT_SAMPLER_2D_ARRAY:
242 case GL_UNSIGNED_INT_SAMPLER_2D:
243 case GL_UNSIGNED_INT_SAMPLER_3D:
244 case GL_UNSIGNED_INT_SAMPLER_CUBE:
245 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400246 case GL_SAMPLER_2D_SHADOW:
247 case GL_SAMPLER_CUBE_SHADOW:
248 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000249 return 1;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000250 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000251 case GL_FLOAT_MAT3x2:
252 case GL_FLOAT_MAT4x2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000253 return 2;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000254 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000255 case GL_FLOAT_MAT2x3:
256 case GL_FLOAT_MAT4x3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000257 return 3;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000258 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000259 case GL_FLOAT_MAT2x4:
260 case GL_FLOAT_MAT3x4:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000261 return 4;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000262 default:
263 UNREACHABLE();
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000264 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000265
266 return 0;
267}
268
269int VariableColumnCount(GLenum type)
270{
271 switch (type)
272 {
273 case GL_NONE:
Jamie Madill66192b32013-09-09 15:41:37 -0400274 case GL_STRUCT_ANGLEX:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000275 return 0;
276 case GL_BOOL:
277 case GL_FLOAT:
278 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000279 case GL_UNSIGNED_INT:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000280 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -0400281 case GL_SAMPLER_3D:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000282 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -0400283 case GL_SAMPLER_2D_ARRAY:
284 case GL_INT_SAMPLER_2D:
285 case GL_INT_SAMPLER_3D:
286 case GL_INT_SAMPLER_CUBE:
287 case GL_INT_SAMPLER_2D_ARRAY:
Jamie Madillaa72d782014-07-02 15:31:19 -0400288 case GL_SAMPLER_EXTERNAL_OES:
289 case GL_SAMPLER_2D_RECT_ARB:
Nicolas Capense6050882013-07-08 10:43:10 -0400290 case GL_UNSIGNED_INT_SAMPLER_2D:
291 case GL_UNSIGNED_INT_SAMPLER_3D:
292 case GL_UNSIGNED_INT_SAMPLER_CUBE:
293 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400294 case GL_SAMPLER_2D_SHADOW:
295 case GL_SAMPLER_CUBE_SHADOW:
296 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000297 return 1;
298 case GL_BOOL_VEC2:
299 case GL_FLOAT_VEC2:
300 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000301 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000302 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000303 case GL_FLOAT_MAT2x3:
304 case GL_FLOAT_MAT2x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000305 return 2;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000306 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000307 case GL_FLOAT_VEC3:
308 case GL_INT_VEC3:
309 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000310 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000311 case GL_FLOAT_MAT3x2:
312 case GL_FLOAT_MAT3x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000313 return 3;
314 case GL_BOOL_VEC4:
315 case GL_FLOAT_VEC4:
316 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000317 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000318 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000319 case GL_FLOAT_MAT4x2:
320 case GL_FLOAT_MAT4x3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000321 return 4;
322 default:
323 UNREACHABLE();
324 }
325
326 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000327}
328
Geoff Lang2ec386b2014-12-03 14:44:38 -0500329bool IsSamplerType(GLenum type)
Nicolas Capense6050882013-07-08 10:43:10 -0400330{
331 switch (type)
332 {
333 case GL_SAMPLER_2D:
334 case GL_SAMPLER_3D:
335 case GL_SAMPLER_CUBE:
336 case GL_SAMPLER_2D_ARRAY:
337 case GL_INT_SAMPLER_2D:
338 case GL_INT_SAMPLER_3D:
339 case GL_INT_SAMPLER_CUBE:
340 case GL_INT_SAMPLER_2D_ARRAY:
341 case GL_UNSIGNED_INT_SAMPLER_2D:
342 case GL_UNSIGNED_INT_SAMPLER_3D:
343 case GL_UNSIGNED_INT_SAMPLER_CUBE:
344 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400345 case GL_SAMPLER_2D_SHADOW:
346 case GL_SAMPLER_CUBE_SHADOW:
347 case GL_SAMPLER_2D_ARRAY_SHADOW:
Nicolas Capense6050882013-07-08 10:43:10 -0400348 return true;
349 }
350
351 return false;
352}
353
Geoff Langf51bc792015-05-04 14:57:03 -0400354GLenum SamplerTypeToTextureType(GLenum samplerType)
355{
356 switch (samplerType)
357 {
358 case GL_SAMPLER_2D:
359 case GL_INT_SAMPLER_2D:
360 case GL_UNSIGNED_INT_SAMPLER_2D:
361 case GL_SAMPLER_2D_SHADOW:
362 return GL_TEXTURE_2D;
363
364 case GL_SAMPLER_CUBE:
365 case GL_INT_SAMPLER_CUBE:
366 case GL_UNSIGNED_INT_SAMPLER_CUBE:
367 case GL_SAMPLER_CUBE_SHADOW:
368 return GL_TEXTURE_CUBE_MAP;
369
370 case GL_SAMPLER_2D_ARRAY:
371 case GL_INT_SAMPLER_2D_ARRAY:
372 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
373 case GL_SAMPLER_2D_ARRAY_SHADOW:
374 return GL_TEXTURE_2D_ARRAY;
375
376 case GL_SAMPLER_3D:
377 case GL_INT_SAMPLER_3D:
378 case GL_UNSIGNED_INT_SAMPLER_3D:
379 return GL_TEXTURE_3D;
380
381 default:
382 UNREACHABLE();
383 return 0;
384 }
385}
386
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000387bool IsMatrixType(GLenum type)
388{
389 return VariableRowCount(type) > 1;
390}
391
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000392GLenum TransposeMatrixType(GLenum type)
393{
394 if (!IsMatrixType(type))
395 {
396 return type;
397 }
398
399 switch (type)
400 {
401 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
402 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
403 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
404 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
405 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
406 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
407 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
408 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
409 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
410 default: UNREACHABLE(); return GL_NONE;
411 }
412}
413
Jamie Madill8c6befc2013-06-20 11:55:55 -0400414int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
415{
416 ASSERT(IsMatrixType(type));
417 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
418}
419
420int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
421{
422 ASSERT(IsMatrixType(type));
423 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
424}
425
Jamie Madillf2575982014-06-25 16:04:54 -0400426int VariableRegisterCount(GLenum type)
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000427{
428 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
429}
430
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000431int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
432{
433 ASSERT(allocationSize <= bitsSize);
434
435 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
436
437 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
438 {
439 if ((*bits & mask) == 0)
440 {
441 *bits |= mask;
442 return i;
443 }
444
445 mask <<= 1;
446 }
447
448 return -1;
449}
450
Geoff Langd4475812015-03-18 10:53:05 -0400451static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
452static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
453static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
454static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
455static_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 -0500456
457bool IsCubeMapTextureTarget(GLenum target)
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000458{
Geoff Lang691e58c2014-12-19 17:03:25 -0500459 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
460}
461
462size_t CubeMapTextureTargetToLayerIndex(GLenum target)
463{
464 ASSERT(IsCubeMapTextureTarget(target));
465 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
466}
467
468GLenum LayerIndexToCubeMapTextureTarget(size_t index)
469{
470 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
471 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000472}
473
Geoff Lang3edfe032015-09-04 16:38:24 -0400474IndexRange ComputeIndexRange(GLenum indexType,
475 const GLvoid *indices,
476 size_t count,
477 bool primitiveRestartEnabled)
Geoff Lang831b1952015-05-05 11:02:27 -0400478{
479 switch (indexType)
480 {
Geoff Lang3edfe032015-09-04 16:38:24 -0400481 case GL_UNSIGNED_BYTE:
482 return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
483 primitiveRestartEnabled,
484 GetPrimitiveRestartIndex(indexType));
485 case GL_UNSIGNED_SHORT:
486 return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
487 primitiveRestartEnabled,
488 GetPrimitiveRestartIndex(indexType));
489 case GL_UNSIGNED_INT:
490 return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
491 primitiveRestartEnabled,
492 GetPrimitiveRestartIndex(indexType));
493 default:
494 UNREACHABLE();
495 return IndexRange();
496 }
497}
498
499GLuint GetPrimitiveRestartIndex(GLenum indexType)
500{
501 switch (indexType)
502 {
503 case GL_UNSIGNED_BYTE:
504 return 0xFF;
505 case GL_UNSIGNED_SHORT:
506 return 0xFFFF;
507 case GL_UNSIGNED_INT:
508 return 0xFFFFFFFF;
509 default:
510 UNREACHABLE();
511 return 0;
Geoff Lang831b1952015-05-05 11:02:27 -0400512 }
513}
514
daniel@transgaming.com97c852b2012-12-20 20:56:23 +0000515bool IsTriangleMode(GLenum drawMode)
516{
517 switch (drawMode)
518 {
519 case GL_TRIANGLES:
520 case GL_TRIANGLE_FAN:
521 case GL_TRIANGLE_STRIP:
522 return true;
523 case GL_POINTS:
524 case GL_LINES:
525 case GL_LINE_LOOP:
526 case GL_LINE_STRIP:
527 return false;
528 default: UNREACHABLE();
529 }
530
531 return false;
532}
533
Jamie Madill865d1452014-07-02 15:31:20 -0400534// [OpenGL ES SL 3.00.4] Section 11 p. 120
535// Vertex Outs/Fragment Ins packing priorities
536int VariableSortOrder(GLenum type)
537{
538 switch (type)
539 {
540 // 1. Arrays of mat4 and mat4
541 // Non-square matrices of type matCxR consume the same space as a square
542 // matrix of type matN where N is the greater of C and R
543 case GL_FLOAT_MAT4:
544 case GL_FLOAT_MAT2x4:
545 case GL_FLOAT_MAT3x4:
546 case GL_FLOAT_MAT4x2:
547 case GL_FLOAT_MAT4x3:
548 return 0;
549
550 // 2. Arrays of mat2 and mat2 (since they occupy full rows)
551 case GL_FLOAT_MAT2:
552 return 1;
553
554 // 3. Arrays of vec4 and vec4
555 case GL_FLOAT_VEC4:
556 case GL_INT_VEC4:
557 case GL_BOOL_VEC4:
558 case GL_UNSIGNED_INT_VEC4:
559 return 2;
560
561 // 4. Arrays of mat3 and mat3
562 case GL_FLOAT_MAT3:
563 case GL_FLOAT_MAT2x3:
564 case GL_FLOAT_MAT3x2:
565 return 3;
566
567 // 5. Arrays of vec3 and vec3
568 case GL_FLOAT_VEC3:
569 case GL_INT_VEC3:
570 case GL_BOOL_VEC3:
571 case GL_UNSIGNED_INT_VEC3:
572 return 4;
573
574 // 6. Arrays of vec2 and vec2
575 case GL_FLOAT_VEC2:
576 case GL_INT_VEC2:
577 case GL_BOOL_VEC2:
578 case GL_UNSIGNED_INT_VEC2:
579 return 5;
580
581 // 7. Single component types
582 case GL_FLOAT:
583 case GL_INT:
584 case GL_BOOL:
585 case GL_UNSIGNED_INT:
586 case GL_SAMPLER_2D:
587 case GL_SAMPLER_CUBE:
588 case GL_SAMPLER_EXTERNAL_OES:
589 case GL_SAMPLER_2D_RECT_ARB:
590 case GL_SAMPLER_2D_ARRAY:
591 case GL_SAMPLER_3D:
592 case GL_INT_SAMPLER_2D:
593 case GL_INT_SAMPLER_3D:
594 case GL_INT_SAMPLER_CUBE:
595 case GL_INT_SAMPLER_2D_ARRAY:
596 case GL_UNSIGNED_INT_SAMPLER_2D:
597 case GL_UNSIGNED_INT_SAMPLER_3D:
598 case GL_UNSIGNED_INT_SAMPLER_CUBE:
599 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
600 case GL_SAMPLER_2D_SHADOW:
601 case GL_SAMPLER_2D_ARRAY_SHADOW:
602 case GL_SAMPLER_CUBE_SHADOW:
603 return 6;
604
605 default:
606 UNREACHABLE();
607 return 0;
608 }
609}
610
Geoff Langcfaeaa92015-04-14 13:41:02 -0400611std::string ParseUniformName(const std::string &name, size_t *outSubscript)
612{
613 // Strip any trailing array operator and retrieve the subscript
614 size_t open = name.find_last_of('[');
615 size_t close = name.find_last_of(']');
616 bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
617 if (!hasIndex)
618 {
619 if (outSubscript)
620 {
621 *outSubscript = GL_INVALID_INDEX;
622 }
623 return name;
624 }
625
626 if (outSubscript)
627 {
628 int index = atoi(name.substr(open + 1).c_str());
629 if (index >= 0)
630 {
631 *outSubscript = index;
632 }
633 else
634 {
635 *outSubscript = GL_INVALID_INDEX;
636 }
637 }
638
639 return name.substr(0, open);
640}
641
Jamie Madill4a3c2342015-10-08 12:58:45 -0400642unsigned int ParseAndStripArrayIndex(std::string *name)
643{
644 unsigned int subscript = GL_INVALID_INDEX;
645
646 // Strip any trailing array operator and retrieve the subscript
647 size_t open = name->find_last_of('[');
648 size_t close = name->find_last_of(']');
649 if (open != std::string::npos && close == name->length() - 1)
650 {
651 subscript = atoi(name->c_str() + open + 1);
652 name->erase(open);
653 }
654
655 return subscript;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000656}
657
Jamie Madill4a3c2342015-10-08 12:58:45 -0400658} // namespace gl
659
Geoff Langa8406172015-07-21 16:53:39 -0400660namespace egl
661{
662static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
663 "Unexpected EGL cube map enum value.");
664static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
665 "Unexpected EGL cube map enum value.");
666static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
667 "Unexpected EGL cube map enum value.");
668static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
669 "Unexpected EGL cube map enum value.");
670static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
671 "Unexpected EGL cube map enum value.");
672
673bool IsCubeMapTextureTarget(EGLenum target)
674{
675 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
676}
677
678size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
679{
680 ASSERT(IsCubeMapTextureTarget(target));
681 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
682}
683
684EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
685{
686 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
687 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
688}
689
690bool IsTextureTarget(EGLenum target)
691{
692 switch (target)
693 {
694 case EGL_GL_TEXTURE_2D_KHR:
695 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
696 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
697 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
698 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
699 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
700 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
701 case EGL_GL_TEXTURE_3D_KHR:
702 return true;
703
704 default:
705 return false;
706 }
707}
708
709bool IsRenderbufferTarget(EGLenum target)
710{
711 return target == EGL_GL_RENDERBUFFER_KHR;
712}
713}
714
715namespace egl_gl
716{
717GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
718{
719 ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
720 return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
721}
722
723GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
724{
725 switch (eglTarget)
726 {
727 case EGL_GL_TEXTURE_2D_KHR:
728 return GL_TEXTURE_2D;
729
730 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
731 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
732 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
733 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
734 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
735 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
736 return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
737
738 case EGL_GL_TEXTURE_3D_KHR:
739 return GL_TEXTURE_3D;
740
741 default:
742 UNREACHABLE();
743 return GL_NONE;
744 }
745}
746
747GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
748{
749 return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
750}
751}
752
Austin Kinross922a9fb2014-10-21 14:26:33 -0700753#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000754std::string getTempPath()
755{
Shannon Woodsfb839472014-06-16 13:21:41 -0400756#ifdef ANGLE_PLATFORM_WINDOWS
Austin Kinross922a9fb2014-10-21 14:26:33 -0700757 char path[MAX_PATH];
758 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
759 if (pathLen == 0)
760 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000761 UNREACHABLE();
762 return std::string();
Austin Kinross922a9fb2014-10-21 14:26:33 -0700763 }
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000764
Austin Kinross922a9fb2014-10-21 14:26:33 -0700765 UINT unique = GetTempFileNameA(path, "sh", 0, path);
766 if (unique == 0)
767 {
768 UNREACHABLE();
769 return std::string();
770 }
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +0000771
Austin Kinross922a9fb2014-10-21 14:26:33 -0700772 return path;
Geoff Lang83217792014-01-16 09:52:38 -0500773#else
774 UNIMPLEMENTED();
775 return "";
776#endif
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000777}
778
779void writeFile(const char* path, const void* content, size_t size)
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000780{
781 FILE* file = fopen(path, "w");
782 if (!file)
783 {
784 UNREACHABLE();
785 return;
786 }
787
788 fwrite(content, sizeof(char), size, file);
789 fclose(file);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000790}
Austin Kinross922a9fb2014-10-21 14:26:33 -0700791#endif // !ANGLE_ENABLE_WINDOWS_STORE
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700792
Cooper Partin1edac3b2014-11-20 13:49:27 -0800793#if defined (ANGLE_PLATFORM_WINDOWS)
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700794
Cooper Partin1edac3b2014-11-20 13:49:27 -0800795// Causes the thread to relinquish the remainder of its time slice to any
796// other thread that is ready to run.If there are no other threads ready
797// to run, the function returns immediately, and the thread continues execution.
798void ScheduleYield()
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700799{
Cooper Partin1edac3b2014-11-20 13:49:27 -0800800#if defined(ANGLE_ENABLE_WINDOWS_STORE)
801 // This implementation of Sleep exists because it is not available prior to Update 4.
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700802 static HANDLE singletonEvent = nullptr;
803 HANDLE sleepEvent = singletonEvent;
804 if (!sleepEvent)
805 {
806 sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
807
808 if (!sleepEvent)
809 return;
810
811 HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
812
813 if (previousEvent)
814 {
815 // Back out if multiple threads try to demand create at the same time.
816 CloseHandle(sleepEvent);
817 sleepEvent = previousEvent;
818 }
819 }
820
821 // Emulate sleep by waiting with timeout on an event that is never signalled.
Cooper Partin1edac3b2014-11-20 13:49:27 -0800822 WaitForSingleObjectEx(sleepEvent, 0, false);
823#else
Geoff Lange5f735f2015-09-17 13:26:59 -0400824 Sleep(0);
Cooper Partin1edac3b2014-11-20 13:49:27 -0800825#endif
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700826}
827
Kenneth Russellb23deb22014-11-21 14:53:56 -0800828#endif