blob: b9fc0b4ca4f91337e6e427074c6b37723525346f [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 Madill033dae62014-06-18 12:56:28 -040012#include "common/shadervars.h"
Jamie Madill77f74852014-07-08 15:02:34 -040013#include "common/utilities.h"
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000014
Zhenyao Mof1d723c2013-09-23 14:57:07 -040015bool atof_clamp(const char *str, float *value)
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000016{
Zhenyao Mocc4ec642013-09-23 14:57:10 -040017 bool success = pp::numeric_lex_float(str, value);
Zhenyao Mof1d723c2013-09-23 14:57:07 -040018 if (!success)
19 *value = std::numeric_limits<float>::max();
20 return success;
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000021}
Zhenyao Mof1d723c2013-09-23 14:57:07 -040022
23bool atoi_clamp(const char *str, int *value)
24{
Zhenyao Mocc4ec642013-09-23 14:57:10 -040025 bool success = pp::numeric_lex_int(str, value);
26 if (!success)
Zhenyao Mof1d723c2013-09-23 14:57:07 -040027 *value = std::numeric_limits<int>::max();
Zhenyao Mocc4ec642013-09-23 14:57:10 -040028 return success;
Zhenyao Mof1d723c2013-09-23 14:57:07 -040029}
30
Jamie Madill033dae62014-06-18 12:56:28 -040031namespace sh
32{
33
34GLenum 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;
Jamie Madillaa72d782014-07-02 15:31:19 -0400148 case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES;
149 case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB;
Jamie Madill033dae62014-06-18 12:56:28 -0400150 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
168GLenum GLVariablePrecision(const TType &type)
169{
170 if (type.getBasicType() == EbtFloat)
171 {
172 switch (type.getPrecision())
173 {
Jamie Madilla718c1e2014-07-02 15:31:22 -0400174 case EbpHigh:
Jamie Madill033dae62014-06-18 12:56:28 -0400175 return GL_HIGH_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400176 case EbpMedium:
Jamie Madill033dae62014-06-18 12:56:28 -0400177 return GL_MEDIUM_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400178 case EbpLow:
Jamie Madill033dae62014-06-18 12:56:28 -0400179 return GL_LOW_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400180 case EbpUndefined:
181 // Should be defined as the default precision by the parser
182 default:
Jamie Madill033dae62014-06-18 12:56:28 -0400183 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
207TString ArrayString(const TType &type)
208{
209 if (!type.isArray())
210 {
211 return "";
212 }
213
214 return "[" + str(type.getArraySize()) + "]";
215}
216
217bool 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
235bool 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
253bool IsVarying(TQualifier qualifier)
254{
255 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
256}
257
Jamie Madillf2575982014-06-25 16:04:54 -0400258InterpolationType GetInterpolationType(TQualifier qualifier)
Jamie Madill033dae62014-06-18 12:56:28 -0400259{
260 switch (qualifier)
261 {
262 case EvqFlatIn:
263 case EvqFlatOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400264 return INTERPOLATION_FLAT;
Jamie Madill033dae62014-06-18 12:56:28 -0400265
266 case EvqSmoothIn:
267 case EvqSmoothOut:
268 case EvqVertexOut:
269 case EvqFragmentIn:
270 case EvqVaryingIn:
271 case EvqVaryingOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400272 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400273
274 case EvqCentroidIn:
275 case EvqCentroidOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400276 return INTERPOLATION_CENTROID;
Jamie Madill033dae62014-06-18 12:56:28 -0400277
278 default: UNREACHABLE();
Jamie Madillf2575982014-06-25 16:04:54 -0400279 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400280 }
281}
282
Jamie Madill77f74852014-07-08 15:02:34 -0400283template <typename VarT>
284void GetVariableTraverser<VarT>::traverse(const TType &type, const TString &name)
285{
286 const TStructure *structure = type.getStruct();
287
288 VarT variable;
289 variable.name = name.c_str();
290 variable.arraySize = static_cast<unsigned int>(type.getArraySize());
291
292 if (!structure)
293 {
294 variable.type = GLVariableType(type);
295 variable.precision = GLVariablePrecision(type);
296 }
297 else
298 {
299 variable.type = GL_STRUCT_ANGLEX;
300
301 mOutputStack.push(&variable.fields);
302
303 const TFieldList &fields = structure->fields();
304
305 for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
306 {
307 TField *field = fields[fieldIndex];
308 traverse(*field->type(), field->name());
309 }
310
311 mOutputStack.pop();
312 }
313
314 visitVariable(&variable);
315
316 ASSERT(!mOutputStack.empty());
317 mOutputStack.top()->push_back(variable);
318}
319
320template <typename VarT>
321GetVariableTraverser<VarT>::GetVariableTraverser(std::vector<VarT> *output)
322{
323 ASSERT(output);
324 mOutputStack.push(output);
325}
326
327template class GetVariableTraverser<Uniform>;
328template class GetVariableTraverser<Varying>;
329template class GetVariableTraverser<InterfaceBlockField>;
330
331GetInterfaceBlockFieldTraverser::GetInterfaceBlockFieldTraverser(std::vector<InterfaceBlockField> *output, bool isRowMajorMatrix)
332 : GetVariableTraverser(output),
333 mIsRowMajorMatrix(isRowMajorMatrix)
334{
335}
336
337void GetInterfaceBlockFieldTraverser::visitVariable(InterfaceBlockField *newField)
338{
339 if (gl::IsMatrixType(newField->type))
340 {
341 newField->isRowMajorMatrix = mIsRowMajorMatrix;
342 }
343}
344
Jamie Madill033dae62014-06-18 12:56:28 -0400345}