blob: fa4a76719e6b92bdd4facf8e0fef76710e7d61f0 [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:
167 case GL_BOOL_VEC2:
168 case GL_FLOAT_VEC2:
169 case GL_INT_VEC2:
170 case GL_INT_VEC3:
171 case GL_FLOAT_VEC3:
172 case GL_BOOL_VEC3:
173 case GL_BOOL_VEC4:
174 case GL_FLOAT_VEC4:
175 case GL_INT_VEC4:
daniel@transgaming.comda8d3802012-12-20 21:12:55 +0000176 case GL_SAMPLER_2D:
177 case GL_SAMPLER_CUBE:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000178 return 1;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000179 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000180 case GL_FLOAT_MAT3x2:
181 case GL_FLOAT_MAT4x2:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000182 return 2;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000183 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000184 case GL_FLOAT_MAT2x3:
185 case GL_FLOAT_MAT4x3:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000186 return 3;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000187 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000188 case GL_FLOAT_MAT2x4:
189 case GL_FLOAT_MAT3x4:
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000190 return 4;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000191 default:
192 UNREACHABLE();
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000193 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000194
195 return 0;
196}
197
198int VariableColumnCount(GLenum type)
199{
200 switch (type)
201 {
202 case GL_NONE:
203 return 0;
204 case GL_BOOL:
205 case GL_FLOAT:
206 case GL_INT:
shannon.woods@transgaming.com2494c972013-02-28 23:10:03 +0000207 case GL_SAMPLER_2D:
208 case GL_SAMPLER_CUBE:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000209 return 1;
210 case GL_BOOL_VEC2:
211 case GL_FLOAT_VEC2:
212 case GL_INT_VEC2:
213 case GL_FLOAT_MAT2:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000214 case GL_FLOAT_MAT2x3:
215 case GL_FLOAT_MAT2x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000216 return 2;
217 case GL_INT_VEC3:
218 case GL_FLOAT_VEC3:
219 case GL_BOOL_VEC3:
220 case GL_FLOAT_MAT3:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000221 case GL_FLOAT_MAT3x2:
222 case GL_FLOAT_MAT3x4:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000223 return 3;
224 case GL_BOOL_VEC4:
225 case GL_FLOAT_VEC4:
226 case GL_INT_VEC4:
227 case GL_FLOAT_MAT4:
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000228 case GL_FLOAT_MAT4x2:
229 case GL_FLOAT_MAT4x3:
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000230 return 4;
231 default:
232 UNREACHABLE();
233 }
234
235 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000236}
237
shannon.woods%transgaming.com@gtempaccount.com02e11f32013-04-13 03:40:50 +0000238bool IsMatrixType(GLenum type)
239{
240 return VariableRowCount(type) > 1;
241}
242
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000243GLenum TransposeMatrixType(GLenum type)
244{
245 if (!IsMatrixType(type))
246 {
247 return type;
248 }
249
250 switch (type)
251 {
252 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
253 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
254 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
255 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
256 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
257 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
258 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
259 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
260 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
261 default: UNREACHABLE(); return GL_NONE;
262 }
263}
264
265int AttributeRegisterCount(GLenum type)
266{
267 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
268}
269
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000270int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
271{
272 ASSERT(allocationSize <= bitsSize);
273
274 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
275
276 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
277 {
278 if ((*bits & mask) == 0)
279 {
280 *bits |= mask;
281 return i;
282 }
283
284 mask <<= 1;
285 }
286
287 return -1;
288}
289
daniel@transgaming.com8e91d252012-10-17 18:22:44 +0000290bool IsStencilTexture(GLenum format)
291{
292 if (format == GL_DEPTH_STENCIL_OES ||
293 format == GL_DEPTH24_STENCIL8_OES)
294 {
295 return true;
296 }
297
298 return false;
299}
300
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000301void MakeValidSize(bool isImage, bool isCompressed, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
302{
303 int upsampleCount = 0;
304
305 if (isCompressed)
306 {
307 // Don't expand the size of full textures that are at least 4x4
308 // already.
309 if (isImage || *requestWidth < 4 || *requestHeight < 4)
310 {
311 while (*requestWidth % 4 != 0 || *requestHeight % 4 != 0)
312 {
313 *requestWidth <<= 1;
314 *requestHeight <<= 1;
315 upsampleCount++;
316 }
317 }
318 }
319 *levelOffset = upsampleCount;
320}
321
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000322// Returns the size, in bytes, of a single texel in an Image
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000323int ComputePixelSize(GLint internalformat)
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000324{
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000325 switch (internalformat)
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000326 {
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000327 case GL_ALPHA8_EXT: return sizeof(unsigned char);
328 case GL_LUMINANCE8_EXT: return sizeof(unsigned char);
329 case GL_ALPHA32F_EXT: return sizeof(float);
330 case GL_LUMINANCE32F_EXT: return sizeof(float);
331 case GL_ALPHA16F_EXT: return sizeof(unsigned short);
332 case GL_LUMINANCE16F_EXT: return sizeof(unsigned short);
333 case GL_LUMINANCE8_ALPHA8_EXT: return sizeof(unsigned char) * 2;
334 case GL_LUMINANCE_ALPHA32F_EXT: return sizeof(float) * 2;
335 case GL_LUMINANCE_ALPHA16F_EXT: return sizeof(unsigned short) * 2;
336 case GL_RGB8_OES: return sizeof(unsigned char) * 3;
337 case GL_RGB565: return sizeof(unsigned short);
338 case GL_RGB32F_EXT: return sizeof(float) * 3;
339 case GL_RGB16F_EXT: return sizeof(unsigned short) * 3;
340 case GL_RGBA8_OES: return sizeof(unsigned char) * 4;
341 case GL_RGBA4: return sizeof(unsigned short);
342 case GL_RGB5_A1: return sizeof(unsigned short);
343 case GL_RGBA32F_EXT: return sizeof(float) * 4;
344 case GL_RGBA16F_EXT: return sizeof(unsigned short) * 4;
345 case GL_BGRA8_EXT: return sizeof(unsigned char) * 4;
shannon.woods%transgaming.com@gtempaccount.com8dce6512013-04-13 03:42:19 +0000346 case GL_SRGB8_ALPHA8: return sizeof(unsigned char) * 4;
347 case GL_RGB10_A2: return sizeof(unsigned char) * 4;
348 case GL_RG8: return sizeof(unsigned char) * 2;
349 case GL_R8: return sizeof(unsigned char);
daniel@transgaming.com6b1a0a02012-10-17 18:22:47 +0000350 case GL_BGRA4_ANGLEX: return sizeof(unsigned short);
351 case GL_BGR5_A1_ANGLEX: return sizeof(unsigned short);
shannon.woods%transgaming.com@gtempaccount.com8dce6512013-04-13 03:42:19 +0000352 default:
353 UNIMPLEMENTED(); // TODO: Remaining ES3 formats
354 UNREACHABLE();
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000355 }
356
357 return 0;
358}
359
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000360bool IsCubemapTextureTarget(GLenum target)
361{
362 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
363}
364
apatrick@chromium.org551022e2012-01-23 19:56:54 +0000365bool IsInternalTextureTarget(GLenum target)
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000366{
367 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
368}
369
daniel@transgaming.com97c852b2012-12-20 20:56:23 +0000370bool IsTriangleMode(GLenum drawMode)
371{
372 switch (drawMode)
373 {
374 case GL_TRIANGLES:
375 case GL_TRIANGLE_FAN:
376 case GL_TRIANGLE_STRIP:
377 return true;
378 case GL_POINTS:
379 case GL_LINES:
380 case GL_LINE_LOOP:
381 case GL_LINE_STRIP:
382 return false;
383 default: UNREACHABLE();
384 }
385
386 return false;
387}
388
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000389}
390
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000391std::string getTempPath()
392{
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000393 char path[MAX_PATH];
394 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
395 if (pathLen == 0)
396 {
397 UNREACHABLE();
398 return std::string();
399 }
400
401 UINT unique = GetTempFileNameA(path, "sh", 0, path);
402 if (unique == 0)
403 {
404 UNREACHABLE();
405 return std::string();
406 }
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +0000407
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000408 return path;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000409}
410
411void writeFile(const char* path, const void* content, size_t size)
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000412{
413 FILE* file = fopen(path, "w");
414 if (!file)
415 {
416 UNREACHABLE();
417 return;
418 }
419
420 fwrite(content, sizeof(char), size, file);
421 fclose(file);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000422}