• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
arrayBrackets(int index)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.
getVariableDataType(const TType & type)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.
getVariableInfo(const TType & type,const TString & name,TVariableInfoList & infoList)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 
getBuiltInVariableInfo(const TType & type,const TString & name,TVariableInfoList & infoList)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 
getUserDefinedVariableInfo(const TType & type,const TString & name,TVariableInfoList & infoList)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 
CollectAttribsUniforms(TVariableInfoList & attribs,TVariableInfoList & uniforms)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.
visitSymbol(TIntermSymbol *)139 void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
140 {
141 }
142 
visitConstantUnion(TIntermConstantUnion *)143 void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
144 {
145 }
146 
visitBinary(Visit,TIntermBinary *)147 bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
148 {
149     return false;
150 }
151 
visitUnary(Visit,TIntermUnary *)152 bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
153 {
154     return false;
155 }
156 
visitSelection(Visit,TIntermSelection *)157 bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
158 {
159     return false;
160 }
161 
visitAggregate(Visit,TIntermAggregate * node)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 
visitLoop(Visit,TIntermLoop *)201 bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
202 {
203     return false;
204 }
205 
visitBranch(Visit,TIntermBranch *)206 bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
207 {
208     return false;
209 }
210 
211