Home | History | Annotate | Download | only in compiler
      1 //
      2 // Copyright (c) 2002-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/VariableInfo.h"
      8 
      9 static TString arrayBrackets(int index)
     10 {
     11     TStringStream stream;
     12     stream << "[" << index << "]";
     13     return stream.str();
     14 }
     15 
     16 // Returns the data type for an attribute or uniform.
     17 static ShDataType getVariableDataType(const TType& type)
     18 {
     19     switch (type.getBasicType()) {
     20       case EbtFloat:
     21           if (type.isMatrix()) {
     22               switch (type.getNominalSize()) {
     23                 case 2: return SH_FLOAT_MAT2;
     24                 case 3: return SH_FLOAT_MAT3;
     25                 case 4: return SH_FLOAT_MAT4;
     26                 default: UNREACHABLE();
     27               }
     28           } else if (type.isVector()) {
     29               switch (type.getNominalSize()) {
     30                 case 2: return SH_FLOAT_VEC2;
     31                 case 3: return SH_FLOAT_VEC3;
     32                 case 4: return SH_FLOAT_VEC4;
     33                 default: UNREACHABLE();
     34               }
     35           } else {
     36               return SH_FLOAT;
     37           }
     38       case EbtInt:
     39           if (type.isMatrix()) {
     40               UNREACHABLE();
     41           } else if (type.isVector()) {
     42               switch (type.getNominalSize()) {
     43                 case 2: return SH_INT_VEC2;
     44                 case 3: return SH_INT_VEC3;
     45                 case 4: return SH_INT_VEC4;
     46                 default: UNREACHABLE();
     47               }
     48           } else {
     49               return SH_INT;
     50           }
     51       case EbtBool:
     52           if (type.isMatrix()) {
     53               UNREACHABLE();
     54           } else if (type.isVector()) {
     55               switch (type.getNominalSize()) {
     56                 case 2: return SH_BOOL_VEC2;
     57                 case 3: return SH_BOOL_VEC3;
     58                 case 4: return SH_BOOL_VEC4;
     59                 default: UNREACHABLE();
     60               }
     61           } else {
     62               return SH_BOOL;
     63           }
     64       case EbtSampler2D: return SH_SAMPLER_2D;
     65       case EbtSamplerCube: return SH_SAMPLER_CUBE;
     66       default: UNREACHABLE();
     67     }
     68     return SH_NONE;
     69 }
     70 
     71 static void getBuiltInVariableInfo(const TType& type,
     72                                    const TString& name,
     73                                    TVariableInfoList& infoList);
     74 static void getUserDefinedVariableInfo(const TType& type,
     75                                        const TString& name,
     76                                        TVariableInfoList& infoList);
     77 
     78 // Returns info for an attribute or uniform.
     79 static void getVariableInfo(const TType& type,
     80                             const TString& name,
     81                             TVariableInfoList& infoList)
     82 {
     83     if (type.getBasicType() == EbtStruct) {
     84         if (type.isArray()) {
     85             for (int i = 0; i < type.getArraySize(); ++i) {
     86                 TString lname = name + arrayBrackets(i);
     87                 getUserDefinedVariableInfo(type, lname, infoList);
     88             }
     89         } else {
     90             getUserDefinedVariableInfo(type, name, infoList);
     91         }
     92     } else {
     93         getBuiltInVariableInfo(type, name, infoList);
     94     }
     95 }
     96 
     97 void getBuiltInVariableInfo(const TType& type,
     98                             const TString& name,
     99                             TVariableInfoList& infoList)
    100 {
    101     ASSERT(type.getBasicType() != EbtStruct);
    102 
    103     TVariableInfo varInfo;
    104     if (type.isArray()) {
    105         varInfo.name = (name + "[0]").c_str();
    106         varInfo.size = type.getArraySize();
    107     } else {
    108         varInfo.name = name.c_str();
    109         varInfo.size = 1;
    110     }
    111     varInfo.type = getVariableDataType(type);
    112     infoList.push_back(varInfo);
    113 }
    114 
    115 void getUserDefinedVariableInfo(const TType& type,
    116                                 const TString& name,
    117                                 TVariableInfoList& infoList)
    118 {
    119     ASSERT(type.getBasicType() == EbtStruct);
    120 
    121     TString lname = name + ".";
    122     const TTypeList* structure = type.getStruct();
    123     for (size_t i = 0; i < structure->size(); ++i) {
    124         const TType* fieldType = (*structure)[i].type;
    125         getVariableInfo(*fieldType,
    126                         lname + fieldType->getFieldName(),
    127                         infoList);
    128     }
    129 }
    130 
    131 CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
    132                                                TVariableInfoList& uniforms)
    133     : mAttribs(attribs),
    134       mUniforms(uniforms)
    135 {
    136 }
    137 
    138 // We are only interested in attribute and uniform variable declaration.
    139 void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
    140 {
    141 }
    142 
    143 void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
    144 {
    145 }
    146 
    147 bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
    148 {
    149     return false;
    150 }
    151 
    152 bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
    153 {
    154     return false;
    155 }
    156 
    157 bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
    158 {
    159     return false;
    160 }
    161 
    162 bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
    163 {
    164     bool visitChildren = false;
    165 
    166     switch (node->getOp())
    167     {
    168     case EOpSequence:
    169         // We need to visit sequence children to get to variable declarations.
    170         visitChildren = true;
    171         break;
    172     case EOpDeclaration: {
    173         const TIntermSequence& sequence = node->getSequence();
    174         TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
    175         if (qualifier == EvqAttribute || qualifier == EvqUniform)
    176         {
    177             TVariableInfoList& infoList = qualifier == EvqAttribute ?
    178                 mAttribs : mUniforms;
    179             for (TIntermSequence::const_iterator i = sequence.begin();
    180                  i != sequence.end(); ++i)
    181             {
    182                 const TIntermSymbol* variable = (*i)->getAsSymbolNode();
    183                 // The only case in which the sequence will not contain a
    184                 // TIntermSymbol node is initialization. It will contain a
    185                 // TInterBinary node in that case. Since attributes and unifroms
    186                 // cannot be initialized in a shader, we must have only
    187                 // TIntermSymbol nodes in the sequence.
    188                 ASSERT(variable != NULL);
    189                 getVariableInfo(variable->getType(), variable->getSymbol(),
    190                                 infoList);
    191             }
    192         }
    193         break;
    194     }
    195     default: break;
    196     }
    197 
    198     return visitChildren;
    199 }
    200 
    201 bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
    202 {
    203     return false;
    204 }
    205 
    206 bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
    207 {
    208     return false;
    209 }
    210 
    211