blob: 9686c7403dd1d54e8f7d619319be6aa07789b818 [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:
Ian Ewellbda75592016-04-18 17:25:54 -0400130 case GL_SAMPLER_EXTERNAL_OES:
Nicolas Capense6050882013-07-08 10:43:10 -0400131 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:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400139 case GL_SAMPLER_2D_SHADOW:
140 case GL_SAMPLER_CUBE_SHADOW:
141 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000142 case GL_INT_VEC2:
143 case GL_INT_VEC3:
144 case GL_INT_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -0400145 return GL_INT;
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000146 case GL_UNSIGNED_INT:
147 case GL_UNSIGNED_INT_VEC2:
148 case GL_UNSIGNED_INT_VEC3:
149 case GL_UNSIGNED_INT_VEC4:
Nicolas Capense6050882013-07-08 10:43:10 -0400150 return GL_UNSIGNED_INT;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000151 default:
Nicolas Capense6050882013-07-08 10:43:10 -0400152 UNREACHABLE();
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000153 }
154
155 return GL_NONE;
156}
157
Jamie Madillf2575982014-06-25 16:04:54 -0400158size_t VariableComponentSize(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000159{
160 switch(type)
161 {
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000162 case GL_BOOL: return sizeof(GLint);
163 case GL_FLOAT: return sizeof(GLfloat);
164 case GL_INT: return sizeof(GLint);
165 case GL_UNSIGNED_INT: return sizeof(GLuint);
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000166 default: UNREACHABLE();
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000167 }
168
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000169 return 0;
170}
171
Jamie Madillf2575982014-06-25 16:04:54 -0400172size_t VariableInternalSize(GLenum type)
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000173{
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000174 // Expanded to 4-element vectors
Jamie Madillf2575982014-06-25 16:04:54 -0400175 return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000176}
177
Jamie Madillf2575982014-06-25 16:04:54 -0400178size_t VariableExternalSize(GLenum type)
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000179{
Jamie Madillf2575982014-06-25 16:04:54 -0400180 return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000181}
182
Jamie Madillf2575982014-06-25 16:04:54 -0400183GLenum VariableBoolVectorType(GLenum type)
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000184{
185 switch (type)
186 {
187 case GL_FLOAT:
188 case GL_INT:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000189 case GL_UNSIGNED_INT:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000190 return GL_BOOL;
191 case GL_FLOAT_VEC2:
192 case GL_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000193 case GL_UNSIGNED_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000194 return GL_BOOL_VEC2;
195 case GL_FLOAT_VEC3:
196 case GL_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000197 case GL_UNSIGNED_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000198 return GL_BOOL_VEC3;
199 case GL_FLOAT_VEC4:
200 case GL_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000201 case GL_UNSIGNED_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000202 return GL_BOOL_VEC4;
203
204 default:
205 UNREACHABLE();
206 return GL_NONE;
207 }
208}
209
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000210int VariableRowCount(GLenum type)
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000211{
212 switch (type)
213 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000214 case GL_NONE:
Jamie Madill66192b32013-09-09 15:41:37 -0400215 case GL_STRUCT_ANGLEX:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000216 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000217 case GL_BOOL:
218 case GL_FLOAT:
219 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000220 case GL_UNSIGNED_INT:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000221 case GL_BOOL_VEC2:
222 case GL_FLOAT_VEC2:
223 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000224 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000225 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000226 case GL_FLOAT_VEC3:
227 case GL_INT_VEC3:
228 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000229 case GL_BOOL_VEC4:
230 case GL_FLOAT_VEC4:
231 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000232 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000233 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -0400234 case GL_SAMPLER_3D:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000235 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -0400236 case GL_SAMPLER_2D_ARRAY:
Jamie Madillaa72d782014-07-02 15:31:19 -0400237 case GL_SAMPLER_EXTERNAL_OES:
238 case GL_SAMPLER_2D_RECT_ARB:
Nicolas Capense6050882013-07-08 10:43:10 -0400239 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:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400247 case GL_SAMPLER_2D_SHADOW:
248 case GL_SAMPLER_CUBE_SHADOW:
249 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000250 return 1;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000251 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000252 case GL_FLOAT_MAT3x2:
253 case GL_FLOAT_MAT4x2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000254 return 2;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000255 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000256 case GL_FLOAT_MAT2x3:
257 case GL_FLOAT_MAT4x3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000258 return 3;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000259 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000260 case GL_FLOAT_MAT2x4:
261 case GL_FLOAT_MAT3x4:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000262 return 4;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000263 default:
264 UNREACHABLE();
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000265 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000266
267 return 0;
268}
269
270int VariableColumnCount(GLenum type)
271{
272 switch (type)
273 {
274 case GL_NONE:
Jamie Madill66192b32013-09-09 15:41:37 -0400275 case GL_STRUCT_ANGLEX:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000276 return 0;
277 case GL_BOOL:
278 case GL_FLOAT:
279 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000280 case GL_UNSIGNED_INT:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000281 case GL_SAMPLER_2D:
Nicolas Capense6050882013-07-08 10:43:10 -0400282 case GL_SAMPLER_3D:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000283 case GL_SAMPLER_CUBE:
Nicolas Capense6050882013-07-08 10:43:10 -0400284 case GL_SAMPLER_2D_ARRAY:
285 case GL_INT_SAMPLER_2D:
286 case GL_INT_SAMPLER_3D:
287 case GL_INT_SAMPLER_CUBE:
288 case GL_INT_SAMPLER_2D_ARRAY:
Jamie Madillaa72d782014-07-02 15:31:19 -0400289 case GL_SAMPLER_EXTERNAL_OES:
290 case GL_SAMPLER_2D_RECT_ARB:
Nicolas Capense6050882013-07-08 10:43:10 -0400291 case GL_UNSIGNED_INT_SAMPLER_2D:
292 case GL_UNSIGNED_INT_SAMPLER_3D:
293 case GL_UNSIGNED_INT_SAMPLER_CUBE:
294 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400295 case GL_SAMPLER_2D_SHADOW:
296 case GL_SAMPLER_CUBE_SHADOW:
297 case GL_SAMPLER_2D_ARRAY_SHADOW:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000298 return 1;
299 case GL_BOOL_VEC2:
300 case GL_FLOAT_VEC2:
301 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000302 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000303 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000304 case GL_FLOAT_MAT2x3:
305 case GL_FLOAT_MAT2x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000306 return 2;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000307 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000308 case GL_FLOAT_VEC3:
309 case GL_INT_VEC3:
310 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000311 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000312 case GL_FLOAT_MAT3x2:
313 case GL_FLOAT_MAT3x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000314 return 3;
315 case GL_BOOL_VEC4:
316 case GL_FLOAT_VEC4:
317 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000318 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000319 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000320 case GL_FLOAT_MAT4x2:
321 case GL_FLOAT_MAT4x3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000322 return 4;
323 default:
324 UNREACHABLE();
325 }
326
327 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000328}
329
Geoff Lang2ec386b2014-12-03 14:44:38 -0500330bool IsSamplerType(GLenum type)
Nicolas Capense6050882013-07-08 10:43:10 -0400331{
332 switch (type)
333 {
334 case GL_SAMPLER_2D:
335 case GL_SAMPLER_3D:
336 case GL_SAMPLER_CUBE:
337 case GL_SAMPLER_2D_ARRAY:
Ian Ewellbda75592016-04-18 17:25:54 -0400338 case GL_SAMPLER_EXTERNAL_OES:
Nicolas Capense6050882013-07-08 10:43:10 -0400339 case GL_INT_SAMPLER_2D:
340 case GL_INT_SAMPLER_3D:
341 case GL_INT_SAMPLER_CUBE:
342 case GL_INT_SAMPLER_2D_ARRAY:
343 case GL_UNSIGNED_INT_SAMPLER_2D:
344 case GL_UNSIGNED_INT_SAMPLER_3D:
345 case GL_UNSIGNED_INT_SAMPLER_CUBE:
346 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
Nicolas Capenscb127d32013-07-15 17:26:18 -0400347 case GL_SAMPLER_2D_SHADOW:
348 case GL_SAMPLER_CUBE_SHADOW:
349 case GL_SAMPLER_2D_ARRAY_SHADOW:
Nicolas Capense6050882013-07-08 10:43:10 -0400350 return true;
351 }
352
353 return false;
354}
355
Geoff Langf51bc792015-05-04 14:57:03 -0400356GLenum SamplerTypeToTextureType(GLenum samplerType)
357{
358 switch (samplerType)
359 {
360 case GL_SAMPLER_2D:
361 case GL_INT_SAMPLER_2D:
362 case GL_UNSIGNED_INT_SAMPLER_2D:
363 case GL_SAMPLER_2D_SHADOW:
364 return GL_TEXTURE_2D;
365
Ian Ewellbda75592016-04-18 17:25:54 -0400366 case GL_SAMPLER_EXTERNAL_OES:
367 return GL_TEXTURE_EXTERNAL_OES;
368
Geoff Langf51bc792015-05-04 14:57:03 -0400369 case GL_SAMPLER_CUBE:
370 case GL_INT_SAMPLER_CUBE:
371 case GL_UNSIGNED_INT_SAMPLER_CUBE:
372 case GL_SAMPLER_CUBE_SHADOW:
373 return GL_TEXTURE_CUBE_MAP;
374
375 case GL_SAMPLER_2D_ARRAY:
376 case GL_INT_SAMPLER_2D_ARRAY:
377 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
378 case GL_SAMPLER_2D_ARRAY_SHADOW:
379 return GL_TEXTURE_2D_ARRAY;
380
381 case GL_SAMPLER_3D:
382 case GL_INT_SAMPLER_3D:
383 case GL_UNSIGNED_INT_SAMPLER_3D:
384 return GL_TEXTURE_3D;
385
386 default:
387 UNREACHABLE();
388 return 0;
389 }
390}
391
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000392bool IsMatrixType(GLenum type)
393{
394 return VariableRowCount(type) > 1;
395}
396
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000397GLenum TransposeMatrixType(GLenum type)
398{
399 if (!IsMatrixType(type))
400 {
401 return type;
402 }
403
404 switch (type)
405 {
406 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
407 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
408 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
409 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
410 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
411 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
412 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
413 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
414 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
415 default: UNREACHABLE(); return GL_NONE;
416 }
417}
418
Jamie Madill8c6befc2013-06-20 11:55:55 -0400419int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
420{
421 ASSERT(IsMatrixType(type));
422 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
423}
424
425int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
426{
427 ASSERT(IsMatrixType(type));
428 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
429}
430
Jamie Madillf2575982014-06-25 16:04:54 -0400431int VariableRegisterCount(GLenum type)
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000432{
433 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
434}
435
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000436int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
437{
438 ASSERT(allocationSize <= bitsSize);
439
440 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
441
442 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
443 {
444 if ((*bits & mask) == 0)
445 {
446 *bits |= mask;
447 return i;
448 }
449
450 mask <<= 1;
451 }
452
453 return -1;
454}
455
Geoff Langd4475812015-03-18 10:53:05 -0400456static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
457static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
458static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
459static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
460static_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 -0500461
462bool IsCubeMapTextureTarget(GLenum target)
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000463{
Geoff Lang691e58c2014-12-19 17:03:25 -0500464 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
465}
466
467size_t CubeMapTextureTargetToLayerIndex(GLenum target)
468{
469 ASSERT(IsCubeMapTextureTarget(target));
470 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
471}
472
473GLenum LayerIndexToCubeMapTextureTarget(size_t index)
474{
475 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
476 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000477}
478
Geoff Lang3edfe032015-09-04 16:38:24 -0400479IndexRange ComputeIndexRange(GLenum indexType,
480 const GLvoid *indices,
481 size_t count,
482 bool primitiveRestartEnabled)
Geoff Lang831b1952015-05-05 11:02:27 -0400483{
484 switch (indexType)
485 {
Geoff Lang3edfe032015-09-04 16:38:24 -0400486 case GL_UNSIGNED_BYTE:
487 return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
488 primitiveRestartEnabled,
489 GetPrimitiveRestartIndex(indexType));
490 case GL_UNSIGNED_SHORT:
491 return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
492 primitiveRestartEnabled,
493 GetPrimitiveRestartIndex(indexType));
494 case GL_UNSIGNED_INT:
495 return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
496 primitiveRestartEnabled,
497 GetPrimitiveRestartIndex(indexType));
498 default:
499 UNREACHABLE();
500 return IndexRange();
501 }
502}
503
504GLuint GetPrimitiveRestartIndex(GLenum indexType)
505{
506 switch (indexType)
507 {
508 case GL_UNSIGNED_BYTE:
509 return 0xFF;
510 case GL_UNSIGNED_SHORT:
511 return 0xFFFF;
512 case GL_UNSIGNED_INT:
513 return 0xFFFFFFFF;
514 default:
515 UNREACHABLE();
516 return 0;
Geoff Lang831b1952015-05-05 11:02:27 -0400517 }
518}
519
daniel@transgaming.com97c852b2012-12-20 20:56:23 +0000520bool IsTriangleMode(GLenum drawMode)
521{
522 switch (drawMode)
523 {
524 case GL_TRIANGLES:
525 case GL_TRIANGLE_FAN:
526 case GL_TRIANGLE_STRIP:
527 return true;
528 case GL_POINTS:
529 case GL_LINES:
530 case GL_LINE_LOOP:
531 case GL_LINE_STRIP:
532 return false;
533 default: UNREACHABLE();
534 }
535
536 return false;
537}
538
Jamie Madill865d1452014-07-02 15:31:20 -0400539// [OpenGL ES SL 3.00.4] Section 11 p. 120
540// Vertex Outs/Fragment Ins packing priorities
541int VariableSortOrder(GLenum type)
542{
543 switch (type)
544 {
545 // 1. Arrays of mat4 and mat4
546 // Non-square matrices of type matCxR consume the same space as a square
547 // matrix of type matN where N is the greater of C and R
548 case GL_FLOAT_MAT4:
549 case GL_FLOAT_MAT2x4:
550 case GL_FLOAT_MAT3x4:
551 case GL_FLOAT_MAT4x2:
552 case GL_FLOAT_MAT4x3:
553 return 0;
554
555 // 2. Arrays of mat2 and mat2 (since they occupy full rows)
556 case GL_FLOAT_MAT2:
557 return 1;
558
559 // 3. Arrays of vec4 and vec4
560 case GL_FLOAT_VEC4:
561 case GL_INT_VEC4:
562 case GL_BOOL_VEC4:
563 case GL_UNSIGNED_INT_VEC4:
564 return 2;
565
566 // 4. Arrays of mat3 and mat3
567 case GL_FLOAT_MAT3:
568 case GL_FLOAT_MAT2x3:
569 case GL_FLOAT_MAT3x2:
570 return 3;
571
572 // 5. Arrays of vec3 and vec3
573 case GL_FLOAT_VEC3:
574 case GL_INT_VEC3:
575 case GL_BOOL_VEC3:
576 case GL_UNSIGNED_INT_VEC3:
577 return 4;
578
579 // 6. Arrays of vec2 and vec2
580 case GL_FLOAT_VEC2:
581 case GL_INT_VEC2:
582 case GL_BOOL_VEC2:
583 case GL_UNSIGNED_INT_VEC2:
584 return 5;
585
586 // 7. Single component types
587 case GL_FLOAT:
588 case GL_INT:
589 case GL_BOOL:
590 case GL_UNSIGNED_INT:
591 case GL_SAMPLER_2D:
592 case GL_SAMPLER_CUBE:
593 case GL_SAMPLER_EXTERNAL_OES:
594 case GL_SAMPLER_2D_RECT_ARB:
595 case GL_SAMPLER_2D_ARRAY:
596 case GL_SAMPLER_3D:
597 case GL_INT_SAMPLER_2D:
598 case GL_INT_SAMPLER_3D:
599 case GL_INT_SAMPLER_CUBE:
600 case GL_INT_SAMPLER_2D_ARRAY:
601 case GL_UNSIGNED_INT_SAMPLER_2D:
602 case GL_UNSIGNED_INT_SAMPLER_3D:
603 case GL_UNSIGNED_INT_SAMPLER_CUBE:
604 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
605 case GL_SAMPLER_2D_SHADOW:
606 case GL_SAMPLER_2D_ARRAY_SHADOW:
607 case GL_SAMPLER_CUBE_SHADOW:
608 return 6;
609
610 default:
611 UNREACHABLE();
612 return 0;
613 }
614}
615
Geoff Langcfaeaa92015-04-14 13:41:02 -0400616std::string ParseUniformName(const std::string &name, size_t *outSubscript)
617{
618 // Strip any trailing array operator and retrieve the subscript
619 size_t open = name.find_last_of('[');
620 size_t close = name.find_last_of(']');
621 bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
622 if (!hasIndex)
623 {
624 if (outSubscript)
625 {
626 *outSubscript = GL_INVALID_INDEX;
627 }
628 return name;
629 }
630
631 if (outSubscript)
632 {
633 int index = atoi(name.substr(open + 1).c_str());
634 if (index >= 0)
635 {
636 *outSubscript = index;
637 }
638 else
639 {
640 *outSubscript = GL_INVALID_INDEX;
641 }
642 }
643
644 return name.substr(0, open);
645}
646
Jamie Madill4a3c2342015-10-08 12:58:45 -0400647unsigned int ParseAndStripArrayIndex(std::string *name)
648{
649 unsigned int subscript = GL_INVALID_INDEX;
650
651 // Strip any trailing array operator and retrieve the subscript
652 size_t open = name->find_last_of('[');
653 size_t close = name->find_last_of(']');
654 if (open != std::string::npos && close == name->length() - 1)
655 {
656 subscript = atoi(name->c_str() + open + 1);
657 name->erase(open);
658 }
659
660 return subscript;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000661}
662
Jamie Madill4a3c2342015-10-08 12:58:45 -0400663} // namespace gl
664
Geoff Langa8406172015-07-21 16:53:39 -0400665namespace egl
666{
667static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
668 "Unexpected EGL cube map enum value.");
669static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
670 "Unexpected EGL cube map enum value.");
671static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
672 "Unexpected EGL cube map enum value.");
673static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
674 "Unexpected EGL cube map enum value.");
675static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
676 "Unexpected EGL cube map enum value.");
677
678bool IsCubeMapTextureTarget(EGLenum target)
679{
680 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
681}
682
683size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
684{
685 ASSERT(IsCubeMapTextureTarget(target));
686 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
687}
688
689EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
690{
691 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
692 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
693}
694
695bool IsTextureTarget(EGLenum target)
696{
697 switch (target)
698 {
699 case EGL_GL_TEXTURE_2D_KHR:
700 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
701 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
702 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
703 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
704 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
705 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
706 case EGL_GL_TEXTURE_3D_KHR:
707 return true;
708
709 default:
710 return false;
711 }
712}
713
714bool IsRenderbufferTarget(EGLenum target)
715{
716 return target == EGL_GL_RENDERBUFFER_KHR;
717}
718}
719
720namespace egl_gl
721{
722GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
723{
724 ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
725 return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
726}
727
728GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
729{
730 switch (eglTarget)
731 {
732 case EGL_GL_TEXTURE_2D_KHR:
733 return GL_TEXTURE_2D;
734
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 return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
742
743 case EGL_GL_TEXTURE_3D_KHR:
744 return GL_TEXTURE_3D;
745
746 default:
747 UNREACHABLE();
748 return GL_NONE;
749 }
750}
751
752GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
753{
754 return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
755}
756}
757
Austin Kinross922a9fb2014-10-21 14:26:33 -0700758#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000759std::string getTempPath()
760{
Shannon Woodsfb839472014-06-16 13:21:41 -0400761#ifdef ANGLE_PLATFORM_WINDOWS
Austin Kinross922a9fb2014-10-21 14:26:33 -0700762 char path[MAX_PATH];
763 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
764 if (pathLen == 0)
765 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000766 UNREACHABLE();
767 return std::string();
Austin Kinross922a9fb2014-10-21 14:26:33 -0700768 }
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000769
Austin Kinross922a9fb2014-10-21 14:26:33 -0700770 UINT unique = GetTempFileNameA(path, "sh", 0, path);
771 if (unique == 0)
772 {
773 UNREACHABLE();
774 return std::string();
775 }
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +0000776
Austin Kinross922a9fb2014-10-21 14:26:33 -0700777 return path;
Geoff Lang83217792014-01-16 09:52:38 -0500778#else
779 UNIMPLEMENTED();
780 return "";
781#endif
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000782}
783
784void writeFile(const char* path, const void* content, size_t size)
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000785{
786 FILE* file = fopen(path, "w");
787 if (!file)
788 {
789 UNREACHABLE();
790 return;
791 }
792
793 fwrite(content, sizeof(char), size, file);
794 fclose(file);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000795}
Austin Kinross922a9fb2014-10-21 14:26:33 -0700796#endif // !ANGLE_ENABLE_WINDOWS_STORE
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700797
Cooper Partin1edac3b2014-11-20 13:49:27 -0800798#if defined (ANGLE_PLATFORM_WINDOWS)
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700799
Cooper Partin1edac3b2014-11-20 13:49:27 -0800800// Causes the thread to relinquish the remainder of its time slice to any
801// other thread that is ready to run.If there are no other threads ready
802// to run, the function returns immediately, and the thread continues execution.
803void ScheduleYield()
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700804{
Geoff Lange5f735f2015-09-17 13:26:59 -0400805 Sleep(0);
Cooper Partin88d3b8c2014-10-08 10:41:56 -0700806}
807
Kenneth Russellb23deb22014-11-21 14:53:56 -0800808#endif