Home | History | Annotate | Download | only in common
      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