Merge "Fix eglBindAPI negative test" into nougat-cts-dev am: 6068dfbf3a am: 839be6fae...
[platform/upstream/VK-GL-CTS.git] / framework / randomshaders / rsgUtils.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Random Shader Generator
3  * ----------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Utilities.
22  *//*--------------------------------------------------------------------*/
23
24 #include "rsgUtils.hpp"
25
26 #include <set>
27 #include <string>
28
29 using std::set;
30 using std::string;
31 using std::vector;
32
33 namespace rsg
34 {
35
36 void addNewUniforms (vector<const ShaderInput*>& uniforms, set<string>& addedUniforms, const Shader& shader)
37 {
38         const vector<ShaderInput*>& shaderUniforms = shader.getUniforms();
39         for (vector<ShaderInput*>::const_iterator i = shaderUniforms.begin(); i != shaderUniforms.end(); i++)
40         {
41                 const ShaderInput* uniform = *i;
42                 if (addedUniforms.find(uniform->getVariable()->getName()) == addedUniforms.end())
43                 {
44                         addedUniforms.insert(uniform->getVariable()->getName());
45                         uniforms.push_back(uniform);
46                 }
47         }
48 }
49
50 void computeUnifiedUniforms (const Shader& vertexShader, const Shader& fragmentShader, std::vector<const ShaderInput*>& uniforms)
51 {
52         set<string> addedUniforms;
53         addNewUniforms(uniforms, addedUniforms, vertexShader);
54         addNewUniforms(uniforms, addedUniforms, fragmentShader);
55 }
56
57 void computeRandomValue (de::Random& rnd, ValueAccess dst, ConstValueRangeAccess valueRange)
58 {
59         const VariableType& type = dst.getType();
60
61         switch (type.getBaseType())
62         {
63                 case VariableType::TYPE_FLOAT:
64                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
65                         {
66                                 const float quantizeStep = 1.0f/8.0f;
67                                 float minVal = valueRange.component(ndx).getMin().asFloat();
68                                 float maxVal = valueRange.component(ndx).getMax().asFloat();
69                                 dst.component(ndx).asFloat() = getQuantizedFloat(rnd, minVal, maxVal, quantizeStep);
70                         }
71                         break;
72
73                 case VariableType::TYPE_BOOL:
74                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
75                         {
76                                 int minVal = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
77                                 int maxVal = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
78                                 dst.component(ndx).asBool() = rnd.getInt(minVal, maxVal) == 1;
79                         }
80                         break;
81
82                 case VariableType::TYPE_INT:
83                 case VariableType::TYPE_SAMPLER_2D:
84                 case VariableType::TYPE_SAMPLER_CUBE:
85                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
86                         {
87                                 int     minVal = valueRange.component(ndx).getMin().asInt();
88                                 int maxVal = valueRange.component(ndx).getMax().asInt();
89                                 dst.component(ndx).asInt() = rnd.getInt(minVal, maxVal);
90                         }
91                         break;
92
93                 case VariableType::TYPE_ARRAY:
94                 {
95                         int numElements = type.getNumElements();
96                         for (int ndx = 0; ndx < numElements; ndx++)
97                                 computeRandomValue(rnd, dst.arrayElement(ndx), valueRange.arrayElement(ndx));
98                         break;
99                 }
100
101                 case VariableType::TYPE_STRUCT:
102                 {
103                         int numMembers = (int)type.getMembers().size();
104                         for (int ndx = 0; ndx < numMembers; ndx++)
105                                 computeRandomValue(rnd, dst.member(ndx), valueRange.member(ndx));
106                         break;
107                 }
108
109                 default:
110                         TCU_FAIL("Invalid type");
111         }
112 }
113
114 void computeUniformValues (de::Random& rnd, std::vector<VariableValue>& values, const std::vector<const ShaderInput*>& uniforms)
115 {
116         DE_ASSERT(values.empty());
117         for (vector<const ShaderInput*>::const_iterator i = uniforms.begin(); i != uniforms.end(); i++)
118         {
119                 const ShaderInput* uniform = *i;
120                 values.push_back(VariableValue(uniform->getVariable()));
121                 computeRandomValue(rnd, values[values.size()-1].getValue(), uniform->getValueRange());
122         }
123 }
124
125 bool isUndefinedValueRange (ConstValueRangeAccess valueRange)
126 {
127         switch (valueRange.getType().getBaseType())
128         {
129                 case VariableType::TYPE_FLOAT:
130                 case VariableType::TYPE_INT:
131                 {
132                         bool    isFloat = valueRange.getType().getBaseType() == VariableType::TYPE_FLOAT;
133                         Scalar  infMin  = isFloat ? Scalar::min<float>() : Scalar::min<int>();
134                         Scalar  infMax  = isFloat ? Scalar::max<float>() : Scalar::max<int>();
135
136                         for (int ndx = 0; ndx < valueRange.getType().getNumElements(); ndx++)
137                         {
138                                 if (valueRange.getMin().component(ndx).asScalar() != infMin ||
139                                         valueRange.getMax().component(ndx).asScalar() != infMax)
140                                         return false;
141                         }
142                         return true;
143                 }
144
145                 case VariableType::TYPE_BOOL:
146                         return false;
147
148                 default:
149                         TCU_FAIL("Unsupported type");
150         }
151 }
152
153 VariableType computeRandomType (GeneratorState& state, int maxScalars)
154 {
155         DE_ASSERT(maxScalars >= 1);
156
157         static const VariableType::Type baseTypes[] =
158         {
159                 VariableType::TYPE_BOOL,
160                 VariableType::TYPE_INT,
161                 VariableType::TYPE_FLOAT
162                 // \todo [pyry] Other types
163         };
164
165         VariableType::Type baseType = VariableType::TYPE_LAST;
166         state.getRandom().choose(baseTypes, baseTypes + DE_LENGTH_OF_ARRAY(baseTypes), &baseType, 1);
167
168         switch (baseType)
169         {
170                 case VariableType::TYPE_BOOL:
171                 case VariableType::TYPE_INT:
172                 case VariableType::TYPE_FLOAT:
173                 {
174                         const int minVecLength = 1;
175                         const int maxVecLength = 4;
176                         return VariableType(baseType, state.getRandom().getInt(minVecLength, de::min(maxScalars, maxVecLength)));
177                 }
178
179                 default:
180                         DE_ASSERT(DE_FALSE);
181                         throw Exception("computeRandomType(): Unsupported type");
182         }
183 }
184
185 void computeRandomValueRange (GeneratorState& state, ValueRangeAccess valueRange)
186 {
187         const VariableType&     type    = valueRange.getType();
188         de::Random&                     rnd             = state.getRandom();
189
190         switch (type.getBaseType())
191         {
192                 case VariableType::TYPE_BOOL:
193                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
194                         {
195                                 bool minVal = rnd.getBool();
196                                 bool maxVal = minVal ? true : rnd.getBool();
197                                 valueRange.getMin().component(ndx).asBool() = minVal;
198                                 valueRange.getMax().component(ndx).asBool() = maxVal;
199                         }
200                         break;
201
202                 case VariableType::TYPE_INT:
203                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
204                         {
205                                 const int minIntVal             = -16;
206                                 const int maxIntVal             =  16;
207                                 const int maxRangeLen   = maxIntVal - minIntVal;
208
209                                 int rangeLen    = rnd.getInt(0, maxRangeLen);
210                                 int minVal              = minIntVal + rnd.getInt(0, maxRangeLen-rangeLen);
211                                 int maxVal              = minVal + rangeLen;
212
213                                 valueRange.getMin().component(ndx).asInt() = minVal;
214                                 valueRange.getMax().component(ndx).asInt() = maxVal;
215                         }
216                         break;
217
218                 case VariableType::TYPE_FLOAT:
219                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
220                         {
221                                 const float step                        = 0.1f;
222                                 const int       maxSteps                = 320;
223                                 const float minFloatVal         = -16.0f;
224
225                                 int rangeLen    = rnd.getInt(0, maxSteps);
226                                 int minStep             = rnd.getInt(0, maxSteps-rangeLen);
227
228                                 float minVal    = minFloatVal + step*(float)minStep;
229                                 float maxVal    = minVal + step*(float)rangeLen;
230
231                                 valueRange.getMin().component(ndx).asFloat() = minVal;
232                                 valueRange.getMax().component(ndx).asFloat() = maxVal;
233                         }
234                         break;
235
236                 default:
237                         DE_ASSERT(DE_FALSE);
238                         throw Exception("computeRandomValueRange(): Unsupported type");
239         }
240 }
241
242 int getTypeConstructorDepth (const VariableType& type)
243 {
244         switch (type.getBaseType())
245         {
246                 case VariableType::TYPE_STRUCT:
247                 {
248                         const vector<VariableType::Member>& members             = type.getMembers();
249                         int                                                                     maxDepth        = 0;
250                         for (vector<VariableType::Member>::const_iterator i = members.begin(); i != members.end(); i++)
251                         {
252                                 const VariableType&     memberType      = i->getType();
253                                 int                                     depth           = 0;
254                                 switch (memberType.getBaseType())
255                                 {
256                                         case VariableType::TYPE_STRUCT:
257                                                 depth = getTypeConstructorDepth(memberType);
258                                                 break;
259
260                                         case VariableType::TYPE_BOOL:
261                                         case VariableType::TYPE_FLOAT:
262                                         case VariableType::TYPE_INT:
263                                                 depth = memberType.getNumElements() == 1 ? 1 : 2;
264                                                 break;
265
266                                         default:
267                                                 DE_ASSERT(DE_FALSE);
268                                                 break;
269                                 }
270
271                                 maxDepth = de::max(maxDepth, depth);
272                         }
273                         return maxDepth + 1;
274                 }
275
276                 case VariableType::TYPE_BOOL:
277                 case VariableType::TYPE_FLOAT:
278                 case VariableType::TYPE_INT:
279                         return 2; // One node for ctor, another for value
280
281                 default:
282                         DE_ASSERT(DE_FALSE);
283                         return 0;
284         }
285 }
286
287 int getConservativeValueExprDepth (const GeneratorState& state, ConstValueRangeAccess valueRange)
288 {
289         // \todo [2011-03-22 pyry] Do a look-up into variable manager?
290         DE_UNREF(state);
291         return getTypeConstructorDepth(valueRange.getType());
292 }
293
294 static float computeRangeLengthSum (ConstValueRangeAccess valueRange)
295 {
296         const VariableType&     type            = valueRange.getType();
297         float                           rangeLength     = 0.0f;
298
299         switch (type.getBaseType())
300         {
301                 case VariableType::TYPE_FLOAT:
302                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
303                         {
304                                 float minVal = valueRange.component(ndx).getMin().asFloat();
305                                 float maxVal = valueRange.component(ndx).getMax().asFloat();
306                                 rangeLength += maxVal - minVal;
307                         }
308                         break;
309
310                 case VariableType::TYPE_BOOL:
311                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
312                         {
313                                 int minVal = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
314                                 int maxVal = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
315                                 rangeLength += (float)(maxVal - minVal);
316                         }
317                         break;
318
319                 case VariableType::TYPE_INT:
320                 case VariableType::TYPE_SAMPLER_2D:
321                 case VariableType::TYPE_SAMPLER_CUBE:
322                         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
323                         {
324                                 int     minVal = valueRange.component(ndx).getMin().asInt();
325                                 int maxVal = valueRange.component(ndx).getMax().asInt();
326                                 rangeLength += (float)(maxVal - minVal);
327                         }
328                         break;
329
330                 case VariableType::TYPE_ARRAY:
331                 {
332                         int numElements = type.getNumElements();
333                         for (int ndx = 0; ndx < numElements; ndx++)
334                                 rangeLength += computeRangeLengthSum(valueRange.arrayElement(ndx));
335                         break;
336                 }
337
338                 case VariableType::TYPE_STRUCT:
339                 {
340                         int numMembers = (int)type.getMembers().size();
341                         for (int ndx = 0; ndx < numMembers; ndx++)
342                                 rangeLength += computeRangeLengthSum(valueRange.member(ndx));
343                         break;
344                 }
345
346                 default:
347                         TCU_FAIL("Invalid type");
348         }
349
350         return rangeLength;
351 }
352
353 float computeDynamicRangeWeight (ConstValueRangeAccess valueRange)
354 {
355         const VariableType& type                = valueRange.getType();
356         float                           rangeLenSum     = computeRangeLengthSum(valueRange);
357         int                                     numScalars      = type.getScalarSize();
358
359         return rangeLenSum / (float)numScalars;
360 }
361
362 } // rsg