blob: ad0325070252856c9cc6b58531e09e6737b8a47f [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"
11
12#include <set>
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000013
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000014namespace gl
15{
16
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +000017int UniformComponentCount(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000018{
19 switch (type)
20 {
21 case GL_BOOL:
22 case GL_FLOAT:
23 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000024 case GL_SAMPLER_2D:
25 case GL_SAMPLER_CUBE:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +000026 case GL_UNSIGNED_INT:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000027 return 1;
28 case GL_BOOL_VEC2:
29 case GL_FLOAT_VEC2:
30 case GL_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +000031 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000032 return 2;
33 case GL_INT_VEC3:
34 case GL_FLOAT_VEC3:
35 case GL_BOOL_VEC3:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +000036 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000037 return 3;
38 case GL_BOOL_VEC4:
39 case GL_FLOAT_VEC4:
40 case GL_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +000041 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000042 case GL_FLOAT_MAT2:
43 return 4;
shannon.woods%transgaming.com@gtempaccount.come6ca6702013-04-13 03:40:44 +000044 case GL_FLOAT_MAT2x3:
45 case GL_FLOAT_MAT3x2:
46 return 6;
47 case GL_FLOAT_MAT2x4:
48 case GL_FLOAT_MAT4x2:
49 return 8;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000050 case GL_FLOAT_MAT3:
51 return 9;
shannon.woods%transgaming.com@gtempaccount.come6ca6702013-04-13 03:40:44 +000052 case GL_FLOAT_MAT3x4:
53 case GL_FLOAT_MAT4x3:
54 return 12;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000055 case GL_FLOAT_MAT4:
56 return 16;
57 default:
58 UNREACHABLE();
59 }
60
61 return 0;
62}
63
64GLenum UniformComponentType(GLenum type)
65{
66 switch(type)
67 {
68 case GL_BOOL:
69 case GL_BOOL_VEC2:
70 case GL_BOOL_VEC3:
71 case GL_BOOL_VEC4:
72 return GL_BOOL;
73 case GL_FLOAT:
74 case GL_FLOAT_VEC2:
75 case GL_FLOAT_VEC3:
76 case GL_FLOAT_VEC4:
77 case GL_FLOAT_MAT2:
78 case GL_FLOAT_MAT3:
79 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.come6ca6702013-04-13 03:40:44 +000080 case GL_FLOAT_MAT2x3:
81 case GL_FLOAT_MAT3x2:
82 case GL_FLOAT_MAT2x4:
83 case GL_FLOAT_MAT4x2:
84 case GL_FLOAT_MAT3x4:
85 case GL_FLOAT_MAT4x3:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000086 return GL_FLOAT;
87 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000088 case GL_SAMPLER_2D:
89 case GL_SAMPLER_CUBE:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000090 case GL_INT_VEC2:
91 case GL_INT_VEC3:
92 case GL_INT_VEC4:
93 return GL_INT;
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +000094 case GL_UNSIGNED_INT:
95 case GL_UNSIGNED_INT_VEC2:
96 case GL_UNSIGNED_INT_VEC3:
97 case GL_UNSIGNED_INT_VEC4:
98 return GL_UNSIGNED_INT;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000099 default:
100 UNREACHABLE();
101 }
102
103 return GL_NONE;
104}
105
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000106size_t UniformComponentSize(GLenum type)
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000107{
108 switch(type)
109 {
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000110 case GL_BOOL: return sizeof(GLint);
111 case GL_FLOAT: return sizeof(GLfloat);
112 case GL_INT: return sizeof(GLint);
113 case GL_UNSIGNED_INT: return sizeof(GLuint);
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000114 default: UNREACHABLE();
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000115 }
116
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000117 return 0;
118}
119
daniel@transgaming.come918ea22011-11-12 03:15:28 +0000120size_t UniformInternalSize(GLenum type)
jbauman@chromium.org72e8f442011-10-20 00:22:01 +0000121{
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000122 // Expanded to 4-element vectors
123 return UniformComponentSize(UniformComponentType(type)) * VariableRowCount(type) * 4;
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000124}
125
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000126size_t UniformExternalSize(GLenum type)
127{
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000128 return UniformComponentSize(UniformComponentType(type)) * UniformComponentCount(type);
daniel@transgaming.com47c60052011-11-12 03:17:50 +0000129}
130
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000131GLenum UniformBoolVectorType(GLenum type)
132{
133 switch (type)
134 {
135 case GL_FLOAT:
136 case GL_INT:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000137 case GL_UNSIGNED_INT:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000138 return GL_BOOL;
139 case GL_FLOAT_VEC2:
140 case GL_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000141 case GL_UNSIGNED_INT_VEC2:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000142 return GL_BOOL_VEC2;
143 case GL_FLOAT_VEC3:
144 case GL_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000145 case GL_UNSIGNED_INT_VEC3:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000146 return GL_BOOL_VEC3;
147 case GL_FLOAT_VEC4:
148 case GL_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com44ce5b12013-04-13 03:40:30 +0000149 case GL_UNSIGNED_INT_VEC4:
shannon.woods%transgaming.com@gtempaccount.com8a19eed2013-04-13 03:40:22 +0000150 return GL_BOOL_VEC4;
151
152 default:
153 UNREACHABLE();
154 return GL_NONE;
155 }
156}
157
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000158int VariableRowCount(GLenum type)
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000159{
160 switch (type)
161 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000162 case GL_NONE:
163 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000164 case GL_BOOL:
165 case GL_FLOAT:
166 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000167 case GL_UNSIGNED_INT:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000168 case GL_BOOL_VEC2:
169 case GL_FLOAT_VEC2:
170 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000171 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000172 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000173 case GL_FLOAT_VEC3:
174 case GL_INT_VEC3:
175 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000176 case GL_BOOL_VEC4:
177 case GL_FLOAT_VEC4:
178 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000179 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000180 case GL_SAMPLER_2D:
181 case GL_SAMPLER_CUBE:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000182 return 1;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000183 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000184 case GL_FLOAT_MAT3x2:
185 case GL_FLOAT_MAT4x2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000186 return 2;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000187 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000188 case GL_FLOAT_MAT2x3:
189 case GL_FLOAT_MAT4x3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000190 return 3;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000191 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000192 case GL_FLOAT_MAT2x4:
193 case GL_FLOAT_MAT3x4:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000194 return 4;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000195 default:
196 UNREACHABLE();
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000197 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000198
199 return 0;
200}
201
202int VariableColumnCount(GLenum type)
203{
204 switch (type)
205 {
206 case GL_NONE:
207 return 0;
208 case GL_BOOL:
209 case GL_FLOAT:
210 case GL_INT:
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000211 case GL_UNSIGNED_INT:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000212 case GL_SAMPLER_2D:
213 case GL_SAMPLER_CUBE:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000214 return 1;
215 case GL_BOOL_VEC2:
216 case GL_FLOAT_VEC2:
217 case GL_INT_VEC2:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000218 case GL_UNSIGNED_INT_VEC2:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000219 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000220 case GL_FLOAT_MAT2x3:
221 case GL_FLOAT_MAT2x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000222 return 2;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000223 case GL_BOOL_VEC3:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000224 case GL_FLOAT_VEC3:
225 case GL_INT_VEC3:
226 case GL_UNSIGNED_INT_VEC3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000227 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000228 case GL_FLOAT_MAT3x2:
229 case GL_FLOAT_MAT3x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000230 return 3;
231 case GL_BOOL_VEC4:
232 case GL_FLOAT_VEC4:
233 case GL_INT_VEC4:
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000234 case GL_UNSIGNED_INT_VEC4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000235 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000236 case GL_FLOAT_MAT4x2:
237 case GL_FLOAT_MAT4x3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000238 return 4;
239 default:
240 UNREACHABLE();
241 }
242
243 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000244}
245
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000246bool IsMatrixType(GLenum type)
247{
248 return VariableRowCount(type) > 1;
249}
250
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000251GLenum TransposeMatrixType(GLenum type)
252{
253 if (!IsMatrixType(type))
254 {
255 return type;
256 }
257
258 switch (type)
259 {
260 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
261 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
262 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
263 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
264 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
265 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
266 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
267 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
268 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
269 default: UNREACHABLE(); return GL_NONE;
270 }
271}
272
Jamie Madill8c6befc2013-06-20 11:55:55 -0400273int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
274{
275 ASSERT(IsMatrixType(type));
276 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
277}
278
279int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
280{
281 ASSERT(IsMatrixType(type));
282 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
283}
284
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000285int AttributeRegisterCount(GLenum type)
286{
287 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
288}
289
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000290int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
291{
292 ASSERT(allocationSize <= bitsSize);
293
294 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
295
296 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
297 {
298 if ((*bits & mask) == 0)
299 {
300 *bits |= mask;
301 return i;
302 }
303
304 mask <<= 1;
305 }
306
307 return -1;
308}
309
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000310bool IsStencilTexture(GLenum format)
311{
312 if (format == GL_DEPTH_STENCIL_OES ||
313 format == GL_DEPTH24_STENCIL8_OES)
314 {
315 return true;
316 }
317
318 return false;
319}
320
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000321void MakeValidSize(bool isImage, bool isCompressed, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
322{
323 int upsampleCount = 0;
324
325 if (isCompressed)
326 {
327 // Don't expand the size of full textures that are at least 4x4
328 // already.
329 if (isImage || *requestWidth < 4 || *requestHeight < 4)
330 {
331 while (*requestWidth % 4 != 0 || *requestHeight % 4 != 0)
332 {
333 *requestWidth <<= 1;
334 *requestHeight <<= 1;
335 upsampleCount++;
336 }
337 }
338 }
339 *levelOffset = upsampleCount;
340}
341
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000342// Returns the size, in bytes, of a single texel in an Image
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000343int ComputePixelSize(GLint internalformat)
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000344{
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000345 switch (internalformat)
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000346 {
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000347 case GL_ALPHA8_EXT: return sizeof(unsigned char);
348 case GL_LUMINANCE8_EXT: return sizeof(unsigned char);
349 case GL_ALPHA32F_EXT: return sizeof(float);
350 case GL_LUMINANCE32F_EXT: return sizeof(float);
351 case GL_ALPHA16F_EXT: return sizeof(unsigned short);
352 case GL_LUMINANCE16F_EXT: return sizeof(unsigned short);
353 case GL_LUMINANCE8_ALPHA8_EXT: return sizeof(unsigned char) * 2;
354 case GL_LUMINANCE_ALPHA32F_EXT: return sizeof(float) * 2;
355 case GL_LUMINANCE_ALPHA16F_EXT: return sizeof(unsigned short) * 2;
356 case GL_RGB8_OES: return sizeof(unsigned char) * 3;
357 case GL_RGB565: return sizeof(unsigned short);
358 case GL_RGB32F_EXT: return sizeof(float) * 3;
359 case GL_RGB16F_EXT: return sizeof(unsigned short) * 3;
360 case GL_RGBA8_OES: return sizeof(unsigned char) * 4;
361 case GL_RGBA4: return sizeof(unsigned short);
362 case GL_RGB5_A1: return sizeof(unsigned short);
363 case GL_RGBA32F_EXT: return sizeof(float) * 4;
364 case GL_RGBA16F_EXT: return sizeof(unsigned short) * 4;
365 case GL_BGRA8_EXT: return sizeof(unsigned char) * 4;
shannon.woods%transgaming.com@gtempaccount.com8dce6512013-04-13 03:42:19 +0000366 case GL_SRGB8_ALPHA8: return sizeof(unsigned char) * 4;
367 case GL_RGB10_A2: return sizeof(unsigned char) * 4;
368 case GL_RG8: return sizeof(unsigned char) * 2;
369 case GL_R8: return sizeof(unsigned char);
daniel@transgaming.com6b1a0a02012-10-17 18:22:47 +0000370 case GL_BGRA4_ANGLEX: return sizeof(unsigned short);
371 case GL_BGR5_A1_ANGLEX: return sizeof(unsigned short);
shannon.woods%transgaming.com@gtempaccount.com8dce6512013-04-13 03:42:19 +0000372 default:
373 UNIMPLEMENTED(); // TODO: Remaining ES3 formats
374 UNREACHABLE();
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000375 }
376
377 return 0;
378}
379
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000380bool IsCubemapTextureTarget(GLenum target)
381{
382 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
383}
384
apatrick@chromium.org551022e2012-01-23 19:56:54 +0000385bool IsInternalTextureTarget(GLenum target)
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000386{
387 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
388}
389
daniel@transgaming.com97c852b2012-12-20 20:56:23 +0000390bool IsTriangleMode(GLenum drawMode)
391{
392 switch (drawMode)
393 {
394 case GL_TRIANGLES:
395 case GL_TRIANGLE_FAN:
396 case GL_TRIANGLE_STRIP:
397 return true;
398 case GL_POINTS:
399 case GL_LINES:
400 case GL_LINE_LOOP:
401 case GL_LINE_STRIP:
402 return false;
403 default: UNREACHABLE();
404 }
405
406 return false;
407}
408
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000409}
410
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000411std::string getTempPath()
412{
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000413 char path[MAX_PATH];
414 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
415 if (pathLen == 0)
416 {
417 UNREACHABLE();
418 return std::string();
419 }
420
421 UINT unique = GetTempFileNameA(path, "sh", 0, path);
422 if (unique == 0)
423 {
424 UNREACHABLE();
425 return std::string();
426 }
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +0000427
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000428 return path;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000429}
430
431void writeFile(const char* path, const void* content, size_t size)
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000432{
433 FILE* file = fopen(path, "w");
434 if (!file)
435 {
436 UNREACHABLE();
437 return;
438 }
439
440 fwrite(content, sizeof(char), size, file);
441 fclose(file);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000442}