1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Random Shader Generator
3 * ----------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 *//*--------------------------------------------------------------------*/
24 #include "rsgUtils.hpp"
36 void addNewUniforms (vector<const ShaderInput*>& uniforms, set<string>& addedUniforms, const Shader& shader)
38 const vector<ShaderInput*>& shaderUniforms = shader.getUniforms();
39 for (vector<ShaderInput*>::const_iterator i = shaderUniforms.begin(); i != shaderUniforms.end(); i++)
41 const ShaderInput* uniform = *i;
42 if (addedUniforms.find(uniform->getVariable()->getName()) == addedUniforms.end())
44 addedUniforms.insert(uniform->getVariable()->getName());
45 uniforms.push_back(uniform);
50 void computeUnifiedUniforms (const Shader& vertexShader, const Shader& fragmentShader, std::vector<const ShaderInput*>& uniforms)
52 set<string> addedUniforms;
53 addNewUniforms(uniforms, addedUniforms, vertexShader);
54 addNewUniforms(uniforms, addedUniforms, fragmentShader);
57 void computeRandomValue (de::Random& rnd, ValueAccess dst, ConstValueRangeAccess valueRange)
59 const VariableType& type = dst.getType();
61 switch (type.getBaseType())
63 case VariableType::TYPE_FLOAT:
64 for (int ndx = 0; ndx < type.getNumElements(); ndx++)
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);
73 case VariableType::TYPE_BOOL:
74 for (int ndx = 0; ndx < type.getNumElements(); ndx++)
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;
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++)
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);
93 case VariableType::TYPE_ARRAY:
95 int numElements = type.getNumElements();
96 for (int ndx = 0; ndx < numElements; ndx++)
97 computeRandomValue(rnd, dst.arrayElement(ndx), valueRange.arrayElement(ndx));
101 case VariableType::TYPE_STRUCT:
103 int numMembers = (int)type.getMembers().size();
104 for (int ndx = 0; ndx < numMembers; ndx++)
105 computeRandomValue(rnd, dst.member(ndx), valueRange.member(ndx));
110 TCU_FAIL("Invalid type");
114 void computeUniformValues (de::Random& rnd, std::vector<VariableValue>& values, const std::vector<const ShaderInput*>& uniforms)
116 DE_ASSERT(values.empty());
117 for (vector<const ShaderInput*>::const_iterator i = uniforms.begin(); i != uniforms.end(); i++)
119 const ShaderInput* uniform = *i;
120 values.push_back(VariableValue(uniform->getVariable()));
121 computeRandomValue(rnd, values[values.size()-1].getValue(), uniform->getValueRange());
125 bool isUndefinedValueRange (ConstValueRangeAccess valueRange)
127 switch (valueRange.getType().getBaseType())
129 case VariableType::TYPE_FLOAT:
130 case VariableType::TYPE_INT:
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>();
136 for (int ndx = 0; ndx < valueRange.getType().getNumElements(); ndx++)
138 if (valueRange.getMin().component(ndx).asScalar() != infMin ||
139 valueRange.getMax().component(ndx).asScalar() != infMax)
145 case VariableType::TYPE_BOOL:
149 TCU_FAIL("Unsupported type");
153 VariableType computeRandomType (GeneratorState& state, int maxScalars)
155 DE_ASSERT(maxScalars >= 1);
157 static const VariableType::Type baseTypes[] =
159 VariableType::TYPE_BOOL,
160 VariableType::TYPE_INT,
161 VariableType::TYPE_FLOAT
162 // \todo [pyry] Other types
165 VariableType::Type baseType = VariableType::TYPE_LAST;
166 state.getRandom().choose(baseTypes, baseTypes + DE_LENGTH_OF_ARRAY(baseTypes), &baseType, 1);
170 case VariableType::TYPE_BOOL:
171 case VariableType::TYPE_INT:
172 case VariableType::TYPE_FLOAT:
174 const int minVecLength = 1;
175 const int maxVecLength = 4;
176 return VariableType(baseType, state.getRandom().getInt(minVecLength, de::min(maxScalars, maxVecLength)));
181 throw Exception("computeRandomType(): Unsupported type");
185 void computeRandomValueRange (GeneratorState& state, ValueRangeAccess valueRange)
187 const VariableType& type = valueRange.getType();
188 de::Random& rnd = state.getRandom();
190 switch (type.getBaseType())
192 case VariableType::TYPE_BOOL:
193 for (int ndx = 0; ndx < type.getNumElements(); ndx++)
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;
202 case VariableType::TYPE_INT:
203 for (int ndx = 0; ndx < type.getNumElements(); ndx++)
205 const int minIntVal = -16;
206 const int maxIntVal = 16;
207 const int maxRangeLen = maxIntVal - minIntVal;
209 int rangeLen = rnd.getInt(0, maxRangeLen);
210 int minVal = minIntVal + rnd.getInt(0, maxRangeLen-rangeLen);
211 int maxVal = minVal + rangeLen;
213 valueRange.getMin().component(ndx).asInt() = minVal;
214 valueRange.getMax().component(ndx).asInt() = maxVal;
218 case VariableType::TYPE_FLOAT:
219 for (int ndx = 0; ndx < type.getNumElements(); ndx++)
221 const float step = 0.1f;
222 const int maxSteps = 320;
223 const float minFloatVal = -16.0f;
225 int rangeLen = rnd.getInt(0, maxSteps);
226 int minStep = rnd.getInt(0, maxSteps-rangeLen);
228 float minVal = minFloatVal + step*(float)minStep;
229 float maxVal = minVal + step*(float)rangeLen;
231 valueRange.getMin().component(ndx).asFloat() = minVal;
232 valueRange.getMax().component(ndx).asFloat() = maxVal;
238 throw Exception("computeRandomValueRange(): Unsupported type");
242 int getTypeConstructorDepth (const VariableType& type)
244 switch (type.getBaseType())
246 case VariableType::TYPE_STRUCT:
248 const vector<VariableType::Member>& members = type.getMembers();
250 for (vector<VariableType::Member>::const_iterator i = members.begin(); i != members.end(); i++)
252 const VariableType& memberType = i->getType();
254 switch (memberType.getBaseType())
256 case VariableType::TYPE_STRUCT:
257 depth = getTypeConstructorDepth(memberType);
260 case VariableType::TYPE_BOOL:
261 case VariableType::TYPE_FLOAT:
262 case VariableType::TYPE_INT:
263 depth = memberType.getNumElements() == 1 ? 1 : 2;
271 maxDepth = de::max(maxDepth, depth);
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
287 int getConservativeValueExprDepth (const GeneratorState& state, ConstValueRangeAccess valueRange)
289 // \todo [2011-03-22 pyry] Do a look-up into variable manager?
291 return getTypeConstructorDepth(valueRange.getType());
294 static float computeRangeLengthSum (ConstValueRangeAccess valueRange)
296 const VariableType& type = valueRange.getType();
297 float rangeLength = 0.0f;
299 switch (type.getBaseType())
301 case VariableType::TYPE_FLOAT:
302 for (int ndx = 0; ndx < type.getNumElements(); ndx++)
304 float minVal = valueRange.component(ndx).getMin().asFloat();
305 float maxVal = valueRange.component(ndx).getMax().asFloat();
306 rangeLength += maxVal - minVal;
310 case VariableType::TYPE_BOOL:
311 for (int ndx = 0; ndx < type.getNumElements(); ndx++)
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);
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++)
324 deInt64 minVal = valueRange.component(ndx).getMin().asInt();
325 deInt64 maxVal = valueRange.component(ndx).getMax().asInt();
326 rangeLength += (float)((int)(maxVal - minVal));
330 case VariableType::TYPE_ARRAY:
332 int numElements = type.getNumElements();
333 for (int ndx = 0; ndx < numElements; ndx++)
334 rangeLength += computeRangeLengthSum(valueRange.arrayElement(ndx));
338 case VariableType::TYPE_STRUCT:
340 int numMembers = (int)type.getMembers().size();
341 for (int ndx = 0; ndx < numMembers; ndx++)
342 rangeLength += computeRangeLengthSum(valueRange.member(ndx));
347 TCU_FAIL("Invalid type");
353 float computeDynamicRangeWeight (ConstValueRangeAccess valueRange)
355 const VariableType& type = valueRange.getType();
356 float rangeLenSum = computeRangeLengthSum(valueRange);
357 int numScalars = type.getScalarSize();
359 return rangeLenSum / (float)numScalars;