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