Home | History | Annotate | Download | only in translator
      1 //
      2 // Copyright (c) 2010 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 #include "compiler/translator/util.h"
      8 
      9 #include <limits>
     10 
     11 #include "compiler/preprocessor/numeric_lex.h"
     12 #include "common/utilities.h"
     13 
     14 bool atof_clamp(const char *str, float *value)
     15 {
     16     bool success = pp::numeric_lex_float(str, value);
     17     if (!success)
     18         *value = std::numeric_limits<float>::max();
     19     return success;
     20 }
     21 
     22 bool atoi_clamp(const char *str, int *value)
     23 {
     24     bool success = pp::numeric_lex_int(str, value);
     25     if (!success)
     26         *value = std::numeric_limits<int>::max();
     27     return success;
     28 }
     29 
     30 namespace sh
     31 {
     32 
     33 GLenum GLVariableType(const TType &type)
     34 {
     35     if (type.getBasicType() == EbtFloat)
     36     {
     37         if (type.isScalar())
     38         {
     39             return GL_FLOAT;
     40         }
     41         else if (type.isVector())
     42         {
     43             switch (type.getNominalSize())
     44             {
     45               case 2: return GL_FLOAT_VEC2;
     46               case 3: return GL_FLOAT_VEC3;
     47               case 4: return GL_FLOAT_VEC4;
     48               default: UNREACHABLE();
     49             }
     50         }
     51         else if (type.isMatrix())
     52         {
     53             switch (type.getCols())
     54             {
     55               case 2:
     56                 switch (type.getRows())
     57                 {
     58                   case 2: return GL_FLOAT_MAT2;
     59                   case 3: return GL_FLOAT_MAT2x3;
     60                   case 4: return GL_FLOAT_MAT2x4;
     61                   default: UNREACHABLE();
     62                 }
     63 
     64               case 3:
     65                 switch (type.getRows())
     66                 {
     67                   case 2: return GL_FLOAT_MAT3x2;
     68                   case 3: return GL_FLOAT_MAT3;
     69                   case 4: return GL_FLOAT_MAT3x4;
     70                   default: UNREACHABLE();
     71                 }
     72 
     73               case 4:
     74                 switch (type.getRows())
     75                 {
     76                   case 2: return GL_FLOAT_MAT4x2;
     77                   case 3: return GL_FLOAT_MAT4x3;
     78                   case 4: return GL_FLOAT_MAT4;
     79                   default: UNREACHABLE();
     80                 }
     81 
     82               default: UNREACHABLE();
     83             }
     84         }
     85         else UNREACHABLE();
     86     }
     87     else if (type.getBasicType() == EbtInt)
     88     {
     89         if (type.isScalar())
     90         {
     91             return GL_INT;
     92         }
     93         else if (type.isVector())
     94         {
     95             switch (type.getNominalSize())
     96             {
     97               case 2: return GL_INT_VEC2;
     98               case 3: return GL_INT_VEC3;
     99               case 4: return GL_INT_VEC4;
    100               default: UNREACHABLE();
    101             }
    102         }
    103         else UNREACHABLE();
    104     }
    105     else if (type.getBasicType() == EbtUInt)
    106     {
    107         if (type.isScalar())
    108         {
    109             return GL_UNSIGNED_INT;
    110         }
    111         else if (type.isVector())
    112         {
    113             switch (type.getNominalSize())
    114             {
    115               case 2: return GL_UNSIGNED_INT_VEC2;
    116               case 3: return GL_UNSIGNED_INT_VEC3;
    117               case 4: return GL_UNSIGNED_INT_VEC4;
    118               default: UNREACHABLE();
    119             }
    120         }
    121         else UNREACHABLE();
    122     }
    123     else if (type.getBasicType() == EbtBool)
    124     {
    125         if (type.isScalar())
    126         {
    127             return GL_BOOL;
    128         }
    129         else if (type.isVector())
    130         {
    131             switch (type.getNominalSize())
    132             {
    133               case 2: return GL_BOOL_VEC2;
    134               case 3: return GL_BOOL_VEC3;
    135               case 4: return GL_BOOL_VEC4;
    136               default: UNREACHABLE();
    137             }
    138         }
    139         else UNREACHABLE();
    140     }
    141 
    142     switch (type.getBasicType())
    143     {
    144       case EbtSampler2D:            return GL_SAMPLER_2D;
    145       case EbtSampler3D:            return GL_SAMPLER_3D;
    146       case EbtSamplerCube:          return GL_SAMPLER_CUBE;
    147       case EbtSamplerExternalOES:   return GL_SAMPLER_EXTERNAL_OES;
    148       case EbtSampler2DRect:        return GL_SAMPLER_2D_RECT_ARB;
    149       case EbtSampler2DArray:       return GL_SAMPLER_2D_ARRAY;
    150       case EbtISampler2D:           return GL_INT_SAMPLER_2D;
    151       case EbtISampler3D:           return GL_INT_SAMPLER_3D;
    152       case EbtISamplerCube:         return GL_INT_SAMPLER_CUBE;
    153       case EbtISampler2DArray:      return GL_INT_SAMPLER_2D_ARRAY;
    154       case EbtUSampler2D:           return GL_UNSIGNED_INT_SAMPLER_2D;
    155       case EbtUSampler3D:           return GL_UNSIGNED_INT_SAMPLER_3D;
    156       case EbtUSamplerCube:         return GL_UNSIGNED_INT_SAMPLER_CUBE;
    157       case EbtUSampler2DArray:      return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
    158       case EbtSampler2DShadow:      return GL_SAMPLER_2D_SHADOW;
    159       case EbtSamplerCubeShadow:    return GL_SAMPLER_CUBE_SHADOW;
    160       case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
    161       default: UNREACHABLE();
    162     }
    163 
    164     return GL_NONE;
    165 }
    166 
    167 GLenum GLVariablePrecision(const TType &type)
    168 {
    169     if (type.getBasicType() == EbtFloat)
    170     {
    171         switch (type.getPrecision())
    172         {
    173           case EbpHigh:
    174             return GL_HIGH_FLOAT;
    175           case EbpMedium:
    176             return GL_MEDIUM_FLOAT;
    177           case EbpLow:
    178             return GL_LOW_FLOAT;
    179           case EbpUndefined:
    180           // Should be defined as the default precision by the parser
    181           default:
    182             UNREACHABLE();
    183         }
    184     }
    185     else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
    186     {
    187         switch (type.getPrecision())
    188         {
    189           case EbpHigh:
    190             return GL_HIGH_INT;
    191           case EbpMedium:
    192             return GL_MEDIUM_INT;
    193           case EbpLow:
    194             return GL_LOW_INT;
    195           case EbpUndefined:
    196           // Should be defined as the default precision by the parser
    197           default:
    198             UNREACHABLE();
    199         }
    200     }
    201 
    202     // Other types (boolean, sampler) don't have a precision
    203     return GL_NONE;
    204 }
    205 
    206 TString ArrayString(const TType &type)
    207 {
    208     if (!type.isArray())
    209     {
    210         return "";
    211     }
    212 
    213     return "[" + str(type.getArraySize()) + "]";
    214 }
    215 
    216 bool IsVaryingOut(TQualifier qualifier)
    217 {
    218     switch (qualifier)
    219     {
    220       case EvqVaryingOut:
    221       case EvqInvariantVaryingOut:
    222       case EvqSmoothOut:
    223       case EvqFlatOut:
    224       case EvqCentroidOut:
    225       case EvqVertexOut:
    226         return true;
    227 
    228       default: break;
    229     }
    230 
    231     return false;
    232 }
    233 
    234 bool IsVaryingIn(TQualifier qualifier)
    235 {
    236     switch (qualifier)
    237     {
    238       case EvqVaryingIn:
    239       case EvqInvariantVaryingIn:
    240       case EvqSmoothIn:
    241       case EvqFlatIn:
    242       case EvqCentroidIn:
    243       case EvqFragmentIn:
    244         return true;
    245 
    246       default: break;
    247     }
    248 
    249     return false;
    250 }
    251 
    252 bool IsVarying(TQualifier qualifier)
    253 {
    254     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
    255 }
    256 
    257 InterpolationType GetInterpolationType(TQualifier qualifier)
    258 {
    259     switch (qualifier)
    260     {
    261       case EvqFlatIn:
    262       case EvqFlatOut:
    263         return INTERPOLATION_FLAT;
    264 
    265       case EvqSmoothIn:
    266       case EvqSmoothOut:
    267       case EvqVertexOut:
    268       case EvqFragmentIn:
    269       case EvqVaryingIn:
    270       case EvqVaryingOut:
    271       case EvqInvariantVaryingIn:
    272       case EvqInvariantVaryingOut:
    273         return INTERPOLATION_SMOOTH;
    274 
    275       case EvqCentroidIn:
    276       case EvqCentroidOut:
    277         return INTERPOLATION_CENTROID;
    278 
    279       default: UNREACHABLE();
    280         return INTERPOLATION_SMOOTH;
    281     }
    282 }
    283 
    284 template <typename VarT>
    285 void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
    286 {
    287     const TStructure *structure = type.getStruct();
    288 
    289     VarT variable;
    290     variable.name = name.c_str();
    291     variable.arraySize = static_cast<unsigned int>(type.getArraySize());
    292 
    293     if (!structure)
    294     {
    295         variable.type = GLVariableType(type);
    296         variable.precision = GLVariablePrecision(type);
    297     }
    298     else
    299     {
    300         // Note: this enum value is not exposed outside ANGLE
    301         variable.type = GL_STRUCT_ANGLEX;
    302         variable.structName = structure->name().c_str();
    303 
    304         const TFieldList &fields = structure->fields();
    305 
    306         for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
    307         {
    308             TField *field = fields[fieldIndex];
    309             traverse(*field->type(), field->name(), &variable.fields);
    310         }
    311     }
    312 
    313     visitVariable(&variable);
    314 
    315     ASSERT(output);
    316     output->push_back(variable);
    317 }
    318 
    319 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
    320 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
    321 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
    322 
    323 }
    324