xref: /aosp_15_r20/external/deqp/framework/randomshaders/rsgUtils.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 
addNewUniforms(vector<const ShaderInput * > & uniforms,set<string> & addedUniforms,const Shader & shader)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 
computeUnifiedUniforms(const Shader & vertexShader,const Shader & fragmentShader,std::vector<const ShaderInput * > & uniforms)50 void computeUnifiedUniforms(const Shader &vertexShader, const Shader &fragmentShader,
51                             std::vector<const ShaderInput *> &uniforms)
52 {
53     set<string> addedUniforms;
54     addNewUniforms(uniforms, addedUniforms, vertexShader);
55     addNewUniforms(uniforms, addedUniforms, fragmentShader);
56 }
57 
computeRandomValue(de::Random & rnd,ValueAccess dst,ConstValueRangeAccess valueRange)58 void computeRandomValue(de::Random &rnd, ValueAccess dst, ConstValueRangeAccess valueRange)
59 {
60     const VariableType &type = dst.getType();
61 
62     switch (type.getBaseType())
63     {
64     case VariableType::TYPE_FLOAT:
65         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
66         {
67             const float quantizeStep     = 1.0f / 8.0f;
68             float minVal                 = valueRange.component(ndx).getMin().asFloat();
69             float maxVal                 = valueRange.component(ndx).getMax().asFloat();
70             dst.component(ndx).asFloat() = getQuantizedFloat(rnd, minVal, maxVal, quantizeStep);
71         }
72         break;
73 
74     case VariableType::TYPE_BOOL:
75         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
76         {
77             int minVal                  = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
78             int maxVal                  = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
79             dst.component(ndx).asBool() = rnd.getInt(minVal, maxVal) == 1;
80         }
81         break;
82 
83     case VariableType::TYPE_INT:
84     case VariableType::TYPE_SAMPLER_2D:
85     case VariableType::TYPE_SAMPLER_CUBE:
86         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
87         {
88             int minVal                 = valueRange.component(ndx).getMin().asInt();
89             int maxVal                 = valueRange.component(ndx).getMax().asInt();
90             dst.component(ndx).asInt() = rnd.getInt(minVal, maxVal);
91         }
92         break;
93 
94     case VariableType::TYPE_ARRAY:
95     {
96         int numElements = type.getNumElements();
97         for (int ndx = 0; ndx < numElements; ndx++)
98             computeRandomValue(rnd, dst.arrayElement(ndx), valueRange.arrayElement(ndx));
99         break;
100     }
101 
102     case VariableType::TYPE_STRUCT:
103     {
104         int numMembers = (int)type.getMembers().size();
105         for (int ndx = 0; ndx < numMembers; ndx++)
106             computeRandomValue(rnd, dst.member(ndx), valueRange.member(ndx));
107         break;
108     }
109 
110     default:
111         TCU_FAIL("Invalid type");
112     }
113 }
114 
computeUniformValues(de::Random & rnd,std::vector<VariableValue> & values,const std::vector<const ShaderInput * > & uniforms)115 void computeUniformValues(de::Random &rnd, std::vector<VariableValue> &values,
116                           const std::vector<const ShaderInput *> &uniforms)
117 {
118     DE_ASSERT(values.empty());
119     for (vector<const ShaderInput *>::const_iterator i = uniforms.begin(); i != uniforms.end(); i++)
120     {
121         const ShaderInput *uniform = *i;
122         values.push_back(VariableValue(uniform->getVariable()));
123         computeRandomValue(rnd, values[values.size() - 1].getValue(), uniform->getValueRange());
124     }
125 }
126 
isUndefinedValueRange(ConstValueRangeAccess valueRange)127 bool isUndefinedValueRange(ConstValueRangeAccess valueRange)
128 {
129     switch (valueRange.getType().getBaseType())
130     {
131     case VariableType::TYPE_FLOAT:
132     case VariableType::TYPE_INT:
133     {
134         bool isFloat  = valueRange.getType().getBaseType() == VariableType::TYPE_FLOAT;
135         Scalar infMin = isFloat ? Scalar::min<float>() : Scalar::min<int>();
136         Scalar infMax = isFloat ? Scalar::max<float>() : Scalar::max<int>();
137 
138         for (int ndx = 0; ndx < valueRange.getType().getNumElements(); ndx++)
139         {
140             if (valueRange.getMin().component(ndx).asScalar() != infMin ||
141                 valueRange.getMax().component(ndx).asScalar() != infMax)
142                 return false;
143         }
144         return true;
145     }
146 
147     case VariableType::TYPE_BOOL:
148         return false;
149 
150     default:
151         TCU_FAIL("Unsupported type");
152     }
153 }
154 
computeRandomType(GeneratorState & state,int maxScalars)155 VariableType computeRandomType(GeneratorState &state, int maxScalars)
156 {
157     DE_ASSERT(maxScalars >= 1);
158 
159     static const VariableType::Type baseTypes[] = {
160         VariableType::TYPE_BOOL, VariableType::TYPE_INT, VariableType::TYPE_FLOAT
161         // \todo [pyry] Other types
162     };
163 
164     VariableType::Type baseType = VariableType::TYPE_LAST;
165     state.getRandom().choose(baseTypes, baseTypes + DE_LENGTH_OF_ARRAY(baseTypes), &baseType, 1);
166 
167     switch (baseType)
168     {
169     case VariableType::TYPE_BOOL:
170     case VariableType::TYPE_INT:
171     case VariableType::TYPE_FLOAT:
172     {
173         const int minVecLength = 1;
174         const int maxVecLength = 4;
175         return VariableType(baseType, state.getRandom().getInt(minVecLength, de::min(maxScalars, maxVecLength)));
176     }
177 
178     default:
179         DE_ASSERT(false);
180         throw Exception("computeRandomType(): Unsupported type");
181     }
182 }
183 
computeRandomValueRange(GeneratorState & state,ValueRangeAccess valueRange)184 void computeRandomValueRange(GeneratorState &state, ValueRangeAccess valueRange)
185 {
186     const VariableType &type = valueRange.getType();
187     de::Random &rnd          = state.getRandom();
188 
189     switch (type.getBaseType())
190     {
191     case VariableType::TYPE_BOOL:
192         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
193         {
194             bool minVal                                 = rnd.getBool();
195             bool maxVal                                 = minVal ? true : rnd.getBool();
196             valueRange.getMin().component(ndx).asBool() = minVal;
197             valueRange.getMax().component(ndx).asBool() = maxVal;
198         }
199         break;
200 
201     case VariableType::TYPE_INT:
202         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
203         {
204             const int minIntVal   = -16;
205             const int maxIntVal   = 16;
206             const int maxRangeLen = maxIntVal - minIntVal;
207 
208             int rangeLen = rnd.getInt(0, maxRangeLen);
209             int minVal   = minIntVal + rnd.getInt(0, maxRangeLen - rangeLen);
210             int maxVal   = minVal + rangeLen;
211 
212             valueRange.getMin().component(ndx).asInt() = minVal;
213             valueRange.getMax().component(ndx).asInt() = maxVal;
214         }
215         break;
216 
217     case VariableType::TYPE_FLOAT:
218         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
219         {
220             const float step        = 0.1f;
221             const int maxSteps      = 320;
222             const float minFloatVal = -16.0f;
223 
224             int rangeLen = rnd.getInt(0, maxSteps);
225             int minStep  = rnd.getInt(0, maxSteps - rangeLen);
226 
227             float minVal = minFloatVal + step * (float)minStep;
228             float maxVal = minVal + step * (float)rangeLen;
229 
230             valueRange.getMin().component(ndx).asFloat() = minVal;
231             valueRange.getMax().component(ndx).asFloat() = maxVal;
232         }
233         break;
234 
235     default:
236         DE_ASSERT(false);
237         throw Exception("computeRandomValueRange(): Unsupported type");
238     }
239 }
240 
getTypeConstructorDepth(const VariableType & type)241 int getTypeConstructorDepth(const VariableType &type)
242 {
243     switch (type.getBaseType())
244     {
245     case VariableType::TYPE_STRUCT:
246     {
247         const vector<VariableType::Member> &members = type.getMembers();
248         int maxDepth                                = 0;
249         for (vector<VariableType::Member>::const_iterator i = members.begin(); i != members.end(); i++)
250         {
251             const VariableType &memberType = i->getType();
252             int depth                      = 0;
253             switch (memberType.getBaseType())
254             {
255             case VariableType::TYPE_STRUCT:
256                 depth = getTypeConstructorDepth(memberType);
257                 break;
258 
259             case VariableType::TYPE_BOOL:
260             case VariableType::TYPE_FLOAT:
261             case VariableType::TYPE_INT:
262                 depth = memberType.getNumElements() == 1 ? 1 : 2;
263                 break;
264 
265             default:
266                 DE_ASSERT(false);
267                 break;
268             }
269 
270             maxDepth = de::max(maxDepth, depth);
271         }
272         return maxDepth + 1;
273     }
274 
275     case VariableType::TYPE_BOOL:
276     case VariableType::TYPE_FLOAT:
277     case VariableType::TYPE_INT:
278         return 2; // One node for ctor, another for value
279 
280     default:
281         DE_ASSERT(false);
282         return 0;
283     }
284 }
285 
getConservativeValueExprDepth(const GeneratorState & state,ConstValueRangeAccess valueRange)286 int getConservativeValueExprDepth(const GeneratorState &state, ConstValueRangeAccess valueRange)
287 {
288     // \todo [2011-03-22 pyry] Do a look-up into variable manager?
289     DE_UNREF(state);
290     return getTypeConstructorDepth(valueRange.getType());
291 }
292 
computeRangeLengthSum(ConstValueRangeAccess valueRange)293 static float computeRangeLengthSum(ConstValueRangeAccess valueRange)
294 {
295     const VariableType &type = valueRange.getType();
296     float rangeLength        = 0.0f;
297 
298     switch (type.getBaseType())
299     {
300     case VariableType::TYPE_FLOAT:
301         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
302         {
303             float minVal = valueRange.component(ndx).getMin().asFloat();
304             float maxVal = valueRange.component(ndx).getMax().asFloat();
305             rangeLength += maxVal - minVal;
306         }
307         break;
308 
309     case VariableType::TYPE_BOOL:
310         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
311         {
312             int minVal = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
313             int maxVal = valueRange.component(ndx).getMin().asBool() ? 1 : 0;
314             rangeLength += (float)(maxVal - minVal);
315         }
316         break;
317 
318     case VariableType::TYPE_INT:
319     case VariableType::TYPE_SAMPLER_2D:
320     case VariableType::TYPE_SAMPLER_CUBE:
321         for (int ndx = 0; ndx < type.getNumElements(); ndx++)
322         {
323             int64_t minVal = valueRange.component(ndx).getMin().asInt();
324             int64_t maxVal = valueRange.component(ndx).getMax().asInt();
325             rangeLength += (float)((int)(maxVal - minVal));
326         }
327         break;
328 
329     case VariableType::TYPE_ARRAY:
330     {
331         int numElements = type.getNumElements();
332         for (int ndx = 0; ndx < numElements; ndx++)
333             rangeLength += computeRangeLengthSum(valueRange.arrayElement(ndx));
334         break;
335     }
336 
337     case VariableType::TYPE_STRUCT:
338     {
339         int numMembers = (int)type.getMembers().size();
340         for (int ndx = 0; ndx < numMembers; ndx++)
341             rangeLength += computeRangeLengthSum(valueRange.member(ndx));
342         break;
343     }
344 
345     default:
346         TCU_FAIL("Invalid type");
347     }
348 
349     return rangeLength;
350 }
351 
computeDynamicRangeWeight(ConstValueRangeAccess valueRange)352 float computeDynamicRangeWeight(ConstValueRangeAccess valueRange)
353 {
354     const VariableType &type = valueRange.getType();
355     float rangeLenSum        = computeRangeLengthSum(valueRange);
356     int numScalars           = type.getScalarSize();
357 
358     return rangeLenSum / (float)numScalars;
359 }
360 
361 } // namespace rsg
362