blob: 40c90d8f2281e9bc9ed067adf0b7448a9e8c03a5 [file] [log] [blame]
daniel@transgaming.com91ed1492010-10-29 03:11:43 +00001//
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
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/util.h"
daniel@transgaming.com91ed1492010-10-29 03:11:43 +00008
Zhenyao Mof1d723c2013-09-23 14:57:07 -04009#include <limits>
10
Zhenyao Mocc4ec642013-09-23 14:57:10 -040011#include "compiler/preprocessor/numeric_lex.h"
Jamie Madill77f74852014-07-08 15:02:34 -040012#include "common/utilities.h"
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000013
Zhenyao Mof1d723c2013-09-23 14:57:07 -040014bool atof_clamp(const char *str, float *value)
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000015{
Zhenyao Mocc4ec642013-09-23 14:57:10 -040016 bool success = pp::numeric_lex_float(str, value);
Zhenyao Mof1d723c2013-09-23 14:57:07 -040017 if (!success)
18 *value = std::numeric_limits<float>::max();
19 return success;
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000020}
Zhenyao Mof1d723c2013-09-23 14:57:07 -040021
22bool atoi_clamp(const char *str, int *value)
23{
Zhenyao Mocc4ec642013-09-23 14:57:10 -040024 bool success = pp::numeric_lex_int(str, value);
25 if (!success)
Zhenyao Mof1d723c2013-09-23 14:57:07 -040026 *value = std::numeric_limits<int>::max();
Zhenyao Mocc4ec642013-09-23 14:57:10 -040027 return success;
Zhenyao Mof1d723c2013-09-23 14:57:07 -040028}
29
Jamie Madill033dae62014-06-18 12:56:28 -040030namespace sh
31{
32
33GLenum 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;
Jamie Madillaa72d782014-07-02 15:31:19 -0400147 case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES;
148 case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB;
Jamie Madill033dae62014-06-18 12:56:28 -0400149 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
167GLenum GLVariablePrecision(const TType &type)
168{
169 if (type.getBasicType() == EbtFloat)
170 {
171 switch (type.getPrecision())
172 {
Jamie Madilla718c1e2014-07-02 15:31:22 -0400173 case EbpHigh:
Jamie Madill033dae62014-06-18 12:56:28 -0400174 return GL_HIGH_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400175 case EbpMedium:
Jamie Madill033dae62014-06-18 12:56:28 -0400176 return GL_MEDIUM_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400177 case EbpLow:
Jamie Madill033dae62014-06-18 12:56:28 -0400178 return GL_LOW_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400179 case EbpUndefined:
180 // Should be defined as the default precision by the parser
181 default:
Jamie Madill033dae62014-06-18 12:56:28 -0400182 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
206TString ArrayString(const TType &type)
207{
208 if (!type.isArray())
209 {
210 return "";
211 }
212
213 return "[" + str(type.getArraySize()) + "]";
214}
215
216bool 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
234bool 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
252bool IsVarying(TQualifier qualifier)
253{
254 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
255}
256
Jamie Madillf2575982014-06-25 16:04:54 -0400257InterpolationType GetInterpolationType(TQualifier qualifier)
Jamie Madill033dae62014-06-18 12:56:28 -0400258{
259 switch (qualifier)
260 {
261 case EvqFlatIn:
262 case EvqFlatOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400263 return INTERPOLATION_FLAT;
Jamie Madill033dae62014-06-18 12:56:28 -0400264
265 case EvqSmoothIn:
266 case EvqSmoothOut:
267 case EvqVertexOut:
268 case EvqFragmentIn:
269 case EvqVaryingIn:
270 case EvqVaryingOut:
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400271 case EvqInvariantVaryingIn:
272 case EvqInvariantVaryingOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400273 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400274
275 case EvqCentroidIn:
276 case EvqCentroidOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400277 return INTERPOLATION_CENTROID;
Jamie Madill033dae62014-06-18 12:56:28 -0400278
279 default: UNREACHABLE();
Jamie Madillf2575982014-06-25 16:04:54 -0400280 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400281 }
282}
283
Jamie Madill77f74852014-07-08 15:02:34 -0400284template <typename VarT>
Jamie Madill42bcf322014-08-25 16:20:46 -0400285void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
Jamie Madill77f74852014-07-08 15:02:34 -0400286{
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 {
Jamie Madill42bcf322014-08-25 16:20:46 -0400300 // Note: this enum value is not exposed outside ANGLE
Jamie Madill77f74852014-07-08 15:02:34 -0400301 variable.type = GL_STRUCT_ANGLEX;
Jamie Madill42bcf322014-08-25 16:20:46 -0400302 variable.structName = structure->name().c_str();
Jamie Madill77f74852014-07-08 15:02:34 -0400303
304 const TFieldList &fields = structure->fields();
305
306 for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
307 {
308 TField *field = fields[fieldIndex];
Jamie Madill42bcf322014-08-25 16:20:46 -0400309 traverse(*field->type(), field->name(), &variable.fields);
Jamie Madill77f74852014-07-08 15:02:34 -0400310 }
Jamie Madill77f74852014-07-08 15:02:34 -0400311 }
312
313 visitVariable(&variable);
314
Jamie Madill77f74852014-07-08 15:02:34 -0400315 ASSERT(output);
Jamie Madill42bcf322014-08-25 16:20:46 -0400316 output->push_back(variable);
Jamie Madill77f74852014-07-08 15:02:34 -0400317}
318
Jamie Madill42bcf322014-08-25 16:20:46 -0400319template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
320template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
321template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
Jamie Madill77f74852014-07-08 15:02:34 -0400322
Jamie Madilld5512cd2014-07-10 17:50:08 -0400323BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
324{
325 switch (blockStorage)
326 {
327 case EbsPacked: return BLOCKLAYOUT_PACKED;
328 case EbsShared: return BLOCKLAYOUT_SHARED;
329 case EbsStd140: return BLOCKLAYOUT_STANDARD;
330 default: UNREACHABLE(); return BLOCKLAYOUT_SHARED;
331 }
332}
333
Jamie Madill42bcf322014-08-25 16:20:46 -0400334static TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
335{
336 if (interfaceBlock.hasInstanceName())
337 {
338 return interfaceBlock.name() + "." + field.name();
339 }
340 else
341 {
342 return field.name();
343 }
344}
345
346void GetInterfaceBlockFields(const TInterfaceBlock &interfaceBlock, std::vector<InterfaceBlockField> *fieldsOut)
347{
348 const TFieldList &fieldList = interfaceBlock.fields();
349
350 for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
351 {
352 const TField &field = *fieldList[fieldIndex];
353 const TString &fullFieldName = InterfaceBlockFieldName(interfaceBlock, field);
354 const TType &fieldType = *field.type();
355
356 GetVariableTraverser traverser;
357 traverser.traverse(fieldType, fullFieldName, fieldsOut);
358
Jamie Madilla6f267f2014-08-27 11:44:15 -0400359 fieldsOut->back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
Jamie Madill42bcf322014-08-25 16:20:46 -0400360 }
361}
362
Jamie Madill033dae62014-06-18 12:56:28 -0400363}