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
atof_clamp(const char * str,float * value)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
atoi_clamp(const char * str,int * value)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
GLVariableType(const TType & type)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
GLVariablePrecision(const TType & type)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
ArrayString(const TType & type)206 TString ArrayString(const TType &type)
207 {
208 if (!type.isArray())
209 {
210 return "";
211 }
212
213 return "[" + str(type.getArraySize()) + "]";
214 }
215
IsVaryingOut(TQualifier qualifier)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
IsVaryingIn(TQualifier qualifier)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
IsVarying(TQualifier qualifier)252 bool IsVarying(TQualifier qualifier)
253 {
254 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
255 }
256
GetInterpolationType(TQualifier qualifier)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>
traverse(const TType & type,const TString & name,std::vector<VarT> * output)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