1 // 2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. 3 // 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 9 #include "common/utilities.h" 10 #include "common/mathutil.h" 11 12 #if defined(_WIN32) 13 #include <windows.h> 14 #endif 15 16 #include <set> 17 18 namespace gl 19 { 20 21 int UniformComponentCount(GLenum type) 22 { 23 switch (type) 24 { 25 case GL_BOOL: 26 case GL_FLOAT: 27 case GL_INT: 28 case GL_SAMPLER_2D: 29 case GL_SAMPLER_3D: 30 case GL_SAMPLER_CUBE: 31 case GL_SAMPLER_2D_ARRAY: 32 case GL_INT_SAMPLER_2D: 33 case GL_INT_SAMPLER_3D: 34 case GL_INT_SAMPLER_CUBE: 35 case GL_INT_SAMPLER_2D_ARRAY: 36 case GL_UNSIGNED_INT_SAMPLER_2D: 37 case GL_UNSIGNED_INT_SAMPLER_3D: 38 case GL_UNSIGNED_INT_SAMPLER_CUBE: 39 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 40 case GL_SAMPLER_2D_SHADOW: 41 case GL_SAMPLER_CUBE_SHADOW: 42 case GL_SAMPLER_2D_ARRAY_SHADOW: 43 case GL_UNSIGNED_INT: 44 return 1; 45 case GL_BOOL_VEC2: 46 case GL_FLOAT_VEC2: 47 case GL_INT_VEC2: 48 case GL_UNSIGNED_INT_VEC2: 49 return 2; 50 case GL_INT_VEC3: 51 case GL_FLOAT_VEC3: 52 case GL_BOOL_VEC3: 53 case GL_UNSIGNED_INT_VEC3: 54 return 3; 55 case GL_BOOL_VEC4: 56 case GL_FLOAT_VEC4: 57 case GL_INT_VEC4: 58 case GL_UNSIGNED_INT_VEC4: 59 case GL_FLOAT_MAT2: 60 return 4; 61 case GL_FLOAT_MAT2x3: 62 case GL_FLOAT_MAT3x2: 63 return 6; 64 case GL_FLOAT_MAT2x4: 65 case GL_FLOAT_MAT4x2: 66 return 8; 67 case GL_FLOAT_MAT3: 68 return 9; 69 case GL_FLOAT_MAT3x4: 70 case GL_FLOAT_MAT4x3: 71 return 12; 72 case GL_FLOAT_MAT4: 73 return 16; 74 default: 75 UNREACHABLE(); 76 } 77 78 return 0; 79 } 80 81 GLenum UniformComponentType(GLenum type) 82 { 83 switch(type) 84 { 85 case GL_BOOL: 86 case GL_BOOL_VEC2: 87 case GL_BOOL_VEC3: 88 case GL_BOOL_VEC4: 89 return GL_BOOL; 90 case GL_FLOAT: 91 case GL_FLOAT_VEC2: 92 case GL_FLOAT_VEC3: 93 case GL_FLOAT_VEC4: 94 case GL_FLOAT_MAT2: 95 case GL_FLOAT_MAT3: 96 case GL_FLOAT_MAT4: 97 case GL_FLOAT_MAT2x3: 98 case GL_FLOAT_MAT3x2: 99 case GL_FLOAT_MAT2x4: 100 case GL_FLOAT_MAT4x2: 101 case GL_FLOAT_MAT3x4: 102 case GL_FLOAT_MAT4x3: 103 return GL_FLOAT; 104 case GL_INT: 105 case GL_SAMPLER_2D: 106 case GL_SAMPLER_3D: 107 case GL_SAMPLER_CUBE: 108 case GL_SAMPLER_2D_ARRAY: 109 case GL_INT_SAMPLER_2D: 110 case GL_INT_SAMPLER_3D: 111 case GL_INT_SAMPLER_CUBE: 112 case GL_INT_SAMPLER_2D_ARRAY: 113 case GL_UNSIGNED_INT_SAMPLER_2D: 114 case GL_UNSIGNED_INT_SAMPLER_3D: 115 case GL_UNSIGNED_INT_SAMPLER_CUBE: 116 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 117 case GL_SAMPLER_2D_SHADOW: 118 case GL_SAMPLER_CUBE_SHADOW: 119 case GL_SAMPLER_2D_ARRAY_SHADOW: 120 case GL_INT_VEC2: 121 case GL_INT_VEC3: 122 case GL_INT_VEC4: 123 return GL_INT; 124 case GL_UNSIGNED_INT: 125 case GL_UNSIGNED_INT_VEC2: 126 case GL_UNSIGNED_INT_VEC3: 127 case GL_UNSIGNED_INT_VEC4: 128 return GL_UNSIGNED_INT; 129 default: 130 UNREACHABLE(); 131 } 132 133 return GL_NONE; 134 } 135 136 size_t UniformComponentSize(GLenum type) 137 { 138 switch(type) 139 { 140 case GL_BOOL: return sizeof(GLint); 141 case GL_FLOAT: return sizeof(GLfloat); 142 case GL_INT: return sizeof(GLint); 143 case GL_UNSIGNED_INT: return sizeof(GLuint); 144 default: UNREACHABLE(); 145 } 146 147 return 0; 148 } 149 150 size_t UniformInternalSize(GLenum type) 151 { 152 // Expanded to 4-element vectors 153 return UniformComponentSize(UniformComponentType(type)) * VariableRowCount(type) * 4; 154 } 155 156 size_t UniformExternalSize(GLenum type) 157 { 158 return UniformComponentSize(UniformComponentType(type)) * UniformComponentCount(type); 159 } 160 161 GLenum UniformBoolVectorType(GLenum type) 162 { 163 switch (type) 164 { 165 case GL_FLOAT: 166 case GL_INT: 167 case GL_UNSIGNED_INT: 168 return GL_BOOL; 169 case GL_FLOAT_VEC2: 170 case GL_INT_VEC2: 171 case GL_UNSIGNED_INT_VEC2: 172 return GL_BOOL_VEC2; 173 case GL_FLOAT_VEC3: 174 case GL_INT_VEC3: 175 case GL_UNSIGNED_INT_VEC3: 176 return GL_BOOL_VEC3; 177 case GL_FLOAT_VEC4: 178 case GL_INT_VEC4: 179 case GL_UNSIGNED_INT_VEC4: 180 return GL_BOOL_VEC4; 181 182 default: 183 UNREACHABLE(); 184 return GL_NONE; 185 } 186 } 187 188 int VariableRowCount(GLenum type) 189 { 190 switch (type) 191 { 192 case GL_NONE: 193 case GL_STRUCT_ANGLEX: 194 return 0; 195 case GL_BOOL: 196 case GL_FLOAT: 197 case GL_INT: 198 case GL_UNSIGNED_INT: 199 case GL_BOOL_VEC2: 200 case GL_FLOAT_VEC2: 201 case GL_INT_VEC2: 202 case GL_UNSIGNED_INT_VEC2: 203 case GL_BOOL_VEC3: 204 case GL_FLOAT_VEC3: 205 case GL_INT_VEC3: 206 case GL_UNSIGNED_INT_VEC3: 207 case GL_BOOL_VEC4: 208 case GL_FLOAT_VEC4: 209 case GL_INT_VEC4: 210 case GL_UNSIGNED_INT_VEC4: 211 case GL_SAMPLER_2D: 212 case GL_SAMPLER_3D: 213 case GL_SAMPLER_CUBE: 214 case GL_SAMPLER_2D_ARRAY: 215 case GL_INT_SAMPLER_2D: 216 case GL_INT_SAMPLER_3D: 217 case GL_INT_SAMPLER_CUBE: 218 case GL_INT_SAMPLER_2D_ARRAY: 219 case GL_UNSIGNED_INT_SAMPLER_2D: 220 case GL_UNSIGNED_INT_SAMPLER_3D: 221 case GL_UNSIGNED_INT_SAMPLER_CUBE: 222 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 223 case GL_SAMPLER_2D_SHADOW: 224 case GL_SAMPLER_CUBE_SHADOW: 225 case GL_SAMPLER_2D_ARRAY_SHADOW: 226 return 1; 227 case GL_FLOAT_MAT2: 228 case GL_FLOAT_MAT3x2: 229 case GL_FLOAT_MAT4x2: 230 return 2; 231 case GL_FLOAT_MAT3: 232 case GL_FLOAT_MAT2x3: 233 case GL_FLOAT_MAT4x3: 234 return 3; 235 case GL_FLOAT_MAT4: 236 case GL_FLOAT_MAT2x4: 237 case GL_FLOAT_MAT3x4: 238 return 4; 239 default: 240 UNREACHABLE(); 241 } 242 243 return 0; 244 } 245 246 int VariableColumnCount(GLenum type) 247 { 248 switch (type) 249 { 250 case GL_NONE: 251 case GL_STRUCT_ANGLEX: 252 return 0; 253 case GL_BOOL: 254 case GL_FLOAT: 255 case GL_INT: 256 case GL_UNSIGNED_INT: 257 case GL_SAMPLER_2D: 258 case GL_SAMPLER_3D: 259 case GL_SAMPLER_CUBE: 260 case GL_SAMPLER_2D_ARRAY: 261 case GL_INT_SAMPLER_2D: 262 case GL_INT_SAMPLER_3D: 263 case GL_INT_SAMPLER_CUBE: 264 case GL_INT_SAMPLER_2D_ARRAY: 265 case GL_UNSIGNED_INT_SAMPLER_2D: 266 case GL_UNSIGNED_INT_SAMPLER_3D: 267 case GL_UNSIGNED_INT_SAMPLER_CUBE: 268 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 269 case GL_SAMPLER_2D_SHADOW: 270 case GL_SAMPLER_CUBE_SHADOW: 271 case GL_SAMPLER_2D_ARRAY_SHADOW: 272 return 1; 273 case GL_BOOL_VEC2: 274 case GL_FLOAT_VEC2: 275 case GL_INT_VEC2: 276 case GL_UNSIGNED_INT_VEC2: 277 case GL_FLOAT_MAT2: 278 case GL_FLOAT_MAT2x3: 279 case GL_FLOAT_MAT2x4: 280 return 2; 281 case GL_BOOL_VEC3: 282 case GL_FLOAT_VEC3: 283 case GL_INT_VEC3: 284 case GL_UNSIGNED_INT_VEC3: 285 case GL_FLOAT_MAT3: 286 case GL_FLOAT_MAT3x2: 287 case GL_FLOAT_MAT3x4: 288 return 3; 289 case GL_BOOL_VEC4: 290 case GL_FLOAT_VEC4: 291 case GL_INT_VEC4: 292 case GL_UNSIGNED_INT_VEC4: 293 case GL_FLOAT_MAT4: 294 case GL_FLOAT_MAT4x2: 295 case GL_FLOAT_MAT4x3: 296 return 4; 297 default: 298 UNREACHABLE(); 299 } 300 301 return 0; 302 } 303 304 bool IsSampler(GLenum type) 305 { 306 switch (type) 307 { 308 case GL_SAMPLER_2D: 309 case GL_SAMPLER_3D: 310 case GL_SAMPLER_CUBE: 311 case GL_SAMPLER_2D_ARRAY: 312 case GL_INT_SAMPLER_2D: 313 case GL_INT_SAMPLER_3D: 314 case GL_INT_SAMPLER_CUBE: 315 case GL_INT_SAMPLER_2D_ARRAY: 316 case GL_UNSIGNED_INT_SAMPLER_2D: 317 case GL_UNSIGNED_INT_SAMPLER_3D: 318 case GL_UNSIGNED_INT_SAMPLER_CUBE: 319 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 320 case GL_SAMPLER_2D_SHADOW: 321 case GL_SAMPLER_CUBE_SHADOW: 322 case GL_SAMPLER_2D_ARRAY_SHADOW: 323 return true; 324 } 325 326 return false; 327 } 328 329 bool IsMatrixType(GLenum type) 330 { 331 return VariableRowCount(type) > 1; 332 } 333 334 GLenum TransposeMatrixType(GLenum type) 335 { 336 if (!IsMatrixType(type)) 337 { 338 return type; 339 } 340 341 switch (type) 342 { 343 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2; 344 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3; 345 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4; 346 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2; 347 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3; 348 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2; 349 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4; 350 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3; 351 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4; 352 default: UNREACHABLE(); return GL_NONE; 353 } 354 } 355 356 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix) 357 { 358 ASSERT(IsMatrixType(type)); 359 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type); 360 } 361 362 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix) 363 { 364 ASSERT(IsMatrixType(type)); 365 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type); 366 } 367 368 int AttributeRegisterCount(GLenum type) 369 { 370 return IsMatrixType(type) ? VariableColumnCount(type) : 1; 371 } 372 373 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize) 374 { 375 ASSERT(allocationSize <= bitsSize); 376 377 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize); 378 379 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++) 380 { 381 if ((*bits & mask) == 0) 382 { 383 *bits |= mask; 384 return i; 385 } 386 387 mask <<= 1; 388 } 389 390 return -1; 391 } 392 393 bool IsCubemapTextureTarget(GLenum target) 394 { 395 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); 396 } 397 398 bool IsInternalTextureTarget(GLenum target, GLuint clientVersion) 399 { 400 if (clientVersion == 2) 401 { 402 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target); 403 } 404 else if (clientVersion == 3) 405 { 406 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || 407 target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY; 408 } 409 else 410 { 411 UNREACHABLE(); 412 return false; 413 } 414 } 415 416 bool IsTriangleMode(GLenum drawMode) 417 { 418 switch (drawMode) 419 { 420 case GL_TRIANGLES: 421 case GL_TRIANGLE_FAN: 422 case GL_TRIANGLE_STRIP: 423 return true; 424 case GL_POINTS: 425 case GL_LINES: 426 case GL_LINE_LOOP: 427 case GL_LINE_STRIP: 428 return false; 429 default: UNREACHABLE(); 430 } 431 432 return false; 433 } 434 435 } 436 437 std::string getTempPath() 438 { 439 #if defined (_WIN32) 440 char path[MAX_PATH]; 441 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); 442 if (pathLen == 0) 443 { 444 UNREACHABLE(); 445 return std::string(); 446 } 447 448 UINT unique = GetTempFileNameA(path, "sh", 0, path); 449 if (unique == 0) 450 { 451 UNREACHABLE(); 452 return std::string(); 453 } 454 455 return path; 456 #else 457 UNIMPLEMENTED(); 458 return ""; 459 #endif 460 } 461 462 void writeFile(const char* path, const void* content, size_t size) 463 { 464 FILE* file = fopen(path, "w"); 465 if (!file) 466 { 467 UNREACHABLE(); 468 return; 469 } 470 471 fwrite(content, sizeof(char), size, file); 472 fclose(file); 473 } 474